Search code examples
javascriptjquerymorris.js

jQuery graph, chart custmization as per the inputs is not working


Hi recently i tried Morris Area Charts , and it is good one . But the thing its difficult to understand how the data is fetched there .

I have seen the document https://morrisjs.github.io/morris.js/lines.html , & i make sample graph here

 var data = [
          { y: '2014', a: 50, b: 90},
          { y: '2015', a: 65,  b: 75},
          { y: '2016', a: 50,  b: 50},
          { y: '2017', a: 75,  b: 60},
          { y: '2018', a: 80,  b: 65},
          { y: '2019', a: 90,  b: 70},
          { y: '2020', a: 100, b: 75},
          { y: '2021', a: 115, b: 75},
          { y: '2022', a: 120, b: 85},
          { y: '2023', a: 145, b: 85},
          { y: '2024', a: 160, b: 95}
        ],
        config = {
          data: data,
          xkey: 'y',
          ykeys: ['a', 'b'],
          labels: ['Total Income', 'Total Outcome'],
          fillOpacity: 0.6,
          hideHover: 'auto',
          behaveLikeLine: true,
          resize: true,
          pointFillColors:['#ffffff'],
          pointStrokeColors: ['black'],
          lineColors:['gray','red']
      };
    config.element = 'area-chart';
    Morris.Area(config);
  #area-chart{
      min-height: 250px;
    }
 <head>
    <meta charset=utf-8 />
    <title>Morris.js Area Chart</title>
    </head>
    <body>
      <h3 class="text-primary text-center">
        Morris js charts
      </h3>
      <div class"row">
        <div class="col-sm-12 text-center">
          <label class="label label-success">Area Chart</label>
          <div id="area-chart" ></div>
        </div>
        
    <link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/morris.js/0.5.1/morris.css">
    <script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>
    <script src="//cdnjs.cloudflare.com/ajax/libs/raphael/2.1.0/raphael-min.js"></script>
    <script src="//cdnjs.cloudflare.com/ajax/libs/morris.js/0.5.1/morris.min.js"></script> 
        
        
        
      </div>
    </body>

But i have different requirement now .

In Y axis i have to put year and in x axis and i have to show the following data in chart .

Initial  gain  total_gain  year
 100    10    110          1
 100    25    125          2
 200    20    220          1
 1200   180   1380         1
 1200   720   1920         3

But i don't know how i can i implement this in chart . If some one can understand how this work then please help


Solution

  • The function getData just transforms the original data into the right format so that there is no format-conflict with the current morris-chart-configuration (xkey, ykeys).

    Although the most interesting part are parseTime and xLabelFormat. By setting parseTime false you tell this lib that you want the data not to be transformed into Date-objects. So you have more control of how to print the data onto the x-axis. Furthermore you can use xLabelFormat to actually print the data as you wish. In this examples the corresponding callback-function remembers the last currentYear-Number so that this number can be incremented by the next number.

    function getData(sets) {
        var result = [];
        sets.forEach(function(set) {
            result.push({
                y: set.year.toString(),
                a: set.Initial,
                b: set.Initial + set.gain
            });
        });
        return result;
    }
    
    var data = getData([{
                Initial: 100,
                gain: 10,
                year: 1
            },
            {
                Initial: 100,
                gain: 25,
                year: 2
            },
            {
                Initial: 200,
                gain: 20,
                year: 1
            },
            {
                Initial: 1200,
                gain: 180,
                year: 1
            },
            {
                Initial: 1200,
                gain: 720,
                year: 3
            },
        ]),
        config = {
            data: data,
            xkey: 'y',
            parseTime: false,
            xLabelFormat: function(y) {
                this.currentYear = this.currentYear ? (+this.currentYear) + (+y.label) : y.label;
                return this.currentYear;
            },
            ykeys: ['a', 'b'],
            labels: ['Total Income', 'Total Outcome'],
            fillOpacity: 0.6,
            hideHover: 'auto',
            behaveLikeLine: true,
            resize: true,
            pointFillColors: ['#ffffff'],
            pointStrokeColors: ['black'],
            lineColors: ['gray', 'red']
        };
    config.element = 'area-chart';
    Morris.Area(config);
    #area-chart{
          min-height: 250px;
        }
    <head>
        <meta charset=utf-8 />
        <title>Morris.js Area Chart</title>
        </head>
        <body>
          <h3 class="text-primary text-center">
            Morris js charts
          </h3>
          <div class"row">
            <div class="col-sm-12 text-center">
              <label class="label label-success">Area Chart</label>
              <div id="area-chart" ></div>
            </div>
            
        <link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/morris.js/0.5.1/morris.css">
        <script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>
        <script src="//cdnjs.cloudflare.com/ajax/libs/raphael/2.1.0/raphael-min.js"></script>
        <script src="//cdnjs.cloudflare.com/ajax/libs/morris.js/0.5.1/morris.min.js"></script> 
            
            
            
          </div>
        </body>

    P.s. I actually have made a function (getData) to build the data in the right format so that it does not conflict with the chart-configuration. So when you want to change the chart-config you have to change getData as well.

    I have also provided a fiddle to show of how you can still zoom into this morris-chart by taking advantage of resize-events. In this example the chart will split up into two charts when you zoom in.