summaryrefslogtreecommitdiff
path: root/java/src/IceGridGUI/LiveDeployment/GraphView.java
diff options
context:
space:
mode:
authorJose <jose@zeroc.com>2013-01-03 22:53:33 +0100
committerJose <jose@zeroc.com>2013-01-03 22:53:33 +0100
commit77635fc0733d94e1ef97c6dbc7a2fcef4e8433af (patch)
tree7b6dab1678a6d3a12d023206da984faf8f57181c /java/src/IceGridGUI/LiveDeployment/GraphView.java
parentFixed (ICE-5173) - Missing menu for Enable/Disable Metrics View (diff)
downloadice-77635fc0733d94e1ef97c6dbc7a2fcef4e8433af.tar.bz2
ice-77635fc0733d94e1ef97c6dbc7a2fcef4e8433af.tar.xz
ice-77635fc0733d94e1ef97c6dbc7a2fcef4e8433af.zip
Fixed(ICE-5174) - Metrics Graph and disabled Metrics View
Diffstat (limited to 'java/src/IceGridGUI/LiveDeployment/GraphView.java')
-rw-r--r--java/src/IceGridGUI/LiveDeployment/GraphView.java435
1 files changed, 305 insertions, 130 deletions
diff --git a/java/src/IceGridGUI/LiveDeployment/GraphView.java b/java/src/IceGridGUI/LiveDeployment/GraphView.java
index 168921f36f5..97f108a8a4a 100644
--- a/java/src/IceGridGUI/LiveDeployment/GraphView.java
+++ b/java/src/IceGridGUI/LiveDeployment/GraphView.java
@@ -11,6 +11,7 @@ package IceGridGUI.LiveDeployment;
import java.util.Map;
import java.util.List;
+import java.util.Stack;
import java.util.HashMap;
import java.util.ArrayList;
@@ -352,34 +353,12 @@ public class GraphView extends JFrame implements MetricsFieldContext
public void exception(final Ice.LocalException e)
{
- _queue.enqueue(new Runnable()
- {
- public void run()
- {
- removeRows(m);
- }
- }, false);
- if(!(e instanceof Ice.ObjectNotExistException) &&
- !(e instanceof Ice.CommunicatorDestroyedException) &&
- !(e instanceof Ice.ConnectionRefusedException))
- {
- handleError(m, e.toString());
- }
+ addData(m, null, 0);
}
public void exception(final Ice.UserException e)
{
- _queue.enqueue(new Runnable()
- {
- public void run()
- {
- removeRows(m);
- }
- }, false);
- if(!(e instanceof IceMX.UnknownMetricsView))
- {
- handleError(m, e.toString());
- }
+ addData(m, null, 0);
}
};
try
@@ -388,17 +367,7 @@ public class GraphView extends JFrame implements MetricsFieldContext
}
catch(Ice.LocalException e)
{
- _queue.enqueue(new Runnable()
- {
- public void run()
- {
- removeRows(m);
- }
- }, false);
- if(!(e instanceof Ice.CommunicatorDestroyedException))
- {
- handleError(m, e.toString());
- }
+ addData(m, null, 0);
}
}
if(!_done)
@@ -429,21 +398,6 @@ public class GraphView extends JFrame implements MetricsFieldContext
}
}
- private void
- handleError(final MetricsViewInfo metrics, final String error)
- {
- _queue.enqueue(new Runnable()
- {
- public void run()
- {
- JOptionPane.showMessageDialog(GraphView.this,
- "Error retrieving metrics view from `" + metrics.toString() + "'\n" + error,
- "Error",
- JOptionPane.ERROR_MESSAGE);
- }
- }, false);
- }
-
private int _period;
private boolean _done = false;
}
@@ -511,8 +465,8 @@ public class GraphView extends JFrame implements MetricsFieldContext
builder.rowGroupingEnabled(true);
final JSpinner spinner = new JSpinner(refreshPeriod);
builder.append("Sample interval (s):", spinner);
- builder.append("", new JLabel("<html><p>Sample interval in seconds, minimum values is 1 second," +
- "<br/> maximun value is 3600 seconds.</p></html>"));
+ builder.append("", new JLabel("<html><p>Sample interval in seconds, minimum values is 1 " +
+ "second,<br/> maximun value is 3600 seconds.</p></html>"));
refreshPanel = builder.getPanel();
}
@@ -563,7 +517,8 @@ public class GraphView extends JFrame implements MetricsFieldContext
{
if(convertColumnIndexToModel(columnAtPoint(e.getPoint())) == 6)
{
- return _legendModel.getRows(new int[]{rowAtPoint(e.getPoint())})[0].cell.getField().getColumnToolTip();
+ return _legendModel.getRows(new int[]{rowAtPoint(e.getPoint())})[0].cell.getField().
+ getColumnToolTip();
}
else
{
@@ -636,20 +591,27 @@ public class GraphView extends JFrame implements MetricsFieldContext
{
for(MetricsRow row : rows)
{
- String seriesClass = getSeriesClass(row.series);
- _styles.remove(seriesClass);
- //
- // Don't remove the XYChart.Series object here, to avoid the series style classes
- // to be reasign by JavaFX.
- //
- // _chart.getData().remove(row.series);
- try
- {
- row.series.getData().clear();
- }
- catch(NullPointerException ex)
+ for(int i = 0; i < row.series.size(); ++i)
{
- // JavaFX bug
+ XYChart.Series<Number, Number> series = row.series.get(i);
+ String seriesClass = getSeriesClass(series);
+ if(seriesClass != null)
+ {
+ _styles.remove(seriesClass);
+ }
+ //
+ // Don't remove the XYChart.Series object here, to avoid the series
+ // style classes to be reasign by JavaFX.
+ //
+ // _chart.getData().remove(row.series);
+ try
+ {
+ series.getData().clear();
+ }
+ catch(NullPointerException ex)
+ {
+ // JavaFX bug
+ }
}
}
}
@@ -885,21 +847,28 @@ public class GraphView extends JFrame implements MetricsFieldContext
{
for(MetricsRow row : rows)
{
- String seriesClass = getSeriesClass(row.series);
- _styles.remove(seriesClass);
+ String seriesClass = getSeriesClass(row.series.peek());
+ if(seriesClass != null)
+ {
+ _styles.remove(seriesClass);
+ }
//
// Don't remove the XYChart.Series object here, to avoid the series style classes
// to be reasign by JavaFX.
//
// _chart.getData().remove(row.series);
- if(row.series == null || row.series.getData() == null)
+ for(int i = 0; i < row.series.size(); ++i)
{
- continue;
- }
+ XYChart.Series<Number, Number> series = row.series.get(i);
+ if(series == null || series.getData() == null)
+ {
+ continue;
+ }
- while(row.series.getData().size() > 0)
- {
- row.series.getData().remove(0);
+ while(series.getData().size() > 0)
+ {
+ series.getData().remove(0);
+ }
}
}
}
@@ -1061,10 +1030,12 @@ public class GraphView extends JFrame implements MetricsFieldContext
String color = DefaultColors[_chart.getData().size() % DefaultColors.length];
final MetricsRow row = new MetricsRow(data.info, j, color,
new XYChart.Series<Number, Number>());
- _chart.getData().add(row.series);
- String styleClass = getSeriesClass(row.series);
- addStyle(row.series, styleClass, color);
+ XYChart.Series<Number, Number> series = row.series.peek();
+ _chart.getData().add(series);
+
+ String styleClass = getSeriesClass(series);
+ addStyle(series, styleClass, color);
setNodesStyle(styleClass);
columns.put(j.getField().getFieldName(), row);
@@ -1072,7 +1043,7 @@ public class GraphView extends JFrame implements MetricsFieldContext
//
// When a line is clicked we select the correspoding row in the legend table.
//
- javafx.scene.Node n = _chart.lookup(".chart-series-line." + getSeriesClass(row.series));
+ javafx.scene.Node n = _chart.lookup(".chart-series-line." + styleClass);
if(n != null)
{
n.setOnMousePressed(new EventHandler<MouseEvent>()
@@ -1123,6 +1094,69 @@ public class GraphView extends JFrame implements MetricsFieldContext
}, true);
}
+ //
+ // Added a new chart series to an existing row, the graph series will use the
+ // same configuration, the row cell field must be reset so calculations doesn't
+ // take into account previous data. If we don't reset fields here caculations
+ // can be bogus in case the view was disabled and the data in the view was reset.
+ //
+ void addSeries(final MetricsRow row)
+ {
+ XYChart.Series<Number, Number> series = new XYChart.Series<Number, Number>();
+ row.series.push(series);
+ _chart.getData().add(series);
+
+ //
+ // Retrieve the style class asigned by JavaFX to this series, and set the
+ // same style
+ //
+ String styleClass = getSeriesClass(series);
+ addStyle(series, styleClass, row.color);
+ setNodesStyle(styleClass);
+
+ //
+ // Reset the cell field necessary to avoid bogus calculations.
+ //
+ row.cell.resetField();
+
+ //
+ // We need also a new click handler so click works in all segments
+ // of the line.
+ //
+ // When a line is clicked we select the correspoding row in the legend table.
+ //
+ javafx.scene.Node n = _chart.lookup(".chart-series-line." + styleClass);
+ if(n != null)
+ {
+ n.setOnMousePressed(new EventHandler<MouseEvent>()
+ {
+ @Override public void
+ handle(MouseEvent e)
+ {
+ if(e.getEventType() == MouseEvent.MOUSE_PRESSED &&
+ e.getButton() == MouseButton.PRIMARY)
+ {
+ //
+ // Must run in Swing thread.
+ //
+ _queue.enqueue(new Runnable()
+ {
+ public void run()
+ {
+ int i = _legendModel.getRowIndex(row);
+ if(i != -1)
+ {
+ i = _legendTable.convertRowIndexToView(i);
+ _legendTable.setRowSelectionInterval(i, i);
+ }
+ }
+ }, false);
+ }
+ }
+ });
+ }
+ }
+
private void addData(final MetricsViewInfo info, final Map<String, IceMX.Metrics[]> data,
final long timestamp)
{
@@ -1134,70 +1168,163 @@ public class GraphView extends JFrame implements MetricsFieldContext
@Override
public void run()
{
- Map<String, Map<String, Map<String, MetricsRow>>> metricsCollection = _series.get(info);
- if(metricsCollection != null)
+ Map<String, Map<String, Map<String, MetricsRow>>> series = _series.get(info);
+ if(series == null)
+ {
+ return;
+ }
+
+ for(Map.Entry<String, Map<String, Map<String, MetricsRow>>> i : series.entrySet())
{
- for(Map.Entry<String, IceMX.Metrics[]> i : data.entrySet())
+ IceMX.Metrics[] metricsSeq = null;
+ if(data != null)
+ {
+ metricsSeq = data.get(i.getKey());
+ }
+
+ //
+ // Iterate over all configured values, if there isn't data for one configured
+ // field we need to add a gap.
+ //
+
+ for(Map.Entry<String, Map<String, MetricsRow>> j : i.getValue().entrySet())
{
- Map<String, Map<String, MetricsRow>> rows = metricsCollection.get(i.getKey());
- if(rows == null)
+ IceMX.Metrics metrics = null;
+
+ if(metricsSeq != null)
{
- continue;
+ for(IceMX.Metrics m : metricsSeq)
+ {
+ if(m.id.equals(j.getKey()))
+ {
+ metrics = m;
+ break;
+ }
+ }
}
-
- for(IceMX.Metrics metrics : i.getValue())
+ for(Map.Entry<String, MetricsRow> k : j.getValue().entrySet())
{
- Map<String, MetricsRow> columns = rows.get(metrics.id);
- if(columns == null)
+ MetricsRow row = k.getValue();
+ //
+ // If there isn't a metrics object we disable the row and add a dummy value.
+ //
+ if(metrics == null)
{
- continue;
+ //
+ // If the row isn't disabled we add a new serie to represent the gap
+ // and mark the row as disabled.
+ //
+ if(!row.disabled)
+ {
+ row.series.push(new XYChart.Series<Number, Number>());
+ row.disabled = true;
+ }
+ //
+ // This dummy value is added to represent gap sizes, but isn't displayed
+ // as the series isn't added to the graph.
+ //
+ row.series.peek().getData().add(new XYChart.Data<Number, Number>(0, 0));
}
-
- for(Map.Entry<String, MetricsRow> j : columns.entrySet())
+ else
{
try
{
- MetricsRow row = j.getValue();
+ if(row.disabled)
+ {
+ addSeries(row);
+ row.disabled = false;
+ }
+
Number value = row.cell.getValue(metrics, timestamp);
+ //
+ // The cell returns null to indicate the value must be skipped,
+ // this is usually because it needs two values to calculate
+ // the average.
+ //
if(value == null)
{
continue;
}
- row.series.getData().add(new XYChart.Data<Number, Number>(
- timestamp,
- value));
- final int n = getMaximumSamples();
- while(row.series.getData().size() > n)
- {
- row.series.getData().remove(0);
- }
+ row.series.peek().getData().add(
+ new XYChart.Data<Number, Number>(timestamp, value));
}
catch(java.lang.RuntimeException ex)
{
ex.printStackTrace();
}
}
+
+ //
+ // Remove the vertices from the beginning of the series that exceeded
+ // the maximum number of samples.
+ //
+ adjustSize(row);
}
}
- //
- // Fire an event on the legend model to update all cells.
- //
- _queue.enqueue(new Runnable()
- {
- public void run()
- {
- _legendModel.fireTableChanged(
- new TableModelEvent(_legendModel, 0, _legendModel.getRowCount() - 1,
- TableModelEvent.ALL_COLUMNS,
- TableModelEvent.UPDATE));
- }
- }, false);
}
+ //
+ // Fire an event on the legend model to update all cells.
+ //
+ _queue.enqueue(new Runnable()
+ {
+ public void run()
+ {
+ _legendModel.fireTableChanged(
+ new TableModelEvent(_legendModel, 0, _legendModel.getRowCount() - 1,
+ TableModelEvent.ALL_COLUMNS,
+ TableModelEvent.UPDATE));
+ }
+ }, false);
}
}, true);
}
+ int seriesSize(MetricsRow row)
+ {
+ int size = 0;
+ for(int i = 0; i < row.series.size(); ++i)
+ {
+ size += row.series.get(i).getData().size();
+ }
+ return size;
+ }
+
+ void adjustSize(MetricsRow row)
+ {
+ int samples = seriesSize(row);
+ final int n = getMaximumSamples();
+ while(samples > n)
+ {
+ for(int i = 0; i < row.series.size(); ++i)
+ {
+ XYChart.Series<Number, Number> series = row.series.get(i);
+ while(series.getData().size() > 0 && samples > n)
+ {
+ try
+ {
+ series.getData().remove(0);
+ }
+ catch(java.lang.NullPointerException ex)
+ {
+ // JavaFX bug
+ }
+ samples--;
+
+ //
+ // Remove empty series not longer in use, if there is only one
+ // series that is keep to add new values.
+ //
+ if(series.getData().size() == 0 && row.series.size() > 1)
+ {
+ row.series.remove(series);
+ i--;
+ }
+ }
+ }
+ }
+ }
+
synchronized private void startRefreshThread()
{
if(_refreshThread == null)
@@ -1263,8 +1390,10 @@ public class GraphView extends JFrame implements MetricsFieldContext
{
return;
}
- else if(samples < _samples)
+
+ if(samples < _samples)
{
+ _samples = samples;
//
// If maximum samples change, we remove older samples.
//
@@ -1273,18 +1402,18 @@ public class GraphView extends JFrame implements MetricsFieldContext
@Override
public void run()
{
- for(XYChart.Series<Number, Number> series : _chart.getData())
+ MetricsRow[] rows = _legendModel.getRows();
+ for(MetricsRow row : rows)
{
- while(series.getData().size() > samples)
- {
- series.getData().remove(0);
- }
+ adjustSize(row);
}
}
}, true);
}
- _samples = samples;
-
+ else
+ {
+ _samples = samples;
+ }
}
synchronized private int getMaximumSamples()
@@ -1297,17 +1426,23 @@ public class GraphView extends JFrame implements MetricsFieldContext
public MetricsRow(MetricsViewInfo info, MetricsCell cell, String color, XYChart.Series<Number, Number> series)
{
this.visible = true;
+ this.disabled = false;
this.info = info;
this.cell = cell;
this.color = color;
- this.series = series;
+ this.series.push(series);
}
boolean visible;
+ boolean disabled;
MetricsViewInfo info;
MetricsCell cell;
String color;
- XYChart.Series<Number, Number> series;
+ //
+ // Stack of all the chart series used to represent this metrics object
+ // new values are added to the chart series at the top.
+ //
+ Stack<XYChart.Series<Number, Number>> series = new Stack<XYChart.Series<Number, Number>>();
}
class LegendTableModel extends javax.swing.table.AbstractTableModel
@@ -1485,7 +1620,10 @@ public class GraphView extends JFrame implements MetricsFieldContext
@Override
public void run()
{
- setNodesVisible(getSeriesClass(row.series), row.visible);
+ for(int i = 0; i < row.series.size(); ++i)
+ {
+ setNodesVisible(getSeriesClass(row.series.get(i)), row.visible);
+ }
}
}, true);
}
@@ -1493,7 +1631,10 @@ public class GraphView extends JFrame implements MetricsFieldContext
{
double s1 = ((Double)getValueAt(rowIndex, columnIndex)).doubleValue();
double s2 = ((Double)value).doubleValue();
- updateScaleFactor(row.series, s1, s2);
+ for(int i = 0; i < row.series.size(); ++i)
+ {
+ updateScaleFactor(row.series.get(i), s1, s2);
+ }
row.cell.setScaleFactor(((Double)value).doubleValue());
}
else if(_columnNames[columnIndex].equals("Color"))
@@ -1506,7 +1647,10 @@ public class GraphView extends JFrame implements MetricsFieldContext
row.color = "#" + String.format("%02X", color.getRed()) +
String.format("%02X", color.getGreen()) +
String.format("%02X", color.getBlue());
- updateSeriesColor(row.series, row.color);
+ for(int i = 0; i < row.series.size(); ++i)
+ {
+ updateSeriesColor(row.series.get(i), row.color);
+ }
}
fireTableCellUpdated(rowIndex, columnIndex);
}
@@ -1546,6 +1690,16 @@ public class GraphView extends JFrame implements MetricsFieldContext
return rows;
}
+ public MetricsRow[] getRows()
+ {
+ MetricsRow[] rows = new MetricsRow[_rows.size()];
+ for(Map.Entry<Integer, MetricsRow> entry : _rows.entrySet())
+ {
+ rows[rows.length] = entry.getValue();
+ }
+ return rows;
+ }
+
public int getRowIndex(MetricsRow row)
{
int index = -1;
@@ -1593,9 +1747,12 @@ public class GraphView extends JFrame implements MetricsFieldContext
@Override
public void run()
{
- String cssClass = getSeriesClass(series);
- addStyle(series, cssClass, color);
- setNodesStyle(cssClass);
+ String styleClass = getSeriesClass(series);
+ if(styleClass != null)
+ {
+ addStyle(series, styleClass, color);
+ setNodesStyle(styleClass);
+ }
}
}, true);
}
@@ -1607,6 +1764,10 @@ public class GraphView extends JFrame implements MetricsFieldContext
//
public String getSeriesClass(XYChart.Series<Number, Number> series)
{
+ if(series == null || series.getNode() == null || series.getNode().getStyleClass() == null)
+ {
+ return null;
+ }
String value = null;
for(String styleClass : series.getNode().getStyleClass())
{
@@ -1810,7 +1971,21 @@ public class GraphView extends JFrame implements MetricsFieldContext
"Metrics Name", "Metrics Id", "Metrics Field", "Scale",
"Last", "Average", "Minimum", "Maximum", "Color"};
- private final Map<MetricsViewInfo, Map<String, Map<String, Map<String, MetricsRow>>>> _series =
+
+ //
+ // The metrics view being graph
+ //
+
+ //
+ // MetricsViewInfo (Metrics view of a server)
+ // Metrics Name
+ // Row identity
+ // Field name
+ //
+ private final Map<MetricsViewInfo,
+ Map<String,
+ Map<String,
+ Map<String, MetricsRow>>>> _series =
new HashMap<MetricsViewInfo, Map<String, Map<String, Map<String, MetricsRow>>>>();
private final static String MetricsCellFlavor =