gpt4 book ai didi

java - jstockchart 添加第三个显示

转载 作者:行者123 更新时间:2023-12-01 13:55:42 25 4
gpt4 key购买 nike

我已经实现了jstockchart作为 jfreechart 的插件。

我改变了他们的JStockChartGettingStarted通过实现雅虎财经 API 来获取股票报价。

我运行以下规范:

  • JDK 1.7
  • commons-io-2.4
  • commons-lang3-3.1
  • jfreechart 1.0.15
  • jstockchart 0.4.3

我还使用 jstockchart 0.4.3 package 中找到的所有软件包.

现在我的结果如下:

enter image description here

现在我非常喜欢这个插件的一点是,数量和价格是分开的,但两个显示仍然是链接的。因此,如果我放大一个显示器,另一个显示器也会缩放。

我想知道如何在当前两个显示器下方添加另一个显示器,它也与其他两个显示器交互,正如我上面所解释的。

我知道使用的图是 combinedDomainXYPlot我可以简单地添加如下:

    if (timeseriesArea.getVolumeWeight() > 0) {
XYPlot volumePlot = createVolumePlot();
combinedDomainXYPlot.add(volumePlot, timeseriesArea
.getVolumeWeight());
}

但是如何添加另一个显示器?

更新

所以我想做的是添加一组额外的轴/一个额外的面板,如下所示:

enter image description here

所以我知道如何向任何面板添加额外的绘图,但不知道如何向整个面板添加额外的(第三个)面板。第三个面板也使用与前两个面板相同的 CombinedDomainXYPlot

我知道添加附加面板的代码应该位于下面的代码中。但在哪里呢?

渲染图的代码

package org.jstockchart.plot;

import java.awt.BasicStroke;

import org.jfree.chart.axis.SegmentedTimeline;
import org.jfree.chart.plot.CombinedDomainXYPlot;
import org.jfree.chart.plot.ValueMarker;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.renderer.xy.XYBarRenderer;
import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
import org.jfree.data.time.TimeSeriesCollection;
import org.jstockchart.area.PriceArea;
import org.jstockchart.area.TimeseriesArea;
import org.jstockchart.area.VolumeArea;
import org.jstockchart.axis.TimeseriesDateAxis;
import org.jstockchart.axis.TimeseriesNumberAxis;
import org.jstockchart.axis.logic.CentralValueAxis;
import org.jstockchart.axis.logic.LogicDateAxis;
import org.jstockchart.axis.logic.LogicNumberAxis;
import org.jstockchart.dataset.TimeseriesDataset;

/**
* Creates <code>CombinedDomainXYPlot</code> and <code>XYPlot</code> for the
* timeseries chart.
*
* @author Sha Jiang
*/
public class TimeseriesPlot {

private static final long serialVersionUID = 8799771872991017065L;

private TimeseriesDataset dataset = null;

private SegmentedTimeline timeline = null;

private TimeseriesArea timeseriesArea = null;

/**
* Creates a new <code>TimeseriesPlot</code> instance.
*
* @param dataset
* timeseries data set(<code>null</code> not permitted).
* @param timeline
* a "segmented" timeline.
* @param timeseriesArea
* timeseries area.
*/
public TimeseriesPlot(TimeseriesDataset dataset,
SegmentedTimeline timeline, TimeseriesArea timeseriesArea) {
if (dataset == null) {
throw new IllegalArgumentException("Null 'dataset' argument.");
}
this.dataset = dataset;

this.timeline = timeline;

if (timeseriesArea == null) {
throw new IllegalArgumentException(
"Null 'timeseriesArea' argument.");
}
this.timeseriesArea = timeseriesArea;
}

private CombinedDomainXYPlot createCombinedXYPlot() {
LogicDateAxis logicDateAxis = timeseriesArea.getlogicDateAxis();
TimeseriesDateAxis dateAxis = new TimeseriesDateAxis(logicDateAxis
.getLogicTicks());
if (timeline != null) {
dateAxis.setTimeline(timeline);
}

CombinedDomainXYPlot combinedDomainXYPlot = new CombinedDomainXYPlot(
dateAxis);
combinedDomainXYPlot.setGap(timeseriesArea.getGap());
combinedDomainXYPlot.setOrientation(timeseriesArea.getOrientation());
combinedDomainXYPlot.setDomainAxis(dateAxis);
combinedDomainXYPlot.setDomainAxisLocation(timeseriesArea
.getDateAxisLocation());
combinedDomainXYPlot.setDomainPannable(true);
combinedDomainXYPlot.setRangePannable(true);

if (timeseriesArea.getPriceWeight() <= 0
&& timeseriesArea.getVolumeWeight() <= 0) {
throw new IllegalArgumentException(
"Illegal weight value: priceWeight="
+ timeseriesArea.getPriceWeight()
+ ", volumeWeight="
+ timeseriesArea.getVolumeWeight());
}

if (timeseriesArea.getPriceWeight() > 0) {
XYPlot pricePlot = createPricePlot();
combinedDomainXYPlot
.add(pricePlot, timeseriesArea.getPriceWeight());
}

if (timeseriesArea.getVolumeWeight() > 0) {
XYPlot volumePlot = createVolumePlot();
combinedDomainXYPlot.add(volumePlot, timeseriesArea
.getVolumeWeight());
}

return combinedDomainXYPlot;
}

private XYPlot createPricePlot() {
PriceArea priceArea = timeseriesArea.getPriceArea();
TimeSeriesCollection priceDataset = new TimeSeriesCollection();
priceDataset.addSeries(dataset.getPriceTimeSeries().getTimeSeries());
if (priceArea.isAverageVisible()) {
priceDataset.addSeries(dataset.getAverageTimeSeries()
.getTimeSeries());
}

CentralValueAxis logicPriceAxis = priceArea.getLogicPriceAxis();
TimeseriesNumberAxis priceAxis = new TimeseriesNumberAxis(
logicPriceAxis.getLogicTicks());
XYLineAndShapeRenderer priceRenderer = new XYLineAndShapeRenderer(true,
false);
priceAxis.setUpperBound(logicPriceAxis.getUpperBound());
priceAxis.setLowerBound(logicPriceAxis.getLowerBound());
priceRenderer.setSeriesPaint(0, priceArea.getPriceColor());
priceRenderer.setSeriesPaint(1, priceArea.getAverageColor());

TimeseriesNumberAxis rateAxis = new TimeseriesNumberAxis(logicPriceAxis
.getRatelogicTicks());
rateAxis.setUpperBound(logicPriceAxis.getUpperBound());
rateAxis.setLowerBound(logicPriceAxis.getLowerBound());

XYPlot plot = new XYPlot(priceDataset, null, priceAxis, priceRenderer);
plot.setBackgroundPaint(priceArea.getBackgroudColor());
plot.setOrientation(priceArea.getOrientation());
plot.setRangeAxisLocation(priceArea.getPriceAxisLocation());

if (priceArea.isRateVisible()) {
plot.setRangeAxis(1, rateAxis);
plot.setRangeAxisLocation(1, priceArea.getRateAxisLocation());
plot.setDataset(1, null);
plot.mapDatasetToRangeAxis(1, 1);
}

if (priceArea.isMarkCentralValue()) {
Number centralPrice = logicPriceAxis.getCentralValue();
if (centralPrice != null) {
plot.addRangeMarker(new ValueMarker(centralPrice.doubleValue(),
priceArea.getCentralPriceColor(), new BasicStroke()));
}
}
return plot;
}

private XYPlot createVolumePlot() {
VolumeArea volumeArea = timeseriesArea.getVolumeArea();
LogicNumberAxis logicVolumeAxis = volumeArea.getLogicVolumeAxis();

TimeseriesNumberAxis volumeAxis = new TimeseriesNumberAxis(
logicVolumeAxis.getLogicTicks());
volumeAxis.setUpperBound(logicVolumeAxis.getUpperBound());
volumeAxis.setLowerBound(logicVolumeAxis.getLowerBound());
volumeAxis.setAutoRangeIncludesZero(false);
XYBarRenderer volumeRenderer = new XYBarRenderer();
volumeRenderer.setSeriesPaint(0, volumeArea.getVolumeColor());
volumeRenderer.setShadowVisible(false);

XYPlot plot = new XYPlot(new TimeSeriesCollection(dataset
.getVolumeTimeSeries()), null, volumeAxis, volumeRenderer);
plot.setBackgroundPaint(volumeArea.getBackgroudColor());
plot.setOrientation(volumeArea.getOrientation());
plot.setRangeAxisLocation(volumeArea.getVolumeAxisLocation());
return plot;
}

public CombinedDomainXYPlot getTimeseriesPlot() {
return createCombinedXYPlot();
}

public TimeseriesDataset getDataset() {
return dataset;
}

public void setDataset(TimeseriesDataset dataset) {
if (dataset == null) {
throw new IllegalArgumentException("Null 'dataset' argument.");
}
this.dataset = dataset;
}

public SegmentedTimeline getTimeline() {
return timeline;
}

public void setTimeline(SegmentedTimeline timeline) {
this.timeline = timeline;
}

public TimeseriesArea getTimeseriesArea() {
return timeseriesArea;
}

public void setTimeseriesArea(TimeseriesArea timeseriesArea) {
if (timeseriesArea == null) {
throw new IllegalArgumentException(
"Null 'timeseriesArea' argument.");
}
this.timeseriesArea = timeseriesArea;
}
}

前面板显示代码如下:

GUI 代码

package gui;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import java.text.DateFormat;
import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;
import java.util.Locale;
import java.util.StringTokenizer;

import javax.swing.JFrame;

import org.jfree.chart.ChartPanel;
import org.jfree.chart.ChartUtilities;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.SegmentedTimeline;
import org.jfree.data.Range;
import org.jfree.data.time.Minute;
import org.jfree.data.xy.OHLCDataItem;
import org.jstockchart.JStockChartFactory;
import org.jstockchart.area.PriceArea;
import org.jstockchart.area.TimeseriesArea;
import org.jstockchart.area.VolumeArea;
import org.jstockchart.axis.TickAlignment;
import org.jstockchart.axis.logic.CentralValueAxis;
import org.jstockchart.axis.logic.LogicDateAxis;
import org.jstockchart.axis.logic.LogicNumberAxis;
import org.jstockchart.dataset.TimeseriesDataset;
import org.jstockchart.model.TimeseriesItem;
import org.jstockchart.util.DateUtils;

/**
* Demo application for JStockChart timeseries.
*
* @author Sha Jiang
*/
public class TimeseriesChartDemo {

public static int period = 400;

public static void main(String[] args) throws IOException {
String imageDir = "./images";
File images = new File(imageDir);
if (!images.exists()) {
images.mkdir();
}
String imageFile = imageDir + "/jstockchart-timeseries.png";


Date startTime = DateUtils.createDate(2008, 1, 1, 9, 30, 0);
Date endTime = DateUtils.createDate(2008, 1, 1, 15, 0, 0);
// 'data' is a list of TimeseriesItem instances.
List<TimeseriesItem> data = getData("AAPL", period, "d");

// the 'timeline' indicates the segmented time range '00:00-11:30, 13:00-24:00'.
SegmentedTimeline timeline = new SegmentedTimeline(
SegmentedTimeline.DAY_SEGMENT_SIZE, 1351, 89);
timeline.setStartTime(SegmentedTimeline.firstMondayAfter1900() + 780
* SegmentedTimeline.DAY_SEGMENT_SIZE);

// Creates timeseries data set.
TimeseriesDataset dataset = new TimeseriesDataset(Minute.class, 1,
timeline, true);
dataset.addDataItems(data);

DecimalFormatSymbols otherSymbols = new DecimalFormatSymbols(Locale.US);
otherSymbols.setDecimalSeparator('.');
otherSymbols.setGroupingSeparator(',');
DecimalFormat df = new DecimalFormat(".##", otherSymbols);

// Creates logic price axis.
CentralValueAxis logicPriceAxis = new CentralValueAxis(
dataset.getPriceTimeSeries().getTimeSeries().getValue(data.size()-1).doubleValue(), new Range(
dataset.getMinPrice().doubleValue(), dataset
.getMaxPrice().doubleValue()), 9,
df);
PriceArea priceArea = new PriceArea(logicPriceAxis);

// Creates logic volume axis.
LogicNumberAxis logicVolumeAxis = new LogicNumberAxis(new Range(dataset
.getMinVolume().doubleValue(), dataset.getMaxVolume()
.doubleValue()), 5, new DecimalFormat("0"));
VolumeArea volumeArea = new VolumeArea(logicVolumeAxis);

TimeseriesArea timeseriesArea = new TimeseriesArea(priceArea,
volumeArea, createlogicDateAxis(DateUtils
.createDate(2008, 1, 1)));

JFreeChart jfreechart = JStockChartFactory.createTimeseriesChart(
"Stock chart test with two seperate displays", dataset, timeline, timeseriesArea,
false);


JFrame outside = new JFrame();
ChartPanel chartPanel = new ChartPanel(jfreechart, false);

chartPanel.setMouseWheelEnabled(true);

outside.add(chartPanel);

outside.setVisible(true);

ChartUtilities
.saveChartAsPNG(new File(imageFile), jfreechart, 545, 300);
}

// Specifies date axis ticks.
private static LogicDateAxis createlogicDateAxis(Date baseDate) {
LogicDateAxis logicDateAxis = new LogicDateAxis(baseDate,
new SimpleDateFormat("HH:mm"));
logicDateAxis.addDateTick("09:30", TickAlignment.START);
logicDateAxis.addDateTick("10:00");
logicDateAxis.addDateTick("10:30");
logicDateAxis.addDateTick("11:00");
logicDateAxis.addDateTick("11:30", TickAlignment.END);
logicDateAxis.addDateTick("13:00", TickAlignment.START);
logicDateAxis.addDateTick("13:30");
logicDateAxis.addDateTick("14:00");
logicDateAxis.addDateTick("14:30", TickAlignment.END);
logicDateAxis.addDateTick("15:00", TickAlignment.END);
return logicDateAxis;
}

static List<TimeseriesItem> dataItems;

static boolean TodayAdded = true;

static ArrayList<Double> prices;
static ArrayList<Date> dates;

static List<TimeseriesItem> getData(String stockSymbol, int periodToLoad, String periodUnit) {

TodayAdded = true;

dataItems = new ArrayList<TimeseriesItem>();

Date today = new Date();
today = addDays(today, 1);
Date beginDate = addDays(today, -periodToLoad);

GregorianCalendar BEGIN = (GregorianCalendar) DateToCalendar(beginDate);
GregorianCalendar END = (GregorianCalendar) DateToCalendar(today);

String QUOTE = constructURL(stockSymbol, BEGIN, END, periodUnit);

try {
String strUrl = QUOTE;
URL url = new URL(strUrl);
BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream()));
DateFormat df = new SimpleDateFormat("y-M-d");

dates = new ArrayList<Date>();
prices = new ArrayList<Double>();

String inputLine;
in.readLine();
int counter = 0;

while ((inputLine = in.readLine()) != null) {
StringTokenizer st = new StringTokenizer(inputLine, ",");

Date date = df.parse( st.nextToken() );
double open = Double.parseDouble( st.nextToken() );
double high = Double.parseDouble( st.nextToken() );
double low = Double.parseDouble( st.nextToken() );
double close = Double.parseDouble( st.nextToken() );
double volume = Double.parseDouble( st.nextToken() );
double adjClose = Double.parseDouble( st.nextToken() );

double price = close;

dataItems.add(new TimeseriesItem(date, close, volume));

System.out.println(close);

dates.add(date);
prices.add(close);
}
in.close();
}
catch (Exception e) {
e.printStackTrace();
}

//Reversal of dates
Collections.reverse(dates);
Collections.reverse(prices);
//Data from Yahoo is from newest to oldest. Reverse so it is oldest to newest


return dataItems;
}

public static Date addDays(Date date, int days)
{
Calendar cal = Calendar.getInstance();
cal.setTime(date);
cal.add(Calendar.DATE, days); //minus number would decrement the days
return cal.getTime();
}

public static String constructURL(String symbol, Calendar start, Calendar end, String periodUnit) {
return "http://ichart.finance.yahoo.com/table.csv" +
"?s=" +
symbol +
"&a=" +
Integer.toString(start.get(Calendar.MONTH)) +
"&b=" +
start.get(Calendar.DAY_OF_MONTH) +
"&c=" +
Integer.toString(start.get(Calendar.YEAR)) +
"&d=" +
Integer.toString(end.get(Calendar.MONTH)) +
"&e=" +
Integer.toString(end.get(Calendar.DAY_OF_MONTH)) +
"&f=" +
Integer.toString(end.get(Calendar.YEAR)) +
"&g=" +
periodUnit +
"&ignore=.csv";
}

public static Calendar DateToCalendar(Date date){
Calendar cal = Calendar.getInstance();
cal.setTime(date);
return cal;
}
}

希望有人能帮助我。提前致谢。

最佳答案

trashgod又对了。他确实是jfreechart之神。

我发现jstockchart包中的CombinedDomainXYPlot是由一个名为org.jstockchart.axis.logic的包构建的,它确保了每个新情节有自己的框架。

或者换句话说,该包的行为如下:

  • 创建(完整)独立图表
  • 将图形添加到CombinedDomainXYPlot
  • 该包将确保图表拥有自己的面板

用编码术语来说,这意味着以下语句:

    if (timeseriesArea.getPriceWeight() > 0) {
XYPlot pricePlot = createPricePlot();
combinedDomainXYPlot
.add(pricePlot, timeseriesArea.getPriceWeight());
}

if (timeseriesArea.getVolumeWeight() > 0) {
XYPlot volumePlot = createVolumePlot();
combinedDomainXYPlot.add(volumePlot, timeseriesArea
.getVolumeWeight());
}

if (timeseriesArea.getPriceWeight() > 0) {
XYPlot pricePlot2 = createPricePlot();
combinedDomainXYPlot
.add(pricePlot2, timeseriesArea.getPriceWeight());
}

创建以下输出:

enter image description here

这正是我想要实现(或想要展示)的。

非常感谢您trashgod ,我不知道 jstockchart 包是这样工作的。

关于java - jstockchart 添加第三个显示,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19645117/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com