首页 > 解决方案 > D3 折线图 - 当 sidenav 打开或关闭时重新渲染轴(x 和 y)

问题描述

我试图在 sidenav 打开或关闭时重新渲染折线图。但是当数据发生变化时,轴不会更新以适应该区域。当窗口大小改变时,我试图修复调整大小。我主要关心的是在sidenav打开或关闭时让它表现良好。

我还需要在这里更改什么?

注意:当窗口大小改变时,它会正确调整大小。

    const data = [
                {
                    name: 'line 1',
                    date: '2015-10-01T11:10:00.000Z',
                    value: 64
                },
                {
                    name: 'line 1',
                    date: '2015-11-01T11:15:00.000Z',
                    value: 89
                },
                {
                    name: 'line 1',
                    date: '2015-12-01T11:20:00.000Z',
                    value: 10
                },
                {
                    name: 'line 2',
                    date: '2015-10-01T11:10:00.000Z',
                    value: 64
                },
                {
                    name: 'line 2',
                    date: '2015-11-01T11:15:00.000Z',
                    value: 12
                },
                {
                    name: 'line 2',
                    date: '2015-12-01T11:20:00.000Z',
                    value: 75
                },
                {
                    name: 'line 3',
                    date: '2015-10-01T11:10:00.000Z',
                    value: 41
                },
                {
                    name: 'line 3',
                    date: '2015-11-01T11:15:00.000Z',
                    value: 80
                },
                {
                    name: 'line 3',
                    date: '2015-12-01T11:20:00.000Z',
                    value: 80
                }
            ];
    
    function createChart() {
        d3.selectAll("#chart > *").remove();

        // Set the dimensions of the canvas / graph
        var margin = { top: 10, right: 25, bottom: 45, left: 40 },
            width = 1000 - margin.left - margin.right,
            height = 180 - margin.top - margin.bottom;

        // Parse the date / time
        var parseUTCDate = d3.utcParse('%Y-%m-%dT%H:%M:%S.%LZ');
        var formatUTCDate = d3.timeFormat('%Y-%m-%d');
        var parseDate = d3.timeParse('%Y-%m-%d');
        
        // Set the ranges
        var x = d3.scaleTime().range([0, width]);
        var y = d3.scaleLinear().range([height, 0]);
        // Define the line
        var priceline = d3
            .line()
            .x(function(d) {
                return x(d['date']);
            })
            .y(function(d) {
                return y(d['value']);
            });

        // Adds the svg canvas
        var svg = d3
            .select("#chart")
            .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 + ')'
            );

        // Get the data
        data.forEach(function(d) {
            d.date = parseDate(formatUTCDate(parseUTCDate(d.date)));
            d.value = d.value;
        });
        // 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.value;
            })
        ]);
        // Nest the entries by name
        var dataNest = d3
            .nest()
            .key(function(d) {
                return d['name'];
            })
            .entries(data);
        // set the colour scale
        var color = d3.scaleOrdinal(d3.schemeCategory10);
        // Loop through each name / key
        var legendSpace = width / dataNest.length; // spacing for legend

        // Loop through each name / key
        dataNest.forEach(function(d, i) {
            svg.append('path')
                .attr('class', 'line')
                .style('stroke', function() {
                    return (d['color'] = color(d.key));
                })
                .attr('d', priceline(d.values));

            // Add the Legend
            svg.append('text')
                .attr('x', legendSpace / 2 + i * legendSpace)
                .attr('y', height + margin.bottom / 2 + 18)
                .attr('class', 'legend')
                .style('fill', function() {
                    return (d['color'] = color(d.key));
                })
                .text(d.key);
        });
        // Add the X Axis
        svg.append('g')
            .attr('class', 'axis')
            .attr('transform', 'translate(0,' + height + ')')
            .call(d3.axisBottom(x));
        // Add the Y Axis
        svg.append('g')
            .attr('class', 'axis')
            .call(d3.axisLeft(y));

        function responsivefy(svg) {
            // get container + svg aspect ratio
            var container = d3.select(svg.node().parentNode),
                width = parseInt(svg.style('width')),
                height = parseInt(svg.style('height')),
                aspect = width / height;
            // add viewBox and preserveAspectRatio properties,
            // and call resize so that svg resizes on inital page load
            svg.attr('viewBox', '0 0 ' + width + ' ' + height)
                .attr('preserveAspectRatio', 'xMinYMid')
                .call(resize);

            // register multiple listeners for same event type,
            d3.select(window).on('resize.' + container.attr('id'), resize);

            // get width of container and resize svg to fit it
            function resize() {
                var targetWidth = parseInt(container.style('width'));
                svg.attr('width', targetWidth);
                svg.attr('height', Math.round(targetWidth / aspect));
            }
        }
    }
    createChart();
    path {
        stroke: steelblue;
        stroke-width: 2;
        fill: none;
    }
    .axis path,
    .axis line {
        fill: none;
        stroke: grey;
        stroke-width: 1;
        shape-rendering: crispEdges;
    }
    .legend {
        font-size: 16px;
        font-weight: bold;
        text-anchor: middle;
    }
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.12.0/d3.js" integrity="sha256-3BMRAc+yX0neFRvyfGGfd3aZK8NKwYTOzq93ubNY2iU=" crossorigin="anonymous"></script>

<div #chart id="chart"></div>

标签: javascripthtmlangulard3.js

解决方案


推荐阅读