JFreeChart - XYLineAndShapeRenderer getItemLineVisible() not working

此生再无相见时 提交于 2021-02-05 08:00:31

问题


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.

I subclassed XYLineAndShapeRenderer and overrode the getItemLineVisible() method:

@Override
        public boolean getItemLineVisible(int series, int item){
            if(offline){
                return false;
            }else{
                return 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();
            }
        });
    }
}

What am I doing wrong?


回答1:


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;
}

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

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++;
}


来源:https://stackoverflow.com/questions/65649071/jfreechart-xylineandshaperenderer-getitemlinevisible-not-working

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!