Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

D3 wrapper dev amlalejini #294

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
File renamed without changes.
File renamed without changes.
9,504 changes: 9,504 additions & 0 deletions source/web/d3-old/d3.js

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions source/web/d3-old/d3.min.js

Large diffs are not rendered by default.

259 changes: 259 additions & 0 deletions source/web/d3-old/d3_init.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,259 @@
#ifndef D3_INIT_H
#define D3_INIT_H

#include <iostream>

#include "../../base/errors.h"
#include "../init.h"
#include "../JSWrap.h"
#include "utils.h"

// #ifdef __EMSCRIPTEN__
// extern "C" {
// extern void D3_Initialize();
// }
// #endif

namespace D3 {


// #ifdef __EMSCRIPTEN__
// static void InitD3() {
// static bool init = false;
// if (!init) {
// D3_Initialize();
// init = true;
// }
// }
//
// #endif

int NextD3ID() {
return EM_ASM_INT_V({
id = js.next_id++;
js.counts[id] = 0;
js.objects[id] = -1;
return id;
});
}

/// A base object that all D3 objects inherit from. Handles storing the object in Javascript
/// You probably don't want to instantiate this directly

class D3_Base {
protected:
int id;

/// Default constructor - adds placeholder to js.objects array in Javascript
D3_Base(){
this->id = NextD3ID();
// std::cout << "Default constructor: " << this->id << std::endl;
EM_ASM_ARGS({
js.counts[$0] = 1;
}, this->id);
}

/// Construct an object pointing to a pre-determined location in js.objects.
/// Warning: This trusts that you know what you're doing in choosing an id.
D3_Base(int id){
this->id = id;
// std::cout << "Int constructor: " << id << std::endl;
emp_assert(EM_ASM_INT({return $0 in js.counts;}, this->id));

EM_ASM_ARGS({
js.counts[$0]++;
}, this->id);
}

D3_Base(const D3_Base & other) {
//TODO: Make this a deep copy
// std::cout << "Copying: " << other.id << std::endl;
this->id = other.id;
EM_ASM_ARGS({js.counts[$0]++;}, this->id);
}

D3_Base& operator= (const D3_Base & other) {
// std::cout << "Calling assingment: " << this->id << " " << other.id << std::endl;
this->id = other.id;
EM_ASM_ARGS({js.counts[$0]++;}, this->id);
return (*this);
}

~D3_Base() {
// std::cout << "Destructing: " <<this->id << std::endl;
EM_ASM_ARGS({
js.counts[$0]--;
if (js.counts[$0] == 0) {
// console.log("Deleting: ", $0);
delete js.objects[$0];
delete js.counts[$0];
}
}, this->id);
}

public:
// Get this object's ID (i.e. it's location in the js.objects array in Javascript)
int GetID() const {
return this->id;
}

void Log() const {
EM_ASM_ARGS({console.log($0+":", js.objects[$0]);}, id);
}
};

/// Create a tooltup using the d3.tip Javascript library
class ToolTip : public D3_Base {
public:
/// Default constructor - displays whatever data is bound on mouseover
ToolTip() {
EM_ASM_ARGS({
js.objects[$0] = d3.tip().attr('class', 'd3-tip')
.offset([-10, 0])
.html(function(d, i) { return d; });
}, this->id);
}

/// Cosntructor that allows you to specify a function that returns the html for the tooltip.
/// As input, this function should take 3 parameters: the bound data, the index of this item
/// in the selection (int), and a placeholder (int).
///
/// Example:
///
/// `D3::FormatFunction rounded = D3::FormatFunction(".2f");
///
/// std::function<double, int, int)> tooltip_display =
/// [this](double d, int i, int k) {return "Data: " + to_string(rounded(d));}
///
/// D3::ToolTip tip = D3::ToolTip(tooltip_display);
///
/// D3::Selection example_selection = D3::SelectAll("circle");
///
/// example_selection.SetupToolTip(tip);'
///
/// Mousing over a circle in the example selection will display
/// "Data: " followed by the value of d, rounded to two decimal points.
ToolTip(std::string func) {
EM_ASM_ARGS({
var in_string = UTF8ToString($1);
if (typeof window["d3"][in_string] === "function"){
in_string = window["d3"][in_string];
} else if (typeof window["emp"][in_string] === "function"){
in_string = window["emp"][in_string];
} else if (typeof window[in_string] === "function"){
in_string = window[in_string];
}

js.objects[$0] = d3.tip().attr('class', 'd3-tip').offset([-10, 0]).html(in_string);
}, this->id, func.c_str());
}

/// @cond TEMPLATES
template <typename T>
ToolTip(T func) {
emp::JSWrap(func, emp::to_string(this->id)+"_html_func");
EM_ASM_ARGS({
js.objects[$0] = d3.tip().attr('class', 'd3-tip')
.offset([-10, 0])
.html(emp[$0+"_html_func"]);
}, id);

}
/// @endcond

void SetHtml(std::string func) {
EM_ASM_ARGS({
var in_string = UTF8ToString($1);
if (typeof window["d3"][in_string] === "function"){
in_string = window["d3"][in_string];
} else if (typeof window["emp"][in_string] === "function"){
in_string = window["emp"][in_string];
} else if (typeof window[in_string] === "function"){
in_string = window[in_string];
}

js.objects[$0].html(in_string);
}, this->id, func.c_str());
}

/// @cond TEMPLATES
template <typename T>
emp::sfinae_decoy<void, decltype(&T::operator())>
SetHtml(T func) {
emp::JSWrap(func, emp::to_string(id)+"_html_func");
EM_ASM_ARGS({js.objects[$0].html(emp[$0+"_html_func"]);}, id);
}
/// @endcond

};

/// A callable string d3.format() string formatting function
class FormatFunction : public D3_Base {
public:
FormatFunction(std::string format = "") {
EM_ASM_ARGS({
js.objects[$1] = d3.format(UTF8ToString($0));
}, format.c_str(), this->id);
}

std::string operator() (double d){
char * buffer = (char *) EM_ASM_INT({
var text = js.objects[$0]($1);
var buffer = Module._malloc(text.length+1);
Module.stringToUTF8(text, buffer, lengthBytesUTF8(text)+1);
return buffer;
}, this->id, d);
std::string result = std::string(buffer);
free(buffer);
return result;
}
};

/// Catch-all object for storing references to things created in JS
class JSObject : public D3_Base {
public:
JSObject(){;};
};

/// Wrapper for creating functions in javascript and calling them there
class JSFunction : public D3_Base {
public:
JSFunction() {;}
JSFunction(std::string name) {
int fail = EM_ASM_INT({
var fn = window["d3"][UTF8ToString($2)];
if (typeof fn === "function") {
js.objects[$0] = fn;
return 0;
} else {
var fn = window["emp"][UTF8ToString($2)];
if (typeof fn === "function") {
js.objects[$0] = fn;
return 0;
} else {
var fn = window[UTF8ToString($2)];
if (typeof fn === "function") {
js.objects[$0] = fn;
return 0;
}
}
}
return 1;
}, this->id, name.c_str());

if (fail) {
emp::NotifyWarning("Invalid function name passed to JSFunction");
}
}

/// Only works if function has no arguments or returns
void operator() () {
EM_ASM_ARGS({
js.objects[$0]();
}, this->id);
}

};
}

#endif
File renamed without changes.
File renamed without changes.
File renamed without changes.
12 changes: 12 additions & 0 deletions source/web/d3-old/library_d3.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
var D3Library = {
$js: {objects:{}, counts:{}, next_id:0},
n_objects: function(){
return js.objects.length;
},
// D3_Initialize: function() {
// $.getScript('d3.min.js', function(data, textStatus) { console.log("yay", textStatus); return true ;});
// },
};

autoAddDeps(D3Library, '$js');
mergeInto(LibraryManager.library, D3Library);
File renamed without changes.
File renamed without changes.
File renamed without changes.
Loading