I have two charts that I am trying to load on separate div's on the same page, they are similar but one is a drill down and the other isn't. I have tried wrapping the entire function with var chart = $('#review').highcharts({ but it doesn't work.
The two charts are below:
$(function () {
var colors = Highcharts.getOptions().colors,
categories = ['Metric 1', 'Metric 2', 'Metric 3','metric 4'],
name = 'Votes',
data = [{
y: 1,
color: colors[0],
}, {
y: 2,
color: colors[1],
}, {
y: 3,
color: colors[2],
},{
y: 5,
color: colors[3],
}];
function setChart(name, categories, data, color) {
chart.xAxis[0].setCategories(categories, false);
chart.series[0].remove(false);
chart.addSeries({
name: name,
data: data,
color: color || 'white'
}, false);
chart.redraw();
}
var chart = $('#review').highcharts({
chart: {
type: 'column'
},
title: {
text: 'Review breakdown'
},
xAxis: {
categories: categories
},
tooltip: {
formatter: function() {
var point = this.point,
s = this.x +'<br><b>'+ this.y +' stars</b><br/>';
return s;
}
},
series: [{
name: name,
data: data,
color: 'white'
}],
exporting: {
enabled: false
},
legend: {
enabled: false
},
credits: {
enabled: false
}, yAxis: {min: 0, max: 5,
title: {text: 'Star Rating'}
}
})
.highcharts(); // return chart
});
$(function () {
var colors = Highcharts.getOptions().colors,
categories = ['positive', 'negative', 'sum'],
name = 'Votes',
data = [{
y: 55.11,
color: colors[0],
drilldown: {
name: 'Positive votes',
categories: ['Users', 'Admin', 'Anonymous'],
data: [10.85, 7.35, 33.06],
color: colors[0]
}
}, {
y: -7.15,
color: colors[3],
drilldown: {
name: 'Negative votes',
categories: ['Users', 'Admin', 'Anonymous'],
data: [-4.55, -1.42, -0.23],
color: colors[3]
}
}, {
y: 2.14,
color: colors[4],
drilldown: {
name: 'Total votes',
categories: ['Users', 'Admin', 'Anonymous'],
data: [ 0.12, 0.37, 1.65],
color: colors[4]
}
}];
function setChart(name, categories, data, color) {
chart.xAxis[0].setCategories(categories, false);
chart.series[0].remove(false);
chart.addSeries({
name: name,
data: data,
color: color || 'white'
}, false);
chart.redraw();
}
var chart = $('#votes').highcharts({
chart: {
type: 'column'
},
title: {
text: 'Vote breakdown'
},
subtitle: {
text: 'Click the columns to view breakdown.'
},
xAxis: {
categories: categories
},
yAxis: {
title: {
text: 'Total votes'
}
},
plotOptions: {
column: {
cursor: 'pointer',
point: {
events: {
click: function() {
var drilldown = this.drilldown;
if (drilldown) { // drill down
setChart(drilldown.name, drilldown.categories, drilldown.data, drilldown.color);
} else { // restore
setChart(name, categories, data);
}
}
}
},
dataLabels: {
enabled: true,
color: colors[0],
style: {
fontWeight: 'bold'
}
}
}
},
tooltip: {
formatter: function() {
var point = this.point,
s = this.x +':<b>'+ this.y +' votes</b><br/>';
if (point.drilldown) {
s += 'Click to view '+ point.category +' breakdown';
} else {
s += 'Click to return';
}
return s;
}
},
series: [{
name: name,
data: data,
color: 'white'
}],
exporting: {
enabled: false
},
legend: {
enabled: false
},
credits: {
enabled: false
},
})
.highcharts(); // return chart
});
If you're trying to get two charts on one page then it is VERY simple.
<div id="chart-A" class="chart"></div>
<div class="spacer"></div>
<div id="chart-B" class="chart"></div>
CSS - Just to make the example a little easier on the eyes
.chart {
height: 200px;
}
.spacer {
height: 20px;
}
JavaScript
$(function() {
// If you need to specify any global settings such as colors or other settings you can do that here
// Build Chart A
$('#chart-A').highcharts({
chart: {
type: 'column'
},
title: {
text: 'Chart A'
},
xAxis: {
categories: ['Jane', 'John', 'Joe', 'Jack', 'jim']
},
yAxis: {
min: 0,
title: {
text: 'Apple Consumption'
}
},
legend: {
enabled: false
},
credits: {
enabled: false
},
tooltip: {
shared: true
},
series: [{
name: 'Apples',
data: [5, 3, 8, 2, 4]
}]
});
// Build Chart B
$('#chart-B').highcharts({
chart: {
type: 'column'
},
title: {
text: 'Chart B'
},
xAxis: {
categories: ['Jane', 'John', 'Joe', 'Jack', 'jim']
},
yAxis: {
min: 0,
title: {
text: 'Miles during Run'
}
},
legend: {
enabled: false
},
credits: {
enabled: false
},
tooltip: {
shared: true
},
series: [{
name: 'Miles',
data: [2.4, 3.8, 6.1, 5.3, 4.1]
}]
});
});
Here's a JSFiddle: http://jsfiddle.net/engemasa/7cvCX/
I am not really sure what some of your code is trying to do - seems a little needlessly complicated, FWIW
AS to how to make multiple charts on the same page - you do it just like you would make one chart on a page, just do it more than once :)
and make sure you have different container element ids - otherwise you are just overwriting one chart with the next.
One example of multiple charts on a page:
http://jsfiddle.net/kwtZr/1/
there's no relevant code to put here, just click the link
Related
I have a JSON array like this:
chart_data = [
{category: 'A', per: '0.74', total: 10294, in: 5651, out: 5661},
{category: 'B', per: '0.72', total: 10294, in: 5556, out: 7751},
{category: 'C', per: '0.68', total: 10294, in: 5598, out: 5991},
{category: 'D', per: '0.54', total: 10294, in: 6551, out: 5001}
]
now I am showing the data in the column chart where I am using per column chart data where in Highcharts the only tooltip visible is "per" but I want to show "total, in, out" all of them in the tooltip.
Here's my HighChart Code:
plotColumnChart(chart_data:any, chart_config: any){
let columnChartSeries = [];
let categories = [];
let columnChartData = {
exporting: {
chartOptions: { // specific options for the exported image
plotOptions: {
series: {
dataLabels: {
enabled: true
}
}
}
},
fallbackToExportServer: false
},
chart: {
type: 'column',
borderColor: '#c1e1c182',
borderWidth: 1,
borderRadius: 5,
plotBackgroundColor: null,
plotBorderWidth: null,
plotShadow: false,
},
title: {
text: chart_config['name'],
x: -20,
style: {
color: '#0D6ABF',
fontWeight: 'bold'
}
},
credits: {
enabled: false
},
legend: {
enabled: false,
},
xAxis: {
categories: chart_data.map(function(point:any){
return [(<any>Object).values(point)[0]]
}),
title: {
text: null
},
gridLineColor: '#ffffff',
},
yAxis: {
min: 0,
tickInterval: 20,
max:100,
gridLineColor: '#ffffff',
title: {
text: null,
align: null
},
labels: {
overflow: 'justify'
}
},
tooltip: {
shared: false,
backgroundColor: 'black',
borderColor: 'black',
borderRadius: 10,
style: {
color: 'white'
},
useHTML: true,
borderWidth: 3,
headerFormat: '<b style="color: #fff;">{point.x}</b><br/>',
formatter: function() {
}
},
plotOptions: {
series: {
dataLabels: {
enabled: true,
distance: "-80%",
pointFormat: '{point.y}%',
},
},
column: {
pointPadding: 0.5,
borderWidth: 0,
showInLegend: true,
zones:[{
value: chart_config['color-format'][0], // Values up to 50 (not including) ...
color: '#FA5F55' // ... have the this color.
},
{
value: chart_config['color-format'][1], // Values up to 60/70 (not including) ...
color: '#FFBF00' // ... have the this color.
},
{
color: '#98FB98' // Values greater than 70 ... have the this color.
}
],
}
},
series: [
{
name: '', //chart_config['name'],
color: '', //'#98FB98',
pointWidth: 20,
data: chart_data.map(function(point:any){
return [
Number(
(
parseFloat(
(<any>Object).values(point)[1]
)*100
).toFixed(0)
)
]
})
},
]
} as any;
Highcharts.chart(chart_config['id'], columnChartData);
}
And chart_config = {"id": 'column-chart', "name": 'ABC', 'color-format': [50, 70]};
Can anybody help me to achieve this by writing a formatter function for this?
There is no possibility to get other values from the chart level if you don't provide them in the data. In your example, only "per" value is passed to the series.data . After parsing data to the relevant format, you will also need to define series.keys in order to have access to these options.
//Data parsing to the two dimensional array
let new_chart_data = [];
chart_data.forEach(data => {
data.per = Number(data.per)
new_chart_data.push([data.category, data.per, data.total, data.in, data.out])
})
//Chart
Highcharts.chart('container', {
tooltip: {
pointFormatter: function() {
console.log(this.options)
return `<b>Per:</b> ${this.y}</br><b>Total:</b> ${this.total}</br><b>In:</b> ${this.in}</br><b>Out:</b> ${this.out}</br>`
}
},
series: [{
type: 'column',
keys: ['name', 'y', 'total', 'in', 'out'],
pointWidth: 20,
data: new_chart_data
}]
});
API Reference:
https://api.highcharts.com/highcharts/series.column.keys
Demo:
https://jsfiddle.net/BlackLabel/3dh2m79c/
Something like this?
public formatter(row): string {
return row ? `${row.per}, ${row.in}, ${row.out}` : null;
}
I have a stacked column/scatter chart with some dataLabels off to one side. The issue I am facing is that when my two markers begin to get close to one another, their dataLabels overlap
I need to always show both labels, so is there a way to detect when labels are overlapping and move the bottom one down by adjusting its y value based on how much overlap there is?
sample fiddle of the issue
Highcharts.chart('container', {
chart: {
type: 'column',
width: 500
},
title: {
text: 'Stacked column chart'
},
xAxis: {
visible: false,
},
yAxis: {
min: 0,
visible: false,
title: {
},
},
legend: {
layout:"vertical",
align: "right",
verticalAlign: "bottom",
itemMarginTop: 15,
y: -10,
x: -50
},
tooltip: {
enabled: false,
},
plotOptions: {
scatter: {
marker: {
symbol: "triangle",
},
dataLabels: {
enabled: true,
x: -80,
y: 50,
allowOverlap: true,
useHTML: true,
}
},
column: {
pointWidth: 70,
stacking: 'normal',
dataLabels: {
enabled: false
}
}
},
series: [{
name: '',
data: [100],
color: "#ededed"
}, {
name: '',
data: [500]
}, {
name: '',
data: [400]
},
{
type: "scatter",
data: [1000],
color: "#000",
dataLabels: {
formatter: function(){
return "<div class='label-text'>Your goal of <br/>$"+ this.y +"<br/>text</div>"
},
}
},
{
type: "scatter",
data: [900],
color: "#000",
dataLabels: {
formatter: function(){
return "<div class='label-text'>You are here <br/>$"+ this.y +"<br/>text</div>"
},
}
}]
});
You can correct data-labels positions by using the attr method on their SVG elements.
For example:
chart: {
events: {
render: function() {
const series = this.series;
const dl1 = series[3].points[0].dataLabel;
const dl2 = series[4].points[0].dataLabel;
if (dl1.y + dl1.height > dl2.y) {
dl2.attr({
y: dl1.y + dl1.height
});
}
}
}
}
Live demo: https://jsfiddle.net/BlackLabel/5Lmh4owb/
API Reference:
https://api.highcharts.com/class-reference/Highcharts.SVGElement.html#attr
https://api.highcharts.com/highcharts/chart.events.render
I have this chart and I made some changes in the code so that only I show the points :
chart: {
// type: 'spline',
zoomType: 'x, y',
panning: true,
parKey: 'shift'
},
title: {
text: 'Area de Grafica'
},
xAxis: {
categories: ['']
},
yAxis: {
title:{
text: ''
}
},
tooltip:{
crosshairs: [true,true],
formatter: function() {
return this.x + ', ' + this.y;
}
},
series: [{
name: 'grafica tabla de valores',
data: [[val1, val2], [val3, val4], [val5, val6], [val7, val8], [val9, val10], [val11, val12], [val13, val14], [val15, val16], [val17, val18], [val19, val20]],
lineWidth: 0,
marker: {
enabled: true,
radius: 5,
fillColor: 'Red',
symbol: 'url(assets/imgs/sun.png)' //'diamond', 'square',
//lineWidth: 2,
//lineColor: 'Black',
//fillColor: 'white'
}
}],
states: {
hover: {
lineWidthPlus: 0
}
},
exporting: {
showTable: true
},
});
When I run the app it works but at the moment when I move the mouse cursor to the graphic area, you see the line.
I was trying something like 'showLines' but it doesn't work :(
I have a highchart, as showed on the appended image.
I am attempting to format the legend of only my last data stacked. In this case, index 1 always.
Any help on how to achieve this?
My main goal, being, on there always showing a value i have in a variable, which will be the max value possible.
createChart: function (id, chartData, maxYValues, chartTitle, chartNames, dataToMax) {
var me = this;
debugger;
me.highChart = new Highcharts.Chart({
chart: {
type: 'column',
renderTo: id
},
title: {
text: chartTitle,
fontSize: '8px'
},
xAxis: {
labels: {
overflow: 'justify'
},
categories: chartNames
},
yAxis: {
gridLineWidth: 0,
minorGridLineWidth: 0,
labels: {
enabled: false
},
stackLabels: {
enabled: true,
format: maxYValues
},
title: {
enabled: false
}
},
colors: ['#afafaf', '#f89c1c', '#3aaa80'],
credits: {
enabled: false
},
tooltip: {
pointFormat: '<span>{point.name}</span>'
},
plotOptions: {
series: {
colors: ['#3aab80', '#3aab80'],
colorByPoint: true,
borderWidth: 0,
dataLabels: {
enabled: true,
headerFormat: '{point.y + point.name}',
format: '{y} mb',
verticalAlign: 'top',
y: -20
}
},
column: {
stacking: "percent"
},
area: {
dataLabels: {
enabled: false
}
}
},
legend: {
labelFormat: '<b>{point.y} MB</b><br/>',
labelFormatter: function () {
if (me.series.data.index === 1) {
return maxYValues;
}
}
},
series: [{
showInLegend: false,
data: chartData,
color: '#3aab80'
}, {
showInLegend: false,
data: dataToMax,
legend: {
labelFormat: maxYValues + 'MB</b><br/>'
}
}],
navigation: {
menuItemStyle: {
fontSize: '8px'
}
}
});
},
Thank you
UPDATE: Added code snipped, and updated the image to what my current code is showing
I have a sample Highchart that I'm try to load JSON data without any luck. I see the data return in firebug but the chart bar and line doesn't get drawn. You can see my chart here jsfiddle.net. I know I'm missing something, but I can't seem to put my fingers on it. Any help would greatly appreciated, thank you in advance.
This is my code:
$(function() {
var options = {
chart: {
renderTo: 'container',
zoomType: 'xy'
},
title: {
text: 'JSON Chart'
},
subtitle: {
text: '2012 vs 2011'
},
credits: false,
xAxis: [{
categories:['1','2','3','4','5','6','7','8','9','10']
}],
yAxis: [{ // Primary yAxis
min: 0,
max: 15000,
tickInterval: 1000,
labels: {
formatter: function() {
return Highcharts.numberFormat(this.value, 0);
},
style: {
color: '#89A54E'
}
},
title: {
text: '2012',
style: {
color: '#89A54E'
}
}
}, { // Secondary yAxis
min: 0,
max: 15000,
tickInterval: 1000,
labels: {
formatter: function() {
return Highcharts.numberFormat(this.value, 0);
},
style: {
color: '#4572A7'
}
},
title: {
text: '2011',
style: {
color: '#4572A7'
}
},
opposite: true
}],
tooltip: {
formatter: function() {
return Highcharts.numberFormat(this.y, 0);
}
},
legend: {
layout: 'vertical',
align: 'left',
x: 80,
verticalAlign: 'top',
y: 40,
floating: true,
backgroundColor: '#FFFFFF'
},
series: [{
name: '2011',
type: 'column',
yAxis: 1,
data: []
}, {
name: '2012',
type: 'spline',
data: []
}]
};
});
$.getJSON('data.cfm', function(json) {
options.series = json;
var chart = new Highcharts.Chart(options);
})
Here's what data.cfm return:
[[9233,14837,11442,8080,10302,5373,2450,9612,18656,8999],[7963,7845,8646,5130,2570,8936,17487,9141,6728,6046]];
Shoulnt it be?
options.series[0].data=json[0];
options.series[1].data=json[1];
This might be of use: http://livecoding.gabrielflor.it/3351656