Mekko Chart
A Mekko chart is a stacked column chart whose columns have different widths: the width shows how big each column is, the height how it splits up. Here, five columns of different sizes, each stacked from trucks, SUVs and cars.
About this chart
When a Mekko chart works
A Mekko chart shows two things at once: how big each group is, by its width, and what it is made of, by its stack. It suits market maps, where each column is a market, as wide as its share, and the stack shows its products.
Good for
- Market size and share in one chart
- Groups of very different sizes
- Spotting the biggest blocks at a glance
Think twice when
- Exact comparisons of middle segments: they have no common baseline
- Many columns or segments: the thin ones become unreadable
- Readers new to the form: explain what the width means
For developers
Get the code.
Built with amCharts 5, a JavaScript library. The code includes your theme and renderer (canvas or SVG), but not the changes you make with the controls.
For projects that use npm:
How it reads:
npm install @amcharts/amcharts5. See Getting started.
The same chart as a JSON config. Chart Maker reads and writes this format, the library's JSON parser turns it into a chart, and the <am5-chart> element puts it on a page with no code.How it reads:
"type" is the class to create and "settings" what you would pass to its new() in code; "properties" fill in its parts, lists such as series and axes or templates such as columns.template; "refs" holds objects used in more than one place ("#series-0" stands for the one named series-0); a string starting with "@" takes a value from another object, such as "@series.get('fill')".
A complete page. Save it as an .html file and open it in a browser.
Paste this into an AI coding assistant to build the chart from scratch. More in amCharts & AI.
// Create root element
// https://docs.amcharts.com/v5/getting-started/#root-element
var root = am5.Root.new("chartdiv");
// Set themes
// https://docs.amcharts.com/v5/concepts/themes/
root.setThemes([
am5themes_Animated.new(root),
am5themes_Responsive.new(root)
]);
// Create chart
// https://docs.amcharts.com/v5/charts/xy-chart/
var chart = root.container.children.push(am5xy.XYChart.new(root, {
panX: false, // no dragging to pan...
panY: false, // ...in either direction
layout: root.verticalLayout // the plot and the legend stacked top to bottom
}));
// Add legend
// https://docs.amcharts.com/v5/charts/xy-chart/legend-xy-series/
var legend = chart.children.push(
am5.Legend.new(root, {
centerX: am5.p50, // the legend's middle...
x: am5.p50 // ...at the middle of the chart's width
})
);
// no cursor, so no values for the legend: without the empty value labels its items stay compact
legend.valueLabels.template.set("forceHidden", true);
// Create axes
// https://docs.amcharts.com/v5/charts/xy-chart/axes/
// The horizontal axis runs from 0 to 100: each column's width is its share of the whole
var xAxis = chart.xAxes.push(am5xy.ValueAxis.new(root, {
min: 0,
max: 100,
renderer: am5xy.AxisRendererX.new(root, {})
}));
var yAxis = chart.yAxes.push(am5xy.ValueAxis.new(root, {
min: 0, // the stacks start at zero
renderer: am5xy.AxisRendererY.new(root, {})
}));
// Add series
// https://docs.amcharts.com/v5/charts/xy-chart/series/
// Each segment is a stacked step line: every point starts a column at "ax" with
// a height of "ay", so the steps draw columns of different widths
function createSeries(name, data) {
var series = chart.series.push(am5xy.StepLineSeries.new(root, {
name: name,
xAxis: xAxis,
yAxis: yAxis,
baseAxis: xAxis, // x is the base, so the values stack upward
valueYField: "ay",
valueXField: "ax",
stacked: true // each series sits on top of the one before
}));
series.strokes.template.setAll({
strokeWidth: 3 // a 3px line along the steps
});
series.fills.template.setAll({
fillOpacity: 0.2, // a faint fill...
visible: true // ...under the steps
});
series.data.setAll(data);
// Make stuff animate on load
// https://docs.amcharts.com/v5/concepts/animations/
series.appear();
// A hidden column series, stacked the same way, holds a label in the middle of each block
var bulletSeries = chart.series.push(am5xy.ColumnSeries.new(root, {
name: name,
xAxis: xAxis,
yAxis: yAxis,
baseAxis: xAxis, // x is the base, as for the step line
valueYField: "ay",
valueXField: "ax",
stacked: true // stacked like the step lines, so the labels land in their blocks
}));
bulletSeries.columns.template.setAll({
forceHidden: true // the columns themselves never show
});
// one label per block: in the middle of its width, with the block's height as value
var bulletSeriesData = [];
for(var i = 1; i < data.length; i++) {
bulletSeriesData.push({
"ax": data[i].ax - (data[i].ax - data[i-1].ax) / 2, // halfway between this point and the one before
"ay": data[i-1].ay // the block's height
})
}
bulletSeries.data.setAll(bulletSeriesData);
// a value label in the middle of each block
bulletSeries.bullets.push(function () {
return am5.Bullet.new(root, {
locationX: 0.5, // in the middle of the column...
locationY: 0.5, // ...halfway up
sprite: am5.Label.new(root, {
text: "{valueY}", // the block's height...
centerY: am5.p50, // ...centered on that point...
centerX: am5.p50, // ...both ways...
populateText: true, // ...filled in from the data item
background: am5.RoundedRectangle.new(root, { // on a box in the background color
fill: root.interfaceColors.get("background")
})
})
});
});
// the labels hide and show with their series, as its legend item is clicked
series.on("visible", function(visible, series) {
if (visible) {
bulletSeries.show();
}
else {
bulletSeries.hide();
}
})
legend.data.push(series); // a legend item for the step line only
return series;
}
var series1 = createSeries(
"Trucks",
[
{ "ax": 0, "ay": 20 },
{ "ax": 30, "ay": 10 },
{ "ax": 40, "ay": 35 },
{ "ax": 55, "ay": 43 },
{ "ax": 80, "ay": 33 },
{ "ax": 100, "ay": 33 }
]
);
var series2 = createSeries(
"SUVs",
[
{ "ax": 0, "ay": 10 },
{ "ax": 30, "ay": 39 },
{ "ax": 40, "ay": 22 },
{ "ax": 55, "ay": 26 },
{ "ax": 80, "ay": 15 },
{ "ax": 100, "ay": 15 }
]
);
var series3 = createSeries(
"Cars",
[
{ "ax": 0, "ay": 25 },
{ "ax": 30, "ay": 25 },
{ "ax": 40, "ay": 22 },
{ "ax": 55, "ay": 19 },
{ "ax": 80, "ay": 30 },
{ "ax": 100, "ay": 30 }
]
);
// Make stuff animate on load
// https://docs.amcharts.com/v5/concepts/animations/
chart.appear(1000, 100);



