Search code examples
javascriptchartsamcharts

Amcharts 3D charts - category axis getting mixed with the value axis wrongly


I am using amcharts with 3D (i.e. depth3D=40), the chart comes up good but the category axis is getting overlapped/merged with the value axis

I am using something like this :

var chart = AmCharts.makeChart("chartdiv", {
  "type": "serial",
  "theme": "light",
  "startDuration": 1,   
  "valueAxes": [{
    "id": "v1",
    "title": "Cost (in USD)",
    "position": "left",
    "autoGridCount": false,
    "labelFunction": function(value) {
      return "$" + Math.round(value);
    }
  }, {
    "id": "v2",
    "title": "Effort ( hh:mm )",
    "gridAlpha": 0,
    "position": "right",
    "autoGridCount": false,
    "duration": "mm",
    "durationUnits": {
      "hh": "h ",
      "mm": "min"
     }
  }],

  ---------------------
  ---------------------

 "depth3D": 40,
 "angle": 10,    
  "chartCursor": {
    "pan": true,
    "cursorPosition": "mouse",
    "cursorAlpha": 0.1,
    "cursorColor": "#000000",
    "fullWidth": true,
    "valueLineAlpha": 0.2
  },
  "categoryField": "lob",
   "categoryAxis": {
        "gridPosition": "start",
        "axisAlpha":0.9,
        "axisThickness": 1,                     
        "axisColor": "black",        
        "gridAlpha":0,
        "labelRotation":25,
        "fontSize":10,
        "boldLabels":true

    },

Here is my fiddle

It's the value axis(in red color) getting merged/mixed with the category axis.

Any suggestions to avoid the axis merging/overlapping would be highly appreciated!


Solution

  • When you have 3D enabled using angle/depth3D, the chart perspective is shifted. The red line you're seeing is part of the value axis line that is extended into 3D space due to the new perspective, so it's by design; note that the other axis does this too if you set the angle in the opposite direction. As a result, there isn't a way to remove this using the config. As a hack, you can try editing the SVG directly through the drawn event by querying the axis line by class/id with addClassNames set to true and modifying the d attribute:

    function remove3DSegment() {
      var line = document.querySelector('.value-axis-v2 .amcharts-axis-line');
      var lineSVG = line.getAttribute('d');
      line.setAttribute('d', lineSVG.substr(0, lineSVG.lastIndexOf(' '))); //last part of the SVG path command contains the 3D segment on the bottom
    }
    
    var chart = AmCharts.makeChart("chartdiv", {
      "type": "serial",
      "theme": "light",
      "startDuration": 1,
      "addClassNames": true,
      // ...
      "listeners": [{
        "event": "drawn",
        "method": remove3DSegment
      }],
      // ...
    });
    

    If you want to generalize it, you can have the function look for the chart's id and value axis' id through the event.

    function remove3DSegment(e) {
      var divId = e.chart.div.id;
      var valueAxisId = e.chart.valueAxes[1].id; //assumes your second axis is the one that needs to be modified.
      var line = document.querySelector('#' + divId + ' .value-axis-' + valueAxisId + ' .amcharts-axis-line');
      var lineSVG = line.getAttribute('d');
      line.setAttribute('d', lineSVG.substr(0, lineSVG.lastIndexOf(' '))); //last part of the SVG path command contains the 3D segment on the bottom
    }
    

    Note that this is a hack and if the SVG path command for drawing the axis gets changed in a future v3 release, then this may likely break.

    function remove3DSegment() {
      var line = document.querySelector('.value-axis-v2 .amcharts-axis-line');
      var lineSVG = line.getAttribute('d');
      line.setAttribute('d', lineSVG.substr(0, lineSVG.lastIndexOf(' ')));
    }
    var chart = AmCharts.makeChart("chartdiv", {
      "type": "serial",
      "theme": "light",
      "startDuration": 1,
      "addClassNames": true,
      "valueAxes": [{
        "id": "v1",
        "title": "Cost (in USD)",
        "position": "left",
        "autoGridCount": false,
        "labelFunction": function(value) {
          return "$" + Math.round(value);
        }
      }, {
        "id": "v2",
        "title": "Effort ( hh:mm )",
        "gridAlpha": 0,
        "position": "right",
        "axisAlpha": 0.9,
        "axisThickness": 2,
        "axisColor": "red",
      }],
      "graphs": [{
        "id": "g4",
        "valueAxis": "v1",
        "lineColor": "#3B7610",
        "fillColors": "#3B7610",
        "fillAlphas": 1,
        "type": "column",
        "title": "Cost saving per year",
        "valueField": "costSaving",
        "clustered": false,
        "columnWidth": 0.3,
        "topRadius": 1,
        // "legendValueText": "$[[value]]M",
        "balloonText": "[[title]]<br /><b style='font-size: 90%'>$[[value]]M</b>"
      }, {
        "id": "g1",
        "valueAxis": "v2",
        "bullet": "round",
        "bulletBorderAlpha": 1,
        "bulletColor": "#FFFFFF",
        "bulletSize": 5,
        "hideBulletsCount": 50,
        "lineThickness": 2,
        "lineColor": "#20acd4",
        "type": "smoothedLine",
        "title": "Effort saving per year",
        "topRadius": 0.95,
        "useLineColorForBulletBorder": true,
        "valueField": "effortSaving",
        "balloonText": "[[title]]<br /><b style='font-size: 90%'>[[value]]</b>"
      }],
      "depth3D": 40,
      "angle": 10,
      "chartCursor": {
        "pan": true,
        "cursorPosition": "mouse",
        "cursorAlpha": 0.1,
        "cursorColor": "#000000",
        "fullWidth": true,
        "valueLineAlpha": 0.2
      },
      "categoryField": "lob",
      "categoryAxis": {
        "gridPosition": "start",
        "axisAlpha": 0.9,
        "axisThickness": 1,
        "axisColor": "black",
        "gridAlpha": 0,
        "labelRotation": 25,
        "fontSize": 10,
        "boldLabels": true
    
      },
      "legend": {
        "horizontalGap": 5,
        "maxColumns": 30,
        "useGraphSettings": true,
        "markerSize": 10,
        "leftMargin": 0,
        "valueText": ""
      },
      "balloon": {
        "borderThickness": 1,
        "shadowAlpha": 0
      },
      "export": {
        "enabled": true
      },
      "listeners": [{
        "event": "drawn",
        "method": remove3DSegment
      }],
      "dataProvider": [{
        "lob": "abca",
        "effortSaving": 64140,
        "costSaving": 3600
      }, {
        "lob": "dfasdf",
        "effortSaving": 326724,
        "costSaving": 1875
      }, {
        "lob": "dfgsdfgt",
        "effortSaving": 36864,
        "costSaving": 1500,
      }, {
        "lob": "gfsdg",
        "effortSaving": 101808,
        "costSaving": 3614,
      }, {
        "lob": "fgfgf",
        "effortSaving": 13200,
        "costSaving": 6215,
      }, {
        "lob": "jytujty",
        "effortSaving": 111312,
        "costSaving": 3123,
      }, {
        "lob": "erqwr",
        "effortSaving": 5040,
        "costSaving": 1235,
      }]
    });
    #chartdiv {
      width: 100%;
      height: 500px;
    }
    <script src="https://www.amcharts.com/lib/3/amcharts.js"></script>
    <script src="https://www.amcharts.com/lib/3/serial.js"></script>
    <script src="https://www.amcharts.com/lib/3/plugins/export/export.min.js"></script>
    <link rel="stylesheet" href="https://www.amcharts.com/lib/3/plugins/export/export.css" type="text/css" media="all" />
    <script src="https://www.amcharts.com/lib/3/pie.js"></script>
    <script src="https://www.amcharts.com/lib/3/themes/light.js"></script>
    <div id="chartdiv"></div>