score:2

Accepted answer

I tried to imitate your issue in the demo below.

class Chart extends React.Component {
  componentDidMount() {
  	var data = this.props.data;
		var containerDOMElementWidth = ReactDOM.findDOMNode(this).getBoundingClientRect().width
    var chartHeight = containerDOMElementWidth / 2;

		this.drawChart(data, containerDOMElementWidth, chartHeight);
  }
  
  drawChart(data, chartWidth, chartHeight) {
    var margin = { top: 30, right: 20, bottom: 30, left: 50 };

    var width = chartWidth - margin.left - margin.right;
    var height = chartHeight - margin.top - margin.bottom;

    var parseDate = d3.timeParse("%d-%b-%y");

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

    var xAxis = d3.axisBottom().scale(x)
        .ticks(2);

    var yAxis = d3.axisLeft().scale(y)
        .ticks(2);

    var valueline = d3.line()
        .x(function (d) {
          return x(d.date);
        })
        .y(function (d) {
          return y(d.close);
        });

    var svg = d3.select("body")
        .append("svg")
        .attr("width", width + margin.left + margin.right)
        .attr("height", height + margin.top + margin.bottom)
        .append("g")
        .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

    data.forEach(function (d) {
        d.date = parseDate(d.date);
        d.close = +d.close;
    });

    // Scale the range of the data
    x.domain(d3.extent(data, function (d) {
        return d.date;
        }));
    y.domain([0, d3.max(data, function (d) {
        return d.close;
        })]);

    svg.append("path").attr('class', 'line-chart') // Add the valueline path.
    .attr("d", valueline(data));

    svg.append("g") // Add the X Axis
    .attr("class", "x axis")
        .attr("transform", "translate(0," + height + ")")
        .call(xAxis);

    svg.append("g") // Add the Y Axis
    .attr("class", "y axis")
        .call(yAxis);
  }
  
  render() {
    return <div></div>;
  }
}

function getRandomData() {
	return [{
        date: "1-May-12",
        close: Math.random() * 90
    }, {
        date: "30-Apr-12",
        close: Math.random() * 90
    }, {
        date: "27-Apr-12",
        close: Math.random() * 90
    }, {
        date: "26-Apr-12",
        close: Math.random() * 90
    }, {
        date: "25-Apr-12",
        close: Math.random() * 90
    }];
}

ReactDOM.render(
  <div className="charts-container">
    <div className="chart-wrapper">
      <Chart data={getRandomData()} />
    </div>
        <div className="chart-wrapper">
      <Chart data={getRandomData()} />
    </div>
  </div>,
  document.getElementById('container')
);
.line-chart {
  fill: none;
  stroke: blue
}

.charts-container {
  display: flex;
}

.chart-wrapper {
  width: 100%;
}
<script src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.11.0/d3.min.js"></script>
<div id="container">
</div>

Here we draw two charts one by one and calculate their width and height this way:

componentDidMount() {
  var data = this.props.data;

  // gets the width of container div element with ReactDOM.findDOMNode
  var containerDOMElementWidth = ReactDOM.findDOMNode(this).getBoundingClientRect().width

  // chart height have to be a half of width 
  var chartHeight = containerDOMElementWidth / 2;

  // pass width and height as an arguments
  this.drawChart(data, containerDOMElementWidth, chartHeight);
}

Our drawChart method look like:

drawChart(data, chartWidth, chartHeight) {
  var margin = { top: 30, right: 20, bottom: 30, left: 50 };

  var width = chartWidth - margin.left - margin.right;
  var height = chartHeight - margin.top - margin.bottom;
  ... // code for the chart drawing 

render:

ReactDOM.render(
  <div className="charts-container">
    <div className="chart-wrapper">
      <Chart data={getRandomData()} />
    </div>
    <div className="chart-wrapper">
      <Chart data={getRandomData()} />
    </div>
  </div>,
  document.getElementById('container')
);

If we will render only one chart it also works fine without any code changing because of we calculate the width of the chart as width of parent div element:

class Chart extends React.Component {
  componentDidMount() {
  	var data = this.props.data;
		var containerDOMElementWidth = ReactDOM.findDOMNode(this).getBoundingClientRect().width
    var chartHeight = containerDOMElementWidth / 2;

		this.drawChart(data, containerDOMElementWidth, chartHeight);
  }
  
  drawChart(data, chartWidth, chartHeight) {
    var margin = { top: 30, right: 20, bottom: 30, left: 50 };

    var width = chartWidth - margin.left - margin.right;
    var height = chartHeight - margin.top - margin.bottom;

    var parseDate = d3.timeParse("%d-%b-%y");

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

    var xAxis = d3.axisBottom().scale(x)
        .ticks(2);

    var yAxis = d3.axisLeft().scale(y)
        .ticks(2);

    var valueline = d3.line()
        .x(function (d) {
          return x(d.date);
        })
        .y(function (d) {
          return y(d.close);
        });

    var svg = d3.select("body")
        .append("svg")
        .attr("width", width + margin.left + margin.right)
        .attr("height", height + margin.top + margin.bottom)
        .append("g")
        .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

    data.forEach(function (d) {
        d.date = parseDate(d.date);
        d.close = +d.close;
    });

    // Scale the range of the data
    x.domain(d3.extent(data, function (d) {
        return d.date;
        }));
    y.domain([0, d3.max(data, function (d) {
        return d.close;
        })]);

    svg.append("path").attr('class', 'line-chart') // Add the valueline path.
    .attr("d", valueline(data));

    svg.append("g") // Add the X Axis
    .attr("class", "x axis")
        .attr("transform", "translate(0," + height + ")")
        .call(xAxis);

    svg.append("g") // Add the Y Axis
    .attr("class", "y axis")
        .call(yAxis);
  }
  
  render() {
    return <div></div>;
  }
}

function getRandomData() {
	return [{
        date: "1-May-12",
        close: Math.random() * 90
    }, {
        date: "30-Apr-12",
        close: Math.random() * 90
    }, {
        date: "27-Apr-12",
        close: Math.random() * 90
    }, {
        date: "26-Apr-12",
        close: Math.random() * 90
    }, {
        date: "25-Apr-12",
        close: Math.random() * 90
    }];
}

ReactDOM.render(
  <div className="charts-container">
    <div className="chart-wrapper">
      <Chart data={getRandomData()} />
    </div>
  </div>,
  document.getElementById('container')
);
.line-chart {
  fill: none;
  stroke: blue
}

.charts-container {
  display: flex;
}

.chart-wrapper {
  width: 100%;
}
<script src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.11.0/d3.min.js"></script>
<div id="container">
</div>

The same thing for three charts:

class Chart extends React.Component {
  componentDidMount() {
  	var data = this.props.data;
		var containerDOMElementWidth = ReactDOM.findDOMNode(this).getBoundingClientRect().width
    var chartHeight = containerDOMElementWidth / 2;

		this.drawChart(data, containerDOMElementWidth, chartHeight);
  }
  
  drawChart(data, chartWidth, chartHeight) {
    var margin = { top: 30, right: 20, bottom: 30, left: 50 };

    var width = chartWidth - margin.left - margin.right;
    var height = chartHeight - margin.top - margin.bottom;

    var parseDate = d3.timeParse("%d-%b-%y");

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

    var xAxis = d3.axisBottom().scale(x)
        .ticks(2);

    var yAxis = d3.axisLeft().scale(y)
        .ticks(2);

    var valueline = d3.line()
        .x(function (d) {
          return x(d.date);
        })
        .y(function (d) {
          return y(d.close);
        });

    var svg = d3.select("body")
        .append("svg")
        .attr("width", width + margin.left + margin.right)
        .attr("height", height + margin.top + margin.bottom)
        .append("g")
        .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

    data.forEach(function (d) {
        d.date = parseDate(d.date);
        d.close = +d.close;
    });

    // Scale the range of the data
    x.domain(d3.extent(data, function (d) {
        return d.date;
        }));
    y.domain([0, d3.max(data, function (d) {
        return d.close;
        })]);

    svg.append("path").attr('class', 'line-chart') // Add the valueline path.
    .attr("d", valueline(data));

    svg.append("g") // Add the X Axis
    .attr("class", "x axis")
        .attr("transform", "translate(0," + height + ")")
        .call(xAxis);

    svg.append("g") // Add the Y Axis
    .attr("class", "y axis")
        .call(yAxis);
  }
  
  render() {
    return <div></div>;
  }
}

function getRandomData() {
	return [{
        date: "1-May-12",
        close: Math.random() * 90
    }, {
        date: "30-Apr-12",
        close: Math.random() * 90
    }, {
        date: "27-Apr-12",
        close: Math.random() * 90
    }, {
        date: "26-Apr-12",
        close: Math.random() * 90
    }, {
        date: "25-Apr-12",
        close: Math.random() * 90
    }];
}

ReactDOM.render(
  <div className="charts-container">
    <div className="chart-wrapper">
      <Chart data={getRandomData()} />
    </div>
        <div className="chart-wrapper">
      <Chart data={getRandomData()} />
    </div>
        <div className="chart-wrapper">
      <Chart data={getRandomData()} />
    </div>
  </div>,
  document.getElementById('container')
);
.line-chart {
  fill: none;
  stroke: blue
}

.charts-container {
  display: flex;
}

.chart-wrapper {
  width: 100%;
}
<script src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.11.0/d3.min.js"></script>
<div id="container">
</div>


Related Query

More Query from same tag