admin管理员组文章数量:1394155
I am trying to plot a dynamic stacked bar chart using D3.js. Basic requirement is that I will be getting a new data-point every few seconds and I should be able to replot(transition) the stacked chart. This is the code I have written :
<html>
<head>
<title>Page Title</title>
<script type="text/javascript" src=".min.js"></script>
<script src="d3/d3.js"></script>
<script src="d3/d3.csv.js"></script>
<script src="d3/d3.layout.js"></script>
</head>
<body>
<style type="text/css">
.chart rect {
stroke: white;
}
</style>
<script>
var t = 1297110663, // start time (seconds since epoch)
v = 70, // start value (subscribers)
sentidata = d3.range(33).map(next); // starting dataset
var w = 20,
h = 80;
var x = d3.scale.linear()
.domain([0, 1])
.range([0, w]);
var y = d3.scale.linear()
.domain([0, 200])
.rangeRound([0, h]);
var z = d3.scale.ordinal()
.range(["lightpink", "darkgray"]);
//This function creates random test data of format : time, posvalue, negvalue
function next() {
return {
time: ++t,
posvalue: v = ~~Math.max(10, Math.min(90, v + 10 * (Math.random() - .5))),
negvalue: v = ~~Math.max(10, Math.min(90, v + 10 * (Math.random() - .5)))
};
}
//This function readjusts the data with one new data point and calls redraw function to replot the graph
setInterval(function() {
sentidata.shift();
sentidata.push(next());
redraw(sentidata);
}, 1500);
var svg = d3.select("body").append("svg:svg")
.attr("class", "chart")
.attr("width", w * sentidata.length - 1)
.attr("height", h);
//Transpose the data into layers by Sentiment
var sent = d3.layout.stack()(["posvalue","negvalue"].map(function(sentiment){
return sentidata.map(function(d){
return {x:d.time, y:+d[sentiment]};
});
}));
//Add a group for each Sentiment
var sentiment = svg.selectAll("g.sentiment")
.data(sent)
.enter()
.append("svg:g")
.attr("class","sentiment")
.style("fill", function(d,i){return z(i);})
.style("stroke", function(d,i){return d3.rgb(z(i)).darker();});
//Add a rectangle for each time value
var rect = sentiment.selectAll("rect")
.data(Object)
.enter()
.append("svg:rect")
.attr("x",function(d, i) { return x(i) - .5; })
.attr("y",function(d){return h - y(d.y0)-y(d.y);})
.attr("height", function(d){return y(d.y);})
.attr("width",w);
svg.append("line")
.attr("x1", 0)
.attr("x2", w * sentidata.length)
.attr("y1", h - .5)
.attr("y2", h - .5)
.style("stroke", "#000");
function redraw(data) {
//Transpose the data into layers by Sentiment
var sent = d3.layout.stack()(["posvalue","negvalue"].map(function(sentiment){
return data.map(function(d){
return {x:d.time, y:+d[sentiment]};
});
}));
//Add a group for each Sentiment
var sentiment = svg.selectAll("g.sentiment")
.data(sent)
.transition()
.duration(1000)
.attr("class","sentiment")
.style("fill", function(d,i){return z(i);})
.style("stroke", function(d,i){return d3.rgb(z(i)).darker();});
var rect = sentiment.selectAll("rect")
.data(Object)
.transition()
.duration(1000)
.attr("y",function(d){return h - y(d.y0)-y(d.y);})
.attr("height", function(d){return y(d.y);});
}
</script>
</body>
</html>
Initial stacked chart gets plotted fine. But when I call redraw method it gives me "[object Object] has no method 'data'" error. This error is ing when I am trying to initialize rect variable
var rect = sentiment.selectAll("rect")
.data(Object)
Not sure what I am doing wrong. I am looking for something similar
Any suggestions will be really appreciated !!
I am trying to plot a dynamic stacked bar chart using D3.js. Basic requirement is that I will be getting a new data-point every few seconds and I should be able to replot(transition) the stacked chart. This is the code I have written :
<html>
<head>
<title>Page Title</title>
<script type="text/javascript" src="http://code.jquery./jquery-latest.min.js"></script>
<script src="d3/d3.js"></script>
<script src="d3/d3.csv.js"></script>
<script src="d3/d3.layout.js"></script>
</head>
<body>
<style type="text/css">
.chart rect {
stroke: white;
}
</style>
<script>
var t = 1297110663, // start time (seconds since epoch)
v = 70, // start value (subscribers)
sentidata = d3.range(33).map(next); // starting dataset
var w = 20,
h = 80;
var x = d3.scale.linear()
.domain([0, 1])
.range([0, w]);
var y = d3.scale.linear()
.domain([0, 200])
.rangeRound([0, h]);
var z = d3.scale.ordinal()
.range(["lightpink", "darkgray"]);
//This function creates random test data of format : time, posvalue, negvalue
function next() {
return {
time: ++t,
posvalue: v = ~~Math.max(10, Math.min(90, v + 10 * (Math.random() - .5))),
negvalue: v = ~~Math.max(10, Math.min(90, v + 10 * (Math.random() - .5)))
};
}
//This function readjusts the data with one new data point and calls redraw function to replot the graph
setInterval(function() {
sentidata.shift();
sentidata.push(next());
redraw(sentidata);
}, 1500);
var svg = d3.select("body").append("svg:svg")
.attr("class", "chart")
.attr("width", w * sentidata.length - 1)
.attr("height", h);
//Transpose the data into layers by Sentiment
var sent = d3.layout.stack()(["posvalue","negvalue"].map(function(sentiment){
return sentidata.map(function(d){
return {x:d.time, y:+d[sentiment]};
});
}));
//Add a group for each Sentiment
var sentiment = svg.selectAll("g.sentiment")
.data(sent)
.enter()
.append("svg:g")
.attr("class","sentiment")
.style("fill", function(d,i){return z(i);})
.style("stroke", function(d,i){return d3.rgb(z(i)).darker();});
//Add a rectangle for each time value
var rect = sentiment.selectAll("rect")
.data(Object)
.enter()
.append("svg:rect")
.attr("x",function(d, i) { return x(i) - .5; })
.attr("y",function(d){return h - y(d.y0)-y(d.y);})
.attr("height", function(d){return y(d.y);})
.attr("width",w);
svg.append("line")
.attr("x1", 0)
.attr("x2", w * sentidata.length)
.attr("y1", h - .5)
.attr("y2", h - .5)
.style("stroke", "#000");
function redraw(data) {
//Transpose the data into layers by Sentiment
var sent = d3.layout.stack()(["posvalue","negvalue"].map(function(sentiment){
return data.map(function(d){
return {x:d.time, y:+d[sentiment]};
});
}));
//Add a group for each Sentiment
var sentiment = svg.selectAll("g.sentiment")
.data(sent)
.transition()
.duration(1000)
.attr("class","sentiment")
.style("fill", function(d,i){return z(i);})
.style("stroke", function(d,i){return d3.rgb(z(i)).darker();});
var rect = sentiment.selectAll("rect")
.data(Object)
.transition()
.duration(1000)
.attr("y",function(d){return h - y(d.y0)-y(d.y);})
.attr("height", function(d){return y(d.y);});
}
</script>
</body>
</html>
Initial stacked chart gets plotted fine. But when I call redraw method it gives me "[object Object] has no method 'data'" error. This error is ing when I am trying to initialize rect variable
var rect = sentiment.selectAll("rect")
.data(Object)
Not sure what I am doing wrong. I am looking for something similar
Any suggestions will be really appreciated !!
Share Improve this question edited Oct 8, 2014 at 6:17 Pieter Goosen 9,9515 gold badges37 silver badges57 bronze badges asked Mar 13, 2012 at 12:39 Vikalp JainVikalp Jain 6032 gold badges13 silver badges25 bronze badges 2-
.data()
takes an array of values or objects to use for the plot. Instead of passing "Object", pass it the data you want to show. – Lars Kotthoff Commented Mar 14, 2012 at 8:53 -
Got it. I had defined
var sentiment
as a transition in my redraw, since I used method chaining to create the transition immediately after calling selectAll. Therefore it has no data method, as the error message implied. So I created the transition as a separate statement to avoid the conflict.Thanks to Mike Bostoc for responding so quickly on D3 Google Groups. – Vikalp Jain Commented Mar 14, 2012 at 17:33
1 Answer
Reset to default 5Here's a working example of a "D3 Dynamic Stacked Bar Chart". I hope it helps.
My Best,
Frank
本文标签: javascriptDynamic Stacked Bar Chart in D3Stack Overflow
版权声明:本文标题:javascript - Dynamic Stacked Bar Chart in D3 - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1744700149a2620516.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论