OpenSeSim/src/chart/Chart.java

704 lines
20 KiB
Java
Raw Normal View History

2017-01-08 03:14:27 +01:00
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package chart;
2017-01-22 07:03:16 +01:00
import sesim.OHLCDataItem;
import sesim.OHLCData;
2017-01-08 03:14:27 +01:00
import java.awt.*;
2017-01-08 13:16:00 +01:00
import sesim.Exchange.*;
import sesim.Quote;
2017-01-22 10:04:50 +01:00
import gui.Globals;
2017-01-13 08:16:09 +01:00
import java.awt.geom.Rectangle2D;
2017-01-20 17:03:50 +01:00
import java.text.DateFormat;
import java.text.SimpleDateFormat;
2017-01-12 23:16:37 +01:00
import java.util.ArrayList;
2017-01-20 17:03:50 +01:00
import java.util.Date;
2017-01-12 23:16:37 +01:00
import java.util.Iterator;
2017-02-17 08:33:19 +01:00
import javax.swing.JMenuItem;
2017-02-18 17:44:25 +01:00
import javax.swing.JScrollPane;
import javax.swing.JViewport;
2017-01-23 18:56:09 +01:00
import javax.swing.Scrollable;
import sesim.MinMax;
2017-02-18 17:44:25 +01:00
import sesim.Scheduler;
2017-01-08 03:14:27 +01:00
/**
*
* @author 7u83 <7u83@mail.ru>
*/
2017-01-23 18:56:09 +01:00
public class Chart extends javax.swing.JPanel implements QuoteReceiver, Scrollable {
2017-03-27 01:11:50 +02:00
private int em_height;
private int em_width;
2017-02-18 23:32:03 +01:00
2017-03-27 01:31:55 +02:00
protected double x_legend_height = 3;
2017-03-27 01:11:50 +02:00
protected double x_unit_width = 1.0;
/**
* width of y legend in em
*/
2017-02-18 17:44:25 +01:00
protected float y_legend_width = 10;
2017-01-23 18:56:09 +01:00
protected int num_bars = 4000;
protected Rectangle clip_bounds = new Rectangle();
2017-01-31 08:04:11 +01:00
protected Dimension gdim;
2017-01-23 18:56:09 +01:00
2017-02-04 16:29:45 +01:00
private int first_bar, last_bar;
2017-02-16 18:37:08 +01:00
public final void initChart() {
2017-02-07 01:53:43 +01:00
// data = new OHLCData(60000*30);
2017-02-16 18:37:08 +01:00
//data = new OHLCData(60000*30);
2017-02-17 08:33:19 +01:00
//data = Globals.se.getOHLCdata(60000 * 30);
2017-02-18 17:44:25 +01:00
this.setCompression(10000);
2017-02-04 16:29:45 +01:00
}
2017-01-08 03:14:27 +01:00
/**
* Creates new form Chart
*/
public Chart() {
2017-02-18 23:32:03 +01:00
if (Globals.se == null) {
2017-02-18 17:44:25 +01:00
return;
}
2017-01-08 03:14:27 +01:00
initComponents();
2017-02-04 16:29:45 +01:00
initChart();
2017-02-17 08:33:19 +01:00
initCtxMenu();
2017-02-16 18:37:08 +01:00
//setCompression(60000);
2017-01-22 10:04:50 +01:00
if (Globals.se == null) {
2017-01-09 08:25:29 +01:00
return;
}
2017-01-22 10:04:50 +01:00
Globals.se.addQuoteReceiver(this);
2017-01-08 03:14:27 +01:00
2017-02-18 23:32:03 +01:00
// scrollPane=new JScrollPane();
// scrollPane.setViewportView(this);
2017-01-08 03:14:27 +01:00
}
2017-01-09 08:25:29 +01:00
2017-02-18 23:32:03 +01:00
private String[] ctxMenuCompressionText = {
2017-02-17 08:33:19 +01:00
"5 s", "10 s", "15 s", "30 s",
"1 m", "2 m", "5 m", "10 m", "15 m", "30 m",
"1 h", "2 h", "4 h",
"1 d", "2 d"
};
2017-02-18 23:32:03 +01:00
private Integer[] ctxMenuCompressionValues = {
5 * 1000, 10 * 1000, 15 * 1000, 30 * 1000,
60 * 1000, 2 * 60 * 1000, 5 * 60 * 1000, 10 * 60 * 1000, 15 * 60 * 1000, 30 * 60 * 1000,
1 * 3600 * 1000, 2 * 3600 * 1000, 4 * 3600 * 1000,
1 * 24 * 3600 * 1000, 2 * 24 * 3600 * 1000
2017-02-17 08:33:19 +01:00
};
2017-02-18 23:32:03 +01:00
2017-02-17 08:33:19 +01:00
void initCtxMenu() {
2017-02-18 23:32:03 +01:00
for (int i = 0; i < this.ctxMenuCompressionValues.length; i++) {
JMenuItem item = new JMenuItem(this.ctxMenuCompressionText[i]);
item.addActionListener((java.awt.event.ActionEvent evt) -> {
ctxMenuCompActionPerformed(evt);
2017-02-17 08:33:19 +01:00
});
2017-02-18 23:32:03 +01:00
this.compMenu.add(item);
}
2017-02-17 08:33:19 +01:00
}
2017-02-18 23:32:03 +01:00
2017-02-17 08:33:19 +01:00
private void ctxMenuCompActionPerformed(java.awt.event.ActionEvent evt) {
String cmd = evt.getActionCommand();
2017-02-18 23:32:03 +01:00
for (int i = 0; i < this.ctxMenuCompressionText.length; i++) {
if (this.ctxMenuCompressionText[i].equals(cmd)) {
2017-03-27 01:31:55 +02:00
2017-02-17 08:33:19 +01:00
this.setCompression(this.ctxMenuCompressionValues[i]);
}
}
2017-02-26 03:01:24 +01:00
2017-02-18 23:32:03 +01:00
}
2017-02-17 08:33:19 +01:00
2017-02-04 16:29:45 +01:00
OHLCData data;
2017-01-20 17:03:50 +01:00
2017-01-23 18:56:09 +01:00
@Override
public Dimension getPreferredScrollableViewportSize() {
return this.getPreferredSize();
}
2017-01-20 17:03:50 +01:00
2017-01-23 18:56:09 +01:00
@Override
public int getScrollableUnitIncrement(Rectangle visibleRect, int orientation, int direction) {
return 1;
}
@Override
public int getScrollableBlockIncrement(Rectangle visibleRect, int orientation, int direction) {
return 100;
}
@Override
public boolean getScrollableTracksViewportWidth() {
return false;
}
@Override
public boolean getScrollableTracksViewportHeight() {
return false;
2017-01-13 08:16:09 +01:00
}
2017-01-13 21:49:09 +01:00
2017-01-20 17:03:50 +01:00
class XLegendDef {
2017-03-24 08:35:00 +01:00
int big_tick = 10;
2017-01-20 17:03:50 +01:00
long start;
2017-01-22 07:03:16 +01:00
XLegendDef() {
2017-01-20 17:03:50 +01:00
}
2017-01-22 07:03:16 +01:00
String getAt(int unit) {
2017-02-18 23:32:03 +01:00
2017-02-18 17:44:25 +01:00
int fs = data.getFrameSize();
2017-02-18 23:32:03 +01:00
return Scheduler.formatTimeMillis(0 + unit * fs);
2017-02-18 17:44:25 +01:00
2017-01-20 17:03:50 +01:00
}
}
2017-02-18 23:32:03 +01:00
/**
* Draw the one and only one X legend
*
* @param g Graphics conext to draw
* @param xld Definition
*/
2017-01-22 07:03:16 +01:00
void drawXLegend(Graphics2D g, XLegendDef xld) {
2017-01-20 17:03:50 +01:00
2017-03-27 01:11:50 +02:00
//g = (Graphics2D) g.create();
int yw = (int) (this.y_legend_width * this.em_width);
2017-02-20 08:21:01 +01:00
2017-03-27 01:31:55 +02:00
g.setClip(clip_bounds.x, clip_bounds.y, clip_bounds.width - yw, clip_bounds.height);
2017-02-20 08:21:01 +01:00
2017-02-18 17:44:25 +01:00
Dimension dim = getSize();
2017-01-20 17:03:50 +01:00
int y = dim.height - em_height * 3;
2017-01-13 08:16:09 +01:00
g.drawLine(0, y, dim.width, y);
2017-01-22 07:03:16 +01:00
int n;
double x;
2017-03-27 01:31:55 +02:00
2017-03-24 19:55:56 +01:00
long big_tick = 1;
2017-03-27 01:31:55 +02:00
double btl, xxx;
2017-03-24 19:55:56 +01:00
do {
big_tick++;
2017-03-27 01:31:55 +02:00
btl = em_width * big_tick * x_unit_width;
xxx = 7 * em_width;
} while (btl < xxx);
2017-03-25 18:14:23 +01:00
2017-03-27 01:11:50 +02:00
for (n = 0, x = 0; x < dim.width; x += em_width * x_unit_width) {
2017-01-20 17:03:50 +01:00
2017-03-25 18:14:23 +01:00
if (n % big_tick == 1) {
2017-03-27 01:11:50 +02:00
g.drawLine((int) x, y, (int) x, y + em_width);
2017-02-18 17:44:25 +01:00
String text;
2017-01-22 07:03:16 +01:00
text = xld.getAt(n);
2017-02-18 23:32:03 +01:00
2017-01-20 17:03:50 +01:00
int swidth = g.getFontMetrics().stringWidth(text);
2017-03-27 01:31:55 +02:00
g.drawString(text, (int) x - swidth / 2, y + em_height * 2);
2017-03-24 19:55:56 +01:00
} else {
2017-03-27 01:11:50 +02:00
g.drawLine((int) x, y, (int) x, y + em_width / 2);
2017-03-24 19:55:56 +01:00
}
if (n % big_tick == 0) {
2017-01-20 17:03:50 +01:00
}
2017-01-22 07:03:16 +01:00
2017-03-27 01:31:55 +02:00
n += 1;
2017-01-20 17:03:50 +01:00
}
2017-01-22 07:03:16 +01:00
}
2017-01-20 17:03:50 +01:00
2017-01-22 07:03:16 +01:00
class RenderCtx {
2017-01-13 08:16:09 +01:00
2017-01-22 07:03:16 +01:00
Rectangle rect;
float scaling;
float min;
Graphics2D g;
float iwidth;
2017-01-13 08:16:09 +01:00
2017-01-23 18:56:09 +01:00
float getYc(float y) {
return getY(y);
//return rect.height - ((y - min) * scaling);
2017-01-22 07:03:16 +01:00
}
}
2017-01-13 08:16:09 +01:00
2017-02-18 23:32:03 +01:00
boolean logs = false;
2017-01-13 08:16:09 +01:00
2017-01-23 18:56:09 +01:00
float getY(float y) {
2017-03-27 01:31:55 +02:00
2017-03-25 18:14:23 +01:00
float ys = c_rect.height / c_mm.getDiff();
// ys = c_rect.height / c_mm.getDiff();
2017-03-27 01:31:55 +02:00
2017-03-25 18:14:23 +01:00
if (c_mm.isLog()) {
2017-03-27 01:31:55 +02:00
// c_mm.setLog(true);
// ys = c_rect.height / c_mm.getDiff();
// return (c_rect.height - (((float)Math.log(y) - c_mm.getMin()) * ys)) + c_rect.y;
return c_rect.height + c_rect.y - ((float) Math.log(y) - c_mm.getMin()) * ys;
/* float m = c_mm.getMax() / c_mm.getMin();
2017-02-16 18:37:08 +01:00
float fac = (float) c_rect.height / (float) Math.log(m);
2017-01-23 18:56:09 +01:00
2017-03-25 18:14:23 +01:00
float fmin = c_rect.height - ((float) Math.log((y / c_mm.getMin())) * fac);
2017-02-16 18:37:08 +01:00
2017-01-23 18:56:09 +01:00
return fmin;
2017-03-27 01:31:55 +02:00
*/
2017-03-25 18:14:23 +01:00
//return c_rect.height - ((float) Math.log((y - c_mm.getMin()) * c_yscaling) * fac);
2017-01-23 18:56:09 +01:00
}
2017-03-25 18:14:23 +01:00
return (c_rect.height - ((y - c_mm.getMin()) * c_yscaling)) + c_rect.y;
2017-01-23 18:56:09 +01:00
2017-03-25 18:14:23 +01:00
// return c_rect.height - ((y - c_mm.getMin()) * c_yscaling);
}
2017-03-27 01:31:55 +02:00
double getValAtY(float y) {
float val = 0;
// y = (c_rect.height - ((val - c_mm.getMin()) * c_yscaling)) + c_rect.y;
2017-03-25 18:14:23 +01:00
// y-c_rect.y = c_rect.height - ((val - c_mm.getMin()) * c_yscaling)
// y-c_rect.y-c_rect.height = - ((val - c_mm.getMin()) * c_yscaling)
// -(y-c_rect.y-c_rect.heigh) = (val - c_mm.getMin()) * c_yscaling
// (-(y-c_rect.y-c_rect.heigh))/c_yscaling = (val - c_mm.getMin())
2017-03-27 01:31:55 +02:00
if (c_mm.isLog()) {
float ys = c_rect.height / c_mm.getDiff();
2017-03-25 19:09:12 +01:00
//val = return c_rect.height + c_rect.y - ((float)Math.log(y) - c_mm.getMin()) * ys;
// val + ((float)Math.log(y) - c_mm.getMin()) * ys = c_rect.height + c_rect.y
// val/ys + ((float)Math.log(y) - c_mm.getMin()) = (c_rect.height + c_rect.y)/ys
// val/ys + ((float)Math.log(y) = (c_rect.height + c_rect.y)/ys + c_mm.getMin())
2017-03-25 19:09:12 +01:00
//return (-(Math.exp(y)-c_rect.y-c_rect.height))/ys+c_mm.getMin();
2017-03-27 01:31:55 +02:00
return Math.exp((c_rect.height + c_rect.y) / ys + c_mm.getMin() - y / ys);
2017-03-25 18:14:23 +01:00
}
2017-03-27 01:31:55 +02:00
return (-(y - c_rect.y - c_rect.height)) / c_yscaling + c_mm.getMin();
// return (y+c_rect.y-c_rect.height)/c_yscaling+c_mm.getMin();
2017-01-09 08:25:29 +01:00
}
2017-03-27 01:31:55 +02:00
2017-03-27 08:40:22 +02:00
2017-02-18 23:32:03 +01:00
private void drawCandleItem(RenderCtx ctx, int prevx, int x, OHLCDataItem prev, OHLCDataItem i) {
2017-01-22 07:03:16 +01:00
Graphics2D g = ctx.g;
Rectangle r = ctx.rect;
if (i.open < i.close) {
2017-01-23 18:56:09 +01:00
int xl = (int) (x + ctx.iwidth / 2);
2017-01-22 07:03:16 +01:00
g.setColor(Color.BLACK);
2017-01-23 18:56:09 +01:00
g.drawLine(xl, (int) ctx.getYc(i.close), xl, (int) ctx.getYc(i.high));
g.drawLine(xl, (int) ctx.getYc(i.low), xl, (int) ctx.getYc(i.open));
2017-01-22 07:03:16 +01:00
float w = ctx.iwidth;
2017-01-23 18:56:09 +01:00
float h = (int) (ctx.getYc(i.open) - ctx.getYc(i.close));
2017-01-22 07:03:16 +01:00
g.setColor(Color.GREEN);
2017-01-23 18:56:09 +01:00
g.fillRect((int) (x), (int) ctx.getYc(i.close), (int) w, (int) h);
2017-01-22 07:03:16 +01:00
g.setColor(Color.BLACK);
2017-01-23 18:56:09 +01:00
g.drawRect((int) (x), (int) ctx.getYc(i.close), (int) w, (int) h);
2017-01-22 07:03:16 +01:00
} else {
2017-01-23 18:56:09 +01:00
int xl = (int) (x + ctx.iwidth / 2);
2017-01-22 07:03:16 +01:00
g.setColor(Color.RED);
2017-01-23 18:56:09 +01:00
g.drawLine(xl, (int) ctx.getYc(i.high), xl, (int) ctx.getYc(i.close));
g.drawLine(xl, (int) ctx.getYc(i.open), xl, (int) ctx.getYc(i.low));
2017-01-22 07:03:16 +01:00
float w = ctx.iwidth;
2017-01-23 18:56:09 +01:00
float h = (int) (ctx.getYc(i.close) - ctx.getYc(i.open));
2017-01-22 07:03:16 +01:00
2017-01-23 18:56:09 +01:00
g.fillRect((int) (x), (int) ctx.getYc(i.open), (int) w, (int) h);
2017-01-22 07:03:16 +01:00
g.setColor(Color.BLACK);
2017-01-23 18:56:09 +01:00
g.drawRect((int) (x), (int) ctx.getYc(i.open), (int) w, (int) h);
2017-01-09 08:25:29 +01:00
2017-01-08 13:16:00 +01:00
}
2017-01-09 08:25:29 +01:00
2017-01-08 13:16:00 +01:00
}
2017-01-09 08:25:29 +01:00
2017-02-18 23:32:03 +01:00
private void drawBarItem(RenderCtx ctx, int prevx, int x, OHLCDataItem prev, OHLCDataItem i) {
Graphics2D g = ctx.g;
2017-02-19 15:04:07 +01:00
g.setColor(Color.BLACK);
2017-02-18 23:32:03 +01:00
g.drawLine(x, (int) ctx.getYc(0), x, (int) ctx.getYc(i.volume));
Rectangle r = ctx.rect;
}
2017-03-27 00:44:42 +02:00
/**
* Char types
*/
protected enum ChartType {
2017-02-18 23:32:03 +01:00
CANDLESTICK,
BAR,
VOL,
}
ChartType ct = ChartType.CANDLESTICK;
private void drawItem(RenderCtx ctx, int prevx, int x, OHLCDataItem prev, OHLCDataItem i) {
switch (ct) {
case CANDLESTICK:
this.drawCandleItem(ctx, prevx, x, prev, i);
break;
case VOL:
this.drawBarItem(ctx, prevx, x, prev, i);
break;
}
}
2017-01-23 18:56:09 +01:00
float c_yscaling;
2017-02-18 23:32:03 +01:00
private void drawYLegend(RenderCtx ctx) {
2017-01-23 18:56:09 +01:00
2017-02-19 15:04:07 +01:00
Graphics2D g = ctx.g;
Rectangle dim;
2017-02-18 23:32:03 +01:00
dim = this.clip_bounds;
2017-03-31 18:55:24 +02:00
// Dimension rv = this.getSize();
2017-01-23 18:56:09 +01:00
2017-03-27 01:11:50 +02:00
int yw = (int) (this.y_legend_width * this.em_width);
2017-01-23 18:56:09 +01:00
g.drawLine(dim.width + dim.x - yw, 0, dim.width + dim.x - yw, dim.height);
2017-03-27 01:31:55 +02:00
2017-03-25 18:14:23 +01:00
float y1 = getY(c_mm.getMin(false));
float y2 = getY(c_mm.getMax(false));
2017-03-27 01:31:55 +02:00
float ydiff = y1 - y2;
System.out.printf("%s y1: %f, y2: %f, diff %f\n", Boolean.toString(c_mm.isLog()), y1, y2, ydiff);
2017-01-23 18:56:09 +01:00
2017-03-31 18:55:24 +02:00
for (int yp = (int) y2; yp < y1; yp += em_width * 5) {
2017-03-27 01:31:55 +02:00
g.drawLine(dim.width + dim.x - yw, yp, dim.width + dim.x - yw + em_width, yp);
double v1 = getValAtY(yp);
g.drawString(String.format("%.2f", v1), dim.width + dim.x - yw + em_width * 1.5f, yp + c_font_height / 3);
}
2017-01-23 18:56:09 +01:00
2017-03-27 01:31:55 +02:00
// c_yscaling = c_rect.height / c_mm.getDiff();
//System.out.printf("Step: %f\n",step);
double v1, v2;
v1 = getValAtY(y1);
v2 = getValAtY(y2);
System.out.printf("v1 %f, v2 %f\n", v1, v2);
2017-01-23 18:56:09 +01:00
2017-03-25 18:14:23 +01:00
2017-03-27 01:31:55 +02:00
/* for (float y = c_mm.getMin(); y < c_mm.getMax(); y += step) {
2017-03-25 18:14:23 +01:00
int my = (int) getY(y); //c_rect.height - (int) ((y - c_mm.getMin()) * c_yscaling);
2017-01-23 18:56:09 +01:00
2017-03-27 01:11:50 +02:00
g.drawLine(dim.width + dim.x - yw, my, dim.width + dim.x - yw + em_width, my);
2017-01-23 18:56:09 +01:00
2017-03-27 01:11:50 +02:00
g.drawString(String.format("%.2f", y), dim.width + dim.x - yw + em_width * 1.5f, my + c_font_height / 3);
2017-01-23 18:56:09 +01:00
}
2017-03-27 01:31:55 +02:00
*/
2017-01-23 18:56:09 +01:00
}
private MinMax c_mm = null;
private Rectangle c_rect;
2017-02-18 23:32:03 +01:00
void drawChart(RenderCtx ctx) {
c_yscaling = c_rect.height / c_mm.getDiff();
ctx.g.setClip(null);
2017-02-19 15:04:07 +01:00
// ctx.g.setColor(Color.ORANGE);
// ctx.g.setClip(ctx.rect.x, ctx.rect.y, ctx.rect.width, ctx.rect.height);
// ctx.g.drawRect(ctx.rect.x, ctx.rect.y, ctx.rect.width, ctx.rect.height);
2017-02-18 23:32:03 +01:00
this.drawYLegend(ctx);
2017-02-19 15:04:07 +01:00
/// ctx.g.setColor(Color.ORANGE);
2017-03-27 01:11:50 +02:00
int yw = (int) (this.y_legend_width * this.em_width);
2017-02-19 15:04:07 +01:00
ctx.g.setClip(clip_bounds.x, clip_bounds.y, clip_bounds.width - yw, clip_bounds.height);
2017-02-18 23:32:03 +01:00
// ctx.g.setClip(ctx.rect.x, ctx.rect.y, ctx.rect.width-yw, ctx.rect.height);
OHLCDataItem prev = null;
for (int i = first_bar; i < last_bar && i < data.size(); i++) {
OHLCDataItem di = data.get(i);
2017-03-27 01:11:50 +02:00
int x = (int) (i * em_width * x_unit_width); //em_width;
2017-02-18 23:32:03 +01:00
this.drawItem(ctx, x - em_width, x, prev, di); //, ctx.scaling, data.getMin());
// myi++;
prev = di;
}
}
2017-02-19 15:04:07 +01:00
boolean autoScroll = true;
int lastvpos = 0;
2017-01-22 07:03:16 +01:00
private void draw(Graphics2D g) {
2017-01-23 18:56:09 +01:00
if (data == null) {
2017-01-22 08:53:02 +01:00
return;
2017-01-23 18:56:09 +01:00
}
if (data.size() == 0) {
2017-01-22 08:53:02 +01:00
return;
2017-01-23 18:56:09 +01:00
}
2017-03-26 21:36:53 +02:00
num_bars = data.size();
2017-03-27 01:31:55 +02:00
2017-01-23 18:56:09 +01:00
c_mm = data.getMinMax(first_bar, last_bar);
if (c_mm == null) {
return;
}
2017-03-25 18:14:23 +01:00
// c_mm.min/= 1; //-= c_mm.getMin()/ 2.0f;
// c_mm.max *= 1; //+= c_mm.getMax() / 10.0f;
2017-02-18 17:44:25 +01:00
em_height = g.getFontMetrics().getHeight();
em_width = g.getFontMetrics().stringWidth("M");
2017-02-18 23:32:03 +01:00
2017-01-22 07:03:16 +01:00
XLegendDef xld = new XLegendDef();
this.drawXLegend(g, xld);
2017-02-19 15:04:07 +01:00
int pwidth = (int) (em_width * x_unit_width * (num_bars + 1)) + clip_bounds.width;
// int phight = 400;
2017-02-16 18:37:08 +01:00
// phight=this.getVisibleRect().height;
2017-01-22 07:03:16 +01:00
2017-01-31 08:04:11 +01:00
this.setPreferredSize(new Dimension(pwidth, gdim.height));
2017-01-23 18:56:09 +01:00
this.revalidate();
2017-01-22 07:03:16 +01:00
2017-03-27 01:11:50 +02:00
int bww = (int) (data.size() * (this.x_unit_width * this.em_width));
int p0 = pwidth - clip_bounds.width - (clip_bounds.width - (int) (13 * em_width));
2017-02-19 15:04:07 +01:00
if (p0 < 0) {
p0 = 0;
}
JViewport vp = (JViewport) this.getParent();
Point pp = vp.getViewPosition();
Point cp = vp.getViewPosition();
2017-02-18 23:32:03 +01:00
2017-02-19 15:04:07 +01:00
if (autoScroll && this.lastvpos != cp.x) {
autoScroll = false;
}
2017-01-22 07:03:16 +01:00
2017-02-19 15:04:07 +01:00
if (!autoScroll && cp.x >= p0) {
autoScroll = true;
}
2017-01-22 07:03:16 +01:00
2017-02-19 15:04:07 +01:00
if (autoScroll) {
vp.setViewPosition(new Point(p0, 0));
lastvpos = p0;
}
2017-01-22 07:03:16 +01:00
2017-02-19 15:04:07 +01:00
int cheight = gdim.height - 6 * em_width;
int h = (int) (cheight * 0.8);
Rectangle r = new Rectangle(0, 0, pwidth, h);
c_rect = r;
RenderCtx ctx = new RenderCtx();
// c_rect.x = 0;
// c_rect.y = 50;
// c_rect.height = ;
2017-01-23 18:56:09 +01:00
ctx.rect = c_rect;
ctx.scaling = (float) r.height / (c_mm.getMax() - c_mm.getMin());
ctx.min = c_mm.getMin();
2017-01-22 07:03:16 +01:00
ctx.g = g;
2017-03-27 01:11:50 +02:00
ctx.iwidth = (float) ((x_unit_width * em_width) * 0.9f);
2017-01-23 18:56:09 +01:00
2017-02-18 23:32:03 +01:00
this.ct = ChartType.CANDLESTICK;
2017-03-27 01:31:55 +02:00
logs = true;
c_mm.setLog(true);
2017-02-18 23:32:03 +01:00
drawChart(ctx);
2017-01-23 18:56:09 +01:00
2017-02-18 23:32:03 +01:00
c_mm = data.getVolMinMax(first_bar, last_bar);
2017-01-23 18:56:09 +01:00
2017-03-25 18:14:23 +01:00
// c_mm.min = 0f;
c_mm.setMin(0);
2017-02-18 23:32:03 +01:00
2017-02-19 15:04:07 +01:00
int h1 = h + em_width;
h = (int) (cheight * 0.2);
r = new Rectangle(0, h1, pwidth, h);
c_rect = r;
// c_rect.x = 0;
// c_rect.y = 250;
// c_rect.height = 50;
2017-02-18 23:32:03 +01:00
ctx.rect = c_rect;
ctx.scaling = (float) r.height / (c_mm.getMax() - c_mm.getMin());
ctx.min = c_mm.getMin();
ctx.g = g;
2017-03-27 01:11:50 +02:00
ctx.iwidth = (float) ((x_unit_width * em_width) * 0.9f);
2017-01-22 07:03:16 +01:00
2017-03-27 01:31:55 +02:00
logs = false;
2017-03-25 18:14:23 +01:00
c_mm.setLog(false);
2017-02-18 23:32:03 +01:00
this.ct = ChartType.VOL;
drawChart(ctx);
2017-01-22 07:03:16 +01:00
2017-01-08 13:16:00 +01:00
}
2017-01-09 08:25:29 +01:00
2017-01-23 18:56:09 +01:00
private float c_font_height;
2017-01-08 08:48:31 +01:00
2017-01-23 18:56:09 +01:00
@Override
public final void paintComponent(Graphics g) {
2017-03-27 01:31:55 +02:00
if (Globals.se == null) {
2017-02-20 08:21:01 +01:00
return;
}
2017-03-27 01:31:55 +02:00
2017-01-23 18:56:09 +01:00
super.paintComponent(g);
2017-01-08 08:48:31 +01:00
2017-02-18 17:44:25 +01:00
// Calculate the number of pixels for 1 em
2017-03-27 01:11:50 +02:00
em_width = g.getFontMetrics().stringWidth("M");
2017-02-18 17:44:25 +01:00
2017-01-31 08:04:11 +01:00
this.gdim = this.getParent().getSize(gdim);
this.getParent().setPreferredSize(gdim);
2017-02-16 18:37:08 +01:00
2017-02-18 23:32:03 +01:00
//Object o = this.getParent();
2017-02-18 17:44:25 +01:00
JViewport vp = (JViewport) this.getParent();
2017-02-18 23:32:03 +01:00
//this.clip_bounds=g.getClipBounds();
this.clip_bounds = vp.getViewRect();
2017-03-27 01:11:50 +02:00
first_bar = (int) (clip_bounds.x / (this.x_unit_width * this.em_width));
last_bar = 1 + (int) ((clip_bounds.x + clip_bounds.width - (this.y_legend_width * em_width)) / (this.x_unit_width * this.em_width));
2017-02-18 23:32:03 +01:00
2017-03-27 01:11:50 +02:00
// num_bars = data.size(); // + (int) (clip_bounds.width / (this.x_unit_width * this.em_width))+5;
2017-03-26 21:36:53 +02:00
// num_bars=1;
2017-02-19 15:04:07 +01:00
c_font_height = g.getFontMetrics().getHeight();
2017-01-08 08:48:31 +01:00
2017-01-23 18:56:09 +01:00
draw((Graphics2D) g);
2017-01-08 03:14:27 +01:00
}
/**
* This method is called from within the constructor to initialize the form.
* WARNING: Do NOT modify this code. The content of this method is always
* regenerated by the Form Editor.
*/
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
private void initComponents() {
2017-02-16 18:37:08 +01:00
ctxMenu = new javax.swing.JPopupMenu();
2017-02-17 08:33:19 +01:00
compMenu = new javax.swing.JMenu();
2017-02-18 17:44:25 +01:00
jCheckBoxMenuItem1 = new javax.swing.JCheckBoxMenuItem();
2017-02-16 18:37:08 +01:00
2017-02-17 08:33:19 +01:00
compMenu.setText("Compression");
ctxMenu.add(compMenu);
2017-02-16 18:37:08 +01:00
2017-03-24 08:35:00 +01:00
jCheckBoxMenuItem1.setMnemonic('l');
2017-02-18 17:44:25 +01:00
jCheckBoxMenuItem1.setSelected(true);
2017-03-24 08:35:00 +01:00
jCheckBoxMenuItem1.setText("Log Scale");
jCheckBoxMenuItem1.setToolTipText("");
2017-02-18 17:44:25 +01:00
ctxMenu.add(jCheckBoxMenuItem1);
2017-01-08 13:16:00 +01:00
setBackground(java.awt.Color.white);
2017-01-22 21:41:45 +01:00
setBorder(null);
setOpaque(false);
2017-01-08 13:16:00 +01:00
setPreferredSize(new java.awt.Dimension(300, 300));
2017-01-08 08:48:31 +01:00
setRequestFocusEnabled(false);
2017-02-19 15:04:07 +01:00
addMouseWheelListener(new java.awt.event.MouseWheelListener() {
public void mouseWheelMoved(java.awt.event.MouseWheelEvent evt) {
formMouseWheelMoved(evt);
}
});
2017-02-16 18:37:08 +01:00
addMouseListener(new java.awt.event.MouseAdapter() {
public void mousePressed(java.awt.event.MouseEvent evt) {
formMousePressed(evt);
}
2017-03-26 21:36:53 +02:00
public void mouseReleased(java.awt.event.MouseEvent evt) {
formMouseReleased(evt);
}
2017-02-16 18:37:08 +01:00
});
2017-01-08 08:48:31 +01:00
2017-01-08 03:14:27 +01:00
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
this.setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
2017-02-18 17:44:25 +01:00
.addGap(0, 589, Short.MAX_VALUE)
2017-01-08 03:14:27 +01:00
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
2017-01-22 21:41:45 +01:00
.addGap(0, 300, Short.MAX_VALUE)
2017-01-08 03:14:27 +01:00
);
}// </editor-fold>//GEN-END:initComponents
2017-02-16 18:37:08 +01:00
private void formMousePressed(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_formMousePressed
2017-03-26 21:36:53 +02:00
System.out.printf("There was a mosue event\n");
2017-03-27 01:31:55 +02:00
2017-03-26 21:36:53 +02:00
if (!evt.isPopupTrigger() || true) {
System.out.printf("But there was no pupe trigger\n");
2017-02-16 18:37:08 +01:00
return;
2017-03-26 21:36:53 +02:00
}
2017-02-16 18:37:08 +01:00
2017-02-18 23:32:03 +01:00
// this.invalidate();
2017-02-18 17:44:25 +01:00
this.ctxMenu.setVisible(true);
2017-02-16 18:37:08 +01:00
this.ctxMenu.show(this, evt.getX(), evt.getY());
2017-02-18 23:32:03 +01:00
2017-02-18 17:44:25 +01:00
this.invalidate();
this.repaint();
2017-02-16 18:37:08 +01:00
}//GEN-LAST:event_formMousePressed
2017-02-19 15:04:07 +01:00
private void formMouseWheelMoved(java.awt.event.MouseWheelEvent evt) {//GEN-FIRST:event_formMouseWheelMoved
2017-02-20 08:21:01 +01:00
double n = evt.getPreciseWheelRotation() * (-1.0);
2017-02-19 15:04:07 +01:00
if (n < 0) {
if (this.x_unit_width > 0.3) {
this.x_unit_width += 0.1 * n;
}
} else {
this.x_unit_width += 0.1 * n;
}
this.invalidate();
this.repaint();
}//GEN-LAST:event_formMouseWheelMoved
2017-03-26 21:36:53 +02:00
private void formMouseReleased(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_formMouseReleased
System.out.printf("There was a mosue event released\n");
2017-03-27 01:31:55 +02:00
2017-03-26 21:36:53 +02:00
if (!evt.isPopupTrigger()) {
System.out.printf("But there was no pupe trigger\n");
return;
}
// this.invalidate();
this.ctxMenu.setVisible(true);
this.ctxMenu.show(this, evt.getX(), evt.getY());
this.invalidate();
this.repaint();
2017-03-27 01:31:55 +02:00
2017-03-26 21:36:53 +02:00
}//GEN-LAST:event_formMouseReleased
2017-02-16 18:37:08 +01:00
void setCompression(int timeFrame) {
2017-02-20 08:21:01 +01:00
javax.swing.SwingUtilities.invokeLater(() -> {
data = Globals.se.getOHLCdata(timeFrame);
invalidate();
repaint();
});
2017-02-16 18:37:08 +01:00
}
2017-02-18 23:32:03 +01:00
2017-01-08 13:16:00 +01:00
@Override
public void UpdateQuote(Quote q) {
2017-01-13 01:55:43 +01:00
// System.out.print("Quote Received\n");
2017-01-12 23:16:37 +01:00
// this.realTimeAdd(q.time, (float) q.price, (float)q.volume);
2017-01-13 01:55:43 +01:00
2017-02-16 18:37:08 +01:00
// data.realTimeAdd(q.time, (float) q.price, (float) q.volume);
2017-01-13 01:55:43 +01:00
// this.invalidate();
2017-01-09 08:25:29 +01:00
this.repaint();
2017-01-08 13:16:00 +01:00
}
2017-01-08 03:14:27 +01:00
// Variables declaration - do not modify//GEN-BEGIN:variables
2017-02-17 08:33:19 +01:00
private javax.swing.JMenu compMenu;
2017-02-16 18:37:08 +01:00
private javax.swing.JPopupMenu ctxMenu;
2017-02-18 17:44:25 +01:00
private javax.swing.JCheckBoxMenuItem jCheckBoxMenuItem1;
2017-01-08 03:14:27 +01:00
// End of variables declaration//GEN-END:variables
}