在观察者中动态更新饼图? [英] Dynamically update a pie chart in an Observer?

查看:107
本文介绍了在观察者中动态更新饼图?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用饼图在使用JFreeChart包的JFrame中显示一些统计信息.我正在使用PieDataset传递给createChart方法.另外,数据集设置为动态更新,因为我在应用程序中使用了观察者模式,并对其进行了彻底调试.我的问题是,尽管能够动态更新数据集,但框架上的饼图无法按原样进行更新,也许无法采用新的(更新的)值并显示结果.我想知道是否还有其他方法可以动态更新饼图.

I am using pie chart to display some statistics in a JFrame using JFreeChart package. I am using the PieDataset to be passed to the createChart method. Also, the datatset is set to update dynamically, as I am using the observer pattern in my application, which I thoroughly debugged. My issue is that in spite of being able to update the datatset dynamically, the piechart on the frame does not update as it is, maybe not able to take the new (updated) values and display the result. I would like to know if there is some other way to update the pie-chart dynamically.

public void update(Observable observable, Object o) {
    if (o instanceof Game || o instanceof GameController) {
        String label = "<html><head><h1>World Domination View</h1></head><body> ";

        territoriesList = Game.getInstance().getGameMap().getTerritories();
        String[] name = new String[Game.getInstance().getNumPlayers()] ;
        Float[] value = new Float[Game.getInstance().getNumPlayers()];
        for (int i = 0; i < Game.getInstance().getNumPlayers(); i++) {
            int tempTerritoryCount = 0;
            float percentage = 0;

            for (Territory territory : territoriesList) {
                if (territory.getOwner() == Game.getInstance().getPlayerById(i)) {
                    tempTerritoryCount += 1;
                }
            }
            percentage = (float) 100.0 * tempTerritoryCount / Game.getInstance().getGameMap().getTerritories().size();
            label = label + Game.getInstance().getPlayerById(i).getName() + " owns " + percentage
                    + " % territories and owns " + PhaseView.getInstance().curPArmies + "<br/>";
            worldDominationViewLabel.setText(label);
            //dt = createDataset(Game.getInstance().getPlayerById(i).getName(),percentage);

            //createDataset(Game.getInstance().getPlayerById(i).getName(),percentage);
            //for(int j=0; j<Game.getInstance().getNumPlayers();j++){
                name[i] = Game.getInstance().getPlayerById(i).getName();
            //}
            if(name[i] != null)
        {
            value[i] = percentage;
        }


    }
    dt = createDataset(name,value);
    chartPanel = new ChartPanel(createChart(dt));
    chartPanel.setBounds(1024,0,310,300);//390
    chartPanel.setVisible(true);
    frameFromPhase.add(chartPanel);
    worldDominationViewLabel.setText(label + "</body></html>");}}

//the dataset definition
public static PieDataset createDataset(String[] plname,Float[] value){
    DefaultPieDataset dataset = new DefaultPieDataset();
    for(int i =0; i< plname.length;i++){
        dataset.setValue(plname[i],value[i]);

    }
    return dataset;
}

//chart definition
public static JFreeChart createChart(PieDataset dataset ) {
    JFreeChart chart = ChartFactory.createPieChart(
            "Player Map Domination: Territorywise",   // chart title
            dataset,          // data
            true,             // include legend
            true,
            false);

    return chart;
}

推荐答案

如建议的此处,请勿创建每次更改都有新的数据集和图表;相反,将更新图表的数据模型PieDataset和监听的视图". Observer 接口的实现可以使用update()方法的方法来更新图表的模型,就像JButton的操作处理程序一样.从这个完整的示例开始,我向View添加了一个空饼图,并修改了update()以跟踪猜测通过在统计图数据集上调用setValue().

As suggested here, don't create a new dataset and chart with each change; instead, "update the chart's data model, PieDataset, and the listening view will follow." An implementation of the Observer interface can update the chart's model in its update() method, just as well as the action handler of a JButton can. Starting from this complete example, I've added an empty pie chart to View and modified update() to track guesses by invoking setValue() on the chart's dataset.

class View extends JPanel {

    private static final String s = "Click a button.";
    private static final int SIZE = 256;
    private Model model;
    private ColorIcon icon = new ColorIcon(SIZE, Color.gray);
    private JLabel label = new JLabel(s, icon, JLabel.CENTER);
    DefaultPieDataset dataset = new DefaultPieDataset();

    public View(Model model) {
        super(new BorderLayout());
        this.model = model;
        label.setVerticalTextPosition(JLabel.BOTTOM);
        label.setHorizontalTextPosition(JLabel.CENTER);
        this.add(label, BorderLayout.CENTER);
        this.add(genButtonPanel(), BorderLayout.SOUTH);
        PiePlot plot = new PiePlot(dataset);
        plot.setSimpleLabels(true);
        JFreeChart chart = new JFreeChart(null, null, plot, false);
        this.add(new ChartPanel(chart) {
            @Override
            public Dimension getPreferredSize() {
                return new Dimension(SIZE, SIZE);
            }
        }, BorderLayout.WEST);
        model.addObserver(new ModelObserver());
    }
    …    
    private class ModelObserver implements Observer {

        private int pass, fail;

        @Override
        public void update(Observable o, Object arg) {
            if (arg == null) {
                label.setText(s);
                icon.color = Color.gray;
            } else {
                if ((Boolean) arg) {
                    label.setText("Win!");
                    dataset.setValue("Pass", ++pass);
                } else {
                    label.setText("Keep trying.");
                    dataset.setValue("Fail", ++fail);
                }
            }
        }
    }
    …
}

这篇关于在观察者中动态更新饼图?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆