Example usage for org.jfree.data.xy DefaultHighLowDataset getLowValue

List of usage examples for org.jfree.data.xy DefaultHighLowDataset getLowValue

Introduction

In this page you can find the example usage for org.jfree.data.xy DefaultHighLowDataset getLowValue.

Prototype

@Override
public double getLowValue(int series, int item) 

Source Link

Document

Returns the low-value (as a double primitive) for an item within a series.

Usage

From source file:org.yccheok.jstock.gui.charting.ChartJDialog.java

/**
 * Zoom in to this chart with specific amount of time.
 * @param field the calendar field.//from  ww  w  .  j  a  va  2s. c om
 * @param amount the amount of date or time to be added to the field.
 */
private void _zoom(int field, int amount) {
    this.chartPanel.restoreAutoBounds();

    final int itemCount = this.priceTimeSeries.getItemCount();
    final Day day = (Day) this.priceTimeSeries.getDataItem(itemCount - 1).getPeriod();
    // Candle stick takes up half day space.
    // Volume price chart's volume information takes up whole day space.
    final long end = day.getFirstMillisecond()
            + (this.getCurrentType() == Type.Candlestick ? (1000 * 60 * 60 * 12) : (1000 * 60 * 60 * 24 - 1));
    final Calendar calendar = Calendar.getInstance();
    // -1. Calendar's month is 0 based but JFreeChart's month is 1 based.
    calendar.set(day.getYear(), day.getMonth() - 1, day.getDayOfMonth(), 0, 0, 0);
    calendar.set(Calendar.MILLISECOND, 0);

    calendar.add(field, amount);
    // Candle stick takes up half day space.
    // Volume price chart's volume information does not take up any space.
    final long start = Math.max(0, calendar.getTimeInMillis()
            - (this.getCurrentType() == Type.Candlestick ? (1000 * 60 * 60 * 12) : 0));
    final ValueAxis valueAxis = this.getPlot().getDomainAxis();

    if (priceTimeSeries.getItemCount() > 0) {
        if (start < priceTimeSeries.getTimePeriod(0).getFirstMillisecond()) {
            // To prevent zoom-out too much.
            // This happens when user demands for 10 years zoom, where we
            // are only having 5 years data.
            return;
        }
    }

    valueAxis.setRange(start, end);

    double min = Double.MAX_VALUE;
    double max = Double.MIN_VALUE;
    double max_volume = Double.MIN_VALUE;
    final DefaultHighLowDataset defaultHighLowDataset = (DefaultHighLowDataset) this.priceOHLCDataset;

    for (int i = itemCount - 1; i >= 0; i--) {
        final TimeSeriesDataItem item = this.priceTimeSeries.getDataItem(i);
        final Day d = (Day) item.getPeriod();
        if (d.getFirstMillisecond() < start) {
            break;
        }

        final double high = defaultHighLowDataset.getHighValue(0, i);
        final double low = defaultHighLowDataset.getLowValue(0, i);
        final double volume = defaultHighLowDataset.getVolumeValue(0, i);

        if (max < high) {
            max = high;
        }
        if (min > low) {
            min = low;
        }
        if (max_volume < volume) {
            max_volume = volume;
        }
    }

    if (min > max) {
        return;
    }

    final ValueAxis rangeAxis = this.getPlot().getRangeAxis();
    final Range rangeAxisRange = rangeAxis.getRange();
    // Increase each side by 1%
    double tolerance = 0.01 * (max - min);
    // The tolerance must within range [0.01, 1.0]
    tolerance = Math.min(Math.max(0.01, tolerance), 1.0);
    // The range must within the original chart range.
    min = Math.max(rangeAxisRange.getLowerBound(), min - tolerance);
    max = Math.min(rangeAxisRange.getUpperBound(), max + tolerance);

    this.getPlot().getRangeAxis().setRange(min, max);

    if (this.getPlot().getRangeAxisCount() > 1) {
        final double volumeUpperBound = this.getPlot().getRangeAxis(1).getRange().getUpperBound();
        final double suggestedVolumneUpperBound = max_volume * 4;
        // To prevent over zoom-in.
        if (suggestedVolumneUpperBound < volumeUpperBound) {
            this.getPlot().getRangeAxis(1).setRange(0, suggestedVolumneUpperBound);
        }
    }
}

From source file:org.yccheok.jstock.gui.charting.ChartJDialog.java

/**
 * Calculate and update high low value labels, according to current displayed
 * time range. This is a time consuming method, and shall be called by
 * user thread.//  w  w  w .  jav  a2s .c  o  m
 */
private void _updateHighLowJLabels() {
    SwingUtilities.invokeLater(new Runnable() {
        @Override
        public void run() {
            ChartJDialog.this.jLabel2.setText("");
            ChartJDialog.this.jLabel4.setText("");
        }
    });

    final ValueAxis valueAxis = this.getPlot().getDomainAxis();
    final Range range = valueAxis.getRange();
    final long lowerBound = (long) range.getLowerBound();
    final long upperBound = (long) range.getUpperBound();

    // Perform binary search, to located day in price time series, which
    // is equal or lesser than upperBound.
    int low = 0;
    int high = this.priceTimeSeries.getItemCount() - 1;
    long best_dist = Long.MAX_VALUE;
    int best_mid = -1;
    while (low <= high) {
        int mid = (low + high) >>> 1;
        final Day day = (Day) this.priceTimeSeries.getDataItem(mid).getPeriod();
        long v = day.getFirstMillisecond();

        if (v > upperBound) {
            high = mid - 1;
        } else if (v < upperBound) {
            low = mid + 1;
            long dist = upperBound - v;
            if (dist < best_dist) {
                best_dist = dist;
                best_mid = mid;
            }
        } else {
            best_dist = 0;
            best_mid = mid;
            break;
        }
    }

    if (best_mid < 0) {
        return;
    }

    double high_price = -Double.MAX_VALUE;
    double low_price = Double.MAX_VALUE;
    final DefaultHighLowDataset defaultHighLowDataset = (DefaultHighLowDataset) this.priceOHLCDataset;
    for (int i = best_mid; i >= 0; i--) {
        final TimeSeriesDataItem item = this.priceTimeSeries.getDataItem(i);
        final long time = ((Day) item.getPeriod()).getFirstMillisecond();
        if (time < lowerBound) {
            break;
        }

        final double _high_price = defaultHighLowDataset.getHighValue(0, i);
        final double _low_price = defaultHighLowDataset.getLowValue(0, i);
        final double _last_price = defaultHighLowDataset.getCloseValue(0, i);

        high_price = Math.max(high_price, _high_price);

        // Prevent bad data.
        if (_low_price > 0) {
            low_price = Math.min(low_price, _low_price);
        } else {
            if (_high_price > 0) {
                low_price = Math.min(low_price, _high_price);
            }
            if (_last_price > 0) {
                low_price = Math.min(low_price, _last_price);
            }
        }
    }

    final double h = high_price;
    final double l = low_price;
    if (high_price >= low_price) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                ChartJDialog.this.jLabel2.setText(org.yccheok.jstock.gui.Utils.stockPriceDecimalFormat(h));
                ChartJDialog.this.jLabel4.setText(org.yccheok.jstock.gui.Utils.stockPriceDecimalFormat(l));
            }
        });
    }
}