Is there a way using Highcharts, to achieve that kind of gradients?
Here is some jsfiddle boilerplate
var chart = new Highcharts.Chart({
chart: {
renderTo: 'chart',
type: 'pie'
},
exporting: {
enabled: false
},
credits: {
enabled: false
},
title: {
text: null
},
tooltip: {
enabled: false
},
plotOptions: {
pie: {
animation: false,
enableMouseTracking: false,
borderColor: 'transparent',
colors: ['#fdc81c', '#eee'],
borderWidth: 0,
innerSize: '60%',
dataLabels: {
enabled: false
}
}
},
series: [{ data: [80, 20] }]
})
Thanks!
you can use radial gradient for highcharts, but I'm afraid you would not get the filling of color as per the value.
highcharts have provided in their documentation here that radial and linear gradients can be used with highcharts.
Highcharts only have two types of gradients, linear and radial, so you cannot solve your problem using them. That is why I start thinking how to do it and after wasting a lot of time, I decided to implement it by dividing the chart in small slices with different colors.
Then I have a donut/pie chart with 100 little slices and each one has a different color.
Gradient color degraded from 0 to 100%
Gradient color degraded from 0 to 60%
I am developing a react-native application, so I post you the code here:
gradientColors.js
export default ['#41E500','#44E500','#47E500','#4AE500','#4DE600','#50E601','#53E601','#56E601','#59E701','#5CE702','#5FE702','#62E702','#65E802','#68E803','#6BE803','#6EE903','#71E903','#74E904','#77E904','#7AEA04','#7DEA04','#80EA05','#83EA05','#86EB05','#89EB05','#8CEB05','#8FEC06','#92EC06','#95EC06','#98EC06','#9BED07','#9EED07','#A1ED07','#A4ED07','#A7EE08','#AAEE08','#ADEE08','#B0EE08','#B3EF09','#B6EF09','#B9EF09','#BCF009','#BFF00A','#C2F00A','#C5F00A','#C8F10A','#CBF10A','#CEF10B','#D1F10B','#D4F20B','#D7F20B','#DAF20C','#DDF30C','#E0F30C','#E3F30C','#E6F30D','#E9F40D','#ECF40D','#EFF40D','#F2F40E','#F5F50E','#F8F50E','#FBF50E','#FFF60F','#FFF60F','#FFF20E','#FFEF0E','#FFEC0D','#FFE80D','#FFE50C','#FFE20C','#FFDE0C','#FFDB0B','#FFD80B','#FFD50A','#FFD10A','#FFCE0A','#FFCB09','#FFC709','#FFC408','#FFC108','#FFBE07','#FFBA07','#FFB707','#FFB406','#FFB006','#FFAD05','#FFAA05','#FFA705','#FFA705','#FF9805','#FF8906','#FF7B06','#FF6C07','#FF5D07','#FF4F08','#FF4008','#FF3109','#FF230A','#FF230A'];
ProgressChart.js
'use strict';
const Highcharts = 'Highcharts';
import { COLORS } from '#theme';
import gradientColors from './gradientColors';
const fakeData = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1];
const data = [{
y: 100,
color: COLORS.dark_red,
drilldown: {
name: 'Categories',
categories: ['A', 'B', 'C', 'D', 'E', 'F'],
data: fakeData,
color: COLORS.dark_red
}
}];
const donutData = [];
const donutDataOuter = [];
const dataLen = data.length;
// Build the data arrays
for (let i = 0; i < dataLen; i += 1) {
// add data
const drillDataLen = data[i].drilldown.data.length;
for (let j = 0; j < drillDataLen; j += 1) {
if (j > 60) {
donutData.push({
y: data[i].drilldown.data[j],
color: 'white',
borderColor: 'white'
});
donutDataOuter.push({
y: data[i].drilldown.data[j],
color: 'white',
borderColor: 'white'
});
} else {
donutData.push({
y: data[i].drilldown.data[j],
color: gradientColors[j],
borderColor: gradientColors[j]
});
donutDataOuter.push({
y: data[i].drilldown.data[j],
color: gradientColors[j],
borderColor: gradientColors[j]
});
}
}
}
const donutConf = {
chart: {
type: 'pie',
animation: Highcharts.svg
},
title: {
text: 'Equipment types (%)',
align: 'center',
verticalAlign: 'middle',
floating: true,
style: {
color: COLORS.light_grey_2,
fontWeight: 'bold',
fontSize: 38
}
},
plotOptions: {
pie: {
shadow: false,
center: ['50%', '50%']
},
showCheckbox: true
},
tooltip: {
formatter() {
return '<b>' + this.series.name + '</b><br/>' +
Highcharts.numberFormat(this.y, 2) + ' %';
}
},
legend: {
enabled: true
},
exporting: {
enabled: false
},
series: [
{
name: 'Categories',
data: donutData,
size: '93%',
innerSize: '58%',
dataLabels: {
enabled: false
},
id: 'inner'
},
{
name: 'Categories2',
data: donutDataOuter,
size: '100%',
innerSize: '97%',
dataLabels: {
enabled: false
},
id: 'outer'
}],
};
export default donutConf;
I have developed it very fast. So the example code above is for the 60% chart. In my final version I won't include this dirty if-else clauses I will solve it
Then in your case I recommend you to use this webpage http://www.perbang.dk/rgbgradient/ and use the number of steps that you need. For instance you can simply chose 2 from green to blue as I show you in this image. After copying the hex codes to the gradientColors variable you will be able to solve your problem.
Related
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.
I would like to place 2nd series of data in the middle of the X axis (inverted line chart).
Here is the fiddle and this is the result I would like to get:
https://jsfiddle.net/r03bvcj1/
https://i.imgur.com/Irqt4hi.png
I’ve managed to get it working partially for Y axis.However Impact Tolerance line has disappeared for some reason and I would like to have it against X axis.
https://jsfiddle.net/r03bvcj1/2/
Any help/pointers will be much appraciated.
var chart;
chart= Highcharts.chart('div-impactTolerance', {
chart: {
type: 'line',
inverted: true,
events: {
load: function() {
var check = $('#div-impactTolerance').highcharts();
var min = check.yAxis[0].min;
var max = check.yAxis[0].max;
var pLine = check.yAxis[0].chart.options.yAxis[0].plotLines[0].value;
if (pLine > max) {
check.yAxis[0].setExtremes(null, pLine);
}
if (pLine < min) {
check.yAxis[0].setExtremes(pLine, null);
}
}
}
},
tooltip: {
formatter: function () {
var formatter = this.y >1 ? ' days':' day';
var header ='<span style="font-size: 10px">' + this.key + '</span><br/>';
var point = this.series.name + ': <b>' + this.y + formatter + '</b><br/>';
return header + point;
}
},
credits: {
enabled: false
},
title: {
text: 'Impact Tolerance'
},
xAxis: [{
title: {
text: "Severity"
},
gridLineWidth: 1,
categories: ['Very High','High','Medium','Low']
},
{
visible: true,
title: {
text: "T"
},
gridLineWidth: 1,
categories: [1,2,3,4],
opposite: true
},
],
yAxis: {
tickInterval: 1,
allowDecimals:false,
title: {
text: "Time (days)"
},
min: 0,
gridLineWidth: 0,
minPadding: 0.30,
plotLines: [{
color: '#FF0000',
width: 2,
value: 6,
dashStyle: 'longdashdot',
label: {
text: 'Impact Tolerance ' ,
verticalAlign: 'middle',
textAlign: 'center',
x: -15
},
}]
},
series: [
{
name: 'Scenario Testing',
states: {
hover: {
enabled: false
}
},
data: [5,7,9,11,12,14,17,18],
xAxis: 1,
lineWidth: 0,
showInLegend: true,
marker: {
radius: 10
},
threshold: 6,
negativeColor: 'green',
color: 'red',
tooltip: {
valueDecimals: 2
}
},
{
name: 'Outage Duration',
states: {
hover: {
enabled: false
}
},
data: [1,2,3,4],
xAxis: 0,
lineWidth: 0,
showInLegend: true,
marker: {
radius: 10
},
threshold: 6,
negativeColor: 'green',
color: 'red',
tooltip: {
valueDecimals: 2
}
}
]
});
Currently there are two categories on the right on one category on the left. You should adjust your data in such a way that the x value does not exceed the number of categories:
xAxis: [{
...,
categories: ['Very High', 'High', 'Medium', 'Low']
},
{
...,
categories: [1, 2, 3, 4]
},
],
...,
series: [{
...,
data: [
[0, 5],
[0, 7],
[1, 9],
[1, 11],
[2, 12],
[2, 14],
[3, 17],
[3, 18]
]
},
{
...,
data: [1, 2, 3, 4]
}
]
Live demo: https://jsfiddle.net/BlackLabel/Lhpt2zdb/
Docs: https://www.highcharts.com/docs/chart-concepts/axes
See the attached image. So basically What I need is to draw rows with the chart. Like in image below, I want to show temperature on the chart as a line and snow/rain on the rows aligned with the axis. I have the temperature, rain and snow data in my series array.
Sample Data (For rain and snow, 1 mean yes):
series: [{
type: 'line',
data: [1,2,3,4,5,6,7,5,4,3,9,7],
name: 'Temperature'
}, {
data: [0,1,0,0,0,0,1,0,1,0,0,0],
name: 'Rain'
},{
data: [0,1,0,0,0,0,1,0,0,0,0,0],
name: 'Snow'
}]
You can use Renderer to draw a table but the data will not be treated as series but they will be simple static numbers with lines. However, you can use a heatmap series to have a chart as in the image.
You need 4 y axis - 1 for line, 2 for labels and the last two for snow and rain. The rest is adjusting axis positions though height and top properties.
Highcharts.chart('container', {
chart: {
spacingBottom: 0,
marginBottom: 0
},
legend: {
enabled: false
},
credits: {
enabled: false
},
xAxis: {
visible: false
},
yAxis: [{
height: '60%',
title: {
text: null
}
}, {
height: '10%',
top: '60%',
gridLineWidth: 0,
offset: 0,
endOnTick: false,
startOnTick: false,
title: {
text: null
},
visible: false
}, {
height: '10%',
top: '70%',
gridLineWidth: 0,
offset: 0,
// min: 0, max: 0,
endOnTick: false,
startOnTick: false,
title: {
text: null
},
categories: ['Rain']
}, {
height: '10%',
top: '80%',
gridLineWidth: 0,
offset: 0,
endOnTick: false,
startOnTick: false,
title: {
text: null
},
categories: ['Snow']
}],
colorAxis: {
stops: [
[0, 'white'],
[1, 'red']
]
},
plotOptions: {
heatmap: {
borderColor: 'black',
borderWidth: 0.5
}
},
series: [{
data: [1, 2, 3, 4, 5, 6, 7, 5, 4, 3, 9, 7],
name: 'Temperature',
step: 'left'
}, {
yAxis: 1,
type: 'heatmap',
data: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11].map(v => [0, v, 'white']),
showInLegend: false,
enableMouseTracking: false,
keys: ['y', 'value', 'color'],
dataLabels: {
enabled: true
}
}, {
yAxis: 2,
type: 'heatmap',
data: [0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0].map(v => [0, v]),
name: 'Rain'
}, {
type: 'heatmap',
yAxis: 3,
data: [0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0].map(v => [0, v]),
name: 'Snow'
}]
});
example: http://jsfiddle.net/euLz99mk/
I have a page that uses send data (in the example below the number 2) from a div to a javascript function but it does not seem to be working correctly. The alert comes up as shown. Any ideas?
THE DIV LINE
<div id="containerbar" data-F1="2" style="min-width: 200; height: 400px; margin: 0 auto"></div>
THE JAVASCRIPT
<script>
$(function () {
var $bardata = $("#containerbar");
var valueF1 = parseInt($bardata.data('F1'));
alert("Val1: " + valueF1);
$bardata.highcharts({
chart: {
type: 'bar'
},
title: {
text: 'Teacher count per slider'
},
xAxis: {
categories: ['Feedback', 'Challenge & differentiation', 'Classroom talk', 'Skills development', 'Expectations & relationships'],
title: {
text: null
}
},
yAxis: {
min: 0,
title: {
text: 'Count',
align: 'high'
},
labels: {
overflow: 'justify'
}
},
tooltip: {
valueSuffix: ' xx'
},
plotOptions: {
bar: {
dataLabels: {
enabled: true
}
}
},
legend: {
layout: 'vertical',
align: 'right',
verticalAlign: 'top',
x: -40,
y: 100,
floating: true,
borderWidth: 1,
backgroundColor: '#FFFFFF',
shadow: true
},
credits: {
enabled: false
},
series: [{
name: '1st quartile',
data: [valueF1 , 4, 1, 0, 0]
}, {
name: '2nd quartile',
data: [4, 4, 1, 0, 0]
},{
name: '3rd quartile',
data: [4, 4, 1, 0, 0]
}, {
name: '4th quartile',
data: [4, 4, 1, 0, 0]
}]
});
});
</script>
var valueF1 = parseInt($bardata.attr('data-F1'));
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.