繁体   English   中英

如何使用下拉菜单在 d3 中创建多折线图?

[英]How do I create a multi-line chart in d3 with a dropdown menu?

我发布了一个以前的问题,可能过于具体。 我正在尝试在 d3 中创建一个带有下拉列表的多折线图,类似于this

我已经取消了 v7 所需的明显更改,但仍然遇到麻烦,我相信在var initialGraph之后的 if/else 语句,但我不是 100% 确定。 也可能是因为我的 d3.groups 没有正确设置/引用。

我收到的当前错误是:

Uncaught (in promise) TypeError: Cannot read property 'year' of undefined
    at <anonymous>:23:33
    at a (d3.v7.min.js:2)
    at initialGraph (<anonymous>:83:18)
    at <anonymous>:89:3

我的数据集有四个值:year、state、wvalues 和 lvalues。 state 和 lvalues 是字符串,year 和 wvalues 是数字。 到目前为止,这是我的代码:

  var margin = { top: 50, right: 50, bottom: 50, left: 50 }
  var h = 500 - margin.top - margin.bottom
  var w = 700 - margin.left - margin.right
  var formatDecimal = d3.format('.2')

d3.csv('15/data.csv').then(function (data) {

// Scales
var x = d3.scaleLinear()
  .range([0,w])
var y = d3.scaleLinear()
  .range([h,0])

  y.domain([
    d3.min([0,d3.min(data,function (d) { return d.wvalue })]),
    d3.max([0,d3.max(data,function (d) { return d.wvalue })])
    ]);
  x.domain([1968, 2016])
  
// Define the line
var valueLine = d3.line()
    .x(function(d) { return x(d.year); })
    .y(function(d) { return y(d.wvalue); })

// Create the svg canvas in the "d3block" div
var svg = d3.select("#d3block")
        .append("svg")
        .style("width", w + margin.left + margin.right + "px")
        .style("height", h + margin.top + margin.bottom + "px")
        .attr("width", w + margin.left + margin.right)
        .attr("height", h + margin.top + margin.bottom)
        .append("g")
        .attr("transform","translate(" + margin.left + "," + margin.top + ")")
        .attr("class", "svg");

//nest variable
var nest = d3.groups(data, 
  d => d.state, d => d.lvalue)

  // X-axis
  var xAxis = d3.axisBottom()
    .scale(x)
    .tickFormat(formatDecimal)
    .ticks(7)
  // Y-axis
  var yAxis = d3.axisLeft()
    .scale(y)
    .tickFormat(formatDecimal)
    .ticks(5)
    // Create a dropdown
    var legisMenu = d3.select("#legisDropdown")

    legisMenu
    .append("select")
    .selectAll("option")
        .data(nest)
        .enter()
        .append("option")
        .attr("value", ([key, ]) => key)
        .text(([key, ]) => key)

  // Function to create the initial graph
  var initialGraph = function(legis){

    // Filter the data to include only state of interest
    var selectLegis = nest.filter(([key, ]) => key == legis)

      var selectLegisGroups = svg.selectAll(".legisGroups")
        .data(selectLegis, function(d){
          return d ? d.key : this.key;
        })
        .enter()
        .append("g")
        .attr("class", "legisGroups")

    var initialPath = selectLegisGroups.selectAll(".line")
      .data(([, values]) => values)
      .enter()
      .append("path")

    initialPath
      .attr("d", valueLine(([, values]) => values))
      .attr("class", "line")

  }

  // Create initial graph
  initialGraph("Alabama")


  // Update the data
  var updateGraph = function(legis){

    // Filter the data to include only state of interest
    var selectLegis = nest.filter(([key, ]) => key == legis)

    // Select all of the grouped elements and update the data
      var selectLegisGroups = svg.selectAll(".legisGroups")
        .data(selectLegis)

        // Select all the lines and transition to new positions
            selectLegisGroups.selectAll("path.line")
               .data(([, values]) => values)
                .transition()
                  .duration(1000)
                  .attr("d", valueLine(([, values ]) => values))
  }

  // Run update function when dropdown selection changes
  legisMenu.on('change', function(){

    // Find which state was selected from the dropdown
    var selectedLegis = d3.select(this)
            .select("select")
            .property("value")

        // Run update function with the selected state
        updateGraph(selectedLegis)

    });
      
  // X-axis
  svg.append('g')
      .attr('class','axis')
      .attr('id','xAxis')
      .attr('transform', 'translate(0,' + h + ')')
      .call(xAxis)
    .append('text') // X-axis Label
      .attr('id','xAxisLabel')
      .attr('fill','black')
      .attr('y',-10)
      .attr('x',w)
      .attr('dy','.71em')
      .style('text-anchor','end')
      .text('')
  // Y-axis
  svg.append('g')
      .attr('class','axis')
      .attr('id','yAxis')
      .call(yAxis)
    .append('text') // y-axis Label
      .attr('id', 'yAxisLabel')
      .attr('fill', 'black')
      .attr('transform','rotate(-90)')
      .attr('x',0)
      .attr('y',5)
      .attr('dy','.71em')
      .style('text-anchor','end')
      .text('wvalue')
})

我做了更多的挖掘并在这里找到了答案。

我不得不用.attr('d', (d) => valueLine(Array.from(d.values())[1]))替换初始路径属性.attr("d", valueLine(([, values]) => values)) .attr('d', (d) => valueLine(Array.from(d.values())[1])) 我还必须在selectLegisGroups .attr下的updateGraph函数中进一步替换代码,以便正确更新。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM