D3.js - 折线图:在缩放时区域路径跨越x和y轴

4

我有一张带区域路径的折线图。一切都很好,只是当我缩放时,区域路径会超出x轴和y轴:

enter image description here

请帮我找出代码中缺少的部分,以便在x轴/ y轴处“隐藏”此区域路径。 您可以在这里找到工作示例(jsFiddle)。
以下是图形的完整代码:
    var chartBody;
    var clip;
    var line;
    var x;
    var y;
    var zoom;
    var make_x_axis;
    var make_y_axis;
    var xAxis;
    var yAxis;
    var area;
    var areaPath;
    var width;
    var height;
    var margin;

    var data = [];
    var panel_1_status = 0; //0 - not loaded, 1 - first time loaded, 2 - getting new data every X seconds

    function initGraph() {

        margin = {
            top: 0,
            right: 20,
            bottom: 20,
            left: 45
        };

        width = 600 - margin.left - margin.right;
        height = 400 - margin.top - margin.bottom;

        x = d3.time.scale()
                .domain(d3.extent(data, function (d) {
                    return d.t;
                }))
                .range([0, width]);

        y = d3.scale.linear()
                .domain(d3.extent(data, function (d) {
                    return d.val;
                }))
                .range([height, 0]);

        line = d3.svg.line()
                .interpolate('basis') //krivulja smooth
                .x(function (d) {
                    return x(d.t);
                })
                .y(function (d) {
                    return y(d.val);
                });

        zoom = d3.behavior.zoom()
                .x(x)
                .y(y)
                .on("zoom", zoomed);

        svg = d3.select('#chart > .svg-container')
                .append("svg:svg")
                .attr("preserveAspectRatio", "xMinYMin meet")
                .attr("viewBox", "0 0 600 400")
                .classed("svg-content-responsive", true)
                .append("svg:g")
                .attr("transform", "translate(" + margin.left + "," + margin.top + ")")
                .call(zoom);

        svg.append("svg:rect")
                .attr("width", width)
                .attr("height", height)
                .attr("class", "plot");

        make_x_axis = function () {
            return d3.svg.axis()
                    .scale(x)
                    .orient("bottom")
                    .ticks(5);
        };

        make_y_axis = function () {
            return d3.svg.axis()
                    .scale(y)
                    .orient("left")
                    .ticks(5);
        };

        xAxis = d3.svg.axis()
                .scale(x)
                .orient("bottom")
                .ticks(5);

        svg.append("svg:g")
                .attr("class", "x axis")
                .attr("transform", "translate(0, " + height + ")")
                .call(xAxis);

        yAxis = d3.svg.axis()
                .scale(y)
                .orient("left")
                .ticks(5);

        svg.append("g")
                .attr("class", "y axis")
                .call(yAxis)
                .append("text")
                .attr("transform", "rotate(-90)")
                .attr("y", 6)
                .attr("x", -5)
                .attr("dy", ".71em")
                .style("text-anchor", "end")
                .text("Temperature °C");

        svg.append("g")
                .attr("class", "x grid")
                .attr("transform", "translate(0," + height + ")")
                .call(make_x_axis()
                        .tickSize(-height, 0, 0)
                        .tickFormat(""));

        svg.append("g")
                .attr("class", "y grid")
                .call(make_y_axis()
                        .tickSize(-width, 0, 0)
                        .tickFormat(""));

        clip = svg.append("svg:clipPath")
                .attr("id", "clip")
                .append("svg:rect")
                .attr("x", 0)
                .attr("y", 0)
                .attr("width", width)
                .attr("height", height);

        chartBody = svg.append("g")
                .attr("clip-path", "url(#clip)");

        chartBody.append("svg:path")
                .datum(data)
                .attr("class", "line")
                .attr("d", line);

        area = d3.svg.area()
                .interpolate('basis')
                .x(function (d) {
                    return x(d.t);
                })
                .y0(height)
                .y1(function (d) {
                    return y(d.val);
                });
        // Add the filled area
        areaPath = svg.append("path")
                .datum(data)
                .attr("class", "area")
                .attr("d", area);

    }

    function zoomed(){

        svg.select(".x.axis").call(xAxis);
        svg.select(".y.axis").call(yAxis);
        svg.select(".x.grid")
                .call(make_x_axis()
                        .tickSize(-height, 0, 0)
                        .tickFormat(""));
        svg.select(".y.grid")
                .call(make_y_axis()
                        .tickSize(-width, 0, 0)
                        .tickFormat(""));
        svg.select(".line")
                .attr("class", "line")
                .attr("d", line);

        svg.select("path.area").attr("d", area);

    }

    //load data
    data = [
    {
        t: 1457040823000,
        val: 20
    },
    {
        t: 1457040828000,
        val: 1
    },
    {
        t: 1457040833000,
        val: 39
    },
    {
        t: 1457040838000,
        val: 3
    },
    {
        t: 1457040843000,
        val: 33
    },
    {
        t: 1457040848000,
        val: -10
    },
    {
        t: 1457040853000,
        val: 21
    },
    {
        t: 1457040858000,
        val: 17
    },
    {
        t: 1457040863000,
        val: 13
    },
    {
        t: 1457040868000,
        val: 4
    }

    ];
    initGraph();

1
areaPath = **chartBody**.append("path") - Justin Heath
因为chartBody具有“剪切路径”矩形,而svg没有。 - Justin Heath
1个回答

4

感谢@thisOneGuy和@styletron。这就是它,现在它运行得很好 :) 顺便说一句:@thisOneGuy,您更新的fiddle并没有“更新”,您可能忘记更改为areaPath = chartBody.append("path") - Matjaž Železnik
1
保存更改后,这很奇怪。无论如何,已更新答案 :) - thatOneGuy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接