如何在D3中为多个数据点制作单独的标签?

huangapple go评论69阅读模式
英文:

How do I make individual labels for multiple data points in D3?

问题

以下是您要翻译的内容:

我的数据文件是一个.csv文件(下面是数据),其中有一个名为"myletters"的列。它有3行的值为A,6行的值为B,11行的值为C,以及约18行的值为D。

我正在进行实验/学习,并尝试为每个字母值创建单独的圆圈,并根据值(A、B、C或D)将它们放置在4个不同的x、y坐标上。这部分已经实现了。我的问题是,我想为A、B、C或D创建一个标签,但.text将我的值的每个实例都引入,这会导致标签根据每个字母的实例数量变得逐渐变暗。A是黑色的,但D是非常、非常深的黑色。

我尝试过使用.data(unique_values)代替.data(data),但那只会在每个框中列出A、B、C、D。

如何在D3中为多个数据点制作单独的标签?

英文:

My data file is a .csv (data below) with one column called myletters. It has 3 rows with the value A, 6 rows with the value B, 11 rows with the value C, and about 18 rows with the value D.

I am experimenting/learning and trying to make individual circles for each letter value and place them in 4 different x,y coordinates based on the value (A,B,C, or D). This works. My problem is I want to create a label for A, B, C, or D but the .text is pulling in every instance of my value which causes the label to be progressively darker depending on how many instances of each letter. A is black but D is very, very heavy black.

    const margin = {left: 170, top: 50, bottom: 50, right: 20}
    const width = 1000 - margin.left - margin.right
    const height = 950 - margin.top - margin.bottom

    const coordinates = {
    'A': [300,150],
    'B': [450,150], 
    'C': [300,400],
    'D': [450,400] } ;    

    const svg = d3.select("#vis")
    .append('svg')
    .attr('width', 1000)
    .attr('height', 950)
    .attr('opacity', 1)
        
    const x = d3.scaleOrdinal()
    .domain([1, 2, 3,4])
    .range([150,300,450,550])

    const color = d3.scaleOrdinal()
    .domain([1, 2, 3,4])
    .range([ "#F8766D", "#00BA38", "#619CFF","#666666"])
 
      
    d3.csv('../data/testdata.csv').then(data => {
    const xAccessor = d => d.myletters

    const unique_value = [...new Set(data.map((item) => item.myletters))];

    const nodes = svg.selectAll("circle")
    .data(data)
    .enter()
    .append('circle')
    .style("fill", d=> color(xAccessor(d)))
    .style("fill-opacity", 0.8)
    .attr("stroke", "black")
    .attr('r', 7)
    .style("stroke-width", 1)

    simulation = d3.forceSimulation(data)
    simulation  
    .force('forceX',d3.forceX(d=> coordinates[xAccessor(d)][0])) //works
    .force('forceY',d3.forceY(d=> coordinates[xAccessor(d)][1])) //workd     
    .force("center", d3.forceCenter().x(width / 2).y(height / 2)) 
    .force("charge", d3.forceManyBody().strength(10)) 
    .force("collide", d3.forceCollide().strength(1).radius(8).iterations(5)) 
   
    .on("tick", function(d){
    nodes
    .attr('cx', d => d.x)
    .attr('cy', d => d.y)
          
    });

    //add label rectangle
     svg.selectAll('my_rect')
     .data(data)
     .enter()
     .append('rect')
    .attr('x',d=> coordinates[xAccessor(d)][0]) 
    .attr('y',d=> coordinates[xAccessor(d)][1]) 
    .attr('width',50)
    .attr('height', 30)
    .style("fill", d=> color(xAccessor(d)))
    .style("fill-opacity", 0.2)
    .attr("stroke", "#989898")
    const texts =  svg.selectAll('mytext')
    .data(data)
    .enter()
    .append('text')
         
    texts
                 
    .attr('x',d=> coordinates[xAccessor(d)][0]) 
    .attr('y',d=> coordinates[xAccessor(d)][1]) 
    .attr('font-size','12px')
    .attr('text-anchor','middle')
    .text(d => xAccessor(d))   

         
              
                     

    })
    //csv data
    myletters
    A
    A
    A
    B
    B
    B
    B
    B
    B
    C
    C
    C
    C
    C
    C
    C
    C
    C
    C
    C
    D
    D
    D
    D
    D
    D
    D
    D
    D
    D
    D
    D
    D
    D
    D
    D
    D
    D

I tried .data(unique_values) instead of .data(data) but that just lists A,B,C,D in each box.

如何在D3中为多个数据点制作单独的标签?

答案1

得分: 1

你可以通过使用 unique_value 来实现这一点。以下是修改后的代码:

svg
  .selectAll("my_rect")
  .data(unique_value) // 使用 unique_value
  .enter()
  .append("rect")
  .attr("x", (d) => coordinates[d][0]) // 不再使用 xAccessor
  .attr("y", (d) => coordinates[d][1]) // 不再使用 xAccessor
  .attr("width", 50)
  .attr("height", 30)
  .style("fill", (d) => color(d)) // 不再使用 xAccessor
  .style("fill-opacity", 0.2)
  .attr("stroke", "#989898");

const texts = svg.selectAll("mytext")
  .data(unique_value) // 使用 unique_value
  .enter()
  .append("text");

texts
  .attr("x", (d) => coordinates[d][0]) // 不再使用 xAccessor
  .attr("y", (d) => coordinates[d][1]) // 不再使用 xAccessor
  .attr("font-size", "12px")
  .attr("text-anchor", "middle")
  .text((d) => d); // 不再使用 xAccessor
英文:

You can achieve that by using unique_value. Here is the modified code:

svg
  .selectAll("my_rect")
  .data(unique_value) // use unique_value
  .enter()
  .append("rect")
  .attr("x", (d) => coordinates[d][0]) // no longer use xAccessor
  .attr("y", (d) => coordinates[d][1]) // no longer use xAccessor
  .attr("width", 50)
  .attr("height", 30)
  .style("fill", (d) => color(d)) // no longer use xAccessor
  .style("fill-opacity", 0.2)
  .attr("stroke", "#989898");

const texts = svg.selectAll("mytext")
  .data(unique_value) // use unique_value
  .enter()
  .append("text");

texts
  .attr("x", (d) => coordinates[d][0]) // no longer use xAccessor
  .attr("y", (d) => coordinates[d][1]) // no longer use xAccessor
  .attr("font-size", "12px")
  .attr("text-anchor", "middle")
  .text((d) => d); // no longer use xAccessor

huangapple
  • 本文由 发表于 2023年5月30日 03:11:27
  • 转载请务必保留本文链接:https://go.coder-hub.com/76359842.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定