Highcharts - Column/bar chart with target lines - javascript

Using highcharts, what would be the best way to implement target lines over a column or bar chart? (Also known as target vs goal)
Found this picture from a similar d3.js thread as an example:
I'm thinking another series, but don't see any options in the documentation about a target line. Here's a basic column chart: jsfiddle.net/eksh8a8p/
I've thought about using a columnrange series, but you are limited to having a start/end value which can be problematic due to scaling of number values.
Are there other ideas/options that could create a similar result to the picture above?

You can use a columnrange series but there is a simpler option - a scatter series with a rectangle marker
//custom marker
Highcharts.SVGRenderer.prototype.symbols['c-rect'] = function (x, y, w, h) {
return ['M', x, y + h / 2, 'L', x + w, y + h / 2];
};
//series options
{
marker: {
symbol: 'c-rect',
lineWidth:3,
lineColor: Highcharts.getOptions().colors[1],
radius: 10
},
type: 'scatter'
example: http://jsfiddle.net/eksh8a8p/1/

Related

Highcharts - overlapping values with the x-Axis

I am trying to create a line graph, wherein if all the values for the particular series is zero then, I want the line to be drawn on the bottom over the x-axis line. But it seems like the line of the x-axis takes the preference than the series line. Is there any way to change that?
Below is my configuration:
xAxis: {
type: "datetime",
tickmarkPlacement: "on",
lineWidth: 10,
lineColor: 'red',
},
yAxis: {
min: 0,
minRange : 0.1,
title: {
text: ""
}
},
plotOptions: {
line: {
softThreshold: false
}
},
Example:
http://jsfiddle.net/shivajyothibalavikas/twxs7mL2/3
In the above example the axis line color is red and series line color is black. but red takes the preference. I want the black line to take the preference while displaying
It is not possible to move a series line above an axis line by options in Highcharts API. As a solution, you can use the Highcharts.SVGRenderer class and draw a custom line at the chart bottom.
chart: {
...,
events: {
render: function() {
const chart = this;
const x1 = chart.plotLeft;
const x2 = x1 + chart.plotWidth;
const y = chart.plotTop + chart.plotHeight;
if (!chart.customLine) {
chart.customLine = chart.renderer
.path().attr({
stroke: 'red',
'stroke-width': 10
}).add();
}
chart.customLine.attr({
d: ['M', x1, y, 'L', x2, y]
});
}
}
}
Live demo: http://jsfiddle.net/BlackLabel/70d6sg2o/
API Reference: https://api.highcharts.com/class-reference/Highcharts.SVGRenderer

What JavaScript code would I use to plot a trend line?

UPDATE
I managed to get trendline support added to the RGrah Line and Scatter charts. There's a demo in the download archive called demos/line-trendline.html that shows it. The Scatter chart supports trendlines too.
Assuming that I have the following values that I'm going to plot on a Line chart (these are values and not coordinates - the coordinates are calculated by my software and are shown below):
[4,4,3,2,5,5]
How would I turn those values into a set of trendline values/coordinates? (BTW I don't really have any Maths expertise beyond school level - so no fancy Maths terminology please!).
To add further details: These are a set of values that are spaced equally across a 500 pixel space (an HTML5 canvas tag). So the X coordinates are calculated for you and will come out like this (35 pixel margin on both sides of the chart): [35,121,207,293,379,465].
These are just the X coordinates, the Y coordinates are calculated automatically based on the scale, the height of the chart and the value. Here's an example Line chart that my software creates using this code:
<canvas id="cvs" width="500" height="250">
[No canvas support]
</canvas>
<script>
line = new RGraph.Line({
id: 'cvs',
data: [4,4,3,2,5,5],
options: {
xaxisLabels: ['Monday','Tuesday','Wednesday','Thursday','Friday','Saturday'],
shadow: false,
backgroundGridBorder: false,
backgroundGridVlines: false,
xaxis: false,
yaxis: false
}
}).draw()
</script>
You can see the chart online here:
https://www.rgraph.net/demos/line-csv-reader.html
And the X/Y coordinates (that are then plotted on the canvas tag) that are generated end up as this:
[[35,71],[121,71],[207,107],[293,143],[379,35],[465,35]]
So you already know:
the X coordinates are calculated for you ... (35 pixel margin): 35, 121, 207, 293, 379, 465.
the generated result:
[[35,71], [121,71], [207,107], [293,143], [379,35], [465,35]] that's just a list of [x,y] points
From that we can remove the X we know (calculated for us) and we will get:
71, 71, 107, 143, 35, 35
we can see a pattern with the original input
4, 4, 3, 2, 5, 5
piece of cake to get the formula with that sequence:
35 + (5 - y)*36
All that remains is to put that formula into code:
<canvas id="canvas"></canvas>
<script>
canvas = document.getElementById('canvas');
canvas.width = canvas.height = 500;
ctx = canvas.getContext('2d');
x = 35
trendline = []
plot = [4, 4, 3, 2, 5, 5]
plot.forEach(function(value) {
y = 35 + (5 - value) * 36
ctx.lineTo(x, y);
trendline.push([x, y])
x += 86
});
ctx.stroke();
console.log(JSON.stringify(trendline))
</script>
Now from what you mentioned on the comments:
it just plots the values that you give it ... It doesn't generate trend lines from your data
looking at the code of rgraph on the drawLine function:
https://www.rgraph.net/libraries/src/RGraph.line.js
// Loop thru each value given, plotting the line
// (FORMERLY FIRST)
for (i=0,len=lineData.length; i<len; i+=1) {
var data_point = lineData[i];
//
// Get the yPos for the given data point
//
var yPos = this.getYCoord(data_point);
...
//
// Add the coords to an array
//
this.coords.push([xPos, yPos]);
lineCoords.push([xPos, yPos]);
That lineCoords looks like a trendline to me...

How to make mathematical chart with HighCharts?

Hi there, I'm doing a web project which aims to replace a back-end chart renderer with front-end chart renderer. The front-end charting library I'm using is HighCharts. The 1st image shows what the chart supposed to look, and the 2nd is the chart rendered by HighCharts based on same data. As you can see, at point 3 & 4 (count from right to left), since their values are equal, the line between them are considered horizontal, which is different in image 1 as desired.
Is there anyway we can use HighCharts to achieve the first image - like chart? Cheers.
In general, when two points have the same value, then line will be rendered as straight one. You can change that by wrapping getPointSpline. Here is simple POC:
(function(H) {
H.wrap(H.seriesTypes.spline.prototype, 'getPointSpline', function(p, points, point, i) {
var path = p.call(this, points, point, i),
offset = -10;
if (points[i - 1] && points[i - 1].y === point.y) {
path[2] += offset;
path[4] += offset;
}
return path;
});
})(Highcharts)
And working demo: http://jsfiddle.net/99w72efv/8/
Highcharts splice type series doesn't provide the kind of line approximation you are looking for. You could add more data points (that might be hidden) to get the shape that you are looking for.
Example: http://jsfiddle.net/99w72efv/9/
$(function() {
$('#container').highcharts({
chart: {
type: 'spline'
},
yAxis: {max: 3},
series: [{
data: [2, 1, 0, 1, 3, 1, 2, 3, 0, 1, 2, 3, {x: 11.5, y: 3.2, marker: {enabled:false}}, 3, 1, 2, {x: 14.5, y: 2.2, marker: {enabled:false}}, 2, 0, 1]
}]
});
});

Highcharts: Add circle to scatter plot

I would like to draw a circle on a scatter plot to highlight values outside of the acceptable range.
I tried to use chart.renderer.circle but that uses the x and y pixels of the SVG element. I still want to be able to zoom in or out, so absolute x and y values don't work.
Is this possible with Highchart?
Edit:
Added Mockup:
Two ideas...
ONE
Use chart.renderer.circle and translate the point values to pixels.
Say you want to draw a circle at:
var circleX = 161.2; // x coordinate
var circleY = 51.6; // y coordinate
var circleR = 1.0; // radius size in terms of x axis distance
Draw the circle as:
function addCircle(chart){
if (this.circle){
// on a redraw, remove old circle
$(this.circle.element).remove();
}
// translate my coordinates to pixel values
var pixelX = chart.xAxis[0].toPixels(circleX);
var pixelY = chart.yAxis[0].toPixels(circleY);
var pixelR = chart.xAxis[0].toPixels(circleR) - chart.xAxis[0].toPixels(0);
// add my circle
this.circle = chart.renderer.circle(pixelX, pixelY, pixelR).attr({
fill: 'transparent',
stroke: 'black',
'stroke-width': 1
});
this.circle.add();
}
You then call this in the load and redraw events and all is awesome:
events: {
load: function(){
addCircle(this);
},
redraw: function(){
addCircle(this);
}
}
Here's a fiddle example.
TWO
Add the circle as another series, make the marker a giant transparent circle:
{
data: [[circleX, circleY]],
linkedTo: 'other', // link it to other series to avoid legend entry
marker: {
radius: 40,
lineColor: 'red',
fillColor: 'transparent',
lineWidth: 1,
symbol: 'circle'
}
}
Here's a fiddle for this one.

How do I add column-specific plotlines using High Charts?

I am trying to make a column chart using js HighCharts that has 2 unique plotlines for each column of the chart, rather than a single plotline that spans the width of the entire chart.
This way I will be able to show a max and min value for EACH column.
You can't make an actual plot line that works that way.
You can use a scatter series, and define a custom line marker type, like here:
http://jsfiddle.net/highcharts/e96yX/
example code for both a horizontal line and a vertical line:
Highcharts.Renderer.prototype.symbols.vline = function(x, y, width, height) {
return ['M',x ,y + width / 2,'L',x+height,y + width / 2];
};
Highcharts.Renderer.prototype.symbols.hline = function(x, y, width, height) {
return ['M',x ,y + height / 2,'L',x+width,y + width / 2];
};
alternatively, based on your question, a column range chart may be helpful as well:
http://highcharts.com/demo/columnrange

Categories

Resources