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

时间:2016-03-03 22:59:44

标签: javascript d3.js

我有一个带有区域路径的折线图。一切都很好,只有当我放大时,区域路径越过x轴和y轴:

enter image description here

请帮助我找到我的代码中缺少的内容 - "隐藏"这个区域路径涉及x轴/ y轴。

您可以找到工作示例here (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 个答案:

答案 0 :(得分:4)

第151行:

areaPath = svg.append("path")

更改为:

areaPath = chartBody.append("path")

chartBody持有clippath

更新了小提琴:https://jsfiddle.net/reko91/hara70wa/6/