はい、react-art があることは知っていますが、壊れているようです。
問題は、d3.js はすべてブラウザー DOM の変更に関するものであり、ブラウザー DOM へのすべての変更が React の仮想 DOM に反映されないため、それを直接 (たとえば componentDidMount メソッド内で) 使用すると正しく機能しないことです。何か案は?
はい、react-art があることは知っていますが、壊れているようです。
問題は、d3.js はすべてブラウザー DOM の変更に関するものであり、ブラウザー DOM へのすべての変更が React の仮想 DOM に反映されないため、それを直接 (たとえば componentDidMount メソッド内で) 使用すると正しく機能しないことです。何か案は?
戦略の 1 つは、React を更新させないブラックボックス コンポーネントを構築することです。コンポーネント ライフ サイクル メソッドshouldComponentUpdate()
は、再レンダリングが必要かどうかをコンポーネントが独自に判断できるようにすることを目的としています。このメソッドから常に戻る場合false
、React は子要素に飛び込むことはありません (つまり、 を呼び出さない限りforceUpdate()
)。そのため、これは React のディープ アップデート システムに対する一種のファイアウォールとして機能します。
への最初の呼び出しを使用してチャートのコンテナーを作成し、メソッドrender()
内で D3 を使用してチャート自体を描画します。componentDidMount()
あとは、React コンポーネントの更新に応じてチャートを更新するだけです。でそのようなことを行うべきではないかもしれませんが、先に進んでそこから D3 update を呼び出すことができない本当の理由はわかりません (React コンポーネントの のコードを参照してください)。shouldComponentUpdate()
_performUpdateIfNecessary()
したがって、コンポーネントは次のようになります。
React.createClass({
render: function() {
return <svg></svg>;
},
componentDidMount: function() {
d3.select(this.getDOMNode())
.call(chart(this.props));
},
shouldComponentUpdate: function(props) {
d3.select(this.getDOMNode())
.call(chart(props));
return false;
}
});
componentDidMount()
メソッド内(最初のレンダリング用) とメソッド内shouldComponentUpdate()
(以降の更新用) の両方でチャートを呼び出す必要があることに注意してください。また、コンポーネントのプロパティまたは状態をチャートに渡す方法が必要であり、それらがコンテキスト固有であることにも注意してください。最初のレンダリングでは、それらはすでにthis.props
およびthis.state
に設定されていますが、その後の更新では、新しいプロパティはまだ設定されていません。そのため、代わりに関数パラメーターを使用する必要があります。
こちらの jsfiddle を参照してください。
React は SVG 要素を直接レンダリングすることもできます。以下に例を示します: React.js と D3 を統合する方法
D3 はユーティリティとして使用できます。つまり、D3 を使用して DOM を変更しないでください。むしろ、スケールと軸には D3 を使用しますが、それらの D3 関数の出力を html/svg に補間します。
これが私のプロジェクトの例です。
scale = d3.time.scale()
.range([ 0, 100 ])
.clamp(true)
...小道具を介してコンポーネントに渡されます...
React.DOM.rect({
x: "#{props.scale(start)}%"
width: "#{Math.abs( props.scale(end) - props.scale(start)) }%"
})
ここで、D3 の選択ではなく、React がデータを要素にバインドします。