I have a Stacked % Column Highchart which without Hyperlinks on data sets works perfectly, however I need to link away to another page from the chart, If it was a standard column chart, I would have no issue (I have one already). But i cannot seem to work out why I'm getting an undefined error on the link.
Ive searched around for a working example but havent been able to find one matching the stacked percentage column.
I've setup a fiddle to indicate where im up to, any help appreciated.
$(function () {
$('#container').highcharts({
chart: {
type: 'column'
},
title: {
text: 'Space Overview'
},
xAxis: {
categories: ['a', 'b', 'c', 'd']
},
yAxis: {
min: 0,
title: {
text: 'Total Space (%)'
}
},
tooltip: {
pointFormat: '<span style="color:{series.color}">{series.name}</span>: <b>{point.y}</b> ({point.percentage:.0f}%)<br/>',
shared: true
},
plotOptions: {
column: {
stacking: 'percent'
},
series: {
cursor: 'pointer',
point: {
events: {
click: function() {
location.href = this.options.url;
}
}
}
}
},
subtitle: {
text: '+ Items relate to items in the dispay cabinets.',
align: 'left',
x: 10
},
series: [{
name: 'Free',
data: [1498, 1123, 556, 1176],
url: ['Spaces.aspx?box=a', 'Spaces.aspx?box=b', 'Spaces.aspx?box=c', 'Spaces.aspx?box=d']
}, {
name: 'Used',
data: [1234,233,23,759],
url: ['Spaces.aspx?box=a', 'Spaces.aspx?box=b', 'Spaces.aspx?box=c', 'Spaces.aspx?box=d']
}]
});
http://jsfiddle.net/Mooglekins/qv8z5a2o/
This is a great question! I did some digging and think I've found a good solution for you.
First, I needed to update how you defined the custom value in your series. To capture certain values in events, I moved the url attribute within each data point. So now, each point has their y value and the new url value.
(Note: I used dummy URLs here since I wouldn't be able to connect to the ones you provided outside your website.)
series: [{
name: 'Free',
data: [
{ y: 1498, url: 'http://www.google.com' },
{ y: 1123, url: 'http://www.yahoo.com' },
{ y: 556, url: 'http://www.bing.com' },
{ y: 1176, url: 'http://www.msn.com' }
]
}, {
// second series here
}
]
Next, I updated your events call. Now that we've moved the url attribute to each point, we can refer to that value as point.url (as you could the y value using point.y).
What I also did here is use window.open vs. window.location. This will be a better experience for your users so they don't lose sight of the chart. Keep this if you wish.
plotOptions: {
column: {
stacking: 'percent'
},
series: {
cursor: 'pointer',
point: {
events: {
click: function (event) {
window.open(event.point.url);
}
}
}
}
}
Here's your updated fiddle with these changes: http://jsfiddle.net/brightmatrix/qv8z5a2o/5/
I hope this helps!
Related
I'm using highchart large tree map demo. I'm getting level data on click of each section. But also need to get the data on back button. So I'm using events drill up function to get data on click of back button. below is my code.
this.setState({
data: {
series: [{
type: 'treemap',
layoutAlgorithm: 'squarified',
allowDrillToNode: true,
animationLimit: 1000,
dataLabels: {
enabled: false
},
levelIsConstant: false,
levels: [{
level: 1,
dataLabels: {
enabled: true
},
borderWidth: 0,
}],
data: points,
events: {
click:(e)=>{
console.log(e)
},
drillup:(e)=>{
console.log(e)
}
}
}],
// subtitle: {
// text: 'Click points to drill down. Source: WHO.'
// },
title: {
text: ''
}
}
})
But don't know drill up is not working even click is working and also I added
import drilldown from "highcharts/modules/drilldown";
drilldown(Highcharts);
But still not getting any data. Please help.
Notice that treemap series don't use the drilldown module, but has own drilldown implementation, which logic you can find here: https://code.highcharts.com/modules/treemap.src.js
What you will need to do is render a custom button while clicking the point and attach an update functionality on this button. Something like here:
Demo: https://jsfiddle.net/BlackLabel/gas07t34/
events: {
click() {
let chart = this.chart;
chart.button = chart.renderer.button('back', 500, 0, function() {
chart.series[0].update({
data: data1
})
chart.button.destroy();
}).add()
this.update({
data: data2
})
}
}
API: https://api.highcharts.com/class-reference/Highcharts.SVGRenderer#button
API: https://api.highcharts.com/class-reference/Highcharts.Series#update
I want to create a stacked column chart using highcharts.js with datetime data
It works on line type, but not working on column. The result were flat 100%.
What i need is the chart will appear as stacked column. what do i missed?
I tried stacked: 'normal' on plotOptions, but still not working.
Please advise, thank you
My highcharts options:
var optionsProcessTime = {
global: {
useUTC: false
},
title: {
text: '',
x: -20 //center
},
subtitle: {
text: '',
x: -20
},
xAxis: {
categories: [],
labels:{
formatter: function(){
return '#'+this.value;
}
}
},
yAxis: {
title: {
text: ''
},
type: 'datetime',
dateTimeLabelFormats: {
millisecond: '%H:%M:%S',
second: '%H:%M:%S',
minute: '%H:%M:%S',
hour: '%H:%M:%S'
},
labels:{
format: '{value:%H:%M:%S}'
},
gridLineWidth: 0
},
tooltip: {
enabled: true,
type: 'datetime',
formatter: function(){
return Highcharts.dateFormat('%H:%M:%S',new Date(this.y))
}
},
legend: {
enabled : false
},
plotOptions: {
series: {
pointPadding: 0.05,
groupPadding: 0
},
column: {
stacking: 'normal'
},
line: {
marker: {
radius: 2,
fillColor: '#ad050b'
},
dashStyle: 'ShortDash',
lineWidth: 1,
}
},
series: []
}
My Json output:
[{
"name":"Checker",
"data":[86,87,91,92,93,94,99,100,101]},
{
"name":"Estimate",
"type":"column",
"data":[1517018400000,1517014800000,1517014800000,1517018400000,1517017200000,1517015700000,1517013900000,1517013900000,1517013900000]},
{
"name":"Process",
"type":"column",
"data":[1517018400000,1517013666000,1517014800000,1517016664000,1517015107000,1517014984000,1517013604000,1517013900000,1517013900000]
}]
I suggest to disable, for debugging only, your definition for yAxis.labels. You will see original labels and realize how it works :)
In short, stacking renders each value on top of the previous one, for example: 1517018400000 + 1517018400000 = 3034036800000 so it renders point in 2066 year. And since all columns starts from zero (0) the distance is quite big: 136 years. Take a look: http://jsfiddle.net/BlackLabel/L4Lgbvvm/45/
Why it works for a line chart then? Simply, line type doesn't start at zero as column does. You can achieve the same result (without stacking) for column too, by setting series.threshold to null: http://jsfiddle.net/BlackLabel/n1s4sqps/
What about stacking? I'm not sure how this should work.. it works the same way for columns and lines, compare stackings:
line: http://jsfiddle.net/BlackLabel/n1s4sqps/1/
column: http://jsfiddle.net/BlackLabel/n1s4sqps/2/
If you could explain how stacking should be rendered in your opinion, let me know, maybe we can find some solution for it. An image of such stacking would be great.
I am a bit out of my comfort zone, since I normally do analytics and not fancy front-ends. However, I would like to have a real-time demo of some of my work, so it becomes easier to understand and not just numbers in a matrix. I have looked around and found something semi-relevant and come this far:
(It has four series like I want to and it iterates - to some degree)
https://jsfiddle.net/023sre9r/
var series1 = this.series[0],
series2 = this.series[1],
series3 = this.series[2],
series4 = this.series[3];
But I am totally lost on how to remove the random number generators without loosing nice things like the number of data points in a view (seems to depend on the for loop?!). Remove the extra title "Values" right next to my real y-axis title. And of cause how to get a new data point from a XML-file every second.
Ideally I want to have an XML-file containing 4 values, which I update approximately every 200ms in MATLAB. And every second I would like my 4 series chart to update. Is it not relatively easy, if you know what you are doing?! :-)
Thanks in advance!
I simplified your example and added clear code showing how to fetch data from server and append it to your chart using series.addPoint method. Also if you want to use XML, just convert it to JS object / JSON.
const randomData = () => [...Array(12)]
.map((u, i) => [new Date().getTime() + i * 1000, Math.random()])
Highcharts.chart('container', {
chart: {
renderTo: 'container',
type: 'spline',
backgroundColor: null,
animation: Highcharts.svg, // don't animate in old IE
marginRight: 10,
events: {
load () {
const chart = this
setInterval(() => {
// Fetch example below (working example: https://github.com/stpoa/live-btc-chart/blob/master/app.js)
// window.fetch('https://api.cryptonator.com/api/ticker/btc-usd').then((response) => {
// return response.json()
// }).then((data) => {
// chart.series[0].addPoint({ x: data.timestamp * 1000, y: Number(data.ticker.price) })
// })
chart.series.forEach((series) => series.addPoint([new Date().getTime(), Math.random()], true, true))
}, 3000)
}
}
},
title: {
text: null
},
xAxis: {
type: 'datetime',
tickPixelInterval: 150
},
yAxis: [{
title: {
text: 'Temperature [°C]',
margin: 30
},
plotLines: [{
value: 0,
width: 1,
color: '#808080'
}]
}, {
}],
tooltip: {
formatter: function() {
return '<b>' + this.series.name + '</b><br/>' +
Highcharts.dateFormat('%Y-%m-%d %H:%M:%S', this.x) + '<br/>' + Highcharts.numberFormat(this.y, 4);
}
},
legend: {
enabled: true
},
exporting: {
enabled: false
},
rangeSelector: {
enabled: false
},
navigator: {
enabled: false
},
scrollbar: {
enabled: false
},
series: [{
name: 'Setpoint',
data: randomData()
}, {
name: 'Return',
data: randomData()
}, {
name: 'Supply',
data: randomData()
}, {
name: 'Output',
data: randomData()
}]
})
Live example: https://jsfiddle.net/9gw4ttnt/
Working one with external data source: https://jsfiddle.net/111u7nxs/
I've searched around for several days and have not been able to find a solution to this issue. I'm generating highcharts with not problem. Inaddition, I'm using the below simple function to get the svg code for each chart.
function generateSVG (){
var svg_xml = $('#container').highcharts().getSVG();
document.getElementById('svg_code').innerHTML = svg_xml;
}
My issue is that with the chart originally generated by highcharts I am able to mouseover the chart and see tooltips. However, when I later embed the generated svg code, even with including all the external resources, the tooltips do not work - everything becomes like a static image. After inspecting the svg code extracted next to the code used to generate the initial chart, I noticed that the line of code which includes the tooltip class for highcharts was missing in the extracted code. Am I missing something here. Below is an example of one of the functions used to generate a chart.
function highArea(theD){
setHighSize();
var theData = theD;
$.get(theData, function(data) {
Highcharts.chart('chartDisplay', {
colors: ["#67001f","#b2182b","#d6604d","#f4a582","#fddbc7","#ffffff"],
chart: {
type: "area",
useHTML: true
},
exporting: {
buttons: {
contextButton: {
enabled: false
}
}
},
title: {
text: chart_title
},
data: {
csv: data
},
title: {
text: chart_title
},
subtitle: {
text: ''
},
xAxis: {
allowDecimals: false,
labels: {
formatter: function () {
return this.value;
}
}
},
yAxis: {
title: {
text: some_label
},
},
tooltip: {
pointFormat: '{series.name} <b>{point.y:,.0f}</b><br/> {point.x}'
},
plotOptions: {
area: {
marker: {
enabled: true,
symbol: 'circle',
radius: 2,
states: {
hover: {
enabled: true
}
}
}
}
}
});
generateSVG();
});
}
Is what I'm trying to do even possible? I would really appreciate any feedback on this matter.
Thanks :)
I get an error
{"error": "Please use POST request"}
While clicking on the link, I enabled for the columns in the column chart. What is the cause for this error and how do I overcome this error.
My Series
series: [{
name: 'Capital',
data: [1000000.00, 1000000.00, 1000000.00, 1000000.00, 900000.00],
url:'http://www.google.com'
}, {
name: 'Material',
data: [8753.15, 529.00, 5620.00, 35000.00, 30988.86]
}, {
name: 'HR',
data: [66400.00, 320000.00, 488000.00, 48000.00, 512000.00]
}, {
name: 'Equipment',
data: [0.00, 160000.00, 1600000.00, 32000.00, 64000.00]
}, {
name: 'Petty Cash',
data: [10000.00, 100000.00, 100000.00, 10000.00, 150000.00]
}],
Plot options
plotOptions: {
series: {
cursor: 'pointer',
point: {
events: {
click: function (e) {
location.href = this.options.url;
e.preventDefault();
}
}
}
}
}
My consolidated code fiddled here.
Is this the right way to provide links to navigate while clicking ?
You have two bugs:
1) in click event you are using this.options.url, which is undefined, while should be (according to your series configuration) this.series.options.url
2) Add point.events under plotOptions.series:
plotOptions: {
series: {
cursor: 'pointer',
point: {
events: {
click: function () {
console.log(this.series.options.url);
location.href = this.series.options.url;
}
}
}
}
}
And 'working' jsFiddle for you: http://jsfiddle.net/3TRL6/5/show/ - (works for Capital series). Full code is here: http://jsfiddle.net/3TRL6/5/
If you are testing the code with jsFiddle, you might get this error "{"error": "Please use POST request"}", since you are requesting a non secure site "url:'http://www.google.com'" on jsFiddle which is secured i.e 'https://jsfiddle.net/'. Try replacing Http with Https.
Please find jsFiddle link https://jsfiddle.net/ajaytripathi10/dk5ogkj9/1/
plotOptions: {
series: {
borderWidth: 0,
dataLabels: {
enabled: true,
format: '{point.y:.1f}'
},
cursor: 'pointer',
point: {
events: {
click: function() {
console.log(this.options.url);
location.href = this.options.url;
}
}
}
}
},