Javascript 如何使用匿名函数正确调用D3.js中的其他函数

Javascript 如何使用匿名函数正确调用D3.js中的其他函数,javascript,d3.js,anonymous-function,Javascript,D3.js,Anonymous Function,我试图使用一个匿名函数来调用另外两个函数,但实际上无法让它工作。我一直在问这个问题,但仍然不能正确回答 理想的效果是,我的条形图可以同时更改条形图和颜色。这就是我正在尝试的: 我想调用的两个函数: function selectDataset(d) { let value = this.value; if (value == "total") { change(datasetTotal); } else if (value

我试图使用一个匿名函数来调用另外两个函数,但实际上无法让它工作。我一直在问这个问题,但仍然不能正确回答

理想的效果是,我的条形图可以同时更改条形图和颜色。这就是我正在尝试的:

我想调用的两个函数:

 function selectDataset(d) {
        let value = this.value;
        if (value == "total") {
            change(datasetTotal);
        } else if (value == "option1") {
            change(datasetOption1);
        } else if (value == "option2") {
            change(datasetOption2);
        }
    }

    function changeColor(d) {
         let value = this.value;
        if (value == "total") {
            d3.selectAll("rect")
                    .transition()
                    .duration(2000)
                    .style("fill", 'blue')
        } else if (value == "option1") {
            d3.selectAll("rect")
                    .transition()
                    .duration(2000)
                    .style("fill", 'red')
        } else if (value == "option2") {
           d3.selectAll("rect")
                    .transition()
                    .duration(2000)
                    .style("fill", 'yellow')
        }

    }

我的匿名功能:


    d3.selectAll("input").on("change", function(d) {
         selectDataset.call(this, d);
         changeColor.call(this, d);
        });


function change(dataset) {

        y.domain(dataset.map(function(d) {
            return d.label;
        }));
        x.domain([0, d3.max(dataset, function(d) {
            return d.value;
        })]);

        svg.select(".y.axis").remove();
        svg.select(".x.axis").remove();

        svg.append("g")
            .attr("class", "x axis")
            .attr("transform", "translate(0," + height + ")")
            .call(xAxis);

        svg.append("g")
            .attr("class", "y axis")
            .call(yAxis)
            .append("text")
            .attr("transform", "rotate(0)")
            .attr("x", 50)
            .attr("dx", ".1em")
            .style("text-anchor", "end")
            .text("Option %");

        var bar = svg.selectAll(".bar")
            .data(dataset, function(d) {
                return d.label;
            });

        var barExit = bar.exit().remove();

        var barEnter = bar.enter()
                        .append("g")
                        .attr("class", "bar");

        var barRects = barEnter.append("rect")
            .attr("x", function(d) {
            return x(0);
        })
        .attr("y", function(d) {
            return y(d.label);
        })
        .attr("width", function(d) {
            return x(d.value);
        })
        .attr("height", y.bandwidth());

        var barTexts = barEnter.append("text")
            .attr("x", function(d) {
                return x(d.value) + 10;
            })
            .attr("y", function(d) {
                return y(d.label) + y.bandwidth() / 2;
            })
            .attr("dy", ".35em")
            .text(function(d) {
                return d.value;
            });

        var barRectUpdate = bar.select("rect")
            .transition()
            .duration(3050)
            .attr("x", function(d) {
            return x(0);
        })
        .attr("y", function(d) {
            return y(d.label);
        })
        .attr("width", function(d) {
            return x(d.value);
        })
        .attr("height", y.bandwidth());

        var barTextsUpdate = bar.select("text")
              .transition()
              .duration(3050)
              .attr("x", function(d) {
              return x(d.value) + 10;
            })
            .attr("y", function(d) {
                return y(d.label) + y.bandwidth() / 2;
            })
            .attr("dy", ".35em")
            .text(function(d) {
                return d.value;
            });
    };
这里是我的变化函数:


    d3.selectAll("input").on("change", function(d) {
         selectDataset.call(this, d);
         changeColor.call(this, d);
        });


function change(dataset) {

        y.domain(dataset.map(function(d) {
            return d.label;
        }));
        x.domain([0, d3.max(dataset, function(d) {
            return d.value;
        })]);

        svg.select(".y.axis").remove();
        svg.select(".x.axis").remove();

        svg.append("g")
            .attr("class", "x axis")
            .attr("transform", "translate(0," + height + ")")
            .call(xAxis);

        svg.append("g")
            .attr("class", "y axis")
            .call(yAxis)
            .append("text")
            .attr("transform", "rotate(0)")
            .attr("x", 50)
            .attr("dx", ".1em")
            .style("text-anchor", "end")
            .text("Option %");

        var bar = svg.selectAll(".bar")
            .data(dataset, function(d) {
                return d.label;
            });

        var barExit = bar.exit().remove();

        var barEnter = bar.enter()
                        .append("g")
                        .attr("class", "bar");

        var barRects = barEnter.append("rect")
            .attr("x", function(d) {
            return x(0);
        })
        .attr("y", function(d) {
            return y(d.label);
        })
        .attr("width", function(d) {
            return x(d.value);
        })
        .attr("height", y.bandwidth());

        var barTexts = barEnter.append("text")
            .attr("x", function(d) {
                return x(d.value) + 10;
            })
            .attr("y", function(d) {
                return y(d.label) + y.bandwidth() / 2;
            })
            .attr("dy", ".35em")
            .text(function(d) {
                return d.value;
            });

        var barRectUpdate = bar.select("rect")
            .transition()
            .duration(3050)
            .attr("x", function(d) {
            return x(0);
        })
        .attr("y", function(d) {
            return y(d.label);
        })
        .attr("width", function(d) {
            return x(d.value);
        })
        .attr("height", y.bandwidth());

        var barTextsUpdate = bar.select("text")
              .transition()
              .duration(3050)
              .attr("x", function(d) {
              return x(d.value) + 10;
            })
            .attr("y", function(d) {
                return y(d.label) + y.bandwidth() / 2;
            })
            .attr("dy", ".35em")
            .text(function(d) {
                return d.value;
            });
    };
我的图表

   var margin = {
            top: (parseInt(d3.select('.area-heat-cool').style('height'), 10) / 20),
            right: (parseInt(d3.select('.area-heat-cool').style('width'), 10) / 20),
            bottom: (parseInt(d3.select('.area-heat-cool').style('height'), 10) / 20),
            left: (parseInt(d3.select('.area-heat-cool').style('width'), 10) / 5)
        },
        width = parseInt(d3.select('.area-heat-cool').style('width'), 10) - margin.left - margin.right,
        height = parseInt(d3.select('.area-heat-cool').style('height'), 10) - margin.top - margin.bottom;

    var div = d3.select(".area-heat-cool").append("div").attr("class", "toolTip");

    var y = d3.scaleBand()
        .rangeRound([height, 0], .2, 0.5)
        .paddingInner(0.1);

    var x = d3.scaleLinear()
        .range([0, width]);

    var xAxis = d3.axisBottom()
        .scale(x);

    var yAxis = d3.axisLeft()
        .scale(y);

    var svg = d3.select(".area-heat-cool").append("svg")
        .attr("width", width + margin.left + margin.right)
        .attr("height", height + margin.top + margin.bottom)
        .append("g")
        .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

    svg.append("g")
        .attr("class", "x axis")
        .attr("transform", "translate(0," + height + ")")
        .call(xAxis);

    d3.select("input[value=\"total\"]").property("checked", true);
    change(datasetTotal);
数据集示例:

data1 = [{label: "example 1", value: 156}
{label: "example 2", value: 189}
{label: "example 3", value: 234}
{label: "example 4", value: 345}
{label: "example 5", value: 346}
{label: "example 6", value: 456}
{label: "example 7", value: 489}
{label: "example 8", value: 567}]; 


data2 = [{label: "example 1", value: 23}
{label: "example 2", value: 211}
{label: "example 3", value: 45}
{label: "example 4", value: 64}
{label: "example 5", value: 95}
{label: "example 6", value: 32}
{label: "example 7", value: 0}
{label: "example 8", value: 234}]; 

还有我的单选按钮:

<div class="area-heat-cool">
<form>
    <label><input type="radio" name="dataset" id="dataset" value="total" checked> Total</label>
    <label><input type="radio" name="dataset" id="dataset" value="option1"> Option 1</label>
    <label><input type="radio" name="dataset" id="dataset" value="option2"> Option 2</label>
</form>
</div>


全部的
选择1
选择2
当我这样做的时候,不知何故会把我的数据弄乱。颜色会改变,但条不再移动到正确的位置。我没有得到任何错误抛出,但行为不是预期的


我是否正确使用此匿名函数?非常感谢您的帮助。提前多谢

当触发事件时,您将对
rect
元素应用两个转换。但是,执行此操作时,第二个转换将覆盖第一个转换

然后在
change
函数中应用第一个转换,您可以在其中更改
rect
元素的大小。当
change
函数返回时,您立即调用
changeColor
函数,该函数选择所有
rect
元素,并应用不同的转换来更改
rect
元素的颜色。因此,颜色转换将覆盖大小转换

要解决此问题,可以在一个位置将所有转换应用于相同的图元。在我的示例中,我将把changeColor函数中的代码放入
change
函数中

首先,更改
change
功能声明以启用包括收音机选择值:

function change(dataset, optionSelect) {
  // code not shown
}
然后,更新执行
rect
元素转换的
change
中的代码:

var barRectUpdate = bar.select("rect")
  .transition()
  .duration(3050)
  .attr("x", function(d) {
    return x(0);
  })
  .attr("y", function(d) {
    return y(d.label);
  })
  .attr("width", function(d) {
    return x(d.value);
  })
  .attr("height", y.bandwidth())
  .style('fill', function () {
    if (optionSelect === "total") {
      return 'blue'
    } else if (optionSelect === "option1") {
      return 'red'
    } else if (optionSelect === "option2") {
      return 'yellow'
    }
  });
在调用
change
时,更新
selectDataset
功能以包括收音机选择值:

function selectDataset(d) {
  let value = this.value;
  if (value === "total") {
    change(datasetTotal, value);
  } else if (value === "option1") {
    change(datasetOption1, value);
  } else if (value === "option2") {
    change(datasetOption2, value);
  }
}
删除对
changeColor
函数的调用:

d3.selectAll("input").on("change", function(d) {
  selectDataset.call(this, d);
});
最后,删除
changeColor
函数

需要考虑的其他几件事:

  • id
    属性应该是唯一的。现在,您所有的
    输入
    元素都具有相同的id
  • 考虑将
    选择数据集
    中的字符串值检查更改为
    =
    ,而不是
    =
    ,以避免在比较值时发生意外的类型转换:
  • 如果以后不使用这些变量,则不需要将所有D3操作存储在变量中。例如,
    bar.select(“rect”)
    var barRectUpdate=bar.select(“rect”)
    一样有效

希望这有帮助

那么,“改变”功能在哪里?我们只能看到“changeColor”,但数据集请参考“change”。如果您能在生成图表的地方发布其余代码,则最好使用一段代码。@MKougiouris在
selectDataset
方法中调用change函数,该方法在其own@Micromegas对但定义在哪里?向我们展示功能,以便我们可以查看“内部”a是的,抱歉,我更新了问题哦,我的。。。谢谢matthias,你真的很棒!就像它应该的那样工作。。。。还有一个小问题,就是两个条不会改变颜色。但我想这可能是我的css文件中的某个内容,我会检查它并在这里发表评论。但这两种转换现在都可以工作了,非常感谢。我还更改了比较运算符并删除了不使用的变量。非常感谢。