簡體   English   中英

D3.js遍歷對象數組

[英]D3.js looping through an array of objects

我正在嘗試根據標題制作一排高度和寬度相等的條形圖。 有一個100個對象的數組,每個對象包含一個稱為result ,它本身和其他20個對象的數組,因此最終結果必須是一行2000條,但是我只能得到20條:

錯誤的輸出

Codepen: https ://codepen.io/ekilja01/pen/RdJqGO

數據是一個對象數組,具有一個稱為result的對象數組,格式如下:

0:
page: 1
results: Array(20)
0: {vote_count: 17968, id: 19995, video: false, vote_average: 7.4, title: "Avatar", …}
...
length: 20

1: {page: 2, total_results: 406130, total_pages: 20307, results: Array(20)}
2: {page: 3, total_results: 406130, total_pages: 20307, results: Array(20)}

這是我的方法:

d3.json('data.json').then(data => {

  console.log(data);
  for (let i = 0; i < data.length; i++) {


    //x and y domain
    xScale.domain(data[i].results.map(d => d.title));
    yScale.domain(data[i].results.map(d => d.original_title));

    svg.selectAll('rect')
      .data(data[i].results)
      .enter()
      .append('rect')
      .style('fill', 'red')
      .attr('width', xScale.bandwidth())
      .attr('height', 70)
      .attr('x', function (d) {
        return xScale(d.title);
      })
      .attr('y', function (d) {
        return yScale.bandwidth() + 175;
      });

  }
}).catch(error => console.log(error));

精美的問題描述和CodePen-輕松幫助您!

我已經為您的CodePen鏈接做了一個稍微修改的版本

基本上,發生的事情是,對於for循環中的每個迭代,您都將選擇前x個(在您的情況下為20個)匹配的rect元素。 這意味着在第一次迭代之后,每次迭代都將使用當前迭代的20個數據條目替換與相同的20個rect元素的數據綁定。

我進行了兩種更改來解決此問題:

  1. svg.selectAll('rect')更改為svg.selectAll('.rect_${i}') ,這將選擇具有相應類( .rect_0.rect_1等)的所有元素。 這樣做可以防止覆蓋先前的rect元素。
  2. .attr('x')的回調函數中添加+ xScale.range()[1] * i 這會將每20個rect元素向右移動,以確保rect元素不會相互繪制。

但是,要點2確實可以繪制出非常寬的圖表。 如果您希望各行之間彼此相鄰,我使用rect元素的高度添加了功能(在注釋中)。

讓我知道這是否對您有幫助!

在循環中,僅在循環中第一次添加元素:數據數組中有20個項目,svg中沒有矩形,因此輸入了全部20個項目。 第二次在數據數組中有20個項目,在svg中有20個矩形,因此enter選擇為空,新數據僅綁定到20個現有矩形。

作為其他答案的替代方法,您的數據似乎不是分層的,但是您具有分層的結構。 如果您的數據結構與DOM結構相同,那么這將更加簡單。 讓我們對數據進行一些重組:

var combined = [];
for (let i = 0; i < data.length; i++) {
  combined.push(...data[i].results);
}

現在我們的數據是:

[
  {vote_count: 17968, id: 19995, video: false, vote_average: 7.4, title: "Avatar", …,}
  {...},
  {...},
  ...

並且所有要映射的對象都在一個數組中,該數組中的一項,一個要添加到圖表中的元素。 現在我們可以做一個簡單的輸入循環:

svg.selectAll('rect')
  .data(combined)
  .enter()
  .append('rect')
  .style('fill', 'red')
  .attr('width', xScale.bandwidth())
  .attr('height', 70)
  .attr('x', function (d) {
    return xScale(d.title);
  })
  .attr('y', function (d) {
    return yScale.bandwidth() + 175;
  });

通常,如果需要循環以在DOM中輸入元素,則無需使用慣用的d3。 通過避免for循環輸入元素,縮放也變得更加容易,因為在遍歷父數組時我們不會不斷更新它。 比例域和范圍只需設置一次。

這是更新的codepen

現在,2000個元素將生成非常小的矩形,可能小於一個像素寬,我不確定為什么要像這樣縮放條形的高度,但這是不同的問題。

暫無
暫無

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

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