var bardata = []; //array that holds the current value for the candlestick chart
var pastRectangles = [50,12,14,15,35,64] //holds the data for the historical rectangles to be drawn
var data;
setInterval(function () {
var x = Math.floor(Math.random() * 100) //generate a random whole number between 0-99
bardata.push(x); // push that value into the bardata array
// console.log(bardata)
data = x; //set the value of x to data, will be used to update the pastRectangles array every 10 seconds
}, 1000);
var height = 900
, width = 900
, barWidth = 50
, barOffset = 55;
var offset = pastRectangles.length * (barOffset + barWidth);
var scale = d3.scale.linear()
.range([0, pastRectangles])
.domain([0, height]);
var svg = d3.select('body')
.append('svg')
.attr('width', width)
.attr('height', height)
.style('background', 'black')
.append("g")
.attr("class", "rectangles")
update(pastRectangles[pastRectangles.length-1]);
pastDraw(); // call post draw to draw the dummy data first before the update function starts running
function pastDraw()
{
var pastRect = svg.selectAll('rect').data(pastRectangles); //This function will loop through the pastRectangles array and will
pastRect.enter() //draw a rectange for every index in the array
.append("rect") //The reason for not using bardata is that it only holds one value
.attr("g", "rectangles")
.attr("x", function(d,i){return i * (barWidth+barOffset)}) //every second and therefore a second array is needed to hold the
.attr("y", function(d){return height - d}) //historical data
.attr("height", function(d){return d})
.attr("width", 60)
.attr("id", "history")
.attr("fill", "steelblue")
pastRect.transition()
.duration(1000)
.ease('linear')
.attr("height", function (d) {
return d
})
pastRect.exit()
}
function update(bardata) {
var rect = svg.selectAll('rect').data([bardata]); //This function essentially draws a new rectangle for every
rect.enter() //value of bardata, however, because bardata is constantly
.append("rect") //removing the current value for a new value every second
.attr("x",offset) //it gives the illusion of one rectangle updating regularly
.attr("y", function(d){return height - d})
.attr("id", "updateBar")
.attr("height", bardata)
.attr("width", 60)
.attr("fill", "steelblue")
rect.transition()
.duration(1000)
.ease('linear')
.attr("height", function (d) {
return d
})
// rect.exit().transition()
// .duration(1000)
// .attr("transform", "translate(-80,0)")
// .remove();
//
//console.log(bardata);
}
function moveBar()
{
svg.selectAll("#history")
.transition()
.duration(1000)
.attr("transform", "translate(-80,0)")
svg.select("#updateRect")
.transition()
.duration(1000)
.attr("transform", "translate(80,0)")
}
setInterval(function () {
update(bardata); //call the update function with the current value of bardata
bardata.shift(); // remove the the last index of the array from bardata
}, 1000)
setInterval(function () {
pastRectangles.push(data) //update pastrectangles array with the most current value of x every 10 seconds
pastDraw(); // call the pastDraw function to draw the latest recatngle
moveBar();
}, 10000)

<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
&#13;
乱七八糟地试图制作一个实时条形图,我希望它的行为像烛台图表 那些不知道那是什么的人的参考图像:http://www.chart-formations.com/stock-charts/_img/candlestickChart.gif
我想要一个实时更新栏,经过一段时间后我想在它的左边画一个矩形,到目前为止我已经成功使用了两个数组,一个只有一个值的数组它每隔一秒绘制一次更新条,另一个将保存所有过去矩形的数据。
然而pastRectangles
中的矩形以错误的顺序绘制,我只能假设这是因为当d3通过数据集时它从数组的开头到数组的末尾,我&# 39;我试过逆转阵列试图阻止但仍然没有帮助。
我已经修好它并让它工作得有点像我想要的那样,但我无法翻译它我想要它,它似乎只是将最新的矩形转换为数组而不是每次整个阵列,无论如何都有吗?或者,也可以每次都向前移动更新栏。
答案 0 :(得分:0)
我没有将整个数字数组向左移动,而是通过编写一个简单的moveBars函数让我更新了向右移动
date_input.datepicker({
format: 'mm/dd/yyyy',
container: container,
todayHighlight: true,
autoclose: true,
startDate: '-2d',
endDate: '+2d'
})
然后我在我的pastDraw()函数中调用它,每10秒调用一次
function moveBar()
{
var bar = svg.selectAll("#updateBar")
.transition()
.duration(50)
.attr("transform", "translate("+move+",0)")
move += (barWidth+barOffset);
console.log(move)
}
&#13;
var bardata = []; //array that holds the current value for the candlestick chart
var pastRectangles = [50,12,14,15,35,64] //holds the data for the historical rectangles to be drawn
var data
, height = 250
, width = 800
, barWidth = 50
, barOffset= 55;
var move = 0;
setInterval(function () {
var x = Math.floor(Math.random() * 100) //generate a random whole number between 0-99
bardata.push(x); // push that value into the bardata array
data = x; //set the value of x to data, will be used to update the pastRectangles array every 10 seconds
}, 1000);
data = (barOffset+barOffset)
var offset = pastRectangles.length * (barOffset + barWidth);
var scale = d3.scale.linear()
.range([0, pastRectangles])
.domain([0, height]);
var svg = d3.select('body')
.append('svg')
.attr('width', width)
.attr('height', height)
.style('background', 'red')
.append("g")
.attr("class", "rectangles")
update(pastRectangles[pastRectangles.length-1]);
pastDraw()
function pastDraw()
{
var pastRect = svg.selectAll('rect').data(pastRectangles); //This function will loop through the pastRectangles array and will
pastRect.enter() //draw a rectange for every index in the array
.append("rect") //The reason for not using bardata is that it only holds one value
.attr("g", "rectangles")
.attr("x", function(d,i){return i * (barWidth+barOffset)}) //every second and therefore a second array is needed to hold the
.attr("y", function(d){return height - d}) //historical data
.attr("height", function(d){return d})
.attr("width", 60)
.attr("id", "history")
.attr("fill", "steelblue")
pastRect.transition()
.duration(1000)
.ease('linear')
.attr("height", function (d) {
return d
})
pastRect.exit()
var bar = svg.selectAll("#updateBar")
.transition()
.duration(1000)
.attr("transform", "translate("+move+",0)")
move += (barWidth+barOffset);
setTimeout(function()
{
pastRectangles.push(data)
pastDraw();
},30000)
}
function update(bardata) {
var rect = svg.selectAll('rect').data([bardata]); //This function essentially draws a new rectangle for every
rect.enter() //value of bardata, however, because bardata is constantly
.append("rect") //removing the current value for a new value every second
.attr("x",offset) //it gives the illusion of one rectangle updating regularly
.attr("y", function(d){return height - d})
.attr("id", "updateBar")
.attr("height", bardata)
.attr("width", 60)
.attr("fill", "white")
.attr("stroke", "black")
rect.transition()
.duration(1000)
.ease('linear')
.attr("height", function (d) {
return d
})
rect.exit();
//console.log(bardata);
}
setInterval(function () {
update(bardata); //call the update function with the current value of bardata
bardata.shift(); // remove the the last index of the array from bardata
}, 1000)
&#13;
在Chrome上运行此代码可能会因Chrome处理<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
的方式而停滞,因此我选择使用递归SetInterval()
代替