• Edit
  • Download
  • <!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>
        .zc-body {
          background-color: #FFF;
          font: 100%/1.5 'Helvetica Neue', 'Helvetica', 'Arial', sans-serif, 'Comic Sans';
        }
    
        .chart--container {
          background-color: #FFF;
          min-height: 530px;
          width: 100%;
          height: 100%;
        }
    
        #day {
          color: #2196F3;
        }
    
        #day {
          margin-top: 20px;
          margin-right: 20px;
          font-size: 25px;
          float: right;
        }
    
        #date-picker-container {
          margin-left: 25px;
        }
    
        [data-period] {
          margin: 5px;
          padding: 10px 10px;
          background-color: #2196F3;
          color: #FFF;
          display: inline-block;
        }
    
        [data-period]:hover {
          cursor: pointer;
          opacity: .7;
        }
    
        #date-picker-container div {
          display: inline-block;
        }
    
        #date-from,
        #date-to {
          margin-right: 6px;
          margin-left: 6px;
          color: #2196F3;
        }
    
        .active {
          background: #fd992b;
        }
    
        .zc-ref {
          display: none;
        }
      </style>
    </head>
    
    <body>
      <div id="myChart" class="chart--container">
        <div id="date-picker-container">
          <span data-period="1" class="active">30 Days</span>
          <span data-period="2">60 Days</span>
          <span data-period="3">90 Days</span>
          <div>
            <b>From:</b>
            <span id="date-from">1/31/19</span>
          </div>
          <div>
            <b>To:</b>
            <span id="date-to">6/17/19</span>
          </div>
          <div id="day"></div>
        </div>
        <div id="main-container">
          <a class="zc-ref" href="https://www.zingchart.com/">Powered by ZingChart</a>
        </div>
      </div>
      <script>
        ZC.LICENSE = ["569d52cefae586f634c54f86dc99e6a9", "b55b025e438fa8a98e32482b5f768ff5"];
        let chartConfig = {
          type: 'mixed',
          title: {
            text: 'Projected Cash Flow',
            align: 'center',
          },
          plot: {
            tooltip: {
              visible: false,
            },
            aspect: 'spline',
            marker: {
              visible: false,
            },
          },
          plotarea: {},
          scaleX: {
            values: [
              '1/31/19',
              '2/10/19',
              '2/11/19',
              '2/12/19',
              '2/13/19',
              '2/19/19',
              '2/18/19',
              '2/19/19',
              '2/20/19',
              '2/21/19',
              '2/24/19',
              '2/25/19',
              '2/26/19',
              '2/27/19',
              '2/28/19',
              '2/3/19',
              '2/4/19',
              '2/5/19',
              '2/6/19',
              '2/7/19',
              '3/10/19',
              '3/11/19',
              '3/12/19',
              '3/13/19',
              '3/14/19',
              '3/17/19',
              '3/18/19',
              '3/19/19',
              '3/20/19',
              '3/21/19',
              '3/24/19',
              '3/25/19',
              '3/26/19',
              '3/27/19',
              '3/28/19',
              '3/3/19',
              '3/31/19',
              '3/4/19',
              '3/5/19',
              '3/6/19',
              '3/7/19',
              '4/1/19',
              '4/10/19',
              '4/11/19',
              '4/14/19',
              '4/15/19',
              '4/16/19',
              '4/17/19',
              '4/2/19',
              '4/21/19',
              '4/22/19',
              '4/23/19',
              '4/24/19',
              '4/25/19',
              '4/28/19',
              '4/29/19',
              '4/3/19',
              '4/30/19',
              '4/4/19',
              '4/7/19',
              '4/8/19',
              '4/9/19',
              '5/1/19',
              '5/12/19',
              '5/13/19',
              '5/14/19',
              '5/15/19',
              '5/16/19',
              '5/19/19',
              '5/20/19',
              '5/21/19',
              '5/22/19',
              '5/23/19',
              '5/27/19',
              '5/28/19',
              '5/29/19',
              '5/30/19',
              '5/5/19',
              '5/6/19',
              '5/7/19',
              '5/8/19',
              '5/9/19',
              '6/10/19',
              '6/11/19',
              '6/12/19',
              '6/13/19',
              '6/16/19',
              '6/17/19',
            ],
            itemsOverlap: true,
            lineWidth: '0px',
            tick: {
              alpha: 1,
              lineColor: '#2196F3',
              lineWidth: '2px',
            },
            zooming: true,
            zoomTo: [0, 30],
          },
          scaleY: {
            values: '0:20000:1000',
            guide: {
              visible: false,
            },
          },
          scaleY2: {},
          crosshairX: {
            lineColor: '#2196F3',
            lineStyle: 'dashed',
            lineWidth: '2px',
            marker: {
              type: 'triangle',
              size: '5px',
              visible: true,
            },
            plotLabel: {
              visible: false,
            },
          },
          preview: {
            live: true,
          },
          series: [{
              type: 'bar',
              values: [
                4000, 10000, 5000, 2000, 6000, 10000, 15000, 8000, 3000, 7000, 13000,
                4000, 10000, 5000, 2000, 6000, 10000, 15000, 8000, 3000, 7000, 13000,
                4000, 10000, 5000, 2000, 6000, 10000, 15000, 8000, 3000, 7000, 13000,
                4000, 10000, 5000, 2000, 6000, 10000, 15000, 8000, 3000, 7000, 13000,
                4000, 10000, 5000, 2000, 6000, 10000, 15000, 8000, 3000, 7000, 13000,
                4000, 10000, 5000, 2000, 6000, 10000, 15000, 8000, 3000, 7000, 13000,
                4000, 10000, 5000, 2000, 6000, 10000, 15000, 8000, 3000, 7000, 13000,
                4000, 10000, 5000, 2000, 6000, 10000, 15000, 8000, 3000, 7000, 13000,
                8000, 0, 5000,
              ],
              backgroundColor: '#FFEB3B',
              scales: 'scale-x, scale-y-2',
            },
            {
              type: 'line',
              values: [
                6000, 7000, 3000, 4000, 10000, 13000, 5000, 0, 9000, 16000, 9000, 6000,
                7000, 3000, 4000, 10000, 13000, 5000, 0, 9000, 16000, 9000, 6000, 7000,
                3000, 4000, 10000, 13000, 5000, 0, 9000, 16000, 9000, 6000, 7000, 3000,
                4000, 10000, 13000, 5000, 0, 9000, 16000, 9000, 6000, 7000, 3000, 4000,
                10000, 13000, 5000, 0, 9000, 16000, 9000, 6000, 7000, 3000, 4000, 10000,
                13000, 5000, 0, 9000, 16000, 9000, 6000, 7000, 3000, 4000, 10000, 13000,
                5000, 0, 9000, 16000, 9000, 6000, 7000, 3000, 4000, 10000, 13000, 5000,
                0, 9000, 16000, 9000, 6000, 7000, 15000,
              ],
              lineColor: '#2196F3',
              scales: 'scale-x, scale-y-2',
            },
          ],
        };
    
        zingchart.render({
          id: 'myChart',
          data: chartConfig,
          width: '100%',
        });
    
        /**
         * As we are moving the guide, we want to update the items outside
         * of the chart. We could do this inside the chart, but since JS
         * is single threaded we don't want to block UI with a chart
         * update. A chart update is more expensive than a node update.
         * You may see no performance gains on a dataset this size, but
         * with some increase its possible to see a discrepancy for the
         * user. This is why I chose to contstruct the items outside
         * of the graph.
         */
        zingchart.guide_mousemove = (e) => {
          if (e['scale-label']) {
            document.getElementById('day').innerHTML =
              'Day: ' + e['scale-label']['scale-x'];
          }
        };
    
        /*********** Functions ***********/
    
        /**
         * ZingChart defined event listener. Will capture ZoomEvent and related
         * Zooming Information.
         */
        zingchart.zoom = (e) => {
          displayZoomValues(e.kmin, e.kmax);
        };
    
        /**
         * Apply dates to display current zoomed dates
         */
        let displayZoomValues = (sFrom, sTo) => {
          let dateFrom = document.getElementById('date-from');
          let dateTo = document.getElementById('date-to');
    
          // If viewall is clicked show the default dates
          if (!sFrom) {
            sFrom = '1/31/19';
          }
          if (!sTo) {
            sTo = '6/17/19';
          }
    
          dateFrom.innerHTML = sFrom;
          dateTo.innerHTML = sTo;
        };
    
        /**
         * Apply zoom to graph.
         */
        let zoomToIndex = (max) => {
          // ZingChart api automated zoom. Have to be careful
          // not to zoom past the end of the graph
          zingchart.exec('myChart', 'zoomto', {
            xmax: max,
            xmin: 0,
          });
        };
    
        /**
         * Capture the spans clicks with data-period attribute.
         */
        document
          .getElementById('date-picker-container')
          .addEventListener('click', (e) => {
            let target = e.target;
    
            // Only capture spans with data-period attribute
            if (target.dataset['period']) {
              // Toggle classes
              removeActiveClass();
              e.target.classList.toggle('active');
    
              switch (target.dataset['period']) {
                case '1':
                  zoomToIndex(30);
                  break;
                case '2':
                  zoomToIndex(60);
                  break;
                default:
                  zingchart.exec('myChart', 'viewall');
                  break;
              }
            }
          });
    
        let removeActiveClass = () => {
          let activeElement = document.querySelector('[data-period].active');
          activeElement.classList.toggle('active');
        };
      </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" class="chart--container">
        <div id="date-picker-container">
          <span data-period="1" class="active">30 Days</span>
          <span data-period="2">60 Days</span>
          <span data-period="3">90 Days</span>
          <div>
            <b>From:</b>
            <span id="date-from">1/31/19</span>
          </div>
          <div>
            <b>To:</b>
            <span id="date-to">6/17/19</span>
          </div>
          <div id="day"></div>
        </div>
        <div id="main-container">
          <a class="zc-ref" href="https://www.zingchart.com/">Powered by ZingChart</a>
        </div>
      </div>
    </body>
    
    </html>
    .zc-body {
      background-color: #FFF;
      font: 100%/1.5 'Helvetica Neue', 'Helvetica', 'Arial', sans-serif, 'Comic Sans';
    }
    
    .chart--container {
      background-color: #FFF;
      min-height: 530px;
      width: 100%;
      height: 100%;
    }
    
    #day {
      color: #2196F3;
    }
    
    #day {
      margin-top: 20px;
      margin-right: 20px;
      font-size: 25px;
      float: right;
    }
    
    #date-picker-container {
      margin-left: 25px;
    }
    
    [data-period] {
      margin: 5px;
      padding: 10px 10px;
      background-color: #2196F3;
      color: #FFF;
      display: inline-block;
    }
    
    [data-period]:hover {
      cursor: pointer;
      opacity: .7;
    }
    
    #date-picker-container div {
      display: inline-block;
    }
    
    #date-from,
    #date-to {
      margin-right: 6px;
      margin-left: 6px;
      color: #2196F3;
    }
    
    .active {
      background: #fd992b;
    }
    
    .zc-ref {
      display: none;
    }
    let chartConfig = {
      type: 'mixed',
      title: {
        text: 'Projected Cash Flow',
        align: 'center',
      },
      plot: {
        tooltip: {
          visible: false,
        },
        aspect: 'spline',
        marker: {
          visible: false,
        },
      },
      plotarea: {},
      scaleX: {
        values: [
          '1/31/19',
          '2/10/19',
          '2/11/19',
          '2/12/19',
          '2/13/19',
          '2/19/19',
          '2/18/19',
          '2/19/19',
          '2/20/19',
          '2/21/19',
          '2/24/19',
          '2/25/19',
          '2/26/19',
          '2/27/19',
          '2/28/19',
          '2/3/19',
          '2/4/19',
          '2/5/19',
          '2/6/19',
          '2/7/19',
          '3/10/19',
          '3/11/19',
          '3/12/19',
          '3/13/19',
          '3/14/19',
          '3/17/19',
          '3/18/19',
          '3/19/19',
          '3/20/19',
          '3/21/19',
          '3/24/19',
          '3/25/19',
          '3/26/19',
          '3/27/19',
          '3/28/19',
          '3/3/19',
          '3/31/19',
          '3/4/19',
          '3/5/19',
          '3/6/19',
          '3/7/19',
          '4/1/19',
          '4/10/19',
          '4/11/19',
          '4/14/19',
          '4/15/19',
          '4/16/19',
          '4/17/19',
          '4/2/19',
          '4/21/19',
          '4/22/19',
          '4/23/19',
          '4/24/19',
          '4/25/19',
          '4/28/19',
          '4/29/19',
          '4/3/19',
          '4/30/19',
          '4/4/19',
          '4/7/19',
          '4/8/19',
          '4/9/19',
          '5/1/19',
          '5/12/19',
          '5/13/19',
          '5/14/19',
          '5/15/19',
          '5/16/19',
          '5/19/19',
          '5/20/19',
          '5/21/19',
          '5/22/19',
          '5/23/19',
          '5/27/19',
          '5/28/19',
          '5/29/19',
          '5/30/19',
          '5/5/19',
          '5/6/19',
          '5/7/19',
          '5/8/19',
          '5/9/19',
          '6/10/19',
          '6/11/19',
          '6/12/19',
          '6/13/19',
          '6/16/19',
          '6/17/19',
        ],
        itemsOverlap: true,
        lineWidth: '0px',
        tick: {
          alpha: 1,
          lineColor: '#2196F3',
          lineWidth: '2px',
        },
        zooming: true,
        zoomTo: [0, 30],
      },
      scaleY: {
        values: '0:20000:1000',
        guide: {
          visible: false,
        },
      },
      scaleY2: {},
      crosshairX: {
        lineColor: '#2196F3',
        lineStyle: 'dashed',
        lineWidth: '2px',
        marker: {
          type: 'triangle',
          size: '5px',
          visible: true,
        },
        plotLabel: {
          visible: false,
        },
      },
      preview: {
        live: true,
      },
      series: [{
          type: 'bar',
          values: [
            4000, 10000, 5000, 2000, 6000, 10000, 15000, 8000, 3000, 7000, 13000,
            4000, 10000, 5000, 2000, 6000, 10000, 15000, 8000, 3000, 7000, 13000,
            4000, 10000, 5000, 2000, 6000, 10000, 15000, 8000, 3000, 7000, 13000,
            4000, 10000, 5000, 2000, 6000, 10000, 15000, 8000, 3000, 7000, 13000,
            4000, 10000, 5000, 2000, 6000, 10000, 15000, 8000, 3000, 7000, 13000,
            4000, 10000, 5000, 2000, 6000, 10000, 15000, 8000, 3000, 7000, 13000,
            4000, 10000, 5000, 2000, 6000, 10000, 15000, 8000, 3000, 7000, 13000,
            4000, 10000, 5000, 2000, 6000, 10000, 15000, 8000, 3000, 7000, 13000,
            8000, 0, 5000,
          ],
          backgroundColor: '#FFEB3B',
          scales: 'scale-x, scale-y-2',
        },
        {
          type: 'line',
          values: [
            6000, 7000, 3000, 4000, 10000, 13000, 5000, 0, 9000, 16000, 9000, 6000,
            7000, 3000, 4000, 10000, 13000, 5000, 0, 9000, 16000, 9000, 6000, 7000,
            3000, 4000, 10000, 13000, 5000, 0, 9000, 16000, 9000, 6000, 7000, 3000,
            4000, 10000, 13000, 5000, 0, 9000, 16000, 9000, 6000, 7000, 3000, 4000,
            10000, 13000, 5000, 0, 9000, 16000, 9000, 6000, 7000, 3000, 4000, 10000,
            13000, 5000, 0, 9000, 16000, 9000, 6000, 7000, 3000, 4000, 10000, 13000,
            5000, 0, 9000, 16000, 9000, 6000, 7000, 3000, 4000, 10000, 13000, 5000,
            0, 9000, 16000, 9000, 6000, 7000, 15000,
          ],
          lineColor: '#2196F3',
          scales: 'scale-x, scale-y-2',
        },
      ],
    };
    
    zingchart.render({
      id: 'myChart',
      data: chartConfig,
      width: '100%',
    });
    
    /**
     * As we are moving the guide, we want to update the items outside
     * of the chart. We could do this inside the chart, but since JS
     * is single threaded we don't want to block UI with a chart
     * update. A chart update is more expensive than a node update.
     * You may see no performance gains on a dataset this size, but
     * with some increase its possible to see a discrepancy for the
     * user. This is why I chose to contstruct the items outside
     * of the graph.
     */
    zingchart.guide_mousemove = (e) => {
      if (e['scale-label']) {
        document.getElementById('day').innerHTML =
          'Day: ' + e['scale-label']['scale-x'];
      }
    };
    
    /*********** Functions ***********/
    
    /**
     * ZingChart defined event listener. Will capture ZoomEvent and related
     * Zooming Information.
     */
    zingchart.zoom = (e) => {
      displayZoomValues(e.kmin, e.kmax);
    };
    
    /**
     * Apply dates to display current zoomed dates
     */
    let displayZoomValues = (sFrom, sTo) => {
      let dateFrom = document.getElementById('date-from');
      let dateTo = document.getElementById('date-to');
    
      // If viewall is clicked show the default dates
      if (!sFrom) {
        sFrom = '1/31/19';
      }
      if (!sTo) {
        sTo = '6/17/19';
      }
    
      dateFrom.innerHTML = sFrom;
      dateTo.innerHTML = sTo;
    };
    
    /**
     * Apply zoom to graph.
     */
    let zoomToIndex = (max) => {
      // ZingChart api automated zoom. Have to be careful
      // not to zoom past the end of the graph
      zingchart.exec('myChart', 'zoomto', {
        xmax: max,
        xmin: 0,
      });
    };
    
    /**
     * Capture the spans clicks with data-period attribute.
     */
    document
      .getElementById('date-picker-container')
      .addEventListener('click', (e) => {
        let target = e.target;
    
        // Only capture spans with data-period attribute
        if (target.dataset['period']) {
          // Toggle classes
          removeActiveClass();
          e.target.classList.toggle('active');
    
          switch (target.dataset['period']) {
            case '1':
              zoomToIndex(30);
              break;
            case '2':
              zoomToIndex(60);
              break;
            default:
              zingchart.exec('myChart', 'viewall');
              break;
          }
        }
      });
    
    let removeActiveClass = () => {
      let activeElement = document.querySelector('[data-period].active');
      activeElement.classList.toggle('active');
    };