D3 and two-way data binding

I'm interested in modern best practices and solutions for using data-driven documents with two-way AJAX data bindings. In particular, I wonder how d3 is best integrated with libraries that support two-way data bindings such as Angular or Knockout .

Obvious conflicts arise because d3 and AJAX libs are inserting data into the DOM , which basically means you need to wrap another.

+6
source share
1 answer

DOM Details

You were worried about the data inserted in the DOM. Here are some of the added properties:

  • D3js: __data__ , __onmouseover.force , __onmouseout.force , __onmousedown.drag , __ontouchstart.drag , __onmousedown
  • AngularJS: value , type , version , align , ng339

So, there are no collisions and there is no need to wrap one in the other. You can verify this using Object.keys(SOME_DOM_ELEMENT); and Object.keys(SOME_DOM_ELEMENT.__proto__);

About implementation

Pure javascript

This is how you assign D3js data:

 d3selector.data( myNameSpace.myDataObject ); 

And this is my data binding approach using the clock: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/watch

 d3selector myNameSpace.watch('myDataObject', function (id, oldval, newval) { d3selector.data( newval ); return newval; }); 

That way, every time you change myNameSpace.myDataObject , the data used by D3js will also be updated. But this will only work on Firefox.

Angularjs

There is an Angular + d3.js answer in this question : data binding using SVG text attr? which explains how to do this using $ watch.

similar to a Firefox watch:

 directive('myDirective', function ( /* dependencies */ ) { // Imagine your $scope has myDataObject $scope.$watch('myDataObject', function (newVal, oldVal) { d3selector.data(newVal); }); } 

Now every time you change myDataObject to $scope , D3js data will also be updated.

More details

The following is an example of two-way data binding using polymer : http://bl.ocks.org/psealock/a4f1e24535f0353d91ea you can test it here: http://bl.ocks.org/psealock/raw/a4f1e24535f0353d91ea/

As you can see in refreshChart , the binding is not really used. Instead, in an event triggered by a data change, D3js loads the new data:

 this.g.data(this.pie(this.data)); 

D3js is not ready to listen to data changes unless you use the data method. This is why data already processed will not change.

If data bindings were bound in the future, I assume there will be a new method on selection :

selection.update - Returns placeholders for updated items.

similar to current enter and exit :

selection.enter - returns placeholders for missing items.

selection.exit - Returns items that are no longer needed.

Removing the need to create update features.

+2
source

Source: https://habr.com/ru/post/983646/


All Articles