在D3图例中绘制另外一个元素

时间:2017-09-04 15:03:43

标签: javascript d3.js

当我尝试在图表中使用D3绘制图例时,它会在图例中绘制另外一个元素。控制台告诉我这个错误信息:

  

poly1.js:83 Uncaught TypeError:无法读取未定义的属性“1”       在SVGGElement。 (poly1.js:83)       在pt.each(d3.v4.min.js:2)       在mycanvas(poly1.js:77)       在main(poly1.js:96)

这是javascript代码:

var x = d3.range(-2., 2.1, 0.1)

myfunction = x => Math.pow(x, 3) - 1

var y = new Array()
for (var i = 0 ; i < x.length ; i++) {
    y[i] = myfunction(x[i])
}
var dataset = []
for (var j = 0; j < x.length; j++) {
    dataset[j] = []
    dataset[j][0] = x[j]
    dataset[j][1] = y[j]
}

var w = 500
var h = 500
var padding = 50

var xScale = d3.scaleLinear()
            .domain([d3.min(x, function(d) { return d }), d3.max(x, function(d) { return d })])
            .range([padding, w - padding])

var yScale = d3.scaleLinear()
             .domain([-10, 8])
             .range([h - padding, padding])

var color_hash = {0 : ["f(x)", "blue"]}
/*var color_hash = {  0 : ["f(x)", "blue"],
                        1 : ["mango", "orange"],
                        2 : ["cherry", "red"]
                      }*/

function mycanvas() {
    var svg = d3.select('.myfunction')
            .append('svg')
            .attr('width', w)
            .attr('height', h)
    svg.append('rect')
        .attr('width', '100%')
        .attr('height', '100%')
        .style('fill', '#ffcc99')

    // Define the axis
    var xAxis = d3.axisBottom().scale(xScale).ticks(9)
    var yAxis = d3.axisLeft().scale(yScale).ticks(9)

    // Create the axis
    svg.append('g')
        .attr('class', 'axis')
        .attr('transform', 'translate(0,' + (h - padding) + ')')
        .call(xAxis)
    svg.append('g')
        .attr('class', 'axis')
        .attr('transform', 'translate(' + padding + ', 0)')
        .call(yAxis)

    // Define and plotting the function
    var line = d3.line()
        .x(function(d) { return xScale(d[0])})
        .y(function(d) { return yScale(d[1])})

    svg.append('path')
    .attr('d', line(dataset))
    .attr('stroke', 'blue')
    .attr('fill', 'none')

    //--------- THE LEGEND ------
    var legend = svg.append("g")
      .attr("class", "legend")
      .attr("x", w)
      .attr("y", 25)
      .attr("height", 100)
      .attr("width", 100)
    legend.selectAll('g').data(dataset)
      .enter()
      .append('g')
      .each(function(d, i) {
        d3.select(this).append("rect")
          .attr("x", w - 400)
          .attr("y", i * 25 + 20)
          .attr("width", 10)
          .attr("height", 10)
          .style("fill", color_hash[dataset.indexOf(d)][1])

         d3.select(this).append("text")
          .attr("x", w - 385)
          .attr("y", i * 25 + 30)
          .attr("height",30)
          .attr("width",100)
          .style("fill", color_hash[String(i)][1])
          .text(color_hash[String(i)][0])
    })
}

function main() {
    mycanvas()
}

window.onload = main

我正在使用带有D3的v4

1 个答案:

答案 0 :(得分:0)

拆包有点难,但问题在于:

color_hash[dataset.indexOf(d)][1]

在第一次迭代中,indexOf(d)0color_hash[0]已定义,因此没有问题。在第二次迭代中,indexOf(d)1。由于color_hash定义为:

var color_hash = {0 : ["f(x)", "blue"]}

color_hash[1]未定义,因此color_hash[1][1]是错误的。

看起来您定义了更大的颜色哈希并注释了更多值。如果您取消注释,则在indexOf(d)3时出现错误,您将获得另外两个图例项。看起来您的数据中有40个项目,这意味着您需要一个包含40种颜色的哈希才能使此方案正常工作。所以我怀疑,这不是你想要做的。如果您告诉我们您期望发生的事情,可能会有人提供更多建议。