Highchart sankey- Show multiple entries having same name independently - highcharts

I have a requirement that in case of an example like
I want the two r1s to appear independently on their respective axis
I.e
I want something like
l1 - r1
l3 - r1
l2 - r2
r1 - r3
i.e the 2 r1s should exist independently on the correct sides I.e the ‘from and’to’sides depending on their position in the array of data say having keys [‘from’ ,’to’, ‘weight’
I do not want
L1 - r1 - r3

Use distinct values in the data object, and then use the nodes object to make their names (and optionally colors) the same.
Highcharts.chart('container', {
title: {
text: 'Highcharts Sankey Diagram'
},
series: [{
keys: ['from', 'to', 'weight', 'id'],
data: [{
from: 'L1',
to: 'R1',
weight: 5
},
{
from: 'L3',
to: 'R1',
weight: 1
},
{
from: 'L2',
to: 'R2',
weight: 1
},
{
from: 'L4',
to: 'R3',
weight: 1
},
],
nodes: [{
id: 'L4',
name: 'R1',
color: '#000'
},
{
id: 'R1',
name: 'R1',
color: '#000'
}
],
type: 'sankey',
name: 'Sankey demo series'
}]
});
https://jsfiddle.net/kLx2n7mz/12/
Note, you wouldn't need to include id:'R1' in the nodes object if you didn't want to assure they have the same color.

Related

HighMap data table not loading points

I'm trying to populate a map of the U.S. in HighMaps with data from an html table. The map is showing but the data point is not. It's a latitude/longitude point. The documentation is sparse, so I'm not sure what I'm doing wrong. Here's a JSFiddle: https://jsfiddle.net/sfjeld/1wjm04fc/6/
Highcharts.mapChart('container', {
chart: {
map: 'countries/us/custom/us-all-territories'
},
series: [{
name: 'Basemap',
dataLabels: {
enabled: true,
format: '{point.name}'
}
},
{
// Specify points using lat/lon
type: 'mappoint',
data: {
table: 'pvsoiling-table',
startRow: 1,
startColumn: 1,
endColumn: 2
},
name: 'PV',
marker: {
fillColor: 'white',
lineColor: 'black',
lineWidth: 2,
radius: 10
},
color: Highcharts.getOptions().colors[1]
}
]
});
thanks,
Shauna
You can make the following changes to your code:
At the start of your <script> section, load your HTML table data into a JavaScript array:
var mapData = [];
Highcharts.data({
table: document.getElementById('pvsoiling-table'),
startColumn: 1,
endColumn: 2,
firstRowAsNames: true,
complete: function (options) {
options.series[0].data.forEach(function (p) {
mapData.push({
lat: p[0],
lon: p[1]
});
});
//console.log(mapData);
}
});
We will refer to this mapData array later on. Here is what it contains:
[
{ "lat": 33.3, "lon": -111.67 }
]
Make changes to the series section in your Highcharts.mapChart.
series: [{
name: 'Basemap',
nullColor: '#e0f9e3',
dataLabels: {
enabled: true,
format: '{point.name}'
}},
{
// Specify points using lat/lon
data: mapData,
type: 'mappoint',
name: 'PV',
marker: {
fillColor: 'white',
lineColor: 'black',
lineWidth: 1,
radius: 3
},
color: Highcharts.getOptions().colors[1]
}
]
The key part to note is the data: mapData option. The JavaScript mapData variable is the exact array that we need to represent a set of points on the map. In our case the array only contains one point - but that's because there is only one relevant row of data in the HTML table.
My map ends up looking like this:
It looks like the marker is in or near Phoenix, AZ.
Final notes:
(a) I also adjusted the marker to have lineWidth: 1 and radius: 3 (a bit smaller).
(b) I added a document ready function around everything, to ensure the DataTable is loaded before you try to read its data.
(c) There may be a more elegant way to do this, but I followed the approach in this demo. The demo actually shows how to join 2 different sets of data - not what you need. But it does show a good approach for extracting the HTML data so it can be used in the map.
Using the the Highcharts.data({...}) approach lets you access any HTML table. But since you are using DataTables, you can choose to do the following, instead. It uses the DataTables API to access each row of data:
var mapData = [];
$('#pvsoiling-table').DataTable({
"initComplete": function(settings, json) {
var api = this.api();
api.rows().data().each(function (p) {
mapData.push({ lat: Number(p[1]), lon: Number(p[2]) });
});
// your Highcharts.mapChart() logic, in a function:
buildChart();
}
});

highcharts lollipop/dumbbell chart change position/colour of positive and negative marker values

I am trying to create a lollipop chart where some values are negative, and some are positive, either side of zero, like this:
image
However the chart seemingly only allows the marker to be on the "high" end of the chart. Is there a way to control which end has the marker ?
I'm using these chart options:
chartOptions: {
chart: {
type: 'dumbbell',
inverted: true
},
title: {
text: 'lollipop chart'
},
xAxis: {
type: 'category'
},
yAxis: {
title: {
text: 'value'
}
},
series: [{
name: 'value',
data: [{
name: 'a',
low:0,
high:13,
}, {
name: 'b',
low:0,
high:26,
},{
name: 'c',
low:-43,
high:0
},{
name: 'd',
low:-83,
high:0
},{
name: 'e',
low:0,
high:113
}]
}]
}
The series which should be used in this case is a lollipop, but it seems that the array of objects configuration doesn't work. I reported it on the Highcharts Github issue channel, where you can follow this thread: https://github.com/highcharts/highcharts/issues/13202
As a solution in the dumbell series I suggest to find those graphics in the render callback and hide them.
Demo: https://jsfiddle.net/BlackLabel/3o7acsbt/
events: {
render() {
let chart = this;
chart.series[0].points.forEach(p => {
if (p.low >= 0){
p.lowerGraphic.hide()
} else {
p.upperGraphic.hide()
}
})
}
}
API: https://api.highcharts.com/highcharts/chart.events.render
EDIT
Under the GitHub link, the workaround showed up. Please check it, maybe will be fit better to your requirement.

How to show multiple sets in a Highcharts Venn chart?

I'd like to show two sets of Venn diagrams inside a single chart. So I have the following code for sets A and B:
Highcharts.chart('container', {
series: [{
type: 'venn',
data: [{
sets: ['A1'],
value: 188956
}, {
sets: ['A2'],
value: 211267
}, {
sets: ['A1', 'A2'],
value: 23085,
name: "overlap"
}, {
sets: ['B1'],
value: 10880
}, {
sets: ['B2'],
value: 10880
}, {
sets: ['B1', 'B2'],
value: 6389,
name: "overlap"
}]
}],
title: {
text: 'Sets A and B'
}
});
What's really nice about showing everything together is that the four circles are sized proportionately to each other. The problem is how they're laid out. I'd want to show set B on the right side of A with some spacing between them. I also want set B to be laid out horizontally like A is.
Is this doable and if so how?
Thanks!
Alvaro
That is not possible in one chart, but you can create multiple charts:
Highcharts.chart('container', {
...,
series: [{
type: 'venn',
data: [...]
}]
});
Highcharts.chart('container2', {
...,
series: [{
type: 'venn',
data: [...]
}]
});
Live demo: https://jsfiddle.net/BlackLabel/xy5dfq4s/
Docs: https://www.highcharts.com/docs/chart-and-series-types/venn-series

Highcharts: set only last chunk of line as a dotted zone

I'm trying to get this chart to only be dotted for the last month:
chart_data = [[1496275200000, 981], [1498867200000, 1089], [1501545600000, 1595], [1504224000000, 1296], [1506816000000, 1678], [1509494400000, 1879], [1512086400000, 2028], [1514764800000, 1885], [1517443200000, 1366], [1519862400000, 1558], [1522540800000, 1636], [1525132800000, 2438], [1527811200000, 2899], [1530403200000, 2521], [1533081600000, 2879], [1535760000000, 1702]]
Highcharts.chart('container', {
title: {
text: 'Zone with dash style'
},
subtitle: {
text: 'Dotted line typically signifies prognosis'
},
xAxis: {
type: 'datetime',
labels: {
formatter: function () {
return Highcharts.dateFormat('%Y-%m', this.value)
}
},
tickInterval: 30 * 24 * 3600 * 1000,
},
series: [{
data: chart_data,
zoneAxis: 'x',
zones: [{
value: chart_data.length - 2
}, {
dashStyle: 'dot'
}]
}]
});
https://jsfiddle.net/aL57381b/
(This highcharts code is basically the same as: http://jsfiddle.net/gh/get/library/pure/highcharts/highcharts/tree/master/samples/highcharts/series/color-zones-dashstyle-dot/ from the highcharts documentation, just with my time-series data instead.
However, it makes the entire chart turn dotted instead of just the last bit. Any ideas why? I can't seem to fix this.
You need the real value not the starting index like that :
dottedStartIndex = chart_data[chart_data.length - 2][0];
Highcharts.chart('container', {
...
zones: [{
value: dottedStartIndex
}, {
dashStyle: 'dot'
}]
Fiddle

Highcharts : selection

I made a barchart with dates. Currently, to remove the dates, you must click on the dates in the legend. I wish delete multiple dates at once.
Let's take an example. My dates range from 1960 to 2015. If I would have on my chart the dates from 2000 to 2005, so I would like that if you click on 1960 and 1999, then all the dates between are deleted / hidden. It goes faster when many dates.
How to do ?
Here is my code :
$(function () {
$('#container').highcharts({
chart: {
type: 'column'
},
colors:[
'#7cb5ec',
'#434348',
'#90ed7d',
'#f7a35c',
'#8085e9',
'#f15c80',
'#e4d354',
'#2b908f',
'#f45b5b',
'#91e8e1',
'#DA70D6',
'#1E90FF',
'#E0F000'
],
legend:{
itemStyle:{
fontSize:'10px',
font:'10pt',
color:'#000000'
}
},
title:{
style:{
fontSize:'0px'
}
},
subtitle:{
style:{
fontSize:'0px'
}
},
xAxis: {
categories: [
'',
],
},
yAxis: {
min: 15,
title: {
text: 'Number',
style:{
fontSize:'0px'
}
}
},
tooltip: {
shared: false,
useHTML: true
},
plotOptions: {
column: {
pointPadding: 0.2,
borderWidth: 0
}
},
series: [{
name: '2004',
data: [49.9],
},
{
name: '2005',
data: [83.6]
},
{
name: '2006',
data: [48.9]
},
{
name: '2007',
data: [69.1]
},
{
name: '2008',
data: [83.6]
},
{
name: '2009',
data: [40.9]
},
{
name: '2010',
data: [69.9]
},
{
name: '2011',
data: [83]
},
{
name: '2012',
data: [28.9]
},
{
name: '2013',
data: [40.9]
},
{
name: '2014',
data: [81.6]
},
{
name: '2015',
data: [24.9]
},
{
name: '2016',
data: [46.4]
}]
});
});
Thanks
Rather than having each year as its own series, I would recommend that you place the years as the values in your x-axis (as categories) and then use Highcharts' native zoom function to allow users to select a certain date range.
I've updated your fiddle with some changes, which I explain below: https://jsfiddle.net/brightmatrix/hr28s27L/
First, in your chart option, I added zoomType: 'x' to allow users to use their mouse to zoom in on specific years. The value x means they can only zoom horizontally (across), which makes for a "cleaner" interaction.
chart: {
type: 'column',
zoomType: 'x'
},
Second, I updated your x-axis with the years as the categories/values:
xAxis: {
categories: ['2004','2005','2006','2007','2008','2009','2010','2011','2012','2013','2014','2015','2016']
},
Lastly, I updated your series to show just the data points, which are then plotted on the y-axis:
series: [{
name: 'data by year',
data: [49.9,83.6,48.9,69.1,83.6,40.9,69.9,83,28.9,40.9,81.6,24.9,46.4]
}]
Here is what happens when a user clicks and drags their mouse cursor:
The shaded box is what they are selecting. Once they release the cursor, the chart will automatically adjust to show only what they chose. A "Reset Zoom" button will appear at the top right to allow them to go back to all years:
Update (July 19, 2016): I did some research on adding a simple slider element to this chart that allows users to choose from a range of years.
An updated version of my fiddle that shows this example chart with sliders can be found here: https://jsfiddle.net/brightmatrix/uvat8u05/.
The code to handle the sliders is shown below. I discovered that explicitly setting the slider values to integers using the parseInt() function solved a couple of problems:
You can correctly compare the slider values to make sure users can't choose an end year that is earlier than the start year.
The setExtremes() function correctly shows a single year when users choose the same start and end year.
All x-axis labels are shown at all times. Before I added parseInt(), some labels disappeared when users chose different values in the sliders.
Please be sure to read the comments I've left in both the HTML and Javascript panes, as I've included additional details on why I made certain code decisions.
// on change handler for both sliders
$('.mySlider').bind('change', function(e) {
e.preventDefault();
var chart = $('#container').highcharts();
// convert the slider values to integers to make sure setExtremes() works as expected
var slider1Val = parseInt($('input[name="slider1"]').val());
var slider2Val = parseInt($('input[name="slider2"]').val());
if (slider2Val < slider1Val) {
// warn the user if they try to choose an end year that is later than the start year
alert("You can't choose an end year that is earlier than your start year.");
} else {
// use setExtremes to set the x-axis ranges based on the values in the sliders
chart.xAxis[0].setExtremes(slider1Val, slider2Val);
}
});
I hope this information is helpful for you.

Resources