在d3中连续翻译整个阵列

时间:2016-12-26 14:14:30

标签: javascript html d3.js



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;
&#13;
&#13;

乱七八糟地试图制作一个实时条形图,我希望它的行为像烛台图表 那些不知道那是什么的人的参考图像:http://www.chart-formations.com/stock-charts/_img/candlestickChart.gif

我想要一个实时更新栏,经过一段时间后我想在它的左边画一个矩形,到目前为止我已经成功使用了两个数组,一个只有一个值的数组它每隔一秒绘制一次更新条,另一个将保存所有过去矩形的数据。

然而pastRectangles中的矩形以错误的顺序绘制,我只能假设这是因为当d3通过数据集时它从数组的开头到数组的末尾,我&# 39;我试过逆转阵列试图阻止但仍然没有帮助。

我已经修好它并让它工作得有点像我想要的那样,但我无法翻译它我想要它,它似乎只是将最新的矩形转换为数组而不是每次整个阵列,无论如何都有吗?或者,也可以每次都向前移动更新栏。

1 个答案:

答案 0 :(得分:0)

我没有将整个数字数组向左移动,而是通过编写一个简单的moveBars函数让我更新了向右移动

date_input.datepicker({
    format: 'mm/dd/yyyy',
    container: container,
    todayHighlight: true,
    autoclose: true,
    startDate: '-2d',
    endDate: '+2d'
})

然后我在我的pastDraw()函数中调用它,每10秒调用一次

&#13;
&#13;
    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;
&#13;
&#13;

在Chrome上运行此代码可能会因Chrome处理<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>的方式而停滞,因此我选择使用递归SetInterval()代替