英文:
How to join data by special order to svg text
问题
我的数据如下:
const data = [
{ name: 'Jane', age: 90 },
{ name: 'Paul', age: 20 },
{ name: 'Jerry', age: 32 },
{ name: 'Mary', age: 75 },
];
我的SVG如下:
```
正如你上面所看到的,数据和SVG并未按照名称排序。
我想保持这个顺序 Jerry → Paul → Mary → Jane
。但是每次我尝试使用d3进行连接时,它都会按照数据的顺序连接(jane → paul → jerry → mary
)。
我不知道如何按照SVG的顺序连接数据。:(
const svg = d3.select('svg');
svg.selectAll('.age').data(data).text(function(d){return d.age})
有没有解决这个问题的方法?有什么线索吗?
或者也许这不是使用d3的正确或适当的方式?:(
谢谢。
<details>
<summary>英文:</summary>
my data is like
const data = [
{ name: 'Jane', age: 90 },
{ name: 'Paul', age: 20 },
{ name: 'Jerry', age: 32 },
{ name: 'Mary', age: 75 },
];
my svg is like
<svg>
<g data-name='Jerry'><text>Jerry</text> <text>age</text> <text class='age'>0</text></g>
<g data-name='Paul'><text>Paul</text> <text>age</text> <text class='age'>0</text></g>
<g data-name='Mary'><text>Mary</text> <text>age</text> <text class='age'>0</text></g>
<g data-name='Jane'><text>Jane</text> <text>age</text> <text class='age'>0</text></g>
</svg>
As you can see above, data and svg is not sorted by name.
I want to keep this order `Jerry → Paul → Mary → Jane`. But every time I tried to join the data using d3, it joined with data's order (`jane → paul → jerry → mary`)
I have no clue how to join data in svg's order. :(
const svg = d3.select('svg');
svg.selectAll('.age').data(data).text(function(d){return d.age})
Is there any way to solve this? any clues?
or maybe this is not the correct or propery way using d3? :(
thanks.
</details>
# 答案1
**得分**: 1
你在绑定数据时需要使用一个关键函数。然而,在这里有两个复杂因素:
1. 由于你已经有要将数据绑定到的元素,你需要检查数据的唯一属性 **和** 元素的 `data` 属性,因为在函数第一次运行时,元素还没有绑定数据。
2. `data` 属性在父级元素中,而不在元素本身,因此你需要使用 `parentNode`:
```javascript
.data(data, function(d) {
return d ? d.name : this.parentNode.dataset.name
})
以下是带有关键函数的你的代码:
const data = [{
name: 'Jane',
age: 90
},
{
name: 'Paul',
age: 20
},
{
name: 'Jerry',
age: 32
},
{
name: 'Mary',
age: 75
},
];
const svg = d3.select('svg');
svg.selectAll('.age')
.data(data, function(d) {
return d ? d.name : this.parentNode.dataset.name
})
.text(function(d) {
return d.age
});
<svg>
<g transform='translate(30,20)' data-name='Jerry'><text>Jerry</text> <text x="50">age</text> <text class='age' x="80">0</text></g>
<g transform='translate(30,40)' data-name='Paul'><text>Paul</text> <text x="50">age</text> <text class='age' x="80">0</text></g>
<g transform='translate(30,60)' data-name='Mary'><text>Mary</text> <text x="50">age</text> <text class='age' x="80">0</text></g>
<g transform='translate(30,80)' data-name='Jane'><text>Jane</text> <text x="50">age</text> <text class='age' x="80">0</text></g>
</svg>
<script src="https://d3js.org/d3.v7.min.js"></script>
英文:
You need to use a key function when binding the data. However, you have two complicating factors here:
-
Since you already have elements to which you want to bind the data, you have to check for the unique property in the data and the element's
data
property, because the element has no bound data when the function first runs. -
The
data
property is in the parent, not in the element itself, therefore you need to useparentNode
:.data(data, function(d) { return d ? d.name : this.parentNode.dataset.name })
Here's your code with the key function:
<!-- begin snippet: js hide: true console: true babel: false -->
<!-- language: lang-js -->
const data = [{
name: 'Jane',
age: 90
},
{
name: 'Paul',
age: 20
},
{
name: 'Jerry',
age: 32
},
{
name: 'Mary',
age: 75
},
];
const svg = d3.select('svg');
svg.selectAll('.age')
.data(data, function(d) {
return d ? d.name : this.parentNode.dataset.name
})
.text(function(d) {
return d.age
})
<!-- language: lang-html -->
<svg>
<g transform='translate(30,20)' data-name='Jerry'><text>Jerry</text> <text x="50">age</text> <text class='age' x="80">0</text></g>
<g transform='translate(30,40)' data-name='Paul'><text>Paul</text> <text x="50">age</text> <text class='age' x="80">0</text></g>
<g transform='translate(30,60)' data-name='Mary'><text>Mary</text> <text x="50">age</text> <text class='age' x="80">0</text></g>
<g transform='translate(30,80)' data-name='Jane'><text>Jane</text> <text x="50">age</text> <text class='age' x="80">0</text></g>
</svg>
<script src="https://d3js.org/d3.v7.min.js"></script>
<!-- end snippet -->
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论