castis
castis

Reputation: 8223

Amcharts, replace 0 with 1 in vertical valueAxis

Looking for a way to make the following chart top out at 1 instead of 0.

enter image description here

I can set minimum: 1 in the valueAxes config section but that forces 1 to be the lower limit of what it will display regardless of where the line appears.

I don't see anything like this in the amcharts docs so I don't actually think its possible but I'm frequently wrong so I'm hoping thats the case.

Upvotes: 0

Views: 956

Answers (1)

martynasma
martynasma

Reputation: 8595

There's no one-line solution to what you need.

Using minimum: 1 in combination with (or without) strictMinMax would force the scale to start at particular number, regardless of actual scope of the chart variables.

You can try a couple of more "involved" approaches.

Pre-calculate the minimum

Before the chart builds, cycle through the chart data and set minimum only if there are values close to it.

/**
 * Create the chart
 */
var chart = AmCharts.makeChart("chartdiv", {
  "type": "serial",
  "theme": "light",
  "path": "http://www.amcharts.com/lib/3/",
  "dataProvider": [{
    "year": "1950",
    "value": 9
  }, {
    "year": "1951",
    "value": 30
  }, {
    "year": "1952",
    "value": 35
  }, {
    "year": "1953",
    "value": 25
  }, {
    "year": "1954",
    "value": 70
  }, {
    "year": "1955",
    "value": 45
  }, {
    "year": "1956",
    "value": 55
  }],
  "valueAxes": [{
    "reversed": true,
    // these are the made up properties that are used by our custom code
    // set value axis minimum with "tentativeMinimum" if there are
    // values withing "minimumThreshold" to it
    "tentativeMinimum": 1,
    "minimumThreshold": 9
  }],
  "graphs": [{
    "id": "g1",
    "bullet": "round",
    "lineThickness": 2,
    "type": "smoothedLine",
    "valueField": "value"
  }],
  "categoryField": "year",
  "categoryAxis": {
    "labelsEnabled": false,
  }
});

/**
 * Add chart pre-processor
 */
AmCharts.addInitHandler( function( chart ) {
  
  // check if there are any value axes defined
  if ( typeof chart.valueAxes !== "object" || ! chart.valueAxes.length )
    return;
  
  // check if chart's value axis has "tentativeMinimum" set
  // For the sake of simplicity we're just gonna take the first 
  // value axis and first graph.
  // Normally we would want to check all value axes and their attached
  // graphs to check for their respective values.
  var axis = chart.valueAxes[0];
  if ( axis.tentativeMinimum === undefined || axis.minimumThreshold === undefined )
    return;
  
  // get first charts valueField to check agains
  var field = chart.graphs[0].valueField;
  
  // cycle through the data
  var min;
  for ( var x = 0; x < chart.dataProvider.length; x++ ) {
    if ( min === undefined || ( chart.dataProvider[x][field] < min ) )
      min = chart.dataProvider[x][field];
  }
  
  // check if min is within the threshold
  if ( min <= ( axis.tentativeMinimum + axis.minimumThreshold ) )
    axis.minimum = axis.tentativeMinimum;
  
}, [ "serial" ] );
#chartdiv {
  width: 400px;
  height: 300px;
}
<script src="http://www.amcharts.com/lib/3/amcharts.js"></script>
<script src="http://www.amcharts.com/lib/3/serial.js"></script>
<script src="http://www.amcharts.com/lib/3/themes/light.js"></script>
<div id="chartdiv"></div>

Swap out "0" label for "1"

Use value axis' labelFunction to simply replace zero with 1:

var chart = AmCharts.makeChart("chartdiv", {
  ...
  "valueAxes": [{
    "reversed": true,
    "labelFunction": function( label ) {
      return label === 0 ? 1 : label;
    }
  }],
  ...
});

Please note, that this will not influence actual value axis scale. However, the difference might not be noticeable.

Upvotes: 2

Related Questions