How to make mathematical chart with HighCharts? - javascript

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]
}]
});
});

Related

Putting the Z-Coordinate in the Highcharts Tooltip

I have three graphs. All three graphs have the same x axis values (category), different y-values, and the same z-value (date). The graphs have synced tooltips when you hover over a point. I want to be able to populate the tooltip with the z-coordinate for each point. I do not want to plot the z coordinate... just have it show in the tooltip. I am not sure how to do this because there are more multiple graphs with synced tooltips.
I made a basic example to show how to put the z-value (date) in a tooltip for one graph. https://codepen.io/austeng/pen/ZEGxWyK
Highcharts.chart('container', {
tooltip: {
formatter: function() {
return 'x: ' + this.x + ', y: ' + this.y + ', z: ' + Highcharts.dateFormat('%b/%e/%Y',
new Date(this.point.z));
}
},
xAxis:{
type: 'category'
},
series: [{
data: [{
x: 0,
y: 0,
z: 1564358400000
},
{
x: 1,
y: 5,
z: 1564531200000
},
{
x: 2,
y: 2,
z: 1564963200000
}
]
}]
});
This is my codepen for the three graphs: https://codepen.io/austeng/pen/gOppRWY
Any help on how to extend my example for one graph to my current code of three graphs w/sync tooltip would be very appreciated. Thanks.
I think that it will be better to achieve it in a different way.
Create some global function, let's say setTooltip which will take a point as a parameter.
For each chart config set the tooltip.pointFormatter callback which returns above function.
tooltip: {
pointFormatter() {
let point = this;
return setTooltip(point)
}
},
Use the keys feature to get the z value in the point object.
API: https://api.highcharts.com/highcharts/series.line.keys
Final output: https://jsfiddle.net/BlackLabel/sjv18rbn/

Is there a way to calculate custom label position on a Highcharts Activity Gauge?

I have a Highcharts activity gauge that has two series. I am trying to place labels at the starting point of each ring. I have it working with hardcoded x,y coordinates, but I'm wondering if there is a way to calculate the location instead. It looks like this currently:
Here is the code I am using to add the labels in the chart render event:
function render() {
var chart = this;
chart.renderer.label('Completed 65%', 24, 25, 'rect', 0, 0, true, true, '')
.add();
chart.renderer.label('Follow-up 45%', 28, 42, 'rect', 0, 0, true, true, '')
.add();
}
I'd like to calculate the x,y values in the chart.renderer.label() function instead of hardcoding them to 24,25 and 28,42. However, I have not been able to find anything in the object model to locate the physical location of the series starting x and y, or the size of the label. I have many of these activity gauges to complete and going through them all and trying to find the magic coordinates seems like the wrong approach.
You can follow the same approach as icons rendered in the official Activity gauge demo here: https://jsfiddle.net/gh/get/library/pure/highcharts/highcharts/tree/master/samples/highcharts/demo/gauge-activity/
There you will find position calculated using series point shapeArgs. I modified that function to render labels as you expected. Check it in the demo posted below.
Function code:
function renderLabels() {
var offsetTop = 5,
offsetLeft = 5;
if (!this.series[0].label) {
this.series[0].label = this.renderer
.label('Completed 65%', 0, 0, 'rect', 0, 0, true, true)
.add(this.series[1].group);
}
this.series[0].label.translate(
this.chartWidth / 2 - this.series[0].label.width + offsetLeft,
this.plotHeight / 2 - this.series[0].points[0].shapeArgs.innerR -
(this.series[0].points[0].shapeArgs.r - this.series[0].points[0].shapeArgs.innerR) / 2 + offsetTop
);
if (!this.series[1].label) {
this.series[1].label = this.renderer
.label('Follow-up 45%', 0, 0, 'rect', 0, 0, true, true)
.add(this.series[1].group);
}
this.series[1].label.translate(
this.chartWidth / 2 - this.series[1].label.width + offsetLeft,
this.plotHeight / 2 - this.series[1].points[0].shapeArgs.innerR -
(this.series[1].points[0].shapeArgs.r - this.series[1].points[0].shapeArgs.innerR) / 2 + offsetTop
);
}
Function invocation:
chart: {
type: 'solidgauge',
events: {
render: renderLabels
}
}
Demo:
https://jsfiddle.net/BlackLabel/vpj32tmy/

set minimum and maximum values for axis' data in highchart

I want to set minimum and maximum values in an axis in highcharts. I have tried min, max, ceiling and floor attributes. They change the range of axis.
Link to the JS Fiddle
yAxis: {
floor: 0,
ceiling: 40,
title: {
text: 'Percentage'
}
},
series: [{
data: [0, 1, -5, 2, 3, 5, 8, 5, 50, 14, 25, 54]
}]
I want the data to be modified automatically based on the minimum/floor and maximum/ceiling values declared in the axis declaration.
For example, if in the above mentioned case, the last and last 4th elements of series should be automatically modified to 40 and the 3rd element to 0.
Is there any attribute of highchart using which I can achieve this without manually checking all the series elements to fall between the min and max values?
No I don't think there is no such a function. Highcharts does not alter your data, it just changes what is displayed. But checking for values beneath or above certain thresholds is really simple:
var data = [0, 1, -5, 2, 3, 5, 8, 5, 50, 14, 25, 54];
var max = 40;
var min = 0;
// clamping "by hand"
console.log( data.map(function(d) { return Math.max(min, Math.min(max, d)); }) );
If you use a library like lodash: these often provide a clamp function so you could write
console.log( _.map(data, function(d) { return _.clamp(d, min, max) }

JavaScript, Plotly: How to customise axis labels on bar plot?

I am plotting a bar chart with date values on the x-axis. Simply setting the values for bins and bar heights gives the desired plot, but the axis labels (date values) are positioned below centres of the bars (see the screenshot).
However each bar represents date range and I would like the labels to be located below the edges of the bars. How do I do that?
You could convert your plot to a scatter line plot and fill it to the x-axis. The labels appearing on the x-axis can be specified via layout: xaxis: tickvals.
If you want equally size bars, set layout: xaxis: type to category.
var data = {
x: ['2013-11-02', '2013-11-04', '2013-11-05', '2013-11-07', '2013-11-09', '2013-11-11', '2013-11-13'],
y: [1, 3, 6, 4, 5, 2, 6],
};
var trace = {
x: [],
y: [],
type: 'scatter',
mode: 'lines',
fill: 'tozeroy'
};
for (var i = 0; i < data.x.length - 1; i += 1) {
trace.x.push(data.x[i]);
trace.y.push(0);
trace.x.push(data.x[i]);
trace.y.push(data.y[i]);
trace.x.push(data.x[i + 1]);
trace.y.push(data.y[i]);
}
trace.x.push(data.x[data.x.length - 1]);
trace.y.push(0);
var layout = {
xaxis: {
type: 'category',
tickvals: data.x,
tickangle: -45
}
}
Plotly.newPlot('myDiv', [trace], layout);
<script src="https://cdn.plot.ly/plotly-latest.min.js"></script>
<div id="myDiv"></div>

Highcharts - Column/bar chart with target lines

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/

Categories

Resources