【问题标题】:Amchart 4: How to highlight bar/column on click of bar/column in bar plotsAmcharts 4:如何在单击条形图中的条形/列时突出显示条形/列
【发布时间】:2020-07-11 15:16:12
【问题描述】:

我试图在 Amchart 4 中单击栏/列时突出显示栏/列。使用下面的代码,我得到当前单击的栏/列的值,但使用column.isActive 属性,栏/列没有突出显示。

我找到了这个Amchart official Documentation 链接,但它是关于单击轴标签的。我正在尝试实现相同但单击条/列,而不是轴标签。

这是代码实现:

am4core.ready(function() {

// Themes begin
am4core.useTheme(am4themes_animated);
// Themes end

// Create chart instance
var chart = am4core.create("chartdiv", am4charts.XYChart);

// Add data
chart.data = [{
  "country": "USA",
  "visits": 2025
}, {
  "country": "China",
  "visits": 1882
}, {
  "country": "Japan",
  "visits": 1809
}, {
  "country": "Germany",
  "visits": 1322
}, {
  "country": "UK",
  "visits": 1122
}];

// Create axes

var categoryAxis = chart.xAxes.push(new am4charts.CategoryAxis());
categoryAxis.dataFields.category = "country";
categoryAxis.renderer.grid.template.location = 0;
categoryAxis.renderer.minGridDistance = 30;

categoryAxis.renderer.labels.template.adapter.add("dy", function(dy, target) {
  if (target.dataItem && target.dataItem.index & 2 == 2) {
    return dy + 25;
  }
  return dy;
});

var valueAxis = chart.yAxes.push(new am4charts.ValueAxis());

// Create series
var series = chart.series.push(new am4charts.ColumnSeries());
series.dataFields.valueY = "visits";
series.dataFields.categoryX = "country";
series.name = "Visits";
series.columns.template.tooltipText = "{categoryX}: [bold]{valueY}[/]";
series.columns.template.fillOpacity = .8;

var columnTemplate = series.columns.template;
columnTemplate.strokeWidth = 2;
columnTemplate.strokeOpacity = 1;

// Make a panning cursor
chart.cursor = new am4charts.XYCursor();
chart.cursor.behavior = "panXY";
chart.cursor.snapToSeries = series;

chart.events.on("hit", function(ev){
 chart.series.each(function(series) {
     if (series instanceof am4charts.ColumnSeries) {
       series.columns.each(function(column) {
         if (column.dataItem.categories.categoryX == series.tooltipDataItem.dataContext.country) {           
           console.log(column.dataItem.categories.categoryX, series.tooltipDataItem.dataContext.country);
           column.isActive = true;
         } else {
           column.isActive = false;
         }
       })
     }
   })
})
}); // end am4core.ready()

现在,我还找到了这个 stackoverflow 帖子链接,但它与 Amchart 版本 3 图书馆有关,我正在使用 Amchart 4。

请检查此jfiddle 实现。

【问题讨论】:

    标签: javascript bar-chart amcharts4


    【解决方案1】:

    对于每个定义,您不需要 hit 侦听器,仅当您想在激活单击的列时停用其他列。您只需创建列 togglable 并在 active 状态下定义实际属性。

    您必须使列可切换。

    series.columns.template.togglable = true;

    这会将活动状态从false 切换到truetogglable

    状态激活时的属性

    var tActiveState = series.columns.template.states.create("active");
    tActiveState.properties.strokeWidth = 0;
    tActiveState.properties.fill = "crimson";
    

    您必须设置活动状态的属性。 states

    在点击时停用其他列

    series.columns.template.events.on("hit", function(event){
      series.columns.each(function(column){
        if(column !== event.target){
          column.setState("default");
          column.isActive = false
        }
      })
    });
    

    为此,我们将再次使用hit 监听器。 Event Listeners

    基于您的代码的示例

    am4core.ready(function() {
      // Themes begin
      am4core.useTheme(am4themes_animated);
      // Themes end
    
      // Create chart instance
      var chart = am4core.create("chartdiv", am4charts.XYChart);
    
      // Add data
      chart.data = [{
        "country": "USA",
        "visits": 2025
      }, {
        "country": "China",
        "visits": 1882
      }, {
        "country": "Japan",
        "visits": 1809
      }, {
        "country": "Germany",
        "visits": 1322
      }, {
        "country": "UK",
        "visits": 1122
      }];
    
      // Create axes
    
      var categoryAxis = chart.xAxes.push(new am4charts.CategoryAxis());
      categoryAxis.dataFields.category = "country";
      categoryAxis.renderer.grid.template.location = 0;
      categoryAxis.renderer.minGridDistance = 30;
    
      categoryAxis.renderer.labels.template.adapter.add("dy", function(dy, target) {
        if (target.dataItem && target.dataItem.index & 2 == 2) {
          return dy + 25;
        }
        return dy;
      });
    
      var valueAxis = chart.yAxes.push(new am4charts.ValueAxis());
    
      // Create series
      var series = chart.series.push(new am4charts.ColumnSeries());
      series.dataFields.valueY = "visits";
      series.dataFields.categoryX = "country";
      series.name = "Visits";
      series.columns.template.tooltipText = "{categoryX}: [bold]{valueY}[/]";
      series.columns.template.fillOpacity = .8;
    
      //REM: Making the columns togglable.
      series.columns.template.togglable = true;
    
      //REM: Setting the properties of the "hover" state
      var tHoverState = series.columns.template.states.create("hover");
      tHoverState.properties.strokeWidth = 1;
      tHoverState.properties.fill = "yellow";
    
      //REM: Setting the properties of the active state "isActive=true"
      var tActiveState = series.columns.template.states.create("active");
      tActiveState.properties.strokeWidth = 0;
      tActiveState.properties.fill = "crimson";
    
      var columnTemplate = series.columns.template;
      columnTemplate.strokeWidth = 2;
      columnTemplate.strokeOpacity = 1;
    
      // Make a panning cursor
      chart.cursor = new am4charts.XYCursor();
      chart.cursor.behavior = "panXY";
      chart.cursor.snapToSeries = series;
    
      //REM: To deactivate other columns on click
      series.columns.template.events.on("hit", function(event){
        series.columns.each(function(column){
          if(column !== event.target){
            column.setState("default");
            column.isActive = false
          }
        })
      });
    
    }); // end am4core.ready()
    <script src="https://www.amcharts.com/lib/4/core.js"></script>
    <script src="https://www.amcharts.com/lib/4/charts.js"></script>
    <script src="https://www.amcharts.com/lib/4/themes/animated.js"></script>
    
    <div id = 'chartdiv'></div>

    或者,您可以跳过可切换并仅使用命中

    series.columns.template.events.on("hit", function(event){
      series.columns.each(function(column){
        //REM: Deactivate all non clicked columns
        if(column !== event.target){
          column.setState("default");
          column.isActive = false
        }
        //REM: Toggle the clicked column
        else{
          column.isActive = !column.isActive
        }
      })
    });
    

    【讨论】:

    • 多么美丽的答案。使用了我一天中的最后一次投票。
    • 伟人。谢谢您的帮助。我真的很感激。
    • 在接下来的 6 小时内,我会奖励你赏金。无论如何,如果您知道如何将两个 amchart 图表合并为一个,请告诉我。 stackoverflow.com/questions/61682646/…
    • 可悲的是我自己大多还是卡在V3上,如果我周末有时间我会看看它。
    【解决方案2】:

    我不确定 amchart 是否有 api,但因为它是基于 svg 的,我们可以轻松地为选定的列设置样式,如 this

    column.element.node.parentNode.setAttribute('fill', highLightColor);           
    column.element.node.parentNode.setAttribute('stroke', highLightStrokeColor);
    

    【讨论】:

      猜你喜欢
      • 2019-04-29
      • 2014-04-04
      • 2019-06-13
      • 2019-03-26
      • 1970-01-01
      • 2023-03-11
      • 1970-01-01
      • 2018-10-03
      • 1970-01-01
      相关资源
      最近更新 更多