在使用变量比例时将关注与React和D3分开

时间:2018-04-26 16:10:20

标签: javascript reactjs d3.js

我一直关注Shirley Wu's post about using React with D3并将问题分成单独的文件。我们的想法是visualisation文件夹中的模块处理D3属性。

在我的示例中,文件visualisation/node.js负责设置表示数据集的循环节点的属性。它们的位置应该基于它们的value属性和一个变量比例,它的域设置为数据值的范围。

比例本身是在加载数据的父组件中创建的,因此我没有看到任何传递方式。这到nodeViz.create,其中设置了节点属性(包括它们的位置)。我也不相信该功能/模块对数据集有任何意识,允许在node.js文件中重新创建比例。

使用比例尺来定位元素时,有没有办法实现这种分离?感觉我必须遗漏一些东西......

您可以see a version of this in codesandbox.io,但代码也在下面:

chart.js之

import React from "react";

import { extent, scaleLinear, select } from "d3";
import nodeViz from "./visualisation/node";

const width = 800;
const height = 500;

class Chart extends React.Component {
  data = [
    { id: 0, value: 4 },
    { id: 1, value: 0 },
    { id: 2, value: 7 },
    { id: 3, value: 5 },
    { id: 4, value: 2 }
  ];

  xScale = scaleLinear()
    .range([0, width])
    .domain(extent(this.data.map(d => d.value)));

  createChart = () => {
    // The following would normally happen on componentDidUpdate
    // when we have some new data via the props, but in this
    // case we're not async so the data will already exist.
    const svg = select(this.node);

    const nodes = svg.selectAll("circle").data(this.data, d => d.id);

    nodes.enter().call(nodeViz.create);
    nodes.exit().remove();
  };

  componentDidMount() {
    this.createChart();
  }

  render() {
    return (
      <svg ref={node => (this.node = node)} width={width} height={height}>
        <g />
      </svg>
    );
  }
}

export default Chart;

可视化/ node.js的

const create = selection => {
  return selection
    .append("circle")
    .attr("r", 3)
    .merge(selection)
    .attr("fill", "red")
    .attr("cx", d => d.value) // Should be xScale(d.value)
    .attr("cy", 150);
};

export default {
  create
};

1 个答案:

答案 0 :(得分:2)

我说实话,自从我写了这篇文章以来,我实际上有了一些新意见(尽管核心概念保持不变)已经这么多年了。在这种情况下,属性设置被分离出来,以便能够使用d3执行诸如转换/动画之类的操作(bc d3需要直接操作DOM,因此我们不想做出反应来跟踪它) 。你在秤中所拥有的是数据计算和渲染的分离,在这种情况下,我在渲染阶段之前完成数据计算。因此,在该示例中,数据计算happens in _onChange和呈现happens in renderGraphVisualization.update

如果我现在要这样做,我可能只是让React渲染所有东西(包括属性)或者让D3渲染所有东西(所以输入 - 更新 - 退出所有东西)。我在this talk中谈到了这一点。