Highcharts plotbands different per category - javascript

I am attempting to create the following chart:
However I can't seem to get the plotbands to work in this way; right now, they fill the entire axis:
I am not sure if I should use annotations instead, but so far I haven't gotten it to work. What can I try next?
Highcharts.chart('container',{
credits: {
enabled: false
},
title: {
text: "hello world",
style: {
visibility: 'hidden'
}
},
chart: {
type: 'line',
width: 400,
},
legend: {
enabled: false
},
exporting: {
enabled: true,
allowHTML:true,
chartOptions: {
chart: {
marginLeft: 175,
marginRight: 175
},
plotOptions: {
line: {
dataLabels: {
style: {
fontSize: 14
},
verticalAlign: "top",
useHTML: true
}
}
}
}
},
yAxis: {
startOnTick: false,
endOnTick: false,
gridLineWidth: 2,
tickWidth: 2,
tickLength: 20,
plotBands: [{
color: 'rgba(231, 23, 60, 0.5)', // Color value
from: 5, // Start of the plot band
to: 6.2 // End of the plot band
},
{
color: 'rgba(53, 101, 237, 0.5)', // Color value
from: 1, // Start of the plot band
to: 3 // End of the plot band
}
],
title: {
align: 'high',
offset: -40,
text: 'mmol/L',
style: {
fontWeight: "bold",
fontSize: 15
},
rotation: 0,
y: -20
},
min: 0,
max: 7,
labels: {
x: -10,
y: -3,
formatter: function () {
if (this.value != 0) {
if (this.value < 8) {
return this.value;
}
}
},
style: {
fontWeight: "400",
lineHight: "20",
padding: "0",
fontSize: "13"
}
}
},
annotations: [{
shapes: [{
point: '0',
type: 'circle',
r: 10
}, {
point: '3',
type: 'rect',
width: 20,
height: 20,
x: -10,
y: -25
}, {
fill: 'none',
stroke: 'red',
strokeWidth: 3,
type: 'path',
points: ['0', '1', {
x: 6,
y: 195,
xAxis: 0,
yAxis: 0
}],
markerEnd: 'arrow'
}],
labels: [{
point: {
x: 6,
y: 195,
xAxis: 0,
yAxis: 0
}
}]
}],
xAxis: {
gridLineColor: 'transparent',
accessibility: {
rangeDescription: 'Range: 2010 to 2020'
},
categories: [2018, 2019]
},
plotOptions: {
line: {
dataLabels: {
style: {
fontSize: 14
},
verticalAlign: "top",
useHTML: true,
format: '<div style="max-width: 10ch; text-align: center;">{y}<br/>mmol/L</div>'
}
}
},
series: [{
name: '',
color: "black",
data: [5.4, 3],
showInLegend: false,
dataLabels: {
enabled: true,
useHTML: true,
}
}],
});
<script src="https://code.highcharts.com/highcharts.js"></script>
<script src="https://code.highcharts.com/modules/series-label.js"></script>
<script src="https://code.highcharts.com/modules/annotations.js"></script>
<script src="https://code.highcharts.com/modules/exporting.js"></script>
<script src="https://code.highcharts.com/modules/export-data.js"></script>
<script src="https://code.highcharts.com/modules/accessibility.js"></script>
<figure class="highcharts-figure">
<div id="container"></div>
</figure>

This kind of plotBand shape is not possible from the API level, but you can simulate it in several ways. Example configurations:
SVG Renderer:
chart: {
events: {
render() {
const chart = this;
if (chart.rects) {
chart.rects = chart.rects.destroy();
}
chart.rects = chart.renderer.g('rects').attr({
zIndex: 1
}).add();
let x = chart.xAxis[0].toPixels(1),
y = chart.yAxis[0].toPixels(4),
width = chart.xAxis[0].toPixels(2) - chart.xAxis[0].toPixels(1),
height = chart.yAxis[0].toPixels(2) - chart.yAxis[0].toPixels(4);
chart.rect = chart.renderer.rect(x, y, width, height)
.attr({
fill: 'grey'
}).add(chart.rects)
chart.rect = chart.renderer.rect(chart.xAxis[0].toPixels(3), y, width, height)
.attr({
fill: 'grey'
}).add(chart.rects)
}
}
},
Demo:
https://jsfiddle.net/BlackLabel/wst607ub/
API Reference:
https://api.highcharts.com/class-reference/Highcharts.SVGRenderer
Annotations:
annotations: [{
draggable: false,
shapes: [{
points: [{
x: 1,
y: 2,
xAxis: 0, // xAxis reference used, use xAxis value
yAxis: 0 // yAxis reference used, use xAxis value
}, {
x: 2,
y: 2,
xAxis: 0,
yAxis: 0
}, {
x: 2,
y: 4,
xAxis: 0,
yAxis: 0
}, {
x: 1,
y: 4,
xAxis: 0,
yAxis: 0
}],
type: 'path'
}]
}]
Demo:
https://jsfiddle.net/BlackLabel/uvxzp6o7/
API Reference:
https://api.highcharts.com/highcharts/annotations
Polygon series:
series: [{
name: 'Polygons',
type: 'polygon',
color: 'grey',
showInLegend: false,
enableMouseTracking: false,
states: {
inactive: {
opacity: 1,
},
},
data: [
[1, 2],
[2, 2],
[2, 4],
[1, 4],
null, // allows multiple polygons
[3, 2],
[4, 2],
[4, 4],
[3, 4],
]
}]
Demo:
https://jsfiddle.net/BlackLabel/4n7ep3k2/
API Reference:
https://api.highcharts.com/highcharts/series.polygon
Take note that annotations and polygon series require the module to be included.

Related

Y-axis exceeds the max value when height of highchart is decreased

The yAxis values min and max are set to 0 and 100 with a tick interval of 20 by me.
But when the resolution is changed to a lower resolution or the chart is zoomed in,
I have observed that the height of the high hart decreases and the max value is set to 120 and tick interval to 40 on its own
Which is not the desired behavior can you please help me out how to avoid it?
How can i make sure the max is 100 with a tickinterval 20 in all chart heights and also in turn in lower resolution.
Thanks in advance
Note:- I believe the height is decreased because the xAxis labels rotate diagonally as the width is decreased (in lower resolution) and that occupies more space in the HTML div and causes the height of the chart to decrease.
YAxis with expected behaviour
YAxis in lower resolution with decreased height
https://jsfiddle.net/BlackLabel/drgkt598/
Highcharts.chart('container', {
chart: {
type: "column",
height: 205,
plotBackgroundColor: "#D3D3D3",
width: 250,
},
title: {
text: ''
},
credits: {
enabled: false
},
plotOptions: {
series: {
dataLabels: {
enabled: false
},
pointPadding: 0
}
},
xAxis: {
lineWidth: 2,
type: 'category',
lineColor: '#000',
tickLength: 0
},
yAxis: [{
title: {
text: ''
},
min: 0,
max: 100,
tickInterval: 10,
gridLineWidth: 0,
plotLines: [{
value: 70,
color: 'black',
dashStyle: "Solid",
width: 4,
zIndex: 5,
label: {
text: 39,
align: "right",
x: 2,
y: -5,
style: {
color: 'black',
fontWeight: "bold",
fontSize: "18px",
}
}
}],
}, {
linkedTo: 0,
width: 60,
labels: {
enabled: false
},
plotBands: [{
color: 'rgb(204,0,0)',
from: 0,
to: 30.99,
zIndex: 1,
},
{
color: 'rgb(226,113,113)',
from: 31,
to: 44.99,
zIndex: 3,
},
{
color: 'rgb(247,209,34)',
from: 45,
to: 54.99,
zIndex: 3,
},
{
color: 'rgb(136,207,136)',
from: 55,
to: 68.99,
zIndex: 3,
},
{
color: 'rgb(68,180,68)',
from: 69,
to: 87.99,
zIndex: 3,
},
{
color: 'rgb(0,153,0)',
from: 88,
to: 100,
zIndex: 3,
}
]
}],
series: [{
dataLabels: {
color: "white",
verticalAlign: "bottom",
crop: false,
style: {
fontWeight: "Normal"
}
},
data: [{
y: 85,
name: 'A',
color: 'red',
dataLabels: {
formatter() {
return '<span style="font-size:11px;">A</span>';
},
y: -20
}
}, {
y: 72,
name: 'B',
color: 'green',
dataLabels: {
formatter() {
return '<span style="font-size:11px;">B</span>';
},
y: -15
}
}, {
y: 83,
name: 'C',
color: 'blue',
dataLabels: {
formatter() {
return '<span style="font-size:11px;">C</span>';
},
y: -15
}
}],
showInLegend: false
}]
});
Just like you have noted - there is not enough space to render 5 labels for some smaller dimensions, so implemented logic tries to calculate other timestamps, which will fit, like [0, 40, 80, 120].
I think that you can control it by using the responsive options and set the tickInterval to another value like 50.
Demo: https://jsfiddle.net/BlackLabel/zupbe174/
responsive: {
rules: [{
condition: {
maxHeight: 120
},
chartOptions: {
yAxis: [{
tickInterval: 50
}, {
}]
}
}]
}
API: https://api.highcharts.com/highcharts/responsive.rules.condition

When there is a plotband and a plotline emerging from yAxis how to set a particular width for plotband only in highchart

The plotline should spread across the graph but the plot band should of smaller width.
1) Initially without width being set.
2) When y axis width is set to 20
3) I want something like this where both the plot band and the plotline co exists
this is the fiddle code link to what I have tried so far.
Can someone please help me out thank you very much in advance.
https://jsfiddle.net/mncfy80p/
chart: {
type: "column",
height: 205,
plotBackgroundColor: "#D3D3D3",
width:250,
},
title : {
text:''
},
credits: {
enabled: false
},
plotOptions: {
series: {
dataLabels: {
enabled: true,
inside: true
},
pointPadding: 0
}
},
xAxis: {
visible:false,
},
yAxis: {
title: {
text: ''
},
min : 0,
max : 100,
tickInterval : 10,
gridLineWidth: 0,
plotLines: [{
value: 70,
color: 'black',
dashStyle: "Solid",
width: 4,
zIndex: 5,
label: {
text: 39,
align: "right",
x: 2,
y: -5,
style: {
color: 'black',
fontWeight: "bold",
fontSize: "18px",
}
}
}],
plotBands: [
{
color: 'rgb(204,0,0)',
from: 0,
to: 30.99,
zIndex: 3,
},
{
color: 'rgb(226,113,113)',
from: 31,
to: 44.99,
zIndex: 3,
},
{
color: 'rgb(247,209,34)',
from: 45,
to: 54.99,
zIndex: 3,
},
{
color: 'rgb(136,207,136)',
from: 55,
to: 68.99,
zIndex: 3,
},
{
color: 'rgb(68,180,68)',
from: 69,
to: 87.99,
zIndex: 3,
},
{
color: 'rgb(0,153,0)',
from: 88,
to: 100,
zIndex: 3,
}
],
},
series: [{
dataLabels: {
color: "white",
verticalAlign: "bottom",
crop: false,
style: {
fontWeight: "Normal"
}
},
data: [{
y: 85,
color:'red',
dataLabels: {
formatter(){
return '<span style="font-size:11px;">A</span>';
},
y:-20
}
}, {
y: 72,
color:'green',
dataLabels:{
formatter(){
return '<span style="font-size:11px;">B</span>';
},
y:-15
}
}, {
y: 83,
color:'blue',
dataLabels:{
formatter(){
return '<span style="font-size:11px;">C</span>';
},
y:-15
}
}],
showInLegend: false
}]
});
The simplest solution is to create another y-axis and move plot bands to it:
yAxis: [{
...,
plotLines: [...],
}, {
...,
plotBands: [...]
}]
Live demo: https://jsfiddle.net/BlackLabel/agq6ebjd/
API Reference: https://api.highcharts.com/highcharts/yAxis

I want to develop a Spider web graph/Radar graph using Highchart

I would like to develop a Spider Web Radar which looks similar to the graph shown in image below using highcharts. can you please tell me wether this could be achieved using High charts. please check the below code and image attached
This is my approach Fiddle.
Highcharts.chart('container', {
chart: {
polar: true,
type: 'area',
},
legend: {
enabled: false
},
title: {
text: 'Budget vs spending',
x: -90
},
pane: {
size: '90%'
},
xAxis: {
categories: ['Bonds', 'Future', 'Past', 'Value', 'Health', 'Divedend'],
tickmarkPlacement: 'on',
lineWidth: 0
},
yAxis: {
gridLineInterpolation: 'polygon',
lineWidth: 0,
min: 0,
labels:
{
enabled: false
}
},
tooltip: {
shared: true,
pointFormat: '<span style="color:{series.color}">{series.name}: <b>${point.y:,.0f}</b><br/>'
},
series: [{
color: {
linearGradient: {
x1: 0,
y1: 0,
x2: 1,
y2: 0
},
stops: [
[0, '#50e3c2'],
[1, '#50e3c2']
]
},
marker: {
enabled: false,
states: {
hover: {
radius: 8,
symbol: 'square',
}
}
},
name: 'Allocated Budget',
data: [80, 70, 60, 70, 70, 60],
pointPlacement: 'on',
shadow: {
color: '#000000',
width: 7,
opacity: 0.08,
offsetY: 3,
offsetX: 0
},
}]
});

Custom HighCharts - change the height of plotLines , show the marker value by default at a specific x and y

I am trying to customize highcharts
1) I need to change the height of the plotlines
2) Show the marker value inside the marker image itself at a specific place(Inside the white circles at the top)
This is what I have achieved so far
Highcharts.setOptions({
global: {
useUTC: false
}
});
/*function updateData(x,y)
{
var series = chart.series[0];
series.addPoint([x, y], true, true);
}*/
var chart;
$(function () {
var color = '#AA34FF';
$('#container').highcharts({
chart: {
events: {
load: function(event) {
_bindCustomEvents();
}
},
backgroundColor: 'transparent'
},
series: [
{
color:
{
linearGradient:
{
x1: 0,
y1: 0,
x2: 0,
y2: 1
},
stops:
[
/*[0, '#a83e3e'],
[0.21, '#d34e47'],
[0.40, '#edbb5a'],
[0.57, '#e2e57a'],
[0.76, '#8dcc63'],
[1, '#7ab237']*/
[0, '#7ab237'],
[0.21, '#8dcc63'],
[0.40, '#e2e57a'],
[0.57, '#edbb5a'],
[0.76, '#d34e47'],
[1, '#a83e3e']
]
},
lineWidth: 4,
marker: {
enabled: false,
fillColor: '#FFFFFF',
lineWidth: 2,
lineColor: null,
},
type: 'spline',
data: [1, 2, 5, 3, 6, 7, 4],
backgroundColor: 'transparent',
plotShadow : false
},
{
name: '',
marker: {
symbol: 'diamond'
},
//same inmage for all points
marker: {
symbol: 'url(http://fc08.deviantart.net/fs71/f/2014/016/b/9/top_marker_by_skyrbe-d72ewk0.png)'
},
data: [8,8,8,8,8,8,8],
type:'scatter'
},
{
name: '',
marker: {
symbol: 'diamond'
},
//same inmage for all points
marker: {
symbol: 'url(http://fc03.deviantart.net/fs71/f/2014/016/f/a/bottom_marker_by_skyrbe-d72ew7w.png)'
},
data: [-1,-1,-1,-1,-1,-1,-1],
type:'scatter'
}
],
xAxis: {
categories: [
'Sun',
'Mon',
'Tue',
'Wed',
'Thu',
'Fri',
'Sat'
],
title: {
enabled: true,
text: null,
},
labels: {
style: {
fontFamily: 'gestaregular',
fontSize: '16px',
color:'#fff'
}
},
plotLines: [
{ // mark the weekend
color: 'rgba(255,255,255,0.3)',
width: 1,
value: 0,
dashStyle: 'dash',
zIndex:10
},
{
color: 'rgba(255,255,255,0.3)',
width: 1,
value: 1,
dashStyle: 'dash',
zIndex:10
},
{
color: 'rgba(255,255,255,0.3)',
width: 1,
value: 2,
dashStyle: 'dash',
zIndex:10
},
{
color: 'rgba(255,255,255,0.3)',
width: 1,
value: 3,
dashStyle: 'dash',
zIndex:10
},
{
color: 'rgba(255,255,255,0.3)',
width: 1,
value: 4,
dashStyle: 'dash',
zIndex:10
},
{
color: 'rgba(255,255,255,0.3)',
width: 1,
value: 5,
dashStyle: 'dash',
zIndex:10
},
{
color: 'rgba(255,255,255,0.3)',
width: 1,
value: 6,
dashStyle: 'dash',
zIndex:10
}],
lineWidth: 0,
minorGridLineWidth: 0,
lineColor: 'transparent',
},
yAxis: {
labels: {
enabled: false
},
title: {
enabled: true,
text: null,
}
},
legend: {
enabled: false
},
minorTickLength: 0,
tickLength: 0
});
});
function _bindCustomEvents()
{
var chart = $('#container').highcharts();
chart.setTitle({ text: ''});
$('.highcharts-axis').hide();
$('.highcharts-grid').hide();
$('.highcharts-axis').find('path').hide();
}
FIDDLE LINK
This is how I want it to look like : Instead of '2' in the top circles , it should be the corresponding value from the center spline [1, 2, 5, 3, 6, 7, 4]
1) The plotLines are infinite. The extend as far as the plot area is. So, to limit this, how about you change your yAxis max:
yAxis: {
max: 8,
labels: {
enabled: false
},
title: {
enabled: true,
text: null
}
},
Or, you could create a column series on the points you want and give them a certain value for the height you want. Making the columns thin to mimic your plotLines will help like so:
series: [{
name: '',
type: 'column',
pointWidth: 1,
borderWidth: 0,
data: [8, 8, 8, 8, 8, 8, 8]
},
...
2) Which values in the circles (I am guessing)? The "Series 1: XX"? Or the whole tooltip?
EDIT:
For question 2 you can do this with a formatter function on the dataLabel for the scatter series (your circles). Here is the function:
var customFormatPoint = function (pointX, seriesIndex) {
var theChart = $('#container').highcharts();
var yValue = null;
var points = theChart.series[seriesIndex].options.data[pointX];
return points;
};
You call this from:
series: [{
name: '',
type: 'column',
pointWidth: 1,
borderWidth: 0,
dataLabels: {
enabled: true,
formatter: function () {
return customFormatPoint(this.point.x, 1);
}
},
data: [7.70, 7.70, 7.70, 7.70, 7.70, 7.70, 7.70]
}, {...
Key element here is that you have this.point.x which is that scatter point's xAxis location. You then need to send in which index the series is that contains the y value you want to show in the dataLabel.
I have also removed the plotLines and created a series that just contains the bars with width of 1 and no border. I had to mess around to get the end of the bar (its max value) to coincide with the scatter circle diameter.
Please see this jsFiddle.

HighCharts JS Ajax Data Guage

Could someone please assist me on modifying the code from HighCharts Angular Gauge demo to load data from a comma-separated values file?
The comma-separated values column should be specifiable. i.e: data[0], data[1], data[2]
$(function () {
$('#container').highcharts({
chart: {
type: 'gauge',
plotBackgroundColor: null,
plotBackgroundImage: null,
plotBorderWidth: 0,
plotShadow: false
},
title: {
text: 'Speedometer'
},
pane: {
startAngle: -150,
endAngle: 150,
background: [{
backgroundColor: {
linearGradient: { x1: 0, y1: 0, x2: 0, y2: 1 },
stops: [
[0, '#FFF'],
[1, '#333']
]
},
borderWidth: 0,
outerRadius: '109%'
}, {
backgroundColor: {
linearGradient: { x1: 0, y1: 0, x2: 0, y2: 1 },
stops: [
[0, '#333'],
[1, '#FFF']
]
},
borderWidth: 1,
outerRadius: '107%'
}, {
// default background
}, {
backgroundColor: '#DDD',
borderWidth: 0,
outerRadius: '105%',
innerRadius: '103%'
}]
},
// the value axis
yAxis: {
min: 0,
max: 200,
minorTickInterval: 'auto',
minorTickWidth: 1,
minorTickLength: 10,
minorTickPosition: 'inside',
minorTickColor: '#666',
tickPixelInterval: 30,
tickWidth: 2,
tickPosition: 'inside',
tickLength: 10,
tickColor: '#666',
labels: {
step: 2,
rotation: 'auto'
},
title: {
text: 'km/h'
},
plotBands: [{
from: 0,
to: 120,
color: '#55BF3B' // green
}, {
from: 120,
to: 160,
color: '#DDDF0D' // yellow
}, {
from: 160,
to: 200,
color: '#DF5353' // red
}]
},
series: [{
name: 'Speed',
data: [80],
tooltip: {
valueSuffix: ' km/h'
}
}]
},
// Add some life
function (chart) {
if (!chart.renderer.forExport) {
setInterval(function () {
var point = chart.series[0].points[0],
newVal,
inc = Math.round((Math.random() - 0.5) * 20);
newVal = point.y + inc;
if (newVal < 0 || newVal > 200) {
newVal = point.y - inc;
}
point.update(newVal);
}, 3000);
}
});
});
An Example of comma-separated values data being loaded into Highcharts Demo - Ajax loaded data, clickable points.
$(function () {
// Register a parser for the American date format used by Google
Highcharts.Data.prototype.dateFormats['m/d/Y'] = {
regex: '^([0-9]{1,2})\/([0-9]{1,2})\/([0-9]{2})$',
parser: function (match) {
return Date.UTC(+('20' + match[3]), match[1] - 1, +match[2]);
}
};
// Get the CSV and create the chart
$.get('/samples/highcharts/demo/line-ajax/analytics.csv', function (csv) {
$('#container').highcharts({
data: {
csv: csv
},
title: {
text: 'Daily visits at www.highcharts.com'
},
subtitle: {
text: 'Source: Google Analytics'
},
xAxis: {
type: 'datetime',
tickInterval: 7 * 24 * 3600 * 1000, // one week
tickWidth: 0,
gridLineWidth: 1,
labels: {
align: 'left',
x: 3,
y: -3
}
},
yAxis: [{ // left y axis
title: {
text: null
},
labels: {
align: 'left',
x: 3,
y: 16,
formatter: function() {
return Highcharts.numberFormat(this.value, 0);
}
},
showFirstLabel: false
}, { // right y axis
linkedTo: 0,
gridLineWidth: 0,
opposite: true,
title: {
text: null
},
labels: {
align: 'right',
x: -3,
y: 16,
formatter: function() {
return Highcharts.numberFormat(this.value, 0);
}
},
showFirstLabel: false
}],
legend: {
align: 'left',
verticalAlign: 'top',
y: 20,
floating: true,
borderWidth: 0
},
tooltip: {
shared: true,
crosshairs: true
},
plotOptions: {
series: {
cursor: 'pointer',
point: {
events: {
click: function() {
hs.htmlExpand(null, {
pageOrigin: {
x: this.pageX,
y: this.pageY
},
headingText: this.series.name,
maincontentText: Highcharts.dateFormat('%A, %b %e, %Y', this.x) +':<br/> '+
this.y +' visits',
width: 200
});
}
}
},
marker: {
lineWidth: 1
}
}
},
series: [{
name: 'All visits',
lineWidth: 4,
marker: {
radius: 4
}
}, {
name: 'New visitors'
}]
});
});
});
Many Thanks,
First of all I see that you have empty series.data which doesn't exists. In case when you download data by ajax, you push your data to series or use i.e setData() / addPoint() functions. All of them are documented here: http://api.highcharts.com/highcharts
I advice to familiar with article about preprocessing data http://docs.highcharts.com/#preprocessing

Categories

Resources