#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')
...
для каждого экземпляра