I am using the react wrapper for high charts btw.
What I have currently.
What I'm aiming for with but stacked waterfall chart
Just started using high charts and I love it but this one has me stumped. I figured out the data that I need to put that but now I just need to be able to place it in there..
Possible avenues of approach: Is there a way to add custom HTML only for the top series? Could I alter the data set to maybe re-render with the top label? Could I just make the labels show but add an additional label above with the points I wants and make the rest transparent?
import React from "react";
import Highcharts from "highcharts";
import HighchartsReact from "highcharts-react-official";
import HC_more from "highcharts/highcharts-more";
HC_more(Highcharts);
let categories = ["bar 1", "bar 2", "bar 3", "bar 4", "total bar"];
let series = [
{
data: [
20,
10,
-15,
30,
{
isSum: true,
},
],
name: "custom series 1",
},
{
data: [
20,
50,
-25,
10,
{
isSum: true,
},
],
name: "custom series 2",
lineWidth: 0,
},
{
data: [
5,
10,
-5,
10,
{
isSum: true,
},
],
name: "custom series 3",
lineWidth: 0,
},
];
let grandTotal = true;
function _createLabelValuePairs(s, c) {
let collection = {};
//Step 0 - iterate over data to get the series
s.map((dataSet) => {
//since we have total bars. Something that shouldn't be calc into the dataset we still need to figure out how many series it has
//for all the set values
dataSet.data.map((item, idx) => {
if (typeof item == "number") {
if (collection[c[idx]]) {
collection[c[idx]]["values"].push(item);
} else {
collection[c[idx]] = {};
collection[c[idx]]["values"] = [];
collection[c[idx]]["values"].push(item);
}
}
});
});
//Step 1 - Get my totals for each dataset
for (const a in collection) {
collection[a]["barTotal"] = collection[a].values.reduce(
(partialSum, a) => partialSum + a,
0,
);
}
//Step 2 - Get grand total numbers of all datasets.
if (grandTotal) {
//Step 2a - Totals for each bar
let sum = 0;
for (const item in collection) {
sum = sum + collection[item].barTotal;
if (collection[c[c.length - 1]]) {
collection[c[c.length - 1]]["values"].push(collection[item].barTotal);
} else {
collection[c[c.length - 1]] = {};
collection[c[c.length - 1]]["values"] = [];
collection[c[c.length - 1]]["values"].push(collection[item].barTotal);
}
}
//grand total bar will be the last entry in the set you pass in
collection[c[c.length - 1]]["barTotal"] = sum;
//Step 2b - Totals for each series
options.series.map((item) => {
if (collection[c[c.length - 1]]["seriesTotal"]) {
collection[c[c.length - 1]]["seriesTotal"][
item["name"]
] = item.data.reduce((partialSum, a) => {
if (typeof partialSum == "number") {
return Number(partialSum) + a;
}
}, 0);
} else {
collection[c[c.length - 1]]["seriesTotal"] = {};
collection[c[c.length - 1]]["seriesTotal"][item["name"]] = 0;
collection[c[c.length - 1]]["seriesTotal"][
item["name"]
] = item.data.reduce((partialSum, a) => {
if (typeof partialSum == "number") {
return Number(partialSum) + a;
}
}, 0);
}
if (
collection[c[c.length - 1]]["seriesTotal"][item["name"]].indexOf(
"[object Object]",
)
) {
collection[c[c.length - 1]]["seriesTotal"][item["name"]] = Number(
collection[c[c.length - 1]]["seriesTotal"][item["name"]].split(
"[object Object]",
)[0],
);
}
});
}
return collection;
}
function _getDelta(key, sets) {
console.log(sets);
//not passing anything back into the datalabel
return null;
}
const options = {
chart: {
type: "waterfall",
className: "test",
showAxes: false,
},
colors: ["#00A9F4", "#B3B3B3", "#000000"],
legend: {
align: "right",
symbolRadius: 0,
verticalAlign: "top",
},
title: {
text: "Stacked waterfall example",
},
plotOptions: {
series: {
stacking: "normal",
},
waterfall: {
borderColor: "none",
dashStyle: "Solid",
dataLabels: {
useHTML: true,
className: "waterfall-label",
enabled: true,
formatter: function(a) {
return _getDelta(
this.key,
_createLabelValuePairs(series, categories),
);
},
inside: false,
},
states: {
hover: {
animation: {
duration: 0,
},
enabled: false,
},
inactive: {
enabled: false,
},
select: {
enabled: false,
},
},
},
},
xAxis: {
categories: categories,
labels: {
style: {
color: "#000000",
cursor: "default",
fontSize: "14px",
fontFamily: "Mckinsey Sans Regular",
width: "75px",
whiteSpace: "normal", //set to normal
},
},
},
yAxis: {
visible: false,
},
series: series,
credits: {
enabled: false,
},
tooltip: {
animation: false,
backgroundColor: "#333333",
borderColor: "inherit",
borderRadius: 0,
formatter: function() {
return this.x + ": " + this.y;
},
hideDelay: 0,
shadow: false,
style: {
color: "white",
},
},
};
function Waterfall() {
return <HighchartsReact highcharts={Highcharts} options={options} />;
}
export default Waterfall;
And if you want to know what all that code was for _createLabelPairs it's just to get the totals of the series and that of the bars as well( If I need to use those later). I can figure out the percentages with barTotals and total property in the total bar


