Java tutorial
/* * Copyright (c) 2005-2011 KOM - Multimedia Communications Lab * * This file is part of PeerfactSim.KOM. * * PeerfactSim.KOM is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * PeerfactSim.KOM is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with PeerfactSim.KOM. If not, see <http://www.gnu.org/licenses/>. * */ package de.tud.kom.p2psim.impl.skynet.visualization; import java.awt.BasicStroke; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Dimension; import java.awt.FlowLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.text.DecimalFormat; import java.util.Arrays; import java.util.HashMap; import javax.swing.BorderFactory; import javax.swing.JComponent; import javax.swing.JPanel; import javax.swing.JRadioButton; import javax.swing.border.EtchedBorder; import org.jfree.chart.ChartFactory; import org.jfree.chart.ChartPanel; import org.jfree.chart.JFreeChart; import org.jfree.chart.axis.DateAxis; import org.jfree.chart.plot.XYPlot; import org.jfree.chart.renderer.xy.DeviationRenderer; import org.jfree.chart.renderer.xy.XYItemRenderer; import org.jfree.chart.util.RelativeDateFormat; import org.jfree.data.xy.YIntervalSeries; import org.jfree.data.xy.YIntervalSeriesCollection; import de.tud.kom.p2psim.impl.skynet.SkyNetPropertiesReader; import de.tud.kom.p2psim.impl.skynet.visualization.util.DataSet; import de.tud.kom.p2psim.impl.skynet.visualization.util.DeviationSet; import de.tud.kom.p2psim.impl.skynet.visualization.util.SeriesInfo; import de.tud.kom.p2psim.impl.skynet.visualization.util.VisualizationType; /** * * @author <peerfact@kom.tu-darmstadt.de> * @version 05/06/2011 * */ public class MetricsPlot implements ActionListener { private JPanel container; private ChartPanel plotPanel; private JFreeChart chart; private static String X_AXIS_TITLE = "Time [h:m:s]"; private long step; private int interval; private int plotWidth; private int plotHeight; private int boxOffset = 25; private long upperDomainBound; private boolean autoScrolling; private HashMap<String, SeriesInfo> displayedSeries; private Color[] colors = { Color.ORANGE, Color.RED, Color.PINK, Color.BLUE, Color.GREEN }; private boolean showSdtDev; private boolean showMin; private boolean showMax; private VisualizationType visType; public MetricsPlot(String title, long time, int interval, int plotWidth, int plotHeight, VisualizationType visType) { this.visType = visType; this.container = new JPanel(new BorderLayout(), true); this.plotWidth = plotWidth; this.plotHeight = plotHeight; this.displayedSeries = new HashMap<String, SeriesInfo>(); this.autoScrolling = false; showSdtDev = false; showMin = false; showMax = false; SkyNetPropertiesReader instance = SkyNetPropertiesReader.getInstance(); if (visType == VisualizationType.Attribute) { this.step = SkyNetPropertiesReader.getInstance().getTimeProperty("AttributeUpdateTime"); this.interval = (int) (interval * (instance.getTimeProperty("MetricUpdateTime") / (double) instance.getTimeProperty("AttributeUpdateTime"))); } else { this.step = instance.getTimeProperty("MetricUpdateTime"); this.interval = interval; } createChartPanel(title, time); } private void createChartPanel(String title, long time) { YIntervalSeriesCollection dataset = new YIntervalSeriesCollection(); chart = ChartFactory.createTimeSeriesChart(title, X_AXIS_TITLE, "", dataset, true, true, true); XYPlot plot = (XYPlot) chart.getPlot(); DeviationRenderer errorRenderer = new DeviationRenderer(); errorRenderer.setShapesVisible(false); errorRenderer.setLinesVisible(true); errorRenderer.setAlpha(0.0f); // errorRenderer.setDrawYError(false); // errorRenderer.setDrawXError(false); plot.setRenderer(errorRenderer); plot.setBackgroundPaint(Color.WHITE); plot.setRangeGridlinePaint(Color.DARK_GRAY); plot.setDomainGridlinePaint(Color.DARK_GRAY); upperDomainBound = (time / 1000) + ((interval - 1) * step / 1000); DateAxis domain = (DateAxis) plot.getDomainAxis(); domain.setAutoRange(false); domain.setRange((time / 1000), upperDomainBound); RelativeDateFormat rdf = new RelativeDateFormat(); rdf.setHourSuffix(":"); rdf.setMinuteSuffix(":"); rdf.setSecondSuffix(""); rdf.setSecondFormatter(new DecimalFormat("0")); domain.setDateFormatOverride(rdf); plot.setDomainAxis(domain); plotPanel = new ChartPanel(chart, true); setSizeOfComponent(plotPanel, new Dimension(plotWidth, plotHeight)); container.add(plotPanel, BorderLayout.CENTER); container.add(createRadioBoxes(visType == VisualizationType.Metric), BorderLayout.SOUTH); setSizeOfComponent(container, new Dimension(plotWidth, plotHeight + boxOffset)); } public JPanel getPlotPanel() { return container; } public void updatePlot(String plotTitle, DataSet dataSet) { if (displayedSeries.size() == 0) { if (dataSet.getVisType() == VisualizationType.Metric) { displayedSeries.putAll(createMetricSeriesInfo(dataSet)); } else { displayedSeries.putAll(createStateSeriesInfo(dataSet)); } } else { updateSeriesInfo(dataSet); } updateChartPanel(plotTitle); } private void updateChartPanel(String plotTitle) { XYPlot plot = (XYPlot) chart.getPlot(); YIntervalSeriesCollection dataset = new YIntervalSeriesCollection();// (YIntervalSeriesCollection) // plot.getDataset() String[] names = displayedSeries.keySet().toArray(new String[displayedSeries.keySet().size()]); Arrays.sort(names, null); if (!autoScrolling && displayedSeries.get(names[0]).getDataSeries().getItemCount() == displayedSeries .get(names[0]).getDataSeries().getMaximumItemCount()) { autoScrolling = true; DateAxis domain = (DateAxis) plot.getDomainAxis(); domain.setAutoRange(true); plot.setDomainAxis(domain); } for (int i = 0; i < names.length; i++) { if (names[i].startsWith("Min_")) { if (showMin) dataset.addSeries(displayedSeries.get(names[i]).getDataSeries()); } else if (names[i].startsWith("Max_")) { if (showMax) dataset.addSeries(displayedSeries.get(names[i]).getDataSeries()); } else { dataset.addSeries(displayedSeries.get(names[i]).getDataSeries()); } } plot.setDataset(dataset); plot.setRenderer(configureRendererForDataSet(plot.getRenderer(), dataset)); plotPanel.setChart(chart); setSizeOfComponent(plotPanel, new Dimension(plotWidth, plotHeight)); container.add(plotPanel, BorderLayout.CENTER); setSizeOfComponent(container, new Dimension(plotWidth, plotHeight + boxOffset)); } private DeviationRenderer configureRendererForDataSet(XYItemRenderer r, YIntervalSeriesCollection dataSet) { DeviationRenderer renderer = (DeviationRenderer) r; YIntervalSeries serie = null; for (int i = 0; i < dataSet.getSeriesCount(); i++) { serie = dataSet.getSeries(i); renderer.setSeriesStroke(i, displayedSeries.get(serie.getKey()).getStroke()); renderer.setSeriesPaint(i, displayedSeries.get(serie.getKey()).getColor()); renderer.setSeriesFillPaint(i, Color.LIGHT_GRAY); } if (showSdtDev) { renderer.setAlpha(0.3f); } return renderer; } private JPanel createRadioBoxes(boolean enable) { JPanel rbPanel = new JPanel(new FlowLayout()); rbPanel.add(setJRadioButton("Min-Values", enable)); rbPanel.add(setJRadioButton("Max-Values", enable)); rbPanel.add(setJRadioButton("Standard-Deviation", enable)); setSizeOfComponent(rbPanel, new Dimension(plotWidth, boxOffset)); rbPanel.setBorder(BorderFactory.createEtchedBorder(EtchedBorder.LOWERED)); return rbPanel; } private JRadioButton setJRadioButton(String title, boolean enable) { JRadioButton radioButton = new JRadioButton(title); radioButton.addActionListener(this); radioButton.setEnabled(enable); return radioButton; } private void setSizeOfComponent(JComponent component, Dimension dim) { component.setMinimumSize(dim); component.setMaximumSize(dim); component.setPreferredSize(dim); component.setSize(dim); } private HashMap<String, SeriesInfo> createMetricSeriesInfo(DataSet dataSet) { String[] names = dataSet.getNames(); HashMap<String, SeriesInfo> tempMap = new HashMap<String, SeriesInfo>(); SeriesInfo seriesInfo = null; for (int i = 0; i < names.length; i++) { DeviationSet set = dataSet.getValues()[i]; if (names[i].startsWith("Min_")) { seriesInfo = new SeriesInfo(interval, names[i], Color.BLUE, new BasicStroke(1)); } else if (names[i].startsWith("Max_")) { seriesInfo = new SeriesInfo(interval, names[i], Color.RED, new BasicStroke(1)); } else if (names[i].startsWith("Measured")) { seriesInfo = new SeriesInfo(interval, names[i], Color.GRAY, new BasicStroke(3)); } else { seriesInfo = new SeriesInfo(interval, names[i], Color.BLACK, new BasicStroke(4)); } seriesInfo.getDataSeries().add(dataSet.getTime(), set.getValue(), set.getValue() + set.getDeviation(), Math.max(set.getValue() - set.getDeviation(), 0)); tempMap.put(names[i], seriesInfo); } return tempMap; } private HashMap<String, SeriesInfo> createStateSeriesInfo(DataSet dataSet) { String[] names = dataSet.getNames(); HashMap<String, SeriesInfo> tempMap = new HashMap<String, SeriesInfo>(); SeriesInfo seriesInfo = null; int counter = 0; for (int i = 0; i < names.length; i++) { DeviationSet set = dataSet.getValues()[i]; if (names[i].startsWith("Real ")) { seriesInfo = new SeriesInfo(interval, names[i], Color.BLACK, new BasicStroke(3)); } else { seriesInfo = new SeriesInfo(interval, names[i], colors[counter], new BasicStroke(1)); counter++; } seriesInfo.getDataSeries().add(dataSet.getTime(), set.getValue(), set.getValue() + set.getDeviation(), Math.max(set.getValue() - set.getDeviation(), 0)); tempMap.put(names[i], seriesInfo); } return tempMap; } private void updateSeriesInfo(DataSet dataSet) { String[] names = dataSet.getNames(); for (int i = 0; i < names.length; i++) { DeviationSet set = dataSet.getValues()[i]; displayedSeries.get(names[i]).getDataSeries().add(dataSet.getTime(), set.getValue(), set.getValue() + set.getDeviation(), Math.max(set.getValue() - set.getDeviation(), 0)); } } @Override public void actionPerformed(ActionEvent e) { JRadioButton button = (JRadioButton) e.getSource(); if (button.isSelected()) { if (e.getActionCommand().equals("Min-Values")) { showMin = true; } else if (e.getActionCommand().equals("Max-Values")) { showMax = true; } else { showSdtDev = true; } } else { if (e.getActionCommand().equals("Min-Values")) { showMin = false; } else if (e.getActionCommand().equals("Max-Values")) { showMax = false; } else { showSdtDev = false; } } } }