I tried to imitate your problem 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; });
.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 diagrams one by one and calculate their width and height as follows:
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 is as follows:
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; ...
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 display only one graph, it also works fine without changing the code, because we calculate the width of the diagram as the width of the 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; });
.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 goes for the three diagrams:
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; });
.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>
source share