如何将MouseHandler正确添加到JFreeChart-FX以将图表从左向右拖动 [英] How do I properly add a MouseHandler to my JFreeChart-FX to drag the chart from left to right

查看:99
本文介绍了如何将MouseHandler正确添加到JFreeChart-FX以将图表从左向右拖动的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我设法使用JFreeChart-FX创建烛台图表,并使用fxgraphics2d API将其显示.但是我对如何启用与图表的任何交互感到非常困惑,并且对此需要一些帮助.

I managed to create a Candlestick Chart using JFreeChart-FX and display it using the fxgraphics2d API. But I am pretty much confused on how to enable any interaction with my chart and need some help to this.

如果能在正确的方向上提供帮助,我将不胜感激.

I'd be very grateful for any help in the right direction.

我从示例开始起床并更改我的初始图表,以便它使用我的数据.然后,我使用自定义Canvas,该自定义Canvas利用fxgraphics2d使JPanel组件可作为我的JavaFX应用程序的节点进行访问. 所以我知道例如有一个特定的PanHandlerFX

I started with this example to get up my initial Chart and altered it so that it uses my data. Then I use a custom Canvas, which utilizes fxgraphics2d to make the JPanel component accessable as a node for my JavaFX applicaiton. So I know there is for example a specific PanHandlerFX class, but I am lost to utilize this. As far as I was able to research (e.g. here), I need to add the PanHandlerFX class to the list of availableMouseHandlers of my ChartCanvas. But my canvas does not offer anything like availableMouseHandlers. I feel lost now, since there is so few tutorials and information to find regarding the JFree-FX charts and the documentation does not help me either.

这是我的自定义画布类:

Here is my custom canvas class:

import javafx.scene.canvas.Canvas;
import org.jfree.chart.JFreeChart;
import org.jfree.fx.FXGraphics2D;

import java.awt.geom.Rectangle2D;

public class ChartCanvas extends Canvas {

    JFreeChart chart;
    private FXGraphics2D graphics2D;

    public ChartCanvas(JFreeChart chart) {
        this.chart = chart;
        this.graphics2D = new FXGraphics2D(getGraphicsContext2D());
        // Redraw canvas when size changes.
        widthProperty().addListener(e -> draw());
        heightProperty().addListener(e -> draw());

    }

    private void draw() {
        double width = getWidth();
        double height = getHeight();
        getGraphicsContext2D().clearRect(0, 0, width, height);
        this.chart.draw(this.graphics2D, new Rectangle2D.Double(0, 0, width, height));
        //(this.graphics2D,, new Rectangle2D.Double(0, 0, width, height));
    }
}

这是我自定义的JFreeChart:

Here is my custom JFreeChart:

import javafx.collections.ObservableList;
import org.ezstrats.model.chartData.Candlestick;
import org.ezstrats.model.chartData.Exchange;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.DateAxis;
import org.jfree.chart.axis.NumberAxis;
import org.jfree.chart.labels.HighLowItemLabelGenerator;
import org.jfree.chart.labels.StandardXYToolTipGenerator;
import org.jfree.chart.plot.CombinedDomainXYPlot;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.renderer.xy.CandlestickRenderer;
import org.jfree.chart.renderer.xy.XYBarRenderer;
import org.jfree.data.time.FixedMillisecond;
import org.jfree.data.time.TimeSeries;
import org.jfree.data.time.TimeSeriesCollection;
import org.jfree.data.time.ohlc.OHLCSeries;
import org.jfree.data.time.ohlc.OHLCSeriesCollection;

import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import java.text.DateFormat;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;

public class JFreeCandlestickChart extends JPanel {

    private static final DateFormat READABLE_TIME_FORMAT = new SimpleDateFormat("kk:mm:ss");

    private OHLCSeries ohlcSeries;
    private TimeSeries volumeSeries;
    private JFreeChart candlestickChart;

    public JFreeCandlestickChart(String title) {
        ObservableList<Candlestick> candlesticks = Exchange.getCandlesticks();
        // Create new chart
        candlestickChart = createChart(title, candlesticks);
        // Create new chart panel
        final ChartPanel chartPanel = new ChartPanel(candlestickChart);
        chartPanel.setPreferredSize(new Dimension(832, 468));
        chartPanel.getChart().getXYPlot().getDomainAxis().setAutoRange(false);
        chartPanel.getChart().getXYPlot().getDomainAxis().setLowerBound(candlesticks.get(candlesticks.size() - 300).getTimestampOpen());
        chartPanel.getChart().getXYPlot().getDomainAxis().setUpperBound(candlesticks.get(candlesticks.size() - 1).getTimestampOpen());
        // Enable zooming - not workign?! ...
        chartPanel.setMouseZoomable(true);
        chartPanel.setMouseWheelEnabled(true);
        chartPanel.addMouseMotionListener(new MouseMotionAdapter() {
            @Override
            public void mouseDragged(MouseEvent e) {
                // process before
                super.mouseDragged(e);
                chartPanel.getChart().getXYPlot().getDomainAxis().configure();
                // process after
            }
        });


        add(chartPanel, BorderLayout.CENTER);
    }

    public JFreeChart createChart(String title, ObservableList<Candlestick> candlesticks){

        /**
         * 1st:
         * Creating candlestick subplot
         */
        // Create OHLCSeriesCollection as a price dataset for candlestick chart
        OHLCSeriesCollection candlestickDataset = new OHLCSeriesCollection();
        ohlcSeries = new OHLCSeries("Price");
        candlestickDataset.addSeries(ohlcSeries);

        // Create candlestick chart priceAxis
        NumberAxis priceAxis = new NumberAxis("Price");
        priceAxis.setAutoRangeIncludesZero(false);

        // Create candlestick chart renderer
        CandlestickRenderer candlestickRenderer = new CandlestickRenderer(CandlestickRenderer.WIDTHMETHOD_AVERAGE,
                false,
                new HighLowItemLabelGenerator(new SimpleDateFormat("kk:mm"), new DecimalFormat("0.00000000")));

        // Create candlestickSubplot
        XYPlot candlestickSubplot = new XYPlot(candlestickDataset, null, priceAxis, candlestickRenderer);
        candlestickSubplot.setBackgroundPaint(Color.white);


        /**
         * 2nd:
         * Creating volume subplot
         */
        // creates TimeSeriesCollection as a volume dataset for volume chart
        TimeSeriesCollection volumeDataset = new TimeSeriesCollection();
        volumeSeries = new TimeSeries("Volume");
        volumeDataset.addSeries(volumeSeries);

        // Create volume chart volumeAxis
        NumberAxis volumeAxis = new NumberAxis("Volume");
        volumeAxis.setAutoRangeIncludesZero(true);

        // Set to no decimal
        volumeAxis.setNumberFormatOverride(new DecimalFormat("0"));

        // Create volume chart renderer
        XYBarRenderer timeRenderer = new XYBarRenderer();
        timeRenderer.setShadowVisible(false);
        timeRenderer.setDefaultToolTipGenerator(new StandardXYToolTipGenerator("Volume--> Time={1} Size={2}",
                new SimpleDateFormat("kk:mm"), new DecimalFormat("0")));

        // Create volumeSubplot
        XYPlot volumeSubplot = new XYPlot(volumeDataset, null, volumeAxis, timeRenderer);
        volumeSubplot.setBackgroundPaint(Color.white);


        /**
         * 3rd:
         * Adding Candles to this chart
         **/
         for (Candlestick candle: candlesticks){
            addCandleToChart(candle.getTimestampOpen(),
                    candle.getPriceOpen(),
                    candle.getPriceHigh(),
                    candle.getPriceLow(),
                    candle.getPriceClose(),
                    candle.getVolumeQuote());
        }


        /**
         * 4th:
         * Create chart main plot with two subplots (candlestickSubplot,
         * volumeSubplot) and one common dateAxis
         */
        // Creating charts common dateAxis
        DateAxis dateAxis = new DateAxis("Time");
        dateAxis.setDateFormatOverride(new SimpleDateFormat("dd.mm.yy kk:mm"));
        //dateAxis.setRange();
        // reduce the default left/right margin from 0.05 to 0.02
        dateAxis.setLowerMargin(0.02);
        dateAxis.setUpperMargin(0.02);
        dateAxis.setLabelAngle(0);

        // Create mainPlot
        CombinedDomainXYPlot mainPlot = new CombinedDomainXYPlot(dateAxis);
        mainPlot.setGap(10.0);
        mainPlot.add(candlestickSubplot, 4);
        mainPlot.add(volumeSubplot, 1);
        mainPlot.setOrientation(PlotOrientation.VERTICAL);
        mainPlot.setDomainPannable(true);

        JFreeChart chart = new JFreeChart(title, JFreeChart.DEFAULT_TITLE_FONT, mainPlot, false);
        //chart.removeLegend();

        // Einbetten in JScrollPaenl??? um Scrollen zu ermöglichen...
//        ChartPanel chartPanel = new ChartPanel(chart);


        return chart;
    }


    /**
     * Fill series with data.
     *
     * @param c opentime
     * @param o openprice
     * @param h highprice
     * @param l lowprice
     * @param c closeprice
     * @param v volume
     */
    private void addCandleToChart(long time, double o, double h, double l, double c, double v) {
        // Add bar to the data. Let's repeat the same bar
        FixedMillisecond t = new FixedMillisecond(time);
        //READABLE_TIME_FORMAT.parse(String.valueOf(time)));
        ohlcSeries.add(t, o, h, l, c);
        volumeSeries.add(t, v);
    }


    public void setOhlcSeries(OHLCSeries ohlcSeries) {
        this.ohlcSeries = ohlcSeries;
    }
    public void setVolumeSeries(TimeSeries volumeSeries) {
        this.volumeSeries = volumeSeries;
    }
    public OHLCSeries getOhlcSeries() {
        return ohlcSeries;
    }
    public TimeSeries getVolumeSeries() {
        return volumeSeries;
    }
    public JFreeChart getCandlestickChart() {
        return candlestickChart;
    }
}

这就是我打印图表(main.class)的方式:

And this is how I print the chart (main.class):

    // Switching Views
    public void drawNewChart(JFreeChart newChart){
        centerChart.getChildren().removeAll();

        ChartCanvas chartCanvas = new ChartCanvas(newChart);

        centerChart.getChildren().add(chartCanvas);
        chartCanvas.widthProperty().bind(centerChart.widthProperty());
        chartCanvas.heightProperty().bind(centerChart.heightProperty());

    }

推荐答案

此处所示,构造一个 ChartViewer JFreeChart一起创建交互式图表.查看者随附的 ChartCanvas 将为您管理PanHandlerFX.作为一个具体示例,将以下行添加到示例,然后按照

As shown here, construct a ChartViewer with your JFreeChart to create an interactive chart. The viewer's enclosed ChartCanvas will manage the PanHandlerFX for you. As a concrete example, add the following line to the example, and drag as described here:

plot.setDomainPannable(true);

原文:

向右拖动后:

顺便说一句,您可能会找到 JavaFX演示 在这种情况下很有帮助.

As an aside, you may find the JavaFX Demos helpful in this context.

这篇关于如何将MouseHandler正确添加到JFreeChart-FX以将图表从左向右拖动的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆