1

I want to add a Cross Hair on top of my Jfreechart's Gantt Chart that moves along with mouse similar to what was mentioned here.

Following that example I created my own:

private Crosshair xCrosshair;
private Crosshair yCrosshair; 

public void createChartPanel(JFreeChart chart){

    chartPanel = new ChartPanel(chart); 
    chartPanel.setInitialDelay(0);  // make the tooltip appear quicker

    // Mouse wheel listener for the zoom in out feature
    chartPanel.addMouseWheelListener(this);
    // Mouse movement listener for the cross hair feature
    chartPanel.addChartMouseListener(this);

    CrosshairOverlay crosshairOverlay = new CrosshairOverlay();
    this.xCrosshair = new Crosshair(Double.NaN, Color.GRAY, new BasicStroke(0f));
    this.xCrosshair.setLabelVisible(true);
    this.yCrosshair = new Crosshair(Double.NaN, Color.GRAY, new BasicStroke(0f));
    this.yCrosshair.setLabelVisible(true);
    crosshairOverlay.addDomainCrosshair(xCrosshair);
    crosshairOverlay.addRangeCrosshair(yCrosshair);
    chartPanel.addOverlay(crosshairOverlay);
}

 // add the custom renderer and modify x axis
 public void createCategoryPlot(JFreeChart chart){

    plot = chart.getCategoryPlot();
    ganttRenderer = new Renderer();
    plot.setRenderer(ganttRenderer);

            /* Modify the x axis */
    DecimalFormat format = (DecimalFormat) NumberFormat.getNumberInstance(Locale.ENGLISH);
    format.applyPattern("#");

    xAxis = new NumberAxis();
    xAxis.setNumberFormatOverride(format);
    xAxis.setLabel("Cycles");

    CategoryAxis axis = plot.getDomainAxis();
    axis.setLowerMargin(0.05);
    axis.setCategoryMargin(0.55);
    axis.setUpperMargin(0.05);  // modify the position of each task axis
    plot.setRangeAxis(xAxis);

    // add change listener to for change in the axis range
    plot.getRangeAxis().addChangeListener(this); 
    initRange = xAxis.getRange();
    chartPanel.getChart().removeLegend();
}

public void chartMouseMoved(ChartMouseEvent event) {    

    int mouseX = event.getTrigger().getX();
    int mouseY = event.getTrigger().getY();


    Rectangle2D dataArea = this.chartPanel.getScreenDataArea();
    JFreeChart chart = event.getChart();

    double x = xAxis.java2DToValue(event.getTrigger().getX(), dataArea, RectangleEdge.BOTTOM);
    //        double y = DatasetUtilities.findYValue(plot.getDataset(), 0, x);
    this.xCrosshair.setValue(x);

    this.yCrosshair.setLabelGenerator(new CrosshairLabelGenerator(){

        @Override
        public String generateLabel(Crosshair arg0) {
            return "y value";
        }

    });        
}

Unfortunately this error is shown, which does not allow me to overlay on top of category plot.

 Exception in thread "AWT-EventQueue-0" java.lang.ClassCastException: org.jfree.chart.plot.CategoryPlot cannot be cast to org.jfree.chart.plot.XYPlot
at org.jfree.chart.panel.CrosshairOverlay.paintOverlay(CrosshairOverlay.java:233)
at org.jfree.chart.ChartPanel.paintComponent(ChartPanel.java:1658)

Any ideas on how to work around this?

Community
  • 1
  • 1
2c00L
  • 495
  • 12
  • 29
  • `CrosshairOverlay` expects an `XYPlot`, not a `CategoryPlot`. – trashgod Feb 06 '15 at 22:51
  • Understood that from the error. But I need a workaround to implement the cross hair for the 'Category Plot'. – 2c00L Feb 08 '15 at 15:23
  • Maybe a `CategoryMarker`? – trashgod Feb 08 '15 at 16:21
  • I was actually playing around with the markers. But the problem is that I need to redraw the markers each time I move the mouse. That means the whole chart needs to be redrawn. My gantt chart may contains a lot of stuff. Redrawing each time I move the mouse will the make the program unnecessarily slow. – 2c00L Feb 09 '15 at 09:50

1 Answers1

1

ChartFactory.createGanttChart() instantiates a CategoryPlot, as shown here, but CrosshairOverlay expects an XYPlot. You can get a comparable effect using the plot's existing crosshair implementation and a custom tool tip format based on the DEFAULT_TOOL_TIP_FORMAT_STRING seen in IntervalCategoryToolTipGenerator.

CategoryPlot plot = (CategoryPlot) chart.getPlot();
plot.setDomainCrosshairVisible(true);
plot.setRangeCrosshairVisible(true);
GanttRenderer r = (GanttRenderer) plot.getRenderer();
r.setBaseToolTipGenerator(new IntervalCategoryToolTipGenerator(
    "{0}, {1}: {3} - {4}", DateFormat.getDateInstance()));
trashgod
  • 203,806
  • 29
  • 246
  • 1,045