I am trying to migrate the boxplot chart below from amcharts3 to amcharts5 and could use a hand.
There is a demo which looks close to what I need: text. The issue here is that I can't find a way to change the sticks colors and the box below and above the median.
The way it was done with amcharts 3 was by stacking graphs with the adjustment of the Y axis values: (the first graph represents the bottom green stick, the second is the yellow box and so on)
defaultBoxPlotOptions.graphs = [
{
"name": "Lower Limit",
"type": "candlestick",
"fill": ConfigService.chartColorsCandlestick('lower'),
'colorKey': 'lower',
"fillAlphas": 0,
"openField": "bottomOpen",
"highField": "lowOpen",
"lowField": "bottomOpen",
"closeField": "bottomOpen",
lineThickness: 2
},
{
"name": "Middle",
"type": "candlestick",
"fill": ConfigService.chartColorsCandlestick('open'),
"fillColors": ConfigService.chartColorsCandlestick('open'),
'colorKey': 'open',
"fillAlphas": 1,
"openField": "bottomOpen",
"highField": "middle",
"lowField": "bottomOpen",
"closeField": "middle"
},
.....
]
I understand that the equivalent of the graps in amcharts v5 are series, I tried the implementation in a vue3 component below. If I include stacked: true,
then I am getting the result below, otherwise I have the cluestered as default (one next to the other)
<template>
<div
id="chartdiv"
style="width: 100%; height: 500px"
></div>
</template>
<script setup lang="ts">
import { onMounted } from 'vue';
import * as am5 from '@amcharts/amcharts5';
import * as am5xy from '@amcharts/amcharts5/xy';
import am5themes_Animated from '@amcharts/amcharts5/themes/Animated';
onMounted(() => {
// Sample data
let data = [
{ date: '2019-08-01', open: 32.3, high: 36.96, low: 31.15, close: 36.49, median: 0 },
{ date: '2019-08-02', open: 35.26, high: 35.95, low: 31.5, close: 31.85, median: 0 },
{ date: '2019-08-03', open: 29.9, high: 33.27, low: 28.3, close: 32.25, median: 0 },
];
// Create root element
let root = am5.Root.new('chartdiv');
// Set themes
root.setThemes([
am5themes_Animated.new(root),
]);
// Create chart
let chart = root.container.children.push(
am5xy.XYChart.new(root, {
focusable: true,
panX: true,
panY: true,
wheelX: 'panX',
wheelY: 'zoomX',
}),
);
// Create axes
let xAxis = chart.xAxes.push(
am5xy.DateAxis.new(root, {
baseInterval: { timeUnit: 'day', count: 1 },
renderer: am5xy.AxisRendererX.new(root, {
pan: 'zoom',
minorGridEnabled: true,
minGridDistance: 70,
}),
tooltip: am5.Tooltip.new(root, {}),
}),
);
let yAxis = chart.yAxes.push(
am5xy.ValueAxis.new(root, {
renderer: am5xy.AxisRendererY.new(root, {
pan: 'zoom',
}),
}),
);
// Add series
let series = chart.series.push(
am5xy.CandlestickSeries.new(root, {
name: 'MDXI',
xAxis: xAxis,
yAxis: yAxis,
valueYField: 'close',
openValueYField: 'open',
lowValueYField: 'close',
highValueYField: 'open',
valueXField: 'date',
stacked: true,
tooltip: am5.Tooltip.new(root, {
pointerOrientation: 'horizontal',
labelText:
'open: {openValueY}\nlow: {lowValueY}\nhigh: {highValueY}\nclose: {valueY}\nmedian: {median}',
}),
}),
);
let series2 = chart.series.push(
am5xy.CandlestickSeries.new(root, {
name: 'wefwdfwd',
xAxis: xAxis,
yAxis: yAxis,
valueYField: 'open',
openValueYField: 'low',
lowValueYField: 'low',
highValueYField: 'low',
valueXField: 'date',
stacked: true,
}),
);
// Add median to data
data.forEach((item) => {
item.median = item.low + (item.high - item.low) / 2;
});
series.data.processor = am5.DataProcessor.new(root, {
dateFields: ['date'],
dateFormat: 'yyyy-MM-dd',
});
series.data.setAll(data);
series2.data.setAll(data);
// Median series
let medianSeries = chart.series.push(
am5xy.StepLineSeries.new(root, {
stroke: am5.color(0xff0000),
xAxis: xAxis,
yAxis: yAxis,
valueYField: 'median',
valueXField: 'date',
noRisers: true,
}),
);
medianSeries.data.setAll(data);
// Add cursor
let cursor = chart.set(
'cursor',
am5xy.XYCursor.new(root, {
xAxis: xAxis,
}),
);
cursor.lineY.set('visible', false);
// Make stuff animate on load
series.appear(1000, 100);
series2.appear(1000, 100);
medianSeries.appear(1000, 100);
chart.appear(1000, 100);
});
</script>
I can see two ways of achieving the boxplot chart in version 5 but I failed getting a result. Any tips would be greatly appreciated.
I have found that to create a candlestick chart like that we need to use ColumnSeries instead of CandlestickSeries
const boxplotSectionSeries = chart.series.push(
am5xy.ColumnSeries.new(root, {
name: "boxplotSection",
xAxis: xAxis,
yAxis: yAxis,
valueYField: "upper",
openValueYField: "up",
categoryXField: "category",
clustered: false,
fill: am5.color("#FFFFFF"),
})
);
boxplotSectionSeries.columns.template.setAll({
width: 50,
strokeWidth: 2,
tooltipText: " {openValueY}\nUpper: {valueY}",
tooltipY: am5.percent(10),
});
boxplotSectionSeries.data.setAll(data);
clustered: false, //will make the series stack
width: 50, // sets the width
fill: am5.color("#FFFFFF"), // sets the color
Hopefully this will help someone