I grab the example from: https://www.highcharts.com/demo/column-stacked
Also referring some of the code from: How to use Vue bound data in Highcharts?
I build a sample as bellow:
<html>
<head>
<meta charset="utf-8">
<title></title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.13/vue.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/highcharts/7.1.1/highcharts.js"></script>
</head>
<body>
<div id="app">
<div id="container">
</div>
</div>
</body>
</html>
<script>
new Vue({
el: "#app",
data: {
chart: undefined,
config: {
chart: {
type: 'column'
},
title: {
text: 'Stacked column chart'
},
xAxis: {
categories: ['Apples', 'Oranges', 'Pears', 'Grapes', 'Bananas']
},
yAxis: {
min: 0,
title: {
text: 'Total fruit consumption'
},
stackLabels: {
enabled: true,
style: {
fontWeight: 'bold',
color: ( // theme
Highcharts.defaultOptions.title.style &&
Highcharts.defaultOptions.title.style.color
) || 'gray'
}
}
},
legend: {
align: 'right',
x: -30,
verticalAlign: 'top',
y: 25,
floating: true,
backgroundColor:
Highcharts.defaultOptions.legend.backgroundColor || 'white',
borderColor: '#CCC',
borderWidth: 1,
shadow: false
},
tooltip: {
headerFormat: '<b>{point.x}</b><br/>',
pointFormat: '{series.name}: {point.y}<br/>Total: {point.stackTotal}'
},
plotOptions: {
column: {
stacking: 'normal',
dataLabels: {
enabled: true
}
}
},
series: [{
name: 'John',
data: [3, 3, 4, 8, 2]
}, {
name: 'Jane',
data: [3, 2, 3, 2, 1]
}, {
name: 'Joe',
data: [3, 4, 4, 3, 5]
}]
},
},
mounted() {
this.render();
// simulation of some data changing after some time
setTimeout(() => {
this.config.series = [{
name: 'John',
data: [53, 23, 24, 27, 32]
}, {
name: 'Jane',
data: [23, 22, 23, 32, 31]
}, {
name: 'Joe',
data: [33, 24, 24, 32, 35]
}]
console.log('updated')
}, 3000)
},
watch: {
config() {
this.render();
},
},
methods: {
render() {
this.chart = Highcharts.chart('container', this.config)
}
}
})
</script>
But I don't know why the chart wouldn't redraw after config.series updated ( with higher value of each category).
The problem is your config watcher only watch the change of config not its nested properties so this.config.series = [...] won't trigger your watcher.
First solution, use deep option:
watch: {
config: {
handler() {
this.render()
},
deep: true
}
}
Demo
Second solution, use spread syntax to assign the whole object:
this.config = {
...this.config,
series: [{ /* */ }]
}
Demo
Here is the solution for you:
Destruct the config object in render method to lose a reference:
render() {
this.chart = Highcharts.chart('container', {...this.config});
}
Change your config watcher to deep (that way watcher will react when you are changing property that belongs to the object e.g. this.config.series = [...]):
config: {
deep: true,
handler() {
this.render();
}
}
Related
I'm trying to create a stacked column chart in highchart, with the x-axis labels being SVG-images as shown on this image:
I've gotten it to work with single data points per label (ie non-stacked data), but as soon I change the input data to an array, the data stops rendering.
This "works":
https://jsfiddle.net/jakobhl/krx4e5pm/2/
var dataName = function(imgSrc) {
return '<span><img src=' + imgSrc + ' ' + 'style="width: 40px; height: 40px;"/><br></span>';
};
var data2016 = [
[11, dataName("https://image.flaticon.com/icons/svg/197/197571.svg")],
[11, dataName("https://image.flaticon.com/icons/svg/197/197408.svg")],
[11, dataName("https://image.flaticon.com/icons/svg/197/197375.svg")],
[14, dataName("https://image.flaticon.com/icons/svg/197/197374.svg")],
[12, dataName("https://image.flaticon.com/icons/svg/197/197484.svg")],
];
Highcharts.chart('container', {
chart: {
type: 'column'
},
plotOptions: {
column: {
stacking: 'normal',
dataLabels: {
enabled: true
}
}
},
xAxis: {
tickmarkPlacement: 'on',
lineWidth: 0,
type: 'category',
labels: {
useHTML: true,
align: 'center'
}
},
series: [{
keys: ['y', 'name'],
data: data2016,
}]
});
<script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
<script src="https://code.highcharts.com/highcharts.js"></script>
<script src="https://code.highcharts.com/highcharts-more.js"></script>
<div id="container"></div>
This does not:
https://jsfiddle.net/jakobhl/2rfa645x/3/
var dataName = function(imgSrc) {
return '<span><img src=' + imgSrc + ' ' + 'style="width: 40px; height: 40px;"/><br></span>';
};
var data2016 = [
[[11, 15], dataName("https://image.flaticon.com/icons/svg/197/197571.svg")],
[[12, 15], dataName("https://image.flaticon.com/icons/svg/197/197408.svg")],
[[13, 15], dataName("https://image.flaticon.com/icons/svg/197/197375.svg")],
[[41, 15], dataName("https://image.flaticon.com/icons/svg/197/197374.svg")],
[[11, 15], dataName("https://image.flaticon.com/icons/svg/197/197484.svg")],
];
Highcharts.chart('container', {
chart: {
type: 'column'
},
plotOptions: {
column: {
stacking: 'normal',
dataLabels: {
enabled: true
}
}
},
xAxis: {
tickmarkPlacement: 'on',
lineWidth: 0,
type: 'category',
labels: {
useHTML: true,
align: 'center'
}
},
series: [{
keys: ['y', 'name'],
data: data2016,
}]
});
<script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
<script src="https://code.highcharts.com/highcharts.js"></script>
<script src="https://code.highcharts.com/highcharts-more.js"></script>
<div id="container"></div>
How can I get the data to stack per country while still using SVGs as labels?
Thanks to the jsfiddle user BlackLabel for inspiration.
You can add another value, but you need to adapt the data format required by Highcharts. If the new value is x, just do it as below:
var data2016 = [
[
11, 15, dataName("https://image.flaticon.com/icons/svg/197/197571.svg")
],
...
];
Highcharts.chart('container', {
...,
series: [{
keys: ['y', 'x', 'name'],
data: data2016
}]
});
Live demo: https://jsfiddle.net/BlackLabel/vubjn8od/
API Reference: https://api.highcharts.com/highcharts/series.column.keys
I never found out why the original solution didn't work, but a working solution was to use categories instead of series:
https://jsfiddle.net/jakobhl/L3hzeqpv/1/
var dataName = function(imgSrc) {
return '<span><img src=' + imgSrc + ' ' + 'style="width: 40px; height: 40px;"/><br></span>';
};
Highcharts.chart('container', {
chart: {
type: 'column'
},
title: {
text: 'Stacked column chart'
},
xAxis: {
labels: {
useHTML: true,
align: 'center'
},
categories: [dataName("https://image.flaticon.com/icons/svg/197/197571.svg"), dataName("https://image.flaticon.com/icons/svg/197/197408.svg"), dataName("https://image.flaticon.com/icons/svg/197/197375.svg"), dataName("https://image.flaticon.com/icons/svg/197/197374.svg"), dataName("https://image.flaticon.com/icons/svg/197/197484.svg")]
},
yAxis: {
min: 0,
title: {
text: 'Total fruit consumption'
},
stackLabels: {
enabled: true,
style: {
fontWeight: 'bold',
color: ( // theme
Highcharts.defaultOptions.title.style &&
Highcharts.defaultOptions.title.style.color
) || 'gray'
}
}
},
legend: {
align: 'right',
x: -30,
verticalAlign: 'top',
y: 25,
floating: true,
backgroundColor:
Highcharts.defaultOptions.legend.backgroundColor || 'white',
borderColor: '#CCC',
borderWidth: 1,
shadow: false
},
tooltip: {
headerFormat: '<b>{point.x}</b><br/>',
pointFormat: '{series.name}: {point.y}<br/>Total: {point.stackTotal}'
},
plotOptions: {
column: {
stacking: 'normal',
dataLabels: {
enabled: true
}
}
},
series: [{
name: 'John',
data: [5, 3, 4, 7, 2]
}, {
name: 'Jane',
data: [2, 2, 3, 2, 1]
}, {
name: 'Joe',
data: [3, 4, 4, 2, 5]
}]
});
<script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
<script src="https://code.highcharts.com/highcharts.js"></script>
<script src="https://code.highcharts.com/highcharts-more.js"></script>
<div id="container"></div>
I'm using Highcharts' x-range chart module to render a range of multiple values. I have a couple of issues in implementing it.
The hover and select states are not having any effect on the chart
The legend icon is not showing the color of the data
Code below:
var myChart7 = Highcharts.chart('sample', {
chart: {
type: 'xrange',
},
title: null,
xAxis: {
opposite: true,
labels: {
useHTML: true,
formatter: function() {
return this.value + "ms";
},
}
},
yAxis: {
title: {
text: ''
},
labels: {
enabled: true,
},
categories: [],
reversed: true
},
tooltip: {
enabled: false
},
plotOptions: {
series: {
dataLabels: {
enabled: true
},
allowPointSelect: true,
states: {
hover: {
color: '#a4edba'
},
select: {
color: '#EFFFEF',
borderColor: 'black',
dashStyle: 'dot'
}
},
pointWidth: 15,
borderRadius: 10,
dashStyle: 'Solid',
}
},
legend: {
enabled: true,
align: 'left',
},
series: [{
color: '#C4D9FF',
name: 'Sample 1',
data: [{
x: 0,
x2: 90,
y: 0,
response: '200',
color: '#C4D9FF',
borderColor: '#789CDF',
}],
},
{
color: '#FFD7C5',
name: 'Sample 2',
data: [{
x: 5,
x2: 70,
y: 1,
response: '200',
color: '#FFD7C5',
borderColor: '#F99B6F',
}],
}, {
color: '#DCFFF5',
name: 'Sample 3',
data: [{
x: 35,
x2: 70,
y: 2,
response: '400',
color: '#DCFFF5',
borderColor: '#35C097',
}],
}
],
});
<div id="sample">
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/highcharts/6.0.4/highstock.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/highcharts/6.0.4/modules/xrange.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/highcharts/6.0.4/highcharts-more.js"></script>
JSFiddle link
I don't know if I'm implementing it in the right or wrong way. Please guide me. TIA.
I'm working on Chrome version 85 on mac. Haven't tested it on other browsers.
Those features hasn't been implemented in the version of the Highcharts which you are using. In the current version everything works fine: https://jsfiddle.net/BlackLabel/trxjw4np/
In the x-range series type the legend item doesn't inherit the color from the series, but you can set it programmatically.
Demo: https://jsfiddle.net/BlackLabel/trxjw4np/
events: {
load() {
let chart = this;
chart.legend.allItems.forEach(item => {
item.legendSymbol.css({
fill: item.userOptions.color
})
})
}
}
API: https://api.highcharts.com/highcharts/chart.events.load
I have included a Highcharts chart embed on my website. Now I would like to create many additional charts using other series data. However, I would like all of these additional charts have exactly the same styling and be the same type as my chart1. The only things I will have to change in each chart is the subtitle and series name. I can easily just copy my chart1 code and rename it chart2, chart3 etc. and this works fine. However, I would very much like to just replicate my chart1 for the other data series while only changing subtitles and series name for each data series (CHART1 SUBTITLE and CHART1 SERIESNAME).
I have tried different solutions but none worked so far. Below is the code I have made for my chart1.
chartOptions.chart1 = {
chart: {
type: 'column'
},
title: {
text: 'CHARTNAME',
style: {
fontFamily: 'Montserrat,serif',
spacingTop: 30,
fontSize: '22px'
}
},
subtitle: {
text: 'CHART1 SUBTITLE',
align: 'left',
x: 55,
style: {
fontFamily: 'Montserrat,serif',
spacingTop: 25,
color: "#000",
fontSize: '14px'
}
},
xAxis: {
categories: [],
labels: {
rotation: -20,
}
},
yAxis: {
title: {
text: 'TITLETEXT',
rotation: 270,
y: -30
},
},
series: [{
name: 'CHART1 SERIESNAME',
color: '#006699',
data: []
}],
tooltip: {
}
},
};
Below is the code I use to initialize the series data in chart1. Here I have added a 'chart2' and I essentially hoped it would somehow be able to initialize that in 'chart1' and somehow also changing the chart subtitle and series name.
$('chart').ready(function() {
var tableName = '<?php echo $tableName; ?>'
$.getJSON("../companychart/chartdataNew.php", {id: escape(tableName)}, function(json) {
chartOptions.chart1.xAxis.categories = json['XAXIS NAME']['data'];
chartOptions.chart1.series[0].data = json['SERIES 1']['data'];
chartOptions.chart2.xAxis.categories = json['XAXIS NAME']['data'];
chartOptions.chart2.series[0].data = json['SERIES 2']['data'];
});
You can use Highcharts.merge method to extend default options (used in each chart) by particular chart options (series, subtitle). Check the demo posted below.
HTML:
<script src="https://code.highcharts.com/highcharts.js"></script>
<div id="container1"></div>
<div id="container2"></div>
<div id="container3"></div>
JS:
var chart1 = {
subtitle: {
text: 'CHART1 SUBTITLE',
},
series: [{
name: 'CHART1 SERIESNAME',
color: '#006699',
data: [1, 2, 3, 4, 5]
}]
},
chart2 = {
subtitle: {
text: 'CHART2 SUBTITLE',
},
series: [{
name: 'CHART2 SERIESNAME',
color: '#0034ef',
data: [5, 1, 2, 6, 2]
}]
},
chart3 = {
subtitle: {
text: 'CHART3 SUBTITLE',
},
series: [{
name: 'CHART3 SERIESNAME',
color: '#23ee45',
data: [3, 5, 2, 3, 1]
}]
},
chartDefaultOptions;
chartDefaultOptions = {
chart: {
type: 'column'
},
title: {
text: 'CHARTNAME',
style: {
fontFamily: 'Montserrat,serif',
spacingTop: 30,
fontSize: '22px'
}
},
subtitle: {
align: 'left',
x: 55,
style: {
fontFamily: 'Montserrat,serif',
spacingTop: 25,
color: "#000",
fontSize: '14px'
}
},
xAxis: {
categories: [],
labels: {
rotation: -20,
}
},
yAxis: {
title: {
text: 'TITLETEXT',
rotation: 270,
y: -30
},
}
};
Highcharts.chart('container1', Highcharts.merge(chartDefaultOptions, chart1));
Highcharts.chart('container2', Highcharts.merge(chartDefaultOptions, chart2));
Highcharts.chart('container3', Highcharts.merge(chartDefaultOptions, chart3));
Demo:
https://jsfiddle.net/BlackLabel/7utogs95/
highchart doesn't show in IE and SAFARI. I try the solution from the official highchart forum, but nothing help (remove "," at the end of json, or resize page on load etc... )
I have multiple different highcharts, but here is only one for explanation. I call config function depends on chart data. My app have many different parts, and it's very hard to make working plunker. Thnx
Here is my code
function getBaseChartConfig(graphName) {
Highcharts.setOptions({
global: {
useUTC: false
}
});
var config =
{
xAxis: {
ordinal: false
},
yAxis: {
},
options: {
chart: {
zoomType: 'x',
backgroundColor: 'rgba(255, 255, 255, 1)',
polar: true,
type: 'line',
borderRadius: 5
},
legend: {
enabled: true
},
rangeSelector: {
//za postavit rucni upis date range-a
enabled: false,
inputStyle: {
color: 'black'
}
},
navigator: {
enabled: true
}
},
series: [],
title: {
text: graphName
},
useHighStocks: true
};
return config;
};
$scope.data.push(solar_voltage);
$scope.data.push(battery_voltage);
$scope.data.push(solar_current);
$scope.data.push(hybridCurrent);
$scope.chartConfig1 = getChartConfigWithYaxisPlotLines('Production');
$scope.chartConfig1.series.push({
id: 1,
name: "Solar voltage",
data: $scope.data[0],
tooltip: {
valueDecimals: 2
}
}, {
id: 2,
name: "Battery voltage",
data: $scope.data[1],
tooltip: {
valueDecimals: 2
}
}, {
id: 3,
name: "Solar current",
data: $scope.data[2],
tooltip: {
valueDecimals: 2
}
}, {
id: 4,
name: "Hybrid current",
data: $scope.data[3],
tooltip: {
valueDecimals: 2
}
}
);
function getChartConfigWithYaxisPlotLines(graphName) {
var baseChartConfig = getBaseChartConfig(graphName);
baseChartConfig.yAxis.plotLines = [{
color: '#FF0000',
width: 1,
value: 11.50,
label: {text: '11.50'}
}];
return baseChartConfig;
}
Here is image how this look in safari or IE
And here is in CHROME and FIREFOX
This is my json from api
I am working on this demo. Why is the plot options color not getting the bar colors from the Color options (two colors)? As you can see it is taking color from only one for both colors.
$(function () {
chart1 = new Highcharts.Chart({
chart: {
renderTo: 'container',
type: 'bar'
},
plotOptions: {
column: {
colorByPoint: true
},
series: {
pointWidth: 50
}
},
colors: [
'#D9844B',
'#3F4539'],
credits: {
enabled: false
},
title: {
text: 'Test',
style: {
color: '#2d2d2d',
fontWeight: 'normal',
fontSize: '11',
marginBottom: '30'
}
},
xAxis: {
categories: ['Ecology & Economics', 'Economics Only'],
},
yAxis: {
tickInterval: 50,
max: 300,
title: {
text: 'Number of ROR Facilities'
}
},
legend: {
enabled: false
},
tooltip: {
formatter: function () {
return this.x + ' <b> : ' + this.y + '</b>';
}
},
series: [{
data: [29.9, 71.5],
dataLabels: {
enabled: true,
color: '#2d2d2d',
align: 'right',
x: -40,
y: 0,
style: {
fontSize: '12px',
fontFamily: 'Verdana, sans-serif'
}
}
}]
});
});
I think the documentation is wrong. It says that colorByPoint is a bar/column option but you are correct it isn't working. Moving it to a series option and it does work:
plotOptions: {
series: {
pointWidth: 50,
colorByPoint: true
}
},
Updated fiddle.
Referring to #Mark answer, the Highcharts documentation is correct.
There is a difference between defining options in every series in Highcharts, especially bar and column series are different series.
You are using bar series (chart.type: 'bar'), but in plotOptions you are defining colorByPoint only for a column series which, obviously, does not even exist in your chart.
You have many solutions:
1) You can define colorByPoint inside a specific series options:
chart: {
type: 'bar'
},
series: [{
colorByPoint: true,
data: [4, 3, 5]
}]
2) you can define colorByPoint for all series:
chart: {
type: 'bar'
},
plotOptions: {
series: {
colorByPoint: true
}
},
series: [{
data: [4, 3, 5]
}]
3) You can define colorByPoint for all bar type series:
chart: {
type: 'bar'
},
plotOptions: {
bar: {
colorByPoint: true
}
},
series: [{
data: [4, 3, 5]
}]
4) You can use inverted column type series (which is actually a bar series):
chart: {
type: 'column',
inverted: true
},
plotOptions: {
column: {
colorByPoint: true
}
},
series: [{
data: [4, 3, 5]
}]
5) You can also define the color for each bar separately:
series: [{
type: 'bar',
data: [{
y: 4,
color: 'red'
}, {
y: 3,
color: 'blue'
}, {
y: 5,
color: 'green'
}]
}]
And even more. Above solution should be enough for you.
Remember, plotOptions.column will not work for chart.type: 'bar'.