我使用D3js(v4)作为Ember组件构建了一个饼图/圆环图,我试图让特定标签的片段用特定的颜色填充,但事实证明这很难。
要为图表着色,我有以下代码:
marc = arc().outerRadius(radius - 10).innerRadius(radius - donutwidth),
color = scaleOrdinal().range(['#49b6d6', '#f59c1a', '#ff5b57', '#00acac',]),
gEnter.append("path")
.attr("d", marc)
.attr("fill", (d, i) => {
return color(i);
})
以上工作正常并使用所选颜色填充圆弧,但不是每个圆弧所需的颜色。数组的索引是一致的,所以我试着简单地重新排列颜色的顺序而没有效果。
我还尝试使用基于索引的if语句,如:
gEnter.append("path")
.attr("d", marc)
.attr("fill", (d, i) => {
if (i === 0 { return color([0]) }
})
这会填充索引为0但不包含列表中所选颜色的段。更改颜色数([0])实际上根本不会产生任何变化。如果我尝试使用基于Label的字符串而不是数组索引的条件,也是如此。
修改
作为格式化图表数据的Ember Computed Property的一部分,数据会重新排序,以便每次都以相同的顺序显示每个标签。计算属性如下:
//takes the ember model 'referralsource' and groups it as needed
sourceData: groupBy('referralsource', 'label'),
//ember computed property that provides data to chart
pieData: Ember.computed('sourceData', function() {
let objs = this.get('sourceData')
let sortedObjs = _.sortBy(objs, 'value')
let newArray = []
sortedObjs.forEach(function(x) {
let newLabel = x.value
let count = x.items.length
let newData = {
label: newLabel,
count: count
}
newArray.push(newData)
})
return newArray
}),
答案 0 :(得分:0)
在您的第一个示例中,请尝试更改此内容:
color = scaleOrdinal().range(['#49b6d6', '#f59c1a', '#ff5b57', '#00acac',]),
为此:
color = scaleOrdinal().range([0,4]),
color.domain(['#49b6d6', '#f59c1a', '#ff5b57', '#00acac']),
用于指示比例尺寸的范围(在这种情况下为4,因为您放置了4种颜色),并且域指定了该比例的每个位置中的内容
答案 1 :(得分:0)
如果您的标签每次都相同(或从相同的选项池中绘制),则可以指定特定的域。在序数范围内,域名:
将域设置为指定的值数组。第一个元素 domain将映射到范围中的第一个元素,第二个元素 域值到第二个范围值,依此类推(from the API documentation)。
通过将域设置为包含每个可能标签选项的数组,您可以轻松地为每个标签指定颜色。下面的示例有五个可能的标签,第一行使用相反的数据数组顺序作为第二行,第三行使用带有重复的随机顺序。所有三行都始终将每个数据与特定颜色相关联:
var labels = ["redData","blueData","orangeData","pinkData","greenData"];
var colors = ["crimson","steelblue","orange","lightsalmon","lawngreen"];
var scale = d3.scaleOrdinal()
.domain(labels) // input values
.range(colors); // output values
var svg = d3.select("svg");
// initial order
svg.selectAll(null)
.data(labels)
.enter()
.append("circle")
.attr("cy",40)
.attr("cx", function(d,i) { return i * 40+ 20; })
.attr("r",15)
.attr("fill",function(d) { return scale(d); });
// reverse order
svg.selectAll(null)
.data(labels.reverse())
.enter()
.append("circle")
.attr("cy",80)
.attr("cx", function(d,i) { return i * 40+ 20; })
.attr("r",15)
.attr("fill",function(d) { return scale(d); });
// random labels
svg.selectAll(null)
.data(["blueData","blueData","redData","orangeData","blueData"])
.enter()
.append("circle")
.attr("cy",120)
.attr("cx", function(d,i) { return i * 40+ 20; })
.attr("r",15)
.attr("fill",function(d) { return scale(d); });
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.10.0/d3.min.js"></script>
<svg width="600" height="400"></svg>