Example usage for org.jfree.data.xy XYDataset getXValue

List of usage examples for org.jfree.data.xy XYDataset getXValue

Introduction

In this page you can find the example usage for org.jfree.data.xy XYDataset getXValue.

Prototype

public double getXValue(int series, int item);

Source Link

Document

Returns the x-value for an item within a series.

Usage

From source file:org.jfree.data.general.DatasetUtilities.java

/**
 * Returns the interpolated value of y that corresponds to the specified
 * x-value in the given series.  If the x-value falls outside the range of
 * x-values for the dataset, this method returns <code>Double.NaN</code>.
 * // ww w.  j  ava  2  s .  co  m
 * @param dataset  the dataset (<code>null</code> not permitted).
 * @param series  the series index.
 * @param x  the x-value.
 * 
 * @return The y value.
 * 
 * @since 1.0.16
 */
public static double findYValue(XYDataset dataset, int series, double x) {
    // delegate null check on dataset
    int[] indices = findItemIndicesForX(dataset, series, x);
    if (indices[0] == -1) {
        return Double.NaN;
    }
    if (indices[0] == indices[1]) {
        return dataset.getYValue(series, indices[0]);
    }
    double x0 = dataset.getXValue(series, indices[0]);
    double x1 = dataset.getXValue(series, indices[1]);
    double y0 = dataset.getYValue(series, indices[0]);
    double y1 = dataset.getYValue(series, indices[1]);
    return y0 + (y1 - y0) * (x - x0) / (x1 - x0);
}

From source file:org.jfree.data.general.DatasetUtilities.java

/**
 * Finds the indices of the the items in the dataset that span the 
 * specified x-value.  There are three cases for the return value:
 * <ul>/*from   ww w . j  a va  2  s.com*/
 * <li>there is an exact match for the x-value at index i 
 * (returns <code>int[] {i, i}</code>);</li>
 * <li>the x-value falls between two (adjacent) items at index i and i+1 
 * (returns <code>int[] {i, i+1}</code>);</li>
 * <li>the x-value falls outside the domain bounds, in which case the 
 *    method returns <code>int[] {-1, -1}</code>.</li>
 * </ul>
 * @param dataset  the dataset (<code>null</code> not permitted).
 * @param series  the series index.
 * @param x  the x-value.
 *
 * @return The indices of the two items that span the x-value.
 *
 * @since 1.0.16
 * 
 * @see #findYValue(org.jfree.data.xy.XYDataset, int, double) 
 */
public static int[] findItemIndicesForX(XYDataset dataset, int series, double x) {
    ParamChecks.nullNotPermitted(dataset, "dataset");
    int itemCount = dataset.getItemCount(series);
    if (itemCount == 0) {
        return new int[] { -1, -1 };
    }
    if (itemCount == 1) {
        if (x == dataset.getXValue(series, 0)) {
            return new int[] { 0, 0 };
        } else {
            return new int[] { -1, -1 };
        }
    }
    if (dataset.getDomainOrder() == DomainOrder.ASCENDING) {
        int low = 0;
        int high = itemCount - 1;
        double lowValue = dataset.getXValue(series, low);
        if (lowValue > x) {
            return new int[] { -1, -1 };
        }
        if (lowValue == x) {
            return new int[] { low, low };
        }
        double highValue = dataset.getXValue(series, high);
        if (highValue < x) {
            return new int[] { -1, -1 };
        }
        if (highValue == x) {
            return new int[] { high, high };
        }
        int mid = (low + high) / 2;
        while (high - low > 1) {
            double midV = dataset.getXValue(series, mid);
            if (x == midV) {
                return new int[] { mid, mid };
            }
            if (midV < x) {
                low = mid;
            } else {
                high = mid;
            }
            mid = (low + high) / 2;
        }
        return new int[] { low, high };
    } else if (dataset.getDomainOrder() == DomainOrder.DESCENDING) {
        int high = 0;
        int low = itemCount - 1;
        double lowValue = dataset.getXValue(series, low);
        if (lowValue > x) {
            return new int[] { -1, -1 };
        }
        double highValue = dataset.getXValue(series, high);
        if (highValue < x) {
            return new int[] { -1, -1 };
        }
        int mid = (low + high) / 2;
        while (high - low > 1) {
            double midV = dataset.getXValue(series, mid);
            if (x == midV) {
                return new int[] { mid, mid };
            }
            if (midV < x) {
                low = mid;
            } else {
                high = mid;
            }
            mid = (low + high) / 2;
        }
        return new int[] { low, high };
    } else {
        // we don't know anything about the ordering of the x-values,
        // so we iterate until we find the first crossing of x (if any)
        // we know there are at least 2 items in the series at this point
        double prev = dataset.getXValue(series, 0);
        if (x == prev) {
            return new int[] { 0, 0 }; // exact match on first item
        }
        for (int i = 1; i < itemCount; i++) {
            double next = dataset.getXValue(series, i);
            if (x == next) {
                return new int[] { i, i }; // exact match
            }
            if ((x > prev && x < next) || (x < prev && x > next)) {
                return new int[] { i - 1, i }; // spanning match
            }
        }
        return new int[] { -1, -1 }; // no crossing of x
    }
}

From source file:edu.dlnu.liuwenpeng.render.XYLineAndShapeRenderer.java

/**    
 * Draws the item (first pass). This method draws the lines    
 * connecting the items. Instead of drawing separate lines,    
 * a GeneralPath is constructed and drawn at the end of    
 * the series painting.    // w w w. ja  v a2 s .c  o  m
 *    
 * @param g2  the graphics device.    
 * @param state  the renderer state.    
 * @param plot  the plot (can be used to obtain standard color information    
 *              etc).    
 * @param dataset  the dataset.    
 * @param pass  the pass.    
 * @param series  the series index (zero-based).    
 * @param item  the item index (zero-based).    
 * @param domainAxis  the domain axis.    
 * @param rangeAxis  the range axis.    
 * @param dataArea  the area within which the data is being drawn.    
 */
protected void drawPrimaryLineAsPath(XYItemRendererState state, Graphics2D g2, XYPlot plot, XYDataset dataset,
        int pass, int series, int item, ValueAxis domainAxis, ValueAxis rangeAxis, Rectangle2D dataArea) {

    RectangleEdge xAxisLocation = plot.getDomainAxisEdge();
    RectangleEdge yAxisLocation = plot.getRangeAxisEdge();

    // get the data point...    
    double x1 = dataset.getXValue(series, item);
    double y1 = dataset.getYValue(series, item);
    double transX1 = domainAxis.valueToJava2D(x1, dataArea, xAxisLocation);
    double transY1 = rangeAxis.valueToJava2D(y1, dataArea, yAxisLocation);

    State s = (State) state;
    // update path to reflect latest point    
    if (!Double.isNaN(transX1) && !Double.isNaN(transY1)) {
        float x = (float) transX1;
        float y = (float) transY1;
        PlotOrientation orientation = plot.getOrientation();
        if (orientation == PlotOrientation.HORIZONTAL) {
            x = (float) transY1;
            y = (float) transX1;
        }
        if (s.isLastPointGood()) {
            s.seriesPath.lineTo(x, y);
        } else {
            s.seriesPath.moveTo(x, y);
        }
        s.setLastPointGood(true);
    } else {
        s.setLastPointGood(false);
    }
    // if this is the last item, draw the path ...    
    if (item == dataset.getItemCount(series) - 1) {
        // draw path    
        drawFirstPassShape(g2, pass, series, item, s.seriesPath);
    }
}

From source file:edu.dlnu.liuwenpeng.render.XYLineAndShapeRenderer.java

/**    
 * Draws the item shapes and adds chart entities (second pass). This method    
 * draws the shapes which mark the item positions. If <code>entities</code>    
 * is not <code>null</code> it will be populated with entity information    
 * for points that fall within the data area.    
 *    //from w  w w  .j a v a2  s .  c o  m
 * @param g2  the graphics device.    
 * @param plot  the plot (can be used to obtain standard color    
 *              information etc).    
 * @param domainAxis  the domain axis.    
 * @param dataArea  the area within which the data is being drawn.    
 * @param rangeAxis  the range axis.    
 * @param dataset  the dataset.    
 * @param pass  the pass.    
 * @param series  the series index (zero-based).    
 * @param item  the item index (zero-based).    
 * @param crosshairState  the crosshair state.    
 * @param entities the entity collection.    
 */
protected void drawSecondaryPass(Graphics2D g2, XYPlot plot, XYDataset dataset, int pass, int series, int item,
        ValueAxis domainAxis, Rectangle2D dataArea, ValueAxis rangeAxis, CrosshairState crosshairState,
        EntityCollection entities) {

    Shape entityArea = null;

    // get the data point...    
    double x1 = dataset.getXValue(series, item);
    double y1 = dataset.getYValue(series, item);
    if (Double.isNaN(y1) || Double.isNaN(x1)) {
        return;
    }

    PlotOrientation orientation = plot.getOrientation();
    RectangleEdge xAxisLocation = plot.getDomainAxisEdge();
    RectangleEdge yAxisLocation = plot.getRangeAxisEdge();
    double transX1 = domainAxis.valueToJava2D(x1, dataArea, xAxisLocation);
    double transY1 = rangeAxis.valueToJava2D(y1, dataArea, yAxisLocation);

    if (getItemShapeVisible(series, item)) {
        Shape shape = getItemShape(series, item);
        if (orientation == PlotOrientation.HORIZONTAL) {
            shape = ShapeUtilities.createTranslatedShape(shape, transY1, transX1);
        } else if (orientation == PlotOrientation.VERTICAL) {
            shape = ShapeUtilities.createTranslatedShape(shape, transX1, transY1);
        }
        entityArea = shape;
        if (shape.intersects(dataArea)) {
            if (getItemShapeFilled(series, item)) {
                if (this.useFillPaint) {
                    g2.setPaint(getItemFillPaint(series, item));
                } else {
                    g2.setPaint(getItemPaint(series, item));
                }
                //g2.fill(shape);    
            }
            if (this.drawOutlines) {
                if (getUseOutlinePaint()) {
                    g2.setPaint(getItemOutlinePaint(series, item));
                } else {
                    g2.setPaint(getItemPaint(series, item));
                }
                g2.setStroke(getItemOutlineStroke(series, item));
                // g2.draw(shape);    
            }
        }
    }

    double xx = transX1;
    double yy = transY1;
    if (orientation == PlotOrientation.HORIZONTAL) {
        xx = transY1;
        yy = transX1;
    }

    // draw the item label if there is one...    
    if (isItemLabelVisible(series, item)) {
        drawItemLabel(g2, orientation, dataset, series, item, xx, yy, (y1 < 0.0));
    }

    int domainAxisIndex = plot.getDomainAxisIndex(domainAxis);
    int rangeAxisIndex = plot.getRangeAxisIndex(rangeAxis);
    updateCrosshairValues(crosshairState, x1, y1, domainAxisIndex, rangeAxisIndex, transX1, transY1,
            orientation);

    // add an entity for the item, but only if it falls within the data    
    // area...    
    if (entities != null && isPointInRect(dataArea, xx, yy)) {
        addEntity(entities, entityArea, dataset, series, item, xx, yy);
    }
}

From source file:com.att.aro.ui.view.diagnostictab.GraphPanel.java

@Override
public void chartMouseClicked(ChartMouseEvent chartmouseevent) {
    Point2D point = chartmouseevent.getTrigger().getPoint();
    Rectangle2D plotArea = getChartPanel().getScreenDataArea();

    XYPlot plot = (XYPlot) getAdvancedGraph().getPlot();
    final double lastChartX = new Double(
            plot.getDomainAxis().java2DToValue(point.getX(), plotArea, plot.getDomainAxisEdge()));

    // setCrossHair(lastChartX);

    // SwingUtilities.invokeLater(new Runnable() {
    // @Override/*from   w w w.j  a v a 2 s .  c o m*/
    // public void run() {
    // setCrossHair(lastChartX);
    // }
    // });

    for (GraphPanelListener gpl : listeners) {
        gpl.graphPanelClicked(lastChartX);

        /* New added @Tinbit */
        ChartEntity entity = chartmouseevent.getEntity();

        if (entity instanceof XYItemEntity) {
            XYItemEntity xyItem = (XYItemEntity) entity;

            XYDataset xyDataset = xyItem.getDataset();
            int seriesIndex = xyItem.getSeriesIndex();
            int itemIndex = xyItem.getItem();

            double xDataValue = xyDataset.getXValue(seriesIndex, itemIndex);
            double yDataValue = xyDataset.getYValue(seriesIndex, itemIndex);

            Map<Integer, VideoEvent> veSegment = vcPlot.getChunk(xDataValue);
            int indexKey = 0;
            if (vcPlot.isDataItemPoint(xDataValue, yDataValue)) {

                if (veSegment != null) {

                    for (int key : veSegment.keySet()) {
                        // String value="Chunk "+(key+1)+" at
                        // "+String.format("%.2f",
                        // veSegment.get(key).getDLTimeStamp())+"S";
                        chunkInfo.put(key, veSegment.get(key));
                        // chunkInfo.add(value);
                    }
                    indexKey = (int) veSegment.keySet().toArray()[0];
                }

                launchSliderDialog(indexKey);

            } else if (vcPlot.getBufferTimePlot().isDataItemStallPoint(xDataValue, yDataValue) != null) {
                VideoEvent segmentToPlay = vcPlot.getBufferTimePlot().isDataItemStallPoint(xDataValue,
                        yDataValue);
                veSegment = vcPlot.getSegmentToPlayLocation(segmentToPlay);
                if (veSegment != null) {
                    for (int key : veSegment.keySet()) {
                        chunkInfo.put(key, veSegment.get(key));
                    }
                    indexKey = (int) veSegment.keySet().toArray()[0];
                }
                launchSliderDialog(indexKey);
            }
        }
    }
}

From source file:org.jfree.experimental.chart.renderer.xy.VectorRenderer.java

/**
 * Returns the lower and upper bounds (range) of the x-values in the 
 * specified dataset.// ww w  . j  a v a  2  s  . c  o  m
 * 
 * @param dataset  the dataset (<code>null</code> permitted).
 * 
 * @return The range (<code>null</code> if the dataset is <code>null</code>
 *         or empty).
 */
public Range findDomainBounds(XYDataset dataset) {
    if (dataset == null) {
        throw new IllegalArgumentException("Null 'dataset' argument.");
    }
    double minimum = Double.POSITIVE_INFINITY;
    double maximum = Double.NEGATIVE_INFINITY;
    int seriesCount = dataset.getSeriesCount();
    double lvalue;
    double uvalue;
    if (dataset instanceof VectorXYDataset) {
        VectorXYDataset vdataset = (VectorXYDataset) dataset;
        for (int series = 0; series < seriesCount; series++) {
            int itemCount = dataset.getItemCount(series);
            for (int item = 0; item < itemCount; item++) {
                double delta = vdataset.getDeltaXValue(series, item);
                if (delta < 0.0) {
                    uvalue = vdataset.getXValue(series, item);
                    lvalue = uvalue + delta;
                } else {
                    lvalue = vdataset.getXValue(series, item);
                    uvalue = lvalue + delta;
                }
                minimum = Math.min(minimum, lvalue);
                maximum = Math.max(maximum, uvalue);
            }
        }
    } else {
        for (int series = 0; series < seriesCount; series++) {
            int itemCount = dataset.getItemCount(series);
            for (int item = 0; item < itemCount; item++) {
                lvalue = dataset.getXValue(series, item);
                uvalue = lvalue;
                minimum = Math.min(minimum, lvalue);
                maximum = Math.max(maximum, uvalue);
            }
        }
    }
    if (minimum > maximum) {
        return null;
    } else {
        return new Range(minimum, maximum);
    }
}

From source file:com.att.aro.diagnostics.GraphPanel.java

private static void populateScreenStatePlot(XYPlot plot, TraceData.Analysis analysis) {

    final XYIntervalSeriesCollection screenData = new XYIntervalSeriesCollection();
    if (analysis != null) {

        XYIntervalSeries series = new XYIntervalSeries(ScreenState.SCREEN_ON);
        screenData.addSeries(series);/*from   w  w w. j a v a  2s.  c o m*/

        // Populate the data set
        final Map<Double, ScreenStateInfo> dataMap = new HashMap<Double, ScreenStateInfo>();
        Iterator<ScreenStateInfo> iter = analysis.getScreenStateInfos().iterator();
        if (iter.hasNext()) {
            while (iter.hasNext()) {
                ScreenStateInfo screenEvent = iter.next();
                if (screenEvent.getScreenState() == ScreenState.SCREEN_ON) {
                    series.add(screenEvent.getBeginTimeStamp(), screenEvent.getBeginTimeStamp(),
                            screenEvent.getEndTimeStamp(), 0.5, 0, 1);
                    dataMap.put(screenEvent.getBeginTimeStamp(), screenEvent);
                }
            }
        }

        // Assign ToolTip to renderer
        XYItemRenderer renderer = plot.getRenderer();
        renderer.setBaseToolTipGenerator(new XYToolTipGenerator() {

            @Override
            public String generateToolTip(XYDataset dataset, int series, int item) {

                ScreenStateInfo si = dataMap.get(dataset.getXValue(series, item));
                if (si != null) {

                    StringBuffer displayInfo = new StringBuffer(rb.getString("screenstate.tooltip.prefix"));
                    int timeout = si.getScreenTimeout();
                    displayInfo.append(MessageFormat.format(rb.getString("screenstate.tooltip.content"),
                            ResourceBundleManager.getEnumString(si.getScreenState()), si.getScreenBrightness(),
                            timeout > 0 ? timeout : rb.getString("screenstate.noTimeout")));
                    displayInfo.append(rb.getString("screenstate.tooltip.suffix"));
                    return displayInfo.toString();
                }
                return null;
            }
        });
    }

    plot.setDataset(screenData);
}

From source file:com.att.aro.diagnostics.GraphPanel.java

/**
 * Creating Wakelock state for graph plot
 *//*from   w ww  .  j ava2  s .  c  om*/
private static void populateWakelockStatePlot(XYPlot plot, TraceData.Analysis analysis) {

    final XYIntervalSeriesCollection wakelockData = new XYIntervalSeriesCollection();
    if (analysis != null) {

        XYIntervalSeries series = new XYIntervalSeries(WakelockState.WAKELOCK_ACQUIRED);
        wakelockData.addSeries(series);

        // Populate the data set
        final Map<Double, WakelockInfo> dataMap = new HashMap<Double, WakelockInfo>();
        Iterator<WakelockInfo> iter = analysis.getWakelockInfos().iterator();
        if (iter.hasNext()) {
            WakelockInfo lastEvent = iter.next();
            logger.fine("Wakelock Plotting");
            // Check whether WAKELOCK was acquired before logging begins.
            if (lastEvent.getWakelockState() == WakelockState.WAKELOCK_RELEASED) {
                series.add(0, 0, lastEvent.getBeginTimeStamp(), 0.5, 0, 1);
                dataMap.put(lastEvent.getBeginTimeStamp(), lastEvent);
            }
            while (iter.hasNext()) {
                WakelockInfo currEvent = iter.next();
                if (lastEvent.getWakelockState() == WakelockState.WAKELOCK_ACQUIRED) {
                    logger.fine("Wakelock acquired curr " + currEvent.getBeginTimeStamp());
                    logger.fine("Wakelock acquired last " + lastEvent.getBeginTimeStamp());
                    series.add(lastEvent.getBeginTimeStamp(), lastEvent.getBeginTimeStamp(),
                            currEvent.getBeginTimeStamp(), 0.5, 0, 1);
                    dataMap.put(lastEvent.getBeginTimeStamp(), lastEvent);
                }
                lastEvent = currEvent;
            }
            if (lastEvent.getWakelockState() == WakelockState.WAKELOCK_ACQUIRED) {
                series.add(lastEvent.getBeginTimeStamp(), lastEvent.getBeginTimeStamp(),
                        analysis.getTraceData().getTraceDuration(), 0.5, 0, 1);
                dataMap.put(lastEvent.getBeginTimeStamp(), lastEvent);
            }
        }

        // Assign ToolTip to renderer
        XYItemRenderer renderer = plot.getRenderer();
        renderer.setBaseToolTipGenerator(new XYToolTipGenerator() {

            @Override
            public String generateToolTip(XYDataset dataset, int series, int item) {

                WakelockInfo wi = dataMap.get(dataset.getXValue(series, item));
                if (wi != null) {

                    StringBuffer displayInfo = new StringBuffer(rb.getString("wakelock.tooltip.prefix"));
                    displayInfo.append(MessageFormat.format(rb.getString("wakelock.tooltip.content"),
                            ResourceBundleManager.getEnumString(wi.getWakelockState()),
                            wi.getBeginTimeStamp()));
                    displayInfo.append(rb.getString("wakelock.tooltip.suffix"));
                    return displayInfo.toString();
                }
                return null;
            }
        });
    }

    plot.setDataset(wakelockData);
}

From source file:edu.ucla.stat.SOCR.chart.demo.SOCR_EM_MixtureModelChartDemo.java

void printDataset(XYDataset ds) {

    System.out.println("  debugging: print single ds");
    for (int i = 0; i < ds.getSeriesCount(); i++) {
        System.out.println("   debugging: print ds: series:" + i);
        for (int j = 0; j < ds.getItemCount(i); j++)
            System.out.println("      debugging: print ds: series:" + i + "pt " + j + "(" + ds.getXValue(i, j)
                    + "," + ds.getYValue(i, j) + ")");
    } //i//  w ww  . j a v  a  2 s . com

}

From source file:msi.gama.outputs.layers.charts.StandardXYItemRenderer.java

/**
 * Draws the visual representation of a single data item.
 *
 * @param g2/* w w w  .  java  2  s. c o  m*/
 *            the graphics device.
 * @param state
 *            the renderer state.
 * @param dataArea
 *            the area within which the data is being drawn.
 * @param info
 *            collects information about the drawing.
 * @param plot
 *            the plot (can be used to obtain standard color information etc).
 * @param domainAxis
 *            the domain axis.
 * @param rangeAxis
 *            the range axis.
 * @param dataset
 *            the dataset.
 * @param series
 *            the series index (zero-based).
 * @param item
 *            the item index (zero-based).
 * @param crosshairState
 *            crosshair information for the plot (<code>null</code> permitted).
 * @param pass
 *            the pass index.
 */
@Override
public void drawItem(final Graphics2D g2, final XYItemRendererState state, final Rectangle2D dataArea,
        final PlotRenderingInfo info, final XYPlot plot, final ValueAxis domainAxis, final ValueAxis rangeAxis,
        final XYDataset dataset, final int series, final int item, final CrosshairState crosshairState,
        final int pass) {

    boolean itemVisible = getItemVisible(series, item);

    // setup for collecting optional entity info...
    Shape entityArea = null;
    EntityCollection entities = null;
    if (info != null) {
        entities = info.getOwner().getEntityCollection();
    }

    final PlotOrientation orientation = plot.getOrientation();
    final Paint paint = getItemPaint(series, item);
    final Stroke seriesStroke = getItemStroke(series, item);
    g2.setPaint(paint);
    g2.setStroke(seriesStroke);

    // get the data point...
    final double x1 = dataset.getXValue(series, item);
    final double y1 = dataset.getYValue(series, item);
    if (Double.isNaN(x1) || Double.isNaN(y1)) {
        itemVisible = false;
    }

    final RectangleEdge xAxisLocation = plot.getDomainAxisEdge();
    final RectangleEdge yAxisLocation = plot.getRangeAxisEdge();
    final double transX1 = domainAxis.valueToJava2D(x1, dataArea, xAxisLocation);
    final double transY1 = rangeAxis.valueToJava2D(y1, dataArea, yAxisLocation);

    if (getPlotLines()) {
        if (this.drawSeriesLineAsPath) {
            final State s = (State) state;
            if (s.getSeriesIndex() != series) {
                // we are starting a new series path
                s.seriesPath.reset();
                s.lastPointGood = false;
                s.setSeriesIndex(series);
            }

            // update path to reflect latest point
            if (itemVisible && !Double.isNaN(transX1) && !Double.isNaN(transY1)) {
                float x = (float) transX1;
                float y = (float) transY1;
                if (orientation == PlotOrientation.HORIZONTAL) {
                    x = (float) transY1;
                    y = (float) transX1;
                }
                if (s.isLastPointGood()) {
                    // TODO: check threshold
                    s.seriesPath.lineTo(x, y);
                } else {
                    s.seriesPath.moveTo(x, y);
                }
                s.setLastPointGood(true);
            } else {
                s.setLastPointGood(false);
            }
            if (item == dataset.getItemCount(series) - 1) {
                if (s.seriesIndex == series) {
                    // draw path
                    g2.setStroke(lookupSeriesStroke(series));
                    g2.setPaint(lookupSeriesPaint(series));
                    g2.draw(s.seriesPath);
                }
            }
        }

        else if (item != 0 && itemVisible) {
            // get the previous data point...
            final double x0 = dataset.getXValue(series, item - 1);
            final double y0 = dataset.getYValue(series, item - 1);
            if (!Double.isNaN(x0) && !Double.isNaN(y0)) {
                boolean drawLine = true;
                if (getPlotDiscontinuous()) {
                    // only draw a line if the gap between the current and
                    // previous data point is within the threshold
                    final int numX = dataset.getItemCount(series);
                    final double minX = dataset.getXValue(series, 0);
                    final double maxX = dataset.getXValue(series, numX - 1);
                    if (this.gapThresholdType == UnitType.ABSOLUTE) {
                        drawLine = Math.abs(x1 - x0) <= this.gapThreshold;
                    } else {
                        drawLine = Math.abs(x1 - x0) <= (maxX - minX) / numX * getGapThreshold();
                    }
                }
                if (drawLine) {
                    final double transX0 = domainAxis.valueToJava2D(x0, dataArea, xAxisLocation);
                    final double transY0 = rangeAxis.valueToJava2D(y0, dataArea, yAxisLocation);

                    // only draw if we have good values
                    if (Double.isNaN(transX0) || Double.isNaN(transY0) || Double.isNaN(transX1)
                            || Double.isNaN(transY1)) {
                        return;
                    }

                    if (orientation == PlotOrientation.HORIZONTAL) {
                        state.workingLine.setLine(transY0, transX0, transY1, transX1);
                    } else if (orientation == PlotOrientation.VERTICAL) {
                        state.workingLine.setLine(transX0, transY0, transX1, transY1);
                    }

                    if (state.workingLine.intersects(dataArea)) {
                        g2.draw(state.workingLine);
                    }
                }
            }
        }
    }

    // we needed to get this far even for invisible items, to ensure that
    // seriesPath updates happened, but now there is nothing more we need
    // to do for non-visible items...
    if (!itemVisible) {
        return;
    }

    if (getBaseShapesVisible()) {

        Shape shape = getItemShape(series, item);
        if (orientation == PlotOrientation.HORIZONTAL) {
            shape = ShapeUtilities.createTranslatedShape(shape, transY1, transX1);
        } else if (orientation == PlotOrientation.VERTICAL) {
            shape = ShapeUtilities.createTranslatedShape(shape, transX1, transY1);
        }
        if (shape.intersects(dataArea)) {
            if (getItemShapeFilled(series, item)) {
                g2.fill(shape);
            } else {
                g2.draw(shape);
            }
        }
        entityArea = shape;

    }

    if (getPlotImages()) {
        final Image image = getImage(plot, series, item, transX1, transY1);
        if (image != null) {
            final Point hotspot = getImageHotspot(plot, series, item, transX1, transY1, image);
            g2.drawImage(image, (int) (transX1 - hotspot.getX()), (int) (transY1 - hotspot.getY()), null);
            entityArea = new Rectangle2D.Double(transX1 - hotspot.getX(), transY1 - hotspot.getY(),
                    image.getWidth(null), image.getHeight(null));
        }

    }

    double xx = transX1;
    double yy = transY1;
    if (orientation == PlotOrientation.HORIZONTAL) {
        xx = transY1;
        yy = transX1;
    }

    // draw the item label if there is one...
    if (isItemLabelVisible(series, item)) {
        drawItemLabel(g2, orientation, dataset, series, item, xx, yy, y1 < 0.0);
    }

    final int domainAxisIndex = plot.getDomainAxisIndex(domainAxis);
    final int rangeAxisIndex = plot.getRangeAxisIndex(rangeAxis);
    updateCrosshairValues(crosshairState, x1, y1, domainAxisIndex, rangeAxisIndex, transX1, transY1,
            orientation);

    // add an entity for the item...
    if (entities != null && isPointInRect(dataArea, xx, yy)) {
        addEntity(entities, entityArea, dataset, series, item, xx, yy);
    }

}