How to get angled labels that follow your line
Summary: A guide for creating a Line chart which has angled labels that follow the shape of the line. These labels are added to the canvas after the line has been drawn (using the draw event) with some custom code.
This is a demonstration that shows you how to add angled labels to your line where these labels follow the undulations of the line.
These labels are added using the draw
event and the API functions
are used to help with the trigonometry that's involved in calculating the
necessary angle.
The text is added using native canvas text (the accessible
option
is given to the RGraph.text()
function) so it can't be
selected by the
mouse (for cut/copy/paste functions).
The other text on the canvas is still accessible (but the pointer-events
CSS option is set to none
)
The code to achieve the chart is shown and commented below.
<script> // Define the data, labels, the ingraph labels and their size var data = [1,9,5,6,3,4,8,5,2,2], labels = ['Bob','Fred','John','Luis','Jo','Kane','Lou','Pob','Angie', 'Jim'], ingraph = {up:'Good',level:'OK',down:'Bad',size:12}; // Create the Line chart and add some configuration line = new RGraph.Line({ id: 'cvs', data: data, options: { shadow: false, xaxis: false, backgroundGridVlines: false, backgroundGridBorder: false, xaxisLabels: labels, tickmarksSize: 7, marginInner: 15, textSize: 20, marginLeft: 50, title: 'A chart with undulating labels', tickmarksStyle: 'circle' } // Use the draw event to add the angular labels }).on('draw', function (obj) { // This is the first lines coordinates var coords = obj.coords; // Loop thru the coordinates for the line (but not the last one) for (var i=0; i<(coords.length) - 1; ++i) { // Work out the horizontal and vertical distance to the next point var dx = (coords[i + 1][0] - coords[i][0]) / 2, dy = (coords[i + 1][1] - coords[i][1]) / 2; // Work out the direction that the line is going so that the correct // label can be used if (coords[i + 1][1] < coords[i][1]) { var direction = 'up'; } else if (coords[i + 1][1] > coords[i][1]) { var direction = 'down'; } else { var direction = 'level'; } // Work out the angle that the text should be drawn at var angle = RGraph.getAngleByXY({ cx: coords[i][0], cy: coords[i][1], x: coords[i + 1][0], y: coords[i + 1][1], }); // Use the API function to add the text to the chart RGraph.text({ object: obj, x: coords[i][0] + dx, y: coords[i][1] + dy - 5, text: ingraph[direction], halign: 'center', valign: 'bottom', angle: angle * (180 / Math.PI), accessible: false, size: ingraph.size }); } }).draw(); </script>
A version of the chart that uses the adjustable feature
This is an adjustable version of the above chart. You can add adjusting
by simply adding two properties to the chart configuration - adjustable
and yaxisScaleMax
. The adjustable
property adds the adjusting feature and the
yaxisScaleMax
property stops the scale from changing (when you move all of the points
downwards the top value of the scale will change accordingly).
<script> // Define the data, labels, the ingraph labels and their size data = [1,9,5,6,3,4,8,5,2,2]; labels = ['Bob','Fred','John','Luis','Jo','Kane','Lou','Pob','Angie', 'Jim']; ingraph = {up:'Good',level:'OK',down:'Bad',size:12}; // Create the Line chart and add some configuration line = new RGraph.Line({ id: 'cvs2', data: data, options: { shadow: false, xaxis: false, backgroundGridVlines: false, backgroundGridBorder: false, xaxisLabels: labels, tickmarksSize: 7, marginInner: 15, textSize: 20, marginLeft: 50, title: 'An adjustable version of the chart', tickmarksStyle: 'circle', adjustable: true // Add the adjusting feature, yaxisScaleMax: 10 } // Use the draw event to add the angular labels }).on('draw', function (obj) { // This is the first lines coordinates var coords = obj.coords; // Loop thru the coordinates for the line (but not the last one) for (var i=0; i<(coords.length) - 1; ++i) { // Work out the horizontal and vertical distance to the next point var dx = (coords[i + 1][0] - coords[i][0]) / 2, dy = (coords[i + 1][1] - coords[i][1]) / 2; // Work out the direction that the line is going so that the correct // label can be used if (coords[i + 1][1] < coords[i][1]) { var direction = 'up'; } else if (coords[i + 1][1] > coords[i][1]) { var direction = 'down'; } else { var direction = 'level'; } // Work out the angle that the text should be drawn at var angle = RGraph.getAngleByXY({ cx: coords[i][0], cy: coords[i][1], x: coords[i + 1][0], y: coords[i + 1][1], }); // Use the API function to add the text to the chart RGraph.text({ object: obj, x: coords[i][0] + dx, y: coords[i][1] + dy - 5, text: ingraph[direction], halign: 'center', valign: 'bottom', angle: angle * (180 / Math.PI), accessible: false, size: ingraph.size }); } }).draw(); </script>