Work with D3.js and Immutable.js

In my application, I use D3.js for some visualizations.

Now D3 works with mutable JavaScript data structures.

Therefore, working with Immutable.js will require some sorting of the data.

I also use Reflux with React, so in my store I manage an immutable card. Since this map becomes a new thing with every change, I can’t just transfer it to D3 Force Layout, because it works with mutable data, so every time it recalculates everything from scratch.

As a result, I get control of both immutable and volatile data structures, but this seems very wrong.

I found the article Practical Time Series Visualization Using D3 + OM , which seems to touch on this topic and suggests using cursors. The problem is that it uses Clojure (Script) when I use only JavaScript.

I understand that this is very abstract without code examples, but any suggestions on the topic of work / synchronization of both immutable and mutable data will be appreciated!

+6
source share
3 answers

I see no reason why d3.js should not work with immutable.js. In my opinion, the key point is understanding how d3.js processes data, especially how d3.js data works.

Data merging - how data is bound to DOM elements in d3.js

Each time nodes are selected d3.selectAll('div') and connected to .data([1, 3, 5, 9]) , d3.js compares if existing div elements are bound to data elements. This is done by evaluating whether the selected DOM node div __data__ property. The data strong> property is set and supported by d3.js. By default, the index inside the joined array is what goes into __data__ . But you can also define a key function to override this behavior.

Further reading

How the election works , in which Mike Bostock explains how d3.js calculates enter , update, and exit through the data binding mechanism described above.

+3
source

In my opinion, it is important to first understand the problem.

I assume that you are dealing with some D3 functions that mutate the transferred data, for example d3-force , and the data is the state of your applications, for example, if you use Immutable.js with React and Redux.

The problem is that D3 has no way of knowing how to process Immutable.js data. Even if you find a way to get D3, it will not be a good idea, because it is not effective in the case of d3-force , when on each tick it will create a new immutable .

So, I suggest storing your state in a simple JavaScript array or object for interacting with D3.

For example, suppose you have a graph, and when you add a node, you send some action ( ADD_NODE ) to your store, and you may have a handler that updates your immutable state, such as reducers in Redux. You want to create another reducer that takes this node and returns plain [...nodes] . The same goes for other CRUD actions. This way your data will be synchronized. For example, if a user clicks on any of your nodes, you can get the source data for the index and all the D3 mutations saved.

Here is an example if you are using Redux. Hope this helps in collecting ideas.

 const graphNodesReducer = (state = [], action) => { if (action.type in nodeTypes) { return [...state, action.payload]; // or [...state, action.payload.toJS()] if node is sent as immutable // or [...state, action.payload.get('label')] you can choose what to set } return state; } 
+1
source

Now there is own JavaScript React Cursors .

So, you can repeat what the Practical Time Series with D3 + OM offers.

0
source

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


All Articles