JFreeChart-XYLineAndShapeRenderer getItemLineVisible()无法正常工作 [英] JFreeChart - XYLineAndShapeRenderer getItemLineVisible() not working

查看:48
本文介绍了JFreeChart-XYLineAndShapeRenderer getItemLineVisible()无法正常工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用DynamicTimeSeriesCollection模拟虚拟实时数据,例如.在随机间隔内,传递到绘图的数据应丢失"以模拟网络连接丢失.此时,此图应该停止绘制,并且仅在辍学平息之后才开始绘制数据.

I'm simulating dummy real-time data using DynamicTimeSeriesCollection, like this. During random intervals, the data being passed to the plot should 'dropout' to simulate a network connection loss. At this point, this plot should stop drawing and only start plotting the data after the dropout has subsided.

我继承了XYLineAndShapeRenderer并覆盖了getItemLineVisible()方法:

I subclassed XYLineAndShapeRenderer and overrode the getItemLineVisible() method:

@Override
        public boolean getItemLineVisible(int series, int item){
            if(offline){
                return false;
            }else{
                return true;
            }
        }

但是,当离线状态为true时,所有点仍将绘制在图形上.

However when offline is true, all points are still being drawn on the graph.

public class Test extends ApplicationFrame {

    private static final String TITLE = "Dynamic Series";
    private static final String START = "Start";
    private static final String STOP = "Stop";
    private static final int COUNT = 1000*60;
    private static final int FAST = 1; //1000/FAST = occurrences per second real time
    private static final int REALTIME = FAST * 1000;
    private static final Random random = new Random();
    private static final double threshold = 35;
    private double gateStart = ThreadLocalRandom.current().nextInt(0, 101);
    private boolean returning = false;
    private boolean offline = false;
    private Timer timer;
    private Calendar startDate;
    private static final int simulationSpeed = 1000/FAST;
    private final TimeSeries seriesA = new TimeSeries("A");

    public Test(final String title) throws ParseException {
        super(title);

        SimpleDateFormat formatter = new SimpleDateFormat("dd/mm/yyyy HH:mm", Locale.ENGLISH);
        PriceParser parser = new PriceParser();
        List<List<String>> priceData = parser.parse();
        Date date = formatter.parse(priceData.get(0).get(0));
        startDate = Calendar.getInstance();
        startDate.setTime(date);
        Calendar timeBaseStartDate = Calendar.getInstance();
        timeBaseStartDate.setTime(startDate.getTime());
        timeBaseStartDate.add(Calendar.SECOND, -COUNT);
        final TimeSeriesCollection dataset = new TimeSeriesCollection();
        dataset.addSeries(this.seriesA);

        JFreeChart chart = createChart(dataset);
        final JComboBox combo = new JComboBox();
        combo.addItem("Fast");
        combo.addItem("Real-time");
        combo.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                if ("Fast".equals(combo.getSelectedItem())) {
                    timer.setDelay(FAST);
                } else {
                    timer.setDelay(REALTIME);
                }
            }
        });

        JFrame frame = new JFrame("Test");
        JLabel label = new JLabel("Network connectivity lost.");

        this.add(new ChartPanel(chart), BorderLayout.CENTER);
        JPanel btnPanel = new JPanel(new FlowLayout());
        btnPanel.add(combo);
        JPanel test = new JPanel();
        test.add(label);
        this.add(btnPanel, BorderLayout.SOUTH);

        // frame.add(btnPanel);
        //frame.add(test);

        timer = new Timer(FAST, new ActionListener() {
            Date timeToCheck = formatter.parse(priceData.get(0).get(0));
            Calendar pauseResume = Calendar.getInstance();
            Calendar offlineTime = Calendar.getInstance();
            boolean paused = false;
            boolean waiting = false;
            //boolean offline = false;
            double currentPrice;
            float[] newData = new float[1];
            PopupFactory pf = PopupFactory.getSharedInstance();
            Popup popup;

            @Override
            public void actionPerformed(ActionEvent e) {
                Date datasetTime = new Date();
                if(offline){
                    System.out.println("Offline: "+offlineTime.getTime());
                    System.out.println("Current: "+datasetTime);
                    if(offlineTime.getTime().compareTo(datasetTime) == 0){
                        offline = false;
                        System.out.println("Im no longer offline");
                        popup.hide();
                    }
                }

                if(ThreadLocalRandom.current().nextInt(0, 1001) > 999 && !offline){
                    offline = true;
                    offlineTime.setTime(datasetTime);
                    offlineTime.add(Calendar.SECOND, ThreadLocalRandom.current().nextInt(1, 5)*10);

//                    dataset.addValue(0, 0, null);
                    popup = pf.getPopup(btnPanel, label, 900, 300);
                    popup.show();
                }

                if(timeToCheck.compareTo(datasetTime) == 0){
                    currentPrice = Double.valueOf(priceData.get(0).get(1));
                    paused = currentPrice >= threshold;
                    priceData.remove(0);
                    try {
                        timeToCheck = formatter.parse(priceData.get(0).get(0));
                    } catch (ParseException ex) {
                        ex.printStackTrace();
                    }
                }

                if(!paused) {
                    if (Math.round(gateStart) * 10 / 10.0 == 100d) {
                        returning = true;
                    } else if (Math.round(gateStart) * 10 / 10.0 == 0) {
                        returning = false;
                    }
                    if (returning) {
                        gateStart -= 0.1d;
                    } else {
                        gateStart += 0.1d;
                    }
                }else{
                    if(datasetTime.compareTo(pauseResume.getTime()) == 0 && currentPrice < threshold){
                        paused = false;
                        waiting = false;
                    }else{
                        if(Math.round(gateStart)*10/10.0 == 0 || Math.round(gateStart)*10/10.0 == 100){
                            if(!waiting){
                                pauseResume.setTime(datasetTime);
                                pauseResume.add(Calendar.SECOND, 120);
                            }
                            waiting = true;
                        }else{
                            if(Math.round(gateStart)*10/10.0 >= 50){
                                gateStart += 0.1d;
                            }else if(Math.round(gateStart)*10/10.0 < 50){
                                gateStart -= 0.1d;
                            }
                        }
                    }
                }
                newData[0] = (float)gateStart;
                seriesA.addOrUpdate(new Second(), gateStart);
            }
        });
    }

    private JFreeChart createChart(final XYDataset dataset) {
        final JFreeChart result = ChartFactory.createTimeSeriesChart(
                TITLE, "Time", "Shearer Position", dataset, true, true, false);
        final XYPlot plot = result.getXYPlot();
        plot.setDomainZeroBaselineVisible(false);
        XYLineAndShapeRendererTest renderer = new XYLineAndShapeRendererTest(true, false);
        plot.setRenderer(renderer);
        DateAxis domain = (DateAxis)plot.getDomainAxis();

        Calendar endDate = Calendar.getInstance();
        endDate.setTime(new Date());
        endDate.add(Calendar.HOUR_OF_DAY, 12);
        System.out.println(new Date());
        System.out.println(endDate.getTime());
        domain.setRange(new Date(), endDate.getTime());
        domain.setTickUnit(new DateTickUnit(DateTickUnitType.HOUR, 1));
        domain.setDateFormatOverride(new SimpleDateFormat("HH:mm"));

        ValueAxis range = plot.getRangeAxis();
        range.setRange(0, 100);

        return result;
    }

    private class XYLineAndShapeRendererTest extends XYLineAndShapeRenderer {

        private boolean drawSeriesLineAsPath;

        public XYLineAndShapeRendererTest(boolean line, boolean shapes){
            super(line, shapes);
        }

        @Override
        public Paint getItemPaint(int row, int col) {
            if(!offline){
                return super.getItemPaint(row, col);
            }else{
                return new Color(0, 0, 0);
            }

        }
    }

    private void start() {
        timer.start();
    }

    public static void main(final String[] args) {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                Test demo = null; //pass date in from csv
                try {
                    demo = new Test(TITLE);
                } catch (ParseException e) {
                    e.printStackTrace();
                }
                demo.pack();
                RefineryUtilities.centerFrameOnScreen(demo);
                demo.setVisible(true);
                demo.start();
            }
        });
    }
}

我在做什么错了?

推荐答案

一种方法是在离线时附加适当的基线值.从此示例开始,范围以零毫伏为中心.下面的修改在60到90毫秒之间添加了零:

One approach would be to append an appropriate baseline value when off line. Starting from this example, the range is centered on a value of zero millivolts. The modification below adds zeroes between 60 and 90 milliseconds:

private float[] gaussianData() {
    float[] a = new float[COUNT];
    for (int i = 0; i < a.length; i++) {
        if (i > 60 && i < 90) a[i] = 0;
        else a[i] = randomValue();
    }
    return a;
}

在我的情况下,一段 offline 应该有效地停止绘制图形.

In my instance, a period of offline should effectively stop graphing.

使用此处建议的方法,该方法使用setMaximumItemAge()限制显示的记录数.根据建议此处添加null值,以中断显示.从这个示例开始,我得到了以下显示的更改:

Use the approach suggested here, which uses setMaximumItemAge() to limit the number of displayed records. Add null values, as suggested here, to interrupt the display. Starting from this example, I got this display with these changes:

seriesA.setMaximumItemCount(120);
seriesB.setMaximumItemCount(120);
…
int i;
…
public void addNull() {
    this.seriesA.add(new Millisecond(), null);
    this.seriesB.add(new Millisecond(), null);
}

@Override
public void actionPerformed(ActionEvent e) {
    if (i > 60 && i < 90) {
        demo.addNull();
    } else {
        …
    }
    i++;
}

这篇关于JFreeChart-XYLineAndShapeRenderer getItemLineVisible()无法正常工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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