package org.rrd4j.inspector; import org.rrd4j.core.*; import org.rrd4j.graph.RrdGraphDef; import org.rrd4j.graph.RrdGraph; import org.rrd4j.graph.RrdGraphInfo; import org.rrd4j.data.LinearInterpolator; import javax.swing.*; import javax.swing.filechooser.FileFilter; import java.awt.*; import java.awt.event.*; import java.io.IOException; import java.io.File; import java.io.RandomAccessFile; import java.util.Date; class GraphFrame extends JFrame { private static final Color COLOR = Color.RED; private static final int WIDTH = 400, HEIGHT = 240; private int deltaWidth = 0, deltaHeight = 0; private Color color = COLOR; private GraphPanel graphPanel = new GraphPanel(); private JComboBox graphCombo = new JComboBox(); private RrdGraph rrdGraph; private String sourcePath; private int dsIndex, arcIndex; GraphFrame(String sourcePath, int dsIndex, int arcIndex) { this.sourcePath = sourcePath; this.dsIndex = dsIndex; this.arcIndex = arcIndex; fillGraphCombo(); constructUI(); pack(); //createRrdGraph(); Util.placeWindow(this); setVisible(true); } private void createRrdGraph() { System.out.println("Creating graph..."); try { RrdDb rrdDb = new RrdDb(sourcePath, true); RrdDef rrdDef; long[] timestamps; double[] values; String dsName; long t1, t2; try { Datasource ds = rrdDb.getDatasource(dsIndex); Archive arc = rrdDb.getArchive(arcIndex); Robin robin = arc.getRobin(dsIndex); dsName = ds.getName(); t1 = arc.getStartTime(); t2 = arc.getEndTime(); long step = arc.getArcStep(); int count = robin.getSize(); timestamps = new long[count]; for (int i = 0; i < count; i++) { timestamps[i] = t1 + i * step; } values = robin.getValues(); rrdDef = rrdDb.getRrdDef(); } finally { rrdDb.close(); } RrdGraphDef rrdGraphDef = new RrdGraphDef(); rrdGraphDef.setTimeSpan(t1, t2); rrdGraphDef.setImageFormat("png"); rrdGraphDef.setTitle(rrdDef.getDsDefs()[dsIndex].dump() + " " + rrdDef.getArcDefs()[arcIndex].dump()); LinearInterpolator linearInterpolator = new LinearInterpolator(timestamps, values); linearInterpolator.setInterpolationMethod(LinearInterpolator.INTERPOLATE_RIGHT); rrdGraphDef.datasource(dsName, linearInterpolator); rrdGraphDef.area(dsName, color, dsName + "\\r"); rrdGraphDef.comment("START: " + new Date(t1 * 1000L) + "\\r"); rrdGraphDef.comment("END: " + new Date(t2 * 1000L) + "\\r"); int width = graphPanel.getWidth(), height = graphPanel.getHeight(); rrdGraphDef.setWidth(width + deltaWidth); rrdGraphDef.setHeight(height + deltaHeight); rrdGraph = new RrdGraph(rrdGraphDef); if (deltaWidth == 0 && deltaHeight == 0) { RrdGraphInfo info = rrdGraph.getRrdGraphInfo(); deltaWidth = graphPanel.getWidth() - info.getWidth(); deltaHeight = graphPanel.getHeight() - info.getHeight(); if (deltaWidth != 0 && deltaHeight != 0) { createRrdGraph(); // recursion is divine! } } } catch (Exception e) { Util.error(this, e); } } private void fillGraphCombo() { try { RrdDb rrdDb = new RrdDb(sourcePath, true); try { RrdDef rrdDef = rrdDb.getRrdDef(); final DsDef[] dsDefs = rrdDef.getDsDefs(); final ArcDef[] arcDefs = rrdDef.getArcDefs(); GraphComboItem[] items = new GraphComboItem[rrdDef.getDsCount() * rrdDef.getArcCount()]; int selectedItem = -1; for (int i = 0, k = 0; i < rrdDef.getDsCount(); i++) { for (int j = 0; j < rrdDef.getArcCount(); k++, j++) { String description = dsDefs[i].dump() + " " + arcDefs[j].dump(); items[k] = new GraphComboItem(description, i, j); if (i == dsIndex && j == arcIndex) { selectedItem = k; } } } graphCombo.setModel(new DefaultComboBoxModel(items)); graphCombo.setSelectedIndex(selectedItem); } finally { rrdDb.close(); } } catch (Exception e) { Util.error(this, e); } } private void constructUI() { setTitle(new File(sourcePath).getName()); JPanel content = (JPanel) getContentPane(); content.setLayout(new BorderLayout(0, 0)); content.add(graphCombo, BorderLayout.NORTH); graphPanel.setPreferredSize(new Dimension(WIDTH, HEIGHT)); content.add(graphPanel, BorderLayout.CENTER); JPanel southPanel = new JPanel(); southPanel.setLayout(new FlowLayout(FlowLayout.LEFT, 0, 0)); JButton colorButton = new JButton("Change graph color"); southPanel.add(colorButton); colorButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { changeColor(); } }); JButton saveButton = new JButton("Save graph"); saveButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { saveGraph(); } }); southPanel.add(Box.createHorizontalStrut(3)); southPanel.add(saveButton); content.add(southPanel, BorderLayout.SOUTH); // EVENT HANDLERS setDefaultCloseOperation(DISPOSE_ON_CLOSE); addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { closeWindow(); } }); addComponentListener(new ComponentAdapter() { public void componentResized(ComponentEvent e) { createRrdGraph(); graphPanel.repaint(); } }); graphCombo.addItemListener(new ItemListener() { public void itemStateChanged(ItemEvent e) { if (e.getStateChange() == ItemEvent.SELECTED) { GraphComboItem item = (GraphComboItem) e.getItem(); dsIndex = item.getDsIndex(); arcIndex = item.getArcIndex(); createRrdGraph(); graphPanel.repaint(); } } }); } private void closeWindow() { Util.dismissWindow(this); } private void changeColor() { final JColorChooser picker = new JColorChooser(color); ActionListener okListener = new ActionListener() { public void actionPerformed(ActionEvent e) { color = picker.getColor(); createRrdGraph(); repaint(); } }; JColorChooser.createDialog(this, "Select color", true, picker, okListener, null).setVisible(true); } private void saveGraph() { JFileChooser chooser = new JFileChooser(); FileFilter filter = new FileFilter() { public boolean accept(File f) { return f.isDirectory() || f.getAbsolutePath().toLowerCase().endsWith(".png"); } public String getDescription() { return "PNG images"; } }; chooser.setFileFilter(filter); int returnVal = chooser.showSaveDialog(this); if (returnVal == JFileChooser.APPROVE_OPTION) { try { File selectedFile = chooser.getSelectedFile(); String path = selectedFile.getAbsolutePath(); if (!path.toLowerCase().endsWith(".png")) { path += ".png"; selectedFile = new File(path); } if (selectedFile.exists()) { // ask user to overwrite String message = "File [" + selectedFile.getName() + "] already exists. Do you want to overwrite it?"; int answer = JOptionPane.showConfirmDialog(this, message, "File exists", JOptionPane.YES_NO_OPTION); if (answer == JOptionPane.NO_OPTION) { return; } } String absolutePath = selectedFile.getAbsolutePath(); byte[] data = rrdGraph.getRrdGraphInfo().getBytes(); RandomAccessFile f = new RandomAccessFile(absolutePath, "rw"); try { f.write(data); } finally { f.close(); } } catch (IOException e) { Util.error(this, "Could not save graph to file:\n" + e); } } } final class GraphPanel extends JPanel { public void paintComponent(Graphics g) { if (rrdGraph != null) rrdGraph.render(g); } } class GraphComboItem { private String description; private int dsIndex, arcIndex; GraphComboItem(String description, int dsIndex, int arcIndex) { this.description = description; this.dsIndex = dsIndex; this.arcIndex = arcIndex; } public String toString() { return description; } int getDsIndex() { return dsIndex; } int getArcIndex() { return arcIndex; } } }