如何按特定顺序将数据连接到SVG文本。

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

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如下:

Jerry age 0 Paul age 0 Mary age 0 Jane age 0
```

正如你上面所看到的,数据和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&#39;s order (`jane → paul → jerry → mary`)

I have no clue how to join data in svg&#39;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:

  1. 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.

  2. The data property is in the parent, not in the element itself, therefore you need to use parentNode:

    .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: &#39;Jane&#39;,
    age: 90
  },
  {
    name: &#39;Paul&#39;,
    age: 20
  },
  {
    name: &#39;Jerry&#39;,
    age: 32
  },
  {
    name: &#39;Mary&#39;,
    age: 75
  },
];

const svg = d3.select(&#39;svg&#39;);
svg.selectAll(&#39;.age&#39;)
  .data(data, function(d) {
    return d ? d.name : this.parentNode.dataset.name
  })
  .text(function(d) {
    return d.age
  })

<!-- language: lang-html -->

&lt;svg&gt;
  &lt;g transform=&#39;translate(30,20)&#39; data-name=&#39;Jerry&#39;&gt;&lt;text&gt;Jerry&lt;/text&gt; &lt;text x=&quot;50&quot;&gt;age&lt;/text&gt; &lt;text class=&#39;age&#39; x=&quot;80&quot;&gt;0&lt;/text&gt;&lt;/g&gt;  
  &lt;g transform=&#39;translate(30,40)&#39; data-name=&#39;Paul&#39;&gt;&lt;text&gt;Paul&lt;/text&gt; &lt;text x=&quot;50&quot;&gt;age&lt;/text&gt; &lt;text class=&#39;age&#39; x=&quot;80&quot;&gt;0&lt;/text&gt;&lt;/g&gt;
  &lt;g transform=&#39;translate(30,60)&#39; data-name=&#39;Mary&#39;&gt;&lt;text&gt;Mary&lt;/text&gt; &lt;text x=&quot;50&quot;&gt;age&lt;/text&gt; &lt;text class=&#39;age&#39; x=&quot;80&quot;&gt;0&lt;/text&gt;&lt;/g&gt;
  &lt;g transform=&#39;translate(30,80)&#39; data-name=&#39;Jane&#39;&gt;&lt;text&gt;Jane&lt;/text&gt; &lt;text x=&quot;50&quot;&gt;age&lt;/text&gt; &lt;text class=&#39;age&#39; x=&quot;80&quot;&gt;0&lt;/text&gt;&lt;/g&gt;
&lt;/svg&gt;
&lt;script src=&quot;https://d3js.org/d3.v7.min.js&quot;&gt;&lt;/script&gt;

<!-- end snippet -->

huangapple
  • 本文由 发表于 2023年3月15日 18:33:01
  • 转载请务必保留本文链接:https://go.coder-hub.com/75743494.html
匿名

发表评论

匿名网友

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

确定