I am very new to d3, somehow have been able to draw a line graph with animation as following:
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);
Now I want to add at the end of each line some text(denoting name of each line). I can do that using the following code
vis.append("text")
.attr("transform", "translate(" + (WIDTH - 15) + "," + 200 + ")")
.attr("text-anchor", "start")
.style("fill", "steelblue")
.text("Close");
Now my problem is that the text node to be appended has to be at height where the line graph ends( and replace the currently hardcoded y=200). I am not able to achieve that , please help.
As per this example : 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");
So in your case, from your fiddle :
I have got the bounding box of the path to work out the X translation (get the end point of the path) :
var translateWidth = document.getElementsByClassName("pathLine")[0].getBBox().width;
And for the Y translation, I have passed the last value of the array to the yRange like so :
yRange(lineData[lineData.length - 1])
So now your text function is as follows :
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")
Notice I changed the append from path
to vis
as you can't append text to SVG elements like you were trying to do.
Updated fiddle : https://jsfiddle.net/thatOneGuy/dqch1s13/4/
Working code if needed here :
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>