- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我设法使用 JFreeChart-FX
创建了一个烛台图表,并使用 fxgraphics2d
API 显示它。但我对如何启用与我的图表的任何交互感到非常困惑,需要一些帮助。
如果在正确的方向上提供任何帮助,我将不胜感激。
我从 this 开始例如,建立我的初始图表并对其进行更改,以便它使用我的数据。然后我使用自定义 Canvas
,它利用 fxgraphics2d
使 JPanel
组件可作为我的 JavaFX
的节点访问应用程序。所以我知道有一个特定的 PanHandlerFX
class ,但我无法利用它。据我的研究(例如 here),我需要将 PanHandlerFX
类添加到我的 ChartCanvas 的 availableMouseHandlers
列表中。但是我的 canvas
不提供任何类似 availableMouseHandlers
的东西。我现在感到迷茫,因为关于 JFree-FX 图表的教程和信息很少,而且文档也对我没有帮助。
这是我的自定义 Canvas 类:
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:
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) 的方式:
// 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());
}
最佳答案
如图here , 构造一个 ChartViewer
使用您的 JFreeChart
创建交互式图表。查看器的封闭ChartCanvas
将为您管理 PanHandlerFX
。作为具体示例,将以下行添加到 example , 并按照描述拖动 here :
plot.setDomainPannable(true);
原文:
向右拖动后:
顺便说一句,您可能会发现 JavaFX Demos在这方面很有帮助。
关于java - 如何正确地将 MouseHandler 添加到我的 JFreeChart-FX 以从左向右拖动图表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57696148/
我在 Web 应用程序中尝试了一些字节码操作,到目前为止,效果很好。现在我需要在代码中的某些特定位置注入(inject)一些字节代码。我用 switch 语句和 method.inserAt(); 尝
我正在尝试对数组中的对象值求和,然后计算每个值相对于总数的百分比。 这里是数组: [ { "ratiototale": [ [ { "0":
我在接口(interface)中有以下方法.. Task> SearchAsync(TU searchOptions); 效果很好。 现在我正在尝试进行单元测试以测试何时出现问题 - 代码会抛出异常。
我似乎无法让 reveal 开始工作,我已经严格遵守所有内容,添加 modernizr,添加插件,添加 css(reveal 显然包含在 foundation 中),在开始时初始化 foundatio
我正在尝试移植 raspberrypi's userspace 的位从 C 到 golang 的代码,我遇到了一个涉及 ioctl() 的程序。 我在执行 C 代码时遇到了问题 #define MAJ
我一直在尝试用纯 Java 制作一个简单的游戏,但在绘图时遇到了问题。我正在尝试保持相对较高的帧速率,但是 JFrame.repaint() 不能被“强制”并且只是在下一个可用机会重绘帧的请求这一事实
给定一个字符串 "2*(i+j) = 20 我想返回 ((lambda x: x >= 20), ['i']) 我可以然后直接提供给 constraint。 最佳答案 您正在寻找 eval 的替代方法
我对改进我的 javascript 代码以使其成为正确的 OOP 很感兴趣....目前我倾向于做这样的事情: jQuery(document).ready(function () { Page
我有一个调用两个动画 Action 的事件监听器。不幸的是,它们的开始有少量错开(例如,函数中的第一个首先开始)。 有谁知道正确同步它们的方法吗? 这是我的代码: $("#nav ul li a").
我只需要检查目录是否存在!但是,如果目录是“E:\Test”,其中 E: 是 CD/DVD 驱动器,并且上面没有插入磁盘,我会看到以下 Delphi 和 Windows 问题。 第一种方法: func
同样的问题: https://stackoverflow.com/questions/11294207/exchange-web-services-argumentexception-using-my
如果您跳转到 this question 中的第一个答案你会看到他使用 Employee.prototype = new Person(); 将 Person.prototype 继承到 Employ
我需要知道如何正确地遍历元素的 ArrayList 并计算元素在列表中出现的次数,而无需事先知道该元素。我尝试了几种方法并且有一种目前有效,但我觉得它很丑陋且不合适。 为了更深入地解释,我有一个 ja
我有一个用 Python 编写的(非常基本但工作完美的)AWS lambda 函数,但是它具有嵌入式凭证以连接到:1)外部网络服务2) DynamoDB 表。 该函数的作用相当基本:它针对服务发布登录
我很好奇 Tornado 推荐的查询 Redis(或任何数据库)的方法是什么。 我见过一些像 https://gist.github.com/357306 这样的例子但他们似乎都在使用对 redis
这更像是一个“我做得对吗”的问题。 快速背景故事:我已经构建了一个 gradle 插件(在一个独立的 gradle/groovy 项目中)。我在另一个 java 项目中使用它。客户项目通过以下方式引用
在我的代码中,我有: function handleMessage() { const twilio = require('twilio')(process.env.TWILIO_ACCOUNT_
我正在努力在 Linux 中刷新嵌入式设备的先前 ROM 转储。我以前的转储包含 oob 数据。我是用nandwrite -n -N -o/dev/mtd0 backup.bin写的,然后再做一次RO
我正在尝试使用 go 为 react-router 提供服务,我已经做到了,但我遇到了麻烦,我认为我做的方式不正确,或者不完整。我正在使用 Mux。我遇到的麻烦是当我按下 时在我的应用程序中,它正确
我正在尝试 promise JSON.parse 方法,但不幸的是没有任何运气。这是我的尝试: Promise.promisify(JSON.parse, JSON)(data).then((resu
我是一名优秀的程序员,十分优秀!