我是d3的新手,不知何故能够用动画绘制线图如下:
var lineData = _.first(data.data, 30); // some array of numbers
var xRange = d3.scale.linear().range([MARGINS.left, WIDTH - MARGINS.right]).domain([0, 30]),
yRange = d3.scale.linear().range([HEIGHT - MARGINS.top, MARGINS.bottom]).domain([_.min(lineData), _.max(lineData)]);
var lineFunc = d3.svg.line()
.x(function(d) {
return xRange(lineData.indexOf(d));
})
.y(function(d) {
return yRange(d);
})
.interpolate('basis');
var path = vis.append('path')
.attr('d', lineFunc(lineData))
.attr('stroke', color)
.attr('stroke-width', 3)
.attr('fill', 'none');
var totalLength = path.node().getTotalLength();
path
.attr("stroke-dasharray", totalLength + " " + totalLength)
.attr("stroke-dashoffset", totalLength)
.transition()
.duration(5000)
.delay(index * 1000)
.ease("linear")
.attr("stroke-dashoffset", 0);
现在我想在每行的末尾添加一些文本(表示每行的名称)。 我可以使用以下代码
来做到这一点vis.append("text")
.attr("transform", "translate(" + (WIDTH - 15) + "," + 200 + ")")
.attr("text-anchor", "start")
.style("fill", "steelblue")
.text("Close");
现在我的问题是要追加的文本节点必须位于折线图结束的高度(并替换当前硬编码的y = 200)。我无法实现这一目标,请帮助。
答案 0 :(得分:2)
根据此示例:http://bl.ocks.org/d3noob/8603837
svg.append("text")
.attr("transform", "translate(" + (width+3) + "," + y(data[0].close) + ")")
.attr("dy", ".35em")
.attr("text-anchor", "start")
.style("fill", "steelblue")
.text("Close");
所以在你的情况下,从你的小提琴:
我有路径的边界框来计算X转换(得到路径的终点):
var translateWidth = document.getElementsByClassName("pathLine")[0].getBBox().width;
对于Y转换,我已经将数组的最后一个值传递给yRange,如下所示:
yRange(lineData[lineData.length - 1])
现在你的文字功能如下:
vis.append("text")
.attr("transform", function(d) {
return "translate(" + (translateWidth + 50) + "," + yRange(lineData[lineData.length - 1]) + ")"
})
.attr("text-anchor", "start")
.style("fill", "black")
.text("abc")
注意我已将path
的附加内容更改为vis
,因为您无法将文本附加到SVG元素,就像您尝试的那样。
更新了小提琴:https://jsfiddle.net/thatOneGuy/dqch1s13/4/
如果需要,可以使用工作代码:
var vis = d3.select('#visualisation'),
WIDTH = 1000,
HEIGHT = 400,
MARGINS = {
top: 20,
right: 20,
bottom: 20,
left: 50
};
var drawLine = function(data, color, index) {
var lineData = data;
var xRange = d3.scale.linear().range([MARGINS.left, WIDTH - MARGINS.right]).domain([0, 30]),
yRange = d3.scale.linear().range([HEIGHT - MARGINS.top, MARGINS.bottom]).domain([_.min(lineData), _.max(lineData)]);
var lineFunc = d3.svg.line()
.x(function(d) {
return xRange(lineData.indexOf(d));
})
.y(function(d) {
return yRange(d);
})
.interpolate('basis');
console.log(lineData[lineData.length - 1])
var path = vis.append('path').attr('class', 'pathLine')
.attr('d', lineFunc(lineData))
.attr('stroke', function(d) {
return color
})
.attr('stroke-width', 3)
.attr('fill', 'none');
var totalLength = path.node().getTotalLength();
path
.attr("stroke-dasharray", totalLength + " " + totalLength)
.attr("stroke-dashoffset", totalLength)
.transition()
.duration(5000)
.delay(index * 1000)
.ease("linear")
.attr("stroke-dashoffset", 0);
console.log(path)
var translateWidth = document.getElementsByClassName("pathLine")[0].getBBox().width;
vis.append("text")
.attr("transform", function(d) {
return "translate(" + (translateWidth + 50) + "," + yRange(lineData[lineData.length - 1]) + ")"
})
.attr("text-anchor", "start")
.style("fill", "black")
.text("abc")
};
drawLine([1, 20, 3, 4, 15, 6, 7, 18, 9, 0, 12, 23, 24, 12, 100], 'red', 2);
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>
<svg id="visualisation" width="1200" height="400" style="position: absolute;left: 50%;transform: translateX(-50%);"></svg>