(Amcharts.js) Создание круговой диаграммы круговой диаграммы

Я относительно новичок в JavaScript. Недавно мне было поручено создать информационную панель, и поэтому я начал использовать amcharts.js для своих визуализаций.

Следовательно, я хотел бы попросить совета, чтобы создать круговую диаграмму круговой диаграммы (в основном добавляя еще один слой к этому примеру, как это предусмотрено amcharts https://www.amcharts.com/demos/pie-of-a-pie/.

Я сам довольно долго пытался, но безуспешно, как видно здесь 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);
});

Ваша помощь очень ценится.


person X.enia    schedule 28.10.2019    source источник
comment
попробуйте изменить piesries на pieseries2 во втором экземпляре   -  person Arijit Mukherjee    schedule 28.10.2019
comment
вы использовали другую функцию, например, selectlice для 3-го набора   -  person Arijit Mukherjee    schedule 28.10.2019


Ответы (2)


Найдите эту рабочую скрипку.

Вам нужно скопировать функции selectslice и updatelines или изменить параметры, а также вам нужны новые строки для перерисовки при щелчке 3-го пирога при щелчке по Литве, вы можете увидеть 3-й пирог

person Arijit Mukherjee    schedule 28.10.2019
comment
Спасибо за помощь! Теперь я могу получить его (см. Здесь [ссылка] (codepen.io/zxlow/pen/wvvJrZJ)), но мне нужно, чтобы линии появлялись при нажатии на сектор круговой диаграммы, потому что в настоящее время я каким-то образом могу видеть линии только при изменении размера диаграммы. Могу я спросить, знаете ли вы почему? ‹Br› Кроме того, я бы предпочел, чтобы все 3 диаграммы отображались сразу при загрузке, а остальные разделы без субданных нельзя было щелкнуть - person X.enia; 29.10.2019
comment
Это потому, что код для линий должен быть написан для 3-го графика, что необходимо сделать. - person Arijit Mukherjee; 30.10.2019

извините, немного поздно, я взял ваш код и изменил некоторые вещи, есть пример 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>

person jvg    schedule 12.11.2020
comment
Добро пожаловать. Спасибо за ваш вклад. Объясните, пожалуйста, изменения в коде и почему. Выделите, почему / как ваш измененный код решает проблему OP. Ответы только на код не приветствуются. Большинство голосов набирается со временем, поскольку будущие посетители узнают что-то из вашего ответа, чем они могут применить к своим собственным проблемам с кодированием. - person SherylHohman; 12.11.2020