Search code examples
javascriptamchartsamcharts4

amCharts: how to draw correct smoothed line with data gaps


When drawing a smoothed line with data gaps, I see this incorrect behaviour of the renderer. This only happens for the smoothed line, i.e. when setting series.tensionX = 0.77. If the tensionX is set to 1 the line is drawn correctly.

/**
 * ---------------------------------------
 * This demo was created using amCharts 4.
 * 
 * For more information visit:
 * https://www.amcharts.com/
 * 
 * Documentation is available at:
 * https://www.amcharts.com/docs/v4/
 * ---------------------------------------
 */

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

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

// Add data
chart.data = [{"date":"2020-02-28","value":2.7777777777777777},{"date":"2020-02-29","value":4.861111111111112},{"date":"2020-03-01","value":4.861111111111112},{"date":"2020-03-02","value":4.861111111111112},{"date":"2020-03-03","value":4.861111111111112},{"date":"2020-03-04","value":3.4722222222222223},{"date":"2020-03-05","value":3.4722222222222223},{"date":"2020-03-06","value":6.25},{"date":"2020-03-07","value":3.4722222222222223},{"date":"2020-03-08","value":null},{"date":"2020-03-09","value":null},{"date":"2020-03-10","value":null},{"date":"2020-03-11","value":null},{"date":"2020-03-12","value":null},{"date":"2020-03-13","value":null},{"date":"2020-03-14","value":null},{"date":"2020-03-15","value":null},{"date":"2020-03-16","value":null},{"date":"2020-03-17","value":null},{"date":"2020-03-18","value":null},{"date":"2020-03-19","value":null},{"date":"2020-03-20","value":null},{"date":"2020-03-21","value":null},{"date":"2020-03-22","value":null},{"date":"2020-03-23","value":null},{"date":"2020-03-24","value":null},{"date":"2020-03-25","value":null},{"date":"2020-03-26","value":null},{"date":"2020-03-27","value":null},{"date":"2020-03-28","value":null},{"date":"2020-03-29","value":null},{"date":"2020-03-30","value":null},{"date":"2020-03-31","value":null},{"date":"2020-04-01","value":null},{"date":"2020-04-02","value":null},{"date":"2020-04-03","value":null},{"date":"2020-04-04","value":null},{"date":"2020-04-05","value":null},{"date":"2020-04-06","value":null},{"date":"2020-04-07","value":null},{"date":"2020-04-08","value":null},{"date":"2020-04-09","value":null},{"date":"2020-04-10","value":null},{"date":"2020-04-11","value":null},{"date":"2020-04-12","value":null},{"date":"2020-04-13","value":null},{"date":"2020-04-14","value":null},{"date":"2020-04-15","value":null},{"date":"2020-04-16","value":null},{"date":"2020-04-17","value":null},{"date":"2020-04-18","value":null},{"date":"2020-04-19","value":null},{"date":"2020-04-20","value":2.7777777777777777},{"date":"2020-04-21","value":2.7777777777777777},{"date":"2020-04-22","value":2.7777777777777777}]

// Create axes
var categoryAxis = chart.xAxes.push(new am4charts.CategoryAxis());
categoryAxis.dataFields.category = "date";
categoryAxis.renderer.minGridDistance = 50;
categoryAxis.renderer.grid.template.location = 0.5;
categoryAxis.renderer.labels.template.rotation = -45;
categoryAxis.renderer.labels.template.horizontalCenter = "right";
categoryAxis.renderer.labels.template.verticalCenter = "middle";
categoryAxis.startLocation = 0.5;
categoryAxis.endLocation = 0.5;

// Create value axis
var valueAxis = chart.yAxes.push(new am4charts.ValueAxis());
valueAxis.baseValue = 0;

// Create series
var series = chart.series.push(new am4charts.LineSeries());
series.dataFields.valueY = "value";
series.dataFields.categoryX = "date";
series.strokeWidth = 2;
series.tensionX = 0.77;
series.connect = true;

// bullet is added because we add tooltip to a bullet for it to change color
var bullet = series.bullets.push(new am4charts.Bullet());
bullet.tooltipText = "{valueY}";

bullet.adapter.add("fill", function(fill, target){
    if(target.dataItem.valueY < 0){
        return am4core.color("#FF0000");
    }
    return fill;
})
var range = valueAxis.createSeriesRange(series);
range.value = 0;
range.endValue = -1000;
range.contents.stroke = am4core.color("#FF0000");
range.contents.fill = range.contents.stroke;


chart.cursor = new am4charts.XYCursor();
body {
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
}

#chartdiv {
  width: 100%;
  height: 500px;
}
<script src="https://cdn.amcharts.com/lib/4/core.js"></script>
<script src="https://cdn.amcharts.com/lib/4/charts.js"></script>
<script src="https://cdn.amcharts.com/lib/4/themes/animated.js"></script>
<div id="chartdiv"></div>

Screenshots
Smoothed: https://i.sstatic.net/xeb7p.png
Normal: https://i.sstatic.net/uN60h.png

How can I correct this wrong behaviour?


Solution

  • For anyone interested, the solution is to change the smoothing algorithm. https://www.amcharts.com/docs/v4/chart-types/xy-chart/#Alternate_smoothing_algorithm

    By setting series.smoothing = "monotoneX" the line will be drawn correctly. Credits goes to martynasma, who answered here: https://github.com/amcharts/amcharts4/issues/3219