如何从 JFreeChart 中的日期索引或字符串获取 X 像素值?
我有以下示例应用程序:
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;
import java.text.*;
import java.util.*;
import javax.swing.*;
import org.jfree.chart.*;
import org.jfree.chart.annotations.*;
import org.jfree.chart.axis.*;
import org.jfree.chart.entity.*;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.renderer.xy.XYBarRenderer;
import org.jfree.data.time.*;
import org.jfree.data.xy.XYDataset;
import org.jfree.chart.labels.*;
import org.jfree.chart.panel.*;
import org.jfree.chart.plot.*;
import org.jfree.chart.renderer.xy.*;
import org.jfree.chart.ui.*;
public class PriceVolume_Chart extends JPanel implements ChartMouseListener // A demo application for price-volume chart.
{
ChartPanel panel;
TimeSeries Price_Series=new TimeSeries("Price");
TimeSeries Volume_Series=new TimeSeries("Volume");
Crosshair xCrosshair,yCrosshair;
Vector<String> Volume_Color_Vector;
XYTextAnnotation note;
XYPlot plot;
XYLineAndShapeRenderer r;
public PriceVolume_Chart(String Symbol,int Index)
{
// super(new GridLayout());
try
{
JFreeChart chart=createChart(Symbol);
panel=new ChartPanel(chart,true,true,true,false,true);
panel.setPreferredSize(new java.awt.Dimension(1000,500));
panel.addChartMouseListener(this);
CrosshairOverlay crosshairOverlay=new CrosshairOverlay();
float[] dash={2f,0f,2f};
BasicStroke bs=new BasicStroke(1,BasicStroke.CAP_BUTT,BasicStroke.JOIN_ROUND,1.0f,dash,2f);
xCrosshair=new Crosshair(Double.NaN,Color.black,bs);
xCrosshair.setLabelBackgroundPaint(new Color(0f,0f,0f,1f));
xCrosshair.setLabelFont(xCrosshair.getLabelFont().deriveFont(14f));
xCrosshair.setLabelPaint(new Color(1f,1f,1f,1f));
xCrosshair.setLabelGenerator(new CrosshairLabelGenerator()
{
@Override
public String generateLabel(Crosshair crosshair)
{
long ms=(long)crosshair.getValue();
TimeSeriesDataItem item=null;
for (int i=0;i<Volume_Series.getItemCount();i++)
{
item=Volume_Series.getDataItem(i);
if (ms==item.getPeriod().getFirstMillisecond()) break;
}
long volume=item.getValue().longValue();
String s=NumberFormat.getInstance().format(volume);
return MessageFormat.format(" Volume: {0} ",s);
}
});
/*
xCrosshair.setLabelGenerator(new StandardCrosshairLabelGenerator()
{
@Override
public String generateLabel(Crosshair crosshair)
{
long ms=(long)crosshair.getValue();
TimeSeriesDataItem item=null;
for (int i=0;i<Volume_Series.getItemCount();i++)
{
item=Volume_Series.getDataItem(i);
if (ms==item.getPeriod().getFirstMillisecond()) break;
}
long volume=item.getValue().longValue();
return " "+NumberFormat.getInstance().format(volume)+" ";
}
});
*/
xCrosshair.setLabelVisible(true);
yCrosshair=new Crosshair(Double.NaN,Color.black,bs);
yCrosshair.setLabelBackgroundPaint(new Color(0f,0f,0f,1f));
yCrosshair.setLabelFont(xCrosshair.getLabelFont().deriveFont(14f));
yCrosshair.setLabelPaint(new Color(1f,1f,1f,1f));
yCrosshair.setLabelGenerator(new StandardCrosshairLabelGenerator(" Price: {0} ",NumberFormat.getCurrencyInstance()));
yCrosshair.setLabelVisible(true);
crosshairOverlay.addDomainCrosshair(xCrosshair);
crosshairOverlay.addRangeCrosshair(yCrosshair);
panel.addOverlay(crosshairOverlay);
add(panel);
/*
if (Index!=-1 && Index<Volume_Series.getItemCount())
{
TimeSeriesDataItem itemX=Volume_Series.getDataItem(Index);
xCrosshair.setValue(itemX.getPeriod().getFirstMillisecond());
TimeSeriesDataItem itemY=Price_Series.getDataItem(Index);
yCrosshair.setValue(itemY.getValue().doubleValue());
TimeSeriesDataItem item=Price_Series.getDataItem(Index);
float time=item.getPeriod().getFirstMillisecond();
float price=item.getValue().floatValue();
SimpleDateFormat f=new SimpleDateFormat("yyyy-MM-d");
String st=" Price : "+f.format(new Date((long)time))+" , "+NumberFormat.getCurrencyInstance().format(price)+" ";
note=new XYTextAnnotation(st,time,price-1);
note.setFont(UIManager.getFont("ToolTip.font"));
note.setBackgroundPaint(UIManager.getColor("ToolTip.background"));
Out("Index = "+Index);
note.setTextAnchor(Index<Volume_Color_Vector.size()/2?TextAnchor.TOP_LEFT:TextAnchor.TOP_RIGHT);
note.setOutlinePaint(Color.blue);
note.setOutlineVisible(true);
plot.getRenderer().addAnnotation(note);
}
*/
}
catch (Exception e) { e.printStackTrace(); }
}
private JFreeChart createChart(String Symbol)
{
createPriceDataset(Symbol);
XYDataset priceData=new TimeSeriesCollection(Price_Series);
JFreeChart chart=ChartFactory.createTimeSeriesChart(Symbol,"Date",getYLabel("Price ( $ )"),priceData,true,true,true);
plot=chart.getXYPlot();
plot.setBackgroundPaint(new Color(192,196,196));
NumberAxis rangeAxis1=(NumberAxis)plot.getRangeAxis();
rangeAxis1.setLowerMargin(0.40); // Leave room for volume bars
plot.getRenderer().setDefaultToolTipGenerator(new StandardXYToolTipGenerator(StandardXYToolTipGenerator.DEFAULT_TOOL_TIP_FORMAT,new SimpleDateFormat("yyyy-MM-d"),NumberFormat.getCurrencyInstance()));
NumberAxis rangeAxis2=new NumberAxis("Volume");
rangeAxis2.setUpperMargin(1.00); // Leave room for price line
rangeAxis2.setNumberFormatOverride(NumberFormat.getNumberInstance());
plot.setRangeAxis(1,rangeAxis2);
plot.setDataset(1,new TimeSeriesCollection(Volume_Series));
plot.setRangeAxis(1,rangeAxis2);
plot.mapDatasetToRangeAxis(1,1);
MyRender Renderer=new MyRender(this);
Renderer.setShadowVisible(false);
plot.setRenderer(1,Renderer);
DateAxis domainAxis=(DateAxis) plot.getDomainAxis(); // Consider adjusting the lower margin of the domain axis for symmetry.
domainAxis.setLowerMargin(0.05);
r=(XYLineAndShapeRenderer)plot.getRenderer();
return chart;
}
private void createPriceDataset(String Symbol)
{
String Lines[]=new String[21],Items[],Date;
int Year, Month, Day;
long Volume,Last_Volume=0;
float Price;
Lines[0]="Date,Open,High,Low,Close,Adj Close,Volume";
Lines[1]="2020-07-17,44.110001,44.369999,41.919998,42.509998,42.323395,849700";
Lines[2]="2020-07-20,41.630001,41.680000,39.669998,40.119999,39.943886,1319300";
Lines[3]="2020-07-21,40.880001,42.860001,40.860001,42.270000,42.084450,2070300";
Lines[4]="2020-07-22,41.919998,42.700001,41.090000,42.570000,42.383133,1317600";
Lines[5]="2020-07-23,43.919998,46.389999,43.279999,44.759998,44.563519,1917700";
Lines[6]="2020-07-24,46.500000,46.500000,43.950001,44.410000,44.215057,1384600";
Lines[7]="2020-07-27,44.000000,44.240002,42.610001,43.860001,43.667469,799800";
Lines[8]="2020-07-28,43.389999,44.590000,42.930000,43.020000,42.831158,699700";
Lines[9]="2020-07-29,42.759998,45.590000,42.740002,45.430000,45.230579,826200";
Lines[10]="2020-07-30,44.160000,44.639999,42.959999,44.500000,44.304661,798100";
Lines[11]="2020-07-31,44.330002,44.419998,42.580002,44.360001,44.165276,1037800";
Lines[12]="2020-08-03,44.560001,45.599998,43.419998,44.939999,44.742729,797000";
Lines[13]="2020-08-04,44.900002,45.500000,43.450001,43.540001,43.348877,971100";
Lines[14]="2020-08-05,44.860001,45.389999,43.650002,45.330002,45.131020,902000";
Lines[15]="2020-08-06,45.049999,46.279999,44.330002,45.299999,45.101147,645200";
Lines[16]="2020-08-07,44.849998,46.189999,44.189999,46.150002,45.947418,604900";
Lines[17]="2020-08-10,46.669998,48.410000,46.549999,47.290001,47.082417,960200";
Lines[18]="2020-08-11,49.110001,50.849998,48.799999,48.910000,48.695301,1187700";
Lines[19]="2020-08-12,49.759998,50.009998,47.060001,47.840000,47.630001,752800";
Lines[20]="2020-08-13,46.950001,48.369999,46.459999,47.110001,47.110001,535700";
Volume_Color_Vector=new Vector();
for (int i=1;i<Lines.length;i++)
{
Items=Lines[i].split(",");
Date=Items[0].replace("-0","-");
Price=Float.parseFloat(Items[5]);
Volume=Long.parseLong(Items[6]);
Items=Date.split("-");
Year=Integer.parseInt(Items[0]);
Month=Integer.parseInt(Items[1]);
Day=Integer.parseInt(Items[2]);
Price_Series.add(new Day(Day,Month,Year),Price);
Volume_Series.add(new Day(Day,Month,Year),Volume);
Volume_Color_Vector.add(Volume>=Last_Volume?"+":"-");
Last_Volume=Volume;
}
}
@Override
public void chartMouseClicked(ChartMouseEvent e)
{
Out("x = "+e.getTrigger().getX()); // Find X pixel location by mouse click
}
public int getX(int index) // Find X pixel location by date index : In this example : index = 0 points to "2020-07-17"
{
int X=-999;
Out("X = "+X);
return X;
}
public int getX(String date) // Find X pixel location by date string : For example "2020-08-03"
{
int X=-999;
Out("X = "+X);
return X;
}
public void chartMouseMoved(ChartMouseEvent cmevent)
{
ChartEntity chartentity=cmevent.getEntity();
if (chartentity instanceof XYItemEntity)
{
if (!r.getAnnotations().isEmpty()) r.removeAnnotation(note);
XYItemEntity e=(XYItemEntity)chartentity;
XYDataset d=e.getDataset();
int s=e.getSeriesIndex();
int i=e.getItem();
double x=d.getXValue(s,i);
double y=d.getYValue(s,i);
// Out("x = "+x+" y = "+y);
xCrosshair.setValue(x);
yCrosshair.setValue(y);
}
}
String getYLabel(String Text)
{
String Result="";
for (int i=0;i<Text.length();i++) Result+=Text.charAt(i)+(i<Text.length()-1?"\u2009":"");
// Out(Result);
return Result;
}
private static void out(String message) { System.out.print(message); }
private static void Out(String message) { System.out.println(message); }
// Create the GUI and show it. For thread safety, this method should be invoked from the event-dispatching thread.
static void Create_And_Show_GUI()
{
final PriceVolume_Chart demo=new PriceVolume_Chart("ADS",10);
JFrame frame=new JFrame("PriceVolume_Chart Frame");
frame.add(demo);
frame.addWindowListener(new WindowAdapter()
{
public void windowActivated(WindowEvent e) { }
public void windowClosed(WindowEvent e) { }
public void windowClosing(WindowEvent e) { System.exit(0); }
public void windowDeactivated(WindowEvent e) { }
public void windowDeiconified(WindowEvent e) { demo.repaint(); }
public void windowGainedFocus(WindowEvent e) { demo.repaint(); }
public void windowIconified(WindowEvent e) { }
public void windowLostFocus(WindowEvent e) { }
public void windowOpening(WindowEvent e) { demo.repaint(); }
public void windowOpened(WindowEvent e) { }
public void windowResized(WindowEvent e) { demo.repaint(); }
public void windowStateChanged(WindowEvent e) { demo.repaint(); }
});
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args)
{
// Schedule a job for the event-dispatching thread : creating and showing this application's GUI.
SwingUtilities.invokeLater(new Runnable() { public void run() { Create_And_Show_GUI(); } });
}
}
class MyRender extends XYBarRenderer
{
PriceVolume_Chart PVC;
MyRender(PriceVolume_Chart PVC)
{
this.PVC=PVC;
}
@Override
public Paint getItemPaint(int row,int col)
{
this.setBarAlignmentFactor(0.5);
// System.out.println(row+" "+col+" "+super.getItemPaint(row,col));
return PVC.Volume_Color_Vector.elementAt(col).equals("+")?super.getItemPaint(row,col):new Color(0.56f,0.2f,0.5f,1f);
}
}
如何实现上面的 2 个“getX()”方法,以便它们通过输入日期索引或日期字符串返回 X 像素值?
I have the following sample app :
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;
import java.text.*;
import java.util.*;
import javax.swing.*;
import org.jfree.chart.*;
import org.jfree.chart.annotations.*;
import org.jfree.chart.axis.*;
import org.jfree.chart.entity.*;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.renderer.xy.XYBarRenderer;
import org.jfree.data.time.*;
import org.jfree.data.xy.XYDataset;
import org.jfree.chart.labels.*;
import org.jfree.chart.panel.*;
import org.jfree.chart.plot.*;
import org.jfree.chart.renderer.xy.*;
import org.jfree.chart.ui.*;
public class PriceVolume_Chart extends JPanel implements ChartMouseListener // A demo application for price-volume chart.
{
ChartPanel panel;
TimeSeries Price_Series=new TimeSeries("Price");
TimeSeries Volume_Series=new TimeSeries("Volume");
Crosshair xCrosshair,yCrosshair;
Vector<String> Volume_Color_Vector;
XYTextAnnotation note;
XYPlot plot;
XYLineAndShapeRenderer r;
public PriceVolume_Chart(String Symbol,int Index)
{
// super(new GridLayout());
try
{
JFreeChart chart=createChart(Symbol);
panel=new ChartPanel(chart,true,true,true,false,true);
panel.setPreferredSize(new java.awt.Dimension(1000,500));
panel.addChartMouseListener(this);
CrosshairOverlay crosshairOverlay=new CrosshairOverlay();
float[] dash={2f,0f,2f};
BasicStroke bs=new BasicStroke(1,BasicStroke.CAP_BUTT,BasicStroke.JOIN_ROUND,1.0f,dash,2f);
xCrosshair=new Crosshair(Double.NaN,Color.black,bs);
xCrosshair.setLabelBackgroundPaint(new Color(0f,0f,0f,1f));
xCrosshair.setLabelFont(xCrosshair.getLabelFont().deriveFont(14f));
xCrosshair.setLabelPaint(new Color(1f,1f,1f,1f));
xCrosshair.setLabelGenerator(new CrosshairLabelGenerator()
{
@Override
public String generateLabel(Crosshair crosshair)
{
long ms=(long)crosshair.getValue();
TimeSeriesDataItem item=null;
for (int i=0;i<Volume_Series.getItemCount();i++)
{
item=Volume_Series.getDataItem(i);
if (ms==item.getPeriod().getFirstMillisecond()) break;
}
long volume=item.getValue().longValue();
String s=NumberFormat.getInstance().format(volume);
return MessageFormat.format(" Volume: {0} ",s);
}
});
/*
xCrosshair.setLabelGenerator(new StandardCrosshairLabelGenerator()
{
@Override
public String generateLabel(Crosshair crosshair)
{
long ms=(long)crosshair.getValue();
TimeSeriesDataItem item=null;
for (int i=0;i<Volume_Series.getItemCount();i++)
{
item=Volume_Series.getDataItem(i);
if (ms==item.getPeriod().getFirstMillisecond()) break;
}
long volume=item.getValue().longValue();
return " "+NumberFormat.getInstance().format(volume)+" ";
}
});
*/
xCrosshair.setLabelVisible(true);
yCrosshair=new Crosshair(Double.NaN,Color.black,bs);
yCrosshair.setLabelBackgroundPaint(new Color(0f,0f,0f,1f));
yCrosshair.setLabelFont(xCrosshair.getLabelFont().deriveFont(14f));
yCrosshair.setLabelPaint(new Color(1f,1f,1f,1f));
yCrosshair.setLabelGenerator(new StandardCrosshairLabelGenerator(" Price: {0} ",NumberFormat.getCurrencyInstance()));
yCrosshair.setLabelVisible(true);
crosshairOverlay.addDomainCrosshair(xCrosshair);
crosshairOverlay.addRangeCrosshair(yCrosshair);
panel.addOverlay(crosshairOverlay);
add(panel);
/*
if (Index!=-1 && Index<Volume_Series.getItemCount())
{
TimeSeriesDataItem itemX=Volume_Series.getDataItem(Index);
xCrosshair.setValue(itemX.getPeriod().getFirstMillisecond());
TimeSeriesDataItem itemY=Price_Series.getDataItem(Index);
yCrosshair.setValue(itemY.getValue().doubleValue());
TimeSeriesDataItem item=Price_Series.getDataItem(Index);
float time=item.getPeriod().getFirstMillisecond();
float price=item.getValue().floatValue();
SimpleDateFormat f=new SimpleDateFormat("yyyy-MM-d");
String st=" Price : "+f.format(new Date((long)time))+" , "+NumberFormat.getCurrencyInstance().format(price)+" ";
note=new XYTextAnnotation(st,time,price-1);
note.setFont(UIManager.getFont("ToolTip.font"));
note.setBackgroundPaint(UIManager.getColor("ToolTip.background"));
Out("Index = "+Index);
note.setTextAnchor(Index<Volume_Color_Vector.size()/2?TextAnchor.TOP_LEFT:TextAnchor.TOP_RIGHT);
note.setOutlinePaint(Color.blue);
note.setOutlineVisible(true);
plot.getRenderer().addAnnotation(note);
}
*/
}
catch (Exception e) { e.printStackTrace(); }
}
private JFreeChart createChart(String Symbol)
{
createPriceDataset(Symbol);
XYDataset priceData=new TimeSeriesCollection(Price_Series);
JFreeChart chart=ChartFactory.createTimeSeriesChart(Symbol,"Date",getYLabel("Price ( $ )"),priceData,true,true,true);
plot=chart.getXYPlot();
plot.setBackgroundPaint(new Color(192,196,196));
NumberAxis rangeAxis1=(NumberAxis)plot.getRangeAxis();
rangeAxis1.setLowerMargin(0.40); // Leave room for volume bars
plot.getRenderer().setDefaultToolTipGenerator(new StandardXYToolTipGenerator(StandardXYToolTipGenerator.DEFAULT_TOOL_TIP_FORMAT,new SimpleDateFormat("yyyy-MM-d"),NumberFormat.getCurrencyInstance()));
NumberAxis rangeAxis2=new NumberAxis("Volume");
rangeAxis2.setUpperMargin(1.00); // Leave room for price line
rangeAxis2.setNumberFormatOverride(NumberFormat.getNumberInstance());
plot.setRangeAxis(1,rangeAxis2);
plot.setDataset(1,new TimeSeriesCollection(Volume_Series));
plot.setRangeAxis(1,rangeAxis2);
plot.mapDatasetToRangeAxis(1,1);
MyRender Renderer=new MyRender(this);
Renderer.setShadowVisible(false);
plot.setRenderer(1,Renderer);
DateAxis domainAxis=(DateAxis) plot.getDomainAxis(); // Consider adjusting the lower margin of the domain axis for symmetry.
domainAxis.setLowerMargin(0.05);
r=(XYLineAndShapeRenderer)plot.getRenderer();
return chart;
}
private void createPriceDataset(String Symbol)
{
String Lines[]=new String[21],Items[],Date;
int Year, Month, Day;
long Volume,Last_Volume=0;
float Price;
Lines[0]="Date,Open,High,Low,Close,Adj Close,Volume";
Lines[1]="2020-07-17,44.110001,44.369999,41.919998,42.509998,42.323395,849700";
Lines[2]="2020-07-20,41.630001,41.680000,39.669998,40.119999,39.943886,1319300";
Lines[3]="2020-07-21,40.880001,42.860001,40.860001,42.270000,42.084450,2070300";
Lines[4]="2020-07-22,41.919998,42.700001,41.090000,42.570000,42.383133,1317600";
Lines[5]="2020-07-23,43.919998,46.389999,43.279999,44.759998,44.563519,1917700";
Lines[6]="2020-07-24,46.500000,46.500000,43.950001,44.410000,44.215057,1384600";
Lines[7]="2020-07-27,44.000000,44.240002,42.610001,43.860001,43.667469,799800";
Lines[8]="2020-07-28,43.389999,44.590000,42.930000,43.020000,42.831158,699700";
Lines[9]="2020-07-29,42.759998,45.590000,42.740002,45.430000,45.230579,826200";
Lines[10]="2020-07-30,44.160000,44.639999,42.959999,44.500000,44.304661,798100";
Lines[11]="2020-07-31,44.330002,44.419998,42.580002,44.360001,44.165276,1037800";
Lines[12]="2020-08-03,44.560001,45.599998,43.419998,44.939999,44.742729,797000";
Lines[13]="2020-08-04,44.900002,45.500000,43.450001,43.540001,43.348877,971100";
Lines[14]="2020-08-05,44.860001,45.389999,43.650002,45.330002,45.131020,902000";
Lines[15]="2020-08-06,45.049999,46.279999,44.330002,45.299999,45.101147,645200";
Lines[16]="2020-08-07,44.849998,46.189999,44.189999,46.150002,45.947418,604900";
Lines[17]="2020-08-10,46.669998,48.410000,46.549999,47.290001,47.082417,960200";
Lines[18]="2020-08-11,49.110001,50.849998,48.799999,48.910000,48.695301,1187700";
Lines[19]="2020-08-12,49.759998,50.009998,47.060001,47.840000,47.630001,752800";
Lines[20]="2020-08-13,46.950001,48.369999,46.459999,47.110001,47.110001,535700";
Volume_Color_Vector=new Vector();
for (int i=1;i<Lines.length;i++)
{
Items=Lines[i].split(",");
Date=Items[0].replace("-0","-");
Price=Float.parseFloat(Items[5]);
Volume=Long.parseLong(Items[6]);
Items=Date.split("-");
Year=Integer.parseInt(Items[0]);
Month=Integer.parseInt(Items[1]);
Day=Integer.parseInt(Items[2]);
Price_Series.add(new Day(Day,Month,Year),Price);
Volume_Series.add(new Day(Day,Month,Year),Volume);
Volume_Color_Vector.add(Volume>=Last_Volume?"+":"-");
Last_Volume=Volume;
}
}
@Override
public void chartMouseClicked(ChartMouseEvent e)
{
Out("x = "+e.getTrigger().getX()); // Find X pixel location by mouse click
}
public int getX(int index) // Find X pixel location by date index : In this example : index = 0 points to "2020-07-17"
{
int X=-999;
Out("X = "+X);
return X;
}
public int getX(String date) // Find X pixel location by date string : For example "2020-08-03"
{
int X=-999;
Out("X = "+X);
return X;
}
public void chartMouseMoved(ChartMouseEvent cmevent)
{
ChartEntity chartentity=cmevent.getEntity();
if (chartentity instanceof XYItemEntity)
{
if (!r.getAnnotations().isEmpty()) r.removeAnnotation(note);
XYItemEntity e=(XYItemEntity)chartentity;
XYDataset d=e.getDataset();
int s=e.getSeriesIndex();
int i=e.getItem();
double x=d.getXValue(s,i);
double y=d.getYValue(s,i);
// Out("x = "+x+" y = "+y);
xCrosshair.setValue(x);
yCrosshair.setValue(y);
}
}
String getYLabel(String Text)
{
String Result="";
for (int i=0;i<Text.length();i++) Result+=Text.charAt(i)+(i<Text.length()-1?"\u2009":"");
// Out(Result);
return Result;
}
private static void out(String message) { System.out.print(message); }
private static void Out(String message) { System.out.println(message); }
// Create the GUI and show it. For thread safety, this method should be invoked from the event-dispatching thread.
static void Create_And_Show_GUI()
{
final PriceVolume_Chart demo=new PriceVolume_Chart("ADS",10);
JFrame frame=new JFrame("PriceVolume_Chart Frame");
frame.add(demo);
frame.addWindowListener(new WindowAdapter()
{
public void windowActivated(WindowEvent e) { }
public void windowClosed(WindowEvent e) { }
public void windowClosing(WindowEvent e) { System.exit(0); }
public void windowDeactivated(WindowEvent e) { }
public void windowDeiconified(WindowEvent e) { demo.repaint(); }
public void windowGainedFocus(WindowEvent e) { demo.repaint(); }
public void windowIconified(WindowEvent e) { }
public void windowLostFocus(WindowEvent e) { }
public void windowOpening(WindowEvent e) { demo.repaint(); }
public void windowOpened(WindowEvent e) { }
public void windowResized(WindowEvent e) { demo.repaint(); }
public void windowStateChanged(WindowEvent e) { demo.repaint(); }
});
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args)
{
// Schedule a job for the event-dispatching thread : creating and showing this application's GUI.
SwingUtilities.invokeLater(new Runnable() { public void run() { Create_And_Show_GUI(); } });
}
}
class MyRender extends XYBarRenderer
{
PriceVolume_Chart PVC;
MyRender(PriceVolume_Chart PVC)
{
this.PVC=PVC;
}
@Override
public Paint getItemPaint(int row,int col)
{
this.setBarAlignmentFactor(0.5);
// System.out.println(row+" "+col+" "+super.getItemPaint(row,col));
return PVC.Volume_Color_Vector.elementAt(col).equals("+")?super.getItemPaint(row,col):new Color(0.56f,0.2f,0.5f,1f);
}
}
How to implement the 2 "getX()" methods above, so they will return the X pixel values by inputting date index or date string ?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
给定一个
ChartPanel
(参见此处),以下方法会查找 <priceSeries
中的 code>index 项并将其时间转换为相对于 图表。TimeSeries
方法getIndex()
可用于查找具有与给定日期字符串对应的RegularTimePeriod
的TimeSeriesDataItem
的索引;结果索引可以传递给getX(int index)
。将这样的行添加到
chartMouseMoved
处理程序中以查看坐标之间的对应关系:Given a
ChartPanel
, seen here, the following method finds theindex
item in thepriceSeries
and converts its time to Java2D coordinates relative to the chart.The
TimeSeries
methodgetIndex()
can be used to find the the index of aTimeSeriesDataItem
having theRegularTimePeriod
corresponding to a given date string; the resulting index can be passed togetX(int index)
.Add a line like this to the
chartMouseMoved
handler to see the correspondence between coordinates:我在@trashgod的帮助下,弄清楚了如何实现以下内容:
I, with the help of @trashgod, figured out how to implement the following :