Having no luck with updating the chart, I can init it with a full data set just fine, tried many many examples. I'm starting by trying to update the X and Y axis scale for a constantly increasing data set. Ultimately, I actually just want to update the whole chart, data points included. So there maybe a simpler way.
I'm hoping to just push()
to the data_set
, and call chart.update
var margin, x, y, valueline, div, svg, xAxis, yAxis;
var data_set = [
{ser1: 0, ser2: 0}
];
The init code:
chart.init = function() {
// set the dimensions and margins of the graph
margin = {top: 20, right: 20, bottom: 20, left: 20},
width = 860 - margin.left - margin.right,
height = 400 - margin.top - margin.bottom;
// set the ranges
x = d3.scaleLinear().range([0,width]);
y = d3.scaleLinear().range([height, 0]);
// define the line
valueline = d3.line()
.x(function(d) { return x(d.ser1); })
.y(function(d) { return y(d.ser2); });
// Define the div for the tooltip
div = d3.select("body").append("div")
.attr("class", "tooltip")
.style("opacity", 0);
// append the svg obgect to the body of the page
// appends a 'group' element to 'svg'
// moves the 'group' element to the top left margin
svg = d3.select("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform",
"translate(" + margin.left + "," + margin.top + ")");
// format the data
data_set.forEach(function(d) {
d.ser1 =+ d.ser1;
d.ser2 =+ d.ser2;
});
// Scale the range of the data
x.domain([0, d3.max(data_set, function(d) { return d.ser1; })]);
y.domain([0, d3.max(data_set, function(d) { return d.ser2; })]);
// Add the valueline path.
svg.append("path")
.data([data_set])
.attr("class", "line")
.attr("d", valueline);
// Add the X axis
xAxis = d3.axisBottom().scale(x);
svg.append("g")
.attr("transform", "translate(0," + height + ")")
.call(xAxis);
// Add the Y axis
yAxis = d3.axisLeft().scale(y);
svg.append("g")
.call(yAxis);
// Add data points and tool tips
svg.selectAll(".dot")
.data(data_set)
.enter().append("circle")
.attr("class", "dot")
.attr("cx", function(d, i) { return x(d.ser1) })
.attr("cy", function(d) { return y(d.ser2) })
.attr("r", 5)
.on("mouseover", function(d) {
div.transition()
.duration(200)
.style("opacity", .9);
div .html("Ser1: "+d.ser1 + "<br/>Ser2: "+ + d.ser2)
.style("left", (d3.event.pageX) + "px")
.style("top", (d3.event.pageY - 28) + "px");
})
.on("mouseout", function(d) {
div.transition()
.duration(500)
.style("opacity", 0);
});
}
The update code:
chart.update = function() {
// format the data
data_set.forEach(function(d) {
d.ser1 =+ d.ser1;
d.ser2 =+ d.ser2;
});
// Scale the range of the data
x.domain([0, d3.max(data_set, function(d) { return d.ser1; })]);
y.domain([0, d3.max(data_set, function(d) { return d.ser2; })]);
// define the line
valueline = d3.line()
.x(function(d) { return x(d.ser1); })
.y(function(d) { return y(d.ser2); });
// update try?
var t = svg.transition().duration(750);
yAxis.scale(y);
t.select("g.y.axis").call(yAxis);
xAxis.scale(x);
t.select("g.x.axis").call(xAxis);
svg.data(data_set);
svg.select("g.y.axis")
.attr("transform", "translate(0," + height + ")")
.transition(t)
.call(xAxis);
svg.select("g.x.axis")
.transition(t)
.call(yAxis);
/*
// update no luck
svg.data(data_set);
var t = svg.transition().duration(750);
xAxis.scale(x);
t.select("g.x.axis").call(xAxis);
var axis = d3.axisBottom().scale(x);
d3.selectAll("g.x.axis")
.transition(t)
.call(axis)
*/
}
Here's how I'd do it:
1 Append all g elements outside the update function and give them a class name so you can reference them, for example:
svg.append("g")
.attr("class","axis axis--y")
2 Select an empty class and append the line and circles new data through enter()
, Example:
var line = svg.selectAll(".lineTest")
.data([data],function(d){ return d.ser1 });
line = line
.enter()
.append("path")
.attr("class","lineTest")
.merge(line);
line.transition()
.duration(durations)
.attr("d", valueline)
3 Toggle the dataset:
data = d3.select('#selection')
.property('value') == "First" ? data_set : data_set2
Here's a modified version of your code: Plunker
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.