Custom hover / tooltip data on highcharts network chart - highcharts

I am trying to display a custom tooltip on a react highcharts network chart that includes the node id as well as the title and other fields in the JSON data I am feeding it. However I am not able to get this to work using the formatted function specified in the API.
My simplified code is as follows:
import React, { useState, useEffect, useRef } from 'react';
import Highcharts from 'highcharts';
import HighchartsReact from 'highcharts-react-official';
import networkgraph from "highcharts/modules/networkgraph";
networkgraph(Highcharts);
const NetworkChart = () => {
const chartComponent = useRef(null); // reference to chart obj
const [nodeData, setNodeData] = useState([
{ 'id': 'A', title:'ABC', other:'X', dataLabels: { enabled: true }, marker: { radius: 11, fillColor: 'red' } },
{ 'id': 'P', title:'CDE', other:'Y', dataLabels: { enabled: true } },
{ 'id': 'K', title:'EDF', other:'X', dataLabels: { enabled: true } },
{ 'id': 'S', title:'DFG', other:'Z', dataLabels: { enabled: true } },
{ 'id': 'D', title:'SDF', other:'Y', dataLabels: { enabled: true } },
]);
const [linkData, setLinkData] = useState([
{ 'from': 'D', 'to': 'A' },
{ 'from': 'S', 'to': 'A' },
{ 'from': 'K', 'to': 'A' },
{ 'from': 'P', 'to': 'A' }
]);
const [chartOptions, setChartOptions] = useState({
chart: {
type: 'networkgraph',
plotBorderWidth: 1,
},
title: {
text: 'Phrasal verbs'
},
subtitle: {
text: 'Integration: ' + 'euler'
},
credits: false,
plotOptions: {
networkgraph: {
layoutAlgorithm: {
enableSimulation: false,
integration: 'euler',
linkLength: 25,
},
keys: ['from', 'to'],
marker: {
radius: 5,
lineWidth: 1
}
},
series: {
point: {
events: {
click: function () {
// click function
},
}
}
}
},
series: [{
allowPointSelect: true,
nodes: nodeData,
data: linkData,
}]
});
return (
<div>
<HighchartsReact
highcharts={Highcharts}
options={chartOptions}
containerProps={{ style: { height: 700 } }}
allowChartUpdate = {true}
ref={chartComponent}
/>
</div>
)
};
export default NetworkChart;
Currently all I see is node id on hover. What I want to see is node id, title and other field values when I hover on each node in the chart.

You can get the required propeerties through: this.point.options
tooltip: {
formatter: function() {
const { title, other } = this.point.options;
return 'Title: ' + title + ' Other: ' + other
}
}
Live demo: http://jsfiddle.net/BlackLabel/4zgrnqc2/
API Reference: https://api.highcharts.com/highcharts/tooltip.formatter

Related

Add additional tooltip from from JSON Array

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;
}

"viewFullscreen" menu item is not showing in the context menu of highcharts 6.2.0

I have a highchart line chart which currently displayed in bootstrap 4 card.
I want it to displayed full screen, which I'm currently aware that highchart 6.2.0 has option to enabled exporting file, so that I can use the exporting context menu. so, I enabled them but "showFullscreen" option not showing in the exporting context menu.
I imported highchart and exporting module to the component.
in the documentation highchart guys says that I have to include viewFullscreen as string to the menuItems array. I also did that. but nothing work.
import { chart } from 'highcharts';
import * as Highcharts from 'highcharts/highcharts';
import * as HighchartsMore from 'highcharts/highcharts-more';
import * as HighchartsSolidGauge from 'highcharts/modules/solid-gauge';
import * as HighChartExport from 'highcharts/modules/exporting';
HighchartsMore(Highcharts);
HighchartsSolidGauge(Highcharts);
HighChartExport(Highcharts);
#Component({
selector: 'app-line-chart',
templateUrl: './line-chart.component.html',
styleUrls: ['./line-chart.component.css']
})
export class LineChartComponent implements OnInit, OnChanges {
#ViewChild('chartTarget') chartTarget: ElementRef;
#Input() data;
#Input() lineColor;
options: any;
chart: Highcharts.ChartObject;
constructor() { }
ngOnInit() {
this.drawLineChart();
}
ngOnChanges(changes: SimpleChanges) {
if (this.chart && changes['data']) {
this.drawLineChart();
}
}
drawLineChart() {
this.options = {
chart: {
scrollablePlotArea: {
minWidth: 700
},
height: 230,
zoomType: 'x'
},
title: {
text: ''
},
credits: {
enabled: false
},
xAxis: {
gridLineWidth: 1,
/*tickInterval: 7 * 24 * 3600 * 1000, // one week
tickWidth: 0,*/
labels: {
align: 'left',
x: 3,
y: -3,
enabled: false
}
},
yAxis: [{ // left y axis
title: {
text: null
},
padding: 3,
showFirstLabel: false,
gridLineWidth: 1,
/*labels: {
align: 'left',
x: -10
}*/
}],
colors: this.lineColor,
legend: {
align: 'left',
verticalAlign: 'bottom',
borderWidth: 0
},
tooltip: {
shared: true,
crosshairs: true,
headerFormat: ''
},
exporting: {
enabled: true,
menuItemDefinitions: {
// Custom definition
},
buttons: {
contextButton: {
menuItems: ['viewFullscreen']
}
}
},
plotOptions: {
series: {
cursor: 'pointer',
marker: {
enabled: false
}
}
},
series: this.data
};
this.chart = chart(this.chartTarget.nativeElement, this.options as any);
}
}
I followed this link https://jsfiddle.net/gh/get/library/pure/highcharts/highcharts/tree/master/samples/highcharts/exporting/menuitemdefinitions/
but when I clicked that hamburger icon every other options showing except "viewFullscreen" option didn't work.
To add a custom button to context menu you have to add it to exporting.menuItemDefinitions and also exporting.buttons.contextButton.menuItems array. Note, that fullscreen requires an additional module to be loaded: modules/full-screen.
Code:
Highcharts.chart('container', {
exporting: {
menuItemDefinitions: {
fullscreen: {
onclick: function() {
Highcharts.FullScreen.prototype.init(this.renderTo);
},
text: 'Full screen'
}
},
buttons: {
contextButton: {
menuItems: ['downloadPNG', 'downloadSVG', 'separator', 'fullscreen']
}
}
},
series: [{
data: [
43934,
52503,
57177,
69658,
97031,
119931,
137133,
154175
]
}],
});
<script src="https://code.highcharts.com/highcharts.js"></script>
<script src="https://code.highcharts.com/modules/exporting.js"></script>
<script src="https://code.highcharts.com/modules/full-screen.js"></script>
<div id="container"></div>
Demo:
https://jsfiddle.net/BlackLabel/qydgxs12/
Angular demo:
https://codesandbox.io/s/73lomvnqk0
API reference:
https://api.highcharts.com/highcharts/exporting.buttons.contextButton.menuItems
https://api.highcharts.com/highcharts/exporting.menuItemDefinitions

Highchart hide a category and rescale is messing

I'm trying to draw a chart where categories can be filtered, and it's working pretty nicely, I used this to do it.
Problem is : my last category is the total of the others, and so is taller. I want that when the "total" checkbox is unchecheck the chart resize, but it doesn't and resize only if I also uncheck the "class7" checkbox.
you can try it here : https://jsfiddle.net/4rfdgvum/
var chart=null;
$(function() {
var chart = new Highcharts.Chart('container', {
chart: {
type: 'column',
shadow: true
},
title: {
text: 'My Title'
},
xAxis: {
categories: [{"class":"class1","name":"cat1"},{"class":"class2","name":"cat2"},{"class":"class3","name":"cat3"},{"class":"class4","name":"cat4"},{"class":"class5","name":"cat5"},{"class":"class6","name":"cat6"},{"class":"class7","name":"cat7"},{'class': 'total','name':'total'}],
labels: {
formatter: function() {
return this.value.name;
},
useHTML: true
}
},
yAxis: {
allowDecimals: false,
min: 0,
title: {
text: 'Numbers'
}
},
legend: {
enabled: true
},
tooltip: {
formatter: function () {
return '<b>' + this.x.name + '</b><br/>' +
this.series.name + ': ' + this.y + '<br/>' +
'Total: ' + this.point.stackTotal;
}
},
plotOptions: {
column: {
stacking: 'normal',
dataLabels: {
enabled: true,
color: (Highcharts.theme && Highcharts.theme.dataLabelsColor) || 'white',
formatter: function(){
return Highcharts.numberFormat(this.percentage,0) + '%';
}
}
}
},
series: [{
name: 'Ok',
color: 'green',
stack: 'a',
data: [
223,174,139,27,17,6,3,589 ]
},
{
name: 'Not Ok',
color: 'red',
stack: 'a',
data: [
21,29,26,14,15,11,11,127 ]
},
{
name: 'Partialy Ok',
color:'orange',
stack: 'a',
data: [
5,11,25,1,1,3,0,46 ]
},
{
name: 'Not usable',
color:'grey',
stack: 'a',
data: [
20,70,67,160,163,170,168,818 ]
},
{
name: 'Not done',
color:'brown',
stack: 'a',
data: [
173,158,185,240,246,252,260,1514 ]
}
]
}, function() {
$('input[type=checkbox]').bind('click', function() {
togglePointsByClass(this.value, $(this).is(':checked'), chart)
});
});
var visibleArr = [0,1,2,3,4,5,6,7];
function togglePointsByClass(className, shouldShow, chart) {
var isChartDirty = false;
if (shouldShow) {
chart.xAxis[0].userOptions.categories.forEach(function(category, i) {
if (category.class === className) {
visibleArr.push(i);
}
});
} else {
chart.xAxis[0].userOptions.categories.forEach(function(category, i) {
if (category.class === className && visibleArr.indexOf(i) > -1) {
visibleArr.splice(visibleArr.indexOf(i), 1);
}
});
}
if (visibleArr.length) {
chart.xAxis[0].update({
min: Math.min.apply(null, visibleArr),
max: Math.max.apply(null, visibleArr)
})
}
}
$('#container').highcharts().redraw();
});
Thanks
You can use axis.setExtremes() for setting max of the yAxis.
if (visibleArr.length) {
chart.xAxis[0].update({
min: Math.min.apply(null, visibleArr),
max: Math.max.apply(null, visibleArr)
}, false, false);
const max = visibleArr.reduce((a, b) => Math.max(chart.yAxis[0].stacks.columna[b].total, a), -Infinity)
chart.yAxis[0].setExtremes(0, max);
}
example: https://jsfiddle.net/mw7euo1a/

how do I get two highcharts on one page?

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

Retrieve series name and data with getjson

I'm trying to retrieve from a JSON formatted file this series name and data
[
{ "name":"gfs00", "data": [ [1359676800000, 30], [1359687600000, 32]]
},
{ "name":"gfs06", "data": [ [1359676800000, 28], [1359687600000, 29]]
}
]
Here's the highchart code:
var data_temp;
$.getJSON('dati/performance_gfs/precipitazioni/pioggia_live_data.php',
{ run: runs_gfs} ,function(data_temp){
for (var i = 0; i <data_temp.length ;i++){
chart.addSeries({
data:data_temp,
});
}
});
$(document).ready(function() {
chart = new Highcharts.Chart({
chart: {
renderTo: 'container_temperatura_windchill_heatindex',
defaultSeriesType: 'line',
zoomType: 'x',
},
title: {
text: 'Ensemble'
},
xAxis: {
type: 'datetime'
},
yAxis: [{ // Primary yAxis
id:0,
labels: {
formatter: function() {
return this.value +'°C';
},
style: {
color: '#89A54E'
}
},
title: {
text: 'Temperature',
style: {
color: '#89A54E'
}
}
}],
plotOptions: {
line: {
lineWidth: 1,
states: {
hover: {
lineWidth: 2
}
},
marker: {
enabled: false,
states: {
hover: {
enabled: true,
symbol: 'circle',
radius: 5,
lineWidth: 1
}
}
},
pointInterval: 24 * 3600000, // one hour
pointStart: Date.UTC(2012, 9, 6, 0, 0, 0)
}
},
tooltip: {
formatter: function() {
return '<b>'+ this.series.name +'</b><br/>'+
Highcharts.dateFormat('%d-%m-%Y %H:%M', this.x)+'<br/>'+
this.y;
}
},
series: []
});
});
}
As can be seen I don't know how to assign the series names and data from the JSON file which is correct what I need is something like http://jsfiddle.net/vXdxv/1/
Try the following:
for (var i = 0; i <data_temp.length ;i++){
chart.addSeries(data_temp[i], false);
});
chart.redraw();

Resources