2016-07-26 2 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

우선 이런 변수를 정의 :

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 바이올린이 있습니다.

단순히 이전 회전을 저장하고이를 트윈에 사용하여 계산 된 새 위치로 이동하십시오. 새로운 functon

// 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/

트윈 바늘 :

var angle = 0; 

이어서 tweenNeedle 기능이 같은 이전 값을 활용 :

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

이제 알겠습니다. 당신을 설명해 주셔서 감사합니다! – nataliekate