Realtime Dynamic Crosshair (trace) and tooltip (patch code)

A discussion forum for JFreeChart (a 2D chart library for the Java platform).
wzwei28
Posts: 105
Joined: Wed Mar 16, 2005 9:17 am
Location: Malaysia, Earth
Contact:

Realtime Dynamic Crosshair (trace) and tooltip (patch code)

Post by wzwei28 » Fri Oct 12, 2007 2:52 pm

Title:Realtime Dynamic Crosshair (trace line) and tooltip (X n Y)
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;
Existing paintComponent() method: (for dynamic crosshair only)

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();
New mouseMoved(MouseEvent e) method:
(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
}
New drawRTCrosshair method: (For crosshair implementation only)

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();
}
New drawRTInfo method: (for draw realtime dynamic tooltip(on top banner) only)

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();
}
New getInfo() && getHMS() methods called in drawRTInfo method: (for draw realtime dynamic tooltip(on top banner) only)

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;
}
Idea:
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]
Last edited by wzwei28 on Thu Oct 18, 2007 1:30 pm, edited 5 times in total.

annac
Posts: 24
Joined: Mon Oct 01, 2007 7:56 pm
Location: Canada

Post by annac » Fri Oct 12, 2007 4:47 pm

again, thank you!

I am definitely going to take a look at this

UniShadow
Posts: 3
Joined: Thu Jun 11, 2009 2:54 pm

Re: Realtime Dynamic Crosshair (trace) and tooltip (patch code)

Post by UniShadow » Thu Jun 11, 2009 6:52 pm

Hi,

I'am a student working for a project with jfreechart (Prof. Iwe,
HTW-Dresden, who bought JfreeChart) working on part that was
programmed by forumUser:wzwei28.

concerning the following Post about crosshairs in chartPanel:
http://www.jfree.org/phpBB2/viewtopic.p ... 888#p64888

paintComponent() method

Code: Select all

super.paintComponent(g);
Graphics2D g2 = (Graphics2D)g;
//draw Line on ChartPanel
Line2D line = new Line2D.Double(...)
g2.draw(line);

//^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
g2 = (Graphics2D) g.create();
- first problem is: The Line draw on the g2 doesn't work with jfreechart 1.0.13 & Java 1.6.0_13
you could see the drawing for one second or so, but then it's repaint?

- second problem: the crosshairs(XYPlot) drawing is very slow ? 1-2 seconds
for mouse event reaction and drawing the crosshairs in the ChartPanel with Java 1.6.0_13,
but with Java 1.6.0_01, the same code, it works pretty fast!

Changed on jfreechart 1.0.13:
" -updates to the ChartPanel class to support copying charts to the clipboard,
panning and mouse-wheel zooming, and an overlay mechanism that supports crosshairs"
How can I use this changes in the right way for my crosshair and linedrawing problem?

Thanks for your help!

wzwei28
Posts: 105
Joined: Wed Mar 16, 2005 9:17 am
Location: Malaysia, Earth
Contact:

Re: Realtime Dynamic Crosshair (trace) and tooltip (patch code)

Post by wzwei28 » Thu Jun 11, 2009 9:54 pm

Hi Friend,

When Java update to version 6, it had several major impact on Java2D drawing. (especially flicking, lag 1-2 second for every repaint)
Solution: Quite easy. Just compile with this lines in ur IDE or plain batch. To avoid the java2d.d3d draw, then it will works perfect as usual (like Java1.4->1.5).

(Arguments in IDE-Netbeans or Eclipse when running the class)
-Dsun.java2d.d3d=false

Hope it helps! Solution for Java 6 and above (on realtime crosshair dynamic change).
Reply me if this lines not works. For better performance, set VM Options: -Xmx768m and above. (especially large dataset).

UniShadow
Posts: 3
Joined: Thu Jun 11, 2009 2:54 pm

Re: Realtime Dynamic Crosshair (trace) and tooltip (patch code)

Post by UniShadow » Sun Jun 14, 2009 11:27 am

Hi wzwei28,

thanks for your fast answer!

I working with eclipse 3.4.1 / Ganymed. I add the arguments and VM Option
under Project Properties > Run/Debug Settings > Programm arguments:
-Dsun.java2d.d3d=false
( I also try -Dsun.java2d.ddoffscreen=false
and -Dsun.java2d.noddraw=true )

under Project Properties > Run/Debug Settings > VM arguments :
-Xmx768m

I'am sorry, but it doesn't has any effect? Is there something wrong with
my configuration settings?

wzwei28
Posts: 105
Joined: Wed Mar 16, 2005 9:17 am
Location: Malaysia, Earth
Contact:

Re: Realtime Dynamic Crosshair (trace) and tooltip (patch code)

Post by wzwei28 » Tue Jun 16, 2009 9:09 pm

Maybe u can have a try on JNLP (java web start) way of load.

<?xml version="1.0" encoding="utf-8"?>
<jnlp spec="1.5.0+"
codebase="http://localhost/***/jnlp/"
href="***.jnlp">
<information>
<title>Application</title>
<vendor>Visual Net Technologies</vendor>
<description>Application</description>
<description kind="short">Application</description>
<offline-allowed/>
</information>
<resources>
<jar href="***.jar"/>
<j2se version="1.5.0+"
href="http://java.sun.com/products/autodl/j2se" java-vm-args="-Dsun.java2d.d3d=false" initial-heap-size="256m" max-heap-size="768m"/>
</resources>
<application-desc main-class="com.vnt.***"/>
</jnlp>

Abbrevations: *** can be any variable based on ur own project name.

If the realtime dynamic crosshair still flicking+lag ....then, maybe u need to provide a extremely simple demo (as minimize as possible), then I test for u. Or perhaps u can search via internet.

UniShadow
Posts: 3
Joined: Thu Jun 11, 2009 2:54 pm

Re: Realtime Dynamic Crosshair (trace) and tooltip (patch code)

Post by UniShadow » Fri Jun 19, 2009 1:49 pm

Hi,

I need to start the program under windows with an executable, so the java
web start is no option for me. But I think about a java wrapper which could
include the older Java version. I notice that my problem has nothing to do
with the new jfreechart update 13. The Problem is the new java version.

I could give you a link of the demoproject with the ChartPanel, this demo
that you made :). Than you can look at the problem using the new java
version 1.6.0_13-b03. But its not extremely simple :) the 4 classes.

thanks anyway,
UniShadow

wzwei28
Posts: 105
Joined: Wed Mar 16, 2005 9:17 am
Location: Malaysia, Earth
Contact:

Re: Realtime Dynamic Crosshair (trace) and tooltip (patch code)

Post by wzwei28 » Sat Jun 20, 2009 7:19 am

In command line(cmd) (or batch file), simply type following lines.

java -Xms256M -Xmx1024M -Dsun.java2d.d3d=false -jar jnlp\???.jar

IT will automatic run the apps from desktop, not JNLP java web start. Dual mode.
U can have a try. where ???.jar is ur core runnable file.

Maybe need to include classpath in Manifest(within ???.Jar) like following: (if got link with library such as JFreechart etc.)
Manifest-Version: 1.0
Class-Path: ??a.jar ??b.jar ??c.jar

hope it helps!

venkat24
Posts: 1
Joined: Wed Oct 10, 2012 8:03 am
antibot: No, of course not.

Re: Realtime Dynamic Crosshair (trace) and tooltip (patch co

Post by venkat24 » Wed Oct 10, 2012 8:15 am

Hi,
I am new in drawing graph using Jfree chart or java swings,AWT and Graphic2D. I have a requirement to plot the time-varying properties of ducts and junctions of a gas network.

The graph contains multiple line graphs with different colors and wil be chnaging dynamicaaly based on the receiving Y -axis values.

John Matthews
Posts: 513
Joined: Wed Sep 12, 2007 3:18 pm

Re: Realtime Dynamic Crosshair (trace) and tooltip (patch co

Post by John Matthews » Wed Oct 10, 2012 9:53 pm

org.jfree.chart.demo.TimeSeriesChartDemo1, included in the distribution, is a good starting point. Two related approaches are examined in this Q&A. Depending on the circumstances, either TimeSeriesCollection or DynamicTimeSeriesCollection may be worth a look.

matgst
Posts: 8
Joined: Thu Oct 25, 2012 2:14 pm
antibot: No, of course not.

Re: Realtime Dynamic Crosshair (trace) and tooltip (patch co

Post by matgst » Tue May 21, 2013 5:00 pm

Hi guys,

I came across this article when investigating on a problem.

We have an SWT based application which embeds JFreeChart within an SWT_AWT bridge. All works quite well except for
the axis traces (enabled by setting setVerticalAxisTrace(true) and setHorizontalAxisTrace(true)). Drawing these two lines
causes the AWT part (i.e. where the ChartPanel is embedded) of the UI to hang on a few systems.

JVisualVM does not show one single hanging or blocking thread. Also all of the SWT controls like the main menu continue to work.
But the ChartPanel itself does not react anymore.

So far I was able to narrow down the problem: It only occurs on test systems with nVidia graphics card. (NVS 3100m)
On such a system I could always reproduce the problem.

Now the really interesting part:
  • If embedded in a pure Swing application it does not occur.
  • Setting the VM property -Dsun.java2d.d3d=false does also solve the problem.
The first point is no solution for me, since we are in an Eclipse environment where SWT is a must-have.
The second point does not seem like a solution to me, because it disables some default behaviour of the JRE.

By the way:
Does anybody know about possible side-effects (regarding JFreeChart features, performance, etc.) when setting this property?
I'm afraid this could decrease overall performance of our real-time painting (we have dynamic data, not static data) and I am not
comfortable with globally setting this property for all installations.

Who can give me advice?

Thank you very much in advance.
Cheers,
matthias

Update:
According to the trace (-Dsun.java2d.trace=...) I would assume that the problem is related to a "BLIT" operation (at least this is the last traced operation I got).
Maybe this information can help tracking the problem.

Please let me know if there is more information needed in order to elaborate on that.

matgst
Posts: 8
Joined: Thu Oct 25, 2012 2:14 pm
antibot: No, of course not.

Re: Realtime Dynamic Crosshair (trace) and tooltip (patch co

Post by matgst » Fri May 24, 2013 8:47 am

Actually, I am asking for help. Maybe I did not point it out clearly.
But I am also glad if my post helps other people to find a workaround for their problem.

delexi
Posts: 5
Joined: Sat May 25, 2013 11:30 am
antibot: No, of course not.

Re: Realtime Dynamic Crosshair (trace) and tooltip (patch co

Post by delexi » Sat May 25, 2013 11:54 am

Hello matgst,

do you by any chance embed your Charts in a JViewPort[1]? That class has different algorithms to render their embedded childcomponent in regard to scrolling and one of those algorithms is BLIT_SCROLL_MODE. Maybe this can help you?

---
[1] http://docs.oracle.com/javase/7/docs/ap ... wport.html

matgst
Posts: 8
Joined: Thu Oct 25, 2012 2:14 pm
antibot: No, of course not.

Re: Realtime Dynamic Crosshair (trace) and tooltip (patch co

Post by matgst » Mon May 27, 2013 10:02 am

Hi delexi!

No, we do not use JViewPort. But we have got a scrollable SWT control as a container.

Actually this is the hierarchy :

- ScrolledComposite (SWT)
- Composite (SWT)
- Frame (SWT_AWT.new_Frame())
- ChartPanel (our own subclass of ChartPanel which supports zooming/panning)

Is it recommended to use JViewPort? Or is it may NOT recommended to use a scrollable control?

delexi
Posts: 5
Joined: Sat May 25, 2013 11:30 am
antibot: No, of course not.

Re: Realtime Dynamic Crosshair (trace) and tooltip (patch co

Post by delexi » Mon May 27, 2013 10:36 am

Hi matgst,
matgst wrote: Hi delexi!

No, we do not use JViewPort. But we have got a scrollable SWT control as a container.
Oh, ok I did not know that. I just read about the BLIT part and was reminded of JViewPort.
matgst wrote: Actually this is the hierarchy :

- ScrolledComposite (SWT)
- Composite (SWT)
- Frame (SWT_AWT.new_Frame())
- ChartPanel (our own subclass of ChartPanel which supports zooming/panning)

Is it recommended to use JViewPort? Or is it may NOT recommended to use a scrollable control?
As JViewPort is a Swingcomponent, I am not really sure if that is applicable to your situation. I am quite new to JFreeChart and have only been looking at the use in Swing Apps, so I cannot give you a definite answer.

Regards,
Alex

Locked