Reputation: 3023
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)
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?
Upvotes: 1
Views: 3894
Reputation: 3023
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)");
Upvotes: 2