JFreeChart-XYPlot-マウスの動きに応じて十字線と値を表示する.


目次 ⇒ [JFreeChartサンプル](https://qiita.com/artery/items/3e9c63e5c14a9e965c97)

```java
package jp.avaj.lib.chart;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.geom.Rectangle2D;

import org.jfree.chart.ChartFrame;
import org.jfree.chart.ChartMouseEvent;
import org.jfree.chart.ChartMouseListener;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.NumberAxis;
import org.jfree.chart.axis.ValueAxis;
import org.jfree.chart.panel.CrosshairOverlay;
import org.jfree.chart.plot.Crosshair;
import org.jfree.chart.plot.Plot;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.renderer.xy.StandardXYItemRenderer;
import org.jfree.chart.renderer.xy.XYItemRenderer;
import org.jfree.data.general.DatasetUtilities;
import org.jfree.data.xy.XYDataset;
import org.jfree.data.xy.XYSeries;
import org.jfree.data.xy.XYSeriesCollection;
import org.jfree.ui.RectangleEdge;

/**
■ JFreeChart-XYPlot-マウスの動きに応じて十字線と値を表示する.

 */
public class Chart19_00 implements ChartMouseListener{

  public static void main(String[] args) {
    new Chart19_00();
  }

  private Chart19_00() {
    // 表示データを生成
    XYDataset dataset = createDataset();
    // 軸を生成
    ValueAxis xAxis = new NumberAxis();
    ValueAxis yAxis = new NumberAxis();
    // レンダラ
    XYItemRenderer renderer = new StandardXYItemRenderer();
    // Plotを生成してチャートを表示する
    XYPlot xyPlot = new XYPlot(dataset,xAxis,yAxis,renderer);
    JFreeChart jfreeChart = new JFreeChart("CrossHairOverlay",(Plot)xyPlot);
    ChartFrame cFrame = new ChartFrame("CrossHairOverlay",(JFreeChart)jfreeChart);
    cFrame.pack();
    cFrame.setVisible(true);
    //
    // Overlayとリスナーを登録する.
    {
      this.chartPanel = cFrame.getChartPanel();
      this.chartPanel.addChartMouseListener(this);
      this.crosshairOverlay = new CrosshairOverlay();
      this.chartPanel.addOverlay(crosshairOverlay);
    }
  }

  //// イベントリスナー
  public void chartMouseClicked(ChartMouseEvent paramChartMouseEvent) {
    // 使用しない
  }
  public void chartMouseMoved(ChartMouseEvent ev) {
    // 前回の表示をクリアする
    this.crosshairOverlay.clearDomainCrosshairs();
    this.crosshairOverlay.clearRangeCrosshairs();
    //
    JFreeChart jfreeChart = ev.getChart();
    XYPlot plot = (XYPlot) jfreeChart.getPlot();
    ValueAxis xaxis = plot.getDomainAxis();
    Rectangle2D rectangle = this.chartPanel.getScreenDataArea();
    double dx = xaxis.java2DToValue(ev.getTrigger().getX(),rectangle,RectangleEdge.BOTTOM);
    if (!(xaxis.getRange().contains(dx))) { dx = 0.0D; }

    // Xの値を設定する
    Crosshair xCrosshair = new Crosshair(0.0D,Color.GRAY,new BasicStroke(0.0F));
    xCrosshair.setLabelVisible(true);
    xCrosshair.setValue(dx);
    this.crosshairOverlay.addDomainCrosshair(xCrosshair);

    // Yの値を設定する
    Crosshair yCrosshair;
    // シリーズ数を取得する
    int cnt = plot.getDataset().getSeriesCount();
    // それぞれに対して横線を表示する
    for (int i=0; i<cnt; i++) {
      double dy = DatasetUtilities.findYValue(plot.getDataset(),i,dx);
      //
      yCrosshair = new Crosshair(0.0D,Color.GRAY,new BasicStroke(0.0F));
      yCrosshair.setLabelVisible(true);
      yCrosshair.setValue(dy);
      this.crosshairOverlay.addRangeCrosshair(yCrosshair);
    }
  }
  /** 表示データを作成する */
  private XYDataset createDataset() {
    XYSeriesCollection dataset = new XYSeriesCollection();
    // 一本目
    XYSeries xySeries = new XYSeries("data-0");
    for (int j=0; j<10; j++) {
      xySeries.add(j,j+Math.random()*4.0D);
    }
    dataset.addSeries(xySeries);
    // 二本目
    xySeries = new XYSeries("data-1");
    for (int j=0; j<10; j++) {
      xySeries.add(j,9-j+Math.random()*4.0D);
    }
    dataset.addSeries(xySeries);
    return dataset;
  }
  private ChartPanel chartPanel;
  private CrosshairOverlay crosshairOverlay;
}


```

![無題.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/278568/980954f8-c0e2-1844-9a95-7db9b9e05d37.png)