Search code examples
javascriptamchartsamstock

Amstock chart doesn't zoom on init event


I need to zoom my chart to a specified period on init event.

      "listeners": [{
        "event": "zoomed",
        "method": this.calulateMetrics
      },{
        "event": "dataUpdated",
        "method": this.showPeriod
      }, {
        "event": "init",
        "method": this.showPeriod
      },{
        "event": "rendered",
        "method": this.showPeriod
      }],


  showPeriod(event) {
    // Retrieve the data
    let dates = this.$store.getters.getDates
    let startDate = dates[0]
    let endDate = (dates[dates.length - 1])
    endDate.setHours(22)
    try {
      this.chart.zoom(startDate, endDate)
      console.log("Last date", endDate)
    } catch(err) {
      console.log("Error",(err.message))
    }
  },

Although I can't catch any errors the period remains the same. Beside init I tried rendered and dataUpdated but it didn't help me either.

But when I trigger the call to external event <v-btn v-on:click="showPeriod">Button</v-btn> it works fine.

The whole options file is following:

   this.chart = window.AmCharts.makeChart("chartdiv", {
      "path": AmCharts_path,
      "type": "stock",
      "theme": "light",

      "dataSets": this.$store.state.portfoliosData.performance.map(function (port, idx) {
        return {
          "title": port.name,
          "fieldMappings": [{
            "fromField": "value",
            "toField": "value"
          }],
          "dataProvider": port.data,
          "compared": (idx === 0 ? false : true),
          "categoryField": "date"
        }
      }),

      "panels": [{
        "title": "Value",
        "percentHeight": 70,
        "stockGraphs": [
          {
            "id": "g1",
            "valueField": "value",
            "comparable": true,
            "compareField": "value",
            "balloonFunction": this.ballonRender,
            "compareGraphBalloonFunction": this.ballonRender
          }]
      }],

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

      "categoryAxis": {
        "parseDates": true,
      },

      "categoryAxesSettings": {
        "groupToPeriods": ["DD"]
      },

      "balloon": {
          "fixedPosition": true,
          "maxWidth": 10000,
          "offsetY": 1,
      },

      "dataDateFormat": "YYYY-MM-DD",

      "chartCursorSettings": {
        "valueBalloonsEnabled": true,
        "categoryBalloonEnabled": true,
        "selectWithoutZooming": true,
        "showNextAvailable": true,
        "categoryBalloonAlpha": 0.8,
        "bulletsEnabled": true,
        "bulletSize": 10,
        "valueZoomable":true,
        "usePeriod": "DD",
        "categoryBalloonDateFormats": [
            {period:'fff',format:'JJ:NN:SS'},
            {period:'ss',format:'JJ:NN:SS'},
            {period:'mm',format:'JJ:NN'},
            {period:'hh',format:'JJ:NN'},
            {period:'DD',format:'EEEE, MMM DD'},
            {period:'WW',format:'EEEE, MMM DD'},
            {period:'MM',format:'MMM'},
            {period:'YYYY',format:'YYYY'}
          ]
      },

       "periodSelector": {
         "position": "bottom"
      },
    });
  },

Reproduction link can be find here


Solution

  • The main issue is that AmCharts' listener callbacks don't understand your component scope. this in the callbacks refers to AmCharts' callback scope, not your component. Every AmCharts listener provides a reference to itself in the event's chart property (see init, for example), so changing all of your this.chart lines to event.chart in your callbacks will fix that part of the problem. If you need a reference to your component itself, add a custom property to the chart object in your renderGraph() method then refer to that through event.chart:

      renderGraph() {
        // ...
        this.chart = window.AmCharts.makeChart("chartdiv", {
          // ...
          componentRef: this,
          // ...
        })
      }
    
      //example using initPeriod:
      initPeriod(event) { //event parameter contains {type: "init", chart: stockChartReference}
        console.log("init period")
        let dates = event.chart.componentRef.$store.getters.getDates
        let startDate = dates[0]
        let endDate = (dates[dates.length - 1])
        endDate.setHours(22)
        try {
          event.chart.zoom(startDate, endDate)
          console.log("Last date", endDate)
        } catch(err) {
          console.log("Error",(err.message))
        }
      },
    

    Your zoomed listener is refering to an undefined method called calulateMetrics. I see a method called calculateMetrics in amstore but I'm not sure if that's what you meant and changing it to that doesn't seem to work for me, so I defer to you on adding the appropriate method. Adding that missing method along with making sure that you refer to the chart object correctly like the other callbacks will fix your problem.

    Demo for everything except zoomed due to the missing method: https://codesandbox.io/s/5wpopzwlnp