Я пишу виджет, который отображает значение с возможностью анимировать новое значение, когда это необходимо. Частью отображения номера является возможность отображения символа. Например, процентный символ (%).Цепочки (синхронизация) зависимых переходов с использованием d3
Я смог правильно закодировать переходы, используя d3 и цвет. Значение отлично работает. Переход на цвет символа работает, однако переход для положения символа не синхронизирован.
В моем примере код демонстрирует случайные изменения значений. Но позиция символа всегда соответствует предыдущему случайному значению, а не текущему значению.
JSFiddle проблемы здесь: https://jsfiddle.net/metalskin/ektvL7kj/
Код выглядит следующим образом:
<!doctype html>
<html style="height: 100%">
<head>
<meta charset="UTF-8">
<title>Test Arc Graph</title>
<style>
body {
width: 100%;
height: 100%;
}
.mainDiv {
width: 100%;
height: 25%;
display: block;
overflow: hidden;
}
.widget {
width: 25%;
height: 100%;
float: left;
}
#numWidget {
width: 100%;
height: 100%;
}
</style>
</head>
<body>
<div class="mainDiv">
<div id="widgetDiv" class="widget" />
</div>
<script type="text/javascript" src="js/d3.min.js"></script>
<script>
var value = setValue(0, 0, false);
var svg = d3.select("#widgetDiv").append("svg")
.attr("id", "numWidget")
.attr("viewBox", "0 0 100 100")
.attr("perserveAspectRatio", "meet")
.append("g");
var textInst = svg.append("text")
.attr("id", "numValue")
.attr("dx", 50)
.attr("dy", 50)
.text(value)
.attr("text-anchor", "middle")
.attr("dominant-baseline", "central")
.attr("font-family", "sans-serif")
.style("font-weight", "bold")
.style("font-size", "3em")
.attr("fill", determineForegroundColor(value));
var symbolInst = svg.append("text")
.attr("id", "numSymbol")
.attr("dx", 51 + (textInst.node().getBBox().width/2))
.attr("dy", 53)
.text("%")
.attr("text-anchor", "begin")
.attr("baseline-shift", "super")
.attr("font-family", "sans-serif")
.style("font-weight", "bold")
.style("font-size", "1em")
.attr("fill", determineForegroundColor(value));
setInterval(function() {
var min = -120;
var max = 120;
// calc a int random value between min and max
var newValue = Math.floor(Math.random() * (max - min)) + min;
value = setValue(value, newValue, true, textInst, symbolInst);
}, 1500);
function determineForegroundColor(val) {
if(val <= 80) {
return "rgb(100,100,100)";
} else if(val >= 100) {
return "rgb(200,50,50)";
}
return "rgb(200,200,50)";
}
function setValue(oldValue, newValue, redraw, textValueInst, symbolInst) {
var format = d3.format("f");
if(redraw) {
(function(replacementValue, textInst) {
textInst.transition()
.duration(750)
.ease('linear')
.style("fill", determineForegroundColor())
.tween('text', function() {
var ip = d3.interpolate(oldValue, replacementValue);
return function(t) {
this.textContent = format(ip(t));
};
})
// .each(function() {
// d3.select(this);
// symbolInst
// .style("fill", determineForegroundColor())
// .attr("dx", 51 + (textInst.node().getBBox().width/2));
// })
;
symbolInst.transition()
.duration(750)
.ease('linear')
.style("fill", determineForegroundColor())
.attr("dx", 51 + (textInst.node().getBBox().width/2));
})(newValue, textValueInst);
}
return newValue;
};
</script>
</body>
</html>
Закомментированный из кода является попытка использования each
. Когда это раскомментировано, и переход непосредственно после этого прокомментирован, поведение не меняется. Я думал, используя each
Я бы получил event
во время перехода, чтобы я мог смещать символ на основе текущего значения текстового компонента значения. Я нашел несколько doco, которые предложили сделать d3.select(this)
, но я не мог понять, в чем проблема.
Я подозреваю, что использование each
является правильным подходом, просто не удалось найти пример или обсудить, как его использовать, что соответствует тому, что я делаю.
Спасибо за то ahmohamed, я знал, что это будет что-то вдоль этих линий. Моя ошибка заключалась в том, что я пытался использовать функцию «tween», а не внутри функции возврата внутри функции «tween». :-) – Metalskin