2009-12-14 24 views
6

Estamos usando JFreeChart para hacer gráficas XY y tenemos una solicitud de función para hacer una cruz que se mueve junto con el mouse y resalta el punto de datos que más se acerca al valor x del mouse. Puede ver un ejemplo similar en Google Finance: http://www.google.com/finance?q=INDEXDJX:.DJI,INDEXSP:.INX,INDEXNASDAQ:.IXIC.¿Alguien ha hecho crosshairs que siguen el mouse en JFreeChart?

Esos gráficos de Google solo resaltan el valor actual (queremos hacer eso y también mostrar puntos de mira), pero muestran la interacción del mouse en vivo que estamos buscando.

¿Alguien tiene alguna sugerencia elegante?

Gracias.

Respuesta

4

Esto funcionó usando un detector de mouse y la clase CrosshairOverlay. Después de que regrese del viaje de vacaciones, publicaré mi código. Terminó siendo no demasiado difícil.


Disculpa, se me olvidó esto.

En primer lugar, desea calcular los valores x, y para el lugar donde desea su punto de mira. Para mí, quería que se moviera a lo largo de los puntos de nuestra línea, así que calculé el valor x más cercano y usé ese par de datos para x, y.

Entonces llama a este método:

protected void setCrosshairLocation(double x, Double y) { 
    Crosshair domainCrosshair; 
    List domainCrosshairs = crosshairOverlay.getDomainCrosshairs(); 
    if (domainCrosshairs.isEmpty()) { 
     domainCrosshair = new Crosshair(); 
     domainCrosshair.setPaint(BlueStripeColors.LIGHT_GRAY_C0); 
     crosshairOverlay.addDomainCrosshair(domainCrosshair); 
    } 
    else { 
     // We only have one at a time 
     domainCrosshair = (Crosshair) domainCrosshairs.get(0); 
    } 
    domainCrosshair.setValue(x); 

    if (y != null) { 
     Crosshair rangeCrosshair; 
     List rangeCrosshairs = crosshairOverlay.getRangeCrosshairs(); 
     if (rangeCrosshairs.isEmpty()) { 
      rangeCrosshair = new Crosshair(); 
      rangeCrosshair.setPaint(BlueStripeColors.LIGHT_GRAY_C0); 
      crosshairOverlay.addRangeCrosshair(rangeCrosshair); 
     } 
     else { 
      // We only have one at a time 
      rangeCrosshair = (Crosshair) rangeCrosshairs.get(0); 
     } 

     rangeCrosshair.setValue(y); 
    } 
} 

Tenga en cuenta que crosshairOverlay es una instancia de CrosshairOverlay.

+1

Podría publicar su código PLZ aquí? –

0

Lo primero que me viene a la mente es escribir un Cursor personalizado y configurarlo en su gráfico. Puede tener una referencia al gráfico y resaltar el valor de x que es consistente con la ubicación x/y del cursor.

1

JFreeChart no puede representar una subsección de un gráfico, por lo que querrá hacer algo que no requiera volver a pintar el gráfico. Podría escribir su gráfico en una Imagen Buffered y almacenar eso en la memoria, luego tener un componente personalizado que use el gráfico almacenado como la imagen de fondo, y dibuje retículos y otras ventanas emergentes sobre él.

Existen métodos en JFreeChart para obtener el punto de datos para una determinada coordenada en un gráfico representado. No recuerdo qué están fuera de mi cabeza. Dependiendo de sus necesidades, puede considerar renderizar sus propios datos de gráfico, no es tan difícil como podría pensar.

0

Esto funcionó para mí. He establecido la

chartPanel.addChartMouseListener(new ChartMouseListener() { 
public void chartMouseMoved(ChartMouseEvent event) 
    { 
    try 
    { 
     double[] values = getCrossHairValue(event); 

     plot.clearRangeMarkers(); 
     plot.clearDomainMarkers(); 

     Marker yMarker = new ValueMarker(values[1]); 
     yMarker.setPaint(Color.darkGray); 
     plot.addRangeMarker(yMarker); 

     Marker xMarker = new ValueMarker(values[0]); 
     xMarker.setPaint(Color.darkGray); 
     plot.addDomainMarker(xMarker); 

     chartPanel.repaint(); 
    } catch (Exception e) 
    { 

    } 
    } 

}

+7

¿Qué pasa con el método getCrossHairValue? ¿De dónde viene? –

+0

Creo que simplemente devuelve: 'int mouseX = event.getTrigger(). GetX(); \t \t int mouseY = event.getTrigger(). GetY(); ' – 2c00L

Cuestiones relacionadas