【问题标题】:d3js get data from multidimensional arrayd3js 从多维数组中获取数据
【发布时间】:2018-07-08 20:54:38
【问题描述】:

我正在制作一个 d3js 圆环图,并尝试从多维数组中输入数据:fiddle

topHoldersArray 的输出:

{
"1":{"address":"0xd35a2d8c651f3eba4f0a044db961b5b0ccf68a2d","amount":"309953166.54621424","percent":"30.9953%"},
"2":{"address":"0xe17c20292b2f1b0ff887dc32a73c259fae25f03b","amount":"200000001","percent":"20.0000%"},
"3":{"address":"0x0000000000000000000000000000000000000000","amount":"129336426","percent":"12.9336%"}
}

使用这个数组我得到了错误:

Uncaught TypeError: Cannot read property 'startAngle' of undefined

如何将此数组输入图表?似乎问题在于它是一个多维数组,但我不确定如何访问它的数据点

这是一个说明问题的 sn-p:

var topHoldersArray = [
{
  "1":{"address":"0xd35a2d8c651f3eba4f0a044db961b5b0ccf68a2d","amount":"309953166","percent":"30.9953%"},
  "2":{"address":"0xe17c20292b2f1b0ff887dc32a73c259fae25f03b","amount":"200000001","percent":"20.0000%"},
  "3":{"address":"0x0000000000000000000000000000000000000000","amount":"129336426","percent":"12.9336%"}
}
];

var data = topHoldersArray;
		  
var text = "";

var width = 260;
var height = 260;
var thickness = 40;
var duration = 750;

var radius = Math.min(width, height) / 2;
var color = d3.scaleOrdinal(d3.schemeCategory20);

var svg = d3.select("#topHoldersChart")
.append('svg')
.attr('class', 'pie')
.attr('width', width)
.attr('height', height);

var g = svg.append('g')
.attr('transform', 'translate(' + (width/2) + ',' + (height/2) + ')');

var arc = d3.arc()
.innerRadius(radius - thickness)
.outerRadius(radius);

var pie = d3.pie()
.value(function(d) { return d.amount; })
.sort(null);

var path = g.selectAll('path')
.data(pie(data))
.enter()
.append("g")
.on("mouseover", function(d) {
      let g = d3.select(this)
        .style("cursor", "pointer")
        .style("fill", "black")
        .append("g")
        .attr("class", "text-group");
 
      g.append("text")
        .attr("class", "name-text")
        .text(`${d.data.address}`)
        .attr('text-anchor', 'middle')
        .attr('dy', '-1.2em');
  
      g.append("text")
        .attr("class", "value-text")
        .text(`${d.data.amount}`)
        .attr('text-anchor', 'middle')
        .attr('dy', '.6em');
    })
  .on("mouseout", function(d) {
      d3.select(this)
        .style("cursor", "none")  
        .style("fill", color(this._current))
        .select(".text-group").remove();
    })
  .append('path')
  .attr('d', arc)
  .attr('fill', (d,i) => color(i))
  .on("mouseover", function(d) {
      d3.select(this)     
        .style("cursor", "pointer")
        .style("fill", "black");
    })
  .on("mouseout", function(d) {
      d3.select(this)
        .style("cursor", "none")  
        .style("fill", color(this._current));
    })
  .each(function(d, i) { this._current = i; });


g.append('text')
  .attr('text-anchor', 'middle')
  .attr('dy', '.35em')
  .text(text);
.pie {
  margin: 20px;
}

.pie text {
  font-family: "Verdana";
  fill: #888;
}

.pie .name-text{
  font-size: 1em;
}

.pie .value-text{
  font-size: 3em;
}
<div class="token-chart">
  <h6>Top Holders</h6>
  <div class="chart" id="topHoldersChart"></div>
</div>
    

<script src="https://d3js.org/d3.v4.min.js"></script>

【问题讨论】:

    标签: arrays d3.js multidimensional-array pie-chart


    【解决方案1】:

    让我们看看你的 d3.pie 布局:

    var pie = d3.pie()
    .value(function(d) { return d.amount; })
    .sort(null);
    

    当我们向此 (pie(data)) 提供数据时,pie 需要一个数组。但是你提供了一个对象:

    {
    "1":{"address":"0xd35a2d8c651f3eba4f0a044db961b5b0ccf68a2d","amount":"309953166.54621424","percent":"30.9953%"},
    "2":{"address":"0xe17c20292b2f1b0ff887dc32a73c259fae25f03b","amount":"200000001","percent":"20.0000%"},
    "3":{"address":"0x0000000000000000000000000000000000000000","amount":"129336426","percent":"12.9336%"}
    }
    

    我们需要将其转换为数组以将其提供给d3.pie()。为此,我们可以使用d3.entries()(尽管也有其他方法可以实现)。

    d3.entries() 接受一个对象,比如:

    { a: value1, b: value2 }
    

    并将其转换为数组:

    [ { key: "a", value: value1 }, {key: "b", value: value2 } ]
    

    这些值现在位于名为value 的属性中。这需要我们在d.value.amount 查找金额。例如:

    var topHoldersArray = 
    {
      "1":{"address":"0xd35a2d8c651f3eba4f0a044db961b5b0ccf68a2d","amount":"309953166","percent":"30.9953%"},
      "2":{"address":"0xe17c20292b2f1b0ff887dc32a73c259fae25f03b","amount":"200000001","percent":"20.0000%"},
      "3":{"address":"0x0000000000000000000000000000000000000000","amount":"129336426","percent":"12.9336%"}
    };
    
    var data = d3.entries(topHoldersArray);
    
    var text = "";
    
    var width = 260;
    var height = 260;
    var thickness = 40;
    var duration = 750;
    
    var radius = Math.min(width, height) / 2;
    var color = d3.scaleOrdinal(d3.schemeCategory20);
    
    var svg = d3.select("#topHoldersChart")
    .append('svg')
    .attr('class', 'pie')
    .attr('width', width)
    .attr('height', height);
    
    var g = svg.append('g')
    .attr('transform', 'translate(' + (width/2) + ',' + (height/2) + ')');
    
    var arc = d3.arc()
    .innerRadius(radius - thickness)
    .outerRadius(radius);
    
    var pie = d3.pie()
    .value(function(d) { return d.value.amount; })
    .sort(null);
    
    var path = g.selectAll('path')
    .data(pie(data))
    .enter()
    .append("g")
    .on("mouseover", function(d) {
          let g = d3.select(this)
            .style("cursor", "pointer")
            .style("fill", "black")
            .append("g")
            .attr("class", "text-group");
     
          g.append("text")
            .attr("class", "name-text")
            .text(`${d.data.value.address}`)
            .attr('text-anchor', 'middle')
            .attr('dy', '-1.2em')
      
          g.append("text")
            .attr("class", "value-text")
            .text(`${d.data.value.amount}`)
            .attr('text-anchor', 'middle')
            .attr('dy', '.6em')
        })
      .on("mouseout", function(d) {
          d3.select(this)
            .style("cursor", "none")  
            .style("fill", color(this._current))
            .select(".text-group").remove();
        })
      .append('path')
      .attr('d', arc)
      .attr('fill', (d,i) => color(i))
      .on("mouseover", function(d) {
          d3.select(this)     
            .style("cursor", "pointer")
            .style("fill", "black");
        })
      .on("mouseout", function(d) {
          d3.select(this)
            .style("cursor", "none")  
            .style("fill", color(this._current));
        })
      .each(function(d, i) { this._current = i; });
    
    
    g.append('text')
      .attr('text-anchor', 'middle')
      .attr('dy', '.35em')
      .text(text);
    .pie {
      margin: 20px;
    }
    
    .pie text {
      font-family: "Verdana";
      fill: #888;
    }
    
    .pie .name-text{
      font-size: 1em;
    }
    
    .pie .value-text{
      font-size: 3em;
    }
    <div class="token-chart">
      <h6>Top Holders</h6>
      <div class="chart" id="topHoldersChart"></div>
    </div>
        
    
    <script src="https://d3js.org/d3.v4.min.js"></script>

    【讨论】:

    • 感谢您的回答。我试过了,但图表没有填充。我更新了 OP 以显示 topHoldersArray 的输出。和你预期的一样吗?
    • 我假设你有一个数组(如提供的小提琴),我会调整一个对象。
    • “如果你给 pie 函数提供一个子对象数组而不将它们放在父对象中”......我如何通过代码转换数组来做到这一点?再次感谢
    • @joeshmoe,我已经更新了 sn-p 以使用包含代表每个弧的子对象的输入对象。
    猜你喜欢
    • 2012-07-21
    • 2019-11-04
    • 2016-02-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-20
    相关资源
    最近更新 更多