1

I have the following plot:

Scatter plot

How do I put arrows at the end of leadership line and performance line?

Here is a demo code:

import java.awt.BasicStroke;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GradientPaint;
import java.awt.Paint;
import java.awt.Shape;
import java.awt.geom.Ellipse2D;
import java.util.*;
import javax.swing.JFrame;
import org.jfree.chart.*;
import org.jfree.chart.axis.NumberAxis;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.renderer.xy.XYItemRenderer;
import org.jfree.data.xy.XYDataset;
import org.jfree.data.xy.XYSeries;
import org.jfree.data.xy.XYSeriesCollection;

public class Test extends JFrame {

    private static final int N = 3;
    private static final int SIZE = 345;
    private static final String title = "Scatter Plot Demo";
    private final XYSeries series = new XYSeries("0");

    protected Map<String, Color> colors = new HashMap<String, Color>();
    protected Map<Integer, Shape> shapes = new HashMap<Integer, Shape>();
    private Color bckColor1 = Color.decode("#4282CE");
    private Color bckColor2 = Color.decode("#9BC1FF");
    public static final Shape BASE_SHAPE = new Ellipse2D.Float(0, 0, 12, 12);

    public Test(String s) {
        super(s);
        colores.put("0", Color.decode("#FFAC59")); //Orange
        colores.put("1", Color.decode("#D6FC93"));//Clear green
        colores.put("2", Color.decode("#C0E975"));//Dark green

        for(int i = 0; i < 3; i++)
            shapes.put(i, BASE_SHAPE);

        final ChartPanel chartPanel = createDemoPanel();
        chartPanel.setPreferredSize(new Dimension(SIZE, SIZE));
        this.add(chartPanel, BorderLayout.CENTER);
    }

    protected void processPlot(XYPlot plot) {
        Paint p = new GradientPaint(0,0,bckColor1,0,0,bckColor2);
        Color axisColor = Color.decode("#DD0010"); //Red

        NumberAxis rangeAxis = (NumberAxis) plot.getRangeAxis();
        rangeAxis.setTickLabelsVisible(false);
        rangeAxis.setMinorTickMarksVisible(false);
        rangeAxis.setTickMarksVisible(false);
        rangeAxis.setAxisLinePaint(axisColor);
        rangeAxis.setAxisLineStroke(new BasicStroke(2));

        NumberAxis domainAxis = (NumberAxis) plot.getDomainAxis();
        domainAxis.setTickLabelsVisible(false);
        domainAxis.setMinorTickMarksVisible(false);
        domainAxis.setTickMarksVisible(false);
        domainAxis.setAxisLinePaint(axisColor);
        domainAxis.setAxisLineStroke(new BasicStroke(2));

        plot.setBackgroundPaint(p);
        plot.setDomainGridlinesVisible(false);
        plot.setRangeGridlinesVisible(false);
    }

    private ChartPanel createDemoPanel() {
        JFreeChart jfreechart = ChartFactory.createScatterPlot(
            title, "Performance", "Leadership", createSampleData(),
            PlotOrientation.VERTICAL, true, true, false);

        XYPlot plot = (XYPlot) jfreechart.getPlot();
        XYItemRenderer renderer = (XYItemRenderer) plot.getRenderer();
        renderer.setBaseShape(BASE_SHAPE);

        processPlot(plot);
        XYDataset cd = (XYDataset)plot.getDataset();

        if (cd != null) {
            int rc = cd.getSeriesCount();
            for (int i = 0; i < rc; i++) {
                String key = (String) cd.getSeriesKey(i);

                Color color = colors.get(key);
                Paint p = new GradientPaint(0, 0, color.brighter()
                        , 0, 0, color.darker());

                renderer.setSeriesPaint(i, p);
                renderer.setSeriesOutlinePaint(i, color);
                renderer.setSeriesShape(i, BASE_SHAPE);
            }
        }

        return new ChartPanel(jfreechart);
    }

    private XYDataset createSampleData() {
        XYSeriesCollection xySeriesCollection = new XYSeriesCollection();

        for (int i = 0; i < N; i++) {
            series.add(randomDouble(0D, 100D)
                    , randomDouble(0D, 100D));
        }
        xySeriesCollection.addSeries(series);
        return xySeriesCollection;
    }

    private double randomDouble(double min, double max) {
        Random r = new Random();
        double randomValue = min + (max - min) * r.nextDouble();
        return randomValue;
    }

    public static void main(String args[]) {
        EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                Test demo = new Test(title);
                demo.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                demo.pack();
                demo.setLocationRelativeTo(null);
                demo.setVisible(true);
            }
        });
    }

I've found the class XYPointerAnnotation at http://www.jfree.org/jfreechart/api/javadoc/org/jfree/chart/annotations/XYPointerAnnotation.html, but It works only inside plot, not for axis lines.

Thanks.

dovahkiin
  • 708
  • 14
  • 34

2 Answers2

1

Add a RIGHTWARDS ARROW (U+2192) → to the axis label.

JFreeChart jfreechart = ChartFactory.createScatterPlot(
    title, "Performance →", "Leadership →", createSampleData(),
    PlotOrientation.VERTICAL, true, true, false);

image

trashgod
  • 203,806
  • 29
  • 246
  • 1,045
1

I don't work with jfree in Java; I use it in Clojure via Incanter. No doubt you've moved on from this question, dohvakiin, but since no one has answered after 2.5 years, I'll propose a partially untested solution. I haven't tried this in pure Java, but it's a translation into Java of what I've done with jfree in Clojure:

plot.getDomainAxis().setPositiveArrowVisible(true);
plot.getDomainAxis().setPositiveArrowVisible(true);

Here plot is the XYPlot object defined in your code. This will place an arrow on the right and of the horizontal axis, and on the top end of the vertical axis. There's also a setNegativeArrowVisible method if you want an arrowhead on the other ends.

In your example,

rangeAxis.setPositiveArrowVisible(true);
domainAxis.setPositiveArrowVisible(true);

image

The arrowhead is quite small, however, and replacing it seems to require coding up a new Shape object.

trashgod
  • 203,806
  • 29
  • 246
  • 1,045
Mars
  • 8,689
  • 2
  • 42
  • 70