Override Author:WZW
Date:12/10/2007
JFreechart version: 1.0.6
Override class: org.jfree.chart.ChartPanel
Sample demo link: Order Manager System (OMS) link at http://vnetcode.org
Global variable: (for dynamic crosshair + top dynamic tooltip)
Code: Select all
/** MouseEvent X & Y. */
private int m_iX, m_iY;
private double m_dX, m_dY, m_dXX, m_dYY;
/** Crosshair X & Y. */
private Line2D m_l2dCrosshairX, m_l2dCrosshairY;
Code: Select all
super.paintComponent(g);
if (this.chart == null){
return;
}
//^WZW override start
//^Initialize crosshair XY to avoid multiple line exist in grid
// When chart is repaint, XORmode will not replace previous lines drawn
this.m_l2dCrosshairX = null;
this.m_l2dCrosshairY = null;
//^WZW override end
Graphics2D g2 = (Graphics2D) g.create();
(override all code in mouseMoved, each draw method can run standalone)
Code: Select all
/**
* WZW Override
* Implementation of the MouseMotionListener's method.
*
* @param e the event.
*/
public void mouseMoved(MouseEvent e) {
int iX = e.getX(), iY = e.getY();
this.m_iX = iX;
this.m_iY = iY;
this.m_dX = (double)iX;
this.m_dY = (double)iY;
drawRTCrosshair(); //Draw Realtime crosshair - Can run alone
drawRTInfo(); //Draw Realtime tooltip(info) - Can run alone
//$Pending: drawRTData(); //Draw Realtime tooltip(data)-1 sec fade out box
}
Code: Select all
/*
* WZW override
* Draw a dynamic crosshair(trace line-both axis)
*/
private void drawRTCrosshair(){
Rectangle2D screenDataArea = getScreenDataArea(this.m_iX, this.m_iY);
if(screenDataArea==null)return;
Graphics2D g2 = (Graphics2D) getGraphics();
int iDAMaxX = (int)screenDataArea.getMaxX();
int iDAMinX = (int)screenDataArea.getMinX();
int iDAMaxY = (int)screenDataArea.getMaxY();
int iDAMinY = (int)screenDataArea.getMinY();
g2.setXORMode(new Color(0xFFFF00));//Color of crosshair
if(this.m_l2dCrosshairX!=null && this.m_l2dCrosshairY!=null){
//^Delete(Overwrite) previous draw line
g2.draw(this.m_l2dCrosshairX);
g2.draw(this.m_l2dCrosshairY);
}
Line2D l2dX = new Line2D.Double(this.m_dX, iDAMinY, this.m_dX, iDAMaxY);
g2.draw(l2dX); this.m_l2dCrosshairX =l2dX;
Line2D l2dY = new Line2D.Double(iDAMinX, this.m_dY, iDAMaxX, this.m_dY);
g2.draw(l2dY); this.m_l2dCrosshairY = l2dY;
//^Solution for dual XORMode(crosshair), dispose & re-create in paintComponent
g2.dispose();
}
Code: Select all
/*
* WZW override
* Draw a realtime tooltip at top banner(store X,Y,... value)
*/
private void drawRTInfo(){
Rectangle2D screenDataArea = getScreenDataArea(this.m_iX, this.m_iY);
if(screenDataArea==null)return;
Insets insets = getInsets();
Graphics2D g2 = (Graphics2D) getGraphics();
int iDAMaxX = (int)screenDataArea.getMaxX();
int iDAMinX = (int)screenDataArea.getMinX();
int iDAMaxY = (int)screenDataArea.getMaxY();
int iDAMinY = (int)screenDataArea.getMinY();
Point2D p2dXY = this.translateScreenToJava2D(new Point(this.m_iX, this.m_iY));
XYPlot plot = (XYPlot)chart.getPlot();
ValueAxis domainAxis = plot.getDomainAxis();
ValueAxis rangeAxis = plot.getRangeAxis();
RectangleEdge domainAxisEdge = plot.getDomainAxisEdge();
RectangleEdge rangeAxisEdge = plot.getRangeAxisEdge();
//^For Combination chart only(multiple chart type in 1)
if(plot instanceof CombinedDomainXYPlot){
CombinedDomainXYPlot combineddomainxyplot = (CombinedDomainXYPlot) plot;
plot = combineddomainxyplot.findSubplot(this.getChartRenderingInfo().getPlotInfo(), p2dXY);
if(plot!=null){//reassign value
domainAxis = plot.getDomainAxis();
rangeAxis = plot.getRangeAxis();
domainAxisEdge = plot.getDomainAxisEdge();
rangeAxisEdge = plot.getRangeAxisEdge();
}else{
return; //Quit when mouse out of plot area
}
}
//^Real value in plot
double dXX = domainAxis.java2DToValue(this.m_dX, screenDataArea, domainAxisEdge);
double dYY = rangeAxis.java2DToValue(this.m_dY, screenDataArea, rangeAxisEdge);
this.m_dXX = dXX;
this.m_dYY = dYY;
//^Get title and data
ArrayList<String> alInfo = getInfo();
int iLenInfo = alInfo.size();
//^Customize dynamic tooltip display
String[] asV;
String sT, sV;
int iVLocX;
double dDiv = 10D; //dual usage
FontMetrics fontMetrics = g2.getFontMetrics();
int iFontHgt = fontMetrics.getHeight();
double dDivX = Math.floor((double)iDAMaxX / dDiv); //fixed location of X (division of Max X)
g2.setColor(Color.BLACK);
g2.fillRect(iDAMinX+1, iDAMinY, iDAMaxX-iDAMinX-1, 2*iFontHgt); //+1/-1 = offset
g2.setColor(Color.WHITE);
for(int i=iLenInfo-1; i>=0; i--){
asV = alInfo.get(i).split("\\|");
sT = asV[0];
sV = asV[1];
iVLocX = (int)(dDivX * (dDiv-(i+1)));
g2.drawString(sT+": "+sV, iVLocX, iDAMinY+iFontHgt);
}
g2.dispose();
}
Code: Select all
/*
* WZW override
* get Info
*/
private ArrayList<String> getInfo(){
DecimalFormat dfV = new DecimalFormat("#,###,###,##0.0000");
String[] asT = new String[]{"X", "Y"};
int iLenT = asT.length;
ArrayList<String> alV = new ArrayList<String>();
String sV = "";
//^Binding
for(int i=iLenT-1; i>=0; i--){
switch(i){
case 0: sV = getHMS(); break; //^Customize display for timeseries(intraday) only
case 1: sV = String.valueOf(dfV.format(this.m_dYY)); break;
}
alV.add(asT[i]+"|"+sV);
}
return alV;
}
/* WZW override
* get Hour Minute Seconds
*/
private String getHMS(){
DecimalFormat dfT = new DecimalFormat("00");
GregorianCalendar gc = new GregorianCalendar();
long lDte = (long)this.m_dXX;
Date dtXX = new Date(lDte);
gc.setTime(dtXX);
String sHH = dfT.format(Double.valueOf(String.valueOf(gc.get(GregorianCalendar.HOUR_OF_DAY))));
String sMM = dfT.format(Double.valueOf(String.valueOf(gc.get(GregorianCalendar.MINUTE))));
String sSS = dfT.format(Double.valueOf(String.valueOf(gc.get(GregorianCalendar.SECOND))));
String sV = sHH +":"+ sMM +":"+ sSS;
return sV;
}
This dynamic crosshair + top banner X & Y dynamic tooltip can run standalone.
I try to make this algorithm as simple as possible.
It can be implemented in single chart or combination chart(combineddomainxyplot)
It can be implemented in timeseries chart and category chart.
*If run in category chart(not timeseries), X value is not time(long), but index...just change few lines DecimalFormat in getHMS() or create a new format of display in x and y.
Restore previous zooming point
If interested in restore previous zoom point(right-click to zoom back previous point)...
View http://www.jfree.org/phpBB2/viewtopic.p ... 60#64860[b][/b]