0
votes

I'm trying to update the value of dataset in Stock Chart of AmCharts. Problem, I'm facing is when i enter a year then it shows the year in the legend but it is not appearing in the graph, even after validating the data. This graph is for representing the data for different-different years for the same item. You can see the code here>

var chart;
/**
 * Function that generates yearly data
 * Takes year as a parameter
 */
function generateChartData(year) {
  var data = [];
  var firstDate = new Date(year, 0, 1);
  firstDate.setHours(0, 0, 0, 0);

  for (var i = 0; i < 365; i++) {
    var newDate = new Date(firstDate);
    newDate.setDate(newDate.getDate() + i);
    data.push({
      date: newDate,
      value: Math.round(Math.random() * (40 + i)) + 100 + i
    });
  }
  return data;
}

/**
  Prepare random data for our trhee data sets: 2015, 2014 and 2013
 */
var chartData2015 = generateChartData(2015);
var chartData2014 = generateChartData(2014);
var chartData2013 = generateChartData(2013);

/**
 * Now, let's implement a "plugin" which, when chart loads
 * would check all it's data sets and look for "baseYear" properietary
 * setting, which would indicate to which year should all dates be
 * reset
 * ---
 * NOTE: the plugin assumes there are Date objects as categories.
 * If dates as specified as timestamps or strings, plugin code will
 * need to be updated.
 */

AmCharts.addInitHandler(function(chart) {
  for(var x = 0; x < chart.dataSets.length; x++) {
    var ds = chart.dataSets[x];
    if (ds.baseYear !== undefined) {
      for(var i = 0; i < ds.dataProvider.length; i++) {
        var dp = ds.dataProvider[i];
        dp[ds.categoryField].setFullYear(ds.baseYear);
      }
    }
  }
}, ["stock"]);
/**
 * Build the chart
 */
chart = AmCharts.makeChart("chartdiv", {
  "type": "stock",
  "theme": "light",
  "dataSets": [{
      "title": "2015",
      "fieldMappings": [{
        "fromField": "value",
        "toField": "value"
      }],
      "dataProvider": chartData2015,
      "categoryField": "date"
    }, {
      "title": "2014",
      "fieldMappings": [{
        "fromField": "value",
        "toField": "value"
      }],
      "dataProvider": chartData2014,
      "categoryField": "date",
      "compared": true,
      "baseYear": 2015
    }, {
      "title": "2013",
      "fieldMappings": [{
        "fromField": "value",
        "toField": "value"
      }],
      "dataProvider": chartData2013,
      "categoryField": "date",
      "compared": true,
      "baseYear": 2015
    }],

  "panels": [{
    "title": "Value",
    "categoryAxis": {},
    "stockGraphs": [{
      "id": "g1",
      "valueField": "value",
      "lineThickness": 2,
      "comparable": true,
      "compareField": "value",
      "balloonText": "[[title]]:<b>[[value]]</b>",
      "compareGraphBalloonText": "[[title]]:<b>[[value]]</b>",
      "compareGraph": {
        "dashLength": 5,
        "lineThickness": 2
      }
    }],

    "stockLegend": {
      "periodValueTextComparing": "[[percents.value.close]]%",
      "periodValueTextRegular": "[[value.close]]"
    }
  }],
  
  "panelsSettings": {
    "recalculateToPercents": "never"
  },

  "chartScrollbarSettings": {
    "graph": "g1"
  },

  "chartCursorSettings": {
    "valueBalloonsEnabled": true,
    "fullWidth": true,
    "cursorAlpha": 0.1,
    "valueLineBalloonEnabled": true,
    "valueLineEnabled": true,
    "valueLineAlpha": 0.5
  },
  "periodSelector": {
    "position": "bottom",
    "periods": [{
      "period": "MM",
      "selected": true,
      "count": 1,
      "label": "1 month"
    }, {
      "period": "YYYY",
      "count": 1,
      "label": "1 year"
    }, {
      "period": "YTD",
      "label": "YTD"
    }, {
      "period": "MAX",
      "label": "MAX"
    }]
  }

});
$('document').ready(function(){
  $('#submit').on('click',function(){
    //alert(document.getElementById('year').value);
    add(document.getElementById('year').value);
 //   make();
  });
});

function add(yr){
  chart.dataSets.push( {
      "title": yr,
      "fieldMappings": [{
        "fromField": "value",
        "toField": "value"
      }],
      "dataProvider": generateChartData(yr),
      "categoryField": "date",
      "compared": true,
      "baseYear": 2015
    } );
  chart.validateNow();
  chart.validateData();
}
#chartdiv {
	width	: 100%;
	height	: 500px;
  font-family: Verdana;
  font-size: 12px;
}							
<script type="text/javascript" src="https://code.jquery.com/jquery-1.11.2.min.js"></script>
<script type="text/javascript" src="https://www.amcharts.com/lib/3/amcharts.js"></script>
<script type="text/javascript" src="https://www.amcharts.com/lib/3/serial.js"></script>
<script type="text/javascript" src="https://www.amcharts.com/lib/3/themes/light.js"></script>
<script type="text/javascript" src="https://www.amcharts.com/lib/3/amstock.js"></script>
<input type="text" id="year"><input type="submit" id="submit">
<div id="chartdiv"></div>							

https://codepen.io/rbrohitbisht/pen/yMWmPz?editors=0010

-If i enter year, say 2000 and submit it then it shows in legend without values. -If i enter BaseYear then it shows values.

I'm not able to get the new dataset in the stock amchart, where I'm trying to show the same item values for different years.

1

1 Answers

0
votes

The base year plugin you set in the addInitHandler only runs once upon chart initialization (the init event). validateData and validateNow don't re-trigger that event, so you'll have to re-run that base year plugin code manually.

One way to do this is by creating the function as part of the AmCharts namespace so that it can be also invoked outside of the init context:

AmCharts.addInitHandler(function(chart) {
  AmCharts.baseYearInitialize = function(chart) {
    for (var x = 0; x < chart.dataSets.length; x++) {
      var ds = chart.dataSets[x];
      if (ds.baseYear !== undefined) {
        for (var i = 0; i < ds.dataProvider.length; i++) {
          var dp = ds.dataProvider[i];
          dp[ds.categoryField].setFullYear(ds.baseYear);
        }
      }
    }
  }
  AmCharts.baseYearInitialize(chart);
}, ["stock"]);

This allows you to call it in your add method:

function add(yr) {
  chart.dataSets.push({
    "title": yr,
    "fieldMappings": [{
      "fromField": "value",
      "toField": "value"
    }],
    "dataProvider": generateChartData(yr),
    "categoryField": "date",
    "compared": true,
    "baseYear": 2015
  });
  AmCharts.baseYearInitialize(chart);
  // chart.validateNow();
  chart.validateData();
}

Note you don't need to call both validateNow and validateData - just validateData is sufficient in this case.

Demo below:

var chart;
/**
 * Function that generates yearly data
 * Takes year as a parameter
 */
function generateChartData(year) {
  var data = [];
  var firstDate = new Date(year, 0, 1);
  firstDate.setHours(0, 0, 0, 0);

  for (var i = 0; i < 365; i++) {
    var newDate = new Date(firstDate);
    newDate.setDate(newDate.getDate() + i);
    data.push({
      date: newDate,
      value: Math.round(Math.random() * (40 + i)) + 100 + i
    });
  }
  return data;
}

/**
  Prepare random data for our trhee data sets: 2015, 2014 and 2013
 */
var chartData2015 = generateChartData(2015);
var chartData2014 = generateChartData(2014);
var chartData2013 = generateChartData(2013);

/**
 * Now, let's implement a "plugin" which, when chart loads
 * would check all it's data sets and look for "baseYear" properietary
 * setting, which would indicate to which year should all dates be
 * reset
 * ---
 * NOTE: the plugin assumes there are Date objects as categories.
 * If dates as specified as timestamps or strings, plugin code will
 * need to be updated.
 */

AmCharts.addInitHandler(function(chart) {
  AmCharts.baseYearInitialize = function(chart) {
    for (var x = 0; x < chart.dataSets.length; x++) {
      var ds = chart.dataSets[x];
      if (ds.baseYear !== undefined) {
        for (var i = 0; i < ds.dataProvider.length; i++) {
          var dp = ds.dataProvider[i];
          dp[ds.categoryField].setFullYear(ds.baseYear);
        }
      }
    }
  }
  AmCharts.baseYearInitialize(chart);
}, ["stock"]);
/**
 * Build the chart
 */
chart = AmCharts.makeChart("chartdiv", {
  "type": "stock",
  "theme": "light",
  "dataSets": [{
    "title": "2015",
    "fieldMappings": [{
      "fromField": "value",
      "toField": "value"
    }],
    "dataProvider": chartData2015,
    "categoryField": "date"
  }, {
    "title": "2014",
    "fieldMappings": [{
      "fromField": "value",
      "toField": "value"
    }],
    "dataProvider": chartData2014,
    "categoryField": "date",
    "compared": true,
    "baseYear": 2015
  }, {
    "title": "2013",
    "fieldMappings": [{
      "fromField": "value",
      "toField": "value"
    }],
    "dataProvider": chartData2013,
    "categoryField": "date",
    "compared": true,
    "baseYear": 2015
  }],

  "panels": [{
    "title": "Value",
    "categoryAxis": {},
    "stockGraphs": [{
      "id": "g1",
      "valueField": "value",
      "lineThickness": 2,
      "comparable": true,
      "compareField": "value",
      "balloonText": "[[title]]:<b>[[value]]</b>",
      "compareGraphBalloonText": "[[title]]:<b>[[value]]</b>",
      "compareGraph": {
        "dashLength": 5,
        "lineThickness": 2
      }
    }],

    "stockLegend": {
      "periodValueTextComparing": "[[percents.value.close]]%",
      "periodValueTextRegular": "[[value.close]]"
    }
  }],

  "panelsSettings": {
    "recalculateToPercents": "never"
  },

  "chartScrollbarSettings": {
    "graph": "g1"
  },

  "chartCursorSettings": {
    "valueBalloonsEnabled": true,
    "fullWidth": true,
    "cursorAlpha": 0.1,
    "valueLineBalloonEnabled": true,
    "valueLineEnabled": true,
    "valueLineAlpha": 0.5
  },
  "periodSelector": {
    "position": "bottom",
    "periods": [{
      "period": "MM",
      "selected": true,
      "count": 1,
      "label": "1 month"
    }, {
      "period": "YYYY",
      "count": 1,
      "label": "1 year"
    }, {
      "period": "YTD",
      "label": "YTD"
    }, {
      "period": "MAX",
      "label": "MAX"
    }]
  }

});
$('document').ready(function() {
  $('#submit').on('click', function() {
    //alert(document.getElementById('year').value);
    add(document.getElementById('year').value);
    //   make();
  });
});

function add(yr) {
  chart.dataSets.push({
    "title": yr,
    "fieldMappings": [{
      "fromField": "value",
      "toField": "value"
    }],
    "dataProvider": generateChartData(yr),
    "categoryField": "date",
    "compared": true,
    "baseYear": 2015
  });
  AmCharts.baseYearInitialize(chart);
 // chart.validateNow();
  chart.validateData();
}
#chartdiv {
  width: 100%;
  height: 500px;
  font-family: Verdana;
  font-size: 12px;
}
<script type="text/javascript" src="https://code.jquery.com/jquery-1.11.2.min.js"></script>
<script type="text/javascript" src="https://www.amcharts.com/lib/3/amcharts.js"></script>
<script type="text/javascript" src="https://www.amcharts.com/lib/3/serial.js"></script>
<script type="text/javascript" src="https://www.amcharts.com/lib/3/themes/light.js"></script>
<script type="text/javascript" src="https://www.amcharts.com/lib/3/amstock.js"></script>
<input type="text" id="year"><input type="submit" id="submit">
<div id="chartdiv"></div>