簡體   English   中英

d3.js 中的圖例

[英]Legends in d3.js

我正在做一個項目,需要我創建一個圖例圖例有 2 個值,它們都是文本我能夠創建圖例和其他東西,但我無法獲得相同的設計下面是代碼我正在使用的 .

問題:當前輸出無法處理長文本。 圖例的設計有不同顏色的文本(即;labels("A","B"...) 藍色,其余為黑色)

<!DOCTYPE html>
<meta charset="utf-8">

<body>      
<script src="https://d3js.org/d3.v6.js"></script>
<script>
var data = [{"legend_value":"A","value":8,"label":"test1"},
            {"legend_value":"B","value":15,"label":"this is a veryyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy long text"},
            {"legend_value":"C","value":20,"label":"test3"},
            {"legend_value":"D","value":10,"label":"test4"},
            {"legend_value":"E","value":25,"label":"test5"},
            {"legend_value":"F","value":1000,"label":"test6"},
];
for (var i=0;i <data.length;i++){
data[i]["legend_value"]=String.fromCharCode(65+i)
}
console.log(data)
// set the dimensions and margins of the graph
var margin = {top: 20, right: 500, bottom: 20, left: 40},
    width = 960 - margin.left - margin.right,
    height = 500 - margin.top - margin.bottom;

// set the ranges
var y = d3.scaleBand()
          .range([height, 0])
          .padding(0.2);

var x = d3.scaleLinear()
          .range([0, width-50]);
          
// append the svg object to the body of the page
// append a 'group' element to 'svg'
// moves the 'group' element to the top left margin
var svg = d3.select("body").append("svg")
    .attr("width", width + margin.left + margin.right)
    .attr("height", height + margin.top + margin.bottom)
  .append("g")
    .attr("preserveAspectRatio", "xMinYMin meet")
  .attr("viewBox", "0 0 300 300")
    .attr("transform", 
          "translate(" + margin.left + "," + margin.top + ")");

  // format the data
  data.forEach(function(d) {
    d.value = +d.value;
  });

  // Scale the range of the data in the domains
  x.domain([0, d3.max(data, function(d){ return d.value; })])
  y.domain(data.map(function(d) { return d.legend_value; }));
  //y.domain([0, d3.max(data, function(d) { return d.value; })]);


var bar_height=Math.min(Math.ceil((height/data.length)-data.length*1),45);
  // append the rectangles for the bar chart
  var bars = svg.selectAll(".bar")
      .data(data)
    .enter()
    
    bars.append("path")
      .attr("class", "bar")
      //.attr("x", function(d) { return x(d.value); })
      .attr("width", function(d) {return x(d.value); } )
      .attr("y", function(d) { return y(d.legend_value); })
      .attr("height", y.bandwidth())
      .attr("fill", "#056DFF")
      .attr("d",  function (d) {
                    console.log("y.bandwidth()",y.bandwidth())
                    return rightRoundedRect(0,Math.floor(y(d.legend_value)) , x(d.value), y.bandwidth(), 5);
            });
    
function rightRoundedRect(x, y, width, height, radius) {
  return "M" + x + "," + y
       + "h" + (width - radius)
       + "a" + radius + "," + radius + " 0 0 1 " + radius + "," + radius
       + "v" + (height - 2 * radius)
       + "a" + radius + "," + radius + " 0 0 1 " + -radius + "," + radius
       + "h" + (radius - width)
       + "z";
}

bars.append("text")
            .attr("class", "legend_value")
            //y position of the legend_value is halfway down the bar
            .attr("y",  function (d) { 
             return Math.floor(y(d.legend_value)+y.bandwidth()/data.length) + Math.ceil(bar_height/2);
             })
            //x position is 3 pixels to the right of the bar
            .attr("x", d => x(d.value)+20)
            .style("font-size", function (d) {
                
                return 10;
            })
            .style("font-family","sans-serif")
            .style('fill', '#DCDCDC')
            
            .text(function (d) {
                return d.value;
            })
            //.style("text-anchor", "middle");



  // add the x Axis
  svg.append("g")
      .attr("transform", "translate(0," + height + ")")
      .call(d3.axisBottom(x).tickSize(0));

  // add the y Axis
  svg.append("g")
      .call(d3.axisLeft(y).tickSize(0));





// add legend rect gray
svg.append("rect")
  .attr("class", "legend_text")
.attr("x", function(d, i){ 
    return  450 ;
})
.attr("y", function(d, i){ return 0 })
  .attr("rx", "5px")
  .attr("width", margin.left + margin.right-100)
  .attr("height", height)
  .attr("stroke", "darkgray")
  .attr("fill", "#F8F8F8");
  
var legend_text = svg.selectAll("legend_text")
  .data(data)
  .enter();

legend_text.append("text")
  .attr("class", "legend_text")
.attr("x", function(d, i){ 
    return  470 ;
})
.attr("y", function(d, i){ return 20 + i*20 })
  .attr("dy", "0.32em")
  .style("font-weight", "bold")
  .text(function(d) {
    return d["legend_value"] + "  " + d["label"] ;
  });

</script>
</body>

電流輸出在此處輸入圖片說明

預期產出在此處輸入圖片說明

除非這是必要的要求,否則將圖例設為常規 html 元素會更容易。 您可以在一個容器中有 2 個元素,其中 1 個包含 svg,另一個包含圖例。

我已經創建了我在這里談論的代碼筆: https ://codepen.io/OSquiddy/pen/OJmQxzx

如果由於限制,這不是您的選擇,我建議您重新調整代碼的用途以滿足您的要求(即 text-wrap inside 用於 svg <text>元素)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM