javascript - (Amcharts.js) 创建饼图饼图
问题描述
我对javascript比较陌生。最近我的任务是创建一个仪表板,因此我开始使用 amcharts.js 进行可视化。
因此,我想寻求指导,以创建饼图的饼图(基本上是在 amcharts https://www.amcharts.com/demos/pie-of-提供的此示例中添加另一层一个馅饼/。
我自己已经尝试了很长一段时间,但没有成功,如此处所示https://codepen.io/zxlow/pen/wvvJrZJ
// Themes begin
am4core.useTheme(am4themes_dataviz);
am4core.useTheme(am4themes_animated);
// Themes end
var container = am4core.create("chartdiv", am4core.Container);
container.width = am4core.percent(100);
container.height = am4core.percent(100);
container.layout = "horizontal";
var chart = container.createChild(am4charts.PieChart);
// Add data
chart.data = [{
"country": "Lithuania",
"litres": 500,
"subData": [{ name: "A", value: 200 },
{ name: "B", value: 150 },
{ name: "C", value: 100 },
{ name: "D", value: 50,
subData: [{name: "D2", value: 35,
name: "D3", value: 15}]
}]
}, {
"country": "Czech Republic",
"litres": 300
}, {
"country": "Ireland",
"litres": 200
}, {
"country": "Germany",
"litres": 150
}, {
"country": "Australia",
"litres": 140
}, {
"country": "Austria",
"litres": 120
}];
// Add and configure Series
var pieSeries = chart.series.push(new am4charts.PieSeries());
pieSeries.dataFields.value = "litres";
pieSeries.dataFields.category = "country";
pieSeries.slices.template.states.getKey("active").properties.shiftRadius = 0;
pieSeries.labels.template.disabled = true;
//pieSeries.labels.template.text = "{category}\n{value.percent.formatNumber('#.#')}%";
pieSeries.slices.template.events.on("hit", function(event) {
selectSlice(event.target.dataItem);
})
var chart2 = container.createChild(am4charts.PieChart);
chart2.width = am4core.percent(30);
chart2.radius = am4core.percent(80);
// Add and configure Series
var pieSeries2 = chart2.series.push(new am4charts.PieSeries());
pieSeries2.dataFields.value = "value";
pieSeries2.dataFields.category = "name";
pieSeries2.slices.template.states.getKey("active").properties.shiftRadius = 0;
//pieSeries2.labels.template.radius = am4core.percent(50);
//pieSeries2.labels.template.inside = true;
//pieSeries2.labels.template.fill = am4core.color("#ffffff");
pieSeries2.labels.template.disabled = true;
pieSeries2.ticks.template.disabled = true;
pieSeries2.alignLabels = false;
pieSeries2.events.on("positionchanged", updateLines);
var interfaceColors = new am4core.InterfaceColorSet();
var chart3 = container.createChild(am4charts.PieChart);
chart3.width = am4core.percent(30);
chart3.radius = am4core.percent(80);
// Add and configure Series
var pieSeries3 = chart3.series.push(new am4charts.PieSeries());
pieSeries3.dataFields.value = "litres";
pieSeries3.dataFields.category = "country";
pieSeries3.slices.template.states.getKey("active").properties.shiftRadius = 0;
pieSeries3.labels.template.disabled = true;
//pieSeries.labels.template.text = "{category}\n{value.percent.formatNumber('#.#')}%";
pieSeries.slices.template.events.on("hit", function(event) {
selectSlice(event.target.dataItem);
})
var line1 = container.createChild(am4core.Line);
line1.strokeDasharray = "2,2";
line1.strokeOpacity = 0.5;
line1.stroke = interfaceColors.getFor("alternativeBackground");
line1.isMeasured = false;
var line2 = container.createChild(am4core.Line);
line2.strokeDasharray = "2,2";
line2.strokeOpacity = 0.5;
line2.stroke = interfaceColors.getFor("alternativeBackground");
line2.isMeasured = false;
var selectedSlice;
function selectSlice(dataItem) {
selectedSlice = dataItem.slice;
var fill = selectedSlice.fill;
var count = dataItem.dataContext.subData.length;
pieSeries2.colors.list = [];
for (var i = 0; i < count; i++) {
pieSeries2.colors.list.push(fill.brighten(i * 2 / count));
}
chart2.data = dataItem.dataContext.subData;
pieSeries2.appear();
var middleAngle = selectedSlice.middleAngle;
var firstAngle = pieSeries.slices.getIndex(0).startAngle;
var animation = pieSeries.animate([{ property: "startAngle", to: firstAngle - middleAngle }, { property: "endAngle", to: firstAngle - middleAngle + 360 }], 600, am4core.ease.sinOut);
animation.events.on("animationprogress", updateLines);
selectedSlice.events.on("transformed", updateLines);
// var animation = chart2.animate({property:"dx", from:-container.pixelWidth / 2, to:0}, 2000, am4core.ease.elasticOut)
// animation.events.on("animationprogress", updateLines)
}
function updateLines() {
if (selectedSlice) {
var p11 = { x: selectedSlice.radius * am4core.math.cos(selectedSlice.startAngle), y: selectedSlice.radius * am4core.math.sin(selectedSlice.startAngle) };
var p12 = { x: selectedSlice.radius * am4core.math.cos(selectedSlice.startAngle + selectedSlice.arc), y: selectedSlice.radius * am4core.math.sin(selectedSlice.startAngle + selectedSlice.arc) };
p11 = am4core.utils.spritePointToSvg(p11, selectedSlice);
p12 = am4core.utils.spritePointToSvg(p12, selectedSlice);
var p21 = { x: 0, y: -pieSeries2.pixelRadius };
var p22 = { x: 0, y: pieSeries2.pixelRadius };
p21 = am4core.utils.spritePointToSvg(p21, pieSeries2);
p22 = am4core.utils.spritePointToSvg(p22, pieSeries2);
line1.x1 = p11.x;
line1.x2 = p21.x;
line1.y1 = p11.y;
line1.y2 = p21.y;
line2.x1 = p12.x;
line2.x2 = p22.x;
line2.y1 = p12.y;
line2.y2 = p22.y;
}
}
chart.events.on("datavalidated", function() {
setTimeout(function() {
selectSlice(pieSeries.dataItems.getIndex(0));
}, 1000);
});
非常感谢您的帮助。
解决方案
抱歉,有点晚了,我拿了你的代码,我修改了一些东西,有一个基于你的 3 饼图的例子。
am4core.ready(function() {
// Themes end
var container = am4core.create("pie_chart", am4core.Container);
container.width = am4core.percent(100);
container.height = am4core.percent(100);
container.layout = "horizontal";
var chart = container.createChild(am4charts.PieChart);
// Add data
chart.data = [{
"exist": "yes",
"number": 500,
"subData": [{ name: "A", value: 200,"subData":
[{ name: "X", value: 20 },
{ name: "Y", value: 15 },
{ name: "Z", value: 10 }, { name: "U", value: 5 }
]
}, { name: "B", value: 150, "subData":
[{ name: "X", value: 20 },
{ name: "Y", value: 15 },
{ name: "Z", value: 10 }, { name: "U", value: 5 }
] },
{ name: "C", value: 100,"subData":
[{ name: "X", value: 20 },
{ name: "Y", value: 15 },
{ name: "Z", value: 10 }, { name: "U", value: 5 }
] },
{ name: "D", value: 100,"subData":
[{ name: "X", value: 20 },
{ name: "Y", value: 15 },
{ name: "Z", value: 10 }, { name: "U", value: 5 }
] }
]
}, {
"exist": "No",
"number": 300
}];
// Add and configure Series
var pieSeries = chart.series.push(new am4charts.PieSeries());
pieSeries.dataFields.value = "number";
pieSeries.dataFields.category = "exist";
pieSeries.slices.template.states.getKey("active").properties.shiftRadius = 0;
pieSeries.labels.template.disabled = false;
pieSeries.ticks.template.disabled = false;
//pieSeries.labels.template.text = "{category}\n{value.percent.formatNumber('#.#')}%";
//Override original colors
/*pieSeries.slices.template.stroke = am4core.color("#fff");
pieSeries.slices.template.strokeWidth = 1.5;
pieSeries.slices.template.strokeOpacity = 1;*/
pieSeries.slices.template.events.on("hit", function(event) {
selectSlice(event.target.dataItem);
})
var chart2 = container.createChild(am4charts.PieChart);
chart2.width = am4core.percent(80);
chart2.radius = am4core.percent(70);
// Add and configure Series
var pieSeries2 = chart2.series.push(new am4charts.PieSeries());
pieSeries2.dataFields.value = "value";
pieSeries2.dataFields.category = "name";
pieSeries2.slices.template.states.getKey("active").properties.shiftRadius = 0;
//pieSeries2.labels.template.radius = am4core.percent(50);
//pieSeries2.labels.template.inside = true;
//pieSeries2.labels.template.fill = am4core.color("#ffffff");
pieSeries2.labels.template.disabled = false;
pieSeries2.ticks.template.disabled = false;
pieSeries2.alignLabels = false;
pieSeries2.events.on("positionchanged", updateLines);
//pieSeries2.slices.template.stroke = am4core.color("#fff");
//pieSeries2.slices.template.strokeWidth = 1.5;
//pieSeries2.slices.template.strokeOpacity = 1;
//update
pieSeries2.slices.template.events.on("hit", function(event) {
selectSlice2(event.target.dataItem);
})
pieSeries2.slices.template.events.on("hit", function(ev) {
var series = ev.target.dataItem.component;
series.slices.each(function(item) {
if (item.isActive && item != ev.target) {
item.isActive = false;
}
})
});
pieSeries2.events.on("positionchanged", updateLines);
var chart3 = container.createChild(am4charts.PieChart);
chart3.width = am4core.percent(70);
chart3.radius = am4core.percent(70);
// Add and configure Series
var pieSeries3 = chart3.series.push(new am4charts.PieSeries());
pieSeries3.dataFields.value = "value";
pieSeries3.dataFields.category = "name";
pieSeries3.slices.template.states.getKey("active").properties.shiftRadius = 0;
pieSeries3.slices.template.stroke = am4core.color("#fff");
pieSeries3.slices.template.strokeWidth = 1.5;
pieSeries3.slices.template.strokeOpacity = 1;
pieSeries3.labels.template.disabled = true;
pieSeries3.ticks.template.disabled = true;
pieSeries3.events.on("positionchanged", updateLines2);
//endupdate
var interfaceColors = new am4core.InterfaceColorSet();
var line1 = container.createChild(am4core.Line);
line1.strokeDasharray = "2,2";
line1.strokeOpacity = 0.5;
line1.stroke = interfaceColors.getFor("alternativeBackground");
line1.isMeasured = false;
var line2 = container.createChild(am4core.Line);
line2.strokeDasharray = "2,2";
line2.strokeOpacity = 0.5;
line2.stroke = interfaceColors.getFor("alternativeBackground");
line2.isMeasured = false;
var interfaceColors2 = new am4core.InterfaceColorSet();
var line3 = container.createChild(am4core.Line);
line3.strokeDasharray = "2,2";
line3.strokeOpacity = 0.5;
line3.stroke = interfaceColors2.getFor("alternativeBackground");
line3.isMeasured = false;
var line4 = container.createChild(am4core.Line);
line4.strokeDasharray = "2,2";
line4.strokeOpacity = 0.5;
line4.stroke = interfaceColors2.getFor("alternativeBackground");
line4.isMeasured = false;
var selectedSlice;
function selectSlice(dataItem) {
selectedSlice = dataItem.slice;
var fill = selectedSlice.fill;
var count = dataItem.dataContext.subData.length;
pieSeries2.colors.list = ["#cb2542", "#f2c33a", "#63c66e"].map(function(color) {
return new am4core.color(color);
});
for (var i = 0; i < count; i++) {
pieSeries2.colors.list.push(fill.brighten(i * 2 / count));
}
chart2.data = dataItem.dataContext.subData;
pieSeries2.appear();
var middleAngle = selectedSlice.middleAngle;
var firstAngle = pieSeries.slices.getIndex(0).startAngle;
var animation = pieSeries.animate([{ property: "startAngle", to: firstAngle - middleAngle }, { property: "endAngle", to: firstAngle - middleAngle + 360 }], 600, am4core.ease.sinOut);
animation.events.on("animationprogress", updateLines);
selectedSlice.events.on("transformed", updateLines);
// var animation = chart2.animate({property:"dx", from:-container.pixelWidth / 2, to:0}, 2000, am4core.ease.elasticOut)
// animation.events.on("animationprogress", updateLines)
}
//update
var selectedSlice2;
function selectSlice2(dataItem) {
selectedSlice2 = dataItem.slice;
var fill = selectedSlice2.fill;
var count = dataItem.dataContext.subData.length;
pieSeries3.colors.list = [];
for (var i = 0; i < count; i++) {
pieSeries3.colors.list.push(fill.brighten(i * 2.5 / count));
}
chart3.data = dataItem.dataContext.subData;
pieSeries3.appear();
var middleAngle2 = selectedSlice2.middleAngle + 10;
var firstAngle2 = pieSeries2.slices.getIndex(0).startAngle + 10;
var animation2 = pieSeries2.animate([{ property: "startAngle", to: firstAngle2 - middleAngle2 }, { property: "endAngle", to: firstAngle2 - middleAngle2 + 360 }], 600, am4core.ease.sinOut);
animation2.events.on("animationprogress", updateLines2);
selectedSlice2.events.on("transformed", updateLines2);
}
function updateLines2() {
if (selectedSlice2) {
var p11 = { x: selectedSlice2.radius * am4core.math.cos(selectedSlice2.startAngle), y: selectedSlice2.radius * am4core.math.sin(selectedSlice2.startAngle) };
var p12 = { x: selectedSlice2.radius * am4core.math.cos(selectedSlice2.startAngle + selectedSlice2.arc), y: selectedSlice2.radius * am4core.math.sin(selectedSlice2.startAngle + selectedSlice2.arc) };
p11 = am4core.utils.spritePointToSvg(p11, selectedSlice2);
p12 = am4core.utils.spritePointToSvg(p12, selectedSlice2);
var p21 = { x: 0, y: -pieSeries3.pixelRadius };
var p22 = { x: 0, y: pieSeries3.pixelRadius };
p21 = am4core.utils.spritePointToSvg(p21, pieSeries3);
p22 = am4core.utils.spritePointToSvg(p22, pieSeries3);
line3.x1 = p11.x;
line3.x2 = p21.x;
line3.y1 = p11.y;
line3.y2 = p21.y;
line4.x1 = p12.x;
line4.x2 = p22.x;
line4.y1 = p12.y;
line4.y2 = p22.y;
}
}
//endupdate
function updateLines() {
if (selectedSlice) {
var p11 = { x: selectedSlice.radius * am4core.math.cos(selectedSlice.startAngle), y: selectedSlice.radius * am4core.math.sin(selectedSlice.startAngle) };
var p12 = { x: selectedSlice.radius * am4core.math.cos(selectedSlice.startAngle + selectedSlice.arc), y: selectedSlice.radius * am4core.math.sin(selectedSlice.startAngle + selectedSlice.arc) };
p11 = am4core.utils.spritePointToSvg(p11, selectedSlice);
p12 = am4core.utils.spritePointToSvg(p12, selectedSlice);
var p21 = { x: 0, y: -pieSeries2.pixelRadius };
var p22 = { x: 0, y: pieSeries2.pixelRadius };
p21 = am4core.utils.spritePointToSvg(p21, pieSeries2);
p22 = am4core.utils.spritePointToSvg(p22, pieSeries2);
line1.x1 = p11.x;
line1.x2 = p21.x;
line1.y1 = p11.y;
line1.y2 = p21.y;
line2.x1 = p12.x;
line2.x2 = p22.x;
line2.y1 = p12.y;
line2.y2 = p22.y;
}
}
chart.events.on("datavalidated", function() {
//$("#jsonData").html( "pieSeries.dataItems.getIndex(0)");
//alert("msg " + JSON.stringify(pieSeries.dataItems.getIndex(0)));
setTimeout(function() {
selectSlice(pieSeries.dataItems.getIndex(0));
}, 1000);
});
}); // end am4core.ready
body {
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
}
#chartdiv {
width: 100%;
height: 500px;
}
<script src="https://www.amcharts.com/lib/4/core.js"></script>
<script src="https://www.amcharts.com/lib/4/charts.js"></script>
<script src="https://www.amcharts.com/lib/4/themes/dataviz.js"></script>
<script src="https://www.amcharts.com/lib/4/themes/animated.js"></script>
<div id="pie_chart"></div>
推荐阅读
- asp.net-core - 关闭/断开 ASP.NET Core signalR 客户端连接的正确方法是什么?
- java - 无法使用 Selenium(Java)单击屏幕外按钮并获取 ElementNotInteractableException
- vue.js - 带有 Nuxt 的 Vuex 中的项目是否被爬取?
- azure - Azure Kubernetes 服务中 PVC 的读写权限问题
- android - React Native - “绝对”位置和“zIndex”在Android上不起作用
- powershell - Invoke-Pester -OutputFile 和 -OutputFormat 是旧参数集的成员
- variables - 解决多个变量组中的 Azure YAML Pipeline 重叠变量名称
- python - 为 Django 翻译设置 URL
- python - 将字典字典转换为具有数据类型的数据框
- python - 如何使用 BSON (Python) 从 MongoDB 中检索存储的数据?