首页 > 解决方案 > d3js 从多维数组中获取数据

问题描述

我正在研究 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

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

这是一个说明问题的片段:

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>

标签: arraysd3.jsmultidimensional-arraypie-chart

解决方案


让我们看看你的 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>


推荐阅读