我试图通过将鼠标悬停在图例中的名称来显示雷达图中多边形的百分比。
您可以看到第一个品牌名称正在图例中悬停,并且图表中的相应多边形形状将被选中。我希望形状在每个角度都被其值(以%表示)包围。
我编写了这段代码,将所有百分比放在正确的位置并将console.log(+new Date('Wed Aug 23 2017 11:40:13 GMT-0700 (PDT)'));
设置为opacity
0
如何选择与特定形状相对应的一组百分比并使其显示?
编辑:多边形形状的代码:
// percentages
var pourcents = g.selectAll(".pourcentage")
.data(data)
.enter()
.append("g")
.attr("class","pourcentage");
pourcents.selectAll(".pourcentagetext")
.data(function(d,i) {return d[1]})
.enter().append("text")
.text(function (d,i) { if (d.value == 0) {"fill", "none"} else {return Format(d.value)}})
.attr("x", function(d,i){ return rScale(d.value + 0.05)* Math.cos(angleSlice*i - Math.PI/2) })
.attr("y", function(d,i){ return rScale(d.value + 0.05) * Math.sin(angleSlice*i - Math.PI/2) })
.attr("class", "pourcentagetext")
.attr("id", function (d,i) {return "per" + i})
.style("font-size", 10)
.style("opacity", 0);
我操作选择并通过设置blobWrapper.append("path")
.attr("class", "radarArea")
.attr("d", function(d,i) { return radarLine(d[1])})
.style("fill", function(d,i) { return color(i); })
.style("fill-opacity", cfg.opacityArea)
.attr("id", function (d,i) {return "tag" + i})
:
id
如何进行相同类型的选择,但是有一组相应的百分比?
答案 0 :(得分:1)
你有漂亮的图表
我如何进行相同类型的选择,但是有一组 相应的百分比?
我之前说过你可以添加一个类,使用
选择该类
d3.selectAll(/*class_name*/).each(function(){})
然后对每一个做点什么
如果您使用
d3.select('id')
,则只需选择一个元素
这就是为什么它在path
上工作,而不是text
使用#per1,#per2 etc
它的原因是什么?为什么你没有用相同的类或组来命名呢?
看到这个。我希望你能理解
var data = [
[[{name: "Bonpoint"}], [
{axis: "Coton", value: 1},
{axis: "Laine", value: 0.8},
{axis: "Cachemire", value: 0.6},
{axis: "Soie", value: 0.20},
{axis: "Angora", value: 0.20},
{axis: "Autres", value: 0.20},
{axis: "Nylon", value: 0},
{axis: "Acrylique", value: 0},
{axis: "Viscose", value: 0},
{axis: "Polyuréthane", value: 0},
{axis: "Polyester", value: 0.20}]],
[[{name: "Petit Bateau"}], [
{axis: "Coton", value: 1},
{axis: "Laine", value: 0.40},
{axis: "Cachemire", value: 0},
{axis: "Soie", value: 0},
{axis: "Angora", value: 0},
{axis: "Autres", value: 0},
{axis: "Nylon", value: 0},
{axis: "Acrylique", value: 0},
{axis: "Viscose", value: 0},
{axis: "Polyuréthane", value: 0},
{axis: "Polyester", value: 0.20}]],
[[{name: "Bobo Choses"}], [
{axis: "Coton", value: 1},
{axis: "Laine", value: 0.20},
{axis: "Cachemire", value: 0},
{axis: "Soie", value: 0},
{axis: "Angora", value: 0},
{axis: "Autres", value: 0},
{axis: "Nylon", value: 0.40},
{axis: "Acrylique", value: 0.40},
{axis: "Viscose", value: 0},
{axis: "Polyuréthane", value: 0},
{axis: "Polyester", value: 0}]],
[[{name: "BeBe"}], [
{axis: "Coton", value: 0.40},
{axis: "Laine", value: 0},
{axis: "Cachemire", value: 0},
{axis: "Soie", value: 0},
{axis: "Angora", value: 0},
{axis: "Autres", value: 0},
{axis: "Nylon", value: 0.20},
{axis: "Acrylique", value: 0.80},
{axis: "Viscose", value: 0.40},
{axis: "Polyuréthane", value: 0},
{axis: "Polyester", value: 0.80}]],
[[{name: "Familiar"}], [
{axis: "Coton", value: 1},
{axis: "Laine", value: 0.20},
{axis: "Cachemire", value: 0},
{axis: "Soie", value: 0},
{axis: "Angora", value: 0},
{axis: "Autres", value: 0},
{axis: "Nylon", value: 0},
{axis: "Acrylique", value: 0},
{axis: "Viscose", value: 0},
{axis: "Polyuréthane", value: 0},
{axis: "Polyester", value: 0.40}]],
[[{name: "Miki House"}], [
{axis: "Coton", value: 1},
{axis: "Laine", value: 0},
{axis: "Cachemire", value: 0},
{axis: "Soie", value: 0},
{axis: "Angora", value: 0},
{axis: "Autres", value: 0},
{axis: "Nylon", value: 0},
{axis: "Acrylique", value: 0},
{axis: "Viscose", value: 0},
{axis: "Polyuréthane", value: 0},
{axis: "Polyester", value: 0.40}]],
[[{name: "Uniqlo"}], [
{axis: "Coton", value: 1},
{axis: "Laine", value: 0.20},
{axis: "Cachemire", value: 0},
{axis: "Soie", value: 0},
{axis: "Angora", value: 0},
{axis: "Autres", value: 0},
{axis: "Nylon", value: 0},
{axis: "Acrylique", value: 0.20},
{axis: "Viscose", value: 0},
{axis: "Polyuréthane", value: 0.20},
{axis: "Polyester", value: 0.40}]],
[[{name: "Baby GAP"}], [
{axis: "Coton", value: 1},
{axis: "Laine", value: 0},
{axis: "Cachemire", value: 0},
{axis: "Soie", value: 0},
{axis: "Angora", value: 0},
{axis: "Autres", value: 0},
{axis: "Nylon", value: 0},
{axis: "Acrylique", value: 0.20},
{axis: "Viscose", value: 0},
{axis: "Polyuréthane", value: 0.20},
{axis: "Polyester", value: 0.40}]],
[[{name: "Lucien Zazou"}], [
{axis: "Coton", value: 0.80},
{axis: "Laine", value: 0},
{axis: "Cachemire", value: 0},
{axis: "Soie", value: 0},
{axis: "Angora", value: 0},
{axis: "Autres", value: 0},
{axis: "Nylon", value: 0},
{axis: "Acrylique", value: 0.20},
{axis: "Viscose", value: 0.20},
{axis: "Polyuréthane", value: 0},
{axis: "Polyester", value: 0.60}]],
];
var color = d3.scaleOrdinal().range(["#00baff", "#0014fe", "#00ff9c", "#f4bf02", "#ffa600", "#ff0000", "#ff00c4", "#ee693e", "#99958f"]);
radarChart(".radarChart", data);
function radarChart(id, data, options)
{
var cfg = {w: 700,
h: 700,
margin: {top: 20, right: 20, bottom: 20, left: 20},
levels: 5,
labelFactor: 1.35,
wrapWidth: 60,
opacityArea: 0.2,
dotRadius: 2,
opacityCircles: 0.1,
strokeWidth: 1,
roundStrokes: true,
areaName: "areaName",
ratio: 1.8,
color:function(d){
return 'black'
}
}
if('undefined' !== typeof options)
{for(var i in options)
{if ('undefined' !== typeof options[i]){cfg[i] = options[i]} } }
var maxValue = d3.max(data, function(i){return d3.max(i[1].map(function(o)
{return o.value}))} );
var minValue = d3.min(data, function(i) {return d3.min(i[1].map(function(o) {return o.value}))});
var areaName = cfg["areaName"];
// Variables for when creating the axis
var allAxis = (data[0][1].map(function(i, j) {return i.axis})),
total = allAxis.length, // autant d'axes que d''axis' indiqués dans data
radius = (cfg.h/3), //rayon du cercle le plus éloigné
innerRadius = (radius / cfg.levels) * cfg.ratio,
Format = d3.format('.0%'), //affiche en pourcentage, arrondi à l'entier
angleSlice = Math.PI * 2 / total; // L'écart entre chaque part de camembert
// Radius scale
var rScale =d3.scaleLinear().range([innerRadius,radius]).domain([0,maxValue]);
// Svg
var svg = d3.select("body")
.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");
// g
var g = svg.append("g")
.attr("transform", "translate(" + (cfg.w/2 + cfg.margin.left) + "," + (cfg.h/2 - cfg.margin.top) + ")");
// GRID
var axisGrid = g.append("g").attr("class", "axisWrapper");
// Grid variables
var inconnu = 2.13 //ratio: 1.8
var distance = cfg.ratio * inconnu ;
var step = distance / (cfg.levels + 1)
// drawing the Grid
axisGrid.selectAll(".levels")
.data(d3.range(0, distance, step)) //nombres et écart (1) de cercles à partir du centre
.append("circle")
.attr("class", "gridCircle")
.attr("r", function(d, i){return innerRadius + (radius /cfg.levels * d)})
.style("fill", "white")
.style("stroke", "lightgrey")
.style("stroke-width", 0.2)
.style("fill-opacity", 0);
// Axis displaying the percentages (not displayed atm)
axisGrid.selectAll(".axisLabel")
.data(d3.range(1, cfg.levels+1)) // à partir du 2è cercle jusqau'au 5ème
.enter()
.append("text")
.attr("class", "axisLabel")
.attr("x", -10)
.attr("y", function(d){return innerRadius + (radius /(cfg.levels * 1.575) * d)})
.attr("dy", "0.4em")
.style("font-size", "10px")
.attr("fill", "#737373")
.text(function(d,i) { return Format((d/cfg.levels))})
.style("display", "none");
// Drawing the axis
var axis = axisGrid.selectAll(".axis")
.data(allAxis)
.enter()
.append("g")
.attr("class", "axis");
axis.append("line")
.attr("x1", function(d, i){return rScale(0) * Math.cos(angleSlice*i - Math.PI/2) }) //x du point de départ des lignes
.attr("y1", function(d, i){return rScale(0) * Math.sin(angleSlice*i - Math.PI/2) }) //y du points de départ des lignes
.attr("x2", function(d, i){ return rScale(maxValue) * Math.cos(angleSlice*i - Math.PI/2); })
.attr("y2", function(d, i){ return rScale(maxValue) * Math.sin(angleSlice*i - Math.PI/2); })
.attr("class", "line")
.style("stroke", "lightgrey")
.style("stroke-width", 1)
.attr("display", "none");
// Legend (brand names)
var legende = svg.selectAll("noms")
.data(data)
.enter()
.append("text")
.text(function(d) {return d[0].map(function (o) {return o.name})})
.attr("class", "legende")
.style("font-family", "helvetica")
.style("fill-opacity", 0.8)
.attr("x", 0)
.attr("y", function (d,i) {return 12 + i * 20})
.attr("id", function (d,i) {return "leg" + i})
.style("font-size", 10)
.style("fill", function(d,i) { return color(i)})
.style("opacity", 1);
// Put all the percentages at the right place (opacity set to 0 atm)
var pourcents = g.selectAll(".pourcentage")
.data(data)
.enter()
.append("g")
.attr('class',function(d) {return d[0].map(function (o,i) {return "pourcentage"+d.name})})
// .attr("class","pourcentage");
pourcents.selectAll(".pourcentagetext")
.data(function(d,i) {return d[1]})
.enter().append("text")
.attr("x", function(d,i){ return rScale(d.value + 0.05)* Math.cos(angleSlice*i - Math.PI/2) })
.attr("y", function(d,i){ return rScale(d.value + 0.05) * Math.sin(angleSlice*i - Math.PI/2) })
.attr("id", function (d,i) {return "per" + i})
.attr("class", "per" + "pct" )
.style("font-size", 10)
.text(function (d,i) { if (d.value == 0) {"fill", "none"} else {return Format(d.value)}})
.style("opacity", 0);
// Drawing the lines of the blobs (polygonal shapes)
var radarLine = d3.radialLine()
.curve(d3.curveLinearClosed)
.radius(function(d) { return rScale(d.value); })
.angle(function(d,i) { return i*angleSlice });
if(cfg.roundStrokes) {radarLine.curve(d3.curveLinearClosed)}
var blobWrapper = g.selectAll(".radarWrapper")
.data(data)
.enter().append("g")
.attr("class", "radarWrapper");
//mouseover
var m_over= function(d,i,j){
d3.selectAll(".radarArea")
.transition().duration(100)
.style("fill-opacity", 0);
d3.selectAll(".radarStroke")
.transition().duration(100)
.style("stroke-width", 0);
d3.select("#tag" + i)
.transition()
.duration(100)
.style("fill-opacity", 1);
d3.selectAll(".cir" + i)
.transition()
.duration(100)
.style("fill-opacity", 1);
d3.selectAll(".cir_txt" + i)
.transition()
.duration(100)
.style("fill-opacity", 1);
d3.select(this).style("font-size", 12);
d3.selectAll(".cir_txt" + i).each(function (d,i) {return d3.select(this).style("opacity",1)})
d3.selectAll(".cir" + i).each(function (d,i) {return d3.select(this).style("opacity",1)})
d3.select("#tag" + i).each(function (d,i) {return d3.select("#per").style("opacity", 1)})
}
var m_out= function(d, i) {d3.selectAll(".radarArea")
.transition().duration(500)
.style("fill-opacity", cfg.opacityArea);
d3.selectAll(".radarStroke")
.transition().duration(500)
.style("stroke-width", 0.1);
d3.select("#tag" + i)
.transition()
.duration(700)
.style("fill-opacity", cfg.opacityArea);
d3.selectAll(".cir" + i).each(
function(d,i){
return d3.select(this).style("opacity",0)
}).transition()
.duration(700)
.style("fill-opacity", cfg.opacityArea)
d3.selectAll(".cir_txt" + i).each(
function(d,i){
return d3.select(this).style("opacity",0)
}).transition()
.duration(700)
.style("fill-opacity", cfg.opacityArea)
}
// Drawing the blobs
blobWrapper.append("g")
.attr("id", function (d,i) {return "tog" + i})
.append("path")
.attr("class", "radarArea")
.attr("d", function(d,i) { return radarLine(d[1])})
.style("fill", function(d,i) { return color(i); })
.style("fill-opacity", cfg.opacityArea)
.attr("id", function (d,i) {return "tag" + i})
.on("mouseover",m_over)
.on("mouseout",m_out);
// Drawing the strokes of the blobs
blobWrapper.append("path")
.attr("class", "radarStroke")
.attr("d", function(d,i) { return radarLine(d[1]); })
.style("stroke-width", 0.1)
.style("stroke", function(d,i) { return color(i); })
.style("fill", "none")
.attr("id", function (d,i) {return "rad" + i});
// Add points (small circles) at every blobs angles (not displayed atm)
data.forEach(function(d,i){
var idx = i
d3.select("#tog" + i).selectAll(".circle")
.data(function(d,i,j){return d[1]})
.enter()
.append('circle')
.attr('class', 'cir'+i )
.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) { if (d.value === 0) {return "none"} else {return cfg.color(j)}})
.style("fill-opacity", 0)
.style("fill", color(idx))
d3.select("#tog" + i).selectAll("text")
.data(function(d,i,j) {return d[1]})
.enter().append("text")
.attr('class', 'cir_txt'+i )
.attr("x", function(d,i){ return rScale(d.value) * Math.cos(angleSlice*i - Math.PI/2) })
.attr("y", function(d,i){ return rScale(d.value) * Math.sin(angleSlice*i - Math.PI/2); })
.style("fill", function(d,i,j) { if (d.value == 0) {return "none"} else {return cfg.color(j)}})
.style("fill-opacity", 1)
.attr("dx", -25)
//.attr("dy", -10)
.attr("text-anchor", "right")
.style("font-weight", "bold")
.text( function(d,i,j) { if (d.value == 0) {return "none"} else {return Format(d.value)}})
.style("fill-opacity", 0);
})
// Set a mouseover function for the legend
legende.on("mouseover",m_over)
.on("mouseout",m_out);
// Add a white circle at the center, inside the inner circle
var centercircle = g.append("circle").attr("r", innerRadius + 1.5).raise().style("fill", "white").style("opacity", 1).style("stroke-width", 1).style("stroke", "lightgrey");
// Names of the textiles (one at the end of 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})
.attr("id", function(d,i) {return "mat" + i});
}
body {font-family: 'Open Sans', sans-serif;
font-size: 11px;
font-weight: 300;
fill: #242424;
text-align: center;
cursor: default;}
.legend {font-family: 'Open Sans', sans-serif;
fill: #333333;}
.tooltip {fill: #333333;}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script src="https://code.jquery.com/jquery-3.1.0.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.2.3/d3.min.js"></script>
<meta name="viewport" content="width=device-width">
<title>JS Bin</title>
</head>
<body>
<div class="radarChart"></div>
</body>
</html>