Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/364.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 在CombinedDomainXYPlot中创建标记/十字线_Java_Jfreechart - Fatal编程技术网

Java 在CombinedDomainXYPlot中创建标记/十字线

Java 在CombinedDomainXYPlot中创建标记/十字线,java,jfreechart,Java,Jfreechart,我想在组合域中显示一个标记。这是行不通的。我可以为每个子批次添加标记。但我想为CombinedDomainXYPlot添加它。任何人都可以告诉我一些关于这个问题的事情。我认为十字线的行为是一样的 这是创建CombinedDomainXYPlot并尝试添加标记的工作示例。添加的标记位于createCombinedChart中 drawAnnotations是在XYPlot中实现的,不幸的是合并了DomainXYPlot子类XYPlot,但在其重写的drawAnnotations实现中不调用draw

我想在组合域中显示一个标记。这是行不通的。我可以为每个子批次添加标记。但我想为CombinedDomainXYPlot添加它。任何人都可以告诉我一些关于这个问题的事情。我认为十字线的行为是一样的

这是创建CombinedDomainXYPlot并尝试添加标记的工作示例。添加的标记位于createCombinedChart中

drawAnnotations是在XYPlot中实现的,不幸的是合并了DomainXYPlot子类XYPlot,但在其重写的drawAnnotations实现中不调用drawAnnotations,也不将注释转发到子图

您可以通过子类化CombinedDomainXYPlot来实现addAnnotation和removeAnnotation。

drawAnnotations在XYPlot中实现,不幸的是,CombinedDomainXYPlot子类XYPlot,但在其重写的draw实现中不调用drawAnnotations,也不将注释转发到子图


通过对CombinedDomainXYPlot进行子类化,您可以提供addAnnotation和removeAnnotation的实现。

多亏了Graham,我开发了CombinedDomainXYPlot的调整版,它适合我。结果是这样的

为了实现这一点,我合并了XYPlot和xylineandshaperender中的代码。 这是源代码

import java.awt.AlphaComposite;
import java.awt.Composite;
import java.awt.Font;
import java.awt.GradientPaint;
import java.awt.Graphics2D;
import java.awt.Paint;
import java.awt.geom.Line2D;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.jfree.chart.annotations.XYAnnotation;
import org.jfree.chart.axis.ValueAxis;
import org.jfree.chart.plot.CombinedDomainXYPlot;
import org.jfree.chart.plot.IntervalMarker;
import org.jfree.chart.plot.Marker;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.plot.PlotRenderingInfo;
import org.jfree.chart.plot.PlotState;
import org.jfree.chart.plot.ValueMarker;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.renderer.xy.XYItemRenderer;
import org.jfree.data.Range;
import org.jfree.text.TextUtilities;
import org.jfree.ui.GradientPaintTransformer;
import org.jfree.ui.Layer;
import org.jfree.ui.LengthAdjustmentType;
import org.jfree.ui.RectangleAnchor;
import org.jfree.ui.RectangleInsets;

public class MyCombinedDomainXYPlot extends CombinedDomainXYPlot {

public MyCombinedDomainXYPlot() {
    super();
    // TODO Auto-generated constructor stub
}

public MyCombinedDomainXYPlot(ValueAxis domainAxis) {
    super(domainAxis);
    // TODO Auto-generated constructor stub
}

@Override
public void draw(Graphics2D g2, Rectangle2D area, Point2D anchor,
        PlotState parentState, PlotRenderingInfo info) {
    super.draw(g2, area, anchor, parentState, info);
    drawDomainMarkers(g2, area, 0, Layer.FOREGROUND);
}

/**
 * Draws the domain markers (if any) for an axis and layer.  This method is
 * typically called from within the draw() method.
 *
 * @param g2  the graphics device.
 * @param dataArea  the data area.
 * @param index  the renderer index.
 * @param layer  the layer (foreground or background).
 */
@Override
protected void drawDomainMarkers(Graphics2D g2, Rectangle2D dataArea,
                                 int index, Layer layer) {

    // check that the renderer has a corresponding dataset (it doesn't
    // matter if the dataset is null)
    if (index >= getDatasetCount()) {
        return;
    }
    Collection markers = getDomainMarkers(index, layer);
    ValueAxis axis = getDomainAxisForDataset(index);
    if (markers != null && axis != null) {
        Iterator iterator = markers.iterator();
        while (iterator.hasNext()) {
            Marker marker = (Marker) iterator.next();
            drawDomainMarker(g2, marker, dataArea);
        }
    }

}


/**
 * Draws a vertical line on the chart to represent a 'range marker'.
 * 
 * @param g2
 *            the graphics device.
 * @param plot
 *            the plot.
 * @param domainAxis
 *            the domain axis.
 * @param marker
 *            the marker line.
 * @param dataArea
 *            the axis data area.
 */
public void drawDomainMarker(Graphics2D g2, Marker marker, Rectangle2D dataArea) {

        ValueAxis domainAxis = getDomainAxis();
        if (marker instanceof ValueMarker) {
            ValueMarker vm = (ValueMarker) marker;
            double value = vm.getValue();
            Range range = domainAxis.getRange();
            if (!range.contains(value)) {
                return;
            }

            double v = domainAxis.valueToJava2D(value, dataArea,
                    getDomainAxisEdge());

            PlotOrientation orientation = getOrientation();
            Line2D line = null;
            if (orientation == PlotOrientation.HORIZONTAL) {
                line = new Line2D.Double(dataArea.getMinX(), v,
                        dataArea.getMaxX(), v);
            } else if (orientation == PlotOrientation.VERTICAL) {
                line = new Line2D.Double(v, dataArea.getMinY(), v,
                        dataArea.getMaxY());
            }

            final Composite originalComposite = g2.getComposite();
            g2.setComposite(AlphaComposite.getInstance(
                    AlphaComposite.SRC_OVER, marker.getAlpha()));
            g2.setPaint(marker.getPaint());
            g2.setStroke(marker.getStroke());
            g2.draw(line);

            String label = marker.getLabel();
            RectangleAnchor anchor = marker.getLabelAnchor();
            if (label != null) {
                Font labelFont = marker.getLabelFont();
                g2.setFont(labelFont);
                g2.setPaint(marker.getLabelPaint());
                Point2D coordinates = calculateDomainMarkerTextAnchorPoint(
                        g2, orientation, dataArea, line.getBounds2D(),
                        marker.getLabelOffset(),
                        LengthAdjustmentType.EXPAND, anchor);
                TextUtilities.drawAlignedString(label, g2,
                        (float) coordinates.getX(),
                        (float) coordinates.getY(),
                        marker.getLabelTextAnchor());
            }
            g2.setComposite(originalComposite);
        } else if (marker instanceof IntervalMarker) {
            IntervalMarker im = (IntervalMarker) marker;
            double start = im.getStartValue();
            double end = im.getEndValue();
            Range range = domainAxis.getRange();
            if (!(range.intersects(start, end))) {
                return;
            }

            double start2d = domainAxis.valueToJava2D(start, dataArea,
                    getDomainAxisEdge());
            double end2d = domainAxis.valueToJava2D(end, dataArea,
                    getDomainAxisEdge());
            double low = Math.min(start2d, end2d);
            double high = Math.max(start2d, end2d);

            PlotOrientation orientation = getOrientation();
            Rectangle2D rect = null;
            if (orientation == PlotOrientation.HORIZONTAL) {
                // clip top and bottom bounds to data area
                low = Math.max(low, dataArea.getMinY());
                high = Math.min(high, dataArea.getMaxY());
                rect = new Rectangle2D.Double(dataArea.getMinX(), low,
                        dataArea.getWidth(), high - low);
            } else if (orientation == PlotOrientation.VERTICAL) {
                // clip left and right bounds to data area
                low = Math.max(low, dataArea.getMinX());
                high = Math.min(high, dataArea.getMaxX());
                rect = new Rectangle2D.Double(low, dataArea.getMinY(), high
                        - low, dataArea.getHeight());
            }

            final Composite originalComposite = g2.getComposite();
            g2.setComposite(AlphaComposite.getInstance(
                    AlphaComposite.SRC_OVER, marker.getAlpha()));
            Paint p = marker.getPaint();
            if (p instanceof GradientPaint) {
                GradientPaint gp = (GradientPaint) p;
                GradientPaintTransformer t = im
                        .getGradientPaintTransformer();
                if (t != null) {
                    gp = t.transform(gp, rect);
                }
                g2.setPaint(gp);
            } else {
                g2.setPaint(p);
            }
            g2.fill(rect);

            // now draw the outlines, if visible...
            if (im.getOutlinePaint() != null
                    && im.getOutlineStroke() != null) {
                if (orientation == PlotOrientation.VERTICAL) {
                    Line2D line = new Line2D.Double();
                    double y0 = dataArea.getMinY();
                    double y1 = dataArea.getMaxY();
                    g2.setPaint(im.getOutlinePaint());
                    g2.setStroke(im.getOutlineStroke());
                    if (range.contains(start)) {
                        line.setLine(start2d, y0, start2d, y1);
                        g2.draw(line);
                    }
                    if (range.contains(end)) {
                        line.setLine(end2d, y0, end2d, y1);
                        g2.draw(line);
                    }
                } else { // PlotOrientation.HORIZONTAL
                    Line2D line = new Line2D.Double();
                    double x0 = dataArea.getMinX();
                    double x1 = dataArea.getMaxX();
                    g2.setPaint(im.getOutlinePaint());
                    g2.setStroke(im.getOutlineStroke());
                    if (range.contains(start)) {
                        line.setLine(x0, start2d, x1, start2d);
                        g2.draw(line);
                    }
                    if (range.contains(end)) {
                        line.setLine(x0, end2d, x1, end2d);
                        g2.draw(line);
                    }
                }
            }

            String label = marker.getLabel();
            RectangleAnchor anchor = marker.getLabelAnchor();
            if (label != null) {
                Font labelFont = marker.getLabelFont();
                g2.setFont(labelFont);
                g2.setPaint(marker.getLabelPaint());
                Point2D coordinates = calculateDomainMarkerTextAnchorPoint(
                        g2, orientation, dataArea, rect,
                        marker.getLabelOffset(),
                        marker.getLabelOffsetType(), anchor);
                TextUtilities.drawAlignedString(label, g2,
                        (float) coordinates.getX(),
                        (float) coordinates.getY(),
                        marker.getLabelTextAnchor());
            }
            g2.setComposite(originalComposite);

        }
    }




/**
 * Calculates the (x, y) coordinates for drawing a marker label.
 * 
 * @param g2
 *            the graphics device.
 * @param orientation
 *            the plot orientation.
 * @param dataArea
 *            the data area.
 * @param markerArea
 *            the rectangle surrounding the marker area.
 * @param markerOffset
 *            the marker label offset.
 * @param labelOffsetType
 *            the label offset type.
 * @param anchor
 *            the label anchor.
 * 
 * @return The coordinates for drawing the marker label.
 */
protected Point2D calculateDomainMarkerTextAnchorPoint(Graphics2D g2,
        PlotOrientation orientation, Rectangle2D dataArea,
        Rectangle2D markerArea, RectangleInsets markerOffset,
        LengthAdjustmentType labelOffsetType, RectangleAnchor anchor) {

    Rectangle2D anchorRect = null;
    if (orientation == PlotOrientation.HORIZONTAL) {
        anchorRect = markerOffset.createAdjustedRectangle(markerArea,
                LengthAdjustmentType.CONTRACT, labelOffsetType);
    } else if (orientation == PlotOrientation.VERTICAL) {
        anchorRect = markerOffset.createAdjustedRectangle(markerArea,
                labelOffsetType, LengthAdjustmentType.CONTRACT);
    }
    return RectangleAnchor.coordinates(anchorRect, anchor);

}
}

多亏了格雷厄姆,我开发了一个调整版的CombinedDomainXYPlot,它适合我。结果是这样的

为了实现这一点,我合并了XYPlot和xylineandshaperender中的代码。 这是源代码

import java.awt.AlphaComposite;
import java.awt.Composite;
import java.awt.Font;
import java.awt.GradientPaint;
import java.awt.Graphics2D;
import java.awt.Paint;
import java.awt.geom.Line2D;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.jfree.chart.annotations.XYAnnotation;
import org.jfree.chart.axis.ValueAxis;
import org.jfree.chart.plot.CombinedDomainXYPlot;
import org.jfree.chart.plot.IntervalMarker;
import org.jfree.chart.plot.Marker;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.plot.PlotRenderingInfo;
import org.jfree.chart.plot.PlotState;
import org.jfree.chart.plot.ValueMarker;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.renderer.xy.XYItemRenderer;
import org.jfree.data.Range;
import org.jfree.text.TextUtilities;
import org.jfree.ui.GradientPaintTransformer;
import org.jfree.ui.Layer;
import org.jfree.ui.LengthAdjustmentType;
import org.jfree.ui.RectangleAnchor;
import org.jfree.ui.RectangleInsets;

public class MyCombinedDomainXYPlot extends CombinedDomainXYPlot {

public MyCombinedDomainXYPlot() {
    super();
    // TODO Auto-generated constructor stub
}

public MyCombinedDomainXYPlot(ValueAxis domainAxis) {
    super(domainAxis);
    // TODO Auto-generated constructor stub
}

@Override
public void draw(Graphics2D g2, Rectangle2D area, Point2D anchor,
        PlotState parentState, PlotRenderingInfo info) {
    super.draw(g2, area, anchor, parentState, info);
    drawDomainMarkers(g2, area, 0, Layer.FOREGROUND);
}

/**
 * Draws the domain markers (if any) for an axis and layer.  This method is
 * typically called from within the draw() method.
 *
 * @param g2  the graphics device.
 * @param dataArea  the data area.
 * @param index  the renderer index.
 * @param layer  the layer (foreground or background).
 */
@Override
protected void drawDomainMarkers(Graphics2D g2, Rectangle2D dataArea,
                                 int index, Layer layer) {

    // check that the renderer has a corresponding dataset (it doesn't
    // matter if the dataset is null)
    if (index >= getDatasetCount()) {
        return;
    }
    Collection markers = getDomainMarkers(index, layer);
    ValueAxis axis = getDomainAxisForDataset(index);
    if (markers != null && axis != null) {
        Iterator iterator = markers.iterator();
        while (iterator.hasNext()) {
            Marker marker = (Marker) iterator.next();
            drawDomainMarker(g2, marker, dataArea);
        }
    }

}


/**
 * Draws a vertical line on the chart to represent a 'range marker'.
 * 
 * @param g2
 *            the graphics device.
 * @param plot
 *            the plot.
 * @param domainAxis
 *            the domain axis.
 * @param marker
 *            the marker line.
 * @param dataArea
 *            the axis data area.
 */
public void drawDomainMarker(Graphics2D g2, Marker marker, Rectangle2D dataArea) {

        ValueAxis domainAxis = getDomainAxis();
        if (marker instanceof ValueMarker) {
            ValueMarker vm = (ValueMarker) marker;
            double value = vm.getValue();
            Range range = domainAxis.getRange();
            if (!range.contains(value)) {
                return;
            }

            double v = domainAxis.valueToJava2D(value, dataArea,
                    getDomainAxisEdge());

            PlotOrientation orientation = getOrientation();
            Line2D line = null;
            if (orientation == PlotOrientation.HORIZONTAL) {
                line = new Line2D.Double(dataArea.getMinX(), v,
                        dataArea.getMaxX(), v);
            } else if (orientation == PlotOrientation.VERTICAL) {
                line = new Line2D.Double(v, dataArea.getMinY(), v,
                        dataArea.getMaxY());
            }

            final Composite originalComposite = g2.getComposite();
            g2.setComposite(AlphaComposite.getInstance(
                    AlphaComposite.SRC_OVER, marker.getAlpha()));
            g2.setPaint(marker.getPaint());
            g2.setStroke(marker.getStroke());
            g2.draw(line);

            String label = marker.getLabel();
            RectangleAnchor anchor = marker.getLabelAnchor();
            if (label != null) {
                Font labelFont = marker.getLabelFont();
                g2.setFont(labelFont);
                g2.setPaint(marker.getLabelPaint());
                Point2D coordinates = calculateDomainMarkerTextAnchorPoint(
                        g2, orientation, dataArea, line.getBounds2D(),
                        marker.getLabelOffset(),
                        LengthAdjustmentType.EXPAND, anchor);
                TextUtilities.drawAlignedString(label, g2,
                        (float) coordinates.getX(),
                        (float) coordinates.getY(),
                        marker.getLabelTextAnchor());
            }
            g2.setComposite(originalComposite);
        } else if (marker instanceof IntervalMarker) {
            IntervalMarker im = (IntervalMarker) marker;
            double start = im.getStartValue();
            double end = im.getEndValue();
            Range range = domainAxis.getRange();
            if (!(range.intersects(start, end))) {
                return;
            }

            double start2d = domainAxis.valueToJava2D(start, dataArea,
                    getDomainAxisEdge());
            double end2d = domainAxis.valueToJava2D(end, dataArea,
                    getDomainAxisEdge());
            double low = Math.min(start2d, end2d);
            double high = Math.max(start2d, end2d);

            PlotOrientation orientation = getOrientation();
            Rectangle2D rect = null;
            if (orientation == PlotOrientation.HORIZONTAL) {
                // clip top and bottom bounds to data area
                low = Math.max(low, dataArea.getMinY());
                high = Math.min(high, dataArea.getMaxY());
                rect = new Rectangle2D.Double(dataArea.getMinX(), low,
                        dataArea.getWidth(), high - low);
            } else if (orientation == PlotOrientation.VERTICAL) {
                // clip left and right bounds to data area
                low = Math.max(low, dataArea.getMinX());
                high = Math.min(high, dataArea.getMaxX());
                rect = new Rectangle2D.Double(low, dataArea.getMinY(), high
                        - low, dataArea.getHeight());
            }

            final Composite originalComposite = g2.getComposite();
            g2.setComposite(AlphaComposite.getInstance(
                    AlphaComposite.SRC_OVER, marker.getAlpha()));
            Paint p = marker.getPaint();
            if (p instanceof GradientPaint) {
                GradientPaint gp = (GradientPaint) p;
                GradientPaintTransformer t = im
                        .getGradientPaintTransformer();
                if (t != null) {
                    gp = t.transform(gp, rect);
                }
                g2.setPaint(gp);
            } else {
                g2.setPaint(p);
            }
            g2.fill(rect);

            // now draw the outlines, if visible...
            if (im.getOutlinePaint() != null
                    && im.getOutlineStroke() != null) {
                if (orientation == PlotOrientation.VERTICAL) {
                    Line2D line = new Line2D.Double();
                    double y0 = dataArea.getMinY();
                    double y1 = dataArea.getMaxY();
                    g2.setPaint(im.getOutlinePaint());
                    g2.setStroke(im.getOutlineStroke());
                    if (range.contains(start)) {
                        line.setLine(start2d, y0, start2d, y1);
                        g2.draw(line);
                    }
                    if (range.contains(end)) {
                        line.setLine(end2d, y0, end2d, y1);
                        g2.draw(line);
                    }
                } else { // PlotOrientation.HORIZONTAL
                    Line2D line = new Line2D.Double();
                    double x0 = dataArea.getMinX();
                    double x1 = dataArea.getMaxX();
                    g2.setPaint(im.getOutlinePaint());
                    g2.setStroke(im.getOutlineStroke());
                    if (range.contains(start)) {
                        line.setLine(x0, start2d, x1, start2d);
                        g2.draw(line);
                    }
                    if (range.contains(end)) {
                        line.setLine(x0, end2d, x1, end2d);
                        g2.draw(line);
                    }
                }
            }

            String label = marker.getLabel();
            RectangleAnchor anchor = marker.getLabelAnchor();
            if (label != null) {
                Font labelFont = marker.getLabelFont();
                g2.setFont(labelFont);
                g2.setPaint(marker.getLabelPaint());
                Point2D coordinates = calculateDomainMarkerTextAnchorPoint(
                        g2, orientation, dataArea, rect,
                        marker.getLabelOffset(),
                        marker.getLabelOffsetType(), anchor);
                TextUtilities.drawAlignedString(label, g2,
                        (float) coordinates.getX(),
                        (float) coordinates.getY(),
                        marker.getLabelTextAnchor());
            }
            g2.setComposite(originalComposite);

        }
    }




/**
 * Calculates the (x, y) coordinates for drawing a marker label.
 * 
 * @param g2
 *            the graphics device.
 * @param orientation
 *            the plot orientation.
 * @param dataArea
 *            the data area.
 * @param markerArea
 *            the rectangle surrounding the marker area.
 * @param markerOffset
 *            the marker label offset.
 * @param labelOffsetType
 *            the label offset type.
 * @param anchor
 *            the label anchor.
 * 
 * @return The coordinates for drawing the marker label.
 */
protected Point2D calculateDomainMarkerTextAnchorPoint(Graphics2D g2,
        PlotOrientation orientation, Rectangle2D dataArea,
        Rectangle2D markerArea, RectangleInsets markerOffset,
        LengthAdjustmentType labelOffsetType, RectangleAnchor anchor) {

    Rectangle2D anchorRect = null;
    if (orientation == PlotOrientation.HORIZONTAL) {
        anchorRect = markerOffset.createAdjustedRectangle(markerArea,
                LengthAdjustmentType.CONTRACT, labelOffsetType);
    } else if (orientation == PlotOrientation.VERTICAL) {
        anchorRect = markerOffset.createAdjustedRectangle(markerArea,
                labelOffsetType, LengthAdjustmentType.CONTRACT);
    }
    return RectangleAnchor.coordinates(anchorRect, anchor);

}
}

你是如何预期注释出现在组合图中的?为什么不呢?添加注释的方法在那里,但它们似乎不会引起反应;例如,您是否希望注释出现在两个绘图中?我已经在下面解释了他们为什么不工作,但是在没有进一步信息的情况下无法提出解决方案对不起,格雷厄姆,我没有足够仔细地阅读你的评论。我希望标记会出现在整个组合图上,就像一张透明的纸,覆盖在整个图上。因此,标记也应该出现在子地块和地块之间的间隙中。我将了解如何在XYPlot中实现绘制注释。也许你有个好主意。ThanksHow您是否预期注释会出现在组合图中?为什么不呢?添加注释的方法在那里,但它们似乎不会引起反应;例如,您是否希望注释出现在两个绘图中?我已经在下面解释了他们为什么不工作,但是在没有进一步信息的情况下无法提出解决方案对不起,格雷厄姆,我没有足够仔细地阅读你的评论。我希望标记会出现在整个组合图上,就像一张透明的纸,覆盖在整个图上。因此,标记也应该出现在子地块和地块之间的间隙中。我将了解如何在XYPlot中实现绘制注释。也许你有个好主意。谢谢