add custom links to series / data sections in pie chart (highcharts.js) - javascript

I am simply trying to allow each data section or series of a pie chart via highcharts to be clickable, eg. Shop section should link to #shop_section I've found demos where a global link was set to every data section in a chart. But I simply would like a unique #link to be accessible via clicking one of my three data sections / series.
series: [{
innerSize: '30%',
data: [
['Shop', 10],
['Buy', 10],
['Own', 10],
]
}]
});
This didn't work: (attempt)
data: [
{name: 'Shop', 10, url: 'http://my_site1.com'},
{name: 'Buy', 10, url: 'http://my_site2.com'},
{name: 'Own', 10, url: 'http://my_site3.com'}
]

Your series is incorrect, it should be:
data: [
{name: 'Shop', y: 10, url: 'http://my_site1.com'},
{name: 'Buy', y: 10, url: 'http://my_site2.com'},
{name: 'Own', y: 10, url: 'http://my_site3.com'}
]

Using plotOptions would do the work:
plotOptions: {
series:{
point:{
events:{
click: function(){
window.location.href = this.url;
}
}
}
},
},
By simply using a series->point->events we can speficy which events to delegate to our series points (in the case of a pie chart a point is a "slice").
On the event handler function itself, this refers to the clicked point, therefore I can directly use the custom property url you've set.

Related

How to keep the highcharts legend "on" while hiding the series

I added some dummy series in the highcharts, but I want them to be invisible at all times, independent of whether I click their legends.
series.push({
name: 'dummyPoint',
fontFamily: 'Arial',
data: [dummyPointX, dummyPointY],
visible: false,
showInLegend: true
})
The problem with the above code is that the legends are displayed greyed out by default, and it will display dummies upon the click of legends. How do I prevent it from greying out by default and keep the dummy points invisible at all times?
You can do that with the series.events.legend.itemClick - Api Documentation
series: [{
name: 'Point 1',
color: '#00FF00',
data: [1, 2.5, 3, 4, 3.2],
visible: false,
showInLegend: true,
events: {
legendItemClick: function() {
return false;
}
}
}
edit : Completly invisible legend
Updated Fiddle
You can do a little trick to achieve it: create a "phantom" series that has no data and link the hidden series to it. Legend item will be generated for the phantom series and will serve for the hidden series too. Then disable the default action for this item in events.legendItemClick:
series: [{
// Phantom series - created just to generate legend item
name: 'Series 1',
events: {
legendItemClick: function(e) {
e.preventDefault();
}
}
}, {
data: [3, 0],
visible: false,
name: 'Series 1',
linkedTo: ':previous',
}, {
data: [1, 2],
name: 'Series 2'
}]
Live demo: http://jsfiddle.net/BlackLabel/dc4L30zv/
API references:
https://api.highcharts.com/highcharts/series.line.linkedTo
https://api.highcharts.com/highcharts/series.line.events.legendItemClick

Plotly.js define shape of data

I'm pulling data from an API that comes back in the following format:
[{
"metadata": {"colName": "nameOfCol"},
"value": valueForCol // string or number or whatever
},
...]
But according to Plotly's website, they want two simple arrays of labels and columns:
var data = [{
values: [19, 26, 55],
labels: ['Residential', 'Non-Residential', 'Utility'],
type: 'pie'
}];
or:
var data = [{
x: ['giraffes', 'orangutans', 'monkeys'],
y: [20, 14, 23],
type: 'bar'
}];
Now there's quite a big dataset coming back, so I'd prefer to not have to loop through the whole set and extract the labels and values from everything. Is there a nice way to tell Plotly to loop through my data and find the labels and values?
I don't know what this would look like, maybe something like:
var data = [{
source: myData,
labels: "metadata.colName",
values: "value",
type: "pie"
}]
Short answer: no, there is no feature in Plotly.js for this, you'll unfortunately have to loop through and extract.

chart.js mixed chart types

I have this example from chart.js docs:
var myChart = new Chart(ctx, {
type: 'bar',
data: {
labels: ['Item 1', 'Item 2', 'Item 3'],
datasets: [
{
type: 'bar',
label: 'Bar Component',
data: [10, 20, 30],
},
{
type: 'line',
label: 'Line Component',
data: [30, 20, 10],
}
]
}
});
It works fine. However, my intention is to change the type dynamically.
I am aware that there is getDatasetMeta() method, that you can apply to your chart instance, and if I output the result it returns to the console I get something like this:
{
bar: true,
controller: ChartElement,
data: Array[...],
dataset: null,
hidden: false,
type: 'bar',
...
}
I can control the appearance of a certain dataset via hidden property, though if I change type to line and invoke update() it won't re-render.
So, is there a way to dynamically change dataset type?
Found a workaround here: Chart.js: Dynamic Changing of Chart Type (Line to Bar as Example)
Sad that it's not yet supported officially.

Chart.js: passing objects instead of int values as data

Is it possible to pass an array of objects instead of an array of integers? The following code works but results in a flat zero line:
var ctx = document.getElementById("a").getContext("2d");
var data = {
labels: ["Fri", "Sat", "Sun"],
datasets: [{
label: "Chart B",
fillColor: "rgba(220,220,220,0.2)",
strokeColor: "rgba(150,150,150,1)",
pointColor: "rgba(150,150,150,1)",
pointStrokeColor: "#fff",
pointHighlightFill: "#fff",
pointHighlightStroke: "rgba(220,220,220,1)",
data: [{
y: 48,
name: "Value one",
date: "2015-04-30"
}, {
y: 40,
name: "Value two",
date: "2016-05-30"
}, {
y: 19,
name: "Value three",
date: "2016-06-30"
} ]
}]
};
var Chart = new Chart(ctx).Line(data);
In short, I think your example should work. The key is to use y for the y value in the chart, and to add your arbitrary property to the object, as well.
It looks like this is what you're doing, but you've reported it's not working... It works for me, though! ?
Longer answer
According to the docs for Line, data can be a Number[]:
data: [20, 10]
...but it can also be a Point[]:
data: [{
x: 10,
y: 20
}, {
x: 15,
y: 10
}]
This was intended to be used for sparsely-populated data sets. Through experimentation, I've found you can omit the x property and simply specify the y property. The x value will be inferred, as usual.
You can also add in any other arbitrary properties that can be accessed from your label callback. So, you might end up with something like this:
data: [{
y: 20,
myProperty: "Something"
}, {
y: 10,
myProperty: "Something Else"
}]
I can confirm that answer #rinogo gave works on latests version. You can add custom properties to dataset and use 'em in tooltip or elsewhere afterwards.
First add data to dataset. On my case I only have one set, so I'm just pushing points.
chartData.datasets[0].data.push({
y: groupedBooking.distinctCount,
distinctUsers: distinctUsers
});
... and finally override callback with chartOptions:
options: {
tooltips: {
callbacks: {
label(tooltipItem, data) {
console.log(data);
return data.datasets[0].data[tooltipItem.index].distinctUsers;
}
}
}
}
If you would happen to have multiple datasets you get datasetIndex from tooltipItem as well... so to confirm, X can be omitted from datapoint and customer properties are preserved within object.
In the data structure doc (version 3.5.1 at the time of writing this), it is documented objects can be used as data and parsing option is also available to pick the keys.
Example from the doc:
data: {
datasets: [{
data: [{id: 'Sales', nested: {value: 1500}}, {id: 'Purchases', nested: {value: 500}}]
}]
},
options: {
parsing: {
xAxisKey: 'id',
yAxisKey: 'nested.value'
}
}

How to add another series into my highchart

I have a Tornado chart like the one below:
This chart has a baseline at 29.5, and it's fiddle is here.
series:[{
name: 'Low',
grouping:false,
type:'bar',
data:[
{y:12.15-baseValue, label:10},
{y:15.45-baseValue, label:1},
{y:31.25-baseValue, label:2},
{y:12.15-baseValue, color:'#99CCFF', label: ""},
],
labels:[10,5,1,2,]
},{
name: 'High',
grouping:false,
type:'bar',
data:[
{y:46.86-baseValue, label:30},
{y:42.28-baseValue, label:3},
{y:27.77-baseValue, label:4},
{y:46.86-baseValue, color:'#99CCFF', label:""},
],
labels:[30,10,3,4,]
},
{
name: 'Median',
type: 'scatter',
data: [
null,
null,
null,
27-baseValue
],
marker: {
lineWidth: 2,
lineColor: Highcharts.getOptions().colors[3],
fillColor: 'white'
}
}]
I am trying to add a shadow chart of a second Tornado, where the baseline can be different. For instance, consider four more bars, shifted to the right, in the mockup shown below:
I have been stuck at this because the shadow bars only show relative to the baseValue of the first chart (29.5), and not to the baseValue of the second chart (39.5). So if I try to add them into the existing series, they will work only if the values are in the same direction (as in value-baseValue has the same sign as the original data).
To illustrate, suppose the shadow chart has the following data:
Annual Revenue: 25, 39.5, 55
Number of Years: 33, 39.5, 48
Annual Costs: 35, 39.5, 48
Combined Uncertainty: 23,43,55
How do I add this to the code in the fiddle above and make it look like the mockup? Here is a modified fiddle that does not work.
series:[{
name: 'Low',
grouping:false,
type:'bar',
data:[
{y:12.15-baseValue, label:10},
{y:25-baseValue, label:50},
{y:15.45-baseValue, label:1},
{y:33-baseValue, label:20},
{y:31.25-baseValue, label:2},
{y:48-baseValue, label:8},
{y:12.15-baseValue, color:'#99CCFF', label: ""},
{y:40-baseValue, color:'#99DDDD', label: ""}
],
labels:[10,50,1,20,2,8]
},{
name: 'High',
grouping:false,
type:'bar',
data:[
{y:46.86-baseValue, label:30},
{y:55-baseValue, label:70},
{y:42.28-baseValue, label:3},
{y:48-baseValue, label:30},
{y:27.77-baseValue, label:4},
{y:35-baseValue, label:5},
{y:46.86-baseValue, color:'#99CCFF', label:""},
{y:80-baseValue, color:'#99DDDD', label: ""}
],
labels:[30,70,3,30,4,5,]
},
{
name: 'Median',
type: 'scatter',
data: [
null,
null,
null,
null,
null,
null,
27-baseValue,
60-baseValue
],
marker: {
lineWidth: 2,
lineColor: Highcharts.getOptions().colors[3],
fillColor: 'white'
}
}]
The problems are annotated in the image below:
If you want to have point with 0/origin in different position that rest of series - then instead you should use different series and add hidden another horizontal axis (in your code it will be y-axis because of invert caused by bar charts).
To synchronize those axes you can set proper max and min on axes.
Example: http://jsfiddle.net/frgo4Lun/3/
OR
You can use threshold http://api.highcharts.com/highcharts#plotOptions.bar.threshold.
Example: http://jsfiddle.net/frgo4Lun/4/
You have also posted image with series on between of ticks. You can set x position of point to not round values like 1.5.
Example: http://jsfiddle.net/frgo4Lun/5/

Categories