I have a little problem with gradient in sankey diagram.
My sankey diagram look like this
sankey diagram
I don't know how to set gradient to flow from first node to second node, etc. I'd like to create like this
sankey diagram
At this time I have done something like this
JSFiddle but this isn't what i want to.
My JS code include only sankeyChart class look like this
function sankeyChart() {
var sankey = Highcharts.chart('container', {
title: {
text: 'Sankey Diagram'
},
series: [{
keys: ['from', 'to', 'weight'],
data: [],
type: 'sankey',
name: ''
}],
plotOptions: {
series: {
colorByPoint: true
}
},
credits: {
enabled: false
}
});
function setData(data) {
sankey.series[0].update({
data: data,
}, true);
}
return {
'chart': sankey,
'setData': setData
}
}
I'll be grateful for any idea.
You can overwrite pointAttribs method and set the gradient in the way you want:
var H = Highcharts;
H.seriesTypes.sankey.prototype.pointAttribs = function(point, state) {
var opacity = this.options.linkOpacity,
color = point.color;
if (state) {
opacity = this.options.states[state].linkOpacity || opacity;
color = this.options.states[state].color || point.color;
}
return {
fill: point.isNode ?
color : {
linearGradient: {
x1: 0,
x2: 1,
y1: 0,
y2: 0
},
stops: [
[0, H.color(color).setOpacity(opacity).get()],
[1, H.color(point.toNode.color).setOpacity(opacity).get()]
]
}
};
}
Live demo: https://jsfiddle.net/BlackLabel/w3qgu497/
Docs: https://www.highcharts.com/docs/extending-highcharts/extending-highcharts
Related
I tried to display some map results in JustPy, but HighMap data labels in JustPy show as rotated, but only the label is roated not the map itself.
import justpy as jp
my_chart_def = """
{
chart: {
map: 'custom/europe',
borderWidth: 1
},
title: {
text: 'Nordic countries'
},
subtitle: {
text: 'Demo of drawing all areas in the map, only highlighting partial data'
},
legend: {
enabled: false
},
series: [{
name: 'Country',
data: [
['is', 1],
['no', 1],
['se', 1],
['dk', 1],
['fi', 1]
],
dataLabels: {
enabled: true,
color: '#FFFFFF'
},
}]
}
"""
def chart_test():
wp = jp.WebPage()
wp.head_html = """
<script src="https://code.highcharts.com/maps/9.2.2/highmaps.js"></script>
<script src="https://code.highcharts.com/mapdata/custom/europe.js"></script>
"""
my_chart = jp.HighCharts(a=wp, classes='m-2 p-2 border w-1/2 h-screen', options=my_chart_def)
my_chart.options.chart.type = 'map'
my_chart.options.series[0].name = 'Test chart'
my_chart.options.title.text = 'Data'
return wp
jp.justpy(chart_test)
This is what I got:
If I rotate the map 90 degrees, this is what I see, and the label seems aligned
I've reproduced your example in the editor, and everything seems to be correct https://jsfiddle.net/BlackLabel/6g92m7br/, so the issue occurs from the justpy side.
However, since 9.3.0 Highcharts Maps has improved geometry https://www.highcharts.com/blog/changelog/#highcharts-maps-v9.3.0, which could have affected another framework's behaviour. I would suggest reaching out JustPy developers directly.
As a workaround, you can try to play around with setting x, y dataLabels positions, e.g:
plotOptions: {
series: {
dataLabels: {
x: 15,
y: -50
}
}
}
Demo:
https://jsfiddle.net/BlackLabel/bnejx2kc/
API Reference:
https://api.highcharts.com/highmaps/plotOptions.map.dataLabels.x
https://api.highcharts.com/highmaps/plotOptions.map.dataLabels.y
my problem is that the primary and secondary yAxis zero is not on the same level. The screenshot can describe my problem better. Is there any possibility to fix this?
Here is the JSFiddle
Highcharts.chart('container', {
title: {
text: 'Stückzahl'
},
xAxis: {
categories: ['5007.205.1.1.1', '5007.225.1.1.1', '5007.285.1.1.1'],
labels:{
enabled: false
}
},
credits: {
enabled: false
},
legend:{
enabled: false
},
yAxis: [{
title: {
text: 'Stückzahl',
},
opposite: false
},{
title: {
text: 'FOR[%]',
},
opposite: true,
max:100,
min:0
}],
series: [
{
type: 'column',
name: 'Sollwert',
pointWidth:30,
grouping: false,
color: 'rgba(0,0,0,0.1)',
data: [2000, 1500, 1600],
yAxis: 0
},{
dataLabels:{
enabled:true
},
type: 'column',
grouping: false,
pointWidth:20,
name: 'John',
data: [1941, 975, 1936],
yAxis: 0
},{
dataLabels:{
enabled:true
},
color:'#ef703e',
grouping: false,
pointWidth:20,
type: 'column',
data: [-27, -15, -350],
yAxis: 0
},{
color:'black',
data: [80,60,99],
yAxis: 1,
type: 'line'
}]
});
To post this question, I need to describe my problem better. So ignore these last lines :/
There is an experimental wrap on Highcharts User Voice - multiple axis alignment control. It was written some time ago but it still works.
The wrap:
/**
* Experimental Highcharts plugin to implement chart.alignThreshold option. This primary axis
* will be computed first, then all following axes will be aligned to the threshold.
* Author: Torstein Hønsi
* Last revision: 2016-11-02
*/
(function (H) {
var Axis = H.Axis,
inArray = H.inArray,
wrap = H.wrap;
wrap(Axis.prototype, 'adjustTickAmount', function (proceed) {
var chart = this.chart,
primaryAxis = chart[this.coll][0],
primaryThreshold,
primaryIndex,
index,
newTickPos,
threshold;
// Find the index and return boolean result
function isAligned(axis) {
index = inArray(threshold, axis.tickPositions); // used in while-loop
return axis.tickPositions.length === axis.tickAmount && index === primaryIndex;
}
if (chart.options.chart.alignThresholds && this !== primaryAxis) {
primaryThreshold = (primaryAxis.series[0] && primaryAxis.series[0].options.threshold) || 0;
threshold = (this.series[0] && this.series[0].options.threshold) || 0;
primaryIndex = primaryAxis.tickPositions && inArray(primaryThreshold, primaryAxis.tickPositions);
if (this.tickPositions && this.tickPositions.length &&
primaryIndex > 0 &&
primaryIndex < primaryAxis.tickPositions.length - 1 &&
this.tickAmount) {
// Add tick positions to the top or bottom in order to align the threshold
// to the primary axis threshold
while (!isAligned(this)) {
if (index < primaryIndex) {
newTickPos = this.tickPositions[0] - this.tickInterval;
this.tickPositions.unshift(newTickPos);
this.min = newTickPos;
} else {
newTickPos = this.tickPositions[this.tickPositions.length - 1] + this.tickInterval;
this.tickPositions.push(newTickPos);
this.max = newTickPos;
}
proceed.call(this);
}
}
} else {
proceed.call(this);
}
});
}(Highcharts));
All you need to do is set alignThresholds in chart options.
Highcharts.chart('container', {
chart: {
alignThresholds: true
},
live example: http://jsfiddle.net/f3urehs0/
I have a simple json document :
[ {
"x" : "a",
"y" : 2
}, {
"x" : "b",
"y" : 8
}, {
"x" : "c",
"y" : 4
}, {
"x" : "d",
"y" : 15
} ]
I want to visualize it using Highcharts having 4 series. I could success, however, the data appeared only as one series (see the next Figure).
Here is part of the code:
var options = {
.
.
.
series: [{ }]
};
.
.
.
var data = JSON.parse(json);
var seriesData = [];
for (var i = 0; i < data.length; i++) {
seriesData.push([data[i].x, data[i].y]);
options.xAxis.categories.push( data[i].x );
}
options.series[0].data = seriesData;
var chart = new Highcharts.Chart(options);
also updating the series
chart.series[0].update({
type: type,
});
works fine.
using
options.series.push({name: data[i].x, data: [data[i].x, data[i].y]});
creates 4 series but not appropriately visualized and also updating the series
chart.series[0].update({
type: type,
});
doesn't work, therefore, I want to focus in the first mentioned method.
any hints?
EDit: code which partially works for me:
var options = {
chart: {
renderTo: 'container',
type: 'column' //default
},
title: {
text: ''
},
yAxis: {
title: {
enabled: true,
text: 'Count',
style: {
fontWeight: 'normal'
}
}
},
xAxis: {
title: {
enabled: true,
text: '',
style: {
fontWeight: 'normal'
}
},
categories: [],
crosshair: true
} ,
plotOptions: {
pie: {
innerSize: 125,
depth: 80
},
column: {
pointPadding: 0.2,
borderWidth: 0,
grouping: false
}
},
series: [{ }]
};
// Set type
$.each(['column', 'pie'], function (i, type) {
$('#' + type).click(function () {
chart.series[0].update({
type: type
});
});
var data = get the data fom json file**
var seriesData = [];
for (var i = 0; i < data.length; i++) {
seriesData.push([data[i].x, data[i].y]);
options.xAxis.categories.push( data[i].x );
}
options.series[0].data = seriesData;
var chart = new Highcharts.Chart(options);
});
});
You have to decide whether you want to have 4 different series and update all 4 series at once or you want to have one series an then build e.g. legend on your own.
If you want to have 4 series, set grouping to false, set xAxis categories and each point should be mapped to one series with one point - the point.x should have the index of the series.
const series = data.map((point, x) => ({ name: point.x, data: [{ x, y: point.y }]}))
const chart = Highcharts.chart('container', {
chart: {
type: 'column'
},
plotOptions: {
column: {
grouping: false
}
},
xAxis: {
categories: data.map(point => point.x)
},
series: series
});
Then you can update your all 4 series:
chart.series.forEach(series => series.update({
type: series.type === 'column' ? 'scatter' : 'column'
}, false))
chart.redraw()
example: http://jsfiddle.net/pdjqrj5y/
I am trying to color the bubbles based on the name of the cities. Something like if this.point.capital == Montgomery & this.point.capital == Juneau; color = "red". But I cannot add this if function to the color attribute. Can you help me out?
Thanks!!!!
series: [{
name: 'Basemap',
mapData: map,
borderColor: '#606060',
nullColor: 'rgba(200, 200, 200, 0.2)',
showInLegend: false
}, {
name: 'Separators',
type: 'mapline',
data: H.geojson(map, 'mapline'),
color: '#101010',
enableMouseTracking: false
}, {
type: 'mapbubble',
dataLabels: {
enabled: true,
format: '{point.capital}'
},
name: 'Cities',
data: data,
maxSize: '12%',
color: H.getOptions().colors[0]
}]
http://jsfiddle.net/oufwhmz0/
Do this for each bubble individually (not the series as a whole) in the data array prior to initiating the chart. For example extending your code (JSFiddle):
function determineColor(entry) {
if(entry.capital == "Montgomery")
return "#FF00FF";
else if(entry.capital == "Salt Lake City")
return "#00FF00";
return null;
}
// Add series with state capital bubbles
$.getJSON('http://www.highcharts.com/samples/data/jsonp.php?filename=us-capitals.json&callback=?', function (json) {
var data = [];
$.each(json, function (ix, entry) {
entry.z = entry.population;
entry.color = determineColor(entry); // Added
data.push(entry);
});
// ... rest as usual
});
This just sets the color for each entry (which will be a bubble), as defined by the determineColor function.
I'm working on project to display stock information using Highstock.
Question 1:
I tried to display ohlc data using ohlc graph, high and low using areasplinerange graph, and volume using column chart.
Everything works fine, if i zoom 1m, 3m, 6m, YTD, and 1y. Here is the snapshot. link1. But if zoom to All, The graph messed up like this link2.
Am i wrong in my coding or it's bug?
Question 2:
In the same chart, I have code to change the type of graph from ohlc to line. It works fine when I zoom to 1m, 3m. Here is the snapshot link3. But it show me no line chart when i zoom to 6m, 1y, and All. Here is the snapshot link4.
How can this happen?
Thank you for your help.
The Code:
Here is the code that i used to display the chart
$.getJSON(url, function (data1) {
$.getJSON(urlprediction, function (data2) {
var ohlc = [],
volume = [],
closed = [],
forecast = [],
dataLength1 = data1.length;
dataLength2 = data2.length;
for (i = 0; i < dataLength1; i++) {
ohlc.push([
data1[i][0], // the date
data1[i][1], // open
data1[i][2], // high
data1[i][3], // low
data1[i][4] // close
]);
closed.push([
data1[i][0], // the date
data1[i][4] // close
]);
volume.push([
data1[i][0], // the date
data1[i][5] // the volume
])
}
for (i = 0; i < dataLength2; i++) {
forecast.push([
data1[i][0], // the date
data1[i][1],
data1[i][2], // close
])
}
// set the allowed units for data grouping
var groupingUnits = [[
'week', // unit name
[1] // allowed multiples
], [
'month',
[1, 2, 3, 4, 6]
]];
$('#container').highcharts('StockChart', {
rangeSelector: {
selected: 1
},
title: {
text: title
},
yAxis: [{
title: {
text: 'OHLC'
},
height: 360,
lineWidth: 2
}, {
title: {
text: 'Volume'
},
top: 433,
height: 100,
offset: 0,
lineWidth: 2
}],
series: [{
type: 'ohlc',
name: stockname,
data: ohlc,
}, {
type: 'areasplinerange',
name: stockname,
data: data2,
}, {
type: 'column',
name: 'Volume',
data: volume,
yAxis: 1,
}]
});
});
});