/**
   * Construct a new CandleStickChart with the given axis.
   *
   * @param title The chart title
   * @param xAxis The x axis to use
   * @param yAxis The y axis to use
   * @param bars The bars to display on the chart
   * @param maxBarsToDisplay The maximum number of bars to display on the chart.
   */
  public CandleStickChart(
      String title,
      CategoryAxis xAxis,
      NumberAxis yAxis,
      List<BarData> bars,
      int maxBarsToDisplay) {
    super(xAxis, yAxis);
    this.xAxis = xAxis;
    this.yAxis = yAxis;
    this.maxBarsToDisplay = maxBarsToDisplay;

    yAxis.autoRangingProperty().set(true);
    yAxis.forceZeroInRangeProperty().setValue(Boolean.FALSE);
    setTitle(title);
    setAnimated(true);
    getStylesheets()
        .add(getClass().getResource("/styles/CandleStickChartStyles.css").toExternalForm());
    xAxis.setAnimated(true);
    yAxis.setAnimated(true);
    verticalGridLinesVisibleProperty().set(false);
    XYChart.Series<String, Number> series = new XYChart.Series<>();
    List<BarData> sublist = getSubList(bars, maxBarsToDisplay);
    for (BarData bar : sublist) {
      String label = "";
      label = sdf.format(bar.getDateTime().getTime());
      series.getData().add(new XYChart.Data<>(label, bar.getOpen(), bar));
      logger.log(Level.INFO, "Adding bar with date/time: {0}", bar.getDateTime().getTime());
      logger.log(Level.INFO, "Adding bar with price: {0}", bar.getOpen());
    }

    dataSeries = FXCollections.observableArrayList(series);

    setData(dataSeries);
    lastBar = sublist.get(sublist.size() - 1);
  }
  /**
   * Appends a new bar on to the end of the chart.
   *
   * @param bar The bar to append to the chart
   */
  public void addBar(BarData bar) {

    if (dataSeries.get(0).getData().size() >= maxBarsToDisplay) {
      dataSeries.get(0).getData().remove(0);
    }

    int datalength = dataSeries.get(0).getData().size();
    dataSeries.get(0).getData().get(datalength - 1).setYValue(bar.getOpen());
    dataSeries.get(0).getData().get(datalength - 1).setExtraValue(bar);
    String label = sdf.format(bar.getDateTime().getTime());
    logger.log(Level.INFO, "Adding bar with actual time:  {0}", bar.getDateTime().getTime());
    logger.log(Level.INFO, "Adding bar with formated time: {0}", label);

    lastBar =
        new BarData(
            bar.getDateTime(), bar.getClose(), bar.getClose(), bar.getClose(), bar.getClose(), 0);
    Data<String, Number> data = new XYChart.Data<>(label, lastBar.getOpen(), lastBar);
    dataSeries.get(0).getData().add(data);
  }
  /**
   * Update the "Last" price of the most recent bar
   *
   * @param price The Last price of the most recent bar.
   */
  public void updateLast(double price) {
    if (lastBar != null) {
      lastBar.update(price);
      logger.log(
          Level.INFO, "Updating last bar with date/time: {0}", lastBar.getDateTime().getTime());

      int datalength = dataSeries.get(0).getData().size();
      dataSeries.get(0).getData().get(datalength - 1).setYValue(lastBar.getOpen());

      dataSeries.get(0).getData().get(datalength - 1).setExtraValue(lastBar);
      logger.log(
          Level.INFO,
          "Updating last bar with formatteddate/time: {0}",
          dataSeries.get(0).getData().get(datalength - 1).getXValue());
    }
  }