2011-11-03 7 views
3

스택의 개별 막대를 선택할 수있는 위치에 스택 막대 차트가 있습니다. 그러나 ChartMouseListener는 ChartMouseEvent를 해당 ChartEntity로 해석하지 않습니다. 여기에 리스너 조각입니다 :JFreeChart MouseListener가 차트 요소를 해결하지 않습니다.

public void chartMouseClicked(ChartMouseEvent event){ 
     ChartEntity entity = event.getEntity(); 
     if(entity != null && (entity instanceof XYItemEntity)){ 
      XYItemEntity item = (XYItemEntity)entity; 
      renderer.select(item.getSeriesIndex(), item.getItem()); 
      return; 
     } 

     // deselect 
     renderer.select(-1,-1); 
    } 

문제는 내가 분명히 바의 일부를 클릭하고 때 event.getEntity()가 null을 반환한다는 것입니다. 모든 막대가 실패하지는 않습니다. 차트의 오른쪽 끝으로 갈수록 좌표의 변화가 더 분명 해집니다. 선택한 바가 바깥을 클릭했을 때 실제로 나타나는지 보여주는 아래의 스냅 샷. SWT 컴포지트 내에서 JFreeChart를 사용하고 있습니다. 누구나 이것이 버그가있는 동작인지 또는 이 해결 방법이 있는지 확인할 수 있습니까? 당신이 그것을 실행하고 막대를 클릭 한 후

enter image description here

다음은, 완전한 sscce - 그것은 새끼를 표시됩니다. 그런 다음 창 크기를 다시 조정하고 바를 선택하십시오. 그리울 것입니다. 그리고 저는 그 실수가 새로운 크기의 기능이라고 생각합니다.

import java.awt.Color; 
import java.awt.Paint; 
import java.util.Random; 

import org.eclipse.swt.SWT; 
import org.eclipse.swt.layout.FillLayout; 
import org.eclipse.swt.layout.GridData; 
import org.eclipse.swt.widgets.Display; 
import org.eclipse.swt.widgets.Shell; 
import org.jfree.chart.ChartMouseEvent; 
import org.jfree.chart.ChartMouseListener; 
import org.jfree.chart.JFreeChart; 
import org.jfree.chart.axis.DateAxis; 
import org.jfree.chart.axis.DateTickMarkPosition; 
import org.jfree.chart.axis.NumberAxis; 
import org.jfree.chart.entity.ChartEntity; 
import org.jfree.chart.entity.XYItemEntity; 
import org.jfree.chart.event.RendererChangeEvent; 
import org.jfree.chart.plot.XYPlot; 
import org.jfree.chart.renderer.xy.StackedXYBarRenderer; 
import org.jfree.chart.renderer.xy.StandardXYBarPainter; 
import org.jfree.data.time.Day; 
import org.jfree.data.time.Hour; 
import org.jfree.data.time.TimeTableXYDataset; 
import org.jfree.data.xy.TableXYDataset; 
import org.jfree.experimental.chart.swt.ChartComposite; 

public class StackedChartSwt { 
    private StackedRenderer renderer; 
    private Color[] colors = new Color[]{ 
      new Color(230,240,255), 
      new Color(240,255,240), 
      new Color(255,255,255), 
      new Color(255,255,240), 
      new Color(255,240,240), 
      new Color(240,240,240) 
    }; 

    public StackedChartSwt(){ 
     Display display = new Display(); 
     final Shell shell = new Shell(display); 
     shell.setLayout(new FillLayout()); 

     JFreeChart chart = createStackedChart(createStackedDataset()); 
     ChartComposite chartComposite = new ChartComposite(shell, SWT.NONE, chart, false, false, false, false, false); 
     chartComposite.setLayoutData(new GridData(GridData.FILL_BOTH)); 
     chartComposite.setRangeZoomable(false); 
     chartComposite.setMenu(null); 
     chartComposite.addChartMouseListener(new ThisMouseListener()); 
     shell.setSize(800, 600); 
     shell.open(); 

     while (!shell.isDisposed()) { 
      if (!display.readAndDispatch()) { 
       display.sleep(); 
      } 
      } 

      display.dispose();   
    } 

    private JFreeChart createStackedChart(TableXYDataset tablexydataset) { 
     DateAxis dateaxis = new DateAxis(); 
     dateaxis.setTickMarkPosition(DateTickMarkPosition.MIDDLE); 
     NumberAxis numberaxis = new NumberAxis("Event counts"); 
     renderer = new StackedRenderer(); 
     XYPlot plot = new XYPlot(tablexydataset, dateaxis, numberaxis, renderer); 
     plot.setBackgroundPaint(Color.white); 
     plot.setDomainGridlinePaint(Color.lightGray); 
     plot.setDomainGridlinesVisible(true); 
     plot.setRangeGridlinesVisible(true); 
     plot.setRangeGridlinePaint(Color.lightGray); 

     JFreeChart chart = new JFreeChart(null, plot); 
     chart.setBackgroundPaint(Color.white); 
     chart.setBorderVisible(false); 
     chart.setBorderPaint(null); 

     return chart; 
    } 

    class StackedRenderer extends StackedXYBarRenderer{ 
     int selectedRow=-1, selectedCol=-1; 
     public StackedRenderer(){ 
      setDrawBarOutline(true); 
      setBarPainter(new StandardXYBarPainter()); 
      setShadowVisible(false); 
      setSeriesPaint(0, Color.blue); 
      setMargin(0.2); 
     } 

     public void select(int row, int col){ 
      selectedRow = row; 
      selectedCol = col; 
      notifyListeners(new RendererChangeEvent(this)); 
     } 

     @Override 
     public Paint getItemPaint(final int row, final int col){ 
      if(row == selectedRow && col == selectedCol) 
       return Color.pink; 
      return colors[row]; 
     } 
    } 

    class ThisMouseListener implements ChartMouseListener{ 
     public void chartMouseMoved(ChartMouseEvent event){ 
     } 

     public void chartMouseClicked(ChartMouseEvent event){ 
      ChartEntity entity = event.getEntity(); 
      if(entity != null && (entity instanceof XYItemEntity)){ 
       XYItemEntity item = (XYItemEntity)entity; 
       renderer.select(item.getSeriesIndex(), item.getItem()); 
       return; 
      } 

      // deselect 
      renderer.select(-1,-1); 
     } 
    } 

    private TableXYDataset createStackedDataset(){ 
     Random random = new Random(0); 
     TimeTableXYDataset ds = new TimeTableXYDataset(); 
     Day day = new Day(); 
     for(int i = 0; i < 24; i++){ 
      Hour hour = new Hour(i, day); 
      ds.add(hour, random.nextInt(20), "A"); 
      ds.add(hour, random.nextInt(20), "B"); 
      ds.add(hour, random.nextInt(20), "C"); 
      ds.add(hour, random.nextInt(20), "D"); 
      ds.add(hour, random.nextInt(20), "E"); 
      ds.add(hour, random.nextInt(20), "F"); 
     } 

     return ds; 
    } 

    public static void main(String[] args){ 
     new StackedChartSwt(); 
    } 
} 
+0

설명하는 문제를 보여주는 [sscce] (http://sscce.org/)를 제공하십시오. – trashgod

+0

@trashgod - sscce를 추가 했으므로 실행할 수 있습니다. 문제를보기 위해 창 크기를 다시 조정하십시오. – Dima

+0

+1 [sscce] (http://sscce.org/); 뿐만 아니라 좋은 파스텔. :-) – trashgod

답변

4

OK, 나는 문제를 발견했습니다. SWT에는 ChartComposite를 생성하는 몇 가지 생성자가 있으며, 대부분의 사용 기본값은 최소/최대 너비와 높이를 지정합니다. 필자의 경우 DEFAULT_MAXIMUM_DRAW_WIDTH (800px) 위의 차트를 확대 할 때마다 좌표가 엉망이되기 시작합니다. 따라서, 해결책은 전체 생성자를 사용하고 디스플레이에 대한 관련 경계를 지정하는 것입니다. 그것은 딱딱한 것이 었습니다 ... 주로 적절한 문서가 부족했기 때문입니다.

3

아래 그림과 같이 스윙에서 실행할 때 모범적 인 렌더러의 모양이 정확합니다. SWT로 상황이 왜 잘못되었는지 확신 할 수 없지만이 결과로 검색 범위를 좁힐 수 있습니다.

enter image description here

import java.awt.Color; 
import java.awt.EventQueue; 
import java.awt.Paint; 
import java.util.Random; 
import javax.swing.JFrame; 
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.DateAxis; 
import org.jfree.chart.axis.DateTickMarkPosition; 
import org.jfree.chart.axis.NumberAxis; 
import org.jfree.chart.entity.ChartEntity; 
import org.jfree.chart.entity.XYItemEntity; 
import org.jfree.chart.event.RendererChangeEvent; 
import org.jfree.chart.plot.XYPlot; 
import org.jfree.chart.renderer.xy.StackedXYBarRenderer; 
import org.jfree.chart.renderer.xy.StandardXYBarPainter; 
import org.jfree.data.time.Day; 
import org.jfree.data.time.Hour; 
import org.jfree.data.time.TimeTableXYDataset; 
import org.jfree.data.xy.TableXYDataset; 

public class StackedChartSwing { 

    private ChartPanel panel; 
    private StackedRenderer renderer; 
    private Color[] colors = new Color[]{ 
     new Color(230, 240, 255), 
     new Color(240, 255, 240), 
     new Color(255, 255, 255), 
     new Color(255, 255, 240), 
     new Color(255, 240, 240), 
     new Color(240, 240, 240) 
    }; 

    public StackedChartSwing() { 
     JFreeChart chart = createStackedChart(createStackedDataset()); 
     panel = new ChartPanel(chart); 
     panel.addChartMouseListener(new ThisMouseListener()); 
    } 

    private JFreeChart createStackedChart(TableXYDataset tablexydataset) { 
     DateAxis dateaxis = new DateAxis(); 
     dateaxis.setTickMarkPosition(DateTickMarkPosition.MIDDLE); 
     NumberAxis numberaxis = new NumberAxis("Event counts"); 
     renderer = new StackedRenderer(); 
     XYPlot plot = new XYPlot(tablexydataset, dateaxis, numberaxis, renderer); 
     plot.setBackgroundPaint(Color.white); 
     plot.setDomainGridlinePaint(Color.lightGray); 
     plot.setDomainGridlinesVisible(true); 
     plot.setRangeGridlinesVisible(true); 
     plot.setRangeGridlinePaint(Color.lightGray); 

     JFreeChart chart = new JFreeChart(null, plot); 
     chart.setBackgroundPaint(Color.white); 
     chart.setBorderVisible(false); 
     chart.setBorderPaint(null); 

     return chart; 
    } 

    class StackedRenderer extends StackedXYBarRenderer { 

     int selectedRow = -1, selectedCol = -1; 

     public StackedRenderer() { 
      setDrawBarOutline(true); 
      setBarPainter(new StandardXYBarPainter()); 
      setShadowVisible(false); 
      setSeriesPaint(0, Color.blue); 
      setMargin(0.2); 
     } 

     public void select(int row, int col) { 
      selectedRow = row; 
      selectedCol = col; 
      notifyListeners(new RendererChangeEvent(this)); 
     } 

     @Override 
     public Paint getItemPaint(final int row, final int col) { 
      if (row == selectedRow && col == selectedCol) { 
       return Color.pink; 
      } 
      return colors[row]; 
     } 
    } 

    class ThisMouseListener implements ChartMouseListener { 

     @Override 
     public void chartMouseMoved(ChartMouseEvent event) { 
     } 

     @Override 
     public void chartMouseClicked(ChartMouseEvent event) { 
      ChartEntity entity = event.getEntity(); 
      if (entity != null && (entity instanceof XYItemEntity)) { 
       XYItemEntity item = (XYItemEntity) entity; 
       renderer.select(item.getSeriesIndex(), item.getItem()); 
       return; 
      } 
      // deselect 
      renderer.select(-1, -1); 
     } 
    } 

    private TableXYDataset createStackedDataset() { 
     Random random = new Random(0); 
     TimeTableXYDataset ds = new TimeTableXYDataset(); 
     Day day = new Day(); 
     for (int i = 0; i < 24; i++) { 
      Hour hour = new Hour(i, day); 
      ds.add(hour, random.nextInt(20), "A"); 
      ds.add(hour, random.nextInt(20), "B"); 
      ds.add(hour, random.nextInt(20), "C"); 
      ds.add(hour, random.nextInt(20), "D"); 
      ds.add(hour, random.nextInt(20), "E"); 
      ds.add(hour, random.nextInt(20), "F"); 
     } 

     return ds; 
    } 

    private void display() { 
     JFrame f = new JFrame("Test"); 
     f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     f.add(panel); 
     f.pack(); 
     f.setLocationRelativeTo(null); 
     f.setVisible(true); 
    } 

    public static void main(String[] args) { 
     EventQueue.invokeLater(new Runnable() { 

      @Override 
      public void run() { 
       new StackedChartSwing().display(); 
      } 
     }); 
    } 
} 
+0

@Dima : 참고로'ChartMouseListener'를 ['BarChartDemo1']에 추가하여 비슷한 결과를 얻었습니다. (http://www.jfree.org/jfreechart/api/javadoc/org/jfree/chart /demo/BarChartDemo1.html)를 Swing 아래에 추가하십시오. – trashgod

+0

예, 스윙은 여기에서 문제가되지 않습니다. 문제는 JFreeChart의 SWT 버전입니다. 사실, 처음 열면 모든 것이 잘 작동합니다. 그러나 호스팅 프레임의 크기를 조정하자마자 상황이 너무 복잡해집니다. 차트가 크기가 조정 된 것을 알지 못하는 것처럼 매우 단순한 무언가 여야합니다. 그러나 자체적으로 그립니다. 렌더러가 쓸모 없게됩니다. 이 물건이 일식 RCP 애플 리케이션에서 일하기 위해 필요하다면 고칠 수없는 경우 부끄러운 일이 있습니다. 모든 라이브러리가 무효가됩니다. – Dima

관련 문제