我正在使用此d3 Radar Chart,现在我想为这些组着色。
这是我的数据 -
var data = [
[
{axis:"volume(N)",value:0.074095419,group:"one"},
{axis:"heightBBOX(N)",value:0.618900916,group:"one"},
{axis:"floor_area(N)",value:0.239036487,group:"one"},
{axis:"RatioSunExp_TotWall",value:0.670908597,group:"one"
}],
[
{axis:"volume(N)",value:0.373966243,group:"two"},
{axis:"heightBBOX(N)",value:0.418068276,group:"two"},
{axis:"floor_area(N)",value:0.039064467,group:"two"},
{axis:"RatioSunExp_TotWall",value:0.341108011,group:"two"
}],
[
{axis:"volume(N)",value:0.675991163,group:"two"},
{axis:"heightBBOX(N)",value:0.815015265,group:"two"},
{axis:"floor_area(N)",value:0.94061374,group:"two"},
{axis:"RatioSunExp_TotWall",value:0.974062924,group:"two"
}],
[
{axis:"volume(N)",value:0.875950233,group:"two"},
{axis:"heightBBOX(N)",value:0.210852068,group:"two"},
{axis:"floor_area(N)",value:0.540645865,group:"two"},
{axis:"RatioSunExp_TotWall",value:0.074841546,group:"two"
}]]
这些是我的颜色选项
var color = d3.scale.ordinal()
.domain(["one","two"])
.range(["#CC333F","#53e87d"]);
我想使用特定颜色为一个组着色,为另一种颜色设置两个组。我该怎么办?
更新:当我使用下面的代码时,所有图表都是黄色的。所以我知道这个小组是未定义的。我该如何解决这个问题?
color: function(d){
if(d.group == "one"){
return "red";
}
if(d.group == "two"){
return "green";
}
else{
return "yellow";
}
}
答案 0 :(得分:0)
代码的问题在于radarChartOptions
这个......
color: function(d){
...不会检索绑定到每个元素的datum
。
这里最好的解决方案是查看插件,或通过电子邮件发送给作者,以了解他/她如何传递选项。由于我没有时间检查插件文档,这里有一个简单的解决方案,在渲染后>>绘制路径/圆圈:
d3.selectAll(".radarArea").each(function(d){
d3.select(this).style("fill", color(d[0].group))
});
d3.selectAll(".radarStroke").each(function(d){
d3.select(this).style("stroke", color(d[0].group))
});
d3.selectAll(".radarCircle").each(function(d){
d3.select(this).style("fill", color(d.group))
});
这是更新的小提琴:https://jsfiddle.net/1j59znu9/
答案 1 :(得分:0)
您可能会注意到,通过使用函数insdide颜色,您会得到一个0到3之间的数字,表示包含4个数组的data
的当前数组。并且由于您要为每个颜色指定颜色,因此可以在指定每个颜色的位置使用另一个数组。所以你可能有4个这样的数组:
var colors = ["two","one","one","two"];
您可以使用默认结构保存数据:
var data = [[
{axis:"volume(N)",value:0.074095419},
{axis:"heightBBOX(N)",value:0.618900916},
{axis:"floor_area(N)",value:0.239036487},
{axis:"RatioSunExp_TotWall",value:0.670908597
}],
[
{axis:"volume(N)",value:0.373966243},
{axis:"heightBBOX(N)",value:0.418068276},
{axis:"floor_area(N)",value:0.039064467},
{axis:"RatioSunExp_TotWall",value:0.341108011
}],
[
{axis:"volume(N)",value:0.675991163},
{axis:"heightBBOX(N)",value:0.815015265},
{axis:"floor_area(N)",value:0.94061374},
{axis:"RatioSunExp_TotWall",value:0.974062924
}],
[
{axis:"volume(N)",value:0.875950233},
{axis:"heightBBOX(N)",value:0.210852068},
{axis:"floor_area(N)",value:0.540645865},
{axis:"RatioSunExp_TotWall",value:0.074841546
}]]
然后使用您在函数中获得的索引,测试哪种类型的组并分配所需的颜色:
color: function(d){
if(colors[d] === "one"){
return "red";
}
else if(colors[d] == "two"){
return "green";
}
else{
return "yellow";
}
}
就像那样,您不必更改正在使用的代码的行为,只需更改代码。
以下是完整代码:
function RadarChart(id, data, options) {
var cfg = {
w: 600, //Width of the circle
h: 600, //Height of the circle
margin: {
top: 20,
right: 20,
bottom: 20,
left: 20
}, //The margins of the SVG
levels: 3, //How many levels or inner circles should there be drawn
maxValue: 0, //What is the value that the biggest circle will represent
labelFactor: 1.25, //How much farther than the radius of the outer circle should the labels be placed
wrapWidth: 60, //The number of pixels after which a label needs to be given a new line
opacityArea: 0.35, //The opacity of the area of the blob
dotRadius: 4, //The size of the colored circles of each blog
opacityCircles: 0.1, //The opacity of the circles of each blob
strokeWidth: 2, //The width of the stroke around each blob
roundStrokes: false, //If true the area and stroke will follow a round path (cardinal-closed)
color: d3.scale.category10() //Color function
};
//Put all of the options into a variable called cfg
if ('undefined' !== typeof options) {
for (var i in options) {
if ('undefined' !== typeof options[i]) {
cfg[i] = options[i];
}
} //for i
} //if
//If the supplied maxValue is smaller than the actual one, replace by the max in the data
var maxValue = Math.max(cfg.maxValue, d3.max(data, function(i) {
return d3.max(i.map(function(o) {
return o.value;
}))
}));
var allAxis = (data[0].map(function(i, j) {
return i.axis
})), //Names of each axis
total = allAxis.length, //The number of different axes
radius = Math.min(cfg.w / 2, cfg.h / 2), //Radius of the outermost circle
Format = d3.format('.3'), //Percentage formatting
angleSlice = Math.PI * 2 / total; //The width in radians of each "slice"
//Scale for the radius
var rScale = d3.scale.linear()
.range([0, radius])
.domain([0, maxValue]);
/////////////////////////////////////////////////////////
//////////// Create the container SVG and g /////////////
/////////////////////////////////////////////////////////
//Remove whatever chart with the same id/class was present before
d3.select(id).select("svg").remove();
//Initiate the radar chart SVG
var svg = d3.select(id).append("svg")
.attr("width", cfg.w + cfg.margin.left + cfg.margin.right)
.attr("height", cfg.h + cfg.margin.top + cfg.margin.bottom)
.attr("class", "radar" + id);
//Append a g element
var g = svg.append("g")
.attr("transform", "translate(" + (cfg.w / 2 + cfg.margin.left) + "," + (cfg.h / 2 + cfg.margin.top) + ")");
/////////////////////////////////////////////////////////
////////// Glow filter for some extra pizzazz ///////////
/////////////////////////////////////////////////////////
//Filter for the outside glow
var filter = g.append('defs').append('filter').attr('id', 'glow'),
feGaussianBlur = filter.append('feGaussianBlur').attr('stdDeviation', '2.5').attr('result', 'coloredBlur'),
feMerge = filter.append('feMerge'),
feMergeNode_1 = feMerge.append('feMergeNode').attr('in', 'coloredBlur'),
feMergeNode_2 = feMerge.append('feMergeNode').attr('in', 'SourceGraphic');
/////////////////////////////////////////////////////////
/////////////// Draw the Circular grid //////////////////
/////////////////////////////////////////////////////////
//Wrapper for the grid & axes
var axisGrid = g.append("g").attr("class", "axisWrapper");
//Draw the background circles
axisGrid.selectAll(".levels")
.data(d3.range(1, (cfg.levels + 1)).reverse())
.enter()
.append("circle")
.attr("class", "gridCircle")
.attr("r", function(d, i) {
return radius / cfg.levels * d;
})
.style("fill", "#CDCDCD")
.style("stroke", "#CDCDCD")
.style("fill-opacity", cfg.opacityCircles)
.style("filter", "url(#glow)");
//Text indicating at what % each level is
axisGrid.selectAll(".axisLabel")
.data(d3.range(1, (cfg.levels + 1)).reverse())
.enter().append("text")
.attr("class", "axisLabel")
.attr("x", 4)
.attr("y", function(d) {
return -d * radius / cfg.levels;
})
.attr("dy", "0.4em")
.style("font-size", "10px")
.attr("fill", "#737373")
.text(function(d, i) {
return Format(maxValue * d / cfg.levels);
});
/////////////////////////////////////////////////////////
//////////////////// Draw the axes //////////////////////
/////////////////////////////////////////////////////////
//Create the straight lines radiating outward from the center
var axis = axisGrid.selectAll(".axis")
.data(allAxis)
.enter()
.append("g")
.attr("class", "axis");
//Append the lines
axis.append("line")
.attr("x1", 0)
.attr("y1", 0)
.attr("x2", function(d, i) {
return rScale(maxValue * 1.1) * Math.cos(angleSlice * i - Math.PI / 2);
})
.attr("y2", function(d, i) {
return rScale(maxValue * 1.1) * Math.sin(angleSlice * i - Math.PI / 2);
})
.attr("class", "line")
.style("stroke", "white")
.style("stroke-width", "2px");
//Append the labels at each axis
axis.append("text")
.attr("class", "legend")
.style("font-size", "11px")
.attr("text-anchor", "middle")
.attr("dy", "0.35em")
.attr("x", function(d, i) {
return rScale(maxValue * cfg.labelFactor) * Math.cos(angleSlice * i - Math.PI / 2);
})
.attr("y", function(d, i) {
return rScale(maxValue * cfg.labelFactor) * Math.sin(angleSlice * i - Math.PI / 2);
})
.text(function(d) {
return d
})
.call(wrap, cfg.wrapWidth);
/////////////////////////////////////////////////////////
///////////// Draw the radar chart blobs ////////////////
/////////////////////////////////////////////////////////
//The radial line function
var radarLine = d3.svg.line.radial()
.interpolate("linear-closed")
.radius(function(d) {
return rScale(d.value);
})
.angle(function(d, i) {
return i * angleSlice;
});
if (cfg.roundStrokes) {
radarLine.interpolate("cardinal-closed");
}
//Create a wrapper for the blobs
var blobWrapper = g.selectAll(".radarWrapper")
.data(data)
.enter().append("g")
.attr("class", "radarWrapper");
//Append the backgrounds
blobWrapper
.append("path")
.attr("class", "radarArea")
.attr("d", function(d, i) {
return radarLine(d);
})
.style("fill", function(d, i) {
return cfg.color(i);
})
.style("fill-opacity", cfg.opacityArea)
.on('mouseover', function(d, i) {
//Dim all blobs
d3.selectAll(".radarArea")
.transition().duration(200)
.style("fill-opacity", 0.1);
//Bring back the hovered over blob
d3.select(this)
.transition().duration(200)
.style("fill-opacity", 0.7);
})
.on('mouseout', function() {
//Bring back all blobs
d3.selectAll(".radarArea")
.transition().duration(200)
.style("fill-opacity", cfg.opacityArea);
});
//Create the outlines
blobWrapper.append("path")
.attr("class", "radarStroke")
.attr("d", function(d, i) {
return radarLine(d);
})
.style("stroke-width", cfg.strokeWidth + "px")
.style("stroke", function(d, i) {
return cfg.color(i);
})
.style("fill", "none")
.style("filter", "url(#glow)");
//Append the circles
blobWrapper.selectAll(".radarCircle")
.data(function(d, i) {
return d;
})
.enter().append("circle")
.attr("class", "radarCircle")
.attr("r", cfg.dotRadius)
.attr("cx", function(d, i) {
return rScale(d.value) * Math.cos(angleSlice * i - Math.PI / 2);
})
.attr("cy", function(d, i) {
return rScale(d.value) * Math.sin(angleSlice * i - Math.PI / 2);
})
.style("fill", function(d, i, j) {
return cfg.color(j);
})
.style("fill-opacity", 0.8);
/////////////////////////////////////////////////////////
//////// Append invisible circles for tooltip ///////////
/////////////////////////////////////////////////////////
//Wrapper for the invisible circles on top
var blobCircleWrapper = g.selectAll(".radarCircleWrapper")
.data(data)
.enter().append("g")
.attr("class", "radarCircleWrapper");
//Append a set of invisible circles on top for the mouseover pop-up
blobCircleWrapper.selectAll(".radarInvisibleCircle")
.data(function(d, i) {
return d;
})
.enter().append("circle")
.attr("class", "radarInvisibleCircle")
.attr("r", cfg.dotRadius * 1.5)
.attr("cx", function(d, i) {
return rScale(d.value) * Math.cos(angleSlice * i - Math.PI / 2);
})
.attr("cy", function(d, i) {
return rScale(d.value) * Math.sin(angleSlice * i - Math.PI / 2);
})
.style("fill", "none")
.style("pointer-events", "all")
.on("mouseover", function(d, i) {
newX = parseFloat(d3.select(this).attr('cx')) - 10;
newY = parseFloat(d3.select(this).attr('cy')) - 10;
tooltip
.attr('x', newX)
.attr('y', newY)
.text(Format(d.value))
.transition().duration(200)
.style('opacity', 1);
})
.on("mouseout", function() {
tooltip.transition().duration(200)
.style("opacity", 0);
});
//Set up the small tooltip for when you hover over a circle
var tooltip = g.append("text")
.attr("class", "tooltip")
.style("opacity", 0);
/////////////////////////////////////////////////////////
/////////////////// Helper Function /////////////////////
/////////////////////////////////////////////////////////
//Taken from http://bl.ocks.org/mbostock/7555321
//Wraps SVG text
function wrap(text, width) {
text.each(function() {
var text = d3.select(this),
words = text.text().split(/\s+/).reverse(),
word,
line = [],
lineNumber = 0,
lineHeight = 1.4, // ems
y = text.attr("y"),
x = text.attr("x"),
dy = parseFloat(text.attr("dy")),
tspan = text.text(null).append("tspan").attr("x", x).attr("y", y).attr("dy", dy + "em");
while (word = words.pop()) {
line.push(word);
tspan.text(line.join(" "));
if (tspan.node().getComputedTextLength() > width) {
line.pop();
tspan.text(line.join(" "));
line = [word];
tspan = text.append("tspan").attr("x", x).attr("y", y).attr("dy", ++lineNumber * lineHeight + dy + "em").text(word);
}
}
});
} //wrap
} //RadarChart
/* Radar chart design created by Nadieh Bremer - VisualCinnamon.com */
//////////////////////////////////////////////////////////////
//////////////////////// Set-Up //////////////////////////////
//////////////////////////////////////////////////////////////
var margin = {
top: 100,
right: 100,
bottom: 100,
left: 100
},
width = Math.min(700, window.innerWidth - 10) - margin.left - margin.right,
height = Math.min(width, window.innerHeight - margin.top - margin.bottom - 20);
//////////////////////////////////////////////////////////////
////////////////////////// Data //////////////////////////////
//////////////////////////////////////////////////////////////
var colors = ["two", "one", "one", "two"];
var data = [
[{
axis: "volume(N)",
value: 0.074095419
},
{
axis: "heightBBOX(N)",
value: 0.618900916
},
{
axis: "floor_area(N)",
value: 0.239036487
},
{
axis: "RatioSunExp_TotWall",
value: 0.670908597
}
],
[{
axis: "volume(N)",
value: 0.373966243
},
{
axis: "heightBBOX(N)",
value: 0.418068276
},
{
axis: "floor_area(N)",
value: 0.039064467
},
{
axis: "RatioSunExp_TotWall",
value: 0.341108011
}
],
[{
axis: "volume(N)",
value: 0.675991163
},
{
axis: "heightBBOX(N)",
value: 0.815015265
},
{
axis: "floor_area(N)",
value: 0.94061374
},
{
axis: "RatioSunExp_TotWall",
value: 0.974062924
}
],
[{
axis: "volume(N)",
value: 0.875950233
},
{
axis: "heightBBOX(N)",
value: 0.210852068
},
{
axis: "floor_area(N)",
value: 0.540645865
},
{
axis: "RatioSunExp_TotWall",
value: 0.074841546
}
]
]
//////////////////////////////////////////////////////////////
//////////////////// Draw the Chart //////////////////////////
//////////////////////////////////////////////////////////////
var colorFn = d3.scale.ordinal()
.domain(["one", "two"])
.range(["red", "green"]);
var radarChartOptions = {
w: width,
h: height,
margin: margin,
maxValue: 1,
levels: 10,
roundStrokes: true,
color: function(d) {
if (colors[d] === "one") {
return "red";
} else if (colors[d] == "two") {
return "green";
} else {
return "yellow";
}
},
};
//Call function to draw the Radar chart
RadarChart(".radarChart", data, radarChartOptions);

body {
font-family: 'Open Sans', sans-serif;
font-size: 11px;
font-weight: 300;
fill: #242424;
text-align: center;
text-shadow: 0 1px 0 #fff, 1px 0 0 #fff, -1px 0 0 #fff, 0 -1px 0 #fff;
cursor: default;
}
.legend {
font-family: 'Raleway', sans-serif;
fill: #333333;
}
.tooltip {
fill: #333333;
}

<!-- D3.js -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.6/d3.min.js" charset="utf-8"></script>
<div class="radarChart"></div>
&#13;
您还可以通过执行以下操作进行优化:
var colors = ["two","one","one","two"];
var colorDef = {"one":"red","two":"green"};
color: function(d){
return colorDef[colors[d]];
}
完整代码: