Это должно быть довольно прямым, внутренний и внешний радиус каждой дуги необходимо изменить. В оригинале они установлены здесь:
var arc = d3.arc()
.startAngle(function (d) { return d.x0 })
.endAngle(function (d) { return d.x1 })
.innerRadius(function (d) { return d.y0 })
.outerRadius(function (d) { return d.y1 });
Вместо того, чтобы брать d.y0 и d.y1 в качестве внутреннего и внешнего радиусов, нам нужно взять эти значения и вычесть их из предельного радиуса солнечных лучей. Радиус определяется при масштабировании размера солнечных лучей:
var partition = d3.partition()
.size([2 * Math.PI, radius]);
Итак, мы можем использовать:
var arc = d3.arc()
.startAngle(function (d) { return d.x0 })
.endAngle(function (d) { return d.x1 })
.innerRadius(function (d) { return radius - d.y1 })
.outerRadius(function (d) { return radius - d.y0 });
Это ставит родителей снаружи своих детей.
Я поменял местами d.y1 и d.y0, поскольку d.y0 относится к меньшему числу, это внутренний радиус при нормальном движении наружу, но с возвращенным значением, равным radius-d.y0, теперь используется для определения внешнего радиуса
Вот пример:
// JSON data
var nodeData = {
"name": "TOPICS", "children": [{
"name": "Topic A",
"children": [{"name": "Sub A1", "size": 4}, {"name": "Sub A2", "size": 4}]
}, {
"name": "Topic B",
"children": [{"name": "Sub B1", "size": 3}, {"name": "Sub B2", "size": 3}, {
"name": "Sub B3", "size": 3}]
}, {
"name": "Topic C",
"children": [{"name": "Sub A1", "size": 4}, {"name": "Sub A2", "size": 4}]
}]
};
// Variables
var width = 500;
var height = 500;
var radius = Math.min(width, height) / 2;
var color = d3.scaleOrdinal(d3.schemeCategory20b);
// Create primary <g> element
var g = d3.select('svg')
.attr('width', width)
.attr('height', height)
.append('g')
.attr('transform', 'translate(' + width / 2 + ',' + height / 2 + ')');
// Data strucure
var partition = d3.partition()
.size([2 * Math.PI, radius]);
// Find data root
var root = d3.hierarchy(nodeData)
.sum(function (d) { return d.size});
// Size arcs
partition(root);
var arc = d3.arc()
.startAngle(function (d) { return d.x0 })
.endAngle(function (d) { return d.x1 })
.innerRadius(function (d) { return radius - d.y1; })
.outerRadius(function (d) { return radius - d.y0; });
// Put it all together
g.selectAll('path')
.data(root.descendants())
.enter().append('path')
.attr("d", arc)
.style('stroke', '#fff')
.style("fill", function (d) { return color((d.children ? d : d.parent).data.name); });
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.10.0/d3.min.js"></script>
<svg></svg>
Обратите внимание, здесь я показываю корневой узел, в оригинале он не отображается (создается пончик). Если вы хотите сохранить эффект пончика, мы можем продолжать скрывать корень, но добавим некоторые отступы к значениям радиусов:
// JSON data
var nodeData = {
"name": "TOPICS", "children": [{
"name": "Topic A",
"children": [{"name": "Sub A1", "size": 4}, {"name": "Sub A2", "size": 4}]
}, {
"name": "Topic B",
"children": [{"name": "Sub B1", "size": 3}, {"name": "Sub B2", "size": 3}, {
"name": "Sub B3", "size": 3}]
}, {
"name": "Topic C",
"children": [{"name": "Sub A1", "size": 4}, {"name": "Sub A2", "size": 4}]
}]
};
// Variables
var width = 500;
var height = 500;
var radius = Math.min(width, height) / 2;
var color = d3.scaleOrdinal(d3.schemeCategory20b);
// Create primary <g> element
var g = d3.select('svg')
.attr('width', width)
.attr('height', height)
.append('g')
.attr('transform', 'translate(' + width / 2 + ',' + height / 2 + ')');
// Data strucure
var partition = d3.partition()
.size([2 * Math.PI, radius]);
// Find data root
var root = d3.hierarchy(nodeData)
.sum(function (d) { return d.size});
// Size arcs
partition(root);
var arc = d3.arc()
.startAngle(function (d) { return d.x0 })
.endAngle(function (d) { return d.x1 })
.innerRadius(function (d) { return radius - d.y1 + root.y1; })
.outerRadius(function (d) { return radius - d.y0 + root.y1; });
// Put it all together
g.selectAll('path')
.data(root.descendants())
.enter().append('path')
.attr("display", function (d) { return d.depth ? null : "none"; })
.attr("d", arc)
.style('stroke', '#fff')
.style("fill", function (d) { return color((d.children ? d : d.parent).data.name); });
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.10.0/d3.min.js"></script>
<svg></svg>
Здесь я просто добавляю внешний радиус корневого узла (который является шириной дуги, поскольку внутренний радиус равен 0) к значениям радиусов. Обратите внимание, что если вы хотите сохранить пончик и показать корневой узел, вам необходимо соответствующим образом настроить размер диаграммы солнечных лучей. Хотя я более склонен называть это диаграммой солнечного взрыва.