Многопоточные круговые диаграммы не загружаются

#javascript #jquery #angularjs #d3.js #nvd3.js

#javascript #jquery #angularjs #d3.js #nvd3.js

Вопрос:

Я пытаюсь добавить несколько круговых диаграмм на одной странице, используя d3 js. Круговые диаграммы загружаются, когда их 2, но когда я добавляю 3-ю круговую диаграмму, график не добавляется к SVG. [Вот мой полный код.] Мой скрипт:http://www.jsfiddle.net/SampathPerOxide/xt0L1scu/10 /

   var h = 600;
  var r = h / 2;
  var arc = d3.svg.arc().outerRadius(r);

  var data = [{
        "label": "a",
        "value": 74
     },
     {
        "label": "b",
        "value": 7
     },
     {
        "label": "b",
        "value": 7
     },
     {
        "label": "d",
        "value": 12
     }
  ];
  var data1 = [{
        "label": "e",
        "value": 74
     },
     {
        "label": "f",
        "value": 7
     },
     {
        "label": "g",
        "value": 7
     },
     {
        "label": "h",
        "value": 12
     }
  ];

  var data2 = [{
        "label": "i",
        "value": 74
     },
     {
        "label": "j",
        "value": 7
     },
     {
        "label": "k",
        "value": 7
     },
     {
        "label": "l",
        "value": 12
     }
  ];
  var colors = [
     'rgb(178, 55, 56)',
     'rgb(213, 69, 70)',
     'rgb(230, 125, 126)',
     'rgb(239, 183, 182)'
  ]
  nv.addGraph(function() {
     var chart = nv.models.pieChart()
        .x(function(d) {
           return d.label
        })
        .y(function(d) {
           return d.value
        })
        .color(colors)
        .showLabels(true)
        .labelType("percent");

     d3.select("#chart svg")
        .datum(data)
        .transition().duration(1200)
        .call(chart);

     d3.selectAll(".nv-label text")
        .attr("transform", function(d) {
           d.innerRadius = -450;
           d.outerRadius = r;
           return "translate("   arc.centroid(d)   ")";
        })
        .attr("text-anchor", "middle")
        /* Alter CSS attributes */
        .style({
           "font-size": "1em"
        });

     d3.selectAll('.nv-series').each(function(d, i) {
        var group = d3.select(this),
           circle = group.select('circle');
        var color = circle.style('fill');
        circle.remove();
        var symbol = group.append('path')
           .attr('d', d3.svg.symbol().type('square'))
           .style('stroke', color)
           .style('fill', color)
           .attr('transform', 'scale(1.5) translate(-2,0)')
     });
     return chart;
  });
  nv.addGraph(function() {
     var chartnew = nv.models.pieChart()
        .x(function(d) {
           return d.label
        })
        .y(function(d) {
           return d.value
        })
        .color(colors)
        .showLabels(true)
        .labelType("percent");

     d3.select("#chartnew svg")
        .datum(data1)
        .transition().duration(1200)
        .call(chartnew);

     d3.selectAll(".nv-label text")
        /* Alter SVG attribute (not CSS attributes) */
        .attr("transform", function(d) {
           d.innerRadius = -450;
           d.outerRadius = r;
           return "translate("   arc.centroid(d)   ")";
        })
        .attr("text-anchor", "middle")
        .style({
           "font-size": "1em"
        });

     d3.selectAll('.nv-series').each(function(d, i) {
        var group = d3.select(this),
           circle = group.select('circle');
        var color = circle.style('fill');
        circle.remove();
        var symbol = group.append('path')
           .attr('d', d3.svg.symbol().type('square'))
           .style('stroke', color)
           .style('fill', color)
           .attr('transform', 'scale(1.5) translate(-2,0)')
     });
     return chartnew;
  });
  nv.addGraph(function() {
     var chartnewagains = nv.models.pieChart()
        .x(function(d) {
           return d.label
        })
        .y(function(d) {
           return d.value
        })
        .color(colors)
        .showLabels(true)
        .labelType("percent");

     d3.select("#chartnewagain svg")
        .datum(data2)
        .transition().duration(1200)
        .call(chartnewagains);

     d3.selectAll(".nv-label text")
        .attr("transform", function(d) {
           d.innerRadius = -450;
           d.outerRadius = r;
           return "translate("   arc.centroid(d)   ")";
        })
        .attr("text-anchor", "middle")
        .style({
           "font-size": "1em"
        });

     d3.selectAll('.nv-series').each(function(d, i) {
        var group1 = d3.select(this),
           circle = group.select('circle');
        var color = circle.style('fill');
        circle.remove();
        var symbol = group.append('path')
           .attr('d', d3.svg.symbol().type('square'))
           .style('stroke', color)
           .style('fill', color)
           // ADJUST SIZE AND POSITION
           .attr('transform', 'scale(1.5) translate(-2,0)')
     });
     return chartnewagains;
  });
  

Как я могу добавить пять круговых диаграмм на одной странице, используя приведенный выше код?

Комментарии:

1. Возможно ли улучшить структуру данных таким образом, чтобы данные для всех пяти круговых диаграмм находились в одном массиве?

2. В дополнение к приведенному выше комментарию и просто для улучшения вашего кода, вы используете функции d3 очень НЕСТАНДАРТНЫМ способом (записываете все дважды). Почему бы не создать функцию для рисования круговой диаграммы и вызвать ее, отправив параметры имени div и данных, и создать цикл for с данными, data1, data2 в массиве?

Ответ №1:

Я не думаю, что решение, предложенное Donat, сработало бы, поскольку проблема заключается не только в выборе. Я упростил код, чтобы поместить data , data1 data2 в массив с именем alldata . Это позволило мне создать forEach цикл для каждого из циклов alldata и создать унифицированную функцию drawchart, которая может рисовать круговую диаграмму для данных. После длительного устранения неполадок я обнаружил, что проблема в коде заключалась в добавлении условных обозначений данных, из-за которых возникла проблема. Похоже, circle.remove(); это и было причиной проблемы. Я отредактировал код в скрипте ниже, который устраняет проблему, удаляя круг, используя лучшее выделение.

Вот полная рабочая скрипка с улучшенным кодом, чтобы его было легче читать: https://jsfiddle.net/coolakul/z1b2p7x3 /

Я надеюсь, что это поможет. Дайте мне знать, если есть что-то, по чему вам нужны разъяснения.

Комментарии:

1. Идеально, повторение с использованием цикла. Спасибо за скрипку.

Ответ №2:

Вам нужно сфокусировать свой выбор на каждом SVG. Итак, сначала выберите текущий SVG:

 const svg = d3.select("#chartnewagain svg")
  

затем,

 svg.selectAll(".nv-label text")
svg.selectAll('.nv-series')
  

Потому что, когда вы используете d3.selectAll(«.something»), вы выбираете все с помощью class .something (также в приведенном выше SVG), а вы этого не хотите.

Надеюсь, это поможет 🙂

РЕДАКТИРОВАТЬ: Проблема в

  d3.selectAll('.nv-series').each(function(d, i) {
  var group = d3.select(this),
    circle = group.select('circle');
  console.log(circle)  
  var color = circle.style('fill');  // error
...
  

Потому что, когда вы делаете это в первый раз, '.nv-series' выбирается из первого svg, и все в порядке. Из первого и второго svg выбрано второе время '.nv-series' , и поскольку вы уже удалили этот круг в первом, он выдает ошибку, когда вы указываете, что получить стиль из элемента, с которым он не смог найти circle = group.select('circle')

Итак, решение таково:

 const svg = d3.select("#div_id svg")
...
svg.selectAll(".nv-label text")
...
svg.selectAll('.nv-series')
...
  

для каждого экземпляра