Highcharts per-column gradient not always working - highcharts

I'm trying to make a chart where each column has a gradient assigned to it. It works fine when the screen size is wide or the number of points being displayed is small. For example, a mobile view displaying one week's worth of points works, but showing a month's or 3 month's doesn't. Instead of using the gradient it switches back to using a solid color.
Here is a jsfiddle link that should make it more clear. If you adjust the size of the window you should see the colors in the chart changing from each column having its own gradient to them all being the same solid color.
http://jsfiddle.net/12oqwvLj/
Thanks for the help!
-Karl
$.getJSON('https://www.highcharts.com/samples/data/jsonp.php?filename=aapl-v.json&callback=?', function (data) {
let answerData = data.map(dataPoint => {
let endColor
if ( dataPoint[1] > 28350555){
endColor = 'red'
} else {
endColor = 'green'
}
return {
x:dataPoint[0],
y:dataPoint[1],
color: {
linearGradient: {
x1: 0,
x2: 0,
y1: 0,
y2: 1
},
stops: [
[0, endColor],
[1, 'yellow']
]
},
}
})
// create the chart
Highcharts.stockChart('container', {
chart: {
alignTicks: false
},
rangeSelector: {
selected: 1
},
plotOptions:{
series:{
turboThreshold: 0
}
},
title: {
text: 'AAPL Stock Volume'
},
series: [{
type: 'column',
name: 'AAPL Stock Volume',
data: answerData
}]
});
});

Related

Highcharts area graph with fillColor changing color depending on the zone color?

I want to create a chart that will have a gradient of the colour of the tick under it as a region. It will change as it lands on a different data value with a different colour on the tick. The gradient will be from the tick colour to white.
Here is how it should look:
I managed to create different zone colors using "highcharts zones" and to set up a filling gradient using " highcharts fillColor". Now I can't understand how to generate a different filling color for each area.
This is my graph right now:
And this is part of my code linked to the problem:
this.chartOptions = {
...
plotOptions: {
area: {
pointStart: chartStart,
fillColor: {
linearGradient: {x1: 0, x2: 0, y1: 0, y2: 1},
stops: [
[0, 'red'],
[1, 'white']
]
}
}
},
series: [
{
type: 'area',
data: this.avgVoltageSeries,
pointInterval: ticksTime,
pointStart: chartStart,
zones: [{
value: this.fenceNodeConfiguration.criticalVoltage / 1000,
color: 'red'
}, {
value: this.fenceNodeConfiguration.warningVoltage / 1000,
color: 'orange'
}, {
color: '#009900'
}],
}]
};
Do you know if there is a way to change the filling color based on the area color?
You set the wrong zone, you have to set the zones with xAxis, not yAxis.
series: [
{
type: 'area',
data: this.avgVoltageSeries,
pointInterval: ticksTime,
pointStart: chartStart,
zones: [{
value: (new Date(new Date().setHours(10,0,0,0))).getTime(), // you should change the time here
color: 'red'
}, {
value: (new Date(new Date().setHours(12,0,0,0))).getTime(),// you should change the time here
color: 'orange'
}, {
color: '#009900'
}],
}]

Add different colour in X-range bar based on percentage

I want to add different colours for parts of the bar based on partialfill.
At the moment when the partialfill is 0.5 (50%) it makes half of the bar darker green. Is there a way to define colour in bar based on percentage?
For example
0-49 make the partialfill red and the rest white.
50-100 make the partial fill green and the rest white
etc.
https://jsfiddle.net/sg0co5au/11/
Highcharts.chart('container', {
chart: {
type: 'xrange'
},
title: {
text: 'Highcharts X-range'
},
xAxis: {
type: 'datetime'
},
yAxis: {
title: {
text: ''
},
categories: ['Prototyping', 'Development', 'Testing'],
reversed: true
},
series: [{
name: 'Project 1',
// pointPadding: 0,
// groupPadding: 0,
borderColor: 'gray',
pointWidth: 20,
colour:'#FF0000',
data: [{
x: Date.UTC(2014, 10, 21),
x2: Date.UTC(2014, 11, 2),
y: 0,
partialFill: 0.50,
color:'#469E5A'
},
],
dataLabels: {
enabled: true
}
}]
});
I see that the background rectangle is of class "highcharts-point highcharts-color-0 highcharts-partfill-original" with fill value #469E5A. Change that to "white" where ever you have defined its CSS.
The overlay on that is
<rect x="6.5" y="85.5" width="696" height="20" rx="3" ry="3" class="highcharts-partfill-overlay" clip-path="url(#highcharts-51rfx2r-4)" stroke="gray" stroke-width="1" fill="rgb(0,82,14)"></rect>
For the color by percentage use a variable to store the percentage like percent
if(percent<=49){
document.getElementsByClassName("highcharts-partfill-overlay").setAttribute("fill", "red")
}
else if(percent>49){
document.getElementsByClassName("highcharts-partfill-overlay").setAttribute("fill", "green")
}
You can change the color of the background box similarly using document.getElementsbyClassName()
Yes, you can set the color of your fill after the chart loads by checking against how much of the bar is filled.
First, set the chart options to a variable so you can refer to them later
var thisChart = Highcharts.chart('container', { /* your options here */ });
Next, after the chart loads, check to see whether the fill is below or above 50 (in this case, 0.5 to match the value you set in partialFill), and use the series.update() function (https://api.highcharts.com/class-reference/Highcharts.Series#update) to change the color:
if (thisChart.series[0].data[0].partialFill < 0.5) {
thisChart.series[0].update({
partialFill: {
fill: 'red'
}
});
} else {
thisChart.series[0].update({
partialFill: {
fill: '#469E5A'
}
});
}
I made a few minor changes to your code. First, I explicitly set the series fill color to the green you chose. Then, I set the color of your data to white. What this does is make the color of the partial fill to the series' color, and the other space to white. Then, when you check the partialFill value after the chart is drawn, if the value is below 0.5, the filled value will be red instead.
series: [{
name: 'Project 1',
borderColor: 'gray',
pointWidth: 20,
partialFill: {
fill:'#469E5A' /* default color of the filled part of the bar */
},
data: [{
x: Date.UTC(2014, 10, 21),
x2: Date.UTC(2014, 11, 2),
y: 0,
partialFill: 0.50,
color: 'white' /* color of the unfilled part of the bar */
}],
dataLabels: {
enabled: true
}
}]
See an updated version of your fiddle here: https://jsfiddle.net/brightmatrix/sg0co5au/46/
I hope this information is helpful for you.

Areaspline: edge to edge lines and hide first y label

I received a mockup of a graph using an areaspline (ignoring the column chart):
I have two questions that I can't seem to find any configuration that would satisfy the requirements.
Is there a way to extend the lines to the edge of the graph based on their trending slope, or possibly just a little above or below the end point? On a graph like this, it wouldn't look bad to omit those edge lines, but on a graph in the same area with only 3 data points, the whitespace is much more noticeable.
I have the y-axis labels stepping every other, but I can't seem to find a way to hide the first label ($0) in this case. Aside from just hiding the text element itself, is there a configuration to do this?
Edit: Here's an example of my configuration:
var themeColors = {
primaryColor: '#067bc2', //dark blue
secondaryColor: '#6a61a7', //dark purple
tertiaryColor: '#5ccadc', //turquoise
darkGray: '#37383e', //dark gray
mediumGray: '#919aa2', //medium gray
mediumLightGray: '#c9d3dc', //medium blue gray
lightGray: '#eaf1f8', //light blue gray (hover color)
primaryRed: '#e54443',
secondaryRed: '#e54443',
primaryGreen: '#2bbb2d',
secondaryGreen: '#2bbb2d',
primaryOrange: '#ffa883', //peach
primaryBackground: '#fafcfe',//light blue
secondaryBackground: '#ffffff',
primaryText: '#37383e', //dark gray
secondaryText: '#919aa2', //medium gray
selectedColor: '#f5fafd' //light blue, slightly darker than background
};
var colors = [
themeColors.secondaryColor,
themeColors.tertiaryColor,
themeColors.primaryOrange
];
(function renderChart(series) {
var options = {
chart: {
height: 400,
spacing: [0,0,0,0],
type: 'areaspline',
},
colors: colors,
credits: { enabled: false },
legend: {
align: 'left',
itemStyle: {
color: themeColors.secondaryText,
fontSize: '12px',
fontWeight: 'normal',
},
margin: 30,
symbolHeight: 14,
symbolRadius: 0,
symbolWidth: 14,
},
plotOptions: {
areaspline: {
marker: {
fillColor: themeColors.secondaryBackground,
lineColor: null,
lineWidth: 2,
radius: 3,
symbol: 'circle',
}
}
},
title: { text: null },
xAxis: {
categories: ['first', 'second', 'third'],
crosshair: {
color: Highcharts.color(themeColors.lightGray).setOpacity(.5).get('rgba'),
width: 12
},
labels: {
style: {
color: themeColors.secondaryText,
fontSize: '12px'
}
},
lineColor: themeColors.lightGray,
tickColor: themeColors.lightGray,
tickWidth: 0,
},
yAxis: {
gridLineColor: themeColors.lightGray,
labels: {
align: 'left',
step: 2,
style: {
color: themeColors.secondaryText,
fontSize: '12px'
},
x: 0,
y: 12,
},
lineColor: themeColors.lightGray,
tickColor: themeColors.lightGray,
title: { text: null },
},
};
series.forEach((s,i)=>{
s.fillColor = {
linearGradient: {
x1: 0,
y1: 0,
x2: 0,
y2: 1
},
stops: [
[0, Highcharts.color(colors[i]).setOpacity(0.1).get('rgba')],
[1, Highcharts.color(colors[i]).setOpacity(0).get('rgba')]
]
};
});
options.series = series;
Highcharts.chart('container',options);
})([
{ name: 'a', data:[1,4,2] },
{ name: 'b', data:[3,1,2] }
]);
jsFiddle: https://jsfiddle.net/mtowj6ng/
Thanks!!
You can set min and max of the axis.
xAxis: {
categories: ['first', 'second', 'third'],
min: 0.5,
max: 1.5,
If you have 3 categories, the axis range will be 0 - 2, so you can increase the min and decrease the max in the amount of 0.5 (the middle of the category).
You can also do it dynamically by updating the xAxis with xAxis.update on chart load.
chart: {
events: {
load: function () {
const min = Math.min.apply(null, this.series[0].xData)
const max = Math.max.apply(null, this.series[0].xData)
this.xAxis[0].update({
min: min + 0.5,
max: max - 0.5
})
}
}
},
You can also do it before you render the chart.
Set yAxis.showFirstLabel to false.
example: https://jsfiddle.net/bbd3pu9j/

How to draw following graph using Scatter Plot highchart?

How can i draw following graph using Scatter Plot highchart?
I am trying to achieve this kind of plot that is being displayed in screenshot using Highcharts. Till now I am able to Draw point onto the chart using Scatter Plot but I am having trouble plot these two red line from X-axis and Y-axis. Can anyone of you help me here the what I need to do to draw two straight line from a point, one toward X-axis and second toward Y-axis. The attached code is only the JS code that I used for ploting the scatter graph. Thanks
/* calculationChart */
$(function () {
$('#FHIchart').highcharts({
chart: {
type: 'scatter',
zoomType: 'xy'
},
title: {
text: 'Height Versus Weight of 507 Individuals by Gender'
},
subtitle: {
text: 'Source: Heinz 2003'
},
xAxis: {
title: {
enabled: true,
text: 'Strategic Alignment'
},
startOnTick: true,
endOnTick: true,
showLastLabel: true,
},
yAxis: {
title: {
text: 'Process & Technology Integration'
},
},
legend: {
layout: 'vertical',
align: 'left',
verticalAlign: 'top',
x: 100,
y: 70,
floating: true,
backgroundColor: (Highcharts.theme && Highcharts.theme.legendBackgroundColor) || '#FFFFFF',
borderWidth: 1
},
plotOptions: {
scatter: {
lineWidth: 2
}
},
series: [{
name: ' ',
color: 'Red',
data: [[3.1, 3]]
}]
});
});
here is my code.
Use renderer.path to draw a line. You can draw the line on load event and redraw it on redraw event.
events: {
load: function() {
var point = this.series[0].points[0],
{
plotX: x,
plotY: y
} = point;
point.path = this.renderer.path()
.add(point.series.group)
.attr({
stroke: point.color,
'stroke-width': 1,
d: `M 0 ${y} L ${x} ${y} L ${x} ${this.plotHeight}`
});
},
redraw: function() {
var point = this.series[0].points[0],
{
plotX: x,
plotY: y
} = point,
path = point.path;
if (path) {
path.attr({
d: `M 0 ${y} L ${x} ${y} L ${x} ${this.plotHeight}`
})
}
}
}
example: https://jsfiddle.net/5j208Lpb/
The other solution is to define 2 additional points which will have be drawn outside the plot area. You need to set axes limits and set series.lineWidth to 1.
example: https://jsfiddle.net/5j208Lpb/1/

Highcharts timeseries not correct plotted

Trying to get data from a backing bean to a Highchart line chart.
Problem is, that i need a timeseries with a datetime format, but Java cannot create a JS Date Object. Even with milliseonds, the chart won't display the date.
Sample code of the backing bean:
final List<LineChartSeries> series = new ArrayList<>();
final LineChartSeries chartSerie = new LineChartSeries();
final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
LineSeries2 lineSeries = new LineSeries2();
lineSeries.setY(0.654);
lineSeries.setDate(sdf.parse("2016-01-01").getTime());
chartSerie.addData(lineSeries);
lineSeries = new LineSeries2();
lineSeries.setY(0.337);
lineSeries.setDate(sdf.parse("2016-02-01").getTime());
chartSerie.addData(lineSeries);
lineSeries = new LineSeries2();
lineSeries.setY(0.547);
lineSeries.setDate(sdf.parse("2016-03-01").getTime());
chartSerie.addData(lineSeries);
series.add(chartSerie);
chartData = new Gson().toJson(series);
which produces a JSON like
[{"data":[{"date":1451602800000,"y":0.654},{"date":1454281200000,"y":0.337},{"date":1456786800000,"y":0.547}]}]
My JSF Page with the Highchart (part of)
<script type="text/javascript">
$(function () {
$('#ctrContainer').highcharts({
chart : {
zoomType: 'x'
},
title : {
text : 'VTR'
},
xAxis: {
type: 'datetime'
},
yAxis: {
title: {
text: 'Exchange rate'
}
},
legend: {
enabled: false
},
plotOptions: {
area: {
fillColor: {
linearGradient: {
x1: 0,
y1: 0,
x2: 0,
y2: 1
},
stops: [
[0, Highcharts.getOptions().colors[0]],
[1, Highcharts.Color(Highcharts.getOptions().colors[0]).setOpacity(0).get('rgba')]
]
},
marker: {
radius: 2
},
lineWidth: 1,
states: {
hover: {
lineWidth: 1
}
},
threshold: null
}
},
credits: {
enabled: false
},
series : $.parseJSON('#{lineChartController.chartData}')
});
The data for y-axis will be plotted correctly, but the "date" data are not correct interpreted. Any suggetions?

Resources