How to insert dataset in AmCharts StockChart via Rest Api

Hey there I am trying to use AmCharts
of json version I found out some example on there documentations Here is Json Example but problem is that my API return data differently I mean by json objects not by array looks like below


{
  "Meta Data": {
    "1. Information": "Weekly Prices (open, high, low, close) and Volumes",
    "2. Symbol": "IBM",
    "3. Last Refreshed": "2021-06-02",
    "4. Time Zone": "US/Eastern"
  },
  "Weekly Time Series": {
    "2021-06-02": {
      "1. open": "145.0000",
      "2. high": "145.8300",
      "3. low": "143.7500",
      "4. close": "145.7200",
      "5. volume": "5204371"
    },
    "2021-05-28": {
      "1. open": "145.0600",
      "2. high": "145.3900",
      "3. low": "143.0400",
      "4. close": "143.7400",
      "5. volume": "18483838"
    },
    "2021-05-21": {
      "1. open": "144.4400",
      "2. high": "145.8000",
      "3. low": "140.9200",
      "4. close": "144.7400",
      "5. volume": "20546126"
    },
....... ..... .....

and want to load that data in chart when try to acccess them with bracket notation it gives me and error

In there example data return json like below

and here is how I try to access above data

var chart = am4core.create("chartdiv", am4charts.XYChart);

// Set up data source
chart.dataSource.url = "https://www.alphavantage.co/query?function=TIME_SERIES_WEEKLY&symbol=IBM&apikey=demo";

// Create axes
var categoryAxis = chart.xAxes.push(new am4charts.CategoryAxis());
categoryAxis.dataFields.category = "Weekly Time Series";
// Create value axis
var valueAxis = chart.yAxes.push(new am4charts.ValueAxis());
// "Weekly Time Series": {
//     "2021-06-02": {
//       "1. open": "145.0000",
//       "2. high": "145.8300",
//       "3. low": "143.7500",
//       "4. close": "145.7200",
//       "5. volume": "5204371"
//     },
// Create series
var series1 = chart.series.push(new am4charts.LineSeries());
series1.dataFields.valueY =  ["Weekly Time Series"]["2021-06-02"]["5. volume"];
series1.dataFields.categoryX = ["Weekly Time Series"]["2021-06-02"];
// series1.numberFields.categoryX = ["Weekly Time Series"];

so… make it into an array?
It’ll be easier to make that an array than make the points work individually.

(Assume the above is the variable input)
let output = [];
Object.keys(input["Weekly Time Series"]).forEach((index) => {
   output.push({...input["Weekly Time Series"][index],{"key":index}});
});
...
chart.data = output;
...
categoryAxis.dataFields.category = "key";
1 Like

looks like helpful thank you so much let me try it and let you know what happens
one more thing I want to ask you that can’t we do use AmChart without converting it json object instead of array ???

hey sir I getting and error while tesing this


this is throwing some syntax error what is this and why this occurs ?

woops, missed one of the spreads.

Object.keys(input["Weekly Time Series"]).forEach((index) => {
   output.push({...input["Weekly Time Series"][index],...{"key":index}});
});

OR

Object.keys(input["Weekly Time Series"]).forEach((index) => {
   output.push({...input["Weekly Time Series"][index],"key":index});
});
1 Like

hey @m_hutley this works for me and data is perfectly convert into an array of object
image

but I am facing an error to render candleStick chart with this data I’m trying to fix why map doesn’t render don’t know whats wrong with

Please take a look and let me know what wrong with it ?
here’s my code

   <script>    

var output = [];
    
    $.get('https://www.alphavantage.co/query?function=TIME_SERIES_WEEKLY&symbol=IBM&apikey=demo', function( res ) {
            // let input = (res["Weekly Time Series"]);
            //  console.log(input);
            // let boxes = Object.keys(input).map( key => input);
            // // console.log(boxes);

              Object.keys(res["Weekly Time Series"]).forEach((index) => {
                output.push({...res["Weekly Time Series"][index],"date":index});
              });
            });
            // console.log(output)
   setTimeout((ext) => {
    
    am4core.ready(function() {
        console.log(output)
    // Themes begin
    am4core.useTheme(am4themes_animated);
    // Themes end
    
    // Create chart
    var chart = am4core.create("chartdiv", am4charts.XYChart);
    chart.padding(0, 15, 0, 15);
    
    // Load data
    // chart.dataSource.url = "https://www.amcharts.com/wp-content/uploads/assets/stock/MSFT.csv";
    // chart.dataSource.parser = new am4core.CSVParser();
    // chart.dataSource.parser.options.useColumnNames = true;
    // chart.dataSource.parser.options.reverse = true;
    chart.data = output;
    // the following line makes value axes to be arranged vertically.
    chart.leftAxesContainer.layout = "vertical";
    
    // uncomment this line if you want to change order of axes
    //chart.bottomAxesContainer.reverseOrder = true;
    
    var dateAxis = chart.xAxes.push(new am4charts.DateAxis());
    dateAxis.renderer.grid.template.location = 0;
    dateAxis.renderer.ticks.template.length = 8;
    dateAxis.renderer.ticks.template.strokeOpacity = 0.1;
    dateAxis.renderer.grid.template.disabled = true;
    dateAxis.renderer.ticks.template.disabled = false;
    dateAxis.renderer.ticks.template.strokeOpacity = 0.2;
    dateAxis.renderer.minLabelPosition = 0.01;
    dateAxis.renderer.maxLabelPosition = 0.99;
    dateAxis.keepSelection = true;
    dateAxis.minHeight = 30;
    
    dateAxis.groupData = true;
    dateAxis.minZoomCount = 5;
    
    // these two lines makes the axis to be initially zoomed-in
    // dateAxis.start = 0.7;
    // dateAxis.keepSelection = true;
    
    var valueAxis = chart.yAxes.push(new am4charts.ValueAxis());
    valueAxis.tooltip.disabled = true;
    valueAxis.zIndex = 1;
    valueAxis.renderer.baseGrid.disabled = true;
    // height of axis
    valueAxis.height = am4core.percent(65);
    
    valueAxis.renderer.gridContainer.background.fill = am4core.color("#000000");
    valueAxis.renderer.gridContainer.background.fillOpacity = 0.05;
    valueAxis.renderer.inside = true;
    valueAxis.renderer.labels.template.verticalCenter = "bottom";
    valueAxis.renderer.labels.template.padding(2, 2, 2, 2);
    
    //valueAxis.renderer.maxLabelPosition = 0.95;
    valueAxis.renderer.fontSize = "0.8em"
    
    // "2021-06-03": {
    //         "1. open": "145.0000",
    //         "2. high": "145.8800",
    //         "3. low": "143.7500",
    //         "4. close": "145.5500",
    //         "5. volume": "9335112"
    //     },

    
    
    var series = chart.series.push(new am4charts.CandlestickSeries());
    series.dataFields.dateX = ["date"];
    series.dataFields.openValueY = ["1. open"];
    series.dataFields.valueY = ["4. close"];
    series.dataFields.lowValueY = ["3. low"];
    series.dataFields.highValueY = ["2. high"];
    series.clustered = false;
    series.tooltipText = "open: {openValueY.value}\nlow: {lowValueY.value}\nhigh: {highValueY.value}\nclose: {valueY.value}";
    series.name = "MSFT";
    series.defaultState.transitionDuration = 0;
    
    var valueAxis2 = chart.yAxes.push(new am4charts.ValueAxis());
    valueAxis2.tooltip.disabled = true;
    // height of axis
    valueAxis2.height = am4core.percent(35);
    valueAxis2.zIndex = 3
    // this makes gap between panels
    valueAxis2.marginTop = 30;
    valueAxis2.renderer.baseGrid.disabled = true;
    valueAxis2.renderer.inside = true;
    valueAxis2.renderer.labels.template.verticalCenter = "bottom";
    valueAxis2.renderer.labels.template.padding(2, 2, 2, 2);
    //valueAxis.renderer.maxLabelPosition = 0.95;
    valueAxis2.renderer.fontSize = "0.8em"
    
    valueAxis2.renderer.gridContainer.background.fill = am4core.color("#000000");
    valueAxis2.renderer.gridContainer.background.fillOpacity = 0.05;
    
    var series2 = chart.series.push(new am4charts.ColumnSeries());
    series2.dataFields.dateX = ["date"];
    series2.clustered = false;
    series2.dataFields.valueY = ["5. volume"];
    series2.yAxis = valueAxis2;
    series2.tooltipText = "{valueY.value}";
    series2.name = "Series 2";
    // volume should be summed
    series2.groupFields.valueY = "sum";
    series2.defaultState.transitionDuration = 0;
    
    chart.cursor = new am4charts.XYCursor();
    
    var scrollbarX = new am4charts.XYChartScrollbar();
    
    var sbSeries = chart.series.push(new am4charts.LineSeries());
    sbSeries.dataFields.valueY = "Close";
    sbSeries.dataFields.dateX = "Date";
    scrollbarX.series.push(sbSeries);
    sbSeries.disabled = true;
    scrollbarX.marginBottom = 20;
    chart.scrollbarX = scrollbarX;
    scrollbarX.scrollbarChart.xAxes.getIndex(0).minHeight = undefined;
    
    
    
    /**
     * Set up external controls
     */
    
    // Date format to be used in input fields
    var inputFieldFormat = "yyyy-MM-dd";
    
    document.getElementById("b1m").addEventListener("click", function() {
      var max = dateAxis.groupMax["day1"];
      var date = new Date(max);
      am4core.time.add(date, "month", -1);
      zoomToDates(date);
    });
    
    document.getElementById("b3m").addEventListener("click", function() {
      var max = dateAxis.groupMax["day1"];
      var date = new Date(max);
      am4core.time.add(date, "month", -3);
      zoomToDates(date);
    });
    
    document.getElementById("b6m").addEventListener("click", function() {
      var max = dateAxis.groupMax["day1"];
      var date = new Date(max);
      am4core.time.add(date, "month", -6);
      zoomToDates(date);
    });
    
    document.getElementById("b1y").addEventListener("click", function() {
      var max = dateAxis.groupMax["day1"];
      var date = new Date(max);
      am4core.time.add(date, "year", -1);
      zoomToDates(date);
    });
    
    document.getElementById("bytd").addEventListener("click", function() {
      var max = dateAxis.groupMax["day1"];
      var date = new Date(max);
      am4core.time.round(date, "year", 1);
      zoomToDates(date);
    });
    
    document.getElementById("bmax").addEventListener("click", function() {
      var min = dateAxis.groupMin["day1"];
      var date = new Date(min);
      zoomToDates(date);
    });
    
    dateAxis.events.on("selectionextremeschanged", function() {
      updateFields();
    });
    
    dateAxis.events.on("extremeschanged", updateFields);
    
    function updateFields() {
      var minZoomed = dateAxis.minZoomed + am4core.time.getDuration(dateAxis.mainBaseInterval.timeUnit, dateAxis.mainBaseInterval.count) * 0.5;
      document.getElementById("fromfield").value = chart.dateFormatter.format(minZoomed, inputFieldFormat);
      document.getElementById("tofield").value = chart.dateFormatter.format(new Date(dateAxis.maxZoomed), inputFieldFormat);
    }
    
    document.getElementById("fromfield").addEventListener("keyup", updateZoom);
    document.getElementById("tofield").addEventListener("keyup", updateZoom);
    
    var zoomTimeout;
    function updateZoom() {
      if (zoomTimeout) {
        clearTimeout(zoomTimeout);
      }
      zoomTimeout = setTimeout(function() {
        var start = document.getElementById("fromfield").value;
        var end = document.getElementById("tofield").value;
        if ((start.length < inputFieldFormat.length) || (end.length < inputFieldFormat.length)) {
          return;
        }
        var startDate = chart.dateFormatter.parse(start, inputFieldFormat);
        var endDate = chart.dateFormatter.parse(end, inputFieldFormat);
    
        if (startDate && endDate) {
          dateAxis.zoomToDates(startDate, endDate);
        }
      }, 500);
    }
    
    function zoomToDates(date) {
      var min = dateAxis.groupMin["day1"];
      var max = dateAxis.groupMax["day1"];
      dateAxis.keepSelection = true;
      //dateAxis.start = (date.getTime() - min)/(max - min);
      //dateAxis.end = 1;
    
      dateAxis.zoom({start:(date.getTime() - min)/(max - min), end:1});
    }
    
    });        // end am4core.ready()
    
}, 6000);

The reason to setting out time is conversion take time initially for now I used setTimeOut but when it’s done I replace it with promise

image

And currently above chart is just render with empty data set !!

Just now I find out that with rendering data with DateX property / with date Data must be sorted in ascending order but my dataset are in descending order


above image is documentation snap from AmChart


and look above is my data set which is descending order
I believe I need to sort it in ascending order

JazakAllah Khair for your support @m_hutley problem is from sorting


and above is the solution for that with url Check for Solution

1 Like