Plotly.js Create stacked and grouped bar chart - javascript

How to create barchart on Plotly.js with grouped and stacked bars? I need structure like that:
Barchart with stacked and grouped charts

It is possible to create a grouped-and-stacked bar chart in Plotly.js by creating each group as a subplot. It's not as simple as setting a top-level feature like 'barmode': 'stacked+grouped' but because it's more elemental it offers more options.
See https://community.plot.ly/t/combination-of-grouped-and-stacked-bar-chart/2154
Here each subplot references a shared common yaxis and its own xaxis. Each xaxis gets a "domain" which here means a portion of the overall bottom axis width. Here the first group gets [0.0, 0.33], the second [0.34, 0.66] and the third [0.67, 1.0]
Plotly.newPlot(
"myDiv",
[
{
x: ["A", "B", "C"],
y: [0.3, 0.35, 0.4],
type: "bar",
name: "series 1a",
xaxis: 'x1',
barmode: 'stack',
marker: {color: '#448'}
},
{
x: ["A", "B", "C"],
y: [0.6, 0.50, 0.40],
type: "bar",
name: "series 1b",
xaxis: 'x1',
barmode: 'stack', marker: {color: '#88C'}
},
{
x: ["A", "B", "C"],
y: [0.1, 0.15, 0.20],
type: "bar",
name: "series 1c",
xaxis: 'x1',
barmode: 'stack',
marker: {color: '#CCF'}
},
{
x: ["A", "B", "C"],
y: [0.3, 0.35, 0.4],
type: "bar",
name: "series 2a",
xaxis: 'x2',
barmode: 'stack', marker: {color: '#080'}
},
{
x: ["A", "B", "C"],
y: [0.25, 0.15, 0.05],
type: "bar",
name: "series 2b",
xaxis: 'x2',
barmode: 'stack', marker: {color: '#8c8'}
},
{
x: ["A", "B", "C"],
y: [0.45, 0.50, 0.55],
type: "bar",
name: "series 2c",
xaxis: 'x2',
barmode: 'stack', marker: {color: '#CFC'}
},
{
x: ["A", "B", "C"],
y: [0.3, 0.35, 0.4],
type: "bar",
name: "series 3a",
xaxis: 'x3',
barmode: 'stack', marker: {color: '#880'}
},
{
x: ["A", "B", "C"],
y: [0.6, 0.50, 0.40],
type: "bar",
name: "series 3b",
xaxis: 'x3',
barmode: 'stack', marker: {color: '#CC8'}
},
{
x: ["A", "B", "C"],
y: [0.1, 0.15, 0.20],
type: "bar",
name: "series 3c",
xaxis: 'x3',
barmode: 'stack', marker: {color: '#FFC'}
},
],
{
barmode: "stack",
yaxis: {tickformat: '%'},
xaxis: {
domain: [0, 0.33],
anchor: 'x1',
title: 'Apples'
},
xaxis2: {
domain: [0.33, 0.66],
anchor: 'x2', title: 'Pears'
},
xaxis3: {
domain: [0.67, 1.0],
anchor: 'x3', title: 'Cherries'
}
}
);

Newer answer as of 2021
Plotly.js now allows nested categorical axes without needing to create subplots with dedicated axes (see https://plotly.com/python/categorical-axes/)
The above chart has
Plotly.newPlot(
"myDiv",
[
{
x: [
["Apples","Apples","Apples","Pears","Pears","Pears","Dates","Dates","Dates"],
["East", "South","West","East", "South","West","East", "South","West"]
],
y: [0.3, 0.35, 0.4,0.3, 0.35, 0.4,0.3, 0.35, 0.4],
type: "bar",
name: "Snack",
marker: {color: '#448'}
},
{
x: [
["Apples","Apples","Apples","Pears","Pears","Pears","Dates","Dates","Dates"],
["East", "South","West","East", "South","West","East", "South","West"]
],
y: [0.6, 0.50, 0.40,0.25, 0.15, 0.05,0.6, 0.50, 0.40],
type: "bar",
name: "Ingredient",
marker: {color: '#88C'}
},
{
x: [
["Apples","Apples","Apples","Pears","Pears","Pears","Dates","Dates","Dates"],
["East", "South","West","East", "South","West","East", "South","West"]
],
y: [0.1, 0.15, 0.20,0.45, 0.50, 0.55,0.1, 0.15, 0.20],
type: "bar",
name: "Garnish",
marker: {color: '#CCF'}
}
],
{
barmode: "stack",
yaxis: {tickformat: '%'},
xaxis: {
type: 'multicategory',
title: 'Fruit'
},
yaxis: {
type: '',
range: [0,1],
tickformat: "0.0%"
}
}
);

Related

Adding annotations between subplots in horizontal bar graph (Plotly javascript)

I am making a javascript plotly bar graph to represent system downtime and I want to add annotations between my subplots, like this:
Here's the fiddle for the plot code, and the code here as well:
<head>
<!-- Plotly.js -->
<script src="https://cdn.plot.ly/plotly-latest.min.js"></script>
</head>
<body>
<div id="bar"></div>
</body>
var hoursDown, hoursOperational = [];
hoursDown = [8, 16, 8];
hoursOperational = hoursDown.map(x => 25 - x);
hoursDown2 = [10, 3, 3];
hoursOperational2 = hoursDown2.map(x => 25 - x);
var hoursDownTrace = {
x: hoursDown,
y: ["A", "B", "C"],
name: 'Down',
orientation: 'h',
marker: {
color: 'black',
},
type: 'bar',
width: .5
};
var hoursOperationalTrace = {
x: hoursOperational,
y: ["A", "B", "C"],
name: 'Operational',
orientation: 'h',
type: 'bar',
width: .2,
marker: {
color: 'green',
}
};
var hoursDownTrace2 = {
x: hoursDown2,
y: ["E", "F", "G"],
xaxis: 'x2',
yaxis: 'y2',
name: 'Down',
orientation: 'h',
marker: {
color: 'black',
},
type: 'bar',
width: .5
};
var hoursOperationalTrace2 = {
x: hoursOperational2,
y: ["E", "F", "G"],
name: 'Operational',
orientation: 'h',
type: 'bar',
width: .2,
xaxis: 'x2',
yaxis: 'y2',
marker: {
color: 'green',
}
};
var myData = [hoursDownTrace, hoursOperationalTrace, hoursDownTrace2, hoursOperationalTrace2];
var layout={
title: 'My Title',
barmode: 'stack',
xaxis: {side: 'top', bargap: 10},
xaxis2: {anchor: 'y2', side: 'top', bargap: 10},
xaxis3: {anchor: 'y3'},
yaxis: {domain: [0, 0.266]},
yaxis2: {domain: [0.366, 0.633]},
yaxis3: {domain: [0.733, 1]},
}
var annotations={
xref: 'paper',
yref: 'paper',
x: 0.01,
y: 0.9,
text: 'Annotation',
showarrow: false,
row: 3,
col: 1
}
Plotly.newPlot('bar', myData, layout);
Someone has done something similar in this answer but I wasn't able to integrate it into my code. I also tried several of the options from the plotly annotations documentation page to no luck.

How to render custom yAxis label on Highcharts Gantt with the 'custom' property?

I've got a Gantt chart:
And I want to use the series.gantt.custom object to set specific properties for each series on the yAxis.
From these properties I want to construct the yAxis labels.
My code:
Highcharts.ganttChart('container', {
yAxis: {
categories: ['1', '2'],
labels: {
formatter() {
return this.value
/* + this.chart.series[this.pos].custom.size */
},
}
},
series: [{
groupPadding: 1,
custom: {
size: "small",
},
type: 'line',
zoneAxis: 'x',
data: [{
y: 0,
x: Date.UTC(2022, 10, 18),
custom: {
label: 1,
}
}, {
y: 0,
x: Date.UTC(2022, 10, 25, 12),
custom: {
label: 2
}
}]
}, {
type: 'line',
zoneAxis: 'x',
custom: {
size: "large",
},
data: [{
y: 1,
x: Date.UTC(2022, 10, 18),
custom: {
label: 1
}
}, {
y: 1,
x: Date.UTC(2022, 10, 25, 12),
custom: {
label: 2
}
}]
}]
});
this.chart.series[this.pos].custom.size it's the bit that is not working.
The labels should be 1 small and 2 large.
A fiddle
You can reach this property through the series.options:
this.chart.series[this.pos].options.custom.size
Demo:
https://jsfiddle.net/BlackLabel/gLkn9uqf/

Need a single border for stacked bar graph in Highcharts

I am getting a border for each data in a stacked bar graph.
ChartOptions :
Highcharts.chart('container', {
chart: {
type: 'bar'
},
title: {
text: 'Stacked bar chart'
},
xAxis: {
categories: ['Apples', 'Oranges', 'Pears', 'Grapes', 'Bananas']
},
yAxis: {
min: 0,
title: {
text: 'Total fruit consumption'
}
},
legend: {
reversed: true
},
plotOptions: {
series: {
stacking: 'normal'
}
},
series: [{
name: 'John',
data: [{
y: 5,
borderColor: 'red',
borderWidth: 4
}, 3, 4, 7, 2]
}, {
name: 'Jane',
data: [{y: 2,
borderColor: 'red',
borderWidth: 4}, 2, 3, 2, 1]
}, {[enter image description here][1]
name: 'Joe',
data: [{y: 3,
borderColor: 'red',
borderWidth: 4}, 4, 4, 2, 5]
}]
});
codepen
I want something like this
image
Kindly help me with the correct ChartOptions which gives a single border around the bar without multiple borders around each bar.
Thanks and Regards
You can add fake series with a border and update it dynamically depending on changes on the chart or render a custom shape to simulate borders.
series: [..., {
showInLegend: false,
stacking: false,
data: [10],
grouping: false,
color: 'transparent',
borderWidth: 4,
borderColor: 'red'
}]
Live demo: http://jsfiddle.net/BlackLabel/gtLm9hqk/
API Reference:
https://api.highcharts.com/highcharts/series.column
https://api.highcharts.com/class-reference/Highcharts.SVGRenderer#rect
If you are trying to remove the red border, here is the solution:
Highcharts.chart('container', {
chart: {
type: 'bar'
},
title: {
text: 'Stacked bar chart'
},
xAxis: {
categories: ['Apples', 'Oranges', 'Pears', 'Grapes', 'Bananas']
},
yAxis: {
min: 0,
title: {
text: 'Total fruit consumption'
}
},
legend: {
reversed: true
},
plotOptions: {
series: {
stacking: 'normal'
}
},
series: [{
name: 'John',
data: [{
y: 5,
borderWidth: 1
}, 3, 4, 7, 2]
}, {
name: 'Jane',
data: [{
y: 2,
borderWidth: 1}, 2, 3, 2, 1]
}, {
name: 'Joe',
data: [{
y: 3,
borderWidth: 1}, 4, 4, 2, 5]
}]
});

How to stack bar from data with x and y in Chart JS

I am trying to plot a stack bar with data having the x and y values, eg {x: 1, y:1}.
But it seems that Chart JS follows indexing of array passed in the data with the index in the labels not the x.
I also tried using ticks: {source: 'data'} but no use.
I had to uncomment the labels: on and add index 1 and 2 in Africa dataset to see desired results.
Is there some way?
<canvas id="barchart" width="800" height="450"></canvas>
<script>
var ctx = document.getElementById("barchart").getContext('2d');
var barchart = new Chart(ctx, {
type: 'bar',
data: {
//labels: [0,1,2,3],
datasets: [{
data: [{x: 0, y: 2}, {x: 3, y: 1}],
label: "Africa",
backgroundColor: "#3e95cd",
fill: false
}, {
data: [{x: 0, y: 1}, {x: 1, y: 1}, {x: 2, y: 1}, {x: 3, y: 2}],
label: "Asia",
backgroundColor: "#8e5ea2",
fill: false
}, {
data: [{x: 0, y: 1}, {x: 1, y: 1}, {x: 2, y: 1}, {x: 3, y: 1}],
label: "Europe",
backgroundColor: "#3cba9f",
fill: false
}, {
data: [{x: 0, y: 1}, {x: 1, y: 1}, {x: 2, y: 1}, {x: 3, y: 1}],
label: "Latin America",
backgroundColor: "#e8c3b9",
fill: false
}, {
data: [{x: 0, y: 1}, {x: 1, y: 1}, {x: 2, y: 1}, {x: 3, y: 1}],
label: "North America",
backgroundColor: "#c45850",
fill: false
}
]
},
options: {
legend: { display: false },
title: {
display: true,
text: 'Predicted world population (millions) in 2050'
},
responsive: false,
maintainAspectRatio: false,
scales: {
xAxes: [{
stacked: true,
ticks: {source: 'data'}
}],
yAxes: [{
stacked: true
}]
}
}
});
</script>

Bubble chart (relations between bubbles)

Please can you tell me, is it possible to create relations between bubbles (lines from one bubble to other(s))?
Example:
SE->FL->NL
FL->DE
SE->BE->DE
DE->NL
Demo:
http://jsfiddle.net/2pLog7fw/
Sure, it can be done. One way of creating lines is to set lineWidth to be higher than zero for bubble series.
Live demo: http://jsfiddle.net/kkulig/2d7u7orx/
But this only creates one relation within a series (from the first point to the last one).
The solution here is to create a new scatter series for every relation:
{
data: [
[80.3, 86.1],
[80.8, 91.5],
[80.4, 102.5]
], // SE -> FI -> NL
type: 'scatter'
}, {
data: [
[86.5, 102.9],
[80.4, 102.5]
], // DE -> NL
type: 'scatter'
}
Configuration for all scatter series (plotOptions):
scatter: {
lineWidth: 1, // show the line
marker: {
radius: 0
}
}
Live demo: http://jsfiddle.net/kkulig/x8r6uj5q/
If you want an arrow that shows the direction of the relation you can use the code from this demo: http://jsfiddle.net/kkulig/mLsbzgnp/
This is right answer for my question:
"You can use scatter series to connect bubbles"
https://github.com/highcharts/highcharts/issues/7410
Example
Highcharts.chart('container', {
chart: {
type: 'bubble',
plotBorderWidth: 1,
zoomType: 'xy'
},
legend: {
enabled: false
},
title: {
text: 'Sugar and fat intake per country'
},
subtitle: {
text: 'Source: Euromonitor and OECD'
},
xAxis: {
gridLineWidth: 1,
title: {
text: 'Daily fat intake'
},
labels: {
format: '{value} gr'
},
plotLines: [{
color: 'black',
dashStyle: 'dot',
width: 2,
value: 65,
label: {
rotation: 0,
y: 15,
style: {
fontStyle: 'italic'
},
text: 'Safe fat intake 65g/day'
},
zIndex: 3
}]
},
yAxis: {
startOnTick: false,
endOnTick: false,
title: {
text: 'Daily sugar intake'
},
labels: {
format: '{value} gr'
},
maxPadding: 0.2,
plotLines: [{
color: 'black',
dashStyle: 'dot',
width: 2,
value: 50,
label: {
align: 'right',
style: {
fontStyle: 'italic'
},
text: 'Safe sugar intake 50g/day',
x: -10
},
zIndex: 3
}]
},
tooltip: {
useHTML: true,
headerFormat: '<table>',
pointFormat: '<tr><th colspan="2"><h3>{point.country}</h3></th></tr>' +
'<tr><th>Fat intake:</th><td>{point.x}g</td></tr>' +
'<tr><th>Sugar intake:</th><td>{point.y}g</td></tr>' +
'<tr><th>Obesity (adults):</th><td>{point.z}%</td></tr>',
footerFormat: '</table>',
followPointer: true
},
plotOptions: {
series: {
dataLabels: {
enabled: true,
format: '{point.name}'
}
}
},
series: [{
data: [{
x: 95,
y: 95,
z: 15.8,
name: 'BE',
country: 'Belgium'
}, {
x: 86.5,
y: 102.9,
z: 16,
name: 'DE',
country: 'Germany'
}, {
x: 80.8,
y: 91.5,
z: 15.8,
name: 'FI',
country: 'Finland'
}, {
x: 80.4,
y: 102.5,
z: 16,
name: 'NL',
country: 'Netherlands'
}, {
x: 80.3,
y: 86.1,
z: 18.8,
name: 'SE',
country: 'Sweden'
}]
}, {
type: 'scatter',
lineWidth: 1,
enableMouseTracking: false,
data: [
[95, 95], [86.5, 102.9],
[86.5, null],
[86.5, 102.9], [80.4, 102.5],
[86.5, null],
[86.5, 102.9], [80.3, 86.1]
]
}]
});
Live demo: http://jsfiddle.net/2pLog7fw/1/

Categories

Resources