Search code examples
javascriptamchartsamcharts4

What is the target parameter in amchart adapter


I am trying to create a variance chart using amchart4. And I am using the example from the demo.

https://www.amcharts.com/demos/variance-indicators/

What is the actually the target object in each of the below usages on the adapter?

Is it ValueAxis or the CategoryAxis or something else?

     // Create axes
    var categoryAxis = chart.xAxes.push(new am4charts.CategoryAxis());
    categoryAxis.dataFields.category = "year";
    categoryAxis.renderer.grid.template.location = 0;
    categoryAxis.renderer.minGridDistance = 30;
    
    var valueAxis = chart.yAxes.push(new am4charts.ValueAxis());
    valueAxis.min = 0;
    
    // Create series
    var series = chart.series.push(new am4charts.ColumnSeries());
    series.dataFields.valueY = "value";
    series.dataFields.categoryX = "year";
    
    // Add series for showing variance arrows
    var series2 = chart.series.push(new am4charts.ColumnSeries());
    series2.dataFields.valueY = "valueNext";
    series2.dataFields.openValueY = "value";
    series2.dataFields.categoryX = "year";
    series2.columns.template.width = 1;
    series2.fill = am4core.color("#555");
    series2.stroke = am4core.color("#555");
    
    // Add a triangle for arrow tip
    var arrow = series2.bullets.push(new am4core.Triangle);
    arrow.width = 10;
    arrow.height = 10;
    arrow.horizontalCenter = "middle";
    arrow.verticalCenter = "top";
    arrow.dy = -1;
    
    // Set up a rotation adapter which would rotate the triangle if its a negative change
    arrow.adapter.add("rotation", function(rotation, target) {
      return getVariancePercent(target.dataItem) < 0 ? 180 : rotation;
    });
    
    // Set up a rotation adapter which adjusts Y position
    arrow.adapter.add("dy", function(dy, target) {
      return getVariancePercent(target.dataItem) < 0 ? 1 : dy;
    });
// Add a label
var label = series2.bullets.push(new am4core.Label);
label.padding(10, 10, 10, 10);
label.text = "";
label.fill = am4core.color("#0c0");
label.strokeWidth = 0;
label.horizontalCenter = "middle";
label.verticalCenter = "bottom";
label.fontWeight = "bolder";

// Adapter for label text which calculates change in percent
label.adapter.add("textOutput", function(text, target) {
  var percent = getVariancePercent(target.dataItem);
  return percent ? percent + "%" : text;
});

// Adapter which shifts the label if it's below the variance column
label.adapter.add("verticalCenter", function(center, target) {
  return getVariancePercent(target.dataItem) < 0 ? "top" : center;
});

// Adapter which changes color of label to red
label.adapter.add("fill", function(fill, target) {
  return getVariancePercent(target.dataItem) < 0 ? am4core.color("#c00") : fill;
});

function getVariancePercent(dataItem) {
  if (dataItem) {
    var value = dataItem.valueY;
    var openValue = dataItem.openValueY;
    var change = value - openValue;
    return Math.round(change / openValue * 100);
  }
  return 0;
}

Solution

  • When you add an adapter on an object, the first parameter is the value you're modifying and the second parameter, target, is an instance of the object that the adapter was added to (if you add console.log(target.className) you can see the name of the object class instance). So, in the following snippet:

    // Set up a rotation adapter which would rotate the triangle if its a negative change
    arrow.adapter.add("rotation", function(rotation, target) {
      return getVariancePercent(target.dataItem) < 0 ? 180 : rotation;
    });
    
    // Set up a rotation adapter which adjusts Y position
    arrow.adapter.add("dy", function(dy, target) {
      return getVariancePercent(target.dataItem) < 0 ? 1 : dy;
    });
    

    You're adding adapters to all the triangle bullets in the series that modify the rotation and dy properties of each bullet. The first argument is the property the adapter is modifying (rotation and dy, respectively) and target is the individual bullet instance associated with the data point. Similarly:

    // Adapter for label text which calculates change in percent
    label.adapter.add("textOutput", function(text, target) {
      var percent = getVariancePercent(target.dataItem);
      return percent ? percent + "%" : text;
    });
    
    // Adapter which shifts the label if it's below the variance column
    label.adapter.add("verticalCenter", function(center, target) {
      return getVariancePercent(target.dataItem) < 0 ? "top" : center;
    });
    
    // Adapter which changes color of label to red
    label.adapter.add("fill", function(fill, target) {
      return getVariancePercent(target.dataItem) < 0 ? am4core.color("#c00") : fill;
    });
    

    The target in each of of these adapters is the label (bullet) instance associated with the data point in the series.