2

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?

1 Answer 1

2

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);
  }
}
Sign up to request clarification or add additional context in comments.

1 Comment

I've been using Recharts with great success. If your charts are simple and conventional, Recharts is the way to go (since it's the most React-esque solution). Otherwise, like Ashitika says, you'll have to render using d3 "natively" via componentDidMount.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.