Можно ли встроить одну диаграмму в другую в amCharts?
Кто-нибудь сталкивался с такой задачей или знает, возможно ли ее реализовать?
Когда я нажимаю на элемент на графике, я хотел бы отобразить под ним 3 других графика, часть функционала получилась, но я не понимаю, как переместить другие элементы вниз...
Вот что должно произойти.
const DATA = [
{
id: "1",
name: "Кузнецов Е.К.",
production: 300,
gzn: 60,
loyalty: 70,
firstChildren: [
{
name: "Январь 24",
value: 222,
},
{
name: "Февраль 17",
value: 175,
},
{
name: "Март 10",
value: 47,
},
{
name: "Прогноз",
value: 192,
},
{
name: "План",
value: 201,
},
],
},
{
id: "2",
name: "Петров К.П.",
production: 290,
gzn: 60,
loyalty: 70,
firstChildren: [
{
name: "Январь 24",
value: 222,
},
{
name: "Февраль 17",
value: 175,
},
{
name: "Март 10",
value: 47,
},
{
name: "Прогноз",
value: 192,
},
{
name: "План",
value: 201,
},
],
},
{
id: "3",
name: "Иванов П.И.",
production: 280,
gzn: 60,
loyalty: 70,
firstChildren: [
{
name: "Январь 24",
value: 222,
},
{
name: "Февраль 17",
value: 175,
},
{
name: "Март 10",
value: 47,
},
{
name: "Прогноз",
value: 192,
},
{
name: "План",
value: 201,
},
],
},
{
id: "4",
name: "Сидоров И.С.",
production: 270,
gzn: 60,
loyalty: 70,
firstChildren: [
{
name: "Январь 24",
value: 222,
},
{
name: "Февраль 17",
value: 175,
},
{
name: "Март 10",
value: 47,
},
{
name: "Прогноз",
value: 192,
},
{
name: "План",
value: 201,
},
],
},
{
id: "5",
name: "Алехно С.А.",
production: 260,
gzn: 60,
loyalty: 70,
firstChildren: [
{
name: "Январь 24",
value: 222,
},
{
name: "Февраль 17",
value: 175,
},
{
name: "Март 10",
value: 47,
},
{
name: "Прогноз",
value: 192,
},
{
name: "План",
value: 201,
},
],
},
];
am5.ready(function () {
// Create root element
// https://www.amcharts.com/docs/v5/getting-started/#Root_element
var root = am5.Root.new("stacked_click_bar_chart");
// Set themes
// https://www.amcharts.com/docs/v5/concepts/themes/
root.setThemes([am5themes_Animated.new(root)]);
buildStackedClickBarChart(root, DATA);
function buildStackedClickBarChart(root, data) {
// Create chart
// https://www.amcharts.com/docs/v5/charts/xy-chart/
let chart = root.container.children.push(
am5xy.XYChart.new(root, {
paddingLeft: 0,
paddingRight: 160,
layout: root.verticalLayout,
})
);
// Create axes
// https://www.amcharts.com/docs/v5/charts/xy-chart/axes/
let yRenderer = am5xy.AxisRendererY.new(root, {
inversed: true,
cellStartLocation: 0.1,
cellEndLocation: 0.9,
minorGridEnabled: true,
});
yRenderer.grid.template.setAll({
location: 1,
forceHidden: true,
});
yRenderer.labels.template.set("forceHidden", true);
let yAxis = chart.yAxes.push(
am5xy.CategoryAxis.new(root, {
categoryField: "name",
renderer: yRenderer,
tooltip: am5.Tooltip.new(root, {}),
})
);
yAxis.data.setAll(data);
let xRenderer = am5xy.AxisRendererX.new(root, {});
xRenderer.grid.template.set("forceHidden", true);
xRenderer.labels.template.set("forceHidden", true);
let xAxis = chart.xAxes.push(
am5xy.ValueAxis.new(root, {
min: 0,
maxPrecision: 0,
calculateTotals: true,
renderer: xRenderer,
})
);
// Add legend
// https://www.amcharts.com/docs/v5/charts/xy-chart/legend-xy-series/
let legend = chart.children.push(
am5.Legend.new(root, {
paddingTop: 10,
paddingBottom: 10,
clickTarget: "none",
})
);
legend.labels.template.setAll({
width: 100,
});
legend.markers.template.setAll({
width: 30,
height: 15,
});
legend.markerRectangles.template.setAll({
cornerRadiusTL: 10,
cornerRadiusTR: 10,
cornerRadiusBL: 10,
cornerRadiusBR: 10,
});
// Add series
// https://www.amcharts.com/docs/v5/charts/xy-chart/series/
function makeSeries(
name,
fieldName,
{ production, gzn, loyalty, sum }
) {
var series = chart.series.push(
am5xy.ColumnSeries.new(root, {
name: name,
xAxis: xAxis,
yAxis: yAxis,
valueXField: fieldName,
...getSum(),
categoryYField: "name",
sequencedInterpolation: true,
stacked: true,
clustered: false,
})
);
series.columns.template.events.on("click", function (ev) {
// column id
console.log("Clicked on a column", ev.target.uid);
// data item
console.log(ev.target.dataItem);
// your original data object
console.log(ev.target.dataItem.dataContext);
// series
console.log(ev.target.dataItem.component);
var firstChildrenData =
ev.target.dataItem.dataContext.firstChildren;
var chartFirstChildren =
ev.target.dataItem.component.children.push(
am5xy.XYChart.new(root, {
width: am5.percent(33),
paddingLeft: 0,
paddingRight: 1,
})
);
var xRenderer = am5xy.AxisRendererX.new(root, {
minGridDistance: 30,
minorGridEnabled: true,
});
xRenderer.labels.template.setAll({
rotation: 15,
centerY: am5.p50,
fontSize: 14,
});
xRenderer.grid.template.setAll({
location: 1,
});
var xAxisFirstChildren = chartFirstChildren.xAxes.push(
am5xy.CategoryAxis.new(root, {
maxDeviation: 0.3,
categoryField: "name",
renderer: xRenderer,
tooltip: am5.Tooltip.new(root, {}),
})
);
var yRenderer = am5xy.AxisRendererY.new(root, {
strokeOpacity: 0.1,
});
var yAxisFirstChildren = chartFirstChildren.yAxes.push(
am5xy.ValueAxis.new(root, {
maxDeviation: 0.3,
renderer: yRenderer,
})
);
var seriesFirstChildren = chartFirstChildren.series.push(
am5xy.ColumnSeries.new(root, {
name: "Выработка + ГЗН + лояльность",
xAxis: xAxisFirstChildren,
yAxis: yAxisFirstChildren,
valueYField: "value",
sequencedInterpolation: true,
categoryXField: "name",
tooltip: am5.Tooltip.new(root, {
labelText: "{valueY}",
}),
})
);
seriesFirstChildren.columns.template.setAll({
cornerRadiusTL: 5,
cornerRadiusTR: 5,
strokeOpacity: 0,
});
seriesFirstChildren.columns.template.adapters.add(
"fill",
function (fill, target) {
return chart
.get("colors")
.getIndex(
seriesFirstChildren.columns.indexOf(target)
);
}
);
seriesFirstChildren.columns.template.adapters.add(
"stroke",
function (stroke, target) {
return chart
.get("colors")
.getIndex(
seriesFirstChildren.columns.indexOf(target)
);
}
);
xAxisFirstChildren.data.setAll(firstChildrenData);
seriesFirstChildren.data.setAll(firstChildrenData);
seriesFirstChildren.appear(1000);
chartFirstChildren.appear(1000, 100);
});
series.columns.template.setAll({
height: am5.p100,
fill: getFillStroke(),
cornerRadiusTR: 5,
cornerRadiusBR: 5,
strokeOpacity: 0,
cursorOverStyle: "pointer",
});
series.data.setAll(data);
// Make stuff animate on load
// https://www.amcharts.com/docs/v5/concepts/animations/
series.appear();
series.bullets.push(function () {
return am5.Bullet.new(root, {
locationX: 1,
locationY: 0.5,
sprite: am5.Label.new(root, {}),
});
});
series.bullets.push(function () {
return am5.Bullet.new(root, {
locationX: 0,
locationY: 0.5,
sprite: production
? am5.Label.new(root, {
centerY: am5.p50,
text: "[bold]{name}",
fill: am5.color(0xffffff),
populateText: true,
})
: null,
});
});
if (loyalty) {
series.bullets.push(function () {
var label = am5.Label.new(root, {
centerY: am5.p50,
fill: "#3EB489",
text: "{valueX}",
populateText: true,
});
label.adapters.add("text", function (text, target) {
var { production, gzn, loyalty } =
target.dataItem.dataContext;
var val = Math.abs(production + gzn + loyalty);
return `[bold]${val} тыс.`;
});
return am5.Bullet.new(root, {
locationX: 1,
locationY: 0.5,
sprite: label,
});
});
}
legend.data.push(series);
function getSum() {
if (loyalty) {
return {
productionValueXField: sum.production,
gznValueXField: sum.gzn,
};
}
}
function getFillStroke() {
if (production) {
return "#3EB489";
}
if (gzn) {
return "#EEC759";
}
if (loyalty) {
return "#B08BBB";
}
}
}
makeSeries("Выработка", "production", { production: true });
makeSeries("ГЗН", "gzn", { gzn: true });
makeSeries("Лояльность", "loyalty", {
loyalty: true,
sum: {
production: "production",
gzn: "gzn",
},
});
// Make stuff animate on load
// https://www.amcharts.com/docs/v5/concepts/animations/
chart.appear(1000, 100);
}
});