Search code examples
javascriptc#amcharts

Stacked Bar Chart (AmCharts 4) with one series and repeating category


I'm currently creating a chart whose data is dynamically fetch from a database. Based on this data, I want to create a Horizontal Stacked Bar Chart that has only one series. Would that be possible in AmCharts? Or do I need a different approach?

Here's what I'd like as final result: enter image description here

Here's a sample of what I'm currently doing: Chart Sample

I'm also aware that using series.stacked = true; would make a column chart stacked but I think this needs to have multiple series which I want to avoid for now.


Solution

  • <html>
    
    <head></head>
    <style></style>
    
    <!-- Resources -->
    <script src="https://cdn.amcharts.com/lib/5/index.js"></script>
    <script src="https://cdn.amcharts.com/lib/5/xy.js"></script>
    <script src="https://cdn.amcharts.com/lib/5/themes/Animated.js"></script>
    
    
    <body>
      <div id="chartdiv" style="width: 600px;height: 200px;background:#c7cacb;margin: 0 auto;"></div>
      <script>
    
        am5.ready(function () {
    
          var root = am5.Root.new("chartdiv");
          root._logo.dispose();
    
          root.setThemes([
            am5themes_Animated.new(root)
          ]);
    
          var chart = root.container.children.push(am5xy.XYChart.new(root, {
            panX: false,
            panY: false,
            wheelX: false,
            wheelY: false,
            layout: root.verticalLayout
          }));
    
    
          var data = [{
            "year": "Payments",
            "europe": 50,
            "namerica": 0,
            "asia": 0,
          }, {
            "year": "Invoiced",
            "europe": 30,
            "namerica": 0,
            "asia": 0,
          }, {
            "year": "Other Adjustment Sum",
            "europe": 40,
            "namerica": 20,
            "asia": 39,
          }]
    
          var yAxis = chart.yAxes.push(am5xy.CategoryAxis.new(root, {
            categoryField: "year",
            renderer: am5xy.AxisRendererY.new(root, {}),
            tooltip: am5.Tooltip.new(root, {})
          }));
    
          yAxis.data.setAll(data);
    
          var xAxis = chart.xAxes.push(am5xy.ValueAxis.new(root, {
            min: 0,
            renderer: am5xy.AxisRendererX.new(root, {})
          }));
    
          xAxis = chart.xAxes.push(
            am5xy.ValueAxis.new(root, {
              min: 0,
              numberFormat: "''",
              renderer: am5xy.AxisRendererX.new(root, {
                strokeOpacity: 1,
                strokeWidth: 1,
                minGridDistance: 60
              }),
            })
          );
    
          let myRange = [
            {
              x: 20,
            },
            {
              x: 40,
            },
            {
              x: 60,
            },
            {
              x: 80,
            },
            {
              x: 100,
            },
          ];
    
          for (var i = 0; i < data.length + 2; i++) {
            let value = myRange[i].x;
    
            let rangeDataItem = xAxis.makeDataItem({
              value: value,
            });
    
            let range = xAxis.createAxisRange(rangeDataItem);
    
            rangeDataItem.get('label').setAll({
              forceHidden: false,
              text: value,
            });
          }
    
    
          var legend = chart.children.push(am5.Legend.new(root, {
            centerX: am5.p50,
            x: am5.p50
          }));
    
          function makeSeries(name, fieldName, color) {
            var series = chart.series.push(am5xy.ColumnSeries.new(root, {
              name: name,
              stacked: true,
              xAxis: xAxis,
              yAxis: yAxis,
              baseAxis: yAxis,
              fill: color,
              valueXField: fieldName,
              categoryYField: "year"
            }));
    
            series.columns.template.setAll({
              tooltipText: "{name}, {categoryY}: {valueX}",
              tooltipY: am5.percent(90)
            });
            series.data.setAll(data);
    
            series.appear();
    
          }
    
          makeSeries("Europe", "europe", "#83cdf4");
          makeSeries("North America", "namerica","#caa3ed");
          makeSeries("Asia", "asia","#eec48b");
    
          chart.appear(1000, 100);
        }); 
      </script>
    </body>
    
    </html>