<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>ZingSoft Demo</title>
  <script nonce="undefined" src="https://cdn.zingchart.com/zingchart.min.js"></script>
  <style>
    html,
    body {
      height: 100%;
      width: 100%;
      margin: 0;
      padding: 0;
    }
    #myChart {
      height: 100%;
      width: 100%;
      min-height: 150px;
    }
  </style>
</head>
<body>
  <div id="myChart"></div>
  <script>
    ZC.LICENSE = ["569d52cefae586f634c54f86dc99e6a9", "b55b025e438fa8a98e32482b5f768ff5"];
    var barConfig = { // initial chart config
      type: 'bar',
      title: {
        text: 'Top Stocks Portfolio'
      },
      plot: {
        cursor: 'pointer',
        valueBox: {
          text: '%t'
        }
      },
      scaleX: {
        label: {
          text: 'Company Price Point'
        },
        item: {
          visible: false
        }
      },
      series: [{
          id: 'MSFT',
          text: 'MSFT',
          dataDescription: 'Microsoft Corporation',
          values: [61.25],
          dataUrl: 'https://cdn.zingchart.com/datasets/msft-stock-data.json' // retrieved from quandl and downloaded so our site demo is not dependent on their API
        },
        {
          id: 'NKE',
          text: 'NKE',
          dataDescription: 'Nike',
          values: [58.25],
          dataUrl: 'https://cdn.zingchart.com/datasets/nke-stock-data.json' // retrieved from quandl and downloaded so our site demo is not dependent on their API' // retrieved from quandl and downloaded so our site demo is not dependent on their API
        },
        {
          id: 'AAPL',
          text: 'AAPL',
          dataDescription: 'Apple Inc',
          values: [148.25],
          dataUrl: 'https://cdn.zingchart.com/datasets/aapl-stock-data.json' // retrieved from quandl and downloaded so our site demo is not dependent on their API' // retrieved from quandl and downloaded so our site demo is not dependent on their API
        },
        {
          id: 'INTC',
          text: 'INTC',
          dataDescription: 'Intel Corporation',
          values: [44.55],
          dataUrl: 'https://cdn.zingchart.com/datasets/intc-stock-data.json' // retrieved from quandl and downloaded so our site demo is not dependent on their API' // retrieved from quandl and downloaded so our site demo is not dependent on their API
        },
        {
          id: 'MMM',
          text: 'MMM',
          dataDescription: '3M Company',
          values: [230.23],
          dataUrl: 'https://cdn.zingchart.com/datasets/mmm-stock-data.json' // retrieved from quandl and downloaded so our site demo is not dependent on their API' // retrieved from quandl and downloaded so our site demo is not dependent on their API
        },
        {
          id: 'MCD',
          text: 'MCD',
          dataDescription: 'Macdonalds',
          values: [165.23],
          dataUrl: 'https://cdn.zingchart.com/datasets/mcd-stock-data.json' // retrieved from quandl and downloaded so our site demo is not dependent on their API' // retrieved from quandl and downloaded so our site demo is not dependent on their API
        },
        {
          id: 'DIS',
          text: 'DIS',
          dataDescription: 'DIS Corporation',
          values: [107.67],
          dataUrl: 'https://cdn.zingchart.com/datasets/dis-stock-data.json' // retrieved from quandl and downloaded so our site demo is not dependent on their API' // retrieved from quandl and downloaded so our site demo is not dependent on their API
        },
      ]
    };
    var drilldownConfig = { // second config for the drilldown
      type: 'line',
      utc: true,
      globals: {
        thousandsSeparator: ','
      },
      title: {
        text: 'Title Is N/A',
        adjustLayout: true
      },
      plot: {
        maxTrackers: 0,
        maxNodes: 0,
        exact: true
      },
      plotarea: {
        margin: 'dynamic',
        adjustLayout: true
      },
      legend: {
        toggleAction: 'hide',
        adjustLayout: true
      },
      scaleX: {
        zooming: true,
        transform: {
          type: 'date',
          all: "%Y/%m/%d"
        }
      },
      scaleY: {
      },
      scaleY2: {
        short: true,
        shortUnit: 'M',
        guide: {
          visible: false
        }
      },
      preview: {
        adjustLayout: true
      },
      crosshairX: {
        plotLabel: {
          fontSize: 14,
          borderRadius: 5,
          shadow: 1,
          headerText: '%kv <br><hr>',
          decimals: 2
        }
      },
      scrollX: {},
      series: [],
      labels: [{
        flat: false, // most important. Makes label register click event
        text: 'Go Back',
        backgroundColor: '#C4C4C4',
        borderRadius: 5,
        x: 45,
        y: 15,
        id: 'backwards',
        cursor: 'hand',
        padding: 5,
        hoverState: {
          backgroundColor: '#e0e0e0'
        }
      }]
    };
    zingchart.render({
      id: 'myChart',
      data: barConfig,
      height: '100%',
      width: '100%'
    });
    var oDataStructure = {}; // local variable cache
    /*
     * Retrieve the data. It will be in specific format that can be viewed in the
     * dataUrl property. We initally want to only show the first 4 plots and users can
     * toggle the rest on after load.
     *
     * Real url example: demos.zingchart.com/view/NKVZRE4U/google.json
     */
    function sortAndBindData(aColumnNames, aData, sPlotId) {
      /*
       * assign series attributes.
       * end result is an array of objects.
       * [{
       *   values:[],
       *   id: '',
       *   text: '',
       *   visible: true || false,
       *   scales: 'scale-x,scale-y' || 'scale-x,scale-y-2',
       *   short: false || true
       *   shortUnit: 'M' || ''
       * }]
       */
      for (var i = 1, j = 0; i < aColumnNames.length; i++, j++) {
        oDataStructure[sPlotId].series[j] = {}; // create series object
        oDataStructure[sPlotId].series[j].values = [];
        oDataStructure[sPlotId].series[j].id = aColumnNames[i];
        oDataStructure[sPlotId].series[j].text = aColumnNames[i];
        oDataStructure[sPlotId].series[j].visible = true;
        oDataStructure[sPlotId].series[j].scales = aColumnNames[i].includes('Volume') ? 'scale-x, scale-y-2' : 'scale-x, scale-y';
        oDataStructure[sPlotId].series[j].short = aColumnNames[i].includes('Volume') ? 'true' : 'false';
        oDataStructure[sPlotId].series[j].shortUnit = 'M';
      }
      /* 
       * force assign all values in one pass. This is the format expected from the xhr request
       * ["Date","Open","High","Low","Close","Volume","Ex-Dividend","Split Ratio","Adj. Open","Adj. High","Adj. Low","Adj. Close","Adj. Volume"]
       *
       * aData[i][1] will access "Open" value
       */
      for (var i = aData.length - 1; i >= 0; i--) {
        oDataStructure[sPlotId].series[0].values.push(aData[i][1]);
        oDataStructure[sPlotId].series[1].values.push(aData[i][2]);
        oDataStructure[sPlotId].series[2].values.push(aData[i][3]);
        oDataStructure[sPlotId].series[3].values.push(aData[i][4]);
        oDataStructure[sPlotId].series[4].values.push(aData[i][5]);
        oDataStructure[sPlotId].series[5].values.push(aData[i][6]);
        oDataStructure[sPlotId].series[6].values.push(aData[i][7]);
        oDataStructure[sPlotId].series[7].values.push(aData[i][8]);
        oDataStructure[sPlotId].series[8].values.push(aData[i][9]);
        oDataStructure[sPlotId].series[9].values.push(aData[i][10]);
        oDataStructure[sPlotId].series[10].values.push(aData[i][11]);
        oDataStructure[sPlotId].series[11].values.push(aData[i][12]);
      }
      // this will assign all the data to the chart at once
      zingchart.exec('myChart', 'setdata', {
        data: oDataStructure[sPlotId]
      });
    }
    /*
     * Set up the config that is going to be drilled into.
     */
    function renderStockDataFromQuandl(sUrl, sDescription, sPlotId) {
      fetch(sUrl)
        .then(req => {
          return req.json()
        })
        .then(data => {
          var aColumnNames = data.dataset['column_names'];
          var aData = data.dataset.data;
          oDataStructure[sPlotId] = JSON.parse(JSON.stringify(drilldownConfig));
          //oDataStructure[sPlotId].scaleX.minValue = Date.parse(data.dataset['start_date']);
          //oDataStructure[sPlotId].scaleX.maxValue = Date.parse(data.dataset['end_date']);
          oDataStructure[sPlotId].title.text = sDescription + ' Stock Data';
          sortAndBindData(aColumnNames, aData, sPlotId);
        });
    }
    /*
     * This evnet handler will either retrieve stock data from AJAX
     * or retrieve the structure from our local variable cache
     */
    function plotClickHandler(e) {
      if (e.xdata['url']) {
        if (!oDataStructure[e.plotid]) { // if doesn't exist in cache. Go get it
          oDataStructure[e.plotid] = {};
          renderStockDataFromQuandl(e.xdata['url'], e.xdata['description'], e.plotid);
        } else { // we already have the data. Render it
          zingchart.exec('myChart', 'setdata', {
            data: oDataStructure[e.plotid]
          });
        }
      }
    }
    /*
     * Handle history buttons. You can assign
     * shapes id's and based on id you can go 
     * 'forward' or 'backwards'. You could 
     * also handle this with HTML and register
     * click events to those DOM elements.
     */
    function labelClickHandler(p) {
      var labelId = p.labelid;
      switch (labelId) {
        case 'forwards':
        case 'backwards':
        case 'default':
          zingchart.exec('myChart', 'reload'); // reload loads original JSON packet (not modified packet)
          /* alternative way to reload chart
          zingchart.exec('myChart', 'destroy');
          zingchart.render({
          	id : 'myChart', 
          	data : barConfig, 
            height: '100%', 
          	width: '100%' 
          });
          */
          break;
      }
    }
    zingchart.bind('myChart', 'label_click', labelClickHandler);
    zingchart.bind('myChart', 'plot_click', plotClickHandler);
  </script>
</body>
</html>
       
      
        
        <!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>ZingSoft Demo</title>
  <script src="https://cdn.zingchart.com/zingchart.min.js"></script>
</head>
<body>
  <div id="myChart"></div>
</body>
</html>
       
      
        html,
body {
  height: 100%;
  width: 100%;
  margin: 0;
  padding: 0;
}
#myChart {
  height: 100%;
  width: 100%;
  min-height: 150px;
}
       
      
        var barConfig = { // initial chart config
  type: 'bar',
  title: {
    text: 'Top Stocks Portfolio'
  },
  plot: {
    cursor: 'pointer',
    valueBox: {
      text: '%t'
    }
  },
  scaleX: {
    label: {
      text: 'Company Price Point'
    },
    item: {
      visible: false
    }
  },
  series: [{
      id: 'MSFT',
      text: 'MSFT',
      dataDescription: 'Microsoft Corporation',
      values: [61.25],
      dataUrl: 'https://cdn.zingchart.com/datasets/msft-stock-data.json' // retrieved from quandl and downloaded so our site demo is not dependent on their API
    },
    {
      id: 'NKE',
      text: 'NKE',
      dataDescription: 'Nike',
      values: [58.25],
      dataUrl: 'https://cdn.zingchart.com/datasets/nke-stock-data.json' // retrieved from quandl and downloaded so our site demo is not dependent on their API' // retrieved from quandl and downloaded so our site demo is not dependent on their API
    },
    {
      id: 'AAPL',
      text: 'AAPL',
      dataDescription: 'Apple Inc',
      values: [148.25],
      dataUrl: 'https://cdn.zingchart.com/datasets/aapl-stock-data.json' // retrieved from quandl and downloaded so our site demo is not dependent on their API' // retrieved from quandl and downloaded so our site demo is not dependent on their API
    },
    {
      id: 'INTC',
      text: 'INTC',
      dataDescription: 'Intel Corporation',
      values: [44.55],
      dataUrl: 'https://cdn.zingchart.com/datasets/intc-stock-data.json' // retrieved from quandl and downloaded so our site demo is not dependent on their API' // retrieved from quandl and downloaded so our site demo is not dependent on their API
    },
    {
      id: 'MMM',
      text: 'MMM',
      dataDescription: '3M Company',
      values: [230.23],
      dataUrl: 'https://cdn.zingchart.com/datasets/mmm-stock-data.json' // retrieved from quandl and downloaded so our site demo is not dependent on their API' // retrieved from quandl and downloaded so our site demo is not dependent on their API
    },
    {
      id: 'MCD',
      text: 'MCD',
      dataDescription: 'Macdonalds',
      values: [165.23],
      dataUrl: 'https://cdn.zingchart.com/datasets/mcd-stock-data.json' // retrieved from quandl and downloaded so our site demo is not dependent on their API' // retrieved from quandl and downloaded so our site demo is not dependent on their API
    },
    {
      id: 'DIS',
      text: 'DIS',
      dataDescription: 'DIS Corporation',
      values: [107.67],
      dataUrl: 'https://cdn.zingchart.com/datasets/dis-stock-data.json' // retrieved from quandl and downloaded so our site demo is not dependent on their API' // retrieved from quandl and downloaded so our site demo is not dependent on their API
    },
  ]
};
var drilldownConfig = { // second config for the drilldown
  type: 'line',
  utc: true,
  globals: {
    thousandsSeparator: ','
  },
  title: {
    text: 'Title Is N/A',
    adjustLayout: true
  },
  plot: {
    maxTrackers: 0,
    maxNodes: 0,
    exact: true
  },
  plotarea: {
    margin: 'dynamic',
    adjustLayout: true
  },
  legend: {
    toggleAction: 'hide',
    adjustLayout: true
  },
  scaleX: {
    zooming: true,
    transform: {
      type: 'date',
      all: "%Y/%m/%d"
    }
  },
  scaleY: {
  },
  scaleY2: {
    short: true,
    shortUnit: 'M',
    guide: {
      visible: false
    }
  },
  preview: {
    adjustLayout: true
  },
  crosshairX: {
    plotLabel: {
      fontSize: 14,
      borderRadius: 5,
      shadow: 1,
      headerText: '%kv <br><hr>',
      decimals: 2
    }
  },
  scrollX: {},
  series: [],
  labels: [{
    flat: false, // most important. Makes label register click event
    text: 'Go Back',
    backgroundColor: '#C4C4C4',
    borderRadius: 5,
    x: 45,
    y: 15,
    id: 'backwards',
    cursor: 'hand',
    padding: 5,
    hoverState: {
      backgroundColor: '#e0e0e0'
    }
  }]
};
zingchart.render({
  id: 'myChart',
  data: barConfig,
  height: '100%',
  width: '100%'
});
var oDataStructure = {}; // local variable cache
/*
 * Retrieve the data. It will be in specific format that can be viewed in the
 * dataUrl property. We initally want to only show the first 4 plots and users can
 * toggle the rest on after load.
 *
 * Real url example: demos.zingchart.com/view/NKVZRE4U/google.json
 */
function sortAndBindData(aColumnNames, aData, sPlotId) {
  /*
   * assign series attributes.
   * end result is an array of objects.
   * [{
   *   values:[],
   *   id: '',
   *   text: '',
   *   visible: true || false,
   *   scales: 'scale-x,scale-y' || 'scale-x,scale-y-2',
   *   short: false || true
   *   shortUnit: 'M' || ''
   * }]
   */
  for (var i = 1, j = 0; i < aColumnNames.length; i++, j++) {
    oDataStructure[sPlotId].series[j] = {}; // create series object
    oDataStructure[sPlotId].series[j].values = [];
    oDataStructure[sPlotId].series[j].id = aColumnNames[i];
    oDataStructure[sPlotId].series[j].text = aColumnNames[i];
    oDataStructure[sPlotId].series[j].visible = true;
    oDataStructure[sPlotId].series[j].scales = aColumnNames[i].includes('Volume') ? 'scale-x, scale-y-2' : 'scale-x, scale-y';
    oDataStructure[sPlotId].series[j].short = aColumnNames[i].includes('Volume') ? 'true' : 'false';
    oDataStructure[sPlotId].series[j].shortUnit = 'M';
  }
  /* 
   * force assign all values in one pass. This is the format expected from the xhr request
   * ["Date","Open","High","Low","Close","Volume","Ex-Dividend","Split Ratio","Adj. Open","Adj. High","Adj. Low","Adj. Close","Adj. Volume"]
   *
   * aData[i][1] will access "Open" value
   */
  for (var i = aData.length - 1; i >= 0; i--) {
    oDataStructure[sPlotId].series[0].values.push(aData[i][1]);
    oDataStructure[sPlotId].series[1].values.push(aData[i][2]);
    oDataStructure[sPlotId].series[2].values.push(aData[i][3]);
    oDataStructure[sPlotId].series[3].values.push(aData[i][4]);
    oDataStructure[sPlotId].series[4].values.push(aData[i][5]);
    oDataStructure[sPlotId].series[5].values.push(aData[i][6]);
    oDataStructure[sPlotId].series[6].values.push(aData[i][7]);
    oDataStructure[sPlotId].series[7].values.push(aData[i][8]);
    oDataStructure[sPlotId].series[8].values.push(aData[i][9]);
    oDataStructure[sPlotId].series[9].values.push(aData[i][10]);
    oDataStructure[sPlotId].series[10].values.push(aData[i][11]);
    oDataStructure[sPlotId].series[11].values.push(aData[i][12]);
  }
  // this will assign all the data to the chart at once
  zingchart.exec('myChart', 'setdata', {
    data: oDataStructure[sPlotId]
  });
}
/*
 * Set up the config that is going to be drilled into.
 */
function renderStockDataFromQuandl(sUrl, sDescription, sPlotId) {
  fetch(sUrl)
    .then(req => {
      return req.json()
    })
    .then(data => {
      var aColumnNames = data.dataset['column_names'];
      var aData = data.dataset.data;
      oDataStructure[sPlotId] = JSON.parse(JSON.stringify(drilldownConfig));
      //oDataStructure[sPlotId].scaleX.minValue = Date.parse(data.dataset['start_date']);
      //oDataStructure[sPlotId].scaleX.maxValue = Date.parse(data.dataset['end_date']);
      oDataStructure[sPlotId].title.text = sDescription + ' Stock Data';
      sortAndBindData(aColumnNames, aData, sPlotId);
    });
}
/*
 * This evnet handler will either retrieve stock data from AJAX
 * or retrieve the structure from our local variable cache
 */
function plotClickHandler(e) {
  if (e.xdata['url']) {
    if (!oDataStructure[e.plotid]) { // if doesn't exist in cache. Go get it
      oDataStructure[e.plotid] = {};
      renderStockDataFromQuandl(e.xdata['url'], e.xdata['description'], e.plotid);
    } else { // we already have the data. Render it
      zingchart.exec('myChart', 'setdata', {
        data: oDataStructure[e.plotid]
      });
    }
  }
}
/*
 * Handle history buttons. You can assign
 * shapes id's and based on id you can go 
 * 'forward' or 'backwards'. You could 
 * also handle this with HTML and register
 * click events to those DOM elements.
 */
function labelClickHandler(p) {
  var labelId = p.labelid;
  switch (labelId) {
    case 'forwards':
    case 'backwards':
    case 'default':
      zingchart.exec('myChart', 'reload'); // reload loads original JSON packet (not modified packet)
      /* alternative way to reload chart
      zingchart.exec('myChart', 'destroy');
      zingchart.render({
      	id : 'myChart', 
      	data : barConfig, 
        height: '100%', 
      	width: '100%' 
      });
      */
      break;
  }
}
zingchart.bind('myChart', 'label_click', labelClickHandler);
zingchart.bind('myChart', 'plot_click', plotClickHandler);