Раскрывать элемент диаграммы по которому кликнули. На входе такой массив, где child - это это те элементы, которые надо раскрыть.
data = [{"label":"Расходы", "value":1000},
{"label":"Доходы", "value":2000},
{
"label":"Другое",
"value":500,
"child":[
{"label":"Другое 1", "value":400},
{"label":"Другое 2", "value":70},
{"label":"Другое 3", "value":30},
]
}];
После клика должно быть что-то вроде этого:
var w = 300,
h = 300,
r = 100,
color = d3.scale.category20b();
data = [{"label":"Расходы", "value":1000},
{"label":"Доходы", "value":2000},
{
"label":"Другое",
"value":500,
"child":[
{"label":"Другое 1", "value":400},
{"label":"Другое 2", "value":70},
{"label":"Другое 3", "value":30},
]
}];
var vis = d3.select("body")
.append("svg:svg")
.data([data])
.attr("width", w)
.attr("height", h)
.append("svg:g")
.attr("transform", "translate(" + r + "," + r + ")");
var arc = d3.svg.arc()
.outerRadius(r);
var pie = d3.layout.pie()
.value(function(d) { return d.value; });
var arcs = vis.selectAll("g.slice")
.data(pie)
.enter()
.append("svg:g")
.on("mouseover", function(d) {
});
arcs.append("svg:path")
.attr("fill", function(d, i) { return color(i); } )
.attr("d", arc)
.attr("stroke-width", "3px")
.attr("stroke", "#fff");
arcs.append("svg:text")
.attr("transform", function(d) {
d.innerRadius = 0;
d.outerRadius = r;
return "translate(" + arc.centroid(d) + ")";
})
.attr("text-anchor", "middle")
.attr("fill", "#fff")
.text(function(d, i) { return data[i].label; });
slice{
color: #fff;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Как это можно реализовать?
На самом деле идея проста. Нужно всего лишь определить arc, на который кликнули, и на его месте отрисовать дочерний pie chart.
const w = 300
const h = 300
const r = 150
const color = d3.scale.category20b();
const offset = 20
const data = [{
"label": "Расходы",
"value": 1000
},
{
"label": "Доходы",
"value": 2000
},
{
"label": "Другое",
"value": 500,
"child": [{
"label": "Другое 1",
"value": 400
},
{
"label": "Другое 2",
"value": 70
},
{
"label": "Другое 3",
"value": 30
},
]
}
];
const vis = d3.select("body")
.append("svg")
.data([data])
.attr("width", w)
.attr("height", h)
.append("g")
.attr("transform", "translate(" + r + "," + r + ")");
const arc = d3.svg.arc()
.outerRadius(r - offset)
.innerRadius(0);
const arcChild = d3.svg.arc()
.outerRadius(r)
.innerRadius(r / 2);
const pie = d3.layout.pie()
.value(d => d.value);
const pieChild = d3.layout.pie()
.value(d => d.value);
const arcs = vis.selectAll("g.slice")
.data(pie)
.enter()
.append("g")
.attr('class', 'slice')
.on('click', function(d) {
// если нет дочерних полей, игнорим
if (!('child' in d.data)) {
return
}
// берём настройки текущего arc,
// чтоб рисовать не полный круг,
// а только нужную область
const {
startAngle,
endAngle
} = d;
const self = d3.select(this)
// настраиваем углы в дочернем pie chart
pieChild.startAngle(startAngle).endAngle(endAngle)
// удаляем целый arc с родительскими данными
self.selectAll('path').remove()
self.selectAll('text').remove()
// рисуем дочерние arc
const childs = self
.selectAll('g.child')
.data(pieChild(d.data.child))
.enter()
.append('g')
.attr('class', 'child');
childs.append("path")
.attr("fill", (d, i) => color(i + 10))
.attr("d", arcChild)
.attr("stroke-width", "1px")
.attr("stroke", "#ccc");
});
arcs.append("path")
.attr("fill", (d, i) => color(i))
.attr("d", arc)
.attr("stroke-width", "3px")
.attr("stroke", "#fff");
arcs.append("text")
.attr("transform", d => "translate(" + arc.centroid(d) + ")")
.attr("text-anchor", "middle")
.attr("fill", "#fff")
.text((d, i) => data[i].label);
svg {
margin-top: 100px;
margin-left: 100px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Современные решения для бизнеса: как облачные и виртуальные технологии меняют рынок
Виртуальный выделенный сервер (VDS) становится отличным выбором
Проблема при конвертации heic в jpgИспользую официальную библиотеку на js
В официальном гайде angular2 для сущности Hero рекомендуется использовать пользовательский тип для данных: