javascript - Having problems panning and zooming data received by d3.json in a line chart -
i'm trying build trend component able zoom , pan in data fetched d3.json. first off, here's code:
<script> var margin = { top: 20, right: 80, bottom: 20, left: 50 }, width = $("#trendcontainer").width() - margin.left - margin.right, height = 500 - margin.top - margin.bottom; var format = d3.time.format("%y-%m-%d").parse; var x = d3.time.scale() .domain([-width / 2, width / 2]) .range([0, width]); var y = d3.scale.linear() .domain([-height / 2, height / 2]) .range([height, 0]); var color = d3.scale.category10(); var xaxis = d3.svg.axis() .scale(x) .orient("bottom") .ticksize(-height); var yaxis = d3.svg.axis() .scale(y) .orient("left") .ticks(5) .ticksize(-width); var zoom = d3.behavior.zoom() .x(x) .y(y) .scaleextent([1, 10]) .on("zoom", zoomed); var line = d3.svg.line() .interpolate("basis") .x(function(d) { return x(d.date); }) .y(function(d) { return y(d.value); }); var svg = d3.select(".panel-body").append("svg") .attr("width", width + margin.left + margin.right) .attr("height", height + margin.top + margin.bottom) .append("g") .attr("transform", "translate(" + margin.left + "," + margin.top + ")") .call(zoom); d3.json('@url.action("datablob", "trend", new {id = model.unit.unitid, runid = 5})', function(error, json) { $('#processing').hide(); color.domain(d3.keys(json[0]).filter(function(key) { return key !== "time" && key !== "id"; })); data.foreach(function(d) { var date = new date(parseint(d.time.substr(6))); d.time = date; }); var instruments = color.domain().map(function(name) { return { name: name, values: data.map(function(d) { return { date: d.time, value: +d[name] }; }) }; }); x.domain(d3.extent(data, function(d) { return d.time; })); y.domain([ d3.min(instruments, function(c) { return d3.min(c.values, function(v) { return v.value; }); }), d3.max(instruments, function(c) { return d3.max(c.values, function(v) { return v.value; }); }) ]); svg.append("rect") .attr("width", width) .attr("height", height); svg.append("g") .attr("class", "x axis") .attr("transform", "translate(0," + height + ")") .call(xaxis); svg.append("g") .attr("class", "y axis") .call(yaxis); var instrument = svg.selectall(".instrument") .data(instruments) .enter().append("g") .attr("class", "instrument"); instrument.append("path") .attr("class", "line") .attr("d", function(d) { return line(d.values); }) .style("stroke", function(d) { return color(d.name); }); instrument.append("text") .datum(function(d) { return { name: d.name, value: d.values[d.values.length - 1] }; }) .attr("transform", function(d) { return "translate(" + x(d.value.date) + "," + y(d.value.value) + ")"; }) .attr("x", 3) .attr("dy", ".35em") .text(function(d) { return d.name; }); }); 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); }; 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(y) .orient("left") .ticks(5); }; </script>
problem here being zooming / panning not interact lines. stay same, 'below' zoomable / pannable grid. also, 1 of lines disappear when trying zoom / pan , console says following: error: problem parsing d=""
- referring following snippet, last line:
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); };
here's content of json result controller:
[{"weight":0.0,"speed":59.9,"depth":362.24000,"time":"2014-04-09t10:01:23","id":0},{"weight":10.0,"speed":59.9,"depth":394.07000,"time":"2014-04-09t10:01:56","id":1},{"weight":971.0,"speed":70.1,"depth":425.84650,"time":"2014-04-09t10:02:28","id":2},{"weight":0.0,"speed":-29.9,"depth":422.07465,"time":"2014-04-09t10:03:00","id":3},{"weight":1321.0,"speed":-21.6,"depth":406.32840,"time":"2014-04-09t10:03:32","id":4},{"weight":-6.0,"speed":-30.0,"depth":390.57880,"time":"2014-04-09t10:04:04","id":5},{"weight":3.0,"speed":59.9,"depth":404.50380,"time":"2014-04-09t10:04:36","id":6},{"weight":609.0,"speed":59.9,"depth":435.79380,"time":"2014-04-09t10:05:08","id":7},{"weight":1.0,"speed":59.9,"depth":467.95280,"time":"2014-04-09t10:05:40","id":8},{"weight":-2149.0,"speed":34.6,"depth":498.61060,"time":"2014-04-09t10:06:12","id":9},{"weight":2.0,"speed":59.9,"depth":529.83060,"time":"2014-04-09t10:06:44","id":10}]
trend looks in view now, actual lines don't zoom or pan. overlaying grid (black lines) does;
for simplicitys sake, i've considered starting over, following original example found here, struggle placing json-loaded data this. hopefully, can me figure out :)
thanks lars, able solve this. ultimately, had changes controller in addition using this fiddle assigns scales zoom behaviour after setting domains, returns json string view this:
string json = jsonconvert.serializeobject(model.trend.toarray()); return json(json, jsonrequestbehavior.allowget);
this due fact errors appeared when zooming / panning on array returned without being serialized before returned view.
also had following work:
d3.json('@url.action("datablob", "trend", new {id = model.unit.unitid, runid = 5})', function(error, tmparray) { var json = json.parse(tmparray); ... )};
if step skipped, data not displayed reason, being squeezed left side of graph.
Comments
Post a Comment