【问题标题】:javascript/amcharts - easy way to use legend to show/hide columns of 1 graph for Amchart Column Chartjavascript/amcharts - 使用图例显示/隐藏 Amchart 柱形图的 1 个图表的列的简单方法
【发布时间】:2017-10-12 03:41:44
【问题描述】:

我似乎找不到一种简单的方法来为 amcharts 的 单个 图表中的项目添加具有可切换功能的图例。我四处搜索,发现了一个带有可切换图表的柱形图(JSFiddle 1)。我找到了可切换项目图例,但它没有正确调整大小 (JSFiddle 2)。

这是我能找到的最接近从单个图表 (CodePen 1) 的多个项目添加图例的方法。它来自 amchart 网站本身,但没有可切换的功能。如何在此处添加允许调整列大小的可切换功能(即,2 个项目将显示为大于 10 列的列)?我最初尝试这个只是为了看看是否可以添加开关功能但它不起作用:

AmCharts.addInitHandler(function(chart) {
  //check if legend is enabled and custom generateFromData property
  //is set before running
  if (!chart.legend || !chart.legend.enabled || !chart.legend.generateFromData) {
    return;
  }

  var categoryField = chart.categoryField;
  var colorField = chart.graphs[0].lineColorField || chart.graphs[0].fillColorsField;
  var legendData =  chart.dataProvider.map(function(data) {
    var markerData = {
      "title": data[categoryField] + ": " + data[chart.graphs[0].valueField], 
      "color": data[colorField]
    };
    if (!markerData.color) {
      markerData.color = chart.graphs[0].lineColor;
    }
    return markerData;
  });

  chart.legend.data = legendData;

  // here is the code I add
  chart.legend.switchable=true;

}

【问题讨论】:

    标签: javascript amcharts


    【解决方案1】:

    更新 - AmCharts knowledge base demo 已更新,包括以下修改。

    为了彻底调整图表大小,您必须实际修改dataProvider 并从数组中删除元素并重新绘制图表。您可以使用图例的clickMarker 将数据项存储到事件dataItem 对象中,并根据需要通过隐藏标志检索它。结合以前解决方案中的小提琴,我想出了这个:

    /*
      Plugin to generate legend markers based on category
      and fillColor/lineColor field from the chart data by using 
      the legend's custom data array. Also allows for toggling markers
      and completely removing/adding columns from the chart
    
      The plugin assumes there is  only one graph object. 
    */
    AmCharts.addInitHandler(function(chart) { 
    
      //method to handle removing/adding columns when the marker is toggled
      function handleCustomMarkerToggle(legendEvent) {
          var dataProvider = legendEvent.chart.dataProvider;
          var itemIndex; //store the location of the removed item
    
          //Set a custom flag so that the dataUpdated event doesn't fire infinitely, in case you have
          //a dataUpdated event of your own
          legendEvent.chart.toggleLegend = true; 
          // The following toggles the markers on and off.
          // The only way to "hide" a column and reserved space on the axis is to remove it
          // completely from the dataProvider. You'll want to use the hidden flag as a means
          // to store/retrieve the object as needed and then sort it back to its original location
          // on the chart using the dataIdx property in the init handler
          if (undefined !== legendEvent.dataItem.hidden && legendEvent.dataItem.hidden) {
            legendEvent.dataItem.hidden = false;
            dataProvider.push(legendEvent.dataItem.storedObj);
            legendEvent.dataItem.storedObj = undefined;
            //re-sort the array by dataIdx so it comes back in the right order.
            dataProvider.sort(function(lhs, rhs) {
              return lhs.dataIdx - rhs.dataIdx;
            });
          } else {
            // toggle the marker off
            legendEvent.dataItem.hidden = true;
            //get the index of the data item from the data provider, using the 
            //dataIdx property.
            for (var i = 0; i < dataProvider.length; ++i) { 
              if (dataProvider[i].dataIdx === legendEvent.dataItem.dataIdx) {
                itemIndex = i;
                break;
              }
            }
            //store the object into the dataItem
            legendEvent.dataItem.storedObj = dataProvider[itemIndex];
            //remove it
            dataProvider.splice(itemIndex, 1);
          }
          legendEvent.chart.validateData(); //redraw the chart
      }
    
      //check if legend is enabled and custom generateFromData property
      //is set before running
      if (!chart.legend || !chart.legend.enabled || !chart.legend.generateFromData) {
        return;
      }
    
      var categoryField = chart.categoryField;
      var colorField = chart.graphs[0].lineColorField || chart.graphs[0].fillColorsField;
      var legendData =  chart.dataProvider.map(function(data, idx) {
        var markerData = {
          "title": data[categoryField] + ": " + data[chart.graphs[0].valueField], 
          "color": data[colorField],
          "dataIdx": idx
        };
        if (!markerData.color) {
          markerData.color = chart.graphs[0].lineColor;
        }
        data.dataIdx = idx;
        return markerData;
      });
    
      chart.legend.data = legendData;
    
      //make the markers toggleable
      chart.legend.switchable = true;
      chart.legend.addListener("clickMarker", handleCustomMarkerToggle);
    
    }, ["serial"]);
    

    Demo

    【讨论】:

    • 非常感谢!!我没有将您的解决方案放入我的实际代码中,但 codepen 上的演示看起来很完美!完全符合我的预期。
    • 感谢代码和演示链接。它真的节省了我很多时间。唯一的一点是,需要调整 UI 以便在我们使用 legend.itemContainers.template.togglable = true; 的普通列系列中看到动画。我在一个页面中有多个图表(它们的数量是动态的),并试图从动画点获得更一致的感觉。
    • @Mahesh legend.itemContainers.template.togglable = true; 适用于 AmCharts v4,这是 v3 的答案。如果您对 v4 有疑问,请提出单独的问题,而不是评论 v4 发布前几年写的答案。
    • @xorspark,抱歉,我不知道上述代码中的 AmCharts 版本。是的,我正在寻找第 4 版的解决方案。将为此创建一个新问题
    猜你喜欢
    • 1970-01-01
    • 2012-04-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多