Empirical
dataset.h
Go to the documentation of this file.
1 
10 #ifndef EMP_D3_LOAD_DATA_H
11 #define EMP_D3_LOAD_DATA_H
12 
13 #include <functional>
14 
15 #include "d3_init.h"
16 
17 #include "../JSWrap.h"
18 #include "../js_utils.h"
19 #include "../../tools/string_utils.h"
20 
21 namespace D3 {
22 
23  class Dataset : public D3_Base {
24  public:
25  Dataset(){;};
26  Dataset(int i) : D3_Base(i) {;};
27 
29  EM_ASM({js.objects[$0] = emp.__incoming_data;}, this->id);
30  };
31 
32  template <typename T>
34  Min(T comp) {
35  uint32_t fun_id = emp::JSWrap(comp, "", false);
36 
37  double min = EM_ASM_DOUBLE({
38  return d3.min(js.objects[$0], function(d) {return emp.Callback($1, d);});
39  }, this->id, fun_id);
40 
41  emp::JSDelete(fun_id);
42 
43  return min;
44  }
45 
46  template <typename T>
48  Max(T comp) {
49  uint32_t fun_id = emp::JSWrap(comp, "", false);
50 
51  double max = EM_ASM_DOUBLE({
52  return d3.max(js.objects[$0], function(d) {return emp.Callback($1, d);});
53  }, this->id, fun_id);
54 
55  emp::JSDelete(fun_id);
56 
57  return max;
58  }
59 
60 
61  };
62 
63 
64  class JSONDataset : public Dataset {
65  public:
66  //This should probably be static, but emscripten complains when it is
68 
69  JSONDataset(int i) : Dataset(i) {;}
71  EM_ASM_ARGS({js.objects[$0] = [];}, this->id);
72 
73  //Useful function for dealing with nested JSON data structures
74  //Assumes nested objects are stored in an array called children
75  EM_ASM_ARGS({
76  //Inspired by Niels' answer to
77  //http://stackoverflow.com/questions/12899609/how-to-add-an-object-to-a-nested-javascript-object-using-a-parent-id/37888800#37888800
78  js.objects[$0] = function(root, id) {
79  if (root.name == id){
80  return root;
81  }
82  if (root.children) {
83  for (var k in root.children) {
84  if (root.children[k].name == id) {
85  return root.children[k];
86  }
87  else if (root.children[k].children) {
88  result = js.objects[$0](root.children[k], id);
89  if (result) {
90  return result;
91  }
92  }
93  }
94  }
95  };
96  }, FindInHierarchy.GetID());
97  };
98 
99  void LoadDataFromFile(std::string filename) {
100  EM_ASM_ARGS ({
101  d3.json(Pointer_stringify($1), function(data){js.objects[$0]=data;});
102  }, id, filename.c_str());
103  }
104 
105  template <typename DATA_TYPE>
106  void LoadDataFromFile(std::string filename, std::function<void(DATA_TYPE)> fun) {
107  emp::JSWrap(fun, "__json_load_fun__"+emp::to_string(id));
108 
109  EM_ASM_ARGS ({
110  d3.json(Pointer_stringify($1), function(data){
111  js.objects[$0]=data;
112  emp["__json_load_fun__"+$0](data);
113  });
114  }, id, filename.c_str());
115  }
116 
117  void LoadDataFromFile(std::string filename, std::function<void(void)> fun) {
118  emp::JSWrap(fun, "__json_load_fun__"+emp::to_string(id));
119  std::cout << filename.c_str() << std::endl;
120  EM_ASM_ARGS ({
121  var filename = Pointer_stringify($1);
122  d3.json(filename, function(data){
123  js.objects[$0]=data;
124  console.log(filename, data);
125  emp["__json_load_fun__"+$0]();
126  });
127  }, id, filename.c_str());
128  }
129 
130 
131  void Append(std::string json) {
132  EM_ASM_ARGS({
133  js.objects[$0].push(JSON.parse(Pointer_stringify($1)));
134  }, this->id, json.c_str());
135  }
136 
137  void AppendNested(std::string json) {
138 
139  int fail = EM_ASM_INT({
140 
141  var obj = JSON.parse(Pointer_stringify($2));
142 
143  var result = null;
144  for (var i in js.objects[$0]) {
145  result = js.objects[$1](js.objects[$0][i], obj.parent);
146  if (result) {
147  break;
148  }
149  }
150  if (!result) {
151  return 1;
152  }
153  result.children.push(obj);
154  return 0;
155  }, this->id, FindInHierarchy.GetID(), json.c_str());
156 
157  if (fail) {
158  emp::NotifyWarning("Append to JSON failed - parent not found");
159  }
160  }
161 
162  //Appends into large trees can be sped up by maintaining a list of
163  //possible parent nodes
164  int AppendNestedFromList(std::string json, JSObject & options) {
165  int pos = EM_ASM_INT({
166  var parent_node = null;
167  var pos = -1;
168  var child_node = JSON.parse(Pointer_stringify($1));
169  for (var item in js.objects[$0]) {
170  if (js.objects[$0][item].name == child_node.parent) {
171  parent_node = js.objects[$0][item];
172  pos = item;
173  break;
174  }
175  }
176 
177  if (!parent_node.hasOwnProperty("children")){
178  parent_node.children = [];
179  }
180  parent_node.children.push(child_node);
181  return pos;
182  }, options.GetID(), json.c_str());
183 
184  return pos;
185  }
186 
187  };
188 
189  class CSVDataset : public Dataset {
190  public:
192  CSVDataset(int i) : Dataset(i) {;}
193 
194 
195  void LoadDataFromFile(std::string location, std::string callback, bool header=true) {
196  EM_ASM_ARGS({
197  var acc = function(d){
198  return ([+d[0], +d[1]]);
199  };
200 
201  var arg1 = Pointer_stringify($0);
202  var in_string = Pointer_stringify($1);
203  if (typeof window[in_string] === "function"){
204  in_string = window[in_string];
205  } else if (typeof window["d3"][in_string] === "function") {
206  in_string = window["d3"][in_string];
207  } else if (typeof window["emp"][in_string] === "function") {
208  in_string = window["emp"][in_string];
209  }
210 
211  if ($3) {
212  d3.csv(arg1, acc, function(d){
213  js.objects[$2] = d;
214  in_string($2);
215  });
216  } else {
217  d3.text(arg1, function(d){
218  js.objects[$2] = d3.csvParseRows(d, acc);
219  in_string($2);
220  });
221  }
222  }, location.c_str(), callback.c_str(), this->id, header);
223  }
224 
225  void Parse(std::string contents, std::string accessor){
226  D3_CALLBACK_FUNCTION_2_ARGS(d3.csvParse, contents.c_str(), \
227  accessor.c_str())
228  }
229 
230  void ParseRows(std::string contents, std::string accessor){
231  D3_CALLBACK_FUNCTION_2_ARGS(d3.csvParseRows, contents.c_str(), \
232  accessor.c_str())
233  }
234 
236  template <std::size_t N, typename T>
238  EM_ASM_ARGS({
239  emp_i.__outgoing_array = js.objects[$0][js.objects[$0].length - 1];
240  }, GetID());
242  }
243 
244  //TODO Format and FormatRows
245 
246  };
247 
248 };
249 
250 
251 #endif
void LoadDataFromFile(std::string filename, std::function< void(DATA_TYPE)> fun)
Definition: dataset.h:106
Definition: array.h:42
std::string to_string(ALL_TYPES &&...all_values)
Definition: string_utils.h:511
REAL_TYPE sfinae_decoy
Definition: meta.h:93
Definition: dataset.h:23
void LoadDataFromFile(std::string filename, std::function< void(void)> fun)
Definition: dataset.h:117
void ParseRows(std::string contents, std::string accessor)
Definition: dataset.h:230
Definition: d3_init.h:43
void LoadDataFromFile(std::string location, std::string callback, bool header=true)
Definition: dataset.h:195
emp::sfinae_decoy< double, decltype(&T::operator())> Min(T comp)
Definition: dataset.h:34
JSONDataset()
Definition: dataset.h:70
void LoadDataFromFile(std::string filename)
Definition: dataset.h:99
Catch-all object for storing references to things created in JS.
Definition: d3_init.h:213
CSVDataset()
Definition: dataset.h:191
data
A set of modifiers are available do describe DataNode.
Definition: DataNode.h:38
int id
Definition: d3_init.h:45
JSONDataset(int i)
Definition: dataset.h:69
Definition: dataset.h:189
emp::sfinae_decoy< double, decltype(&T::operator())> Max(T comp)
Definition: dataset.h:48
void pass_array_to_cpp(emp::array< T, SIZE > &arr, bool recurse=false)
Definition: js_utils.h:299
Dataset()
Definition: dataset.h:25
static const PrintStr endl("<br>")
Pre-define emp::endl to insert a "<br>" and thus acting like a newline.
void Parse(std::string contents, std::string accessor)
Definition: dataset.h:225
#define D3_CALLBACK_FUNCTION_2_ARGS(FUNC, CALLBACK, ARG1)
Definition: utils.h:78
void CaptureIncoming()
Definition: dataset.h:28
Wrapper for creating functions in javascript and calling them there.
Definition: d3_init.h:219
void GetLastRow(emp::array< T, N > &arr)
Put the last row of the array into arr.
Definition: dataset.h:237
JSFunction FindInHierarchy
Definition: dataset.h:67
void Append(std::string json)
Definition: dataset.h:131
void AppendNested(std::string json)
Definition: dataset.h:137
If we are in emscripten, make sure to include the header.
Definition: array.h:37
void NotifyWarning(Ts &&...msg)
End user has done something possibly a problem.
Definition: errors.h:141
Definition: axis.h:20
CSVDataset(int i)
Definition: dataset.h:192
Definition: dataset.h:64
int GetID() const
Definition: d3_init.h:96
Dataset(int i)
Definition: dataset.h:26
int AppendNestedFromList(std::string json, JSObject &options)
Definition: dataset.h:164