import * as d3 from 'd3'; const margin = { top: 20, right: 20, bottom: 50, left: 50 }, width = 960 - margin.left - margin.right, height = 500 - margin.top - margin.bottom; const parseTime = d3.timeParse('%Y-%m-%d'); data.forEach((d: any) => { d.date = parseTime(d.date); d.km = +d.km; }); const x = d3.scaleTime() .domain(d3.extent(data, d => d.date)) .range([0, width]); const y = d3.scaleLinear() .domain([0, d3.max(data, d => d.km)]) .range([height, 0]); const line = d3.line() .x(d => x(d.date)) .y(d => y(d.km)); const svg = d3.select('#container') .append('svg') .attr('width', width + margin.left + margin.right) .attr('height', height + margin.top + margin.bottom) .call(responsivefy) .append('g') .attr('transform', `translate(${margin.left},${margin.top})`); svg.append('path') .data([data]) .attr('class', 'line') .attr('d', line); svg.append('g') .attr('transform', `translate(0,${height})`) .call(d3.axisBottom(x)); svg.append('g') .call(d3.axisLeft(y)); function responsivefy(svg: any) { // container will be the DOM element // that the svg is appended to // we then measure the container // and find its aspect ratio const container = d3.select(svg.node().parentNode), width = parseInt(svg.style('width'), 10), height = parseInt(svg.style('height'), 10), aspect = width / height; // set viewBox attribute to the initial size // control scaling with preserveAspectRatio // resize svg on inital page load svg.attr('viewBox', `0 0 ${width} ${height}`) .attr('preserveAspectRatio', 'xMinYMid') .call(resize); // add a listener so the chart will be resized // when the window resizes // multiple listeners for the same event type // requires a namespace, i.e., 'click.foo' // api docs: https://goo.gl/F3ZCFr d3.select(window).on( 'resize.' + container.attr('id'), resize ); // this is the code that resizes the chart // it will be called on load // and in response to window resizes // gets the width of the container // and resizes the svg to fill it // while maintaining a consistent aspect ratio function resize() { const w = parseInt(container.style('width')); svg.attr('width', w); svg.attr('height', Math.round(w / aspect)); } }