Empirical
svg_shapes.h
Go to the documentation of this file.
1 
10 #ifndef EMP_D3_SVG_SHAPES_H
11 #define EMP_D3_SVG_SHAPES_H
12 
13 #include "d3_init.h"
14 #include "selection.h"
15 #include "scales.h"
16 #include "dataset.h"
17 
18 #include "../js_utils.h"
19 
20 namespace D3 {
21 
31  class SvgShapeGenerator : public D3_Base {
32  protected:
34  public:
35 
39  template <typename T, size_t SIZE>
40  std::string Generate(emp::array<emp::array<T, 2>, SIZE> & data){
42 
43  char * buffer = (char *)EM_ASM_INT({
44  var result = js.objects[$0](emp_i.__incoming_array);
45  var buffer = Module._malloc(result.length+1);
46  Module.writeStringToMemory(result, buffer);
47  return buffer;
48  }, this->id);
49 
50  std::string result = std::string(buffer);
51  free(buffer);
52  return result;
53  }
54 
57  template <typename T, std::size_t SIZE>
59  Selection path = s.Append("path");
60  path.SetAttr("d", Generate(data));
61  return path;
62  }
63 
66 
67  s = s.Append("path");
68 
69  EM_ASM_ARGS({
70  var sel = js.objects[$0].attr("d", js.objects[$1](js.objects[$2]));
71  }, s.GetID(), this->id, data.GetID());
72  return s;
73  }
74 
76  template <typename T, std::size_t SIZE, std::size_t SIZE2>
78  SIZE2> & data) {
79  Selection group = Select("svg").Append("g");
80  for (auto arr: data) {
81  Selection path = group.Append("path");
82  path.SetAttr("d", Generate(arr).c_str());
83  }
84  return group;
85  }
86  };
87 
91  public:
93  EM_ASM_ARGS({
94  var new_line = d3.symbol();
95  js.objects[$0] = new_line;
96  }, this->id);
97  }
98 
102  void SetType(std::string type){
103  emp_assert (
104  EM_ASM_INT({
105  return d3.symbolTypes.includes(Pointer_stringify($0)) ||
106  window[Pointer_stringify($0)] === "function" ||
107  window["d3"][Pointer_stringify($0)] === "function" ||
108  window["emp"][Pointer_stringify($0)] === "function";
109  }, type.c_str())
110  );
111  D3_CALLBACK_METHOD_1_ARG(type, type.c_str())
112  }
113 
115 
116  template <typename T>
117  emp::sfinae_decoy<void, decltype(&T::operator())>
118  SetType(T type){
120  }
121 
123 
126  //If size is a constant, it's in pixels, so an int is reasonable
127  void SetSize(int size) {
128  EM_ASM_ARGS({
129  js.objects[$0].size($1);
130  }, this->id, size);
131  }
132 
134  //Otherwise it's a function
135  void SetSize(std::string size){
136  D3_CALLBACK_METHOD_1_ARG(size, size.c_str())
137  }
138 
139  template <typename T>
140  emp::sfinae_decoy<void, decltype(&T::operator())>
141  SetSize(T type){
143  }
145 
146 
147  };
148 
153  public:
155 
159  void SetCurve(std::string curve){
160  D3_CALLBACK_METHOD_1_ARG(curve,curve.c_str())
161  }
162 
165  void SetTension(float tension){
166  EM_ASM_ARGS({
167  js.objects[$0].tension($1);
168  }, this->id, tension);
169  }
170 
173  void SetDefined(std::string defined){
174  D3_CALLBACK_METHOD_1_ARG(defined, defined.c_str())
175  }
176 
178  template <typename T>
179  emp::sfinae_decoy<void, decltype(&T::operator())>
180  SetDefined(T defined){
181  D3_CALLBACK_METHOD_CPP_FUNCTION_1_ARG(defined, defined)
182  }
184  };
185 
188  public:
190  EM_ASM_ARGS({
191  var new_line = d3.line();
192  js.objects[$0] = new_line;
193  }, this->id);
194  }
195 
201  template <typename X_SCALE_TYPE>
202  void AddXScale(X_SCALE_TYPE & scale){
203  EM_ASM_ARGS({
204  var scale = js.objects[$1];
205  var curr_x = js.objects[$0].x();
206 
207  //Apply scale to whatever the current x axis function is
208  js.objects[$0].x(function(d, i){return scale(curr_x(d, i));});
209  }, this->id, scale.GetID());
210  }
211 
217  template <typename Y_SCALE_TYPE>
218  void AddYScale(Y_SCALE_TYPE & scale){
219  EM_ASM_ARGS({
220  var scale = js.objects[$1];
221  var curr_y = js.objects[$0].y();
222 
223  //Apply scale on top of whatever the current y axis function is
224  js.objects[$0].y(function(d, i){return scale(curr_y(d, i));});
225  }, this->id, scale.GetID());
226  }
227 
253  // Handles setting x accessor to a function or string
254  void SetX(std::string x) {
255  D3_CALLBACK_METHOD_1_ARG(x, x.c_str())
256  }
257 
259  // Handles setting x to a constant
260  template <typename T>
261  typename std::enable_if<std::is_fundamental<T>::value, void>::type
262  SetX(T x) {
263  EM_ASM_ARGS({js.objects[$0].x($1);}, this->id, x);
264  }
265 
266  // handles C++ functions
267  template <typename T>
269  SetX(T x) {
271  }
272 
274 
300  //Handles setting x accessor to a function or string
301  void SetY(std::string y) {
302  D3_CALLBACK_METHOD_1_ARG(y, y.c_str())
303  }
304 
306 
307  // Handles constants
308  template <typename T>
309  typename std::enable_if<std::is_fundamental<T>::value, void>::type
310  SetY(T y) {
311  EM_ASM_ARGS({js.objects[$0].y($1);}, this->id, y);
312  }
313 
314  // handles C++ functions
315  template <typename T>
317  SetY(T y) {
319  }
320 
322 
323  };
324 
325  class LinkGenerator : public LineGenerator {
326  public:
327  LinkGenerator(std::string type) {
328  if (type == "vertical") {
329  EM_ASM_ARGS({js.objects[$0] = d3.linkVertical();}, this->id);
330  } else if (type == "horizontal") {
331  EM_ASM_ARGS({js.objects[$0] = d3.linkHorizontal();}, this->id);
332  } else {
333  std::cout << "WARNING: Invalid link type" << std::endl;
334  EM_ASM_ARGS({js.objects[$0] = d3.linkVertical();}, this->id);
335  }
336  }
337 
338  // Handles setting source accessor to a function or string
339  void SetSource(std::string source) {
340  D3_CALLBACK_METHOD_1_ARG(source, source.c_str())
341  }
342 
344  // Handles setting source to a constant
345  template <typename T>
346  typename std::enable_if<std::is_fundamental<T>::value, void>::type
347  SetSource(T source) {
348  EM_ASM_ARGS({js.objects[$0].source($1);}, this->id, source);
349  }
350 
351  // handles C++ functions
352  template <typename T>
354  SetSource(T source) {
356  }
357 
359 
360  //Handles setting target accessor to a function or string
361  void SetTarget(std::string target) {
362  D3_CALLBACK_METHOD_1_ARG(target, target.c_str())
363  }
364 
366 
367  // Handles constants
368  template <typename T>
369  typename std::enable_if<std::is_fundamental<T>::value, void>::type
370  SetY(T target) {
371  EM_ASM_ARGS({js.objects[$0].target($1);}, this->id, target);
372  }
373 
374  // handles C++ functions
375  template <typename T>
377  SetY(T target) {
379  }
380 
382  };
383 
385  class AreaGenerator : public LineGenerator {
386  public:
388  EM_ASM_ARGS({
389  var new_line = d3.area();
390  js.objects[$0] = new_line;
391  }, this->id);
392  }
393 
394  //Handles setting x0 accessor to a constant
395  template <typename T>
396  void SetX0(T x) {
397  EM_ASM_ARGS({js.objects[$0].x0($1);}, this->id, x);
398  }
399 
400  //Handles setting y0 accessor to a constant
401  template <typename T>
402  void SetY0(T y) {
403  EM_ASM_ARGS({js.objects[$0].y0($1);}, this->id, y);
404  }
405 
406  //Handles setting x0 accessor to a function or string
407  void SetX0(std::string x) {
408  D3_CALLBACK_METHOD_1_ARG(x0, x.c_str())
409  }
410 
411  //Handles setting y0 accessor to a function or string
412  void SetY0(std::string y) {
413  D3_CALLBACK_METHOD_1_ARG(y0, y.c_str())
414  }
415 
416  //Handles setting x1 accessor to a constant
417  template <typename T>
418  void SetX1(T x) {
419  EM_ASM_ARGS({js.objects[$0].x1($1);}, this->id, x);
420  }
421 
422  //Handles setting y1 accessor to a constant
423  template <typename T>
424  void SetY1(T y) {
425  EM_ASM_ARGS({js.objects[$0].y1($1);}, this->id, y);
426  }
427 
428  //Handles setting x1 accessor to a function or string
429  void SetX1(std::string x) {
430  D3_CALLBACK_METHOD_1_ARG(x1, x.c_str())
431  }
432 
433  //Handles setting y1 accessor to a function or string
434  void SetY1(std::string y) {
435  D3_CALLBACK_METHOD_1_ARG(y1, y.c_str())
436  }
437  };
438 
440  public:
442  EM_ASM_ARGS({
443  var new_line = d3.radialLine();
444  js.objects[$0] = new_line;
445  }, this->id);
446  }
447 
448  void SetRadius(float radius) {
449  EM_ASM_ARGS({js.objects[$0].radius($1);}, this->id, radius);
450  }
451 
452  void SetRadius(std::string radius) {
453  D3_CALLBACK_METHOD_1_ARG(radius, radius.c_str())
454  }
455 
456  void SetAngle(float angle) {
457  EM_ASM_ARGS({js.objects[$0].angle($1);}, this->id, angle);
458  }
459 
460  void SetAngle(std::string angle) {
461  D3_CALLBACK_METHOD_1_ARG(angle, angle.c_str())
462  }
463  };
464 
466  public:
468  EM_ASM_ARGS({
469  var new_line = d3.radialArea();
470  js.objects[$0] = new_line;
471  }, this->id);
472  }
473 
474  void SetInnerRadius(float radius) {
475  EM_ASM_ARGS({js.objects[$0].innerRadius($1);}, this->id, radius);
476  }
477 
478  void SetInnerRadius(std::string radius) {
479  D3_CALLBACK_METHOD_1_ARG(innerRadius, radius.c_str())
480  }
481 
482  void SetOuterRadius(float radius) {
483  EM_ASM_ARGS({js.objects[$0].outerRadius($1);}, this->id, radius);
484  }
485 
486  void SetOuterRadius(std::string radius) {
487  D3_CALLBACK_METHOD_1_ARG(outerRadius, radius.c_str())
488  }
489 
490  void SetStartAngle(float angle) {
491  EM_ASM_ARGS({js.objects[$0].startAngle($1);}, this->id, angle);
492  }
493 
494  void SetStartAngle(std::string angle) {
495  D3_CALLBACK_METHOD_1_ARG(startAngle, angle.c_str())
496  }
497 
498  void SetEndAngle(float angle) {
499  EM_ASM_ARGS({js.objects[$0].endAngle($1);}, this->id, angle);
500  }
501 
502  void SetEndAngle(std::string angle) {
503  D3_CALLBACK_METHOD_1_ARG(endAngle, angle.c_str())
504  }
505  };
506 
508  public:
510  EM_ASM_ARGS({
511  var new_line = d3.ribbon();
512  js.objects[$0] = new_line;
513  }, this->id);
514  }
515 
516  template <typename T>
517  void SetSource(T source) {
518  EM_ASM_ARGS({js.objects[$0].source($1);}, this->id, source);
519  }
520 
521  void SetSource(std::string source) {
522  D3_CALLBACK_METHOD_1_ARG(source, source.c_str())
523  }
524 
525  template <typename T>
526  void SetTarget(T target) {
527  EM_ASM_ARGS({js.objects[$0].target($1);}, this->id, target);
528  }
529 
530  void SetTarget(std::string target) {
531  D3_CALLBACK_METHOD_1_ARG(target, target.c_str())
532  }
533  };
534 
536  public:
538  EM_ASM_ARGS({
539  var new_line = d3.arc();
540  js.objects[$0] = new_line;
541  }, this->id);
542  }
543 
544  void SetCornerRadius(float radius) {
545  EM_ASM_ARGS({js.objects[$0].cornerRadius($1);}, this->id, radius);
546  }
547 
548  void SetCornerRadius(std::string radius) {
549  D3_CALLBACK_METHOD_1_ARG(cornerRadius, radius.c_str())
550  }
551 
552  void SetPadRadius(float radius) {
553  EM_ASM_ARGS({js.objects[$0].padRadius($1);}, this->id, radius);
554  }
555 
556  void SetPadRadius(std::string radius) {
557  D3_CALLBACK_METHOD_1_ARG(padRadius, radius.c_str())
558  }
559 
560  void SetPadAngle(float angle) {
561  EM_ASM_ARGS({js.objects[$0].padAngle($1);}, this->id, angle);
562  }
563 
564  void SetPadAngle(std::string angle) {
565  D3_CALLBACK_METHOD_1_ARG(padAngle, angle.c_str())
566  }
567 
568  //TODO: Centroid (requires passing array back)
569 
570  };
571 
572 }
573 
574 #endif
void SetX0(std::string x)
Definition: svg_shapes.h:407
void SetTarget(std::string target)
Definition: svg_shapes.h:530
void SetPadRadius(float radius)
Definition: svg_shapes.h:552
Definition: array.h:42
void SetOuterRadius(std::string radius)
Definition: svg_shapes.h:486
void SetTarget(T target)
Definition: svg_shapes.h:526
void SetDefined(std::string defined)
Definition: svg_shapes.h:173
REAL_TYPE sfinae_decoy
Definition: meta.h:93
Definition: dataset.h:23
Selection DrawShape(Dataset data, Selection s)
DrawShape will also accept a D3::Dataset.
Definition: svg_shapes.h:65
void SetX1(std::string x)
Definition: svg_shapes.h:429
void SetX(std::string x)
Definition: svg_shapes.h:254
void SetStartAngle(std::string angle)
Definition: svg_shapes.h:494
void SetY1(T y)
Definition: svg_shapes.h:424
RadialAreaGenerator()
Definition: svg_shapes.h:467
ChordGenerator()
Definition: svg_shapes.h:509
void SetEndAngle(std::string angle)
Definition: svg_shapes.h:502
#define D3_CALLBACK_METHOD_CPP_FUNCTION_1_ARG(FUNC, CPP_FUN)
Definition: utils.h:132
Definition: d3_init.h:43
void AddXScale(X_SCALE_TYPE &scale)
Definition: svg_shapes.h:202
DERIVED & SetAttr(std::string name, std::string value)
Definition: selection.h:208
Definition: svg_shapes.h:31
BaseLineGenerator()
Definition: svg_shapes.h:154
Definition: svg_shapes.h:439
data
A set of modifiers are available do describe DataNode.
Definition: DataNode.h:38
void SetTarget(std::string target)
Definition: svg_shapes.h:361
int id
Definition: d3_init.h:45
RadialLineGenerator()
Definition: svg_shapes.h:441
SymbolGenerator()
Definition: svg_shapes.h:92
Definition: svg_shapes.h:507
void SetInnerRadius(float radius)
Definition: svg_shapes.h:474
void SetX1(T x)
Definition: svg_shapes.h:418
Selection Select(std::string selector)
Definition: selection.h:1670
void SetPadAngle(std::string angle)
Definition: svg_shapes.h:564
Selection DrawShape(emp::array< emp::array< emp::array< T, 2 >, SIZE >, SIZE2 > &data)
If you pass a triple-nested array, it will be treated as an array of paths.
Definition: svg_shapes.h:77
void SetEndAngle(float angle)
Definition: svg_shapes.h:498
void SetSource(std::string source)
Definition: svg_shapes.h:339
LineGenerator()
Definition: svg_shapes.h:189
An area is defined by two lines, with the area in between shaded.
Definition: svg_shapes.h:385
static const PrintStr endl("<br>")
Pre-define emp::endl to insert a "<br>" and thus acting like a newline.
Tools for scaling graph axes in D3.
void SetCornerRadius(float radius)
Definition: svg_shapes.h:544
Definition: svg_shapes.h:325
LinkGenerator(std::string type)
Definition: svg_shapes.h:327
std::string Generate(emp::array< emp::array< T, 2 >, SIZE > &data)
Definition: svg_shapes.h:40
void SetY(std::string y)
Definition: svg_shapes.h:301
Generator for regular old (cartesian) lines.
Definition: svg_shapes.h:187
void SetSource(T source)
Definition: svg_shapes.h:517
Definition: selection.h:936
void AddYScale(Y_SCALE_TYPE &scale)
Definition: svg_shapes.h:218
void SetSource(std::string source)
Definition: svg_shapes.h:521
void SetY1(std::string y)
Definition: svg_shapes.h:434
void SetRadius(std::string radius)
Definition: svg_shapes.h:452
Definition: svg_shapes.h:90
void SetRadius(float radius)
Definition: svg_shapes.h:448
void SetAngle(std::string angle)
Definition: svg_shapes.h:460
void SetSize(int size)
Definition: svg_shapes.h:127
void SetType(std::string type)
Definition: svg_shapes.h:102
Definition: svg_shapes.h:535
ArcGenerator()
Definition: svg_shapes.h:537
void SetX0(T x)
Definition: svg_shapes.h:396
#define emp_assert(...)
Definition: assert.h:199
Definition: axis.h:20
AreaGenerator()
Definition: svg_shapes.h:387
void SetStartAngle(float angle)
Definition: svg_shapes.h:490
#define D3_CALLBACK_METHOD_1_ARG(FUNC, ARG1)
Definition: utils.h:115
void SetOuterRadius(float radius)
Definition: svg_shapes.h:482
Definition: svg_shapes.h:152
SvgShapeGenerator()
Definition: svg_shapes.h:33
void SetInnerRadius(std::string radius)
Definition: svg_shapes.h:478
Definition: svg_shapes.h:465
void SetPadRadius(std::string radius)
Definition: svg_shapes.h:556
void SetY0(std::string y)
Definition: svg_shapes.h:412
void SetPadAngle(float angle)
Definition: svg_shapes.h:560
Selection Append(std::string name)
Append DOM element(s) of the type specified by [name] to this selection.
Definition: selection.h:1417
Selection DrawShape(emp::array< emp::array< T, 2 >, SIZE > &data, Selection &s)
Definition: svg_shapes.h:58
Tools to maintain data in D3.
int GetID() const
Definition: d3_init.h:96
void SetCurve(std::string curve)
Definition: svg_shapes.h:159
void pass_array_to_javascript(C values)
Definition: js_utils.h:212
void SetAngle(float angle)
Definition: svg_shapes.h:456
void SetCornerRadius(std::string radius)
Definition: svg_shapes.h:548
void SetTension(float tension)
Definition: svg_shapes.h:165
void SetY0(T y)
Definition: svg_shapes.h:402