user99999
user99999

Reputation: 2022

Integrating d3 chart with reactjs

I want to create three charts using d3 library - each having its own html. So I want to achieve something like this:

render: function () {
   var elements = [];
   for (var i in response) { // getting chart data from some API response
      elements.push(React.createElement(SingleChartsDOM, {data: response[i]});
      createSingleChart(response[i]);
   }
   return elements;
}

So I basically want chart header (SingleChartsDOM class) -> chart, chart header -> chart, chart header -> chart.

SingleChartsDOM only returns some react dom, it works properly. CreateSingleChart() function is d3 function:

createSingleChart: function (dataset) {
        var container = 'dashboardContent';
        var data = [];
        data = dataset.statistics;

        var margin = {top: 20, right: 0, bottom: 30, left: 60},
        ww = document.getElementById(container).clientWidth - 40,
                width = ww - margin.left - margin.right,
                height = 200 - margin.top - margin.bottom;

        var svg = d3.select('#' + container).append("div").attr("class", "chart").append("svg")
                .data(data)
                .attr("width", width + margin.left + margin.right)
                .attr("height", height + margin.top + margin.bottom)
                .append("g")
                .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

        x.domain(data.map(function (d) {
            return d.date.slice(5, 10);
        }));
        y.domain([0, d3.max(data, function (d) {
                return d.volume;
            })]);

        svg.append("g")
                .attr("class", "x axis")
                .call(xAxis);

        svg.append("g")
                .attr("class", "y axis")
                .call(yAxis)
                .append("text")
                .style("text-anchor", "end")
                .text("Volume");

        svg.selectAll(".bar")
                .data(data)
                .enter().append("rect")
                .attr("height", function (d) {
                    return height - y(d.volume);
                });

        function type(d) {
            d.volume = +d.volume;
            return d;
        }
}

The problem is that all of my html is created first, charts are created last. So I guess my appends don't happen in the loop, but rather the html is rendered first, and appends are executed after that.

How do I integrate this?

Upvotes: 2

Views: 157

Answers (1)

Ashitaka
Ashitaka

Reputation: 19203

D3 cannot be used like that. Either you use declarative charts like recharts, or you have to resort to componentDidMount, like this:

render() {
  return response.map(this.renderChart);
}

renderChart(data, index) {
  return (
    <div className="chartContainer" ref={"container-" + index}>
      <SingleChartsDOM data={data} />
    </div>
  );
}

componentDidMount() {
  for (var index in response) {
    var container, data;

    container = this.refs["container-" + index];
    data = response[index];
    createSingleChart(data, container);
  }
}

Upvotes: 2

Related Questions