首页 > 解决方案 > 如何在 D3 中引用动态对象?

问题描述

我正在尝试使用下拉菜单创建散点图,其中下拉菜单上的不同选择将更改点坐标以及轴的比例。我相信我已经接近创建具有值的对象数组来引用我的数据,具体取决于选择的选择,但我的引用不起作用。

xxScale 和 yyScale 对应于比例,xData 和 yData 指的是我数据中的列。在我更改下拉列表中的选择之前,代码确实有效,然后我收到Uncaught TypeError: selectedGroup.xxScale is not a function了我确定的其他错误。

我相信我的问题仅限于代码的第三个框(标题更新函数)的第 9-18 行,但我也包含了可能是相关代码的内容,以防这是一个错误的假设。

我想要发生的是从度量数组中选择的任何一个过滤到第 9-18 行的代码,例如,如果选择了“b”,那么 d[selectedGroup["yData"]] 将是 d.yDatab

我尝试了不同的包围、点放置等来尝试让它工作,但没有运气。

对象数组、按钮和比例:

  var a = {xxScale: "xScalea", yyScale: "yScalea", xData: "xDataa", yData: "yDataa"}
  var b = {xxScale: "xScaleb", yyScale: "yScaleb", xData: "xDatab", yData: "yDatab"}
  var c = {xxScale: "xScalec", yyScale: "yScalec", xData: "xDatac", yData: "yDatac"}
  // Button
  d3.select("#selectButton")
    .selectAll('myOptions')
    .data(Metric)
    .enter()
    .append('option')
    .text(function (d) { return d; }) // text showed in the menu
    .attr("value", function (d) { return d; })
  // Scales
  var xScale = d3.scaleLinear()
    .domain([0,1.2])
    .range([0,w])
  var xScaleTitle = d3.scaleLinear()
    .domain([0, 1])
    .range([0,w])
  var yScale = d3.scaleLinear()
    .domain([0,1.2 ])
    .range([h,0])
  var yScaleTitle = d3.scaleLinear()
    .domain([0,7])
    .range([h,0])
  var yScaleTitleRatio = d3.scaleLinear()
    .domain([0,9])
    .range([h,0])
  var rScale = d3.scaleSqrt()
    .domain([0.2,0.8])
    .range([0, 20])
  var rScaleMO = d3.scaleSqrt()
    .domain([.2,.8])
    .range([0, 30])

创建 SVG

// Circles
  var circles = svg.selectAll('circle')
      .data(data)
      .enter()
    .append('circle')
      .attr('cx',function (d) { return xScale(d.xDataa) })
      .attr('cy',function (d) { return yScale(d.yDataa) })
      .attr('r',20)
      .attr('stroke', function(d) { return d.Color1.slice(0,-1); })
      .attr('stroke-width',2)
      .style('fill', function(d) { return d.Color2.slice(0,-1); })

更新功能

// A function that updates the chart
    function update(selectedGroup) {

      // Create new data with the selection?

      // Give these new data to update circle
      circles
        .data(data)
        .transition()
        .duration(1000)
          .attr("cx", function(d) { return selectedGroup["xxScale"](d[selectedGroup["xData"]]) })
          .attr("cy", function(d) { return selectedGroup["yyScale"](d[selectedGroup["yData"]]) })

      // Change x-axis
      xAxis = d3.axisLeft()
        .scale(selectedGroup["xxScale"])

      // Change y-axis
      yAxis = d3.axisBottom()
        .scale(selectedGroup["yyScale"])
    }

    // When the button is changed, run the updateChart function
    d3.select("#selectButton").on("change", function(d) {
        // recover the option that has been chosen
        var selectedOption = d3.select(this).property("value")
        // run the updateChart function with this selected option
        update(selectedOption)
    })

标签: javascriptd3.js

解决方案


推荐阅读