This is a simple demo to show you how I integrate React and d3 force layout.
React + D3 exploration with the force layout:
- React in charge of everything except location
- D3 only care about location
Pro:
- Able to do large scale of data.
| /** | |
| my naive hook | |
| - in the hook itself I always instantiate an observer instance, otherwise I dont know where to hold it | |
| - also I pass in a sepefic callback used just for the current comp | |
| - the callback detects if is intersecting, if so call a function right in side the component scope, and also unobserve if trigger only once | |
| I do this because I feel like everything is local, and can only be assessed locally |
| /*--------------------------------QUESTION--------------------------------- | |
| An api called to receipt check items return an array like this (simplified mock data) | |
| const checkItems = [ | |
| { | |
| longName: 'Classic Burger', | |
| basePrice: 3.25, | |
| posItemId: 1, | |
| parentItemId: 0, | |
| }, |
This is a simple demo to show you how I integrate React and d3 force layout.
React + D3 exploration with the force layout:
Pro:
| //1. it is stateful because it knows whether the React Component should update | |
| function makeSelectorStateful(selector, store) { | |
| // wrap the selector in an object that tracks its results between runs. | |
| const statefulSelector = { | |
| run: function (props) { | |
| const nextProps = selector(store.getState(), props); | |
| //but it set shouldComponentUpdate to true if it is a different from previous one | |
| if (nextProps !== statefulSelector.props) { | |
| //update info for React | |
| statefulSelector.shouldComponentUpdate = true; |
| //a factory function that return selector based on the mapping function and store.dispatch method | |
| //the return selector can then use the mapping function to convert the nextState and ownProps to the mergedProps | |
| function selectorFactory(dispatch, mapStateToProps, mapDispatchToProps) { | |
| //cache the DIRECT INPUT for the selector | |
| //the store state | |
| let state | |
| //the container's own props | |
| let ownProps | |
| //cache the itermediate results from mapping functions |
| import React from 'react' | |
| import { PropTypes } from 'react' | |
| const storeShape = PropTypes.shape({ | |
| subscribe: PropTypes.func.isRequired, | |
| dispatch: PropTypes.func.isRequired, | |
| getState: PropTypes.func.isRequired | |
| }) | |
| const subscriptionShape = PropTypes.shape({ | |
| trySubscribe: PropTypes.func.isRequired, | |
| notifyNestedSubs: PropTypes.func.isRequired |
| function connectHOC(mapStateToProps, mapDispatchToProps) { | |
| return function wrapWithConnect(WrappedComponent) { | |
| class Connect extends Component { | |
| constructor(props, context) { | |
| super(props, context) | |
| this.store = context.store | |
| this.initSelector() | |
| // ...subscribtion | |
| } | |
| initSelector() { |
| function connectHOC(mapStateToProps, mapDispatchToProps) { | |
| return function wrapWithConnect(WrappedComponent) { | |
| class Connect extends Component { | |
| constructor(props, context) { | |
| super(props, context) | |
| this.store = context.store //access store from context | |
| //get parent's Subscription instance from context | |
| const parentSub = this.context.parentSub | |
| //init its own Subscription instance based on the parent's Subscription | |
| this.subscription = new Subscription(this.store, parentSub, this.onStateChange.bind(this)) |
| class Subscription { | |
| constructor(store, parentSub, onStateChange) { | |
| this.store = store //global store from context | |
| this.parentSub = parentSub //parentSub from context | |
| this.onStateChange = onStateChange //its own listener | |
| this.subscribed = false //a flag for testing whether itself has been subscribed | |
| this.listeners = [] //nested subscription listeners subscribe here | |
| } | |
| //notify the listeners subscribed to itself | |
| notifyNestedSubs() { |
| import React, { PropTypes } from 'react' | |
| const storeShape = PropTypes.shape({ | |
| subscribe: PropTypes.func.isRequired, | |
| dispatch: PropTypes.func.isRequired, | |
| getState: PropTypes.func.isRequired | |
| }) | |
| const subscriptionShape = PropTypes.shape({ | |
| trySubscribe: PropTypes.func.isRequired, |