amcharts / amstock3

JavaScript Stock Chart V3
Other
53 stars 31 forks source link

How to know which period is selected currently? #9

Closed sunujacob closed 6 years ago

sunujacob commented 6 years ago

I am using stock chart to plot market data. Iam using php and ajax to get chart data to plot candle chart. The chart refreshes every 10 seconds. I want to pass the current zoom level and get corresponding values for plotting chart. I want to know the last clicked period selector button and its label. Is that possible?

Below is my current chart. Also I want to change group of buttons into a select ?

mychart

RobbiesCode commented 6 years ago

Hi,

You can get the last clicked period selector button and its label by listening to your periodSelector changed event:

  // add "changed" listener to periodSelector
  e.chart.periodSelector.addListener("changed", function(e){

    activePeriod = {
      count: e.count,
      period: e.predefinedPeriod,
      label: e.event.target.value
    };

    console.log('new activePeriod', activePeriod);

  });

As a user could also change the zoom level/range by dragging/selecting an area in the scrollbar, you should probably add a listener to the chart's zoomed event as well:

  // add "zoomed" listener
  e.chart.addListener("zoomed", function(e){

    activeRange = {
      startDate: e.startDate,
      endDate: e.endDate,
      period: e.period
    };

    console.log('new activeRange', activeRange);

  });

Here's a Codepen demo that demonstrates this: https://codepen.io/team/amcharts/pen/20f836346504f6de7a2b0f241a9bffc7?editors=1010.

It is not possible to group the default periodSelector buttons in a <select>. If this is a hard requirement, you could perhaps create your own select, not using the built-in periodSelector at all.

mySelect.onchange = function(e){

  // get startDate and endDate from your <select> somehow...
  chart.zoom(startDate, endDate);

};

Docs: https://docs.amcharts.com/3/javascriptstockchart?search=zoom https://docs.amcharts.com/3/javascriptstockchart/PeriodSelector

Hope this helps!

sunujacob commented 6 years ago

Thank you for your help.

I update my chart every 10 seconds with selected period. generateChartData function is an ajax request to a php file which retrives data from mysql database.

but chart is not being redrawn accordingly.

  var chart = AmCharts.makeChart("chartdiv", {
    "type": "stock",
    "theme": "light",
    "autoMarginOffset": 30,
    // This will keep the selection at the end across data updates
    "glueToTheEnd": true,

    "valueAxesSettings": {
      "position": "right",
      "inside": false,
      "autoMargins": true,
      "axisColor": "#000000",
      "tickLength": 1
    },
    "categoryAxesSettings": {
      "parseDates": true,
      "minPeriod": "ss",
      "axisColor": "#000000",
      "tickLength": 1,
      "maxSeries": 0
    },
    "mouseWheelZoomEnabled": true,
    "dataSets": [{
      "fieldMappings": [{
        "fromField": "open",
        "toField": "open"
      }, {
        "fromField": "close",
        "toField": "close"
      }, {
        "fromField": "high",
        "toField": "high"
      }, {
        "fromField": "low",
        "toField": "low"
      }, {
        "fromField": "volume",
        "toField": "volume"
      }],

      "color": "#7f8da9",
      "dataProvider": chartData,
      "categoryField": "date"
    }
    ],

    "panels": [{
      "urlTarget": "_blank",
      "showCategoryAxis": true,
      "percentHeight": 70,
      "valueAxes": [{
        "dashLength": 5
      }],

      "categoryAxis": {
        "dashLength": 5
      },

      "stockGraphs": [{
        "id": "g1",
        "type": "candlestick",
        "proCandlesticks": false,
        "balloonText": "Open:<b>[[open]]</b><br>Low:<b>[[low]]</b><br>High:<b>[[high]]</b><br>Close:<b>[[close]]</b><br>",
        "openField": "open",
        "closeField": "close",
        "highField": "high",
        "lowField": "low",
        "lineAlpha": 1,
        "lineColor": "#53b987",
        "fillColors": "#53b987",
        "fillAlphas": 0.9,
        "negativeFillColors": "#eb4d5c",
        "negativeLineColor": "#eb4d5c",
        "useDataSetColors": false,
        "valueField": "open",
        "title": '<?php echo $symbol; ?>',
      }],

      "stockLegend": {
        "valueTextRegular": "O: [[open]]  H: [[high]]  L: [[low]]  C: [[close]]"
      }
    }
    ],

    "chartScrollbarSettings": {
      "updateOnReleaseOnly": true,
      "autoGridCount": true,
      "graph": "g1",
      "graphType": "line",
      "scrollbarHeight": 30
    },

    "periodSelector": {
      "position": "top",
      "inputFieldsEnabled": false,
      "periodsText": "",
      "dateFormat": "YYYY-MM-DD JJ:NN",
      "periods": [{
        "period": "hh",
        "count": 1,
        "label": "5",
        "selected": true

      }, {
        "period": "hh",
        "count": 3,
        "label": "15"
      }, {
        "period": "hh",
        "count": 6,
        "label": "30"
      }, {
        "period": "hh",
        "count": 15,
        "label": "1H"
      }, {
        "period": "dd",
        "count": "D",
        "label": "1D"
      }]
    },

    "listeners": [
      {
        "event": "rendered",
        "method": function (e) {

          chart.mouseDown = false;
          chart.containerDiv.onmousedown = function () {
            chart.mouseDown = true;
          }
          chart.containerDiv.onmouseup = function () {
            chart.mouseDown = false;
          }

          if (e.chart.ignoreResize) {
            e.chart.ignoreResize = false;
            return;
          }

          // init
          var margins = {
            "left": 0,
            "right": 0
          };

          // iterate thorugh all of the panels
          for (var p = 0; p < chart.panels.length; p++) {
            var panel = chart.panels[p];

            // iterate through all of the axis
            for (var i = 0; i < panel.valueAxes.length; i++) {
              var axis = panel.valueAxes[i];
              if (axis.inside !== false) {
                continue;
              }

              var axisWidth = axis.getBBox().width + 10;
              if (axisWidth > margins[axis.position]) {
                margins[axis.position] = axisWidth;
              }
            }

          }

          // set margins
          if (margins.left || margins.right) {
            chart.panelsSettings.marginLeft = margins.left;
            chart.panelsSettings.marginRight = margins.right;
            e.chart.ignoreResize = true;
            chart.invalidateSize();
          }
        }
      },
      {
        "event": "zoomed",
        "method": function (e) {
          e.chart.lastZoomed = e;
          //console.log(e);
          console.log("ignoring zoomed");
        }
      },

    ]

  });
  setInterval(function () {

    // if mouse is down, stop all updates
    if (chart.mouseDown) {
      return;
    }

//New data array
    var NewChartData = [];

//Adding new data to array
    var dataProvider = generateChartData();
    NewChartData.push(dataProvider);

//Setting the new data to the graph
    chart.dataProvider = NewChartData;

    chart.validateData();
  }, 10000);
RobbiesCode commented 6 years ago

Hi,

Thank for sharing your code, that helps! Your dataProvider "path" is wrong here. There is no chart.dataProvider in Stock Charts; dataProvider is a setting that belongs to dataSets.

In your case, your first and only data set:

chart.dataSets[0].dataProvider = NewChartData;
chart.validateData();

Hope this helps!

sunujacob commented 6 years ago

Thanks alot @RobbiesCode I changed my code as you said.

//Setting the new data to the graph
    chart.dataSets[0].dataProvider = generateChartData();
    chart.validateData();
RobbiesCode commented 6 years ago

You're welcome, glad I could help!