英文:
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。
英文:
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.
答案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
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论