如何在d3中以交互方式显示百分比?

时间:2017-08-23 18:44:43

标签: d3.js graph

我试图通过将鼠标悬停在图例中的名称来显示雷达图中多边形的百分比。

这是一张照片:enter image description here

您可以看到第一个品牌名称正在图例中悬停,并且图表中的相应多边形形状将被选中。我希望形状在每个角度都被其值(以%表示)包围。

我编写了这段代码,将所有百分比放在正确的位置并将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

如何进行相同类型的选择,但是有一组相应的百分比?

1 个答案:

答案 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>