我正在做一些关于简化公司营销图形创建的研究。
一个特别是旭日形图,是在Illustrator中生成的(难以更新),我想将其切换到D3图形(通过JSON或CSV文件轻松更新)。问题是旭日形图是颠倒顺序 ...根节点在外环上,数据向内流动。 注意:我无法交换数据的顺序, 就是这样。
是否有可能在D3中翻转旭日图的绘制顺序?我一直在尝试使用sort函数......它按预期翻转了树根图的排序顺序......但似乎并没有影响旭日图的排序顺序。
这是我正在使用的旭日图表(来自here):
// 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 d.y0 })
.outerRadius(function (d) { return d.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); });
&#13;
<script src="https://d3js.org/d3.v4.min.js"></script>
<svg></svg>
&#13;
很多人! jB表示
答案 0 :(得分:1)
这应该非常简单,每个弧的内半径和外半径都需要修改。在原文中,它们设置在这里:
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); });
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.10.0/d3.min.js"></script>
<svg></svg>
&#13;
注意,我在这里显示根节点,原始它没有显示(创建一个甜甜圈)。如果你想保持甜甜圈效果,我们可以继续隐藏根,但是为半径值添加一些填充:
// 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); });
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.10.0/d3.min.js"></script>
<svg></svg>
&#13;
这里我只是将根节点的外半径(弧的宽度,内半径为0)添加到半径值。请注意,如果要维护甜甜圈并显示根节点,则需要适当调整旭日形图的大小。虽然我更倾向于称之为太阳内爆图。