d3绑定到错误的组件实例的反应

时间:2017-02-06 04:51:21

标签: javascript reactjs d3.js

我有一个d3样本,我试图与react集成。组件应该将数组数组作为数据点(x是日期,y是浮点值)并渲染折线图。组件如下:

import React, {Component} from 'react';
import * as d3 from "d3";

export default class Chart extends Component {
  constructor(props){
    super(props);
  }

  componentDidMount(){
    this.buildLineChart(this.props.stock.dataset.data)
  }

  buildLineChart(data){
    var svg = d3.select("svg"),
              margin = {top: 20, right: 20, bottom: 30, left: 50},
              width = +svg.attr("width") - margin.left - margin.right,
              height = +svg.attr("height") - margin.top - margin.bottom,
              g = svg.append("g").attr("transform", "translate(" + margin.left + "," + margin.top + ")");

    var parseTime = d3.timeParse("%Y-%m-%d");

    var x = d3.scaleTime().rangeRound([0, width]);
    var y = d3.scaleLinear().rangeRound([height, 0]);

    var data = data.map(function(d){
      return [parseTime(d[0]), +d[1]]
    });

    var line = d3.line()
      .x(function(d){
        return x(d[0])
      })
      .y(function(d){
        return y(d[1]) 
      });

    x.domain(d3.extent(data, function(d) { return d[0]; }));
    y.domain(d3.extent(data, function(d) { return d[1]; }));

    g.append("g")
        .attr("transform", "translate(0," + height + ")")
        .call(d3.axisBottom(x))
        .select(".domain")
        .remove();

    g.append("g")
        .call(d3.axisLeft(y))
        .append("text")
        .attr("fill", "#000")
        .attr("transform", "rotate(-90)")
        .attr("y", 50)
        .attr("dy", "0.6em")
        .attr("text-anchor", "end");
        // .text("Price ($)");

    g.append("path")
        .datum(data)
        .attr("fill", "none")
        .attr("stroke", "steelblue")
        .attr("stroke-linejoin", "round")
        .attr("stroke-linecap", "round")
        .attr("stroke-width", 3)
        .attr("d", line);

  }

  render() {
    const divStyle = {
      backgroundColor: '#D8D8D8',
      borderStyle: 'solid',
      borderWidth: 'thin',
      borderRadius: '15px',
      marginLeft: '10px',
      marginRight: '10px'
    };

    return(
      <div className="form-group row col-sm-12" style={divStyle}>
          <div className="row" id="lineChartContainer">
            <svg width="768" height="300"></svg>
          </div>
      </div>
    );
  }
}

我有一个加载的默认组件,一切看起来都很好。但是,当我生成其他组件实例时,在渲染其他组件的同时,d3将新的折线图写在旧的顶部。我得到的是这样的情况: enter image description here

Facebook是默认组件并加载正常,但是当我尝试启动Netflix组件时,会生成实例,但NFLX图表会写在Facebook图表的顶部。是否有一个简单的约定来让d3绑定到它自己的组件实例?

1 个答案:

答案 0 :(得分:1)

你必须选择&#34; svg&#34;组件内的元素如下,

buildLineChart(data){
    var svg = d3.select(this.getDOMNode()).select("svg"),
    ....
}