2016-07-26 30 views
1

我是d3.js的新手,我正在試圖用針進行測量。d3.js計量針隨動態數據旋轉

var margin = { top: 0, left: 0, right: 0, bottom: 0 }, 
    width = 800, 
    height = 600; 

var maxVal = 12; 

var svg = d3.select(".container").append("svg") 
    .attr("width", width) 
    .attr("height", height) 
    .append("g") 
    .attr("transform", "translate(" + margin.left + "," + margin.top + ")"); 

var bgArc = d3.svg.arc() 
    .outerRadius(100) 
    .innerRadius(10) 
    .startAngle(0) 
    .endAngle(2 * Math.PI); 

var needleScale = d3.scale.linear().domain([0, 360]).range([0, 180]); 

//draw donut 
var wrap = svg.append("g") 
    .attr("class", "wrap") 
    .attr("transform", "translate(" + width/2 + "," + height/2 + ")"); 

wrap.append('g') 
    .attr('class', 'donut') 
    .append("path") 
    .attr("d", bgArc) 
    .style("fill", "white") 
    .style("stroke-width", 2) 
    .style("stroke", "white"); 

wrap.append('g') 
    .attr('class', 'outerMostCircle') 
    .append("circle") 
    .attr("cx", 0) 
    .attr("cy", 0) 
    .attr("r", 108) 
    .style("stroke", "white") 
    .style("stroke-width", 2) 
    .style("fill", "transparent"); 

//draw needle 
var needle = wrap.append('g') 
    .attr("class", "needle") 
    .append("line") 
    .attr("x1", 0) 
    .attr("y1", 0) 
    .attr("x2", 0) 
    .attr("y2", -102) 
    .attr("stroke-width", 6) 
    .attr("stroke", "coral"); 

// add text 
var text = svg.append("g") 
    .attr("class", "text") 
    .append("text") 
    .attr("transform", "translate(" + width/2.2 + "," + height/4 + ")") 
    .attr("font-size", "2em"); 

setInterval(function() { 
    curVal = Math.floor(Math.random()* 12); 
     d3.select('.needle').select('line') 
      .transition() 
      .duration(1000) 
      .attrTween('transform', function() { 
     return tweenNeedle(curVal, maxVal); 
     }); 

    text.datum(curVal).text(function(d) { 
     return d + " m/s"; 
    }); 
}, 1500); 

function tweenNeedle(data, max) { 
    return d3.interpolateString("rotate(0)", "rotate(" + (data/max * 360) + ")"); 
} 

function getEndAngle(data, max) { 
    return data/max * 2 * Math.PI; 
} 

wrap.append('g') 
    .attr('class', 'outerCircle') 
    .append("circle") 
    .attr("cx", 0) 
    .attr("cy", 0) 
    .attr("r", 20) 
    .attr("fill", "pink"); 

wrap.append('g') 
    .attr('class', 'innerCircle') 
    .append("circle") 
    .attr("cx", 0) 
    .attr("cy", 0) 
    .attr("r", 10) 
    .attr("fill", "#666"); 

的問題是,當數據發生變化,針總是從一開始,而不是它的最後位置旋轉。

我試圖記住針的最後位置/角度,但我似乎無法得到它的權利......

我應該怎麼做才能解決這個問題?

這是我迄今爲止所做的。 https://jsfiddle.net/pq7t2obc/8/ 在此先感謝!

+0

您需要將當前的旋轉保存到* oldRotation *變量和使用,在你的函數tweenNeedle(數據,最大值)。 – Robert

回答

-1

首先定義這樣一個變量:

var angle = 0; 

然後在tweenNeedle功能利用舊值這樣的:

function tweenNeedle(data, max) { 
    var prevAngle = angle;//get the old angle 
     angle = (data/max * 360);//update it with the latest angle. 
     return d3.interpolateString("rotate(" +prevAngle+")", "rotate(" + (data/max * 360) + ")"); 

} 

工作代碼here

+0

這工作完美。謝謝你的解釋! – nataliekate

1

@Robert的評論正是如此。這是js小提琴。

簡單地存儲舊的旋轉,並使用它來補間新的計算位置像這樣。

// Define global variable 
var lastRotationAngle = "rotate(0)"; 

// Calculate new tween and return InterpolateString into variable. 
// inside .attrTween('transform', function() { 
var interpolateString = tweenNeedle(lastRotationAngle, curVal, maxVal); 

// Update lastRotationAngle 
lastRotationAngle = "rotate(" + (curVal/maxVal * 360) + ")"; 

// Return the InterpolateString 
return interpolateString; 

https://jsfiddle.net/pq7t2obc/8/

吐溫針functon新:

function tweenNeedle(oldRotation, data, max) { 
    return d3.interpolateString(oldRotation, "rotate(" + (data/max * 360) + ")"); 
} 
+0

我現在明白了。謝謝你的解釋! – nataliekate