Question

I have a line chart with several axes, using zooming and panning. Works fine, however when I pan or zoom, my lines extend outside the 'graph' component. I've tried following this example, adding a clipPath to my chart.

When highlighting the code in chromes code inspector, I see the following (which at least indicates that I've got a path present I guess)

enter image description here

Here's my grid:

<script>
    /* d3 vars */
    var x;
    var y1;
    var y2;
    var y3;
    var graph;
    var m = [];
    var w;
    var h;

    /* d3 axes */
    var xAxis;
    var yAxisLeft;
    var yAxisLeftLeft;
    var yAxisRight;

    /* d3 lines */
    var line1;
    var line2;
    var line3;

    /* d3 zoom */
    var zoom;
    var zoomLeftLeft;
    var zoomRight;                           

    /* Data */
    var speed = [];
    var depth = [];
    var weight = [];
    var timestamp = [];

    var url = '@Url.Action("DataBlob", "Trend", new {id = Model.Unit.UnitId, runId = Request.Params["runId"]})';
    var data = $.getJSON(url, null, function(data) {
        var list = JSON.parse(data);
        var format = d3.time.format("%Y-%m-%dT%H:%M:%S").parse;
        list.forEach(function(d) {
            speed.push(d.Speed);
            depth.push(d.Depth);
            weight.push(d.Weight);
            var date = format(d.Time);
            d.Time = date;
            timestamp.push(d.Time);
        });

        m = [10, 80, 30, 100]; // margins: top, right, bottom, left
        w = $("#trendcontainer").width() - m[1] - m[3]; // width
        h = 550 - m[0] - m[2]; // height

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

        y1 = d3.scale.linear().domain([0, d3.max(speed)]).range([h, 0]);
        y2 = d3.scale.linear().domain([0, d3.max(depth)]).range([h, 0]);
        y3 = d3.scale.linear().domain([0, d3.max(weight)]).range([h, 0]);

        line1 = d3.svg.line()
            .interpolate("basis")
            .x(function (d, i) {
                return x(timestamp[i]);
            })
            .y(function (d) {
                return y1(d);
            });

        line2 = d3.svg.line()
            .interpolate("basis")
            .x(function (d, i) {
                return x(timestamp[i]);
            })
            .y(function (d) {
                return y2(d);
            });

        line3 = d3.svg.line()
            .interpolate("basis")
            .x(function (d, i) {
                return x(timestamp[i]);
            })
            .y(function (d) {
                return y3(d);
            });

        zoom = d3.behavior.zoom()
            .x(x)
            .y(y1)
            .scaleExtent([1, 10])
            .on("zoom", zoomed);

        zoomLeftLeft = d3.behavior.zoom()
            .x(x)
            .y(y3)
            .scaleExtent([1, 10]);

        zoomRight = d3.behavior.zoom()
            .x(x)
            .y(y2)
            .scaleExtent([1, 10]);

        // Add an SVG element with the desired dimensions and margin.
        graph = d3.select(".panel-body").append("svg:svg")
            .attr("width", w + m[1] + m[3])
            .attr("height", h + m[0] + m[2])
            .call(zoom)
            .append("svg:g")
            .attr("transform", "translate(" + m[3] + "," + m[0] + ")");

          graph.append("defs").append("clipPath")
    .attr("id", "clip")
    .append("rect")
    .attr("width", w)
    .attr("height", h);

        // create xAxis
        xAxis = d3.svg.axis().scale(x).tickSize(-h).tickSubdivide(false);
        // Add the x-axis.
        graph.append("svg:g")
            .attr("class", "x axis")
            .attr("transform", "translate(0," + h + ")")
            .call(xAxis);

        // create left yAxis
        yAxisLeft = d3.svg.axis().scale(y1).ticks(10).orient("left");
        // Add the y-axis to the left
        graph.append("svg:g")
            .attr("class", "y axis axisLeft")
            .attr("transform", "translate(-15,0)")
            .call(yAxisLeft);

        // create leftleft yAxis
        yAxisLeftLeft = d3.svg.axis().scale(y3).ticks(10).orient("left");
        // Add the y-axis to the left
        graph.append("svg:g")
            .attr("class", "y axis axisLeftLeft")
            .attr("transform", "translate(-50,0)")
            .call(yAxisLeftLeft);

        // create right yAxis
        yAxisRight = d3.svg.axis().scale(y2).ticks(10).orient("right");
        // Add the y-axis to the right
        graph.append("svg:g")
            .attr("class", "y axis axisRight")
            .attr("transform", "translate(" + (w + 15) + ",0)")
            .call(yAxisRight);

        // add lines
        // do this AFTER the axes above so that the line is above the tick-lines
        graph.append("svg:path").attr("d", line1(speed)).attr("class", "y1");
        graph.append("svg:path").attr("d", line2(depth)).attr("class", "y2");
        graph.append("svg:path").attr("d", line3(weight)).attr("class", "y3");
    });

    function zoomed() {
        zoomRight.scale(zoom.scale()).translate(zoom.translate());
        zoomLeftLeft.scale(zoom.scale()).translate(zoom.translate());

        graph.select(".x.axis").call(xAxis);
        graph.select(".y.axisLeft").call(yAxisLeft);
        graph.select(".y.axisLeftLeft").call(yAxisLeftLeft);
        graph.select(".y.axisRight").call(yAxisRight);
        graph.select(".x.grid")
            .call(make_x_axis()
            .tickFormat(""));
        graph.select(".y.axis")
            .call(make_y_axis()
                .tickSize(5, 0, 0));
        graph.selectAll(".y1")
            .attr("d", line1(speed));
        graph.selectAll(".y2")
            .attr("d", line2(depth));
        graph.selectAll(".y3")
            .attr("d", line3(weight));
    };

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

    var make_y_axis = function () {
        return d3.svg.axis()
            .scale(y1)
            .orient("left")
            .ticks(5);
    };
</script>

Any suggestions on what I'm missing here?

Was it helpful?

Solution

Solved by appending the following to the lines being drawn:

graph.append("svg:path").attr("d", line1(speed)).attr("class", "y1").attr("clip-path", "url(#clip)");
graph.append("svg:path").attr("d", line2(depth)).attr("class", "y2").attr("clip-path", "url(#clip)");
graph.append("svg:path").attr("d", line3(weight)).attr("class", "y3").attr("clip-path", "url(#clip)");
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top