有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java JFreeChart:使用ChartMouseListener和鼠标移动在ChartPanel中动态选择点

我有一个使用JFreeChart的图表,单击后将标记放在相关位置(参见下图)

我需要的是改变位置不是在点击后,而是在鼠标移动

我知道使用模块ChartMouseListener可以扩展其功能

    ChartMouseListener l = new ChartMouseListener() {
        @Override
        public void chartMouseMoved(ChartMouseEvent e) {
            int newX = e.getTrigger().getX();
            int newY = e.getTrigger().getY();
            System.out.println("chartMouseMoved to " + newX + " " + newY);
        }
        @Override
        public void chartMouseClicked(ChartMouseEvent e) {
        }
    };
    chartPanel.addChartMouseListener(l);

如何在图表中设置所选轴

JFreeChart withd aditional axis

    package org.jfree.chart.demo;

    import java.awt.Color;
    import java.text.SimpleDateFormat;

    import javax.swing.JPanel;

    import org.jfree.chart.ChartFactory;
    import org.jfree.chart.ChartMouseEvent;
    import org.jfree.chart.ChartMouseListener;
    import org.jfree.chart.ChartPanel;
    import org.jfree.chart.JFreeChart;
    import org.jfree.chart.StandardChartTheme;
    import org.jfree.chart.axis.DateAxis;
    import org.jfree.chart.entity.XYItemEntity;
    import org.jfree.chart.plot.XYPlot;
    import org.jfree.chart.renderer.xy.XYItemRenderer;
    import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
    import org.jfree.data.time.Month;
    import org.jfree.data.time.TimeSeries;
    import org.jfree.data.time.TimeSeriesCollection;
    import org.jfree.data.xy.XYDataset;
    import org.jfree.ui.ApplicationFrame;
    import org.jfree.ui.RectangleInsets;
    import org.jfree.ui.RefineryUtilities;

    /**
     * An example of a time series chart. For the most part, default settings are
     * used, except that the renderer is modified to show filled shapes (as well as
     * lines) at each data point.
     */
    public class TimeSeriesChartDemo1 extends ApplicationFrame {

        private static final long serialVersionUID = 1L;

        {
            // set a theme using the new shadow generator feature available in
            // 1.0.14 - for backwards compatibility it is not enabled by default
            ChartFactory
                    .setChartTheme(new StandardChartTheme("JFree/Shadow", true));
        }

        /**
         * A demonstration application showing how to create a simple time series
         * chart. This example uses monthly data.
         * 
         * @param title
         *            the frame title.
         */
        public TimeSeriesChartDemo1(String title) {
            super(title);
            ChartPanel chartPanel = (ChartPanel) createDemoPanel();
            chartPanel.setPreferredSize(new java.awt.Dimension(800, 600));
            setContentPane(chartPanel);
            ChartMouseListener l = new ChartMouseListener() {
                @Override
                public void chartMouseMoved(ChartMouseEvent e) {
                    int newX = e.getTrigger().getX();
                    int newY = e.getTrigger().getY();
                    System.out.println("chartMouseMoved to " + newX + " " + newY);
                }
                @Override
                public void chartMouseClicked(ChartMouseEvent e) {
                }
            };
            System.out.println(chartPanel.getMouseListeners()[0]);
            chartPanel.addChartMouseListener(l);
        }

        /**
         * Creates a chart.
         * 
         * @param dataset
         *            a dataset.
         * 
         * @return A chart.
         */
        private static JFreeChart createChart(XYDataset dataset) {

            JFreeChart chart = ChartFactory.createTimeSeriesChart(
                    "Legal & General Unit Trust Prices", // title
                    "Date", // x-axis label
                    "Price Per Unit", // y-axis label
                    dataset, // data
                    true, // create legend?
                    true, // generate tooltips?
                    true // generate URLs?
                    );

            chart.setBackgroundPaint(Color.white);

            XYPlot plot = (XYPlot) chart.getPlot();
            plot.setBackgroundPaint(Color.lightGray);
            plot.setDomainGridlinePaint(Color.white);
            plot.setRangeGridlinePaint(Color.white);
            plot.setAxisOffset(new RectangleInsets(5.0, 5.0, 5.0, 5.0));
            plot.setDomainCrosshairVisible(true);
            plot.setRangeCrosshairVisible(true);

            XYItemRenderer r = plot.getRenderer();
            if (r instanceof XYLineAndShapeRenderer) {
                XYLineAndShapeRenderer renderer = (XYLineAndShapeRenderer) r;
                renderer.setBaseShapesVisible(true);
                renderer.setBaseShapesFilled(true);
                renderer.setDrawSeriesLineAsPath(true);
            }

            DateAxis axis = (DateAxis) plot.getDomainAxis();
            axis.setDateFormatOverride(new SimpleDateFormat("MMM-yyyy"));

            return chart;

        }

        /**
         * Creates a dataset, consisting of two series of monthly data.
         * 
         * @return The dataset.
         */
        private static XYDataset createDataset() {

            TimeSeries s1 = new TimeSeries("L&G European Index Trust");
            s1.add(new Month(2, 1), .8);
            s1.add(new Month(3, 1), .3);
            s1.add(new Month(4, 1), .8);
            s1.add(new Month(5, 1), .6);
            s1.add(new Month(6, 1), .8);
            s1.add(new Month(7, 1), .3);
            s1.add(new Month(8, 1), .9);
            s1.add(new Month(9, 1), .7);
            s1.add(new Month(10, 1), .2);
            s1.add(new Month(11, 1), .8);
            s1.add(new Month(12, 1), .6);
            s1.add(new Month(1, 2), .9);
            s1.add(new Month(2, 2), .7);
            s1.add(new Month(3, 2), .3);
            s1.add(new Month(4, 2), .9);
            s1.add(new Month(5, 2), .8);
            s1.add(new Month(6, 2), .0);
            s1.add(new Month(7, 2), .8);

            TimeSeries s2 = new TimeSeries("L&G UK Index Trust");
            s2.add(new Month(2, 1), .6);
            s2.add(new Month(3, 1), .2);
            s2.add(new Month(4, 1), .2);
            s2.add(new Month(5, 1), .1);
            s2.add(new Month(6, 1), .6);
            s2.add(new Month(7, 1), .2);
            s2.add(new Month(8, 1), .5);
            s2.add(new Month(9, 1), .7);
            s2.add(new Month(10, 1), .5);
            s2.add(new Month(11, 1), .1);
            s2.add(new Month(12, 1), .3);
            s2.add(new Month(1, 2), .7);
            s2.add(new Month(2, 2), .0);
            s2.add(new Month(3, 2), .6);
            s2.add(new Month(4, 2), .2);
            s2.add(new Month(5, 2), .6);
            s2.add(new Month(6, 2), .8);
            s2.add(new Month(7, 2), .6);

            // ******************************************************************
            // More than demo applications are included with the JFreeChart
            // Developer Guide...for more information, see:
            //
            // > http://www.object-refinery.com/jfreechart/guide.html
            //
            // ******************************************************************

            TimeSeriesCollection dataset = new TimeSeriesCollection();
            dataset.addSeries(s1);
            dataset.addSeries(s2);

            return dataset;

        }

        /**
         * Creates a panel for the demo (used by SuperDemo.java).
         * 
         * @return A panel.
         */
        public static JPanel createDemoPanel() {
            JFreeChart chart = createChart(createDataset());
            ChartPanel panel = new ChartPanel(chart);
            panel.setFillZoomRectangle(true);
            panel.setMouseWheelEnabled(true);
            return panel;
        }

        /**
         * Starting point for the demonstration application.
         * 
         * @param args
         *            ignored.
         */
        public static void main(String[] args) {

            TimeSeriesChartDemo1 demo = new TimeSeriesChartDemo1(
                    "Time Series Chart Demo 1");
            demo.pack();
            RefineryUtilities.centerFrameOnScreen(demo);
            demo.setVisible(true);

        }

    }

共 (1) 个答案

  1. # 1 楼答案

    有几种方法可以在JFreeChart中绘制十字光标。在您给出的示例中,十字光标是作为图表的一部分绘制的,因此每次十字光标的位置发生变化时,图表都需要重新绘制。在鼠标移动事件中这样做不会非常有效

    另一种方法是使用CrosshairOverlay类。这将在现有图表上绘制十字线作为覆盖,从而避免在十字线值更改时重新绘制图表。这对你想做的事情会更好

    《JFreeChart开发者指南》中包含了几个关于此功能的示例(我们鼓励JFreeChart用户购买,这样他们就可以在财务上帮助JFreeChart项目——只有很小的一部分人这样做,但这是人的天性)

    以下是一个例子:

    /*              
     * CrosshairOverlayDemo1.java
     *              
     * (C) Copyright 2003-2014, by Object Refinery Limited.
     *
     */
    
    package demo;
    
    import java.awt.BasicStroke;
    import java.awt.BorderLayout;
    import java.awt.Color;
    import java.awt.geom.Rectangle2D;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    import javax.swing.SwingUtilities;
    import org.jfree.chart.ChartFactory;
    import org.jfree.chart.ChartMouseEvent;
    import org.jfree.chart.ChartMouseListener;
    import org.jfree.chart.ChartPanel;
    import org.jfree.chart.JFreeChart;
    import org.jfree.chart.axis.ValueAxis;
    import org.jfree.chart.panel.CrosshairOverlay;
    import org.jfree.chart.plot.Crosshair;
    import org.jfree.chart.plot.XYPlot;
    import org.jfree.data.general.DatasetUtilities;
    import org.jfree.data.xy.XYDataset;
    import org.jfree.data.xy.XYSeries;
    import org.jfree.data.xy.XYSeriesCollection;
    import org.jfree.ui.RectangleEdge;
    
    /**
     * A demo showing crosshairs that follow the data points on an XYPlot.
     */
    public class CrosshairOverlayDemo1 extends JFrame {
    
        static class MyDemoPanel extends JPanel implements ChartMouseListener {
    
            private ChartPanel chartPanel;
    
            private Crosshair xCrosshair;
    
            private Crosshair yCrosshair;
    
            public MyDemoPanel() {
                super(new BorderLayout());
                JFreeChart chart = createChart(createDataset());
                this.chartPanel = new ChartPanel(chart);
                this.chartPanel.addChartMouseListener(this);
                CrosshairOverlay crosshairOverlay = new CrosshairOverlay();
                this.xCrosshair = new Crosshair(Double.NaN, Color.GRAY, 
                        new BasicStroke(0f));
                this.xCrosshair.setLabelVisible(true);
                this.yCrosshair = new Crosshair(Double.NaN, Color.GRAY, 
                        new BasicStroke(0f));
                this.yCrosshair.setLabelVisible(true);
                crosshairOverlay.addDomainCrosshair(xCrosshair);
                crosshairOverlay.addRangeCrosshair(yCrosshair);
                this.chartPanel.addOverlay(crosshairOverlay);
                add(this.chartPanel);
            }
    
            private JFreeChart createChart(XYDataset dataset) {
                JFreeChart chart = ChartFactory.createXYLineChart(
                        "CrosshairOverlayDemo1", "X", "Y", dataset);
                return chart;
            }
    
            private XYDataset createDataset() {
                XYSeries series = new XYSeries("S1");
                for (int x = 0; x < 10; x++) {
                    series.add(x, x + Math.random() * 4.0);
                }
                XYSeriesCollection dataset = new XYSeriesCollection(series);
                return dataset;
            }
    
            @Override
            public void chartMouseClicked(ChartMouseEvent event) {
                // ignore
            }
    
            @Override
            public void chartMouseMoved(ChartMouseEvent event) {
                Rectangle2D dataArea = this.chartPanel.getScreenDataArea();
                JFreeChart chart = event.getChart();
                XYPlot plot = (XYPlot) chart.getPlot();
                ValueAxis xAxis = plot.getDomainAxis();
                double x = xAxis.java2DToValue(event.getTrigger().getX(), dataArea, 
                        RectangleEdge.BOTTOM);
                // make the crosshairs disappear if the mouse is out of range
                if (!xAxis.getRange().contains(x)) { 
                    x = Double.NaN;                  
                }
                double y = DatasetUtilities.findYValue(plot.getDataset(), 0, x);
                this.xCrosshair.setValue(x);
                this.yCrosshair.setValue(y);
            }  
    
        }
    
        public CrosshairOverlayDemo1(String title) {
            super(title);
            setContentPane(createDemoPanel());
        }
    
        /**
         * Creates a panel for the demo (used by SuperDemo.java).
         *
         * @return A panel.
         */
        public static JPanel createDemoPanel() {
            return new MyDemoPanel();
        }
    
        public static void main(String[] args) {
            SwingUtilities.invokeLater(new Runnable() {
                @Override
                public void run() {
                    CrosshairOverlayDemo1 app = new CrosshairOverlayDemo1(
                            "JFreeChart: CrosshairOverlayDemo1.java");
                    app.pack();
                    app.setVisible(true);
                }
            });
        }
    
    }