Different symbols at each data point

A discussion forum for JFreeChart (a 2D chart library for the Java platform).
Locked
Stever
Posts: 3
Joined: Fri Oct 29, 2010 1:05 am
antibot: No, of course not.
Location: Vancouver Island, British Columbia, Canada

Different symbols at each data point

Post by Stever » Wed Feb 16, 2011 9:51 pm

Is it possible to specify the shape of each data point on an XP type plot. I have some data where certain values may be erroneous so I want the user to see a different shape or color. For example, if the data is questionable draw a red square instead of a blue circle at the point.
Many thanks,
Stever

Stever
Posts: 3
Joined: Fri Oct 29, 2010 1:05 am
antibot: No, of course not.
Location: Vancouver Island, British Columbia, Canada

Re: Different symbols at each data point

Post by Stever » Fri Mar 18, 2011 5:54 pm

Guess not :(

paradoxoff
Posts: 1634
Joined: Sat Feb 17, 2007 1:51 pm

Re: Different symbols at each data point

Post by paradoxoff » Fri Mar 18, 2011 9:32 pm

Stever wrote:Guess not :(
Guess again. :wink:
If you can indicate the reliability of the data points with a simple number, you can try a DefaultXYZDataset and indicate the reliability of the data points by the z value.
Concerning the rending part: you could write your own renderer that extends e. g.AbstractXYItemRenderer or and override the drawItem method. In your overridden drawItem method, you can, based on the z value of the item defined by the series and item index, access the z value and translate that into a suitable shape.
Here is an example:

Code: Select all

public class XYZDemo1 {
    public static void main(String[] args) {
        JFrame frame = new JFrame("XYZDemo");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        int rows = 4;
        int columns = 2;
        String[] rowKeys = {"X1", "X2", "X3", "X4"};
        String[] columnKeys = {"Y1", "Y2"};
        double[] xValues = {1, 2, 3, 4, 5, 6, 7, 8};
        double[] yValues = {20, 0, 18, 8, 11, 17, 14, 17};
        double[] zValues = {0, 1, 0, 3, 0, 1, 0, 1};
        DefaultXYZDataset dataset = new DefaultXYZDataset();
        double[][] data = new double[3][];
        data[0] = xValues;
        data[1] = yValues;
        data[2] = zValues;
        dataset.addSeries("Series 1", data);
		XYItemRenderer r = new XYZShapeRenderer();
		NumberAxis xAxis = new NumberAxis("x");
        NumberAxis yAxis = new NumberAxis("y");
        XYPlot plot = new XYPlot(dataset, xAxis, yAxis, r);
 		JFreeChart chart = new JFreeChart("XYZ Demo", new Font("Tahoma",0,18), plot, false);
        frame.setContentPane(new ChartPanel(chart));
        frame.pack();
      	frame.setVisible(true);       
    }
    static class XYZShapeRenderer extends AbstractXYItemRenderer{
        private Shape[] shapes = new Shape[]{new Rectangle2D.Double(-8, -8, 16, 16), new Ellipse2D.Double(-8, -8, 16, 16)};
        public void drawItem(Graphics2D g2, XYItemRendererState state,
                Rectangle2D dataArea, PlotRenderingInfo info, XYPlot plot,
                ValueAxis domainAxis, ValueAxis rangeAxis, XYDataset dataset,
                int series, int item, CrosshairState crosshairState, int pass) {
    
            Shape hotspot = null;
            EntityCollection entities = null;
            if (info != null) {
                entities = info.getOwner().getEntityCollection();
            }
    
            double x = dataset.getXValue(series, item);
            double y = dataset.getYValue(series, item);
            if (Double.isNaN(x) || Double.isNaN(y)) {
                // can't draw anything
                return;
            }
    
            double transX = domainAxis.valueToJava2D(x, dataArea,
                    plot.getDomainAxisEdge());
            double transY = rangeAxis.valueToJava2D(y, dataArea,
                    plot.getRangeAxisEdge());
    
            PlotOrientation orientation = plot.getOrientation();
            boolean useDefaultShape = true;
            Shape shape = null;
            if(dataset instanceof XYZDataset){
                XYZDataset xyz = (XYZDataset)dataset;
                double z = xyz.getZValue(series, item);
                if(z == 0){
                    shape = shapes[0];
                    useDefaultShape = false;
                }
                if(z == 1){
                    shape = shapes[1];
                    useDefaultShape = false;
                }
            }
            if(useDefaultShape){
                shape = getItemShape(series, item);
            }
            if (orientation == PlotOrientation.HORIZONTAL) {
                shape = ShapeUtilities.createTranslatedShape(shape, transY,
                        transX);
            }
            else if (orientation == PlotOrientation.VERTICAL) {
                shape = ShapeUtilities.createTranslatedShape(shape, transX,
                        transY);
            }
            hotspot = shape;
            if (shape.intersects(dataArea)) {
                    //if (getItemShapeFilled(series, item)) {
                        g2.setPaint(lookupSeriesPaint(series));
                        g2.fill(shape);
                   //}
                g2.setPaint(getItemOutlinePaint(series, item));
                g2.setStroke(getItemOutlineStroke(series, item));
                g2.draw(shape);
            }
    
            // add an entity for the item...
            if (entities != null) {
                addEntity(entities, hotspot, dataset, series, item, transX,
                        transY);
            }
        }
    }
}

sarehman82
Posts: 4
Joined: Fri May 06, 2011 1:39 pm
antibot: No, of course not.

Re: Different symbols at each data point

Post by sarehman82 » Sat May 07, 2011 12:39 pm

Hi Paradoxoff,

You saved my week. Your code helped me lot. I appreciate your effort in posting it. You posted it in 2007 and now I m using it in 2011.

Thank again,
abdul

Locked