2013-11-02 4 views
1

У меня есть диаграмма рассеивания, которая отображает позиции агентов. Эти позиции меняются. Мне было интересно, как я могу перекрасить/перерисовать диаграмму рассеяния с новыми позициямиДинамически перекрашивать ScatterPlot в jfreechart

мой метод рисования. Мне нужно перерисовать в функции updatePositions. Есть ли способ реализовать любой слушатель для ScatterPlot?

private ChartPanel createPanel() { 
    JFreeChart jfreechart = ChartFactory.createScatterPlot(
      title, "", "", initPositions(),PlotOrientation.VERTICAL, true, true, false); 
    XYPlot xyPlot = (XYPlot) jfreechart.getPlot(); 
    xyPlot.setDomainCrosshairVisible(true); 
    xyPlot.setRangeCrosshairVisible(true); 
    XYItemRenderer renderer = xyPlot.getRenderer(); 
    renderer.setSeriesPaint(0, Color.blue); 
    adjustAxis((NumberAxis) xyPlot.getDomainAxis(), true); 
    adjustAxis((NumberAxis) xyPlot.getRangeAxis(), false); 
    xyPlot.setBackgroundPaint(Color.white); 
    return new ChartPanel(jfreechart); 
} 

private void adjustAxis(NumberAxis axis, boolean vertical) { 
    axis.setRange(-1, lattice+1); 
    axis.setTickUnit(new NumberTickUnit(1)); 
    axis.setVerticalTickLabels(vertical); 
} 

private XYDataset initPositions() { 
    XYSeriesCollection xySeriesCollection = new XYSeriesCollection(); 

    for (int i = 0; i < populationSize; i++) { 
     if(population.get(i).status==1){ 
      healthy.add(population.get(i).position[0], population.get(i).position[1]); 
     }else if(population.get(i).status==2){ 
      infected.add(population.get(i).position[0], population.get(i).position[1]); 
     }else if(population.get(i).status==3){ 
      recovered.add(population.get(i).position[0], population.get(i).position[1]); 
     } 
    } 

    xySeriesCollection.addSeries(healthy); 
    xySeriesCollection.addSeries(infected); 
    xySeriesCollection.addSeries(recovered); 
    return xySeriesCollection; 
} 

public void clear(){ 
    healthy.clear(); 
    infected.clear(); 
    recovered.clear(); 
} 
public void updatePositions(ArrayList<Person> pop){ 
    population = pop; 

    for (int i = 0; i < populationSize; i++) { 
     if(population.get(i).status==1){ 
      healthy.addOrUpdate(population.get(i).position[0], population.get(i).position[1]); 
     }else if(population.get(i).status==2){ 
      infected.addOrUpdate(population.get(i).position[0], population.get(i).position[1]); 
     }else if(population.get(i).status==3){ 
      recovered.addOrUpdate(population.get(i).position[0], population.get(i).position[1]); 
     } 
    } 
} 

Это метод в основном классе. Обновление позиций выполняется в функции «Переместить»

public static void main(String [] args){ 
    createPopulation(populationSize); 
    initInfection(infectRatio); 

    EventQueue.invokeLater(new Runnable() {    
     @Override   
     public void run() {   
      DrawArea demo = new DrawArea("Demo", lattice, populationSize,population);    
      demo.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);     
      demo.pack();     
      demo.setLocationRelativeTo(null);    
      demo.setVisible(true); 
      for(int i =0;i<1000;i++){ 

       for(int j=0; j<populationSize; j++){ 
        population.get(j).move(0.8); 
       } 
       demo.clear(); 
       demo.updatePositions(population); 
      } 
     }   
    }); 
} 

ответ

1

Как показано ниже, на графике (вид) слушает его набора данных (модели) и обновляет себя соответственно. Когда нажата кнопка Move, каждая из XYDataItem в серии изменена в update(), чтобы отразить ее новое положение.

image

import java.awt.BorderLayout; 
import java.awt.Dimension; 
import java.awt.EventQueue; 
import java.awt.event.ActionEvent; 
import java.util.*; 
import javax.swing.AbstractAction; 
import javax.swing.JButton; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 
import org.jfree.chart.*; 
import org.jfree.chart.axis.NumberAxis; 
import org.jfree.chart.axis.NumberTickUnit; 
import org.jfree.chart.plot.PlotOrientation; 
import org.jfree.chart.plot.XYPlot; 
import org.jfree.chart.renderer.xy.XYItemRenderer; 
import org.jfree.data.xy.XYDataItem; 
import org.jfree.data.xy.XYDataset; 
import org.jfree.data.xy.XYSeries; 
import org.jfree.data.xy.XYSeriesCollection; 

/** 
* @see http://stackoverflow.com/a/19749344/230513 
* @see http://stackoverflow.com/a/7208723/230513 
*/ 
public class ScatterMove extends JFrame { 

    private static final int N = 16; 
    private static final String title = "Scatter Move Demo"; 
    private static final Random rand = new Random(); 
    private XYSeries moved = new XYSeries("Population"); 

    public ScatterMove(String s) { 
     super(s); 
     update(); 
     final ChartPanel chartPanel = createDemoPanel(); 
     this.add(chartPanel, BorderLayout.CENTER); 
     JPanel control = new JPanel(); 
     control.add(new JButton(new AbstractAction("Move") { 
      @Override 
      public void actionPerformed(ActionEvent e) { 
       moved.clear(); 
       update(); 
      } 
     })); 
     this.add(control, BorderLayout.SOUTH); 
    } 

    private void update() { 
     for (int i = 0; i < N; i++) { 
      moved.add(new XYDataItem(rand.nextGaussian(), rand.nextGaussian())); 
     } 
    } 

    private ChartPanel createDemoPanel() { 
     JFreeChart jfreechart = ChartFactory.createScatterPlot(
      title, "X", "Y", createSampleData(), 
      PlotOrientation.VERTICAL, true, true, false); 
     XYPlot xyPlot = (XYPlot) jfreechart.getPlot(); 
     XYItemRenderer renderer = xyPlot.getRenderer(); 
     NumberAxis domain = (NumberAxis) xyPlot.getDomainAxis(); 
     domain.setRange(-3.0, 3.0); 
     domain.setTickUnit(new NumberTickUnit(1)); 
     NumberAxis range = (NumberAxis) xyPlot.getRangeAxis(); 
     range.setRange(-3.0, 3.0); 
     range.setTickUnit(new NumberTickUnit(1)); 
     return new ChartPanel(jfreechart){ 

      @Override 
      public Dimension getPreferredSize() { 
       return new Dimension(640, 480); 
      } 
     }; 
    } 

    private XYDataset createSampleData() { 
     XYSeriesCollection xySeriesCollection = new XYSeriesCollection(); 
     xySeriesCollection.addSeries(moved); 
     return xySeriesCollection; 
    } 

    public static void main(String args[]) { 
     EventQueue.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       ScatterMove demo = new ScatterMove(title); 
       demo.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
       demo.pack(); 
       demo.setLocationRelativeTo(null); 
       demo.setVisible(true); 
      } 
     }); 
    } 
} 
+0

хорошо там идет мой XD сна. Спасибо, я попробую. Кажется, он будет работать с тяжелой модификацией (точки меняются в другом классе, поэтому я должен каждый раз обновлять/передавать в сюжет-класс) – MayTheSchwartzBeWithYou

+1

Вместо очистки и добавления вам может понадобиться просмотр и расширение абстрактного класс, который реализует 'XYDataset', как показано [здесь] (http://stackoverflow.com/a/12481509/230513). – trashgod

Смежные вопросы