javascript - 使用 d3js 根据用户选择调用备用图表绘制函数

标签 javascript charts d3.js reusability

我正在尝试使用 d3js 实现可重用的图表,其中图表类型根据用户从下拉菜单中的选择进行更改。

我的代码:http://tributary.io/inlet/8085642

目标:当用户从下拉菜单中选择类型时,重新绘制新的图表类型来代替旧图表。

我已根据需要设置了所有内容:可以手动绘制每个图表,下拉菜单将 console.log 我要绘制的图表类型的名称(折线图、面积图、蜡烛图),但显然目标是以编程方式执行此操作。

编辑:从下面删除,与上面的原始问题无关。

最佳答案

正如 Lars 所说,问题不在于让可重用图表发挥作用。 (事实上​​,我不会真正将其称为“可重用图表”,即您向其传递参数的可自定义图表函数;您只是有多个不同的函数。)但无论如何:您的代码可以在不同的选项下正常工作您在其他函数调用中发表评论。所缺少的只是触发调用和一些清理工作的 Javascript。我在下面讨论了如何做到这一点,但也许将标题/问题更新为“根据用户选择调用备用图表绘制函数”或类似内容。

您需要三样东西:

  1. 附加到下拉菜单的事件监听器,以便在选择更改时触发代码,
  2. 删除或隐藏当前图表数据的方法,以及
  3. 读取所选值并调用相应绘制函数的函数。

您已经在此处获得了事件监听器:

 d3.select("#drop-down").on("change", function () { 
    selected = this.value;
    console.log(selected);
 });

它在控制台上返回值很好,但您需要实际调用适当的方法,如下所示:

 d3.select("#drop-down").on("change", function () { 
    selected = this.value;
    if(selected == "line"){chartDraw.line()}
    else if(selected == "area"){chartDraw.area()}
    else if(selected == "candle"){chartDraw.candle()}
 });

如果您有很多情况,您可能需要将其重写为 switch statement .

但是,这还不是您想要的——新图表只是绘制在旧图表之上。您需要的是一种重新选择每种图表类型所特有的元素的方法,以便您可以删除它们。为此,您需要向在 ChartDraw 方法中创建的所有元素添加一个类,例如 .attr("class""line alt-view") 或 "candle alt-"view”等,然后在事件处理函数中再添加一行:

 d3.select("#drop-down").on("change", function () { 
    selected = this.value;
    d3.selectAll(".alt-view").remove();
    if(selected == "line"){chartDraw.line()}
    else if(selected == "area"){chartDraw.area()}
    else if(selected == "candle"){chartDraw.candle()}
 });

这会为您的重新绘制创建一个干净的 Canvas (不会删除轴和其他常量元素)。

这应该可以让它工作,但您仍然可以提高它的效率,具体取决于您期望它的使用方式。如果您预计用户将在不同 View 之间来回切换(并且不希望数据同时发生变化),您可能只想隐藏替代 View 而不是删除,然后重新绘制它们。

隐藏很容易;只需将上面的 .remove() 替换为 .style("visibility", "hidden") 即可。但您还需要一种方法来测试您是否已经绘制了特定的图 TableView ,以便您可以仅使用 .style("visibility", "visible") 显示它,而不是重新绘制。我的建议?只需创建 bool 变量并在第一次绘制每个图表时设置它们,然后在图表绘制方法中检查它们:

var areaDrawn=false, lineDrawn=false, candleDrawn=false; 

(或将这些全部收集到一个对象中:viewDrawn = {area:false, line:false, 等...并相应地更改以下代码)

//inside the chartDraw object
   area: function (){
     if(areaDrawn){
        d3.selectAll(".area.alt-view").style("visibility", "visible");
     }
     else {  
      canvas.append("path")
        .datum(sample2)
        .attr("class", "area alt-view")
        .attr("d", area);

      areaDrawn=true;
     }
    }
//and similar for the other functions

最后一件事我无法弄清楚:当您从下拉菜单中选择某些内容时,菜单不会立即使用所选值重新绘制。该值会发生变化,如果我按一下标签并返回,则会显示正确的值,但不会立即显示。我不确定这是否是 Tributary 中发生的事情,或者与 Chrome 处理 SVG 中的foreignObjects 的方式有关。无论哪种方式,都需要测试,也许可以考虑在 SVG 之外为您的生产代码创建菜单(由容器 div 分组在一起)。

希望一切都有意义,我已经尝试一步一步地做到这一点,
--ABR

关于javascript - 使用 d3js 根据用户选择调用备用图表绘制函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20734716/

相关文章:

javascript - Axios FormData() 获取空对象

javascript - 如何比较上传文件的宽度和高度?

javascript - 如何在 Chart.js 上自定义边框样式

javascript - 具有多个 ID 的 d3 分类/样式

javascript - 使用 RequireJS Shim 的脚本依赖

javascript - 每 3 秒递增随机数并显示结果

javascript - 使用 AngularJS d3 处理 JSON 数据

javascript - 避免 d3 轴标签中的 dx/dy 属性

reporting-services - 将值放在图表条形内 (Reporting Services 2008)

c# - 如何定位excel图表x轴文本位置c#