Issue #728 - Implementation of Statistics graphs
peer review comments Changing to use average value rather than sum. Change-Id: I7f97e27c4f463fe60bec2cbc52f3eac66d8fa77f Former-commit-id:4e15f63b4e
[formerlyc49759d28e
] [formerlyf000c1a9cf
[formerly f15ba1ee009abf4a562bb37450d65f97c7ffa217]] Former-commit-id:f000c1a9cf
Former-commit-id:56cd5da64d
This commit is contained in:
parent
e709143e10
commit
830a3918d9
47 changed files with 7242 additions and 65 deletions
|
@ -231,4 +231,18 @@
|
||||||
install-size="0"
|
install-size="0"
|
||||||
version="0.0.0"/>
|
version="0.0.0"/>
|
||||||
|
|
||||||
|
<plugin
|
||||||
|
id="com.raytheon.uf.viz.stats"
|
||||||
|
download-size="0"
|
||||||
|
install-size="0"
|
||||||
|
version="0.0.0"
|
||||||
|
unpack="false"/>
|
||||||
|
|
||||||
|
<plugin
|
||||||
|
id="com.raytheon.uf.common.stats"
|
||||||
|
download-size="0"
|
||||||
|
install-size="0"
|
||||||
|
version="0.0.0"
|
||||||
|
unpack="false"/>
|
||||||
|
|
||||||
</feature>
|
</feature>
|
||||||
|
|
7
cave/com.raytheon.uf.viz.stats/.classpath
Normal file
7
cave/com.raytheon.uf.viz.stats/.classpath
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<classpath>
|
||||||
|
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
|
||||||
|
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
|
||||||
|
<classpathentry kind="src" path="src"/>
|
||||||
|
<classpathentry kind="output" path="bin"/>
|
||||||
|
</classpath>
|
28
cave/com.raytheon.uf.viz.stats/.project
Normal file
28
cave/com.raytheon.uf.viz.stats/.project
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<projectDescription>
|
||||||
|
<name>com.raytheon.uf.viz.stats</name>
|
||||||
|
<comment></comment>
|
||||||
|
<projects>
|
||||||
|
</projects>
|
||||||
|
<buildSpec>
|
||||||
|
<buildCommand>
|
||||||
|
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||||
|
<arguments>
|
||||||
|
</arguments>
|
||||||
|
</buildCommand>
|
||||||
|
<buildCommand>
|
||||||
|
<name>org.eclipse.pde.ManifestBuilder</name>
|
||||||
|
<arguments>
|
||||||
|
</arguments>
|
||||||
|
</buildCommand>
|
||||||
|
<buildCommand>
|
||||||
|
<name>org.eclipse.pde.SchemaBuilder</name>
|
||||||
|
<arguments>
|
||||||
|
</arguments>
|
||||||
|
</buildCommand>
|
||||||
|
</buildSpec>
|
||||||
|
<natures>
|
||||||
|
<nature>org.eclipse.pde.PluginNature</nature>
|
||||||
|
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||||
|
</natures>
|
||||||
|
</projectDescription>
|
|
@ -0,0 +1,8 @@
|
||||||
|
#Mon Nov 05 11:14:57 CST 2012
|
||||||
|
eclipse.preferences.version=1
|
||||||
|
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
|
||||||
|
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
|
||||||
|
org.eclipse.jdt.core.compiler.compliance=1.6
|
||||||
|
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
|
||||||
|
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
|
||||||
|
org.eclipse.jdt.core.compiler.source=1.6
|
19
cave/com.raytheon.uf.viz.stats/META-INF/MANIFEST.MF
Normal file
19
cave/com.raytheon.uf.viz.stats/META-INF/MANIFEST.MF
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
Manifest-Version: 1.0
|
||||||
|
Bundle-ManifestVersion: 2
|
||||||
|
Bundle-Name: Stats
|
||||||
|
Bundle-SymbolicName: com.raytheon.uf.viz.stats;singleton:=true
|
||||||
|
Bundle-Version: 1.0.0.qualifier
|
||||||
|
Bundle-Activator: com.raytheon.uf.viz.stats.Activator
|
||||||
|
Bundle-Vendor: RAYTHEON
|
||||||
|
Require-Bundle: org.eclipse.ui,
|
||||||
|
org.eclipse.core.runtime,
|
||||||
|
com.raytheon.uf.viz.core;bundle-version="1.12.1174",
|
||||||
|
com.raytheon.viz.ui;bundle-version="1.12.1174",
|
||||||
|
com.raytheon.uf.common.stats;bundle-version="1.0.0",
|
||||||
|
com.raytheon.uf.common.time;bundle-version="1.12.1174",
|
||||||
|
com.raytheon.uf.common.util;bundle-version="1.12.1174",
|
||||||
|
com.google.guava;bundle-version="1.0.0"
|
||||||
|
Bundle-RequiredExecutionEnvironment: JavaSE-1.6
|
||||||
|
Bundle-ActivationPolicy: lazy
|
||||||
|
Export-Package: com.raytheon.uf.viz.stats,
|
||||||
|
com.raytheon.uf.viz.stats.ui
|
6
cave/com.raytheon.uf.viz.stats/build.properties
Normal file
6
cave/com.raytheon.uf.viz.stats/build.properties
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
source.. = src/
|
||||||
|
output.. = bin/
|
||||||
|
bin.includes = META-INF/,\
|
||||||
|
.,\
|
||||||
|
plugin.xml,\
|
||||||
|
build.properties
|
32
cave/com.raytheon.uf.viz.stats/plugin.xml
Normal file
32
cave/com.raytheon.uf.viz.stats/plugin.xml
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<?eclipse version="3.4"?>
|
||||||
|
<plugin>
|
||||||
|
<extension
|
||||||
|
point="org.eclipse.ui.menus">
|
||||||
|
<menuContribution
|
||||||
|
allPopups="false"
|
||||||
|
locationURI="menu:CAVE?after=group1">
|
||||||
|
<command
|
||||||
|
commandId="com.raytheon.uf.viz.stats.statsui"
|
||||||
|
id="stats"
|
||||||
|
label="AWIPS Statistics..."
|
||||||
|
style="push">
|
||||||
|
</command>
|
||||||
|
</menuContribution>
|
||||||
|
</extension>
|
||||||
|
<extension
|
||||||
|
point="org.eclipse.ui.commands">
|
||||||
|
<command
|
||||||
|
id="com.raytheon.uf.viz.stats.statsui"
|
||||||
|
name="Statistics Display Command">
|
||||||
|
</command>
|
||||||
|
</extension>
|
||||||
|
<extension
|
||||||
|
point="org.eclipse.ui.handlers">
|
||||||
|
<handler
|
||||||
|
class="com.raytheon.uf.viz.stats.action.StatsAction"
|
||||||
|
commandId="com.raytheon.uf.viz.stats.statsui">
|
||||||
|
</handler>
|
||||||
|
</extension>
|
||||||
|
|
||||||
|
</plugin>
|
|
@ -0,0 +1,50 @@
|
||||||
|
package com.raytheon.uf.viz.stats;
|
||||||
|
|
||||||
|
import org.eclipse.ui.plugin.AbstractUIPlugin;
|
||||||
|
import org.osgi.framework.BundleContext;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The activator class controls the plug-in life cycle
|
||||||
|
*/
|
||||||
|
public class Activator extends AbstractUIPlugin {
|
||||||
|
|
||||||
|
// The plug-in ID
|
||||||
|
public static final String PLUGIN_ID = "com.raytheon.uf.viz.stats"; //$NON-NLS-1$
|
||||||
|
|
||||||
|
// The shared instance
|
||||||
|
private static Activator plugin;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The constructor
|
||||||
|
*/
|
||||||
|
public Activator() {
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext)
|
||||||
|
*/
|
||||||
|
public void start(BundleContext context) throws Exception {
|
||||||
|
super.start(context);
|
||||||
|
plugin = this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext)
|
||||||
|
*/
|
||||||
|
public void stop(BundleContext context) throws Exception {
|
||||||
|
plugin = null;
|
||||||
|
super.stop(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the shared instance
|
||||||
|
*
|
||||||
|
* @return the shared instance
|
||||||
|
*/
|
||||||
|
public static Activator getDefault() {
|
||||||
|
return plugin;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,99 @@
|
||||||
|
/**
|
||||||
|
* This software was developed and / or modified by Raytheon Company,
|
||||||
|
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||||
|
*
|
||||||
|
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||||
|
* This software product contains export-restricted data whose
|
||||||
|
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||||
|
* to non-U.S. persons whether in the United States or abroad requires
|
||||||
|
* an export license or other authorization.
|
||||||
|
*
|
||||||
|
* Contractor Name: Raytheon Company
|
||||||
|
* Contractor Address: 6825 Pine Street, Suite 340
|
||||||
|
* Mail Stop B8
|
||||||
|
* Omaha, NE 68106
|
||||||
|
* 402.291.0100
|
||||||
|
*
|
||||||
|
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||||
|
* further licensing information.
|
||||||
|
**/
|
||||||
|
package com.raytheon.uf.viz.stats.action;
|
||||||
|
|
||||||
|
import org.eclipse.core.commands.AbstractHandler;
|
||||||
|
import org.eclipse.core.commands.ExecutionEvent;
|
||||||
|
import org.eclipse.core.commands.ExecutionException;
|
||||||
|
import org.eclipse.swt.widgets.Shell;
|
||||||
|
import org.eclipse.ui.PlatformUI;
|
||||||
|
|
||||||
|
import com.raytheon.uf.common.stats.GraphDataRequest;
|
||||||
|
import com.raytheon.uf.common.stats.GraphDataResponse;
|
||||||
|
import com.raytheon.uf.common.status.IUFStatusHandler;
|
||||||
|
import com.raytheon.uf.common.status.UFStatus;
|
||||||
|
import com.raytheon.uf.common.status.UFStatus.Priority;
|
||||||
|
import com.raytheon.uf.viz.core.exception.VizException;
|
||||||
|
import com.raytheon.uf.viz.core.requests.ThriftClient;
|
||||||
|
import com.raytheon.uf.viz.stats.ui.StatsControlDlg;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stats Action Handler.
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
*
|
||||||
|
* SOFTWARE HISTORY
|
||||||
|
*
|
||||||
|
* Date Ticket# Engineer Description
|
||||||
|
* ------------ ---------- ----------- --------------------------
|
||||||
|
* Sep 11, 2012 728 mpduff Initial creation
|
||||||
|
*
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* @author mpduff
|
||||||
|
* @version 1.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class StatsAction extends AbstractHandler {
|
||||||
|
private final IUFStatusHandler statusHandler = UFStatus
|
||||||
|
.getHandler(StatsAction.class);
|
||||||
|
|
||||||
|
/** Dialog instance */
|
||||||
|
private StatsControlDlg statsControlDlg = null;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object execute(ExecutionEvent event) throws ExecutionException {
|
||||||
|
if ((statsControlDlg == null) || (statsControlDlg.isDisposed() == true)) {
|
||||||
|
GraphDataRequest request = new GraphDataRequest();
|
||||||
|
request.setMetaDataRequest(true);
|
||||||
|
|
||||||
|
GraphDataResponse response = sendRequest(request);
|
||||||
|
|
||||||
|
if (response != null) {
|
||||||
|
Shell shell = PlatformUI.getWorkbench()
|
||||||
|
.getActiveWorkbenchWindow().getShell();
|
||||||
|
statsControlDlg = new StatsControlDlg(shell);
|
||||||
|
statsControlDlg.setConfigList(response.getConfigList());
|
||||||
|
statsControlDlg.open();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
statsControlDlg.bringToTop();
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send GraphDataRequest.
|
||||||
|
*
|
||||||
|
* @param req
|
||||||
|
* The request to send
|
||||||
|
* @return The GraphDataResponse
|
||||||
|
*/
|
||||||
|
private GraphDataResponse sendRequest(GraphDataRequest req) {
|
||||||
|
try {
|
||||||
|
return (GraphDataResponse) ThriftClient.sendRequest(req);
|
||||||
|
} catch (VizException e) {
|
||||||
|
statusHandler.handle(Priority.ERROR, "Error Requesting Data", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,190 @@
|
||||||
|
package com.raytheon.uf.viz.stats.display;
|
||||||
|
|
||||||
|
|
||||||
|
public class ScaleManager {
|
||||||
|
/**
|
||||||
|
* Max number of major ticks, including first and last
|
||||||
|
*/
|
||||||
|
private final int MAX_MAJOR_TICK = 6;
|
||||||
|
|
||||||
|
private final double ZOOMED_FACTOR = 0.01;
|
||||||
|
|
||||||
|
private final double UNZOOMED_FACTOR = 5.0;
|
||||||
|
|
||||||
|
private double[] niceMajorIncrementArray = { 0.01, 0.02, 0.05, 0.1, 0.2,
|
||||||
|
0.5, 1.0, 2.0, 5.0 };
|
||||||
|
|
||||||
|
private double baseFactorStartingPoint = .01;
|
||||||
|
|
||||||
|
private double minDataValue;
|
||||||
|
|
||||||
|
private double maxDataValue;
|
||||||
|
|
||||||
|
private double minScaleValue;
|
||||||
|
|
||||||
|
private double maxScaleValue;
|
||||||
|
|
||||||
|
private int majorTickCount;
|
||||||
|
|
||||||
|
private double majorTickIncrement;
|
||||||
|
|
||||||
|
private boolean zoomFlag;
|
||||||
|
|
||||||
|
public ScaleManager(double minDataValue, double maxDataValue) {
|
||||||
|
this.minDataValue = minDataValue;
|
||||||
|
this.maxDataValue = maxDataValue;
|
||||||
|
|
||||||
|
rescale();
|
||||||
|
}
|
||||||
|
|
||||||
|
private synchronized void rescale() {
|
||||||
|
int multipleCount = 0;
|
||||||
|
|
||||||
|
// if zooming, use the ZOOMED_FACTOR value
|
||||||
|
if (zoomFlag) {
|
||||||
|
multipleCount = (int) Math.floor(minDataValue / ZOOMED_FACTOR);
|
||||||
|
minScaleValue = multipleCount * ZOOMED_FACTOR;
|
||||||
|
}
|
||||||
|
// if NOT zooming, use the UNZOOMED_FACTOR value
|
||||||
|
else {
|
||||||
|
multipleCount = (int) Math.floor(minDataValue / UNZOOMED_FACTOR);
|
||||||
|
minScaleValue = multipleCount * UNZOOMED_FACTOR;
|
||||||
|
|
||||||
|
if ((maxDataValue - minDataValue < 10) && (minDataValue > .5)) {
|
||||||
|
minScaleValue = minDataValue - .5;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
double baseFactor = baseFactorStartingPoint;
|
||||||
|
|
||||||
|
boolean done = false;
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
|
// set the range the values fit into
|
||||||
|
double range = maxDataValue - minScaleValue;
|
||||||
|
if (range < 1 && !zoomFlag) {
|
||||||
|
range = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (!done) {
|
||||||
|
double testIncrement = niceMajorIncrementArray[i] * (baseFactor);
|
||||||
|
|
||||||
|
int testTickCount = (int) Math.ceil(range / testIncrement + 1);
|
||||||
|
|
||||||
|
// if there are a reasonable number of tickCounts, then stop
|
||||||
|
if (testTickCount <= MAX_MAJOR_TICK) {
|
||||||
|
|
||||||
|
majorTickCount = testTickCount;
|
||||||
|
|
||||||
|
majorTickIncrement = testIncrement;
|
||||||
|
|
||||||
|
// first tick counts as a tick, so subtract 1
|
||||||
|
maxScaleValue = minScaleValue
|
||||||
|
+ ((majorTickCount - 1) * majorTickIncrement);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
i++;
|
||||||
|
|
||||||
|
if (i >= niceMajorIncrementArray.length) {
|
||||||
|
i = 0;
|
||||||
|
baseFactor *= 10.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // end while !done
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMaxDataValue(double maxDataValue) {
|
||||||
|
this.maxDataValue = maxDataValue;
|
||||||
|
|
||||||
|
rescale();
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getMaxDataValue() {
|
||||||
|
return maxDataValue;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMinDataValue(double minDataValue) {
|
||||||
|
this.minDataValue = minDataValue;
|
||||||
|
rescale();
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getMinDataValue() {
|
||||||
|
return minDataValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getMajorTickCount() {
|
||||||
|
return majorTickCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getMajorTickIncrement() {
|
||||||
|
return majorTickIncrement;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getMaxScaleValue() {
|
||||||
|
return maxScaleValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getMinScaleValue() {
|
||||||
|
return minScaleValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setNiceMajorIncrementArray(double[] niceMajorIncrementArray) {
|
||||||
|
this.niceMajorIncrementArray = niceMajorIncrementArray;
|
||||||
|
rescale();
|
||||||
|
}
|
||||||
|
|
||||||
|
public double[] getNiceMajorIncrementArray() {
|
||||||
|
return niceMajorIncrementArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isZoomFlag() {
|
||||||
|
return zoomFlag;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setZoomFlag(boolean zoomFlag) {
|
||||||
|
this.zoomFlag = zoomFlag;
|
||||||
|
rescale();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param baseFactorStartingPoint
|
||||||
|
* The baseFactorStartingPoint to set.
|
||||||
|
*/
|
||||||
|
public void setBaseFactorStartingPoint(double baseFactorStartingPoint) {
|
||||||
|
this.baseFactorStartingPoint = baseFactorStartingPoint;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Returns the baseFactorStartingPoint.
|
||||||
|
*/
|
||||||
|
public double getBaseFactorStartingPoint() {
|
||||||
|
return baseFactorStartingPoint;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
String outString = " minDataValue = " + getMinDataValue()
|
||||||
|
+ " maxDataValue = " + getMaxDataValue() + "\n"
|
||||||
|
+ " minScaleValue = " + getMinScaleValue()
|
||||||
|
+ " maxScaleValue = " + getMaxScaleValue() + "\n"
|
||||||
|
+ " majorTickCount = " + getMajorTickCount()
|
||||||
|
+ " majorTickIncrement = " + getMajorTickIncrement();
|
||||||
|
|
||||||
|
return outString;
|
||||||
|
}
|
||||||
|
|
||||||
|
// For testing
|
||||||
|
public static void main(String[] argArray) {
|
||||||
|
double minValue = 5.1;
|
||||||
|
double maxValue = 5.3;
|
||||||
|
ScaleManager scaler = new ScaleManager(minValue, maxValue);
|
||||||
|
|
||||||
|
System.out.println(scaler.toString());
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,142 @@
|
||||||
|
/**
|
||||||
|
* This software was developed and / or modified by Raytheon Company,
|
||||||
|
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||||
|
*
|
||||||
|
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||||
|
* This software product contains export-restricted data whose
|
||||||
|
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||||
|
* to non-U.S. persons whether in the United States or abroad requires
|
||||||
|
* an export license or other authorization.
|
||||||
|
*
|
||||||
|
* Contractor Name: Raytheon Company
|
||||||
|
* Contractor Address: 6825 Pine Street, Suite 340
|
||||||
|
* Mail Stop B8
|
||||||
|
* Omaha, NE 68106
|
||||||
|
* 402.291.0100
|
||||||
|
*
|
||||||
|
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||||
|
* further licensing information.
|
||||||
|
**/
|
||||||
|
package com.raytheon.uf.viz.stats.ui;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Color Manager
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
*
|
||||||
|
* SOFTWARE HISTORY
|
||||||
|
*
|
||||||
|
* Date Ticket# Engineer Description
|
||||||
|
* ------------ ---------- ----------- --------------------------
|
||||||
|
* Oct 16, 2012 mpduff Initial creation.
|
||||||
|
*
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* @version 1.0
|
||||||
|
*/
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.eclipse.swt.graphics.RGB;
|
||||||
|
|
||||||
|
public class ColorManager {
|
||||||
|
|
||||||
|
/** Color list */
|
||||||
|
private List<RGB> colorRGBs;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor.
|
||||||
|
*/
|
||||||
|
public ColorManager() {
|
||||||
|
setupColors();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize the colors
|
||||||
|
*/
|
||||||
|
private void setupColors() {
|
||||||
|
List<RGB> tempColorRGBs = new ArrayList<RGB>();
|
||||||
|
|
||||||
|
tempColorRGBs.add(new RGB(255, 0, 0)); // RED
|
||||||
|
tempColorRGBs.add(new RGB(255, 165, 0)); // ORANGE
|
||||||
|
tempColorRGBs.add(new RGB(0, 255, 0)); // GREEN
|
||||||
|
tempColorRGBs.add(new RGB(255, 255, 0)); // YELLOW
|
||||||
|
tempColorRGBs.add(new RGB(165, 42, 42)); // BROWN
|
||||||
|
tempColorRGBs.add(new RGB(0, 255, 255)); // CYAN
|
||||||
|
tempColorRGBs.add(new RGB(255, 0, 255)); // MAGENTA
|
||||||
|
tempColorRGBs.add(new RGB(0, 0, 255)); // BLUE
|
||||||
|
tempColorRGBs.add(new RGB(138, 43, 226)); // BLUEVIOLET
|
||||||
|
tempColorRGBs.add(new RGB(238, 130, 238)); // VIOLET
|
||||||
|
tempColorRGBs.add(new RGB(102, 205, 170)); // AQUAMARINE3
|
||||||
|
tempColorRGBs.add(new RGB(139, 125, 107)); // BISQUE4
|
||||||
|
tempColorRGBs.add(new RGB(238, 197, 145)); // BURLYWOOD2
|
||||||
|
tempColorRGBs.add(new RGB(205, 205, 0)); // YELLOW3
|
||||||
|
tempColorRGBs.add(new RGB(69, 139, 0)); // CHARTREUSE4
|
||||||
|
tempColorRGBs.add(new RGB(255, 127, 80)); // CORAL
|
||||||
|
tempColorRGBs.add(new RGB(100, 149, 237)); // CORNFLOWERBLUE
|
||||||
|
tempColorRGBs.add(new RGB(0, 139, 139)); // CYAN4
|
||||||
|
tempColorRGBs.add(new RGB(169, 169, 169)); // DARKGRAY
|
||||||
|
tempColorRGBs.add(new RGB(139, 0, 139)); // DARKMAGENTA
|
||||||
|
tempColorRGBs.add(new RGB(238, 118, 0)); // DARKORANGE2
|
||||||
|
tempColorRGBs.add(new RGB(139, 0, 0)); // DARKRED
|
||||||
|
tempColorRGBs.add(new RGB(233, 150, 122)); // DARKSALMON
|
||||||
|
tempColorRGBs.add(new RGB(255, 20, 147)); // DEEPPINK
|
||||||
|
tempColorRGBs.add(new RGB(0, 191, 255)); // DEEPSKYBLUE
|
||||||
|
tempColorRGBs.add(new RGB(255, 255, 255)); // WHITE
|
||||||
|
tempColorRGBs.add(new RGB(193, 205, 193)); // HONEYDEW3
|
||||||
|
tempColorRGBs.add(new RGB(139, 58, 98)); // HOTPINK4
|
||||||
|
tempColorRGBs.add(new RGB(144, 238, 144)); // LIGHTGREEN
|
||||||
|
tempColorRGBs.add(new RGB(255, 182, 193)); // LIGHTPINK
|
||||||
|
tempColorRGBs.add(new RGB(176, 196, 222)); // LIGHTSTEELBLUE
|
||||||
|
tempColorRGBs.add(new RGB(205, 133, 0)); // ORANGE3
|
||||||
|
tempColorRGBs.add(new RGB(139, 105, 105)); // ROSYBROWN4
|
||||||
|
tempColorRGBs.add(new RGB(210, 180, 140)); // TAN
|
||||||
|
tempColorRGBs.add(new RGB(0, 0, 0)); // BLACK
|
||||||
|
|
||||||
|
colorRGBs = Collections.unmodifiableList(tempColorRGBs);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the list of colors.
|
||||||
|
*
|
||||||
|
* @return the list of colors
|
||||||
|
*/
|
||||||
|
public List<RGB> getColorRGBs() {
|
||||||
|
return colorRGBs;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the color at the provided index.
|
||||||
|
*
|
||||||
|
* @param index
|
||||||
|
* The index
|
||||||
|
* @return the color for the index
|
||||||
|
*/
|
||||||
|
public RGB getColorAtIndex(int index) {
|
||||||
|
int indexRV = index % colorRGBs.size();
|
||||||
|
|
||||||
|
RGB returnColor = colorRGBs.get(indexRV);
|
||||||
|
|
||||||
|
if (returnColor == null) {
|
||||||
|
return new RGB(0, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
return returnColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
// for testing
|
||||||
|
public static void main(String[] args) {
|
||||||
|
ColorManager cm = new ColorManager();
|
||||||
|
|
||||||
|
List<RGB> colorRGBArray = cm.getColorRGBs();
|
||||||
|
|
||||||
|
for (RGB rgb : colorRGBArray) {
|
||||||
|
// String s = RGBColors.getColorName(rgb);
|
||||||
|
// System.out.println(String.format("%20S", s) + "\t" +
|
||||||
|
// rgb.toString());
|
||||||
|
System.out.println(rgb.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,356 @@
|
||||||
|
/**
|
||||||
|
* This software was developed and / or modified by Raytheon Company,
|
||||||
|
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||||
|
*
|
||||||
|
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||||
|
* This software product contains export-restricted data whose
|
||||||
|
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||||
|
* to non-U.S. persons whether in the United States or abroad requires
|
||||||
|
* an export license or other authorization.
|
||||||
|
*
|
||||||
|
* Contractor Name: Raytheon Company
|
||||||
|
* Contractor Address: 6825 Pine Street, Suite 340
|
||||||
|
* Mail Stop B8
|
||||||
|
* Omaha, NE 68106
|
||||||
|
* 402.291.0100
|
||||||
|
*
|
||||||
|
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||||
|
* further licensing information.
|
||||||
|
**/
|
||||||
|
package com.raytheon.uf.viz.stats.ui;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.eclipse.swt.SWT;
|
||||||
|
import org.eclipse.swt.custom.ScrolledComposite;
|
||||||
|
import org.eclipse.swt.events.MouseAdapter;
|
||||||
|
import org.eclipse.swt.events.MouseEvent;
|
||||||
|
import org.eclipse.swt.events.SelectionAdapter;
|
||||||
|
import org.eclipse.swt.events.SelectionEvent;
|
||||||
|
import org.eclipse.swt.graphics.Color;
|
||||||
|
import org.eclipse.swt.graphics.RGB;
|
||||||
|
import org.eclipse.swt.layout.GridData;
|
||||||
|
import org.eclipse.swt.layout.GridLayout;
|
||||||
|
import org.eclipse.swt.widgets.Button;
|
||||||
|
import org.eclipse.swt.widgets.ColorDialog;
|
||||||
|
import org.eclipse.swt.widgets.Composite;
|
||||||
|
import org.eclipse.swt.widgets.Label;
|
||||||
|
import org.eclipse.swt.widgets.Layout;
|
||||||
|
import org.eclipse.swt.widgets.Shell;
|
||||||
|
import org.eclipse.swt.widgets.Tree;
|
||||||
|
|
||||||
|
import com.raytheon.uf.common.stats.data.GraphData;
|
||||||
|
import com.raytheon.viz.ui.dialogs.CaveSWTDialogBase;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TODO Add Description
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
*
|
||||||
|
* SOFTWARE HISTORY
|
||||||
|
*
|
||||||
|
* Date Ticket# Engineer Description
|
||||||
|
* ------------ ---------- ----------- --------------------------
|
||||||
|
* Oct 18, 2012 mpduff Initial creation
|
||||||
|
*
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* @author mpduff
|
||||||
|
* @version 1.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class ColorManagerDlg extends CaveSWTDialogBase {
|
||||||
|
private Composite mainComp;
|
||||||
|
|
||||||
|
private final IColorSelection callback;
|
||||||
|
|
||||||
|
private Button individualRdo;
|
||||||
|
|
||||||
|
private Tree selectionTree;
|
||||||
|
|
||||||
|
private final GraphData graphData;
|
||||||
|
|
||||||
|
private final List<Button> radioList = new ArrayList<Button>();
|
||||||
|
|
||||||
|
/** Map of group -> composite */
|
||||||
|
private final Map<String, Composite> compMap = new HashMap<String, Composite>();
|
||||||
|
|
||||||
|
private final Map<String, Map<String, Label>> labelMap = new HashMap<String, Map<String, Label>>();
|
||||||
|
|
||||||
|
/** A map of unique keys, RGB for the check boxes that are checked. */
|
||||||
|
private final Map<String, RGB> keyRgbMap = new LinkedHashMap<String, RGB>();;
|
||||||
|
|
||||||
|
protected ColorManagerDlg(Shell parentShell, GraphData graphData,
|
||||||
|
IColorSelection callback) {
|
||||||
|
super(parentShell, SWT.DIALOG_TRIM | SWT.MIN | SWT.RESIZE,
|
||||||
|
CAVE.DO_NOT_BLOCK | CAVE.MODE_INDEPENDENT
|
||||||
|
| CAVE.INDEPENDENT_SHELL);
|
||||||
|
setText("Color Manager");
|
||||||
|
this.callback = callback;
|
||||||
|
this.graphData = graphData;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Layout constructShellLayout() {
|
||||||
|
// Create the main layout for the shell.
|
||||||
|
GridLayout mainLayout = new GridLayout(1, false);
|
||||||
|
mainLayout.marginHeight = 2;
|
||||||
|
mainLayout.marginWidth = 2;
|
||||||
|
|
||||||
|
return mainLayout;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void initializeComponents(Shell shell) {
|
||||||
|
mainComp = new Composite(shell, SWT.NONE);
|
||||||
|
GridLayout gl = new GridLayout(1, false);
|
||||||
|
gl.marginHeight = 0;
|
||||||
|
gl.marginWidth = 0;
|
||||||
|
gl.horizontalSpacing = 0;
|
||||||
|
gl.verticalSpacing = 5;
|
||||||
|
GridData gd = new GridData(SWT.FILL, SWT.FILL, true, true);
|
||||||
|
mainComp.setLayout(gl);
|
||||||
|
mainComp.setLayoutData(gd);
|
||||||
|
|
||||||
|
createGroups();
|
||||||
|
createActionControls();
|
||||||
|
setupColorsAndKeyRgbMap();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void createGroups() {
|
||||||
|
ScrolledComposite scrolledComp = new ScrolledComposite(mainComp,
|
||||||
|
SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL);
|
||||||
|
GridLayout gl = new GridLayout(1, false);
|
||||||
|
gl.verticalSpacing = 1;
|
||||||
|
scrolledComp.setLayout(gl);
|
||||||
|
|
||||||
|
GridData gd = new GridData(SWT.FILL, SWT.FILL, true, true);
|
||||||
|
gd.widthHint = 220;
|
||||||
|
gd.heightHint = 350;
|
||||||
|
scrolledComp.setLayoutData(gd);
|
||||||
|
|
||||||
|
gl = new GridLayout(1, false);
|
||||||
|
gd = new GridData(SWT.FILL, SWT.FILL, true, true);
|
||||||
|
Composite composite = new Composite(scrolledComp, SWT.NONE);
|
||||||
|
composite.setLayout(gl);
|
||||||
|
composite.setLayoutData(gd);
|
||||||
|
scrolledComp.setContent(composite);
|
||||||
|
scrolledComp.setExpandHorizontal(true);
|
||||||
|
scrolledComp.setExpandVertical(true);
|
||||||
|
|
||||||
|
gl = new GridLayout(1, false);
|
||||||
|
gd = new GridData(SWT.FILL, SWT.FILL, true, false);
|
||||||
|
Composite indComp = new Composite(composite, SWT.NONE);
|
||||||
|
indComp.setLayout(gl);
|
||||||
|
indComp.setLayoutData(gd);
|
||||||
|
individualRdo = new Button(indComp, SWT.RADIO);
|
||||||
|
individualRdo.setText("Individual");
|
||||||
|
individualRdo.setSelection(true);
|
||||||
|
individualRdo.addSelectionListener(new SelectionAdapter() {
|
||||||
|
@Override
|
||||||
|
public void widgetSelected(SelectionEvent e) {
|
||||||
|
handleIndividualSelection();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Map<String, List<String>> groupMap = graphData.getGroupAndNamesMap();
|
||||||
|
|
||||||
|
for (String group : groupMap.keySet()) {
|
||||||
|
if (!labelMap.containsKey(group)) {
|
||||||
|
labelMap.put(group, new HashMap<String, Label>());
|
||||||
|
}
|
||||||
|
|
||||||
|
gl = new GridLayout(1, false);
|
||||||
|
gd = new GridData(SWT.FILL, SWT.FILL, true, true);
|
||||||
|
Composite comp = new Composite(composite, SWT.NONE);
|
||||||
|
comp.setLayout(gl);
|
||||||
|
comp.setLayoutData(gd);
|
||||||
|
|
||||||
|
Button btn1 = new Button(comp, SWT.RADIO);
|
||||||
|
btn1.setText(group);
|
||||||
|
btn1.addSelectionListener(new SelectionAdapter() {
|
||||||
|
@Override
|
||||||
|
public void widgetSelected(SelectionEvent e) {
|
||||||
|
handleGroupSelection(((Button) e.getSource()).getText());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
radioList.add(btn1);
|
||||||
|
|
||||||
|
gd = new GridData(SWT.FILL, SWT.FILL, true, true);
|
||||||
|
gl = new GridLayout(1, false);
|
||||||
|
ScrolledComposite sc = new ScrolledComposite(comp, SWT.BORDER);
|
||||||
|
sc.setLayout(gl);
|
||||||
|
sc.setLayoutData(gd);
|
||||||
|
sc.setExpandHorizontal(true);
|
||||||
|
sc.setExpandVertical(true);
|
||||||
|
compMap.put(group, sc);
|
||||||
|
|
||||||
|
gd = new GridData(SWT.FILL, SWT.FILL, true, true);
|
||||||
|
gl = new GridLayout(2, false);
|
||||||
|
Composite memberComp = new Composite(sc, SWT.NONE);
|
||||||
|
memberComp.setLayout(gl);
|
||||||
|
memberComp.setLayoutData(gd);
|
||||||
|
|
||||||
|
sc.setContent(memberComp);
|
||||||
|
List<String> memberList = groupMap.get(group);
|
||||||
|
for (String member : memberList) {
|
||||||
|
gd = new GridData(20, 10);
|
||||||
|
Label lbl = new Label(memberComp, SWT.BORDER);
|
||||||
|
lbl.setLayoutData(gd);
|
||||||
|
lbl.addMouseListener(new MouseAdapter() {
|
||||||
|
@Override
|
||||||
|
public void mouseDown(MouseEvent e) {
|
||||||
|
Label lbl = (Label) e.getSource();
|
||||||
|
handleLabelClickEvent(lbl);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Label memberLbl = new Label(memberComp, SWT.NONE);
|
||||||
|
memberLbl.setText(member);
|
||||||
|
labelMap.get(group).put(member, lbl);
|
||||||
|
}
|
||||||
|
|
||||||
|
sc.layout();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
scrolledComp.layout();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void createActionControls() {
|
||||||
|
Composite buttonComp = new Composite(shell, SWT.NONE);
|
||||||
|
buttonComp.setLayout(new GridLayout(3, false));
|
||||||
|
buttonComp.setLayoutData(new GridData(SWT.CENTER, SWT.DEFAULT, true,
|
||||||
|
false));
|
||||||
|
|
||||||
|
int buttonWidth = 80;
|
||||||
|
|
||||||
|
GridData gd = new GridData(buttonWidth, SWT.DEFAULT);
|
||||||
|
Button okBtn = new Button(buttonComp, SWT.PUSH);
|
||||||
|
okBtn.setText("OK");
|
||||||
|
okBtn.setLayoutData(gd);
|
||||||
|
okBtn.addSelectionListener(new SelectionAdapter() {
|
||||||
|
@Override
|
||||||
|
public void widgetSelected(SelectionEvent e) {
|
||||||
|
handleApply();
|
||||||
|
close();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
gd = new GridData(buttonWidth, SWT.DEFAULT);
|
||||||
|
Button applyBtn = new Button(buttonComp, SWT.PUSH);
|
||||||
|
applyBtn.setText("Apply");
|
||||||
|
applyBtn.setLayoutData(gd);
|
||||||
|
applyBtn.addSelectionListener(new SelectionAdapter() {
|
||||||
|
@Override
|
||||||
|
public void widgetSelected(SelectionEvent e) {
|
||||||
|
handleApply();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
gd = new GridData(buttonWidth, SWT.DEFAULT);
|
||||||
|
Button cancelBtn = new Button(buttonComp, SWT.PUSH);
|
||||||
|
cancelBtn.setText("Cancel");
|
||||||
|
cancelBtn.setLayoutData(gd);
|
||||||
|
cancelBtn.addSelectionListener(new SelectionAdapter() {
|
||||||
|
@Override
|
||||||
|
public void widgetSelected(SelectionEvent e) {
|
||||||
|
close();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Setup the colors for the labels and put the key, RGB in the selected map.
|
||||||
|
*/
|
||||||
|
private void setupColorsAndKeyRgbMap() {
|
||||||
|
ColorManager cm = new ColorManager();
|
||||||
|
int count = 0;
|
||||||
|
Color c;
|
||||||
|
|
||||||
|
for (String key : labelMap.keySet()) {
|
||||||
|
count = 0;
|
||||||
|
for (String memberKey : labelMap.get(key).keySet()) {
|
||||||
|
c = new Color(this.getDisplay(), cm.getColorAtIndex(count));
|
||||||
|
labelMap.get(key).get(memberKey).setBackground(c);
|
||||||
|
++count;
|
||||||
|
c.dispose();
|
||||||
|
keyRgbMap.put(key + "::" + memberKey, labelMap.get(key).get(memberKey).getBackground().getRGB());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (String key : labelMap.keySet()) {
|
||||||
|
for (String memberKey : labelMap.get(key).keySet()) {
|
||||||
|
keyRgbMap.put(key + "::" + memberKey, labelMap.get(key).get(memberKey).getBackground().getRGB());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void handleIndividualSelection() {
|
||||||
|
for (Button rdo: this.radioList) {
|
||||||
|
rdo.setSelection(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (String key : this.compMap.keySet()) {
|
||||||
|
compMap.get(key).setEnabled(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void handleGroupSelection(String group) {
|
||||||
|
individualRdo.setSelection(false);
|
||||||
|
for (Button rdo: this.radioList) {
|
||||||
|
if (!rdo.getText().equals(group)) {
|
||||||
|
rdo.setSelection(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (String compMapKey: compMap.keySet()) {
|
||||||
|
if (compMapKey.equals(group)) {
|
||||||
|
compMap.get(compMapKey).setEnabled(true);
|
||||||
|
} else {
|
||||||
|
compMap.get(compMapKey).setEnabled(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle the color label that is being clicked.
|
||||||
|
*
|
||||||
|
* @param lbl
|
||||||
|
* Label that was clicked.
|
||||||
|
*/
|
||||||
|
private void handleLabelClickEvent(Label lbl) {
|
||||||
|
RGB rgb = lbl.getBackground().getRGB();
|
||||||
|
String key = (String) lbl.getData();
|
||||||
|
|
||||||
|
ColorDialog colorDlg = new ColorDialog(this.getShell());
|
||||||
|
colorDlg.setRGB(rgb);
|
||||||
|
colorDlg.setText("Select a Color");
|
||||||
|
|
||||||
|
RGB returnRGB = colorDlg.open();
|
||||||
|
|
||||||
|
if (returnRGB == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Color c = new Color(this.getDisplay(), returnRGB);
|
||||||
|
lbl.setBackground(c);
|
||||||
|
c.dispose();
|
||||||
|
|
||||||
|
if (keyRgbMap.containsKey(key) == true) {
|
||||||
|
keyRgbMap.put(key, returnRGB);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void handleApply() {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
// System.out.println("TODO: Implement me");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,408 @@
|
||||||
|
/**
|
||||||
|
* This software was developed and / or modified by Raytheon Company,
|
||||||
|
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||||
|
*
|
||||||
|
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||||
|
* This software product contains export-restricted data whose
|
||||||
|
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||||
|
* to non-U.S. persons whether in the United States or abroad requires
|
||||||
|
* an export license or other authorization.
|
||||||
|
*
|
||||||
|
* Contractor Name: Raytheon Company
|
||||||
|
* Contractor Address: 6825 Pine Street, Suite 340
|
||||||
|
* Mail Stop B8
|
||||||
|
* Omaha, NE 68106
|
||||||
|
* 402.291.0100
|
||||||
|
*
|
||||||
|
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||||
|
* further licensing information.
|
||||||
|
**/
|
||||||
|
package com.raytheon.uf.viz.stats.ui;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TODO Add Description
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
*
|
||||||
|
* SOFTWARE HISTORY
|
||||||
|
*
|
||||||
|
* Date Ticket# Engineer Description
|
||||||
|
* ------------ ---------- ----------- --------------------------
|
||||||
|
* Oct 16, 2012 mpduff Initial creation
|
||||||
|
*
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* @author mpduff
|
||||||
|
* @version 1.0
|
||||||
|
*/
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
import org.eclipse.swt.SWT;
|
||||||
|
import org.eclipse.swt.custom.ScrolledComposite;
|
||||||
|
import org.eclipse.swt.events.ControlAdapter;
|
||||||
|
import org.eclipse.swt.events.ControlEvent;
|
||||||
|
import org.eclipse.swt.events.MouseAdapter;
|
||||||
|
import org.eclipse.swt.events.MouseEvent;
|
||||||
|
import org.eclipse.swt.events.SelectionAdapter;
|
||||||
|
import org.eclipse.swt.events.SelectionEvent;
|
||||||
|
import org.eclipse.swt.graphics.Color;
|
||||||
|
import org.eclipse.swt.graphics.RGB;
|
||||||
|
import org.eclipse.swt.layout.GridData;
|
||||||
|
import org.eclipse.swt.layout.GridLayout;
|
||||||
|
import org.eclipse.swt.widgets.Button;
|
||||||
|
import org.eclipse.swt.widgets.ColorDialog;
|
||||||
|
import org.eclipse.swt.widgets.Composite;
|
||||||
|
import org.eclipse.swt.widgets.Label;
|
||||||
|
|
||||||
|
import com.raytheon.uf.common.stats.data.GraphData;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Composites that contains the controls to change colors and to determine what
|
||||||
|
* is displayed.
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
*
|
||||||
|
* SOFTWARE HISTORY
|
||||||
|
*
|
||||||
|
* Date Ticket# Engineer Description
|
||||||
|
* ------------ ---------- ----------- --------------------------
|
||||||
|
* Oct 16, 2012 lvenable Initial creation
|
||||||
|
*
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* @author lvenable
|
||||||
|
* @version 1.0
|
||||||
|
*/
|
||||||
|
public class GroupingComp extends Composite implements IGroupSelection {
|
||||||
|
/** Parse pattern */
|
||||||
|
private final Pattern colonPattern = Pattern.compile(":");
|
||||||
|
|
||||||
|
/** Selection Manager Dialog */
|
||||||
|
private SelectionManagerDlg selectionMangerDlg;
|
||||||
|
|
||||||
|
/** Scrolled composite containing the control widgets composite. */
|
||||||
|
private ScrolledComposite scrolledComp;
|
||||||
|
|
||||||
|
/** Composite containing the control widgets. */
|
||||||
|
private Composite controlComp;
|
||||||
|
|
||||||
|
/** A map of unique keys, Label controls. */
|
||||||
|
private Map<String, Label> labelMap;
|
||||||
|
|
||||||
|
/** A map of unique keys, Check box controls. */
|
||||||
|
private Map<String, Button> checkBtnMap;
|
||||||
|
|
||||||
|
/** A map of unique keys, RGB for the check boxes that are checked. */
|
||||||
|
private Map<String, RGB> keyRgbMap;
|
||||||
|
|
||||||
|
/** The graph data */
|
||||||
|
private final GraphData graphData;
|
||||||
|
|
||||||
|
/** Grouping callback */
|
||||||
|
private final IStatsGroup callback;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor.
|
||||||
|
*
|
||||||
|
* @param parentComp
|
||||||
|
* Parent composite.
|
||||||
|
* @param swtStyle
|
||||||
|
* SWT style.
|
||||||
|
* @param statsData
|
||||||
|
* Statistical data.
|
||||||
|
*/
|
||||||
|
public GroupingComp(Composite parentComp, int swtStyle,
|
||||||
|
GraphData graphData, IStatsGroup callback) {
|
||||||
|
super(parentComp, swtStyle);
|
||||||
|
this.graphData = graphData;
|
||||||
|
this.callback = callback;
|
||||||
|
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize the class.
|
||||||
|
*/
|
||||||
|
private void init() {
|
||||||
|
labelMap = new LinkedHashMap<String, Label>();
|
||||||
|
checkBtnMap = new LinkedHashMap<String, Button>();
|
||||||
|
keyRgbMap = new LinkedHashMap<String, RGB>();
|
||||||
|
|
||||||
|
GridLayout gl = new GridLayout(1, false);
|
||||||
|
GridData gd = new GridData(SWT.FILL, SWT.FILL, true, true);
|
||||||
|
|
||||||
|
this.setLayout(gl);
|
||||||
|
this.setLayoutData(gd);
|
||||||
|
|
||||||
|
Label grpLbl = new Label(this, SWT.NONE);
|
||||||
|
grpLbl.setText("Groups:");
|
||||||
|
|
||||||
|
createScrolledComposite();
|
||||||
|
setupColorsAndKeyRgbMap();
|
||||||
|
addSelectionColorActionButtons();
|
||||||
|
|
||||||
|
fireCallback();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create the scrolled composite and set the content.
|
||||||
|
*/
|
||||||
|
private void createScrolledComposite() {
|
||||||
|
|
||||||
|
scrolledComp = new ScrolledComposite(this, SWT.BORDER | SWT.H_SCROLL
|
||||||
|
| SWT.V_SCROLL);
|
||||||
|
GridLayout gl = new GridLayout(1, false);
|
||||||
|
gl.verticalSpacing = 1;
|
||||||
|
scrolledComp.setLayout(gl);
|
||||||
|
|
||||||
|
GridData gd = new GridData(SWT.FILL, SWT.FILL, true, true);
|
||||||
|
gd.widthHint = 220;
|
||||||
|
gd.heightHint = 350;
|
||||||
|
scrolledComp.setLayoutData(gd);
|
||||||
|
|
||||||
|
controlComp = new Composite(scrolledComp, SWT.NONE);
|
||||||
|
controlComp.setLayout(new GridLayout(2, false));
|
||||||
|
controlComp.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
|
||||||
|
|
||||||
|
createControls();
|
||||||
|
|
||||||
|
controlComp.layout();
|
||||||
|
|
||||||
|
scrolledComp.setContent(controlComp);
|
||||||
|
scrolledComp.setExpandHorizontal(true);
|
||||||
|
scrolledComp.setExpandVertical(true);
|
||||||
|
scrolledComp.addControlListener(new ControlAdapter() {
|
||||||
|
@Override
|
||||||
|
public void controlResized(ControlEvent e) {
|
||||||
|
scrolledComp.setMinSize(controlComp.computeSize(SWT.DEFAULT,
|
||||||
|
SWT.DEFAULT));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
scrolledComp.layout();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create the color labels and check box controls.
|
||||||
|
*/
|
||||||
|
private void createControls() {
|
||||||
|
List<String> keyArray = graphData.getKeysWithData();
|
||||||
|
|
||||||
|
for (String key : keyArray) {
|
||||||
|
GridData gd = new GridData(20, 10);
|
||||||
|
Label lbl = new Label(controlComp, SWT.BORDER);
|
||||||
|
lbl.setLayoutData(gd);
|
||||||
|
lbl.setData(key);
|
||||||
|
lbl.addMouseListener(new MouseAdapter() {
|
||||||
|
@Override
|
||||||
|
public void mouseDown(MouseEvent e) {
|
||||||
|
Label lbl = (Label) e.getSource();
|
||||||
|
handleLabelClickEvent(lbl);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Button btn = new Button(controlComp, SWT.CHECK);
|
||||||
|
btn.setText(key);
|
||||||
|
btn.setSelection(true);
|
||||||
|
btn.addSelectionListener(new SelectionAdapter() {
|
||||||
|
@Override
|
||||||
|
public void widgetSelected(SelectionEvent e) {
|
||||||
|
Button btn = (Button) e.getSource();
|
||||||
|
handleCheckEvent(btn);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
labelMap.put(key, lbl);
|
||||||
|
checkBtnMap.put(key, btn);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add the Selection and Color Manager buttons.
|
||||||
|
*/
|
||||||
|
private void addSelectionColorActionButtons() {
|
||||||
|
if (checkBtnMap.isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Composite buttonComp = new Composite(this, SWT.NONE);
|
||||||
|
buttonComp.setLayout(new GridLayout(1, false));
|
||||||
|
buttonComp.setLayoutData(new GridData(SWT.CENTER, SWT.DEFAULT, true,
|
||||||
|
false));
|
||||||
|
|
||||||
|
int buttonWidth = 160;
|
||||||
|
GridData gd = new GridData(buttonWidth, SWT.DEFAULT);
|
||||||
|
Button selMgrBtn = new Button(buttonComp, SWT.PUSH);
|
||||||
|
selMgrBtn.setText("Selection Manager...");
|
||||||
|
selMgrBtn.setLayoutData(gd);
|
||||||
|
selMgrBtn.addSelectionListener(new SelectionAdapter() {
|
||||||
|
@Override
|
||||||
|
public void widgetSelected(SelectionEvent e) {
|
||||||
|
displaySelectionMgrDlg();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
// Not including this functionality in the branch.
|
||||||
|
// gd = new GridData(buttonWidth, SWT.DEFAULT);
|
||||||
|
// Button colorMgrBtn = new Button(buttonComp, SWT.PUSH);
|
||||||
|
// colorMgrBtn.setText("Color Manager...");
|
||||||
|
// colorMgrBtn.setLayoutData(gd);
|
||||||
|
// colorMgrBtn.addSelectionListener(new SelectionAdapter() {
|
||||||
|
// @Override
|
||||||
|
// public void widgetSelected(SelectionEvent e) {
|
||||||
|
// displayColorMgrDlg();
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle the check button event.
|
||||||
|
*
|
||||||
|
* @param btn
|
||||||
|
* Check box being checked/unchecked.
|
||||||
|
*/
|
||||||
|
private void handleCheckEvent(Button btn) {
|
||||||
|
String key = btn.getText();
|
||||||
|
|
||||||
|
if (btn.getSelection() == true) {
|
||||||
|
keyRgbMap.put(key, labelMap.get(key).getBackground().getRGB());
|
||||||
|
} else {
|
||||||
|
keyRgbMap.remove(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
fireCallback();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle the color label that is being clicked.
|
||||||
|
*
|
||||||
|
* @param lbl
|
||||||
|
* Label that was clicked.
|
||||||
|
*/
|
||||||
|
private void handleLabelClickEvent(Label lbl) {
|
||||||
|
RGB rgb = lbl.getBackground().getRGB();
|
||||||
|
String key = (String) lbl.getData();
|
||||||
|
|
||||||
|
ColorDialog colorDlg = new ColorDialog(this.getShell());
|
||||||
|
colorDlg.setRGB(rgb);
|
||||||
|
colorDlg.setText("Select a Color");
|
||||||
|
|
||||||
|
RGB returnRGB = colorDlg.open();
|
||||||
|
|
||||||
|
if (returnRGB == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Color c = new Color(this.getDisplay(), returnRGB);
|
||||||
|
lbl.setBackground(c);
|
||||||
|
c.dispose();
|
||||||
|
|
||||||
|
if (keyRgbMap.containsKey(key) == true) {
|
||||||
|
keyRgbMap.put(key, returnRGB);
|
||||||
|
}
|
||||||
|
|
||||||
|
fireCallback();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Call the callback.
|
||||||
|
*/
|
||||||
|
private void fireCallback() {
|
||||||
|
callback.setGroupData(keyRgbMap);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Setup the colors for the labels and put the key, RGB in the selected map.
|
||||||
|
*/
|
||||||
|
private void setupColorsAndKeyRgbMap() {
|
||||||
|
ColorManager cm = new ColorManager();
|
||||||
|
int count = 0;
|
||||||
|
Color c;
|
||||||
|
|
||||||
|
for (String key : labelMap.keySet()) {
|
||||||
|
c = new Color(this.getDisplay(), cm.getColorAtIndex(count));
|
||||||
|
labelMap.get(key).setBackground(c);
|
||||||
|
++count;
|
||||||
|
c.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
for (String key : checkBtnMap.keySet()) {
|
||||||
|
if (checkBtnMap.get(key).getSelection() == true) {
|
||||||
|
keyRgbMap.put(key, labelMap.get(key).getBackground().getRGB());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Display the Selection Manager dialog.
|
||||||
|
*/
|
||||||
|
private void displaySelectionMgrDlg() {
|
||||||
|
if (selectionMangerDlg == null || selectionMangerDlg.isDisposed()) {
|
||||||
|
selectionMangerDlg = new SelectionManagerDlg(getShell(), graphData,
|
||||||
|
this);
|
||||||
|
selectionMangerDlg.open();
|
||||||
|
} else {
|
||||||
|
selectionMangerDlg.bringToTop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Display the Color Manager dialog.
|
||||||
|
*/
|
||||||
|
// Implementing in the next release.
|
||||||
|
// private void displayColorMgrDlg() {
|
||||||
|
// ColorManagerDlg dlg = new ColorManagerDlg(getShell(), graphData, this);
|
||||||
|
// dlg.open();
|
||||||
|
// }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void setSelections(Map<String, Map<String, Boolean>> selectionMap) {
|
||||||
|
List<String> keySequence = graphData.getKeySequence();
|
||||||
|
|
||||||
|
Map<String, List<String>> offMap = new HashMap<String, List<String>>();
|
||||||
|
for (String key : selectionMap.keySet()) {
|
||||||
|
for (String selection : selectionMap.get(key).keySet()) {
|
||||||
|
if (!selectionMap.get(key).get(selection)) {
|
||||||
|
if (!offMap.containsKey(key)) {
|
||||||
|
offMap.put(key, new ArrayList<String>());
|
||||||
|
}
|
||||||
|
offMap.get(key).add(selection);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (offMap.size() == 0) {
|
||||||
|
for (String btnKey : checkBtnMap.keySet()) {
|
||||||
|
checkBtnMap.get(btnKey).setSelection(true);
|
||||||
|
keyRgbMap.put(btnKey, labelMap.get(btnKey).getBackground()
|
||||||
|
.getRGB());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (String btnKey : checkBtnMap.keySet()) {
|
||||||
|
String[] parts = colonPattern.split(btnKey);
|
||||||
|
|
||||||
|
for (String group : offMap.keySet()) {
|
||||||
|
for (String part : parts) {
|
||||||
|
int idx = keySequence.indexOf(part);
|
||||||
|
if (idx >= 0 && offMap.get(group).contains(keySequence.get(idx))) {
|
||||||
|
checkBtnMap.get(btnKey).setSelection(false);
|
||||||
|
keyRgbMap.remove(btnKey);
|
||||||
|
} else {
|
||||||
|
checkBtnMap.get(btnKey).setSelection(true);
|
||||||
|
keyRgbMap.put(btnKey, labelMap.get(btnKey)
|
||||||
|
.getBackground().getRGB());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fireCallback();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,41 @@
|
||||||
|
/**
|
||||||
|
* This software was developed and / or modified by Raytheon Company,
|
||||||
|
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||||
|
*
|
||||||
|
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||||
|
* This software product contains export-restricted data whose
|
||||||
|
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||||
|
* to non-U.S. persons whether in the United States or abroad requires
|
||||||
|
* an export license or other authorization.
|
||||||
|
*
|
||||||
|
* Contractor Name: Raytheon Company
|
||||||
|
* Contractor Address: 6825 Pine Street, Suite 340
|
||||||
|
* Mail Stop B8
|
||||||
|
* Omaha, NE 68106
|
||||||
|
* 402.291.0100
|
||||||
|
*
|
||||||
|
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||||
|
* further licensing information.
|
||||||
|
**/
|
||||||
|
package com.raytheon.uf.viz.stats.ui;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TODO Add Description
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
*
|
||||||
|
* SOFTWARE HISTORY
|
||||||
|
*
|
||||||
|
* Date Ticket# Engineer Description
|
||||||
|
* ------------ ---------- ----------- --------------------------
|
||||||
|
* Oct 18, 2012 mpduff Initial creation
|
||||||
|
*
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* @author mpduff
|
||||||
|
* @version 1.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
public interface IColorSelection {
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,48 @@
|
||||||
|
/**
|
||||||
|
* This software was developed and / or modified by Raytheon Company,
|
||||||
|
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||||
|
*
|
||||||
|
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||||
|
* This software product contains export-restricted data whose
|
||||||
|
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||||
|
* to non-U.S. persons whether in the United States or abroad requires
|
||||||
|
* an export license or other authorization.
|
||||||
|
*
|
||||||
|
* Contractor Name: Raytheon Company
|
||||||
|
* Contractor Address: 6825 Pine Street, Suite 340
|
||||||
|
* Mail Stop B8
|
||||||
|
* Omaha, NE 68106
|
||||||
|
* 402.291.0100
|
||||||
|
*
|
||||||
|
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||||
|
* further licensing information.
|
||||||
|
**/
|
||||||
|
package com.raytheon.uf.viz.stats.ui;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interface for Group Selections.
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
*
|
||||||
|
* SOFTWARE HISTORY
|
||||||
|
*
|
||||||
|
* Date Ticket# Engineer Description
|
||||||
|
* ------------ ---------- ----------- --------------------------
|
||||||
|
* Oct 18, 2012 728 mpduff Initial creation
|
||||||
|
*
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* @author mpduff
|
||||||
|
* @version 1.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
public interface IGroupSelection {
|
||||||
|
/**
|
||||||
|
* Set the selections.
|
||||||
|
*
|
||||||
|
* @param selectionMap
|
||||||
|
*/
|
||||||
|
void setSelections(Map<String, Map<String, Boolean>> selectionMap);
|
||||||
|
}
|
|
@ -0,0 +1,44 @@
|
||||||
|
/**
|
||||||
|
* This software was developed and / or modified by Raytheon Company,
|
||||||
|
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||||
|
*
|
||||||
|
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||||
|
* This software product contains export-restricted data whose
|
||||||
|
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||||
|
* to non-U.S. persons whether in the United States or abroad requires
|
||||||
|
* an export license or other authorization.
|
||||||
|
*
|
||||||
|
* Contractor Name: Raytheon Company
|
||||||
|
* Contractor Address: 6825 Pine Street, Suite 340
|
||||||
|
* Mail Stop B8
|
||||||
|
* Omaha, NE 68106
|
||||||
|
* 402.291.0100
|
||||||
|
*
|
||||||
|
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||||
|
* further licensing information.
|
||||||
|
**/
|
||||||
|
package com.raytheon.uf.viz.stats.ui;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Statistics dialog control interface.
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
*
|
||||||
|
* SOFTWARE HISTORY
|
||||||
|
*
|
||||||
|
* Date Ticket# Engineer Description
|
||||||
|
* ------------ ---------- ----------- --------------------------
|
||||||
|
* Oct 9, 2012 728 mpduff Initial creation
|
||||||
|
*
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* @author mpduff
|
||||||
|
* @version 1.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
public interface IStatsControl {
|
||||||
|
/**
|
||||||
|
* Show the statistics control dialog.
|
||||||
|
*/
|
||||||
|
void showControl();
|
||||||
|
}
|
|
@ -0,0 +1,74 @@
|
||||||
|
/**
|
||||||
|
* This software was developed and / or modified by Raytheon Company,
|
||||||
|
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||||
|
*
|
||||||
|
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||||
|
* This software product contains export-restricted data whose
|
||||||
|
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||||
|
* to non-U.S. persons whether in the United States or abroad requires
|
||||||
|
* an export license or other authorization.
|
||||||
|
*
|
||||||
|
* Contractor Name: Raytheon Company
|
||||||
|
* Contractor Address: 6825 Pine Street, Suite 340
|
||||||
|
* Mail Stop B8
|
||||||
|
* Omaha, NE 68106
|
||||||
|
* 402.291.0100
|
||||||
|
*
|
||||||
|
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||||
|
* further licensing information.
|
||||||
|
**/
|
||||||
|
package com.raytheon.uf.viz.stats.ui;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.eclipse.swt.graphics.RGB;
|
||||||
|
|
||||||
|
import com.raytheon.uf.common.stats.data.GraphData;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stats display interface.
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
*
|
||||||
|
* SOFTWARE HISTORY
|
||||||
|
*
|
||||||
|
* Date Ticket# Engineer Description
|
||||||
|
* ------------ ---------- ----------- --------------------------
|
||||||
|
* Oct 3, 2012 728 mpduff Initial creation
|
||||||
|
*
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* @author mpduff
|
||||||
|
* @version 1.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
public interface IStatsDisplay {
|
||||||
|
/**
|
||||||
|
* Get the GraphData object
|
||||||
|
*
|
||||||
|
* @return GraphData
|
||||||
|
*/
|
||||||
|
GraphData getGraphData();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Draw grid lines flag
|
||||||
|
*
|
||||||
|
* @return true to draw the grid lines
|
||||||
|
*/
|
||||||
|
boolean drawGridLines();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Draw data lines flag
|
||||||
|
*
|
||||||
|
* @return true to draw the data lines
|
||||||
|
*/
|
||||||
|
boolean drawDataLines();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the group settings.
|
||||||
|
*
|
||||||
|
* @return The group settings map
|
||||||
|
*/
|
||||||
|
Map<String, RGB> getGroupSettings();
|
||||||
|
}
|
|
@ -0,0 +1,51 @@
|
||||||
|
/**
|
||||||
|
* This software was developed and / or modified by Raytheon Company,
|
||||||
|
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||||
|
*
|
||||||
|
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||||
|
* This software product contains export-restricted data whose
|
||||||
|
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||||
|
* to non-U.S. persons whether in the United States or abroad requires
|
||||||
|
* an export license or other authorization.
|
||||||
|
*
|
||||||
|
* Contractor Name: Raytheon Company
|
||||||
|
* Contractor Address: 6825 Pine Street, Suite 340
|
||||||
|
* Mail Stop B8
|
||||||
|
* Omaha, NE 68106
|
||||||
|
* 402.291.0100
|
||||||
|
*
|
||||||
|
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||||
|
* further licensing information.
|
||||||
|
**/
|
||||||
|
package com.raytheon.uf.viz.stats.ui;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.eclipse.swt.graphics.RGB;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stats group interface.
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
*
|
||||||
|
* SOFTWARE HISTORY
|
||||||
|
*
|
||||||
|
* Date Ticket# Engineer Description
|
||||||
|
* ------------ ---------- ----------- --------------------------
|
||||||
|
* Oct 17, 2012 728 mpduff Initial creation
|
||||||
|
*
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* @author mpduff
|
||||||
|
* @version 1.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
public interface IStatsGroup {
|
||||||
|
/**
|
||||||
|
* Set the group settings data.
|
||||||
|
*
|
||||||
|
* @param groupSettingsMap
|
||||||
|
*/
|
||||||
|
void setGroupData(Map<String, RGB> groupSettingsMap);
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,319 @@
|
||||||
|
/**
|
||||||
|
* This software was developed and / or modified by Raytheon Company,
|
||||||
|
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||||
|
*
|
||||||
|
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||||
|
* This software product contains export-restricted data whose
|
||||||
|
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||||
|
* to non-U.S. persons whether in the United States or abroad requires
|
||||||
|
* an export license or other authorization.
|
||||||
|
*
|
||||||
|
* Contractor Name: Raytheon Company
|
||||||
|
* Contractor Address: 6825 Pine Street, Suite 340
|
||||||
|
* Mail Stop B8
|
||||||
|
* Omaha, NE 68106
|
||||||
|
* 402.291.0100
|
||||||
|
*
|
||||||
|
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||||
|
* further licensing information.
|
||||||
|
**/
|
||||||
|
package com.raytheon.uf.viz.stats.ui;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.eclipse.swt.SWT;
|
||||||
|
import org.eclipse.swt.events.SelectionAdapter;
|
||||||
|
import org.eclipse.swt.events.SelectionEvent;
|
||||||
|
import org.eclipse.swt.layout.GridData;
|
||||||
|
import org.eclipse.swt.layout.GridLayout;
|
||||||
|
import org.eclipse.swt.widgets.Button;
|
||||||
|
import org.eclipse.swt.widgets.Composite;
|
||||||
|
import org.eclipse.swt.widgets.Event;
|
||||||
|
import org.eclipse.swt.widgets.Layout;
|
||||||
|
import org.eclipse.swt.widgets.Listener;
|
||||||
|
import org.eclipse.swt.widgets.MessageBox;
|
||||||
|
import org.eclipse.swt.widgets.Shell;
|
||||||
|
import org.eclipse.swt.widgets.Tree;
|
||||||
|
import org.eclipse.swt.widgets.TreeItem;
|
||||||
|
|
||||||
|
import com.raytheon.uf.common.stats.data.GraphData;
|
||||||
|
import com.raytheon.viz.ui.dialogs.CaveSWTDialogBase;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stats Selection Manager Dialog.
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
*
|
||||||
|
* SOFTWARE HISTORY
|
||||||
|
*
|
||||||
|
* Date Ticket# Engineer Description
|
||||||
|
* ------------ ---------- ----------- --------------------------
|
||||||
|
* Oct 18, 2012 lvenable Initial creation
|
||||||
|
*
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* @author lvenable
|
||||||
|
* @version 1.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class SelectionManagerDlg extends CaveSWTDialogBase {
|
||||||
|
/** Main Composite */
|
||||||
|
private Composite mainComp;
|
||||||
|
|
||||||
|
/** Selection tree */
|
||||||
|
private Tree selectionTree;
|
||||||
|
|
||||||
|
/** GraphData object */
|
||||||
|
private final GraphData graphData;
|
||||||
|
|
||||||
|
/** Group selection callback */
|
||||||
|
private final IGroupSelection callback;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor.
|
||||||
|
*
|
||||||
|
* @param parentShell
|
||||||
|
* @param graphData
|
||||||
|
* @param callback
|
||||||
|
*/
|
||||||
|
public SelectionManagerDlg(Shell parentShell, GraphData graphData,
|
||||||
|
IGroupSelection callback) {
|
||||||
|
super(parentShell, SWT.DIALOG_TRIM | SWT.MIN | SWT.RESIZE,
|
||||||
|
CAVE.DO_NOT_BLOCK | CAVE.MODE_INDEPENDENT
|
||||||
|
| CAVE.INDEPENDENT_SHELL);
|
||||||
|
setText("Selection Manager");
|
||||||
|
|
||||||
|
this.graphData = graphData;
|
||||||
|
this.callback = callback;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected Layout constructShellLayout() {
|
||||||
|
// Create the main layout for the shell.
|
||||||
|
GridLayout mainLayout = new GridLayout(1, false);
|
||||||
|
mainLayout.marginHeight = 2;
|
||||||
|
mainLayout.marginWidth = 2;
|
||||||
|
|
||||||
|
return mainLayout;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected void initializeComponents(Shell shell) {
|
||||||
|
shell.setMinimumSize(280, 400);
|
||||||
|
mainComp = new Composite(shell, SWT.NONE);
|
||||||
|
GridLayout gl = new GridLayout(1, false);
|
||||||
|
gl.marginHeight = 0;
|
||||||
|
gl.marginWidth = 0;
|
||||||
|
gl.horizontalSpacing = 0;
|
||||||
|
gl.verticalSpacing = 5;
|
||||||
|
GridData gd = new GridData(SWT.FILL, SWT.FILL, true, true);
|
||||||
|
mainComp.setLayout(gl);
|
||||||
|
mainComp.setLayoutData(gd);
|
||||||
|
|
||||||
|
initControls();
|
||||||
|
|
||||||
|
populateTree();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize controls
|
||||||
|
*/
|
||||||
|
private void initControls() {
|
||||||
|
createSelectionTree();
|
||||||
|
createActionControls();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create selection tree
|
||||||
|
*/
|
||||||
|
private void createSelectionTree() {
|
||||||
|
GridData gd = new GridData(SWT.FILL, SWT.FILL, true, true);
|
||||||
|
gd.widthHint = 250;
|
||||||
|
gd.heightHint = 350;
|
||||||
|
selectionTree = new Tree(mainComp, SWT.BORDER | SWT.CHECK);
|
||||||
|
selectionTree.setLayoutData(gd);
|
||||||
|
selectionTree.addListener(SWT.Selection, new Listener() {
|
||||||
|
@Override
|
||||||
|
public void handleEvent(Event event) {
|
||||||
|
if (event.detail == SWT.CHECK) {
|
||||||
|
TreeItem item = (TreeItem) event.item;
|
||||||
|
boolean checked = item.getChecked();
|
||||||
|
checkItems(item, checked);
|
||||||
|
checkPath(item.getParentItem(), checked, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create the buttons
|
||||||
|
*/
|
||||||
|
private void createActionControls() {
|
||||||
|
Composite buttonComp = new Composite(shell, SWT.NONE);
|
||||||
|
buttonComp.setLayout(new GridLayout(3, false));
|
||||||
|
buttonComp.setLayoutData(new GridData(SWT.CENTER, SWT.DEFAULT, true,
|
||||||
|
false));
|
||||||
|
|
||||||
|
int buttonWidth = 80;
|
||||||
|
|
||||||
|
GridData gd = new GridData(buttonWidth, SWT.DEFAULT);
|
||||||
|
Button okBtn = new Button(buttonComp, SWT.PUSH);
|
||||||
|
okBtn.setText("OK");
|
||||||
|
okBtn.setLayoutData(gd);
|
||||||
|
okBtn.addSelectionListener(new SelectionAdapter() {
|
||||||
|
@Override
|
||||||
|
public void widgetSelected(SelectionEvent e) {
|
||||||
|
handleApply();
|
||||||
|
close();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
gd = new GridData(buttonWidth, SWT.DEFAULT);
|
||||||
|
Button applyBtn = new Button(buttonComp, SWT.PUSH);
|
||||||
|
applyBtn.setText("Apply");
|
||||||
|
applyBtn.setLayoutData(gd);
|
||||||
|
applyBtn.addSelectionListener(new SelectionAdapter() {
|
||||||
|
@Override
|
||||||
|
public void widgetSelected(SelectionEvent e) {
|
||||||
|
handleApply();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
gd = new GridData(buttonWidth, SWT.DEFAULT);
|
||||||
|
Button cancelBtn = new Button(buttonComp, SWT.PUSH);
|
||||||
|
cancelBtn.setText("Cancel");
|
||||||
|
cancelBtn.setLayoutData(gd);
|
||||||
|
cancelBtn.addSelectionListener(new SelectionAdapter() {
|
||||||
|
@Override
|
||||||
|
public void widgetSelected(SelectionEvent e) {
|
||||||
|
close();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check the path of the item.
|
||||||
|
*
|
||||||
|
* @param item
|
||||||
|
* @param checked
|
||||||
|
* @param grayed
|
||||||
|
*/
|
||||||
|
private void checkPath(TreeItem item, boolean checked, boolean grayed) {
|
||||||
|
if (item == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (grayed) {
|
||||||
|
checked = true;
|
||||||
|
} else {
|
||||||
|
int index = 0;
|
||||||
|
TreeItem[] items = item.getItems();
|
||||||
|
while (index < items.length) {
|
||||||
|
TreeItem child = items[index];
|
||||||
|
if (child.getGrayed() || checked != child.getChecked()) {
|
||||||
|
checked = grayed = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
item.setChecked(checked);
|
||||||
|
item.setGrayed(grayed);
|
||||||
|
checkPath(item.getParentItem(), checked, grayed);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check or uncheck the items in the TreeItem
|
||||||
|
*
|
||||||
|
* @param item
|
||||||
|
* @param checked
|
||||||
|
*/
|
||||||
|
private void checkItems(TreeItem item, boolean checked) {
|
||||||
|
item.setGrayed(false);
|
||||||
|
item.setChecked(checked);
|
||||||
|
TreeItem[] items = item.getItems();
|
||||||
|
for (int i = 0; i < items.length; i++) {
|
||||||
|
checkItems(items[i], checked);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Populate the tree
|
||||||
|
*/
|
||||||
|
private void populateTree() {
|
||||||
|
Map<String, List<String>> grpMemberMap = graphData
|
||||||
|
.getGroupAndNamesMap();
|
||||||
|
|
||||||
|
for (String key : grpMemberMap.keySet()) {
|
||||||
|
TreeItem treeItem = new TreeItem(selectionTree, SWT.NONE);
|
||||||
|
treeItem.setText(key);
|
||||||
|
treeItem.setChecked(true);
|
||||||
|
List<String> array = grpMemberMap.get(key);
|
||||||
|
|
||||||
|
for (String subKey : array) {
|
||||||
|
TreeItem subTreeItem = new TreeItem(treeItem, SWT.NONE);
|
||||||
|
subTreeItem.setText(subKey);
|
||||||
|
|
||||||
|
subTreeItem.setChecked(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Apply button action handler.
|
||||||
|
*/
|
||||||
|
private void handleApply() {
|
||||||
|
Map<String, Map<String, Boolean>> selectionMap = new HashMap<String, Map<String, Boolean>>();
|
||||||
|
List<String> badList = new ArrayList<String>();
|
||||||
|
|
||||||
|
for (TreeItem item : selectionTree.getItems()) {
|
||||||
|
if (!item.getChecked()) {
|
||||||
|
badList.add(item.getText());
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, Boolean> map = new HashMap<String, Boolean>();
|
||||||
|
for (TreeItem subItem : item.getItems()) {
|
||||||
|
map.put(subItem.getText(), subItem.getChecked());
|
||||||
|
}
|
||||||
|
selectionMap.put(item.getText(), map);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Notify user of situation resulting in no data being graphed
|
||||||
|
if (badList.size() > 0) {
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
sb.append("The following ");
|
||||||
|
if (badList.size() > 1) {
|
||||||
|
sb.append("groups have");
|
||||||
|
} else {
|
||||||
|
sb.append("group has");
|
||||||
|
}
|
||||||
|
sb.append(" no selections made\n");
|
||||||
|
sb.append("and will result in an empty graph.\n\n");
|
||||||
|
|
||||||
|
for (int i = 0; i < badList.size(); i++) {
|
||||||
|
sb.append(badList.get(i)).append("\n");
|
||||||
|
}
|
||||||
|
sb.append("\nDo you wish to continue?");
|
||||||
|
MessageBox mb = new MessageBox(shell, SWT.ICON_QUESTION | SWT.YES
|
||||||
|
| SWT.NO);
|
||||||
|
mb.setText("Empty Graph");
|
||||||
|
mb.setMessage(sb.toString());
|
||||||
|
int choice = mb.open();
|
||||||
|
|
||||||
|
if (choice == SWT.YES) {
|
||||||
|
callback.setSelections(selectionMap);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
callback.setSelections(selectionMap);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,680 @@
|
||||||
|
/**
|
||||||
|
* This software was developed and / or modified by Raytheon Company,
|
||||||
|
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||||
|
*
|
||||||
|
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||||
|
* This software product contains export-restricted data whose
|
||||||
|
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||||
|
* to non-U.S. persons whether in the United States or abroad requires
|
||||||
|
* an export license or other authorization.
|
||||||
|
*
|
||||||
|
* Contractor Name: Raytheon Company
|
||||||
|
* Contractor Address: 6825 Pine Street, Suite 340
|
||||||
|
* Mail Stop B8
|
||||||
|
* Omaha, NE 68106
|
||||||
|
* 402.291.0100
|
||||||
|
*
|
||||||
|
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||||
|
* further licensing information.
|
||||||
|
**/
|
||||||
|
package com.raytheon.uf.viz.stats.ui;
|
||||||
|
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Calendar;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.TimeZone;
|
||||||
|
|
||||||
|
import org.eclipse.swt.SWT;
|
||||||
|
import org.eclipse.swt.events.SelectionAdapter;
|
||||||
|
import org.eclipse.swt.events.SelectionEvent;
|
||||||
|
import org.eclipse.swt.layout.GridData;
|
||||||
|
import org.eclipse.swt.layout.GridLayout;
|
||||||
|
import org.eclipse.swt.widgets.Button;
|
||||||
|
import org.eclipse.swt.widgets.Combo;
|
||||||
|
import org.eclipse.swt.widgets.Composite;
|
||||||
|
import org.eclipse.swt.widgets.Group;
|
||||||
|
import org.eclipse.swt.widgets.Label;
|
||||||
|
import org.eclipse.swt.widgets.MessageBox;
|
||||||
|
import org.eclipse.swt.widgets.Shell;
|
||||||
|
|
||||||
|
import com.raytheon.uf.common.stats.GraphDataRequest;
|
||||||
|
import com.raytheon.uf.common.stats.GraphDataResponse;
|
||||||
|
import com.raytheon.uf.common.stats.data.GraphData;
|
||||||
|
import com.raytheon.uf.common.stats.data.StatsEventData;
|
||||||
|
import com.raytheon.uf.common.stats.xml.StatisticsConfig;
|
||||||
|
import com.raytheon.uf.common.status.IUFStatusHandler;
|
||||||
|
import com.raytheon.uf.common.status.UFStatus;
|
||||||
|
import com.raytheon.uf.common.status.UFStatus.Priority;
|
||||||
|
import com.raytheon.uf.common.time.TimeRange;
|
||||||
|
import com.raytheon.uf.common.time.util.TimeUtil;
|
||||||
|
import com.raytheon.uf.viz.core.exception.VizException;
|
||||||
|
import com.raytheon.uf.viz.core.requests.ThriftClient;
|
||||||
|
import com.raytheon.uf.viz.stats.utils.StatsUiUtils;
|
||||||
|
import com.raytheon.viz.ui.dialogs.AwipsCalendar;
|
||||||
|
import com.raytheon.viz.ui.dialogs.CaveSWTDialog;
|
||||||
|
import com.raytheon.viz.ui.widgets.duallist.DualList;
|
||||||
|
import com.raytheon.viz.ui.widgets.duallist.DualListConfig;
|
||||||
|
import com.raytheon.viz.ui.widgets.duallist.IUpdate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stats graphing control dialog.
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
*
|
||||||
|
* SOFTWARE HISTORY
|
||||||
|
*
|
||||||
|
* Date Ticket# Engineer Description
|
||||||
|
* ------------ ---------- ----------- --------------------------
|
||||||
|
* Sep 25, 2012 mpduff Initial creation
|
||||||
|
*
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* @author mpduff
|
||||||
|
* @version 1.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class StatsControlDlg extends CaveSWTDialog implements IStatsControl,
|
||||||
|
IUpdate {
|
||||||
|
/** Status handler. */
|
||||||
|
private final IUFStatusHandler statusHandler = UFStatus
|
||||||
|
.getHandler(StatsControlDlg.class);
|
||||||
|
|
||||||
|
/** Time Range combo box items */
|
||||||
|
private final String[] TIME_RANGE_ITEMS = new String[] { "1 hr", "3 hr",
|
||||||
|
"6 hr", "12 hr", "24 hr", "1 week", "2 weeks", "1 month" };
|
||||||
|
|
||||||
|
/** Ranges corresponding to the time range combo box */
|
||||||
|
private final long[] MILLI_RANGES = new long[] { TimeUtil.MILLIS_PER_HOUR,
|
||||||
|
TimeUtil.MILLIS_PER_HOUR * 3, TimeUtil.MILLIS_PER_HOUR * 6,
|
||||||
|
TimeUtil.MILLIS_PER_HOUR * 12, TimeUtil.MILLIS_PER_DAY,
|
||||||
|
TimeUtil.MILLIS_PER_WEEK, TimeUtil.MILLIS_PER_WEEK * 2,
|
||||||
|
TimeUtil.MILLIS_PER_MONTH };
|
||||||
|
|
||||||
|
/** Date Format object */
|
||||||
|
private final ThreadLocal<SimpleDateFormat> sdf = new ThreadLocal<SimpleDateFormat>() {
|
||||||
|
@Override
|
||||||
|
protected SimpleDateFormat initialValue() {
|
||||||
|
SimpleDateFormat sTemp = new SimpleDateFormat("MM/dd/yyyy HH");
|
||||||
|
sTemp.setTimeZone(TimeZone.getTimeZone("GMT"));
|
||||||
|
return sTemp;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Main composite */
|
||||||
|
private Composite mainComp;
|
||||||
|
|
||||||
|
/** Date time label */
|
||||||
|
private Label dateTimeSelectedLabel;
|
||||||
|
|
||||||
|
/** Date time button */
|
||||||
|
private Button dateTimeBtn;
|
||||||
|
|
||||||
|
/** Time range selection combo box */
|
||||||
|
private Combo timeRangeCombo;
|
||||||
|
|
||||||
|
/** Start radio button */
|
||||||
|
private Button startRdo;
|
||||||
|
|
||||||
|
/** Split radio button */
|
||||||
|
private Button splitRdo;
|
||||||
|
|
||||||
|
/** Display button */
|
||||||
|
private Button displayBtn;
|
||||||
|
|
||||||
|
/** Close Button */
|
||||||
|
private Button closeBtn;
|
||||||
|
|
||||||
|
/** Category combo box */
|
||||||
|
private Combo categoryCombo;
|
||||||
|
|
||||||
|
/** Event combo box */
|
||||||
|
private Combo eventTypeCombo;
|
||||||
|
|
||||||
|
/** Data type/attribute combo box */
|
||||||
|
private Combo dataTypeCombo;
|
||||||
|
|
||||||
|
/** Groups dual list config object */
|
||||||
|
private DualListConfig groupFilterListConfig;
|
||||||
|
|
||||||
|
/** Group dual list widget */
|
||||||
|
private DualList groupFilterDualList;
|
||||||
|
|
||||||
|
/** Data type label */
|
||||||
|
private Label dataTypeLabel;
|
||||||
|
|
||||||
|
/** Combo box size */
|
||||||
|
private int comboSize;
|
||||||
|
|
||||||
|
/** Selected Date */
|
||||||
|
private Date selectedDate;
|
||||||
|
|
||||||
|
/** List of configuration objects */
|
||||||
|
private List<StatisticsConfig> configList;
|
||||||
|
|
||||||
|
/** StatsUiUtils object */
|
||||||
|
private final StatsUiUtils utils = new StatsUiUtils();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor.
|
||||||
|
*
|
||||||
|
* @param parent parent Shell
|
||||||
|
*/
|
||||||
|
public StatsControlDlg(Shell parent) {
|
||||||
|
super(parent, SWT.DIALOG_TRIM, CAVE.INDEPENDENT_SHELL
|
||||||
|
| CAVE.PERSPECTIVE_INDEPENDENT | CAVE.DO_NOT_BLOCK);
|
||||||
|
setText("Statistics Display Control");
|
||||||
|
|
||||||
|
Calendar cal = TimeUtil.newCalendar(TimeZone.getTimeZone("GMT"));
|
||||||
|
cal.set(Calendar.MILLISECOND, 0);
|
||||||
|
cal.set(Calendar.SECOND, 0);
|
||||||
|
cal.set(Calendar.MINUTE, 0);
|
||||||
|
cal.add(Calendar.DAY_OF_MONTH, -1);
|
||||||
|
this.selectedDate = cal.getTime();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected void initializeComponents(Shell shell) {
|
||||||
|
GridData gd = new GridData(SWT.FILL, SWT.DEFAULT, true, false);
|
||||||
|
GridLayout gl = new GridLayout(1, false);
|
||||||
|
|
||||||
|
mainComp = new Composite(shell, SWT.NONE);
|
||||||
|
mainComp.setLayout(gl);
|
||||||
|
mainComp.setLayoutData(gd);
|
||||||
|
|
||||||
|
// calculateSize();
|
||||||
|
|
||||||
|
createDateTimeComp();
|
||||||
|
createTimeRangeComp();
|
||||||
|
createDataChoiceComp();
|
||||||
|
|
||||||
|
createButtons();
|
||||||
|
generateData();
|
||||||
|
populateCategoryCombo();
|
||||||
|
setDataTypesAndGroups();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create the time composite.
|
||||||
|
*/
|
||||||
|
private void createDateTimeComp() {
|
||||||
|
GridData gd = new GridData(SWT.FILL, SWT.DEFAULT, true, false);
|
||||||
|
GridLayout gl = new GridLayout(2, false);
|
||||||
|
|
||||||
|
Group timeDateGroup = new Group(mainComp, SWT.NONE);
|
||||||
|
timeDateGroup.setText(" Date/Time ");
|
||||||
|
timeDateGroup.setLayout(gl);
|
||||||
|
timeDateGroup.setLayoutData(gd);
|
||||||
|
|
||||||
|
GridData btnData = new GridData(135, SWT.DEFAULT);
|
||||||
|
dateTimeBtn = new Button(timeDateGroup, SWT.PUSH);
|
||||||
|
dateTimeBtn.setLayoutData(btnData);
|
||||||
|
dateTimeBtn.setText("Select Date/Time...");
|
||||||
|
dateTimeBtn
|
||||||
|
.setToolTipText("Click to select a date and time for display");
|
||||||
|
dateTimeBtn.addSelectionListener(new SelectionAdapter() {
|
||||||
|
@Override
|
||||||
|
public void widgetSelected(SelectionEvent e) {
|
||||||
|
handleDateTimeSelection();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
gd = new GridData(SWT.FILL, SWT.CENTER, true, false);
|
||||||
|
dateTimeSelectedLabel = new Label(timeDateGroup, SWT.NONE | SWT.CENTER);
|
||||||
|
dateTimeSelectedLabel.setLayoutData(gd);
|
||||||
|
dateTimeSelectedLabel.setText(getFormattedDate(this.selectedDate));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create the time range composite
|
||||||
|
*/
|
||||||
|
private void createTimeRangeComp() {
|
||||||
|
GridData gd = new GridData(SWT.FILL, SWT.DEFAULT, true, false);
|
||||||
|
GridLayout gl = new GridLayout(2, false);
|
||||||
|
|
||||||
|
Group rangeGroup = new Group(mainComp, SWT.NONE);
|
||||||
|
rangeGroup.setText(" Graph Range ");
|
||||||
|
rangeGroup.setLayout(gl);
|
||||||
|
rangeGroup.setLayoutData(gd);
|
||||||
|
|
||||||
|
gd = new GridData(SWT.FILL, SWT.DEFAULT, true, false);
|
||||||
|
gl = new GridLayout(2, false);
|
||||||
|
Composite comboComp = new Composite(rangeGroup, SWT.NONE);
|
||||||
|
comboComp.setLayout(gl);
|
||||||
|
comboComp.setLayoutData(gd);
|
||||||
|
|
||||||
|
gd = new GridData(SWT.FILL, SWT.CENTER, true, false);
|
||||||
|
timeRangeCombo = new Combo(comboComp, SWT.READ_ONLY);
|
||||||
|
timeRangeCombo.setLayoutData(gd);
|
||||||
|
timeRangeCombo.setToolTipText("Choose a Time Range");
|
||||||
|
timeRangeCombo.setItems(this.TIME_RANGE_ITEMS);
|
||||||
|
timeRangeCombo.select(0);
|
||||||
|
|
||||||
|
gd = new GridData(SWT.CENTER, SWT.DEFAULT, true, false);
|
||||||
|
gl = new GridLayout(2, false);
|
||||||
|
|
||||||
|
Composite rdoComp = new Composite(rangeGroup, SWT.NONE);
|
||||||
|
rdoComp.setLayout(gl);
|
||||||
|
rdoComp.setLayoutData(gd);
|
||||||
|
|
||||||
|
startRdo = new Button(rdoComp, SWT.RADIO);
|
||||||
|
startRdo.setSelection(true);
|
||||||
|
startRdo.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, true, false));
|
||||||
|
startRdo.setText("Start");
|
||||||
|
startRdo.setToolTipText("Start time range\nat selected time");
|
||||||
|
|
||||||
|
splitRdo = new Button(rdoComp, SWT.RADIO);
|
||||||
|
splitRdo.setSelection(false);
|
||||||
|
splitRdo.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, true, false));
|
||||||
|
splitRdo.setText("Split");
|
||||||
|
splitRdo.setToolTipText("Split time range\nat selected time");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create the data choice comp
|
||||||
|
*/
|
||||||
|
private void createDataChoiceComp() {
|
||||||
|
GridData gd = new GridData(SWT.FILL, SWT.DEFAULT, true, false);
|
||||||
|
GridLayout gl = new GridLayout(1, false);
|
||||||
|
|
||||||
|
Group choiceGroup = new Group(mainComp, SWT.NONE);
|
||||||
|
choiceGroup.setText(" Graph Data ");
|
||||||
|
choiceGroup.setLayout(gl);
|
||||||
|
choiceGroup.setLayoutData(gd);
|
||||||
|
|
||||||
|
gd = new GridData(SWT.FILL, SWT.DEFAULT, true, false);
|
||||||
|
gl = new GridLayout(2, false);
|
||||||
|
Composite comboComp = new Composite(choiceGroup, SWT.NONE);
|
||||||
|
comboComp.setLayout(gl);
|
||||||
|
comboComp.setLayoutData(gd);
|
||||||
|
|
||||||
|
gd = new GridData(SWT.FILL, SWT.CENTER, true, false);
|
||||||
|
Label categoryLabel = new Label(comboComp, SWT.NONE);
|
||||||
|
categoryLabel.setLayoutData(gd);
|
||||||
|
categoryLabel.setText(" Category: ");
|
||||||
|
|
||||||
|
gd = new GridData(comboSize + 50, SWT.DEFAULT);
|
||||||
|
gd = new GridData(SWT.FILL, SWT.DEFAULT, true, false);
|
||||||
|
categoryCombo = new Combo(comboComp, SWT.READ_ONLY);
|
||||||
|
categoryCombo.setLayoutData(gd);
|
||||||
|
categoryCombo.setSize(comboSize, SWT.DEFAULT);
|
||||||
|
categoryCombo.setToolTipText("The Statistics Category");
|
||||||
|
categoryCombo.addSelectionListener(new SelectionAdapter() {
|
||||||
|
@Override
|
||||||
|
public void widgetSelected(SelectionEvent e) {
|
||||||
|
updateOptions();
|
||||||
|
setDataTypesAndGroups();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
gd = new GridData(SWT.FILL, SWT.CENTER, true, false);
|
||||||
|
Label eventTypeLabel = new Label(comboComp, SWT.NONE);
|
||||||
|
eventTypeLabel.setLayoutData(gd);
|
||||||
|
eventTypeLabel.setText(" Event Type: ");
|
||||||
|
|
||||||
|
gd = new GridData(comboSize + 50, SWT.DEFAULT);
|
||||||
|
gd = new GridData(SWT.FILL, SWT.DEFAULT, true, false);
|
||||||
|
eventTypeCombo = new Combo(comboComp, SWT.READ_ONLY);
|
||||||
|
eventTypeCombo.setLayoutData(gd);
|
||||||
|
eventTypeCombo.setSize(comboSize, SWT.DEFAULT);
|
||||||
|
eventTypeCombo.setToolTipText("The Event Type to Display");
|
||||||
|
eventTypeCombo.select(0);
|
||||||
|
eventTypeCombo.addSelectionListener(new SelectionAdapter() {
|
||||||
|
@Override
|
||||||
|
public void widgetSelected(SelectionEvent e) {
|
||||||
|
setDataTypesAndGroups();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
gd = new GridData(SWT.FILL, SWT.CENTER, true, false);
|
||||||
|
dataTypeLabel = new Label(comboComp, SWT.NONE);
|
||||||
|
dataTypeLabel.setLayoutData(gd);
|
||||||
|
dataTypeLabel.setText(" Event Attribute: ");
|
||||||
|
|
||||||
|
gd = new GridData(comboSize + 50, SWT.DEFAULT);
|
||||||
|
gd = new GridData(SWT.FILL, SWT.DEFAULT, true, false);
|
||||||
|
dataTypeCombo = new Combo(comboComp, SWT.READ_ONLY);
|
||||||
|
dataTypeCombo.setLayoutData(gd);
|
||||||
|
dataTypeCombo.setSize(comboSize, SWT.DEFAULT);
|
||||||
|
dataTypeCombo.setToolTipText("The Event Attribute to Display");
|
||||||
|
|
||||||
|
gd = new GridData(SWT.FILL, SWT.DEFAULT, true, false);
|
||||||
|
gl = new GridLayout(1, false);
|
||||||
|
Composite dualListComp = new Composite(choiceGroup, SWT.NONE);
|
||||||
|
dualListComp.setLayout(gl);
|
||||||
|
dualListComp.setLayoutData(gd);
|
||||||
|
|
||||||
|
groupFilterListConfig = new DualListConfig();
|
||||||
|
groupFilterListConfig.setAvailableListLabel("Available Groups:");
|
||||||
|
groupFilterListConfig.setSelectedListLabel("Selected Groups:");
|
||||||
|
groupFilterListConfig.setShowUpDownBtns(false);
|
||||||
|
groupFilterListConfig.setListWidth(150);
|
||||||
|
groupFilterListConfig.setListHeight(100);
|
||||||
|
|
||||||
|
this.groupFilterDualList = new DualList(dualListComp, SWT.NONE,
|
||||||
|
groupFilterListConfig, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create the buttons
|
||||||
|
*/
|
||||||
|
private void createButtons() {
|
||||||
|
GridData gd = new GridData(SWT.CENTER, SWT.DEFAULT, true, false);
|
||||||
|
GridLayout gl = new GridLayout(2, false);
|
||||||
|
|
||||||
|
Composite comp = new Composite(mainComp, SWT.NONE);
|
||||||
|
comp.setLayout(gl);
|
||||||
|
comp.setLayoutData(gd);
|
||||||
|
|
||||||
|
GridData btnData = new GridData(85, SWT.DEFAULT);
|
||||||
|
displayBtn = new Button(comp, SWT.PUSH);
|
||||||
|
displayBtn.setLayoutData(btnData);
|
||||||
|
displayBtn.setText("Display");
|
||||||
|
displayBtn.setToolTipText("Display the Statistical Data");
|
||||||
|
displayBtn.addSelectionListener(new SelectionAdapter() {
|
||||||
|
@Override
|
||||||
|
public void widgetSelected(SelectionEvent e) {
|
||||||
|
handleDisplayAction();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
btnData = new GridData(85, SWT.DEFAULT);
|
||||||
|
closeBtn = new Button(comp, SWT.PUSH);
|
||||||
|
closeBtn.setLayoutData(btnData);
|
||||||
|
closeBtn.setText("Close");
|
||||||
|
closeBtn.setToolTipText("Close this dialog");
|
||||||
|
closeBtn.addSelectionListener(new SelectionAdapter() {
|
||||||
|
@Override
|
||||||
|
public void widgetSelected(SelectionEvent e) {
|
||||||
|
close();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Display an informational popup message to the user.
|
||||||
|
*
|
||||||
|
* @param title The title
|
||||||
|
* @param message The message
|
||||||
|
* @param type Type of message
|
||||||
|
*/
|
||||||
|
public void displayPopup(String title, String message, int type) {
|
||||||
|
MessageBox messageDialog = new MessageBox(getShell(), type);
|
||||||
|
messageDialog.setText(title);
|
||||||
|
messageDialog.setMessage(message);
|
||||||
|
messageDialog.open();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the data types.
|
||||||
|
*
|
||||||
|
* @param dataTypes String[] of data types
|
||||||
|
*/
|
||||||
|
public void setDataTypes(String[] dataTypes) {
|
||||||
|
if (dataTypes != null) {
|
||||||
|
dataTypeCombo.setItems(dataTypes);
|
||||||
|
dataTypeCombo.select(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Date/Time selection handler
|
||||||
|
*/
|
||||||
|
protected void handleDateTimeSelection() {
|
||||||
|
AwipsCalendar ac = new AwipsCalendar(getShell(), selectedDate, true);
|
||||||
|
Object obj = ac.open();
|
||||||
|
|
||||||
|
if ((obj != null) && (obj instanceof Calendar)) {
|
||||||
|
selectedDate = ((Calendar) obj).getTime();
|
||||||
|
dateTimeSelectedLabel.setText(getFormattedDate(selectedDate));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate stats config data objects
|
||||||
|
*/
|
||||||
|
private void generateData() {
|
||||||
|
utils.generateData(this.configList);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Populate the categore combo box
|
||||||
|
*/
|
||||||
|
private void populateCategoryCombo() {
|
||||||
|
List<String> items = new ArrayList<String>();
|
||||||
|
for (StatisticsConfig config : this.configList) {
|
||||||
|
items.addAll(config.getCategories());
|
||||||
|
}
|
||||||
|
|
||||||
|
categoryCombo.setItems(items.toArray(new String[items.size()]));
|
||||||
|
categoryCombo.select(0);
|
||||||
|
|
||||||
|
String category = this.categoryCombo.getText();
|
||||||
|
Map<String, String> eventTypes = utils.getEventTypes(category);
|
||||||
|
this.eventTypeCombo.setItems(eventTypes.keySet().toArray(
|
||||||
|
new String[eventTypes.keySet().size()]));
|
||||||
|
eventTypeCombo.select(0);
|
||||||
|
this.eventTypeCombo.setData(eventTypes);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the data types based on category selection.
|
||||||
|
*/
|
||||||
|
public void setDataTypes() {
|
||||||
|
String category = this.categoryCombo.getItem(categoryCombo
|
||||||
|
.getSelectionIndex());
|
||||||
|
String type = this.eventTypeCombo.getItem(eventTypeCombo
|
||||||
|
.getSelectionIndex());
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
String typeID = ((Map<String, String>) eventTypeCombo.getData())
|
||||||
|
.get(type);
|
||||||
|
StatsEventData data = utils.getEventData(category, typeID);
|
||||||
|
this.dataTypeCombo.setItems(data.getAttributes());
|
||||||
|
dataTypeCombo.select(0);
|
||||||
|
Map<String, String> attMap = utils.getEventAttributes(category, type);
|
||||||
|
dataTypeCombo.setData(attMap);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the options based on combo box selections
|
||||||
|
*/
|
||||||
|
private void updateOptions() {
|
||||||
|
String category = this.categoryCombo.getItem(categoryCombo
|
||||||
|
.getSelectionIndex());
|
||||||
|
Map<String, String> eventTypes = utils.getEventTypes(category);
|
||||||
|
this.eventTypeCombo.setItems(eventTypes.keySet().toArray(
|
||||||
|
new String[eventTypes.keySet().size()]));
|
||||||
|
eventTypeCombo.select(0);
|
||||||
|
this.eventTypeCombo.setData(eventTypes);
|
||||||
|
|
||||||
|
String type = this.eventTypeCombo.getItem(eventTypeCombo
|
||||||
|
.getSelectionIndex());
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
String typeID = ((Map<String, String>) eventTypeCombo.getData())
|
||||||
|
.get(type);
|
||||||
|
StatsEventData data = utils.getEventData(category, typeID);
|
||||||
|
this.dataTypeCombo.setItems(data.getAttributes());
|
||||||
|
dataTypeCombo.select(0);
|
||||||
|
|
||||||
|
List<String> groupList = data.getGroupList();
|
||||||
|
Collections.sort(groupList);
|
||||||
|
groupFilterDualList.clearAvailableList(true);
|
||||||
|
groupFilterDualList.clearSelection();
|
||||||
|
groupFilterDualList.setAvailableItems(groupList);
|
||||||
|
groupFilterDualList.getConfig().setFullList(groupList);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the data type and groups
|
||||||
|
*/
|
||||||
|
public void setDataTypesAndGroups() {
|
||||||
|
String category = this.categoryCombo.getItem(categoryCombo
|
||||||
|
.getSelectionIndex());
|
||||||
|
String type = this.eventTypeCombo.getItem(eventTypeCombo
|
||||||
|
.getSelectionIndex());
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
String typeID = ((Map<String, String>) eventTypeCombo.getData())
|
||||||
|
.get(type);
|
||||||
|
StatsEventData data = utils.getEventData(category, typeID);
|
||||||
|
Map<String, String> attMap = utils.getEventAttributes(category, type);
|
||||||
|
dataTypeCombo.setData(attMap);
|
||||||
|
this.dataTypeCombo.setItems(data.getAttributes());
|
||||||
|
dataTypeCombo.select(0);
|
||||||
|
|
||||||
|
List<String> groupList = data.getGroupList();
|
||||||
|
Collections.sort(groupList);
|
||||||
|
groupFilterDualList.clearAvailableList(true);
|
||||||
|
groupFilterDualList.clearSelection();
|
||||||
|
groupFilterDualList.setAvailableItems(groupList);
|
||||||
|
groupFilterDualList.getConfig().setFullList(groupList);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void hasEntries(boolean entries) {
|
||||||
|
this.displayBtn.setEnabled(entries);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void selectionChanged() {
|
||||||
|
// not used
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Display the graph!
|
||||||
|
*/
|
||||||
|
private void handleDisplayAction() {
|
||||||
|
GraphDataRequest request = new GraphDataRequest();
|
||||||
|
|
||||||
|
String type = eventTypeCombo.getText();
|
||||||
|
String category = categoryCombo.getText();
|
||||||
|
String dataType = this.dataTypeCombo.getText();
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
String typeID = ((Map<String, String>) eventTypeCombo.getData())
|
||||||
|
.get(type);
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
String dataTypeID = ((Map<String, String>) dataTypeCombo.getData())
|
||||||
|
.get(dataType);
|
||||||
|
|
||||||
|
String[] selectedGroups = groupFilterDualList.getSelectedListItems();
|
||||||
|
StatsEventData conf = utils.getEventData(category, typeID);
|
||||||
|
List<String> groupList = new ArrayList<String>();
|
||||||
|
for (String group : selectedGroups) {
|
||||||
|
String groupName = conf.getGroupNameFromDisplayName(group);
|
||||||
|
if (groupName != null) {
|
||||||
|
groupList.add(groupName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
request.setField(dataTypeID);
|
||||||
|
request.setCategory(category);
|
||||||
|
request.setEventType(typeID);
|
||||||
|
request.setDataType(dataTypeID);
|
||||||
|
request.setGrouping(groupList);
|
||||||
|
|
||||||
|
int idx = timeRangeCombo.getSelectionIndex();
|
||||||
|
long selectedMillis = MILLI_RANGES[idx];
|
||||||
|
Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
|
||||||
|
cal.setTime(selectedDate);
|
||||||
|
|
||||||
|
Date start;
|
||||||
|
Date end;
|
||||||
|
if (splitRdo.getSelection()) {
|
||||||
|
// Go back half the time range
|
||||||
|
cal.add(Calendar.MILLISECOND, -1 * Math.round(selectedMillis / 2));
|
||||||
|
start = cal.getTime();
|
||||||
|
// move forward the whole time range
|
||||||
|
cal.add(Calendar.MILLISECOND, (int) selectedMillis);
|
||||||
|
end = cal.getTime();
|
||||||
|
} else {
|
||||||
|
start = cal.getTime();
|
||||||
|
// one month of millis is larger than an int
|
||||||
|
if (selectedMillis > Integer.MAX_VALUE) {
|
||||||
|
cal.add(Calendar.SECOND, (int) (selectedMillis / 1000));
|
||||||
|
} else {
|
||||||
|
cal.add(Calendar.MILLISECOND, (int) selectedMillis);
|
||||||
|
}
|
||||||
|
end = cal.getTime();
|
||||||
|
}
|
||||||
|
TimeRange tr = new TimeRange(start, end);
|
||||||
|
request.setTimeRange(tr);
|
||||||
|
request.setTimeStep(5);
|
||||||
|
|
||||||
|
try {
|
||||||
|
GraphDataResponse response = (GraphDataResponse) ThriftClient
|
||||||
|
.sendRequest(request);
|
||||||
|
|
||||||
|
GraphData graphData = response.getGraphData();
|
||||||
|
|
||||||
|
if (graphData != null) {
|
||||||
|
StatsGraphDlg graphDlg = new StatsGraphDlg(getShell(), this);
|
||||||
|
|
||||||
|
graphDlg.setGraphData(graphData);
|
||||||
|
graphDlg.setTitle(type);
|
||||||
|
graphDlg.setGraphTitle(dataType);
|
||||||
|
graphDlg.setGrouping(groupList);
|
||||||
|
graphDlg.setCategory(category);
|
||||||
|
graphDlg.setEventType(typeID);
|
||||||
|
graphDlg.setDataType(dataTypeID);
|
||||||
|
|
||||||
|
graphDlg.open();
|
||||||
|
} else {
|
||||||
|
displayPopup(
|
||||||
|
"No Data",
|
||||||
|
"No statistical data are available for the time period selected.",
|
||||||
|
SWT.ICON_INFORMATION);
|
||||||
|
}
|
||||||
|
} catch (VizException e) {
|
||||||
|
statusHandler.handle(Priority.ERROR, "Error Occured", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Format the date.
|
||||||
|
*
|
||||||
|
* @param date The date to format
|
||||||
|
* @return the formated string
|
||||||
|
*/
|
||||||
|
private String getFormattedDate(Date date) {
|
||||||
|
SimpleDateFormat format = sdf.get();
|
||||||
|
return format.format(date) + "Z";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void showControl() {
|
||||||
|
this.bringToTop();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the configList
|
||||||
|
*/
|
||||||
|
public List<StatisticsConfig> getConfigList() {
|
||||||
|
return configList;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param configList
|
||||||
|
* the configList to set
|
||||||
|
*/
|
||||||
|
public void setConfigList(List<StatisticsConfig> configList) {
|
||||||
|
this.configList = configList;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,824 @@
|
||||||
|
/**
|
||||||
|
* This software was developed and / or modified by Raytheon Company,
|
||||||
|
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||||
|
*
|
||||||
|
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||||
|
* This software product contains export-restricted data whose
|
||||||
|
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||||
|
* to non-U.S. persons whether in the United States or abroad requires
|
||||||
|
* an export license or other authorization.
|
||||||
|
*
|
||||||
|
* Contractor Name: Raytheon Company
|
||||||
|
* Contractor Address: 6825 Pine Street, Suite 340
|
||||||
|
* Mail Stop B8
|
||||||
|
* Omaha, NE 68106
|
||||||
|
* 402.291.0100
|
||||||
|
*
|
||||||
|
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||||
|
* further licensing information.
|
||||||
|
**/
|
||||||
|
package com.raytheon.uf.viz.stats.ui;
|
||||||
|
|
||||||
|
import java.text.DecimalFormat;
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Calendar;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.TimeZone;
|
||||||
|
|
||||||
|
import org.eclipse.swt.SWT;
|
||||||
|
import org.eclipse.swt.events.DisposeEvent;
|
||||||
|
import org.eclipse.swt.events.DisposeListener;
|
||||||
|
import org.eclipse.swt.events.MouseEvent;
|
||||||
|
import org.eclipse.swt.events.MouseMoveListener;
|
||||||
|
import org.eclipse.swt.events.PaintEvent;
|
||||||
|
import org.eclipse.swt.events.PaintListener;
|
||||||
|
import org.eclipse.swt.graphics.Color;
|
||||||
|
import org.eclipse.swt.graphics.Font;
|
||||||
|
import org.eclipse.swt.graphics.GC;
|
||||||
|
import org.eclipse.swt.graphics.Point;
|
||||||
|
import org.eclipse.swt.graphics.RGB;
|
||||||
|
import org.eclipse.swt.graphics.Rectangle;
|
||||||
|
import org.eclipse.swt.graphics.Transform;
|
||||||
|
import org.eclipse.swt.layout.GridData;
|
||||||
|
import org.eclipse.swt.layout.GridLayout;
|
||||||
|
import org.eclipse.swt.widgets.Canvas;
|
||||||
|
import org.eclipse.swt.widgets.Composite;
|
||||||
|
import org.eclipse.swt.widgets.Label;
|
||||||
|
import org.eclipse.swt.widgets.Shell;
|
||||||
|
|
||||||
|
import com.raytheon.uf.common.stats.data.DataPoint;
|
||||||
|
import com.raytheon.uf.common.stats.data.GraphData;
|
||||||
|
import com.raytheon.uf.common.stats.data.StatsData;
|
||||||
|
import com.raytheon.uf.common.time.TimeRange;
|
||||||
|
import com.raytheon.uf.common.time.util.TimeUtil;
|
||||||
|
import com.raytheon.uf.viz.core.RGBColors;
|
||||||
|
import com.raytheon.uf.viz.stats.display.ScaleManager;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Statistics graph canvas.
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
*
|
||||||
|
* SOFTWARE HISTORY
|
||||||
|
*
|
||||||
|
* Date Ticket# Engineer Description
|
||||||
|
* ------------ ---------- ----------- --------------------------
|
||||||
|
* Oct 3, 2012 728 mpduff Initial creation
|
||||||
|
*
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* @author mpduff
|
||||||
|
* @version 1.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class StatsDisplayCanvas extends Canvas {
|
||||||
|
/** Date Format object for graph title */
|
||||||
|
private final ThreadLocal<SimpleDateFormat> titleDateFormat = new ThreadLocal<SimpleDateFormat>() {
|
||||||
|
@Override
|
||||||
|
protected SimpleDateFormat initialValue() {
|
||||||
|
SimpleDateFormat sTemp = new SimpleDateFormat("MM/dd/yyyy HH:mm");
|
||||||
|
sTemp.setTimeZone(TimeZone.getTimeZone("GMT"));
|
||||||
|
return sTemp;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Date Format object for x axis */
|
||||||
|
private final ThreadLocal<SimpleDateFormat> axisFormat = new ThreadLocal<SimpleDateFormat>() {
|
||||||
|
@Override
|
||||||
|
protected SimpleDateFormat initialValue() {
|
||||||
|
SimpleDateFormat sTemp = new SimpleDateFormat("MM/dd/yyyy");
|
||||||
|
sTemp.setTimeZone(TimeZone.getTimeZone("GMT"));
|
||||||
|
return sTemp;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Decimal Format object */
|
||||||
|
private final ThreadLocal<DecimalFormat> numFormat = new ThreadLocal<DecimalFormat>() {
|
||||||
|
@Override
|
||||||
|
protected DecimalFormat initialValue() {
|
||||||
|
DecimalFormat tmp = new DecimalFormat("####.##");
|
||||||
|
return tmp;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Constant */
|
||||||
|
private final String COLON = ":";
|
||||||
|
|
||||||
|
/** Constant */
|
||||||
|
private final String ZERO = "0";
|
||||||
|
|
||||||
|
/** Constant */
|
||||||
|
private final String COUNT = "count";
|
||||||
|
|
||||||
|
/** Canvas initialized flag */
|
||||||
|
private boolean initialized = false;
|
||||||
|
|
||||||
|
/** Constant */
|
||||||
|
private final String MINUTE_00 = "00";
|
||||||
|
|
||||||
|
private final int canvasWidth = 800;
|
||||||
|
|
||||||
|
private final int canvasHeight = 575;
|
||||||
|
|
||||||
|
private final int GRAPH_BORDER = 75;
|
||||||
|
|
||||||
|
private final int GRAPH_WIDTH = canvasWidth - GRAPH_BORDER * 2;
|
||||||
|
|
||||||
|
private final int GRAPH_HEIGHT = canvasHeight - GRAPH_BORDER * 2;
|
||||||
|
|
||||||
|
/** Y Axis dimensions */
|
||||||
|
private final int[] yAxis = new int[] { GRAPH_BORDER, GRAPH_BORDER,
|
||||||
|
GRAPH_BORDER, GRAPH_HEIGHT + GRAPH_BORDER };
|
||||||
|
|
||||||
|
/** X Axis dimensions */
|
||||||
|
private final int[] xAxis = new int[] { GRAPH_BORDER,
|
||||||
|
GRAPH_HEIGHT + GRAPH_BORDER, GRAPH_WIDTH + GRAPH_BORDER,
|
||||||
|
GRAPH_HEIGHT + GRAPH_BORDER };
|
||||||
|
|
||||||
|
/** Top border dimensions */
|
||||||
|
private final int[] borderTop = new int[] { GRAPH_BORDER, GRAPH_BORDER,
|
||||||
|
GRAPH_BORDER + GRAPH_WIDTH, GRAPH_BORDER };
|
||||||
|
|
||||||
|
/** Right border dimensions */
|
||||||
|
private final int[] borderRight = new int[] { GRAPH_BORDER + GRAPH_WIDTH,
|
||||||
|
GRAPH_BORDER, GRAPH_BORDER + GRAPH_WIDTH,
|
||||||
|
GRAPH_BORDER + GRAPH_HEIGHT };
|
||||||
|
|
||||||
|
/** Canvas center */
|
||||||
|
private final int center = canvasWidth / 2;
|
||||||
|
|
||||||
|
/** Canvas font */
|
||||||
|
private Font canvasFont;
|
||||||
|
|
||||||
|
/** Parent Composite */
|
||||||
|
private final Composite parentComp;
|
||||||
|
|
||||||
|
/** Font height in pixels */
|
||||||
|
private int fontHeight;
|
||||||
|
|
||||||
|
/** Font width in pixels */
|
||||||
|
private int fontAveWidth;
|
||||||
|
|
||||||
|
/** Scale value manager */
|
||||||
|
private ScaleManager scalingManager;
|
||||||
|
|
||||||
|
/** The graph title */
|
||||||
|
private String graphTitle;
|
||||||
|
|
||||||
|
/** The secondary graph title */
|
||||||
|
private final String graphTitle2;
|
||||||
|
|
||||||
|
/** Millis per pixel in the X direction */
|
||||||
|
private long millisPerPixelX;
|
||||||
|
|
||||||
|
/** Callback */
|
||||||
|
private final IStatsDisplay callback;
|
||||||
|
|
||||||
|
/** Map of Rectangle objects */
|
||||||
|
private final Map<String, List<Rectangle>> rectangleMap = new HashMap<String, List<Rectangle>>();
|
||||||
|
|
||||||
|
/** Tooltip shell */
|
||||||
|
private Shell tooltip;
|
||||||
|
|
||||||
|
/** Graph Data object */
|
||||||
|
private GraphData graphData;
|
||||||
|
|
||||||
|
/** Smallest value in the data set */
|
||||||
|
private double minValue;
|
||||||
|
|
||||||
|
/** Largest value in the data set */
|
||||||
|
private double maxValue;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*
|
||||||
|
* @param parent
|
||||||
|
* Parent composite
|
||||||
|
* @param callback
|
||||||
|
* Callback to the parent
|
||||||
|
* @param graphTitle
|
||||||
|
* The graph title
|
||||||
|
*/
|
||||||
|
public StatsDisplayCanvas(Composite parent, IStatsDisplay callback,
|
||||||
|
String graphTitle) {
|
||||||
|
super(parent, SWT.DOUBLE_BUFFERED);
|
||||||
|
this.parentComp = parent;
|
||||||
|
this.callback = callback;
|
||||||
|
this.graphTitle = graphTitle;
|
||||||
|
|
||||||
|
this.graphData = callback.getGraphData();
|
||||||
|
TimeRange tr = graphData.getTimeRange();
|
||||||
|
String start = titleDateFormat.get().format(tr.getStart());
|
||||||
|
String end = titleDateFormat.get().format(tr.getEnd());
|
||||||
|
|
||||||
|
this.graphTitle = graphTitle;
|
||||||
|
this.graphTitle2 = start + "Z - " + end + "Z";
|
||||||
|
|
||||||
|
setupCanvas();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize the canvas.
|
||||||
|
*/
|
||||||
|
private void setupCanvas() {
|
||||||
|
canvasFont = new Font(parentComp.getDisplay(), "Monospace", 9,
|
||||||
|
SWT.NORMAL);
|
||||||
|
GridData gd = new GridData(SWT.FILL, SWT.FILL, true, true);
|
||||||
|
gd.heightHint = canvasHeight;
|
||||||
|
gd.widthHint = canvasWidth;
|
||||||
|
setLayoutData(gd);
|
||||||
|
|
||||||
|
addPaintListener(new PaintListener() {
|
||||||
|
@Override
|
||||||
|
public void paintControl(PaintEvent e) {
|
||||||
|
drawCanvas(e.gc);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
addDisposeListener(new DisposeListener() {
|
||||||
|
@Override
|
||||||
|
public void widgetDisposed(DisposeEvent e) {
|
||||||
|
if ((canvasFont != null) && (!canvasFont.isDisposed())) {
|
||||||
|
canvasFont.dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
addMouseMoveListener(new MouseMoveListener() {
|
||||||
|
@Override
|
||||||
|
public void mouseMove(MouseEvent e) {
|
||||||
|
handleMouseMoveEvent(e);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize drawing settings.
|
||||||
|
*
|
||||||
|
* @param gc
|
||||||
|
* The Graphics Context
|
||||||
|
*/
|
||||||
|
private void init(GC gc) {
|
||||||
|
if (!this.initialized) {
|
||||||
|
initialized = true;
|
||||||
|
gc.setAntialias(SWT.ON);
|
||||||
|
|
||||||
|
gc.setFont(canvasFont);
|
||||||
|
|
||||||
|
fontHeight = (gc.getFontMetrics().getHeight());
|
||||||
|
fontAveWidth = gc.getFontMetrics().getAverageCharWidth();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Draw on the canvas.
|
||||||
|
*
|
||||||
|
* @param gc
|
||||||
|
* The Graphics Context
|
||||||
|
*/
|
||||||
|
protected void drawCanvas(GC gc) {
|
||||||
|
init(gc);
|
||||||
|
gc.setBackground(parentComp.getDisplay()
|
||||||
|
.getSystemColor(SWT.COLOR_WHITE));
|
||||||
|
gc.fillRectangle(0, 0, canvasWidth, canvasHeight + 2);
|
||||||
|
|
||||||
|
RGB color = RGBColors.getRGBColor("gray85");
|
||||||
|
gc.setBackground(new Color(parentComp.getDisplay(), color.red,
|
||||||
|
color.green, color.blue));
|
||||||
|
Rectangle graphArea = new Rectangle(GRAPH_BORDER, GRAPH_BORDER,
|
||||||
|
GRAPH_WIDTH, GRAPH_HEIGHT);
|
||||||
|
gc.fillRectangle(graphArea);
|
||||||
|
gc.setBackground(parentComp.getDisplay()
|
||||||
|
.getSystemColor(SWT.COLOR_WHITE));
|
||||||
|
|
||||||
|
gc.setForeground(parentComp.getDisplay()
|
||||||
|
.getSystemColor(SWT.COLOR_BLACK));
|
||||||
|
|
||||||
|
gc.drawPolygon(borderTop);
|
||||||
|
|
||||||
|
gc.drawPolygon(borderRight);
|
||||||
|
|
||||||
|
// Draw the graph title
|
||||||
|
int titleLength = graphTitle.length() * fontAveWidth;
|
||||||
|
int title2Length = graphTitle2.length() * fontAveWidth;
|
||||||
|
int titleX = center - titleLength / 2;
|
||||||
|
int titleY = GRAPH_BORDER / 2 - fontHeight;
|
||||||
|
gc.drawText(graphTitle, titleX, titleY);
|
||||||
|
|
||||||
|
titleX = center - title2Length / 2;
|
||||||
|
titleY = GRAPH_BORDER / 2 + 5;
|
||||||
|
gc.drawText(graphTitle2, titleX, titleY);
|
||||||
|
|
||||||
|
drawXAxis(gc);
|
||||||
|
drawYAxis(gc);
|
||||||
|
|
||||||
|
drawData(gc);
|
||||||
|
|
||||||
|
drawYAxisLabel(gc);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Draw the X axis.
|
||||||
|
*
|
||||||
|
* @param gc
|
||||||
|
* The Graphics Context
|
||||||
|
*/
|
||||||
|
private void drawXAxis(GC gc) {
|
||||||
|
// Draw the xAxis line
|
||||||
|
gc.drawPolyline(xAxis);
|
||||||
|
|
||||||
|
// List of locations for the date labels
|
||||||
|
List<Integer> dateLocationList = new ArrayList<Integer>();
|
||||||
|
dateLocationList.add(GRAPH_BORDER); // first one
|
||||||
|
|
||||||
|
List<Date> dateList = new ArrayList<Date>();
|
||||||
|
|
||||||
|
SimpleDateFormat sdf = axisFormat.get();
|
||||||
|
|
||||||
|
TimeRange tr = graphData.getTimeRange();
|
||||||
|
dateList.add(tr.getStart()); // Add the first date
|
||||||
|
|
||||||
|
long milliRange = tr.getDuration();
|
||||||
|
long numHours = milliRange / TimeUtil.MILLIS_PER_HOUR;
|
||||||
|
|
||||||
|
millisPerPixelX = milliRange / GRAPH_WIDTH;
|
||||||
|
|
||||||
|
boolean showLine = true;
|
||||||
|
int height = 15;
|
||||||
|
long startMillis = tr.getStart().getTime();
|
||||||
|
StringBuilder buffer = new StringBuilder();
|
||||||
|
|
||||||
|
Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
|
||||||
|
for (long i = tr.getStart().getTime(); i <= tr.getEnd().getTime(); i += TimeUtil.MILLIS_PER_HOUR) {
|
||||||
|
cal.setTimeInMillis(i);
|
||||||
|
int[] tickArray = {
|
||||||
|
(int) (GRAPH_BORDER + (i - startMillis) / millisPerPixelX),
|
||||||
|
GRAPH_BORDER + GRAPH_HEIGHT,
|
||||||
|
(int) (GRAPH_BORDER + (i - startMillis) / millisPerPixelX),
|
||||||
|
GRAPH_BORDER + GRAPH_HEIGHT + height };
|
||||||
|
if (cal.get(Calendar.HOUR_OF_DAY) == 0) {
|
||||||
|
gc.setLineWidth(3);
|
||||||
|
} else {
|
||||||
|
gc.setLineWidth(1);
|
||||||
|
}
|
||||||
|
int hour = cal.get(Calendar.HOUR_OF_DAY);
|
||||||
|
|
||||||
|
if ((numHours / 24 <= 7) || (hour % 6) == 0) {
|
||||||
|
gc.drawPolyline(tickArray);
|
||||||
|
|
||||||
|
if (callback.drawGridLines()) {
|
||||||
|
boolean draw = false;
|
||||||
|
if (numHours <= 6) {
|
||||||
|
draw = true;
|
||||||
|
} else if (numHours == 12) {
|
||||||
|
if (hour % 2 == 0) {
|
||||||
|
draw = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (draw) {
|
||||||
|
int[] gridLine = new int[] {
|
||||||
|
(int) (GRAPH_BORDER + (i - startMillis)
|
||||||
|
/ millisPerPixelX),
|
||||||
|
GRAPH_BORDER + GRAPH_HEIGHT,
|
||||||
|
(int) (GRAPH_BORDER + (i - startMillis)
|
||||||
|
/ millisPerPixelX), GRAPH_BORDER };
|
||||||
|
gc.drawPolyline(gridLine);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hour == 0) {
|
||||||
|
dateLocationList.add((int) (GRAPH_BORDER + (i - startMillis)
|
||||||
|
/ millisPerPixelX));
|
||||||
|
if (!dateList.contains(cal.getTime())) {
|
||||||
|
dateList.add(cal.getTime());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
buffer.setLength(0); // Clear the buffer
|
||||||
|
int y = GRAPH_BORDER + GRAPH_HEIGHT + 20;
|
||||||
|
int hr = cal.get(Calendar.HOUR_OF_DAY);
|
||||||
|
if ((numHours <= 24) || (hour % 6 == 0 && numHours <= 168)) {
|
||||||
|
if (numHours <= 3) {
|
||||||
|
for (int j = 0; j < 60; j += 15) {
|
||||||
|
buffer.setLength(0);
|
||||||
|
int x = (int) (GRAPH_BORDER + (i - startMillis + j
|
||||||
|
* TimeUtil.MILLIS_PER_MINUTE)
|
||||||
|
/ millisPerPixelX);
|
||||||
|
if (numHours == 1
|
||||||
|
|| (numHours == 3 && (j == 0 || j == 30))) {
|
||||||
|
String hrStr = (hr < 10) ? ZERO.concat(String
|
||||||
|
.valueOf(hr)) : String.valueOf(hr);
|
||||||
|
if (j == 0) {
|
||||||
|
buffer.append(hrStr).append(COLON)
|
||||||
|
.append(MINUTE_00);
|
||||||
|
} else {
|
||||||
|
buffer.append(hrStr).append(COLON).append(j);
|
||||||
|
}
|
||||||
|
int adjustment = buffer.length() * fontAveWidth / 2
|
||||||
|
- 1;
|
||||||
|
gc.drawText(buffer.toString(), x - adjustment, y);
|
||||||
|
|
||||||
|
if (callback.drawGridLines()) {
|
||||||
|
int[] gridLineArray = {
|
||||||
|
(int) (GRAPH_BORDER + (i - startMillis + TimeUtil.MILLIS_PER_MINUTE
|
||||||
|
* j)
|
||||||
|
/ millisPerPixelX),
|
||||||
|
GRAPH_BORDER + GRAPH_HEIGHT,
|
||||||
|
(int) (GRAPH_BORDER + (i - startMillis + TimeUtil.MILLIS_PER_MINUTE
|
||||||
|
* j)
|
||||||
|
/ millisPerPixelX),
|
||||||
|
GRAPH_BORDER };
|
||||||
|
gc.drawPolyline(gridLineArray);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
int[] minorTickArray = {
|
||||||
|
(int) (GRAPH_BORDER + (i - startMillis + TimeUtil.MILLIS_PER_MINUTE
|
||||||
|
* j)
|
||||||
|
/ millisPerPixelX),
|
||||||
|
GRAPH_BORDER + GRAPH_HEIGHT,
|
||||||
|
(int) (GRAPH_BORDER + (i - startMillis + TimeUtil.MILLIS_PER_MINUTE
|
||||||
|
* j)
|
||||||
|
/ millisPerPixelX),
|
||||||
|
GRAPH_BORDER + GRAPH_HEIGHT + height - 5 };
|
||||||
|
gc.drawPolyline(minorTickArray);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
int x = (int) (GRAPH_BORDER + (i - startMillis)
|
||||||
|
/ millisPerPixelX);
|
||||||
|
String hrStr = (hr < 10) ? ZERO.concat(String.valueOf(hr))
|
||||||
|
: String.valueOf(hr);
|
||||||
|
buffer.append(hrStr);
|
||||||
|
int adjustment = buffer.length() * fontAveWidth / 2 - 1;
|
||||||
|
gc.drawText(buffer.toString(), x - adjustment, y);
|
||||||
|
|
||||||
|
if (callback.drawGridLines()) {
|
||||||
|
if ((numHours == 24 && hr % 6 == 0)
|
||||||
|
|| (numHours == 168 && hr == 0)) {
|
||||||
|
|
||||||
|
int[] gridLineArray = {
|
||||||
|
(int) (GRAPH_BORDER + (i - startMillis)
|
||||||
|
/ millisPerPixelX),
|
||||||
|
GRAPH_BORDER + GRAPH_HEIGHT,
|
||||||
|
(int) (GRAPH_BORDER + (i - startMillis)
|
||||||
|
/ millisPerPixelX), GRAPH_BORDER };
|
||||||
|
gc.setLineWidth(1);
|
||||||
|
gc.drawPolyline(gridLineArray);
|
||||||
|
gc.setLineWidth(3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (numHours == 336 && hour == 0) {
|
||||||
|
int x = (int) (GRAPH_BORDER + (i - startMillis)
|
||||||
|
/ millisPerPixelX);
|
||||||
|
buffer.append(cal.get(Calendar.MONTH) + 1);
|
||||||
|
buffer.append("/");
|
||||||
|
buffer.append(cal.get(Calendar.DAY_OF_MONTH));
|
||||||
|
int adjustment = buffer.length() * fontAveWidth / 2 - 1;
|
||||||
|
gc.drawText(buffer.toString(), x - adjustment, y);
|
||||||
|
|
||||||
|
if (callback.drawGridLines()) {
|
||||||
|
// show every other line
|
||||||
|
if (showLine) {
|
||||||
|
int[] gridLineArray = {
|
||||||
|
(int) (GRAPH_BORDER + (i - startMillis)
|
||||||
|
/ millisPerPixelX),
|
||||||
|
GRAPH_BORDER + GRAPH_HEIGHT,
|
||||||
|
(int) (GRAPH_BORDER + (i - startMillis)
|
||||||
|
/ millisPerPixelX), GRAPH_BORDER };
|
||||||
|
gc.setLineWidth(1);
|
||||||
|
gc.drawPolyline(gridLineArray);
|
||||||
|
gc.setLineWidth(3);
|
||||||
|
}
|
||||||
|
showLine = !showLine;
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if (numHours == 720) {
|
||||||
|
if (cal.get(Calendar.DAY_OF_MONTH) % 2 == 0 && hour == 0) {
|
||||||
|
int x = (int) (GRAPH_BORDER + (i - startMillis)
|
||||||
|
/ millisPerPixelX);
|
||||||
|
buffer.append(cal.get(Calendar.MONTH) + 1);
|
||||||
|
buffer.append("/");
|
||||||
|
buffer.append(cal.get(Calendar.DAY_OF_MONTH));
|
||||||
|
int adjustment = buffer.length() * fontAveWidth / 2 - 1;
|
||||||
|
gc.drawText(buffer.toString(), x - adjustment, y);
|
||||||
|
if (callback.drawGridLines()) {
|
||||||
|
if (showLine) {
|
||||||
|
int[] gridLineArray = {
|
||||||
|
(int) (GRAPH_BORDER + (i - startMillis)
|
||||||
|
/ millisPerPixelX),
|
||||||
|
GRAPH_BORDER + GRAPH_HEIGHT,
|
||||||
|
(int) (GRAPH_BORDER + (i - startMillis)
|
||||||
|
/ millisPerPixelX), GRAPH_BORDER };
|
||||||
|
gc.setLineWidth(1);
|
||||||
|
gc.drawPolyline(gridLineArray);
|
||||||
|
gc.setLineWidth(3);
|
||||||
|
}
|
||||||
|
showLine = !showLine;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dateLocationList.add(GRAPH_BORDER + GRAPH_WIDTH); // last one
|
||||||
|
|
||||||
|
int idx = 0;
|
||||||
|
if (dateLocationList.get(0) == dateLocationList.get(1)) {
|
||||||
|
dateLocationList.remove(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Lower Date label
|
||||||
|
if (numHours < 336) {
|
||||||
|
for (Date date : dateList) {
|
||||||
|
// only one date
|
||||||
|
String dateStr = sdf.format(date);
|
||||||
|
int loc1 = dateLocationList.get(idx);
|
||||||
|
int loc2 = dateLocationList.get(++idx);
|
||||||
|
if (loc2 - loc1 > dateStr.length() * fontAveWidth) {
|
||||||
|
int loc = ((loc2 + loc1) / 2)
|
||||||
|
- (((dateStr.length() * fontAveWidth) / 2) + 1);
|
||||||
|
if (loc < GRAPH_BORDER + GRAPH_WIDTH) {
|
||||||
|
gc.drawText(dateStr, loc, GRAPH_BORDER + GRAPH_HEIGHT
|
||||||
|
+ 40);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Draw the Y axis.
|
||||||
|
*
|
||||||
|
* @param gc
|
||||||
|
* The Graphics Context
|
||||||
|
*/
|
||||||
|
private void drawYAxis(GC gc) {
|
||||||
|
DecimalFormat format = numFormat.get();
|
||||||
|
|
||||||
|
gc.setLineWidth(1);
|
||||||
|
|
||||||
|
gc.drawPolyline(yAxis);
|
||||||
|
|
||||||
|
double minVal = graphData.getMinValue();
|
||||||
|
double maxVal = graphData.getMaxValue();
|
||||||
|
int numberTicks = 4;
|
||||||
|
double inc = 5;
|
||||||
|
double minScaleVal = 0;
|
||||||
|
double maxScaleVal = 10;
|
||||||
|
if (minVal != minValue || maxVal != maxValue) {
|
||||||
|
scalingManager = new ScaleManager(minVal, maxVal);
|
||||||
|
numberTicks = scalingManager.getMajorTickCount();
|
||||||
|
inc = scalingManager.getMajorTickIncrement();
|
||||||
|
|
||||||
|
minScaleVal = scalingManager.getMinScaleValue();
|
||||||
|
maxScaleVal = scalingManager.getMaxScaleValue();
|
||||||
|
}
|
||||||
|
double yVal = minScaleVal;
|
||||||
|
|
||||||
|
// Draw the axis tick marks
|
||||||
|
for (int i = 0; i < numberTicks; i++) {
|
||||||
|
int yPix = y2pixel(minScaleVal, maxScaleVal, yVal);
|
||||||
|
int[] tick = { GRAPH_BORDER, yPix, GRAPH_BORDER - 10, yPix };
|
||||||
|
gc.drawPolyline(tick);
|
||||||
|
|
||||||
|
String label = format.format(yVal);
|
||||||
|
int labelX = GRAPH_BORDER - (label.length() * fontAveWidth) - 20;
|
||||||
|
int labelY = yPix - (fontHeight / 2);
|
||||||
|
gc.drawText(label, labelX, labelY);
|
||||||
|
yVal += inc;
|
||||||
|
|
||||||
|
// Draw gridline if needed
|
||||||
|
if (callback.drawGridLines()) {
|
||||||
|
int[] gridLine = new int[] { GRAPH_BORDER, yPix,
|
||||||
|
GRAPH_BORDER + GRAPH_WIDTH, yPix };
|
||||||
|
gc.drawPolyline(gridLine);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Draw the YAxis label.
|
||||||
|
*
|
||||||
|
* @param gc
|
||||||
|
* The Graphics Context
|
||||||
|
*/
|
||||||
|
private void drawYAxisLabel(GC gc) {
|
||||||
|
String unit = this.graphData.getDisplayUnit();
|
||||||
|
StringBuilder yAxisLabel = new StringBuilder(graphTitle);
|
||||||
|
|
||||||
|
if (unit != null && !unit.equalsIgnoreCase(COUNT) && unit.length() > 0) {
|
||||||
|
yAxisLabel.append(" (").append(unit).append(")");
|
||||||
|
}
|
||||||
|
|
||||||
|
gc.setForeground(getDisplay().getSystemColor(SWT.COLOR_BLACK));
|
||||||
|
|
||||||
|
// Rotate the Y header text.
|
||||||
|
int labelInPixels = gc.getFontMetrics().getAverageCharWidth()
|
||||||
|
* yAxisLabel.length();
|
||||||
|
|
||||||
|
int yCoord = (canvasHeight / 2) + (labelInPixels / 2);
|
||||||
|
|
||||||
|
Transform t = new Transform(gc.getDevice());
|
||||||
|
t.translate(2, yCoord); // new origin
|
||||||
|
t.rotate(-90f);
|
||||||
|
gc.setTransform(t);
|
||||||
|
gc.drawString(yAxisLabel.toString(), 0, 0, true);
|
||||||
|
|
||||||
|
t.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Draw the data on the canvas.
|
||||||
|
*
|
||||||
|
* @param gc
|
||||||
|
* The Graphics Context
|
||||||
|
*/
|
||||||
|
private void drawData(GC gc) {
|
||||||
|
double maxScaleVal = scalingManager.getMaxScaleValue();
|
||||||
|
double minScaleVal = scalingManager.getMinScaleValue();
|
||||||
|
Map<String, RGB> groupSettings = callback.getGroupSettings();
|
||||||
|
|
||||||
|
for (String key : graphData.getKeysWithData()) {
|
||||||
|
if (groupSettings.containsKey(key)) {
|
||||||
|
Color color = new Color(getDisplay(), groupSettings.get(key));
|
||||||
|
gc.setForeground(color);
|
||||||
|
gc.setBackground(color);
|
||||||
|
if (groupSettings.containsKey(key)) {
|
||||||
|
|
||||||
|
List<Integer> pointList = new ArrayList<Integer>();
|
||||||
|
if (!rectangleMap.containsKey(key)) {
|
||||||
|
rectangleMap.put(key, new ArrayList<Rectangle>());
|
||||||
|
}
|
||||||
|
rectangleMap.get(key).clear();
|
||||||
|
|
||||||
|
StatsData data = graphData.getStatsData(key);
|
||||||
|
|
||||||
|
if (data != null) {
|
||||||
|
// Loop over all group members
|
||||||
|
List<DataPoint> dataMap = data.getData(key);
|
||||||
|
long startMillis = graphData.getTimeRange().getStart()
|
||||||
|
.getTime();
|
||||||
|
int lastXpix = -999;
|
||||||
|
int lastYpix = -999;
|
||||||
|
for (DataPoint point : dataMap) {
|
||||||
|
long x = point.getX();
|
||||||
|
double y = point.getY();
|
||||||
|
int yPix = y2pixel(minScaleVal, maxScaleVal, y);
|
||||||
|
int xPix = (int) ((x - startMillis)
|
||||||
|
/ millisPerPixelX + GRAPH_BORDER);
|
||||||
|
|
||||||
|
if (xPix > GRAPH_BORDER + GRAPH_WIDTH) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
pointList.add(xPix);
|
||||||
|
pointList.add(yPix);
|
||||||
|
Rectangle rect = new Rectangle(xPix - 3, yPix - 3,
|
||||||
|
6, 6);
|
||||||
|
rectangleMap.get(key).add(rect);
|
||||||
|
if (lastXpix != -999) {
|
||||||
|
if (callback.drawDataLines()) {
|
||||||
|
gc.drawLine(lastXpix, lastYpix, xPix, yPix);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
lastXpix = xPix;
|
||||||
|
lastYpix = yPix;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < rectangleMap.get(key).size(); i++) {
|
||||||
|
Rectangle rect = rectangleMap.get(key).get(i);
|
||||||
|
gc.setForeground(color);
|
||||||
|
|
||||||
|
gc.fillRectangle(rect);
|
||||||
|
gc.setForeground(getDisplay().getSystemColor(
|
||||||
|
SWT.COLOR_BLACK));
|
||||||
|
gc.drawRectangle(rect);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Y Value to pixel conversion.
|
||||||
|
*
|
||||||
|
* @param yMin
|
||||||
|
* The smallest y value
|
||||||
|
* @param yMax
|
||||||
|
* The largest y value
|
||||||
|
* @param y
|
||||||
|
* The y value
|
||||||
|
* @return the pixel corresponding to the y value
|
||||||
|
*/
|
||||||
|
private int y2pixel(double yMin, double yMax, double y) {
|
||||||
|
double yDiff = yMax - yMin;
|
||||||
|
double yValue = (GRAPH_HEIGHT / yDiff) * (y - yMin);
|
||||||
|
return (int) (GRAPH_HEIGHT - Math.round(yValue) + GRAPH_BORDER);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mouse move event hanler.
|
||||||
|
*
|
||||||
|
* @param e
|
||||||
|
* MouseEvent object
|
||||||
|
*/
|
||||||
|
private void handleMouseMoveEvent(MouseEvent e) {
|
||||||
|
int x = e.x;
|
||||||
|
int y = e.y;
|
||||||
|
final String colon = ": ";
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
GraphData graphData = callback.getGraphData();
|
||||||
|
if (graphData == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for (String key : graphData.getKeys()) {
|
||||||
|
int idx = 0;
|
||||||
|
if (rectangleMap.containsKey(key)) {
|
||||||
|
for (Rectangle rect : rectangleMap.get(key)) {
|
||||||
|
if (callback.getGroupSettings().containsKey(key)) {
|
||||||
|
// if true then data are on the graph
|
||||||
|
if (rect.contains(x, y)) {
|
||||||
|
if (sb.length() > 0) {
|
||||||
|
sb.append("\n");
|
||||||
|
}
|
||||||
|
sb.append(key).append(colon);
|
||||||
|
DataPoint point = graphData.getStatsData(key)
|
||||||
|
.getData(key).get(idx);
|
||||||
|
sb.append(point.getSampleText());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
idx++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle bounds = this.getBounds();
|
||||||
|
Point pos = getShell().toDisplay(bounds.x + x + 15, bounds.y + y + 15);
|
||||||
|
if (sb.length() > 0) {
|
||||||
|
showTooltip(getShell(), pos.x, pos.y, sb.toString());
|
||||||
|
} else {
|
||||||
|
if (tooltip != null && !tooltip.isDisposed()) {
|
||||||
|
this.tooltip.dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show the "tooltip" mouseover.
|
||||||
|
*
|
||||||
|
* @param parent
|
||||||
|
* @param x
|
||||||
|
* @param y
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private Shell showTooltip(Shell parent, int x, int y, String text) {
|
||||||
|
if (tooltip != null && !tooltip.isDisposed()) {
|
||||||
|
tooltip.dispose();
|
||||||
|
}
|
||||||
|
tooltip = new Shell(parent, SWT.TOOL | SWT.ON_TOP);
|
||||||
|
tooltip.setLayout(new GridLayout());
|
||||||
|
|
||||||
|
tooltip.setBackground(tooltip.getDisplay().getSystemColor(
|
||||||
|
SWT.COLOR_INFO_BACKGROUND));
|
||||||
|
tooltip.setBackgroundMode(SWT.INHERIT_FORCE);
|
||||||
|
|
||||||
|
Label lbContent = new Label(tooltip, SWT.NONE);
|
||||||
|
lbContent.setText(text);
|
||||||
|
|
||||||
|
Point lbContentSize = lbContent.computeSize(SWT.DEFAULT, SWT.DEFAULT);
|
||||||
|
|
||||||
|
int width = lbContentSize.x + 10;
|
||||||
|
int height = lbContentSize.y + 10;
|
||||||
|
|
||||||
|
tooltip.setBounds(x, y, width, height);
|
||||||
|
tooltip.setVisible(true);
|
||||||
|
return tooltip;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
*
|
||||||
|
* @see org.eclipse.swt.widgets.Widget#dispose()
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void dispose() {
|
||||||
|
if (this.canvasFont != null && !canvasFont.isDisposed()) {
|
||||||
|
this.canvasFont.dispose();
|
||||||
|
}
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the graph data.
|
||||||
|
*
|
||||||
|
* @param graphData
|
||||||
|
* The GraphData object
|
||||||
|
*/
|
||||||
|
public void setGraphData(GraphData graphData) {
|
||||||
|
this.graphData = graphData;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,583 @@
|
||||||
|
/**
|
||||||
|
* This software was developed and / or modified by Raytheon Company,
|
||||||
|
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||||
|
*
|
||||||
|
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||||
|
* This software product contains export-restricted data whose
|
||||||
|
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||||
|
* to non-U.S. persons whether in the United States or abroad requires
|
||||||
|
* an export license or other authorization.
|
||||||
|
*
|
||||||
|
* Contractor Name: Raytheon Company
|
||||||
|
* Contractor Address: 6825 Pine Street, Suite 340
|
||||||
|
* Mail Stop B8
|
||||||
|
* Omaha, NE 68106
|
||||||
|
* 402.291.0100
|
||||||
|
*
|
||||||
|
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||||
|
* further licensing information.
|
||||||
|
**/
|
||||||
|
package com.raytheon.uf.viz.stats.ui;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.eclipse.swt.SWT;
|
||||||
|
import org.eclipse.swt.events.SelectionAdapter;
|
||||||
|
import org.eclipse.swt.events.SelectionEvent;
|
||||||
|
import org.eclipse.swt.graphics.GC;
|
||||||
|
import org.eclipse.swt.graphics.Image;
|
||||||
|
import org.eclipse.swt.graphics.ImageData;
|
||||||
|
import org.eclipse.swt.graphics.ImageLoader;
|
||||||
|
import org.eclipse.swt.graphics.RGB;
|
||||||
|
import org.eclipse.swt.layout.GridData;
|
||||||
|
import org.eclipse.swt.layout.GridLayout;
|
||||||
|
import org.eclipse.swt.widgets.Button;
|
||||||
|
import org.eclipse.swt.widgets.Composite;
|
||||||
|
import org.eclipse.swt.widgets.Display;
|
||||||
|
import org.eclipse.swt.widgets.FileDialog;
|
||||||
|
import org.eclipse.swt.widgets.Layout;
|
||||||
|
import org.eclipse.swt.widgets.Menu;
|
||||||
|
import org.eclipse.swt.widgets.MenuItem;
|
||||||
|
import org.eclipse.swt.widgets.MessageBox;
|
||||||
|
import org.eclipse.swt.widgets.Shell;
|
||||||
|
|
||||||
|
import com.raytheon.uf.common.stats.GraphDataRequest;
|
||||||
|
import com.raytheon.uf.common.stats.GraphDataResponse;
|
||||||
|
import com.raytheon.uf.common.stats.data.GraphData;
|
||||||
|
import com.raytheon.uf.common.status.IUFStatusHandler;
|
||||||
|
import com.raytheon.uf.common.status.UFStatus;
|
||||||
|
import com.raytheon.uf.common.status.UFStatus.Priority;
|
||||||
|
import com.raytheon.uf.common.time.TimeRange;
|
||||||
|
import com.raytheon.uf.viz.core.exception.VizException;
|
||||||
|
import com.raytheon.uf.viz.core.requests.ThriftClient;
|
||||||
|
import com.raytheon.viz.ui.dialogs.CaveSWTDialog;
|
||||||
|
import com.raytheon.viz.ui.widgets.duallist.ButtonImages;
|
||||||
|
import com.raytheon.viz.ui.widgets.duallist.ButtonImages.ButtonImage;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Graph Data Structure.
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
*
|
||||||
|
* SOFTWARE HISTORY
|
||||||
|
*
|
||||||
|
* Date Ticket# Engineer Description
|
||||||
|
* ------------ ---------- ----------- --------------------------
|
||||||
|
* Oct 3, 2012 728 mpduff Initial creation
|
||||||
|
*
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* @author mpduff
|
||||||
|
* @version 1.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class StatsGraphDlg extends CaveSWTDialog implements IStatsDisplay,
|
||||||
|
IStatsGroup {
|
||||||
|
private final IUFStatusHandler statusHandler = UFStatus
|
||||||
|
.getHandler(StatsGraphDlg.class);
|
||||||
|
|
||||||
|
/** Data Request parameters */
|
||||||
|
public enum REQUEST_PARAMETER {
|
||||||
|
FullLeft, HalfLeft, HalfRight, FullRight
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Callback */
|
||||||
|
private final IStatsControl callback;
|
||||||
|
|
||||||
|
/** The graph canvas */
|
||||||
|
private StatsDisplayCanvas displayCanvas;
|
||||||
|
|
||||||
|
/** The Graph data object */
|
||||||
|
private GraphData graphData;
|
||||||
|
|
||||||
|
/** The graph title */
|
||||||
|
private String graphTitle;
|
||||||
|
|
||||||
|
/** Menu bar */
|
||||||
|
private Menu menuBar;
|
||||||
|
|
||||||
|
/** Save Menu Item */
|
||||||
|
private MenuItem saveMI;
|
||||||
|
|
||||||
|
/** Exit Menu item */
|
||||||
|
private MenuItem exitMI;
|
||||||
|
|
||||||
|
/** Show control dialog menu item */
|
||||||
|
private MenuItem controlDisplayMI;
|
||||||
|
|
||||||
|
/** Show grid lines menu item */
|
||||||
|
private MenuItem gridLinesMI;
|
||||||
|
|
||||||
|
/** Draw grid lines flag */
|
||||||
|
private boolean drawGridLines = true;
|
||||||
|
|
||||||
|
/** Draw data lines flag */
|
||||||
|
private boolean drawDataLines = true;
|
||||||
|
|
||||||
|
/** Draw data items menu item */
|
||||||
|
private MenuItem dataLinesMI;
|
||||||
|
|
||||||
|
/** Grouping composite */
|
||||||
|
private GroupingComp groupComp;
|
||||||
|
|
||||||
|
/** Group Settings Map */
|
||||||
|
private Map<String, RGB> groupSettingsMap;
|
||||||
|
|
||||||
|
/** List of groups */
|
||||||
|
private List<String> groupList;
|
||||||
|
|
||||||
|
/** Category of stats data */
|
||||||
|
private String category;
|
||||||
|
|
||||||
|
/** Event type id of data */
|
||||||
|
private String typeID;
|
||||||
|
|
||||||
|
/** Data type (field) of the data */
|
||||||
|
private String dataTypeID;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor.
|
||||||
|
*
|
||||||
|
* @param parent
|
||||||
|
* Parent Shell
|
||||||
|
* @param callback
|
||||||
|
* Callback
|
||||||
|
*/
|
||||||
|
public StatsGraphDlg(Shell parent, IStatsControl callback) {
|
||||||
|
super(parent, SWT.DIALOG_TRIM | SWT.MIN, CAVE.DO_NOT_BLOCK
|
||||||
|
| CAVE.INDEPENDENT_SHELL);
|
||||||
|
this.callback = callback;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected Layout constructShellLayout() {
|
||||||
|
GridLayout mainLayout = new GridLayout(1, true);
|
||||||
|
mainLayout.verticalSpacing = 0;
|
||||||
|
mainLayout.marginHeight = 0;
|
||||||
|
mainLayout.marginWidth = 0;
|
||||||
|
return mainLayout;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected Object constructShellLayoutData() {
|
||||||
|
return new GridData(SWT.FILL, SWT.FILL, true, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected void initializeComponents(Shell shell) {
|
||||||
|
createMenus();
|
||||||
|
|
||||||
|
GridData gd = new GridData(SWT.FILL, SWT.FILL, false, true);
|
||||||
|
GridLayout gl = new GridLayout(2, false);
|
||||||
|
Composite mainComp = new Composite(shell, SWT.NONE);
|
||||||
|
mainComp.setLayout(gl);
|
||||||
|
mainComp.setLayoutData(gd);
|
||||||
|
|
||||||
|
gd = new GridData(SWT.CENTER, SWT.DEFAULT, false, true);
|
||||||
|
gl = new GridLayout(1, false);
|
||||||
|
Composite leftComp = new Composite(mainComp, SWT.NONE);
|
||||||
|
leftComp.setLayout(gl);
|
||||||
|
leftComp.setLayoutData(gd);
|
||||||
|
|
||||||
|
createCanvas(leftComp);
|
||||||
|
|
||||||
|
gd = new GridData(SWT.FILL, SWT.FILL, false, true);
|
||||||
|
gl = new GridLayout(1, false);
|
||||||
|
groupComp = new GroupingComp(mainComp, SWT.BORDER, graphData, this);
|
||||||
|
groupComp.setLayout(gl);
|
||||||
|
groupComp.setLayoutData(gd);
|
||||||
|
|
||||||
|
gd = new GridData(SWT.CENTER, SWT.DEFAULT, false, true);
|
||||||
|
gl = new GridLayout(4, false);
|
||||||
|
Composite btnComp = new Composite(leftComp, SWT.NONE);
|
||||||
|
btnComp.setLayout(gl);
|
||||||
|
btnComp.setLayoutData(gd);
|
||||||
|
|
||||||
|
ButtonImages btnImg = new ButtonImages(leftComp);
|
||||||
|
|
||||||
|
final int buttonWidth = 45;
|
||||||
|
GridData btnData = new GridData(buttonWidth, SWT.DEFAULT);
|
||||||
|
Button fullLeftBtn = new Button(btnComp, SWT.PUSH);
|
||||||
|
fullLeftBtn.setImage(btnImg.getImage(ButtonImage.RemoveAll));
|
||||||
|
fullLeftBtn.setLayoutData(btnData);
|
||||||
|
fullLeftBtn
|
||||||
|
.setToolTipText("Moves the display a full time period to the left");
|
||||||
|
fullLeftBtn.addSelectionListener(new SelectionAdapter() {
|
||||||
|
@Override
|
||||||
|
public void widgetSelected(SelectionEvent e) {
|
||||||
|
requestRedraw(REQUEST_PARAMETER.FullLeft);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
btnData = new GridData(buttonWidth, SWT.DEFAULT);
|
||||||
|
Button halfLeftBtn = new Button(btnComp, SWT.PUSH);
|
||||||
|
halfLeftBtn.setImage(btnImg.getImage(ButtonImage.Remove));
|
||||||
|
halfLeftBtn.setLayoutData(btnData);
|
||||||
|
halfLeftBtn
|
||||||
|
.setToolTipText("Moves the display half a time period to the left");
|
||||||
|
halfLeftBtn.addSelectionListener(new SelectionAdapter() {
|
||||||
|
@Override
|
||||||
|
public void widgetSelected(SelectionEvent e) {
|
||||||
|
requestRedraw(REQUEST_PARAMETER.HalfLeft);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
btnData = new GridData(buttonWidth, SWT.DEFAULT);
|
||||||
|
Button halfRightBtn = new Button(btnComp, SWT.PUSH);
|
||||||
|
halfRightBtn.setImage(btnImg.getImage(ButtonImage.Add));
|
||||||
|
halfRightBtn.setLayoutData(btnData);
|
||||||
|
halfRightBtn
|
||||||
|
.setToolTipText("Moves the display half a time period to the right");
|
||||||
|
halfRightBtn.addSelectionListener(new SelectionAdapter() {
|
||||||
|
@Override
|
||||||
|
public void widgetSelected(SelectionEvent e) {
|
||||||
|
requestRedraw(REQUEST_PARAMETER.HalfRight);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
btnData = new GridData(buttonWidth, SWT.DEFAULT);
|
||||||
|
Button fullRightBtn = new Button(btnComp, SWT.PUSH);
|
||||||
|
fullRightBtn.setImage(btnImg.getImage(ButtonImage.AddAll));
|
||||||
|
fullRightBtn.setLayoutData(btnData);
|
||||||
|
fullRightBtn
|
||||||
|
.setToolTipText("Moves the display a full time period to the right");
|
||||||
|
fullRightBtn.addSelectionListener(new SelectionAdapter() {
|
||||||
|
@Override
|
||||||
|
public void widgetSelected(SelectionEvent e) {
|
||||||
|
requestRedraw(REQUEST_PARAMETER.FullRight);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
shell.setMenuBar(menuBar);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create the menus
|
||||||
|
*/
|
||||||
|
private void createMenus() {
|
||||||
|
menuBar = new Menu(shell, SWT.BAR);
|
||||||
|
|
||||||
|
MenuItem fileMenuItem = new MenuItem(menuBar, SWT.CASCADE);
|
||||||
|
fileMenuItem.setText("File");
|
||||||
|
|
||||||
|
Menu fileMenu = new Menu(menuBar);
|
||||||
|
fileMenuItem.setMenu(fileMenu);
|
||||||
|
|
||||||
|
saveMI = new MenuItem(fileMenu, SWT.NONE);
|
||||||
|
saveMI.setText("&Save\tCtrl+S");
|
||||||
|
saveMI.setAccelerator(SWT.CTRL + 'S');
|
||||||
|
saveMI.addSelectionListener(new SelectionAdapter() {
|
||||||
|
@Override
|
||||||
|
public void widgetSelected(SelectionEvent event) {
|
||||||
|
saveGraph();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
exitMI = new MenuItem(fileMenu, SWT.NONE);
|
||||||
|
exitMI.setText("&Quit\tCtrl+Q");
|
||||||
|
exitMI.setAccelerator(SWT.CTRL + 'Q');
|
||||||
|
exitMI.addSelectionListener(new SelectionAdapter() {
|
||||||
|
@Override
|
||||||
|
public void widgetSelected(SelectionEvent event) {
|
||||||
|
shell.dispose();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
MenuItem graphMenuItem = new MenuItem(menuBar, SWT.CASCADE);
|
||||||
|
graphMenuItem.setText("Graph");
|
||||||
|
|
||||||
|
Menu graphMenu = new Menu(menuBar);
|
||||||
|
graphMenuItem.setMenu(graphMenu);
|
||||||
|
|
||||||
|
controlDisplayMI = new MenuItem(graphMenu, SWT.NONE);
|
||||||
|
controlDisplayMI.setText("Show &Display Control\tCtrl+D");
|
||||||
|
controlDisplayMI.setAccelerator(SWT.CTRL + 'D');
|
||||||
|
controlDisplayMI.addSelectionListener(new SelectionAdapter() {
|
||||||
|
@Override
|
||||||
|
public void widgetSelected(SelectionEvent event) {
|
||||||
|
callback.showControl();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
gridLinesMI = new MenuItem(graphMenu, SWT.CHECK);
|
||||||
|
gridLinesMI.setText("Display Grid Lines");
|
||||||
|
gridLinesMI.setSelection(true);
|
||||||
|
gridLinesMI.addSelectionListener(new SelectionAdapter() {
|
||||||
|
@Override
|
||||||
|
public void widgetSelected(SelectionEvent event) {
|
||||||
|
drawGridLines = gridLinesMI.getSelection();
|
||||||
|
displayCanvas.redraw();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
dataLinesMI = new MenuItem(graphMenu, SWT.CHECK);
|
||||||
|
dataLinesMI.setText("Display Data Lines");
|
||||||
|
dataLinesMI.setSelection(true);
|
||||||
|
dataLinesMI.addSelectionListener(new SelectionAdapter() {
|
||||||
|
@Override
|
||||||
|
public void widgetSelected(SelectionEvent event) {
|
||||||
|
drawDataLines = dataLinesMI.getSelection();
|
||||||
|
displayCanvas.redraw();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create the canvas.
|
||||||
|
*
|
||||||
|
* @param comp
|
||||||
|
* Composite holding the canvas
|
||||||
|
*/
|
||||||
|
private void createCanvas(Composite comp) {
|
||||||
|
Composite canvasComp = new Composite(comp, SWT.BORDER);
|
||||||
|
GridLayout gl = new GridLayout(1, false);
|
||||||
|
gl.verticalSpacing = 0;
|
||||||
|
gl.horizontalSpacing = 0;
|
||||||
|
gl.marginHeight = 0;
|
||||||
|
gl.marginWidth = 0;
|
||||||
|
GridData gd = new GridData(SWT.FILL, SWT.FILL, true, true);
|
||||||
|
canvasComp.setLayoutData(gd);
|
||||||
|
canvasComp.setLayout(gl);
|
||||||
|
|
||||||
|
displayCanvas = new StatsDisplayCanvas(canvasComp, this, graphTitle);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the GraphData object.
|
||||||
|
*
|
||||||
|
* @param graphData
|
||||||
|
*/
|
||||||
|
public void setGraphData(GraphData graphData) {
|
||||||
|
this.graphData = graphData;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public GraphData getGraphData() {
|
||||||
|
return this.graphData;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the title.
|
||||||
|
*
|
||||||
|
* @param title
|
||||||
|
*/
|
||||||
|
public void setTitle(String title) {
|
||||||
|
setText(title);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the graph title.
|
||||||
|
*
|
||||||
|
* @param graphTitle
|
||||||
|
*/
|
||||||
|
public void setGraphTitle(String graphTitle) {
|
||||||
|
this.graphTitle = graphTitle;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Open a file dialog for saving the canvas.
|
||||||
|
*/
|
||||||
|
private void saveGraph() {
|
||||||
|
FileDialog dialog = new FileDialog(shell, SWT.SAVE);
|
||||||
|
String filename = dialog.open();
|
||||||
|
if (filename == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
saveCanvas(filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Captures the canvas and saves the result into a file in a format
|
||||||
|
* determined by the filename extension .
|
||||||
|
*
|
||||||
|
* @param control
|
||||||
|
* The control to save
|
||||||
|
* @param fileName
|
||||||
|
* The name of the image to be saved
|
||||||
|
*/
|
||||||
|
public void saveCanvas(String filename) {
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
Display display = displayCanvas.getDisplay();
|
||||||
|
Image image = new Image(display, displayCanvas.getBounds().width,
|
||||||
|
displayCanvas.getBounds().height);
|
||||||
|
GC gc = new GC(image);
|
||||||
|
|
||||||
|
displayCanvas.drawCanvas(gc);
|
||||||
|
|
||||||
|
/* Default to PNG */
|
||||||
|
int style = SWT.IMAGE_PNG;
|
||||||
|
|
||||||
|
if ((filename.endsWith(".jpg") == true) || filename.endsWith("jpeg")) {
|
||||||
|
style = SWT.IMAGE_JPEG;
|
||||||
|
} else if (filename.endsWith(".bmp") == true) {
|
||||||
|
style = SWT.IMAGE_BMP;
|
||||||
|
} else {
|
||||||
|
filename += ".png";
|
||||||
|
}
|
||||||
|
|
||||||
|
ImageLoader loader = new ImageLoader();
|
||||||
|
loader.data = new ImageData[] { image.getImageData() };
|
||||||
|
loader.save(filename, style);
|
||||||
|
|
||||||
|
sb.setLength(0);
|
||||||
|
image.dispose();
|
||||||
|
gc.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Request the graph be redrawn with a new time range.
|
||||||
|
*
|
||||||
|
* @param parameter
|
||||||
|
* The amount of time to move
|
||||||
|
*/
|
||||||
|
private void requestRedraw(REQUEST_PARAMETER parameter) {
|
||||||
|
TimeRange tr = this.graphData.getTimeRange();
|
||||||
|
long dur = tr.getDuration();
|
||||||
|
long newStart;
|
||||||
|
long newEnd;
|
||||||
|
long start;
|
||||||
|
long end;
|
||||||
|
|
||||||
|
switch (parameter) {
|
||||||
|
case FullLeft:
|
||||||
|
start = tr.getStart().getTime();
|
||||||
|
newStart = start - dur;
|
||||||
|
newEnd = newStart + dur;
|
||||||
|
break;
|
||||||
|
case HalfLeft:
|
||||||
|
start = tr.getStart().getTime();
|
||||||
|
newStart = start - dur / 2;
|
||||||
|
newEnd = newStart + dur;
|
||||||
|
break;
|
||||||
|
case HalfRight:
|
||||||
|
start = tr.getStart().getTime();
|
||||||
|
newStart = start + dur / 2;
|
||||||
|
newEnd = newStart + dur;
|
||||||
|
break;
|
||||||
|
case FullRight:
|
||||||
|
end = tr.getEnd().getTime();
|
||||||
|
newStart = end;
|
||||||
|
newEnd = newStart + dur;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
GraphDataRequest request = new GraphDataRequest();
|
||||||
|
request.setGrouping(this.groupList);
|
||||||
|
request.setCategory(this.category);
|
||||||
|
request.setEventType(typeID);
|
||||||
|
request.setDataType(dataTypeID);
|
||||||
|
request.setField(dataTypeID);
|
||||||
|
TimeRange newTimeRange = new TimeRange(newStart, newEnd);
|
||||||
|
request.setTimeRange(newTimeRange);
|
||||||
|
request.setTimeStep(5);
|
||||||
|
try {
|
||||||
|
GraphDataResponse response = (GraphDataResponse) ThriftClient
|
||||||
|
.sendRequest(request);
|
||||||
|
GraphData localGraphData = response.getGraphData();
|
||||||
|
if (localGraphData == null
|
||||||
|
|| localGraphData.getStatsDataMap() == null
|
||||||
|
|| localGraphData.getStatsDataMap().size() == 0) {
|
||||||
|
MessageBox messageDialog = new MessageBox(getShell(),
|
||||||
|
SWT.ICON_INFORMATION);
|
||||||
|
messageDialog.setText("No Data Available");
|
||||||
|
messageDialog
|
||||||
|
.setMessage("No data available for the time range selected.");
|
||||||
|
messageDialog.open();
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.graphData = localGraphData;
|
||||||
|
this.displayCanvas.setGraphData(graphData);
|
||||||
|
this.displayCanvas.redraw();
|
||||||
|
} catch (VizException e) {
|
||||||
|
this.statusHandler.handle(Priority.ERROR, "Error Requesting Data",
|
||||||
|
e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public boolean drawGridLines() {
|
||||||
|
return this.drawGridLines;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public boolean drawDataLines() {
|
||||||
|
return this.drawDataLines;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void setGroupData(Map<String, RGB> groupSettingsMap) {
|
||||||
|
this.groupSettingsMap = groupSettingsMap;
|
||||||
|
displayCanvas.redraw();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Map<String, RGB> getGroupSettings() {
|
||||||
|
return this.groupSettingsMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the groups.
|
||||||
|
*
|
||||||
|
* @param groupList
|
||||||
|
* List of groups
|
||||||
|
*/
|
||||||
|
public void setGrouping(List<String> groupList) {
|
||||||
|
this.groupList = groupList;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the category.
|
||||||
|
*
|
||||||
|
* @param category
|
||||||
|
*/
|
||||||
|
public void setCategory(String category) {
|
||||||
|
this.category = category;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the event type.
|
||||||
|
*
|
||||||
|
* @param typeID
|
||||||
|
*/
|
||||||
|
public void setEventType(String typeID) {
|
||||||
|
this.typeID = typeID;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the data type id.
|
||||||
|
*
|
||||||
|
* @param dataTypeID
|
||||||
|
*/
|
||||||
|
public void setDataType(String dataTypeID) {
|
||||||
|
this.dataTypeID = dataTypeID;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,202 @@
|
||||||
|
/**
|
||||||
|
* This software was developed and / or modified by Raytheon Company,
|
||||||
|
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||||
|
*
|
||||||
|
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||||
|
* This software product contains export-restricted data whose
|
||||||
|
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||||
|
* to non-U.S. persons whether in the United States or abroad requires
|
||||||
|
* an export license or other authorization.
|
||||||
|
*
|
||||||
|
* Contractor Name: Raytheon Company
|
||||||
|
* Contractor Address: 6825 Pine Street, Suite 340
|
||||||
|
* Mail Stop B8
|
||||||
|
* Omaha, NE 68106
|
||||||
|
* 402.291.0100
|
||||||
|
*
|
||||||
|
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||||
|
* further licensing information.
|
||||||
|
**/
|
||||||
|
package com.raytheon.uf.viz.stats.utils;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.TreeMap;
|
||||||
|
|
||||||
|
import com.google.common.annotations.VisibleForTesting;
|
||||||
|
import com.raytheon.uf.common.stats.data.StatsEventData;
|
||||||
|
import com.raytheon.uf.common.stats.xml.StatisticsAggregate;
|
||||||
|
import com.raytheon.uf.common.stats.xml.StatisticsConfig;
|
||||||
|
import com.raytheon.uf.common.stats.xml.StatisticsEvent;
|
||||||
|
import com.raytheon.uf.common.stats.xml.StatisticsGroup;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Utility class for the Statistics UI.
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
*
|
||||||
|
* SOFTWARE HISTORY
|
||||||
|
*
|
||||||
|
* Date Ticket# Engineer Description
|
||||||
|
* ------------ ---------- ----------- --------------------------
|
||||||
|
* Nov 8, 2012 728 mpduff Initial creation
|
||||||
|
*
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* @author mpduff
|
||||||
|
* @version 1.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class StatsUiUtils {
|
||||||
|
/** List of statistics configuration objects */
|
||||||
|
private List<StatisticsConfig> configList;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Map of category -> Map of event type -> event type object
|
||||||
|
*/
|
||||||
|
private final Map<String, Map<String, StatsEventData>> eventMap = new HashMap<String, Map<String, StatsEventData>>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*/
|
||||||
|
public StatsUiUtils() {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate the configuration objects.
|
||||||
|
*
|
||||||
|
* @param configList
|
||||||
|
*/
|
||||||
|
public void generateData(List<StatisticsConfig> configList) {
|
||||||
|
this.configList = configList;
|
||||||
|
|
||||||
|
for (StatisticsConfig config: configList) {
|
||||||
|
processConfig(config);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Process a configuration object.
|
||||||
|
*
|
||||||
|
* @param config configuration object
|
||||||
|
*/
|
||||||
|
@VisibleForTesting
|
||||||
|
void processConfig(StatisticsConfig config) {
|
||||||
|
for (StatisticsEvent event: config.getEvents()) {
|
||||||
|
processEvent(event);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Process a configuration event object
|
||||||
|
*
|
||||||
|
* @param event event config object
|
||||||
|
*/
|
||||||
|
@VisibleForTesting
|
||||||
|
void processEvent(StatisticsEvent event) {
|
||||||
|
if (!eventMap.containsKey(event.getCategory())) {
|
||||||
|
eventMap.put(event.getCategory(), new HashMap<String, StatsEventData>());
|
||||||
|
}
|
||||||
|
|
||||||
|
StatsEventData eventData = new StatsEventData();
|
||||||
|
|
||||||
|
eventData.setDisplayName(event.getDisplayName());
|
||||||
|
eventData.setType(event.getType());
|
||||||
|
List<StatisticsAggregate> attributeList = event.getAggregateList();
|
||||||
|
for (StatisticsAggregate attribute: attributeList) {
|
||||||
|
eventData.addAttribute(attribute.getDisplayName());
|
||||||
|
}
|
||||||
|
|
||||||
|
for (StatisticsGroup group: event.getGroupList()) {
|
||||||
|
eventData.addGroup(group.getDisplayName(), group.getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
eventMap.get(event.getCategory()).put(eventData.getType(), eventData);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the event types for this category.
|
||||||
|
*
|
||||||
|
* @param category The category
|
||||||
|
* @return map of event display names -> event id
|
||||||
|
*/
|
||||||
|
@VisibleForTesting
|
||||||
|
public Map<String, String> getEventTypes(String category) {
|
||||||
|
Map<String, StatsEventData> eventsMap = eventMap.get(category);
|
||||||
|
Map<String, String> typeMap = new TreeMap<String, String>();
|
||||||
|
for (String key: eventsMap.keySet()) {
|
||||||
|
StatsEventData data = eventsMap.get(key);
|
||||||
|
typeMap.put(data.getDisplayName(), data.getType());
|
||||||
|
}
|
||||||
|
return typeMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the attributes/data types for the given category and event.
|
||||||
|
*
|
||||||
|
* @param category The category
|
||||||
|
* @param type The event type
|
||||||
|
* @return Map of attribute display name -> field
|
||||||
|
*/
|
||||||
|
@VisibleForTesting
|
||||||
|
public Map<String, String> getEventAttributes(String category, String type) {
|
||||||
|
Map<String, String> attMap = new TreeMap<String, String>();
|
||||||
|
for (StatisticsConfig config: configList) {
|
||||||
|
for (StatisticsEvent event: config.getEvents()) {
|
||||||
|
if (event.getCategory().equals(category) && event.getDisplayName().equals(type)) {
|
||||||
|
for (StatisticsAggregate agg: event.getAggregateList()) {
|
||||||
|
attMap.put(agg.getDisplayName(), agg.getField());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return attMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the eventMap
|
||||||
|
*/
|
||||||
|
@VisibleForTesting
|
||||||
|
public Map<String, Map<String, StatsEventData>> getEventMap() {
|
||||||
|
return eventMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the StatsEventData object for the given category and event type.
|
||||||
|
*
|
||||||
|
* @param category category
|
||||||
|
* @param type event type
|
||||||
|
* @return StatsEventData object
|
||||||
|
*/
|
||||||
|
@VisibleForTesting
|
||||||
|
public StatsEventData getEventData(String category, String type) {
|
||||||
|
return eventMap.get(category).get(type);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the aggregate config file for the given category, event type, and aggregate display name
|
||||||
|
*
|
||||||
|
* @param category category
|
||||||
|
* @param typeID event type id
|
||||||
|
* @param attributeDisplayName attribut display name
|
||||||
|
* @return StatisticsAggregate object
|
||||||
|
*/
|
||||||
|
public StatisticsAggregate getAggregateConfig(String category,
|
||||||
|
String typeID, String attributeDisplayName) {
|
||||||
|
for (StatisticsConfig config : configList) {
|
||||||
|
for (StatisticsEvent event: config.getEvents()) {
|
||||||
|
if (event.getCategory().equals(category) && event.getType().equals(typeID)) {
|
||||||
|
for (StatisticsAggregate agg: event.getAggregateList()) {
|
||||||
|
if (agg.getDisplayName().equals(attributeDisplayName)) {
|
||||||
|
return agg;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
|
@ -78,6 +78,30 @@
|
||||||
name="afterNewGroup"
|
name="afterNewGroup"
|
||||||
visible="true">
|
visible="true">
|
||||||
</separator>
|
</separator>
|
||||||
|
<separator
|
||||||
|
name="group1"
|
||||||
|
visible="true">
|
||||||
|
</separator>
|
||||||
|
<separator
|
||||||
|
name="group2"
|
||||||
|
visible="true">
|
||||||
|
</separator>
|
||||||
|
<separator
|
||||||
|
name="group3"
|
||||||
|
visible="true">
|
||||||
|
</separator>
|
||||||
|
<separator
|
||||||
|
name="group4"
|
||||||
|
visible="true">
|
||||||
|
</separator>
|
||||||
|
<separator
|
||||||
|
name="group5"
|
||||||
|
visible="true">
|
||||||
|
</separator>
|
||||||
|
<separator
|
||||||
|
name="importExportSeparator"
|
||||||
|
visible="true">
|
||||||
|
</separator>
|
||||||
<menu
|
<menu
|
||||||
id="import"
|
id="import"
|
||||||
label="Import">
|
label="Import">
|
||||||
|
|
|
@ -0,0 +1,226 @@
|
||||||
|
/**
|
||||||
|
* This software was developed and / or modified by Raytheon Company,
|
||||||
|
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||||
|
*
|
||||||
|
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||||
|
* This software product contains export-restricted data whose
|
||||||
|
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||||
|
* to non-U.S. persons whether in the United States or abroad requires
|
||||||
|
* an export license or other authorization.
|
||||||
|
*
|
||||||
|
* Contractor Name: Raytheon Company
|
||||||
|
* Contractor Address: 6825 Pine Street, Suite 340
|
||||||
|
* Mail Stop B8
|
||||||
|
* Omaha, NE 68106
|
||||||
|
* 402.291.0100
|
||||||
|
*
|
||||||
|
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||||
|
* further licensing information.
|
||||||
|
**/
|
||||||
|
package com.raytheon.viz.ui.dialogs;
|
||||||
|
|
||||||
|
import java.util.Calendar;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.TimeZone;
|
||||||
|
|
||||||
|
import org.eclipse.swt.SWT;
|
||||||
|
import org.eclipse.swt.events.SelectionAdapter;
|
||||||
|
import org.eclipse.swt.events.SelectionEvent;
|
||||||
|
import org.eclipse.swt.layout.GridData;
|
||||||
|
import org.eclipse.swt.layout.GridLayout;
|
||||||
|
import org.eclipse.swt.widgets.Button;
|
||||||
|
import org.eclipse.swt.widgets.Composite;
|
||||||
|
import org.eclipse.swt.widgets.DateTime;
|
||||||
|
import org.eclipse.swt.widgets.Label;
|
||||||
|
import org.eclipse.swt.widgets.Shell;
|
||||||
|
import org.eclipse.swt.widgets.Spinner;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Awips Calendar Date Selection Dialog.
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
*
|
||||||
|
* SOFTWARE HISTORY
|
||||||
|
*
|
||||||
|
* Date Ticket# Engineer Description
|
||||||
|
* ------------ ---------- ----------- --------------------------
|
||||||
|
* Jan 9, 2012 mpduff Initial creation
|
||||||
|
*
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* @author mpduff
|
||||||
|
* @version 1.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class AwipsCalendar extends CaveSWTDialogBase {
|
||||||
|
|
||||||
|
/** The date selection calendar class */
|
||||||
|
private DateTime calendar;
|
||||||
|
|
||||||
|
/** The hour selection spinner class */
|
||||||
|
private Spinner hourSpinner;
|
||||||
|
|
||||||
|
/** The showHour flag */
|
||||||
|
private boolean showHour = true;
|
||||||
|
|
||||||
|
/** The showHour flag */
|
||||||
|
private Date date = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor.
|
||||||
|
*
|
||||||
|
* @param parentShell
|
||||||
|
* @param showHour
|
||||||
|
*/
|
||||||
|
public AwipsCalendar(Shell parentShell, boolean showHour) {
|
||||||
|
super(parentShell, SWT.DIALOG_TRIM);
|
||||||
|
setText("Calendar");
|
||||||
|
this.showHour = showHour;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor.
|
||||||
|
*
|
||||||
|
* @param parentShell
|
||||||
|
*/
|
||||||
|
public AwipsCalendar(Shell parentShell) {
|
||||||
|
super(parentShell, SWT.DIALOG_TRIM);
|
||||||
|
setText("Calendar");
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor.
|
||||||
|
*
|
||||||
|
* @param parentShell
|
||||||
|
* @param d Date to preset the calendar widget
|
||||||
|
* @param showHour true to display the hour spinner
|
||||||
|
*/
|
||||||
|
public AwipsCalendar(Shell parentShell, Date d, boolean showHour) {
|
||||||
|
super(parentShell, SWT.DIALOG_TRIM);
|
||||||
|
setText("Calendar");
|
||||||
|
this.date = d;
|
||||||
|
this.showHour = showHour;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
*
|
||||||
|
* @see
|
||||||
|
* com.raytheon.viz.ui.dialogs.CaveSWTDialogBase#initializeComponents(org
|
||||||
|
* .eclipse.swt.widgets.Shell)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected void initializeComponents(Shell shell) {
|
||||||
|
|
||||||
|
Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
|
||||||
|
if (date != null) {
|
||||||
|
cal.setTime(date);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (showHour) {
|
||||||
|
createTopWidgets(cal.get(Calendar.HOUR_OF_DAY));
|
||||||
|
}
|
||||||
|
|
||||||
|
calendar = new DateTime(shell, SWT.CALENDAR | SWT.BORDER_SOLID);
|
||||||
|
calendar.setDate(cal.get(Calendar.YEAR), cal.get(Calendar.MONTH), cal.get(Calendar.DAY_OF_MONTH));
|
||||||
|
|
||||||
|
createButtons();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create the top widgets
|
||||||
|
*/
|
||||||
|
private void createTopWidgets(int hour) {
|
||||||
|
GridLayout gl = new GridLayout(2, false);
|
||||||
|
GridData gd = new GridData(SWT.FILL, SWT.DEFAULT, true, false);
|
||||||
|
|
||||||
|
Composite top = new Composite(shell, SWT.NONE);
|
||||||
|
top.setLayout(gl);
|
||||||
|
top.setLayoutData(gd);
|
||||||
|
|
||||||
|
gd = new GridData(SWT.LEFT, SWT.DEFAULT, true, false);
|
||||||
|
Label lbl = new Label(top, SWT.NONE);
|
||||||
|
lbl.setLayoutData(gd);
|
||||||
|
lbl.setText("Select Hour (Z) and Date: ");
|
||||||
|
|
||||||
|
gd = new GridData(SWT.RIGHT, SWT.DEFAULT, true, false);
|
||||||
|
|
||||||
|
hourSpinner = new Spinner(top, SWT.BORDER | SWT.RIGHT);
|
||||||
|
hourSpinner.setLayoutData(gd);
|
||||||
|
hourSpinner.setMinimum(0);
|
||||||
|
hourSpinner.setMaximum(23);
|
||||||
|
hourSpinner.setSelection(hour);
|
||||||
|
hourSpinner.setIncrement(1);
|
||||||
|
hourSpinner.setPageIncrement(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create the buttons
|
||||||
|
*/
|
||||||
|
private void createButtons() {
|
||||||
|
int buttonWidth = 75;
|
||||||
|
GridData btnData = new GridData(buttonWidth, SWT.DEFAULT);
|
||||||
|
|
||||||
|
GridData gd = new GridData(SWT.CENTER, SWT.DEFAULT, true, false);
|
||||||
|
GridLayout gl = new GridLayout(3, false);
|
||||||
|
Composite btnComp = new Composite(shell, SWT.NONE);
|
||||||
|
btnComp.setLayout(gl);
|
||||||
|
btnComp.setLayoutData(gd);
|
||||||
|
|
||||||
|
Button okBtn = new Button(btnComp, SWT.PUSH);
|
||||||
|
okBtn.setText("OK");
|
||||||
|
okBtn.setLayoutData(btnData);
|
||||||
|
okBtn.addSelectionListener(new SelectionAdapter() {
|
||||||
|
@Override
|
||||||
|
public void widgetSelected(SelectionEvent event) {
|
||||||
|
handleOk();
|
||||||
|
shell.dispose();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Button cancelBtn = new Button(btnComp, SWT.PUSH);
|
||||||
|
cancelBtn.setText("Cancel");
|
||||||
|
cancelBtn.setLayoutData(btnData);
|
||||||
|
cancelBtn.addSelectionListener(new SelectionAdapter() {
|
||||||
|
@Override
|
||||||
|
public void widgetSelected(SelectionEvent event) {
|
||||||
|
shell.dispose();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Event handler action for OK button
|
||||||
|
*/
|
||||||
|
private void handleOk() {
|
||||||
|
Calendar selectedDate = Calendar.getInstance(TimeZone
|
||||||
|
.getTimeZone("GMT"));
|
||||||
|
selectedDate.set(Calendar.YEAR, calendar.getYear());
|
||||||
|
selectedDate.set(Calendar.MONTH, calendar.getMonth());
|
||||||
|
selectedDate.set(Calendar.DAY_OF_MONTH, calendar.getDay());
|
||||||
|
if (showHour) {
|
||||||
|
selectedDate.set(Calendar.HOUR_OF_DAY,
|
||||||
|
Integer.parseInt(hourSpinner.getText()));
|
||||||
|
} else {
|
||||||
|
selectedDate.set(Calendar.HOUR_OF_DAY, 0);
|
||||||
|
}
|
||||||
|
selectedDate.set(Calendar.MINUTE, 0);
|
||||||
|
selectedDate.set(Calendar.SECOND, 0);
|
||||||
|
selectedDate.set(Calendar.MILLISECOND, 0);
|
||||||
|
this.setReturnValue(selectedDate);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Main
|
||||||
|
*
|
||||||
|
* @param args
|
||||||
|
*/
|
||||||
|
public static void main(String[] args) {
|
||||||
|
AwipsCalendar ac = new AwipsCalendar(new Shell());
|
||||||
|
ac.open();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -6,10 +6,15 @@ Bundle-Version: 1.0.0.qualifier
|
||||||
Bundle-Vendor: RAYTHEON
|
Bundle-Vendor: RAYTHEON
|
||||||
Bundle-RequiredExecutionEnvironment: JavaSE-1.6
|
Bundle-RequiredExecutionEnvironment: JavaSE-1.6
|
||||||
Export-Package: com.raytheon.uf.common.stats,
|
Export-Package: com.raytheon.uf.common.stats,
|
||||||
|
com.raytheon.uf.common.stats.data,
|
||||||
|
com.raytheon.uf.common.stats.util,
|
||||||
com.raytheon.uf.common.stats.xml
|
com.raytheon.uf.common.stats.xml
|
||||||
Require-Bundle: com.raytheon.uf.common.time;bundle-version="1.12.1174",
|
Require-Bundle: com.raytheon.uf.common.time;bundle-version="1.12.1174",
|
||||||
com.raytheon.uf.common.serialization;bundle-version="1.12.1174",
|
com.raytheon.uf.common.serialization;bundle-version="1.12.1174",
|
||||||
com.raytheon.uf.common.serialization.comm;bundle-version="1.12.1174",
|
com.raytheon.uf.common.serialization.comm;bundle-version="1.12.1174",
|
||||||
javax.persistence;bundle-version="1.0.0",
|
javax.persistence;bundle-version="1.0.0",
|
||||||
com.raytheon.uf.common.dataplugin;bundle-version="1.12.1174",
|
com.raytheon.uf.common.dataplugin;bundle-version="1.12.1174",
|
||||||
com.raytheon.uf.common.event;bundle-version="1.0.0"
|
com.raytheon.uf.common.event;bundle-version="1.0.0",
|
||||||
|
com.google.guava;bundle-version="1.0.0",
|
||||||
|
com.raytheon.uf.common.util;bundle-version="1.12.1174",
|
||||||
|
com.raytheon.uf.common.status;bundle-version="1.12.1174"
|
||||||
|
|
|
@ -1,19 +1,19 @@
|
||||||
/**
|
/**
|
||||||
* This software was developed and / or modified by Raytheon Company,
|
* This software was developed and / or modified by Raytheon Company,
|
||||||
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||||
*
|
*
|
||||||
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||||
* This software product contains export-restricted data whose
|
* This software product contains export-restricted data whose
|
||||||
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||||
* to non-U.S. persons whether in the United States or abroad requires
|
* to non-U.S. persons whether in the United States or abroad requires
|
||||||
* an export license or other authorization.
|
* an export license or other authorization.
|
||||||
*
|
*
|
||||||
* Contractor Name: Raytheon Company
|
* Contractor Name: Raytheon Company
|
||||||
* Contractor Address: 6825 Pine Street, Suite 340
|
* Contractor Address: 6825 Pine Street, Suite 340
|
||||||
* Mail Stop B8
|
* Mail Stop B8
|
||||||
* Omaha, NE 68106
|
* Omaha, NE 68106
|
||||||
* 402.291.0100
|
* 402.291.0100
|
||||||
*
|
*
|
||||||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||||
* further licensing information.
|
* further licensing information.
|
||||||
**/
|
**/
|
||||||
|
@ -37,17 +37,17 @@ import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Record class for an aggregate result.
|
* Record class for an aggregate result.
|
||||||
*
|
*
|
||||||
* <pre>
|
* <pre>
|
||||||
*
|
*
|
||||||
* SOFTWARE HISTORY
|
* SOFTWARE HISTORY
|
||||||
* Date Ticket# Engineer Description
|
* Date Ticket# Engineer Description
|
||||||
* ------------ ---------- ----------- --------------------------
|
* ------------ ---------- ----------- --------------------------
|
||||||
* Aug 21, 2012 jsanchez Initial creation
|
* Aug 21, 2012 jsanchez Initial creation
|
||||||
* Nov 12, 2012 dhladky Updates some things for stats
|
* Nov 12, 2012 dhladky Updates some things for stats
|
||||||
*
|
*
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
* @author jsanchez
|
* @author jsanchez
|
||||||
* @version 1.0
|
* @version 1.0
|
||||||
*/
|
*/
|
||||||
|
@ -57,7 +57,6 @@ import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement;
|
||||||
@XmlAccessorType(XmlAccessType.NONE)
|
@XmlAccessorType(XmlAccessType.NONE)
|
||||||
@DynamicSerialize
|
@DynamicSerialize
|
||||||
public class AggregateRecord extends PersistableDataObject {
|
public class AggregateRecord extends PersistableDataObject {
|
||||||
|
|
||||||
private static final long serialVersionUID = -4553588456131256014L;
|
private static final long serialVersionUID = -4553588456131256014L;
|
||||||
|
|
||||||
@GeneratedValue(strategy = GenerationType.AUTO)
|
@GeneratedValue(strategy = GenerationType.AUTO)
|
||||||
|
@ -189,4 +188,96 @@ public class AggregateRecord extends PersistableDataObject {
|
||||||
this.sum = sum;
|
this.sum = sum;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see java.lang.Object#hashCode()
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
final int prime = 31;
|
||||||
|
int result = super.hashCode();
|
||||||
|
long temp;
|
||||||
|
temp = Double.doubleToLongBits(count);
|
||||||
|
result = prime * result + (int) (temp ^ (temp >>> 32));
|
||||||
|
result = prime * result + ((endDate == null) ? 0 : endDate.hashCode());
|
||||||
|
result = prime * result
|
||||||
|
+ ((eventType == null) ? 0 : eventType.hashCode());
|
||||||
|
result = prime * result + ((field == null) ? 0 : field.hashCode());
|
||||||
|
result = prime * result
|
||||||
|
+ ((grouping == null) ? 0 : grouping.hashCode());
|
||||||
|
temp = Double.doubleToLongBits(max);
|
||||||
|
result = prime * result + (int) (temp ^ (temp >>> 32));
|
||||||
|
temp = Double.doubleToLongBits(min);
|
||||||
|
result = prime * result + (int) (temp ^ (temp >>> 32));
|
||||||
|
result = prime * result
|
||||||
|
+ ((startDate == null) ? 0 : startDate.hashCode());
|
||||||
|
temp = Double.doubleToLongBits(sum);
|
||||||
|
result = prime * result + (int) (temp ^ (temp >>> 32));
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see java.lang.Object#equals(java.lang.Object)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (this == obj) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (!super.equals(obj)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (getClass() != obj.getClass()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
AggregateRecord other = (AggregateRecord) obj;
|
||||||
|
if (Double.doubleToLongBits(count) != Double
|
||||||
|
.doubleToLongBits(other.count)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (endDate == null) {
|
||||||
|
if (other.endDate != null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else if (!endDate.equals(other.endDate)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (eventType == null) {
|
||||||
|
if (other.eventType != null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else if (!eventType.equals(other.eventType)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (field == null) {
|
||||||
|
if (other.field != null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else if (!field.equals(other.field)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (grouping == null) {
|
||||||
|
if (other.grouping != null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else if (!grouping.equals(other.grouping)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (Double.doubleToLongBits(max) != Double.doubleToLongBits(other.max)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (Double.doubleToLongBits(min) != Double.doubleToLongBits(other.min)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (startDate == null) {
|
||||||
|
if (other.startDate != null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else if (!startDate.equals(other.startDate)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (Double.doubleToLongBits(sum) != Double.doubleToLongBits(other.sum)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,200 @@
|
||||||
|
/**
|
||||||
|
* This software was developed and / or modified by Raytheon Company,
|
||||||
|
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||||
|
*
|
||||||
|
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||||
|
* This software product contains export-restricted data whose
|
||||||
|
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||||
|
* to non-U.S. persons whether in the United States or abroad requires
|
||||||
|
* an export license or other authorization.
|
||||||
|
*
|
||||||
|
* Contractor Name: Raytheon Company
|
||||||
|
* Contractor Address: 6825 Pine Street, Suite 340
|
||||||
|
* Mail Stop B8
|
||||||
|
* Omaha, NE 68106
|
||||||
|
* 402.291.0100
|
||||||
|
*
|
||||||
|
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||||
|
* further licensing information.
|
||||||
|
**/
|
||||||
|
package com.raytheon.uf.common.stats;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import com.raytheon.uf.common.serialization.annotations.DynamicSerialize;
|
||||||
|
import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement;
|
||||||
|
import com.raytheon.uf.common.serialization.comm.IServerRequest;
|
||||||
|
import com.raytheon.uf.common.time.TimeRange;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Request object to retrieve data for the Stats graphs
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
*
|
||||||
|
* SOFTWARE HISTORY
|
||||||
|
*
|
||||||
|
* Date Ticket# Engineer Description
|
||||||
|
* ------------ ---------- ----------- --------------------------
|
||||||
|
* Sep 11, 2012 728 mpduff Initial creation
|
||||||
|
*
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* @author mpduff
|
||||||
|
* @version 1.0
|
||||||
|
*/
|
||||||
|
@DynamicSerialize
|
||||||
|
public class GraphDataRequest implements IServerRequest {
|
||||||
|
/** The time range */
|
||||||
|
@DynamicSerializeElement
|
||||||
|
private TimeRange timeRange;
|
||||||
|
|
||||||
|
/** Statistics Category */
|
||||||
|
@DynamicSerializeElement
|
||||||
|
private String category;
|
||||||
|
|
||||||
|
/** Statistics event type */
|
||||||
|
@DynamicSerializeElement
|
||||||
|
private String eventType;
|
||||||
|
|
||||||
|
/** Statistics field */
|
||||||
|
@DynamicSerializeElement
|
||||||
|
private String field;
|
||||||
|
|
||||||
|
/** List of groups */
|
||||||
|
@DynamicSerializeElement
|
||||||
|
private List<String> grouping;
|
||||||
|
|
||||||
|
/** Event data type/Attribute */
|
||||||
|
@DynamicSerializeElement
|
||||||
|
private String dataType;
|
||||||
|
|
||||||
|
/** Metadata request flag */
|
||||||
|
@DynamicSerializeElement
|
||||||
|
private boolean metaDataRequest = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Data timestep (frequency) in minutes.
|
||||||
|
*/
|
||||||
|
@DynamicSerializeElement
|
||||||
|
private int timeStep;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the timeRange
|
||||||
|
*/
|
||||||
|
public TimeRange getTimeRange() {
|
||||||
|
return timeRange;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param timeRange
|
||||||
|
* the timeRange to set
|
||||||
|
*/
|
||||||
|
public void setTimeRange(TimeRange timeRange) {
|
||||||
|
this.timeRange = timeRange;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the eventType
|
||||||
|
*/
|
||||||
|
public String getEventType() {
|
||||||
|
return eventType;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param eventType
|
||||||
|
* the eventType to set
|
||||||
|
*/
|
||||||
|
public void setEventType(String eventType) {
|
||||||
|
this.eventType = eventType;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the field
|
||||||
|
*/
|
||||||
|
public String getField() {
|
||||||
|
return field;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param field
|
||||||
|
* the field to set
|
||||||
|
*/
|
||||||
|
public void setField(String field) {
|
||||||
|
this.field = field;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the grouping
|
||||||
|
*/
|
||||||
|
public List<String> getGrouping() {
|
||||||
|
return grouping;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param grouping
|
||||||
|
* the grouping to set
|
||||||
|
*/
|
||||||
|
public void setGrouping(List<String> grouping) {
|
||||||
|
this.grouping = grouping;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param timeStep
|
||||||
|
* the timeStep to set
|
||||||
|
*/
|
||||||
|
public void setTimeStep(int timeStep) {
|
||||||
|
this.timeStep = timeStep;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the timeStep
|
||||||
|
*/
|
||||||
|
public int getTimeStep() {
|
||||||
|
return timeStep;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the dataType
|
||||||
|
*/
|
||||||
|
public String getDataType() {
|
||||||
|
return dataType;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param dataType
|
||||||
|
* the dataType to set
|
||||||
|
*/
|
||||||
|
public void setDataType(String dataType) {
|
||||||
|
this.dataType = dataType;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param metaDataRequest
|
||||||
|
* the metaDataRequest to set
|
||||||
|
*/
|
||||||
|
public void setMetaDataRequest(boolean metaDataRequest) {
|
||||||
|
this.metaDataRequest = metaDataRequest;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the category
|
||||||
|
*/
|
||||||
|
public String getCategory() {
|
||||||
|
return category;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param category
|
||||||
|
* the category to set
|
||||||
|
*/
|
||||||
|
public void setCategory(String category) {
|
||||||
|
this.category = category;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the metaDataRequest
|
||||||
|
*/
|
||||||
|
public boolean isMetaDataRequest() {
|
||||||
|
return metaDataRequest;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,90 @@
|
||||||
|
/**
|
||||||
|
* This software was developed and / or modified by Raytheon Company,
|
||||||
|
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||||
|
*
|
||||||
|
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||||
|
* This software product contains export-restricted data whose
|
||||||
|
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||||
|
* to non-U.S. persons whether in the United States or abroad requires
|
||||||
|
* an export license or other authorization.
|
||||||
|
*
|
||||||
|
* Contractor Name: Raytheon Company
|
||||||
|
* Contractor Address: 6825 Pine Street, Suite 340
|
||||||
|
* Mail Stop B8
|
||||||
|
* Omaha, NE 68106
|
||||||
|
* 402.291.0100
|
||||||
|
*
|
||||||
|
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||||
|
* further licensing information.
|
||||||
|
**/
|
||||||
|
package com.raytheon.uf.common.stats;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import com.raytheon.uf.common.serialization.ISerializableObject;
|
||||||
|
import com.raytheon.uf.common.serialization.annotations.DynamicSerialize;
|
||||||
|
import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement;
|
||||||
|
import com.raytheon.uf.common.stats.data.GraphData;
|
||||||
|
import com.raytheon.uf.common.stats.xml.StatisticsConfig;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Response object for the GraphDataRequest.
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
*
|
||||||
|
* SOFTWARE HISTORY
|
||||||
|
*
|
||||||
|
* Date Ticket# Engineer Description
|
||||||
|
* ------------ ---------- ----------- --------------------------
|
||||||
|
* Sep 11, 2012 728 mpduff Initial creation
|
||||||
|
*
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* @author mpduff
|
||||||
|
* @version 1.0
|
||||||
|
*/
|
||||||
|
@DynamicSerialize
|
||||||
|
public class GraphDataResponse implements ISerializableObject {
|
||||||
|
@DynamicSerializeElement
|
||||||
|
private GraphData graphData;
|
||||||
|
|
||||||
|
@DynamicSerializeElement
|
||||||
|
private List<StatisticsConfig> configList;
|
||||||
|
|
||||||
|
public GraphDataResponse() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the configList
|
||||||
|
*/
|
||||||
|
public List<StatisticsConfig> getConfigList() {
|
||||||
|
return configList;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param configList
|
||||||
|
* the configList to set
|
||||||
|
*/
|
||||||
|
public void setConfigList(List<StatisticsConfig> configList) {
|
||||||
|
this.configList = configList;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the GraphData object
|
||||||
|
*
|
||||||
|
* @param graphData
|
||||||
|
*/
|
||||||
|
public void setGraphData(GraphData graphData) {
|
||||||
|
this.graphData = graphData;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the GraphData object
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public GraphData getGraphData() {
|
||||||
|
return this.graphData;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,268 @@
|
||||||
|
/**
|
||||||
|
* This software was developed and / or modified by Raytheon Company,
|
||||||
|
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||||
|
*
|
||||||
|
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||||
|
* This software product contains export-restricted data whose
|
||||||
|
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||||
|
* to non-U.S. persons whether in the United States or abroad requires
|
||||||
|
* an export license or other authorization.
|
||||||
|
*
|
||||||
|
* Contractor Name: Raytheon Company
|
||||||
|
* Contractor Address: 6825 Pine Street, Suite 340
|
||||||
|
* Mail Stop B8
|
||||||
|
* Omaha, NE 68106
|
||||||
|
* 402.291.0100
|
||||||
|
*
|
||||||
|
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||||
|
* further licensing information.
|
||||||
|
**/
|
||||||
|
package com.raytheon.uf.common.stats.data;
|
||||||
|
|
||||||
|
import java.text.DecimalFormat;
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.TimeZone;
|
||||||
|
|
||||||
|
import javax.xml.bind.annotation.XmlAccessType;
|
||||||
|
import javax.xml.bind.annotation.XmlAccessorType;
|
||||||
|
import javax.xml.bind.annotation.XmlRootElement;
|
||||||
|
|
||||||
|
import com.raytheon.uf.common.serialization.annotations.DynamicSerialize;
|
||||||
|
import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class holding an x,y data point and other associated information for the
|
||||||
|
* point.
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
*
|
||||||
|
* SOFTWARE HISTORY
|
||||||
|
*
|
||||||
|
* Date Ticket# Engineer Description
|
||||||
|
* ------------ ---------- ----------- --------------------------
|
||||||
|
* Sep 7, 2012 mpduff Initial creation
|
||||||
|
*
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* @author mpduff
|
||||||
|
* @version 1.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
@XmlRootElement
|
||||||
|
@XmlAccessorType(XmlAccessType.NONE)
|
||||||
|
@DynamicSerialize
|
||||||
|
public class DataPoint implements Comparable<DataPoint> {
|
||||||
|
/** Date Format object */
|
||||||
|
private final ThreadLocal<SimpleDateFormat> sdf = new ThreadLocal<SimpleDateFormat>() {
|
||||||
|
@Override
|
||||||
|
protected SimpleDateFormat initialValue() {
|
||||||
|
SimpleDateFormat sTemp = new SimpleDateFormat("MM/dd/yyyy HH:mm");
|
||||||
|
sTemp.setTimeZone(TimeZone.getTimeZone("GMT"));
|
||||||
|
return sTemp;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Decimal Format object */
|
||||||
|
private final ThreadLocal<DecimalFormat> decFormat = new ThreadLocal<DecimalFormat>() {
|
||||||
|
@Override
|
||||||
|
protected DecimalFormat initialValue() {
|
||||||
|
DecimalFormat format = new DecimalFormat("########.#");
|
||||||
|
return format;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* X value - millis
|
||||||
|
*/
|
||||||
|
@DynamicSerializeElement
|
||||||
|
private long x;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Y value
|
||||||
|
*/
|
||||||
|
@DynamicSerializeElement
|
||||||
|
protected double y = 0.0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Text display for the sampling of this point
|
||||||
|
*/
|
||||||
|
@DynamicSerializeElement
|
||||||
|
protected String sampleText;
|
||||||
|
|
||||||
|
/** Min value */
|
||||||
|
@DynamicSerializeElement
|
||||||
|
private double min = Integer.MAX_VALUE;
|
||||||
|
|
||||||
|
/** Max value */
|
||||||
|
@DynamicSerializeElement
|
||||||
|
private double max = Integer.MIN_VALUE;
|
||||||
|
|
||||||
|
/** Count */
|
||||||
|
@DynamicSerializeElement
|
||||||
|
private double count = 0;
|
||||||
|
|
||||||
|
/** Sum */
|
||||||
|
@DynamicSerializeElement
|
||||||
|
private double sum;
|
||||||
|
|
||||||
|
/** Constructor */
|
||||||
|
public DataPoint() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the y
|
||||||
|
*/
|
||||||
|
public double getY() {
|
||||||
|
return this.getAvg();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param y
|
||||||
|
* the y to set
|
||||||
|
*/
|
||||||
|
public void setY(double y) {
|
||||||
|
this.y += y;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param sampleText
|
||||||
|
* the sampleText to set
|
||||||
|
*/
|
||||||
|
public void setSampleText(String sampleText) {
|
||||||
|
this.sampleText = sampleText;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the sample text for this point object
|
||||||
|
*
|
||||||
|
* @return the sample text string
|
||||||
|
*/
|
||||||
|
public String getSampleText() {
|
||||||
|
SimpleDateFormat dateFormat = sdf.get();
|
||||||
|
DecimalFormat decimalFormat = decFormat.get();
|
||||||
|
|
||||||
|
return dateFormat.format(new Date(x)) + "Z, "
|
||||||
|
+ decimalFormat.format(getAvg());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param x
|
||||||
|
* the x to set
|
||||||
|
*/
|
||||||
|
public void setX(long x) {
|
||||||
|
this.x = x;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the x
|
||||||
|
*/
|
||||||
|
public long getX() {
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public int compareTo(DataPoint dp) {
|
||||||
|
if (this.x == dp.x) {
|
||||||
|
return 0;
|
||||||
|
} else if (this.x < dp.x) {
|
||||||
|
return -1;
|
||||||
|
} else if (this.x > dp.x) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the min
|
||||||
|
*/
|
||||||
|
public double getMin() {
|
||||||
|
return min;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the min value if it is less than the current min.
|
||||||
|
*
|
||||||
|
* @param min
|
||||||
|
* the min to set
|
||||||
|
*/
|
||||||
|
public void setMin(double min) {
|
||||||
|
if (this.min > min) {
|
||||||
|
this.min = min;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the max
|
||||||
|
*/
|
||||||
|
public double getMax() {
|
||||||
|
return max;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the max value if it is greater than the current max.
|
||||||
|
*
|
||||||
|
* @param max
|
||||||
|
* the max to set
|
||||||
|
*/
|
||||||
|
public void setMax(double max) {
|
||||||
|
if (this.max < max) {
|
||||||
|
this.max = max;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the count
|
||||||
|
*/
|
||||||
|
public double getCount() {
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param count
|
||||||
|
* the count to set
|
||||||
|
*/
|
||||||
|
public void setCount(double count) {
|
||||||
|
this.count = count;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param count
|
||||||
|
* the count to add
|
||||||
|
*/
|
||||||
|
public void addToCount(double count) {
|
||||||
|
this.count += count;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the sum
|
||||||
|
*/
|
||||||
|
public double getSum() {
|
||||||
|
return sum;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param sum
|
||||||
|
* the sum to set
|
||||||
|
*/
|
||||||
|
public void setSum(double sum) {
|
||||||
|
this.sum += sum;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the avg
|
||||||
|
*/
|
||||||
|
public double getAvg() {
|
||||||
|
if (count > 0) {
|
||||||
|
return this.sum / count;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,376 @@
|
||||||
|
/**
|
||||||
|
* This software was developed and / or modified by Raytheon Company,
|
||||||
|
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||||
|
*
|
||||||
|
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||||
|
* This software product contains export-restricted data whose
|
||||||
|
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||||
|
* to non-U.S. persons whether in the United States or abroad requires
|
||||||
|
* an export license or other authorization.
|
||||||
|
*
|
||||||
|
* Contractor Name: Raytheon Company
|
||||||
|
* Contractor Address: 6825 Pine Street, Suite 340
|
||||||
|
* Mail Stop B8
|
||||||
|
* Omaha, NE 68106
|
||||||
|
* 402.291.0100
|
||||||
|
*
|
||||||
|
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||||
|
* further licensing information.
|
||||||
|
**/
|
||||||
|
package com.raytheon.uf.common.stats.data;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.TreeMap;
|
||||||
|
|
||||||
|
import com.google.common.annotations.VisibleForTesting;
|
||||||
|
import com.raytheon.uf.common.serialization.annotations.DynamicSerialize;
|
||||||
|
import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement;
|
||||||
|
import com.raytheon.uf.common.stats.AggregateRecord;
|
||||||
|
import com.raytheon.uf.common.stats.StatisticsEvent;
|
||||||
|
import com.raytheon.uf.common.stats.util.UnitUtils;
|
||||||
|
import com.raytheon.uf.common.status.IUFStatusHandler;
|
||||||
|
import com.raytheon.uf.common.status.UFStatus;
|
||||||
|
import com.raytheon.uf.common.status.UFStatus.Priority;
|
||||||
|
import com.raytheon.uf.common.time.TimeRange;
|
||||||
|
import com.raytheon.uf.common.util.ReflectionException;
|
||||||
|
import com.raytheon.uf.common.util.ReflectionUtil;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Data object for the statistics graph.
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
*
|
||||||
|
* SOFTWARE HISTORY
|
||||||
|
*
|
||||||
|
* Date Ticket# Engineer Description
|
||||||
|
* ------------ ---------- ----------- --------------------------
|
||||||
|
* Oct 3, 2012 728 mpduff Initial creation
|
||||||
|
*
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* @author mpduff
|
||||||
|
* @version 1.0
|
||||||
|
*/
|
||||||
|
@DynamicSerialize
|
||||||
|
public class GraphData {
|
||||||
|
private static final IUFStatusHandler statusHandler = UFStatus
|
||||||
|
.getHandler(GraphData.class);
|
||||||
|
|
||||||
|
/** Map of milliseconds -> StatsBin object */
|
||||||
|
@DynamicSerializeElement
|
||||||
|
private final Map<Long, StatsBin> bins = new TreeMap<Long, StatsBin>();
|
||||||
|
|
||||||
|
/** List of member keys */
|
||||||
|
@DynamicSerializeElement
|
||||||
|
private List<String> keys;
|
||||||
|
|
||||||
|
/** AggregateRecord list */
|
||||||
|
@DynamicSerializeElement
|
||||||
|
private List<AggregateRecord> recordList = new ArrayList<AggregateRecord>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* key -> stats data object
|
||||||
|
*/
|
||||||
|
@DynamicSerializeElement
|
||||||
|
private Map<String, StatsData> statsDataMap = new HashMap<String, StatsData>();
|
||||||
|
|
||||||
|
/** Time range */
|
||||||
|
@DynamicSerializeElement
|
||||||
|
private TimeRange timeRange;
|
||||||
|
|
||||||
|
/** Map of group -> key */
|
||||||
|
@DynamicSerializeElement
|
||||||
|
private final Map<String, String> keySequenceMap = new LinkedHashMap<String, String>();
|
||||||
|
|
||||||
|
/** StatsLabelData object */
|
||||||
|
@DynamicSerializeElement
|
||||||
|
private StatsLabelData statsLabelData;
|
||||||
|
|
||||||
|
/** Display unit */
|
||||||
|
@DynamicSerializeElement
|
||||||
|
private String displayUnit;
|
||||||
|
|
||||||
|
/** UnitUtils object */
|
||||||
|
private UnitUtils unitUtils;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor.
|
||||||
|
*/
|
||||||
|
public GraphData() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the bins
|
||||||
|
*/
|
||||||
|
public Map<Long, StatsBin> getStatsBins() {
|
||||||
|
return bins;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param recordList
|
||||||
|
* the recordList to set
|
||||||
|
*/
|
||||||
|
public void setRecordList(List<AggregateRecord> recordList) {
|
||||||
|
this.recordList = recordList;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the recordList
|
||||||
|
*/
|
||||||
|
public List<AggregateRecord> getRecordList() {
|
||||||
|
return recordList;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add an AggregateRecord.
|
||||||
|
*
|
||||||
|
* @param record
|
||||||
|
*/
|
||||||
|
public void addRecord(AggregateRecord record) {
|
||||||
|
if (!recordList.contains(record)) {
|
||||||
|
recordList.add(record);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the statsData
|
||||||
|
*/
|
||||||
|
public StatsData getStatsData(String groupMemberName) {
|
||||||
|
return this.statsDataMap.get(groupMemberName);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a list of group memebers.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public List<String> getGroupMembers() {
|
||||||
|
List<String> memberList = new ArrayList<String>(statsDataMap.keySet());
|
||||||
|
Collections.sort(memberList);
|
||||||
|
|
||||||
|
return memberList;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the smallest value in the data set.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public double getMinValue() {
|
||||||
|
double min = Double.MAX_VALUE;
|
||||||
|
for (String key : statsDataMap.keySet()) {
|
||||||
|
double minVal = statsDataMap.get(key).getMinValue();
|
||||||
|
if (minVal < min) {
|
||||||
|
min = minVal;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return min;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the largest value in the data set.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public double getMaxValue() {
|
||||||
|
double max = Double.MIN_VALUE;
|
||||||
|
for (String key : statsDataMap.keySet()) {
|
||||||
|
double maxVal = statsDataMap.get(key).getMaxValue();
|
||||||
|
if (maxVal > max) {
|
||||||
|
max = maxVal;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return max;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the time range for this object.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public TimeRange getTimeRange() {
|
||||||
|
return this.timeRange;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the TimeRange
|
||||||
|
*
|
||||||
|
* @param timeRange
|
||||||
|
*/
|
||||||
|
public void setTimeRange(TimeRange timeRange) {
|
||||||
|
this.timeRange = timeRange;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the key sequence
|
||||||
|
*
|
||||||
|
* @param keySequence
|
||||||
|
*/
|
||||||
|
public void setKeySequence(List<String> keySequence) {
|
||||||
|
for (String key : keySequence) {
|
||||||
|
keySequenceMap.put(key, "");
|
||||||
|
}
|
||||||
|
|
||||||
|
keys = keySequence;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the key sequence.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public List<String> getKeySequence() {
|
||||||
|
return keys;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a list of all keys.
|
||||||
|
*
|
||||||
|
* @return the keys
|
||||||
|
*/
|
||||||
|
public List<String> getKeys() {
|
||||||
|
return keys;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a list of keys that contain data.
|
||||||
|
*
|
||||||
|
* @return the keys with data
|
||||||
|
*/
|
||||||
|
public List<String> getKeysWithData() {
|
||||||
|
List<String> keysWithData = new ArrayList<String>();
|
||||||
|
for (String key : keys) {
|
||||||
|
StatsData sd = this.getStatsData(key);
|
||||||
|
if (sd != null) {
|
||||||
|
keysWithData.add(key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return keysWithData;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the StatsLabelData object
|
||||||
|
*
|
||||||
|
* @param statsLabelData
|
||||||
|
*/
|
||||||
|
public void setStatsLabelData(StatsLabelData statsLabelData) {
|
||||||
|
this.statsLabelData = statsLabelData;
|
||||||
|
this.keys = statsLabelData.makeKeys();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the StatsLabelData
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public StatsLabelData getStatsLabelData() {
|
||||||
|
return this.statsLabelData;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the group and names map.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public Map<String, List<String>> getGroupAndNamesMap() {
|
||||||
|
return statsLabelData.getGroupAndNamesMap();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the units from the event object
|
||||||
|
*
|
||||||
|
* @param eventId
|
||||||
|
* Event id
|
||||||
|
* @param field
|
||||||
|
* data field
|
||||||
|
*
|
||||||
|
* @return The units
|
||||||
|
*/
|
||||||
|
@VisibleForTesting
|
||||||
|
static String getUnitsFromEventObject(String eventId, String field) {
|
||||||
|
// Get the units from the event class
|
||||||
|
String units = "Count";
|
||||||
|
|
||||||
|
try {
|
||||||
|
StatisticsEvent obj = ReflectionUtil.newInstanceOfAssignableType(
|
||||||
|
StatisticsEvent.class, eventId);
|
||||||
|
units = obj.getStorageUnit(field);
|
||||||
|
} catch (ReflectionException e) {
|
||||||
|
statusHandler.handle(Priority.ERROR, "Error Instantiating "
|
||||||
|
+ eventId, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return units;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the statsDataMap
|
||||||
|
*/
|
||||||
|
public Map<String, StatsData> getStatsDataMap() {
|
||||||
|
return statsDataMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the keySequenceMap
|
||||||
|
*/
|
||||||
|
public Map<String, String> getKeySequenceMap() {
|
||||||
|
return keySequenceMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the displayUnit
|
||||||
|
*/
|
||||||
|
public String getDisplayUnit() {
|
||||||
|
return displayUnit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param displayUnit
|
||||||
|
* the displayUnit to set
|
||||||
|
*/
|
||||||
|
public void setDisplayUnit(String displayUnit) {
|
||||||
|
this.displayUnit = displayUnit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param keys
|
||||||
|
* the keys to set
|
||||||
|
*/
|
||||||
|
public void setKeys(List<String> keys) {
|
||||||
|
this.keys = keys;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the StatsData map.
|
||||||
|
*
|
||||||
|
* @param statsDataMap
|
||||||
|
*/
|
||||||
|
public void setStatsDataMap(Map<String, StatsData> statsDataMap) {
|
||||||
|
this.statsDataMap = statsDataMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the unitUtils
|
||||||
|
*/
|
||||||
|
public UnitUtils getUnitUtils() {
|
||||||
|
return unitUtils;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param unitUtils
|
||||||
|
* the unitUtils to set
|
||||||
|
*/
|
||||||
|
public void setUnitUtils(UnitUtils unitUtils) {
|
||||||
|
this.unitUtils = unitUtils;
|
||||||
|
this.unitUtils.setConversion(this.getMaxValue());
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,91 @@
|
||||||
|
/**
|
||||||
|
* This software was developed and / or modified by Raytheon Company,
|
||||||
|
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||||
|
*
|
||||||
|
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||||
|
* This software product contains export-restricted data whose
|
||||||
|
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||||
|
* to non-U.S. persons whether in the United States or abroad requires
|
||||||
|
* an export license or other authorization.
|
||||||
|
*
|
||||||
|
* Contractor Name: Raytheon Company
|
||||||
|
* Contractor Address: 6825 Pine Street, Suite 340
|
||||||
|
* Mail Stop B8
|
||||||
|
* Omaha, NE 68106
|
||||||
|
* 402.291.0100
|
||||||
|
*
|
||||||
|
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||||
|
* further licensing information.
|
||||||
|
**/
|
||||||
|
package com.raytheon.uf.common.stats.data;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import com.raytheon.uf.common.serialization.annotations.DynamicSerialize;
|
||||||
|
import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement;
|
||||||
|
import com.raytheon.uf.common.stats.AggregateRecord;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A bin of Statistical data.
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
*
|
||||||
|
* SOFTWARE HISTORY
|
||||||
|
*
|
||||||
|
* Date Ticket# Engineer Description
|
||||||
|
* ------------ ---------- ----------- --------------------------
|
||||||
|
* Sep 11, 2012 723 mpduff Initial creation
|
||||||
|
*
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* @author mpduff
|
||||||
|
* @version 1.0
|
||||||
|
*/
|
||||||
|
@DynamicSerialize
|
||||||
|
public class StatsBin {
|
||||||
|
/** Millisecond value for this bin */
|
||||||
|
private long binMillis;
|
||||||
|
|
||||||
|
/** List of AggregateRecords */
|
||||||
|
@DynamicSerializeElement
|
||||||
|
private final List<AggregateRecord> data = new ArrayList<AggregateRecord>();
|
||||||
|
|
||||||
|
/** Constructor */
|
||||||
|
public StatsBin() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the binMillis
|
||||||
|
*/
|
||||||
|
public long getBinMillis() {
|
||||||
|
return binMillis;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param binMillis
|
||||||
|
* the binMillis to set
|
||||||
|
*/
|
||||||
|
public void setBinMillis(long binMillis) {
|
||||||
|
this.binMillis = binMillis;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add an AggregateRecord object.
|
||||||
|
*
|
||||||
|
* @param record
|
||||||
|
*/
|
||||||
|
public void setData(AggregateRecord record) {
|
||||||
|
this.data.add(record);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the AggregateRecord objects
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public List<AggregateRecord> getData() {
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,317 @@
|
||||||
|
/**
|
||||||
|
* This software was developed and / or modified by Raytheon Company,
|
||||||
|
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||||
|
*
|
||||||
|
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||||
|
* This software product contains export-restricted data whose
|
||||||
|
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||||
|
* to non-U.S. persons whether in the United States or abroad requires
|
||||||
|
* an export license or other authorization.
|
||||||
|
*
|
||||||
|
* Contractor Name: Raytheon Company
|
||||||
|
* Contractor Address: 6825 Pine Street, Suite 340
|
||||||
|
* Mail Stop B8
|
||||||
|
* Omaha, NE 68106
|
||||||
|
* 402.291.0100
|
||||||
|
*
|
||||||
|
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||||
|
* further licensing information.
|
||||||
|
**/
|
||||||
|
package com.raytheon.uf.common.stats.data;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import javax.xml.bind.annotation.XmlAccessType;
|
||||||
|
import javax.xml.bind.annotation.XmlAccessorType;
|
||||||
|
import javax.xml.bind.annotation.XmlRootElement;
|
||||||
|
|
||||||
|
import com.raytheon.uf.common.serialization.annotations.DynamicSerialize;
|
||||||
|
import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement;
|
||||||
|
import com.raytheon.uf.common.stats.AggregateRecord;
|
||||||
|
import com.raytheon.uf.common.stats.util.UnitUtils;
|
||||||
|
import com.raytheon.uf.common.time.TimeRange;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Statistical data object holding data to be graphed.
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
*
|
||||||
|
* SOFTWARE HISTORY
|
||||||
|
*
|
||||||
|
* Date Ticket# Engineer Description
|
||||||
|
* ------------ ---------- ----------- --------------------------
|
||||||
|
* Sep 07, 2012 728 mpduff Initial creation
|
||||||
|
*
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* @author mpduff
|
||||||
|
* @version 1.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
@XmlRootElement
|
||||||
|
@XmlAccessorType(XmlAccessType.NONE)
|
||||||
|
@DynamicSerialize
|
||||||
|
public class StatsData {
|
||||||
|
/** Key to this object */
|
||||||
|
@DynamicSerializeElement
|
||||||
|
private String key;
|
||||||
|
|
||||||
|
/** List of AggregateRecords */
|
||||||
|
@DynamicSerializeElement
|
||||||
|
private final List<AggregateRecord> recordList = new ArrayList<AggregateRecord>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Frequency (timestep) of the data 5 min, hourly, daily
|
||||||
|
*/
|
||||||
|
@DynamicSerializeElement
|
||||||
|
private int dataFrequency;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Time Range of the data in this object
|
||||||
|
*/
|
||||||
|
@DynamicSerializeElement
|
||||||
|
private TimeRange timeRange = new TimeRange();
|
||||||
|
|
||||||
|
/** List of DataPoint objects */
|
||||||
|
@DynamicSerializeElement
|
||||||
|
private List<DataPoint> pointList = new ArrayList<DataPoint>();
|
||||||
|
|
||||||
|
/** Map of millis -> StatsBin objects */
|
||||||
|
@DynamicSerializeElement
|
||||||
|
private Map<Long, StatsBin> bins;
|
||||||
|
|
||||||
|
/** UnitUtils object */
|
||||||
|
private UnitUtils unitUtils;
|
||||||
|
|
||||||
|
/** Constructor */
|
||||||
|
public StatsData() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*
|
||||||
|
* @param key
|
||||||
|
* Key to the object
|
||||||
|
* @param tsMillis
|
||||||
|
* timestep in ms
|
||||||
|
* @param timeRange
|
||||||
|
* TimeRange object
|
||||||
|
* @param unitUtils
|
||||||
|
* UnitUtils object
|
||||||
|
*/
|
||||||
|
public StatsData(String key, long tsMillis, TimeRange timeRange,
|
||||||
|
UnitUtils unitUtils) {
|
||||||
|
this.key = key;
|
||||||
|
this.dataFrequency = (int) tsMillis;
|
||||||
|
this.timeRange = timeRange;
|
||||||
|
this.unitUtils = unitUtils;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the minValue
|
||||||
|
*/
|
||||||
|
public Double getMinValue() {
|
||||||
|
double minValue = Integer.MAX_VALUE;
|
||||||
|
|
||||||
|
for (DataPoint point : pointList) {
|
||||||
|
if (point.getMin() < minValue) {
|
||||||
|
minValue = point.getMin();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return minValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the maxValue
|
||||||
|
*/
|
||||||
|
public Double getMaxValue() {
|
||||||
|
double maxValue = Integer.MIN_VALUE;
|
||||||
|
|
||||||
|
for (DataPoint point : pointList) {
|
||||||
|
if (point.getAvg() > maxValue) {
|
||||||
|
maxValue = point.getAvg();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return maxValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the dataFrequency
|
||||||
|
*/
|
||||||
|
public int getDataFrequency() {
|
||||||
|
return dataFrequency;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param dataFrequency
|
||||||
|
* the dataFrequency to set
|
||||||
|
*/
|
||||||
|
public void setDataFrequency(int dataFrequency) {
|
||||||
|
this.dataFrequency = dataFrequency;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the list of DataPoint objects for the key.
|
||||||
|
*
|
||||||
|
* @param key
|
||||||
|
* The key
|
||||||
|
* @return List of DataPoint objects
|
||||||
|
*/
|
||||||
|
public List<DataPoint> getData(String key) {
|
||||||
|
Collections.sort(pointList);
|
||||||
|
return pointList;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the timeRange
|
||||||
|
*/
|
||||||
|
public TimeRange getTimeRange() {
|
||||||
|
return timeRange;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param pointList
|
||||||
|
* the pointList to set
|
||||||
|
*/
|
||||||
|
public void setPointList(List<DataPoint> pointList) {
|
||||||
|
this.pointList = pointList;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add an AggregateRecord.
|
||||||
|
*
|
||||||
|
* @param rec
|
||||||
|
* the record to add
|
||||||
|
*/
|
||||||
|
public void addRecord(AggregateRecord rec) {
|
||||||
|
this.recordList.add(rec);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the key
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public String getKey() {
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the key
|
||||||
|
*
|
||||||
|
* @param key
|
||||||
|
* the key to set
|
||||||
|
*/
|
||||||
|
public void setKey(String key) {
|
||||||
|
this.key = key;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the StatsBin object map.
|
||||||
|
*
|
||||||
|
* @param bins
|
||||||
|
*/
|
||||||
|
public void setBins(Map<Long, StatsBin> bins) {
|
||||||
|
this.bins = bins;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Accumulates the AggregateRecord objects into the correct bins.
|
||||||
|
*/
|
||||||
|
public void accumulate(String key) {
|
||||||
|
pointList.clear();
|
||||||
|
for (AggregateRecord record : recordList) {
|
||||||
|
Date startDate = record.getStartDate().getTime();
|
||||||
|
|
||||||
|
long start = startDate.getTime();
|
||||||
|
long bin = getBinKey(start);
|
||||||
|
if (bins.get(bin) != null) {
|
||||||
|
bins.get(bin).setData(record);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
createPoints(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create the points for this key.
|
||||||
|
*
|
||||||
|
* @param dataKey
|
||||||
|
*/
|
||||||
|
private void createPoints(String dataKey) {
|
||||||
|
// Bins are created, now make the graph group member and point objects
|
||||||
|
// convert the data values before storing in the data object
|
||||||
|
double conversion = unitUtils.getConversion();
|
||||||
|
for (long key : bins.keySet()) {
|
||||||
|
StatsBin sb = bins.get(key);
|
||||||
|
List<AggregateRecord> dataList = sb.getData();
|
||||||
|
if (!dataList.isEmpty()) {
|
||||||
|
DataPoint point = new DataPoint();
|
||||||
|
point.setX(sb.getBinMillis());
|
||||||
|
|
||||||
|
for (AggregateRecord rec : dataList) {
|
||||||
|
// Check for an existing point object
|
||||||
|
point.setMax(rec.getMax() / conversion);
|
||||||
|
point.setMin(rec.getMin() / conversion);
|
||||||
|
point.setSum(rec.getSum() / conversion);
|
||||||
|
point.addToCount(rec.getCount());
|
||||||
|
}
|
||||||
|
|
||||||
|
pointList.add(point);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the bin key for the given millisecond value.
|
||||||
|
*
|
||||||
|
* @param millis
|
||||||
|
* The millisecond value
|
||||||
|
* @return The bin that should hold this millisecond value
|
||||||
|
*/
|
||||||
|
private long getBinKey(long millis) {
|
||||||
|
for (long bin : this.bins.keySet()) {
|
||||||
|
if (millis <= bins.get(bin).getBinMillis()) {
|
||||||
|
return bin;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the recordList
|
||||||
|
*/
|
||||||
|
public List<AggregateRecord> getRecordList() {
|
||||||
|
return recordList;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the pointList
|
||||||
|
*/
|
||||||
|
public List<DataPoint> getPointList() {
|
||||||
|
return pointList;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the bins
|
||||||
|
*/
|
||||||
|
public Map<Long, StatsBin> getBins() {
|
||||||
|
return bins;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param timeRange
|
||||||
|
* the timeRange to set
|
||||||
|
*/
|
||||||
|
public void setTimeRange(TimeRange timeRange) {
|
||||||
|
this.timeRange = timeRange;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,164 @@
|
||||||
|
/**
|
||||||
|
* This software was developed and / or modified by Raytheon Company,
|
||||||
|
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||||
|
*
|
||||||
|
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||||
|
* This software product contains export-restricted data whose
|
||||||
|
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||||
|
* to non-U.S. persons whether in the United States or abroad requires
|
||||||
|
* an export license or other authorization.
|
||||||
|
*
|
||||||
|
* Contractor Name: Raytheon Company
|
||||||
|
* Contractor Address: 6825 Pine Street, Suite 340
|
||||||
|
* Mail Stop B8
|
||||||
|
* Omaha, NE 68106
|
||||||
|
* 402.291.0100
|
||||||
|
*
|
||||||
|
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||||
|
* further licensing information.
|
||||||
|
**/
|
||||||
|
package com.raytheon.uf.common.stats.data;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stats Event helper object.
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
*
|
||||||
|
* SOFTWARE HISTORY
|
||||||
|
*
|
||||||
|
* Date Ticket# Engineer Description
|
||||||
|
* ------------ ---------- ----------- --------------------------
|
||||||
|
* Nov 8, 2012 728 mpduff Initial creation
|
||||||
|
*
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* @author mpduff
|
||||||
|
* @version 1.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class StatsEventData {
|
||||||
|
/** Event Type */
|
||||||
|
private String type;
|
||||||
|
|
||||||
|
/** Event display name */
|
||||||
|
private String displayName;
|
||||||
|
|
||||||
|
/** List of groups */
|
||||||
|
private List<String> groupList = new ArrayList<String>();
|
||||||
|
|
||||||
|
/** List of Attributes */
|
||||||
|
private List<String> attributeList = new ArrayList<String>();
|
||||||
|
|
||||||
|
/** Map of Display Name -> Name */
|
||||||
|
private final Map<String, String> groupMap = new HashMap<String, String>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the type
|
||||||
|
*/
|
||||||
|
public String getType() {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param type
|
||||||
|
* the type to set
|
||||||
|
*/
|
||||||
|
public void setType(String type) {
|
||||||
|
this.type = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the displayName
|
||||||
|
*/
|
||||||
|
public String getDisplayName() {
|
||||||
|
return displayName;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param displayName
|
||||||
|
* the displayName to set
|
||||||
|
*/
|
||||||
|
public void setDisplayName(String displayName) {
|
||||||
|
this.displayName = displayName;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the groupList
|
||||||
|
*/
|
||||||
|
public List<String> getGroupList() {
|
||||||
|
return groupList;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param groupList
|
||||||
|
* the groupList to set
|
||||||
|
*/
|
||||||
|
public void setGroupList(List<String> groupList) {
|
||||||
|
this.groupList = groupList;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the attributeList
|
||||||
|
*/
|
||||||
|
public List<String> getAttributeList() {
|
||||||
|
return attributeList;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param attributeList
|
||||||
|
* the attributeList to set
|
||||||
|
*/
|
||||||
|
public void setAttributeList(List<String> attributeList) {
|
||||||
|
this.attributeList = attributeList;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param group
|
||||||
|
* displayName of the group to add
|
||||||
|
*/
|
||||||
|
public void addGroup(String displayName, String name) {
|
||||||
|
this.groupList.add(displayName);
|
||||||
|
this.groupMap.put(displayName, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param attribute
|
||||||
|
* the attribute to add
|
||||||
|
*/
|
||||||
|
public void addAttribute(String attribute) {
|
||||||
|
this.attributeList.add(attribute);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the group list
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public String[] getGroups() {
|
||||||
|
return groupList.toArray(new String[groupList.size()]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the attribute list
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public String[] getAttributes() {
|
||||||
|
return attributeList.toArray(new String[groupList.size()]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the group name from the display name.
|
||||||
|
*
|
||||||
|
* @param displayName
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public String getGroupNameFromDisplayName(String displayName) {
|
||||||
|
return groupMap.get(displayName);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,183 @@
|
||||||
|
/**
|
||||||
|
* This software was developed and / or modified by Raytheon Company,
|
||||||
|
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||||
|
*
|
||||||
|
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||||
|
* This software product contains export-restricted data whose
|
||||||
|
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||||
|
* to non-U.S. persons whether in the United States or abroad requires
|
||||||
|
* an export license or other authorization.
|
||||||
|
*
|
||||||
|
* Contractor Name: Raytheon Company
|
||||||
|
* Contractor Address: 6825 Pine Street, Suite 340
|
||||||
|
* Mail Stop B8
|
||||||
|
* Omaha, NE 68106
|
||||||
|
* 402.291.0100
|
||||||
|
*
|
||||||
|
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||||
|
* further licensing information.
|
||||||
|
**/
|
||||||
|
package com.raytheon.uf.common.stats.data;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import com.raytheon.uf.common.serialization.annotations.DynamicSerialize;
|
||||||
|
import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Statistics Label Object.
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
*
|
||||||
|
* SOFTWARE HISTORY
|
||||||
|
*
|
||||||
|
* Date Ticket# Engineer Description
|
||||||
|
* ------------ ---------- ----------- --------------------------
|
||||||
|
* Oct 16, 2012 728 mpduff Initial creation
|
||||||
|
*
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* @author mpduff
|
||||||
|
* @version 1.0
|
||||||
|
*/
|
||||||
|
@DynamicSerialize
|
||||||
|
public class StatsLabelData {
|
||||||
|
/** Group string */
|
||||||
|
@DynamicSerializeElement
|
||||||
|
private String group = "";
|
||||||
|
|
||||||
|
/** List of group names */
|
||||||
|
@DynamicSerializeElement
|
||||||
|
private List<String> groupNames = new ArrayList<String>();
|
||||||
|
|
||||||
|
/** Recursive reference */
|
||||||
|
@DynamicSerializeElement
|
||||||
|
private StatsLabelData statsLabelData = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor.
|
||||||
|
*/
|
||||||
|
public StatsLabelData() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor.
|
||||||
|
*
|
||||||
|
* @param group
|
||||||
|
* @param groupNames
|
||||||
|
*/
|
||||||
|
public StatsLabelData(String group, List<String> groupNames) {
|
||||||
|
this.groupNames = groupNames;
|
||||||
|
this.group = group;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the group.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public String getGroup() {
|
||||||
|
return group;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the group
|
||||||
|
*
|
||||||
|
* @param group
|
||||||
|
*/
|
||||||
|
public void setGroup(String group) {
|
||||||
|
this.group = group;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the group names
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public List<String> getGroupNames() {
|
||||||
|
return groupNames;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the group name list
|
||||||
|
*
|
||||||
|
* @param groupNames
|
||||||
|
*/
|
||||||
|
public void setGroupNames(List<String> groupNames) {
|
||||||
|
this.groupNames = groupNames;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the StatsLabelData object.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public StatsLabelData getStatsLabelData() {
|
||||||
|
return statsLabelData;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the StatsLabelData object
|
||||||
|
*
|
||||||
|
* @param statsLabelData
|
||||||
|
*/
|
||||||
|
public void setStatsLabelData(StatsLabelData statsLabelData) {
|
||||||
|
this.statsLabelData = statsLabelData;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a group name.
|
||||||
|
*
|
||||||
|
* @param name
|
||||||
|
*/
|
||||||
|
public void addGroupName(String name) {
|
||||||
|
groupNames.add(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Make the data keys
|
||||||
|
*
|
||||||
|
* @return List of the data keys
|
||||||
|
*/
|
||||||
|
public List<String> makeKeys() {
|
||||||
|
ArrayList<String> keysArray = new ArrayList<String>();
|
||||||
|
|
||||||
|
if (statsLabelData == null) {
|
||||||
|
return groupNames;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<String> subKeys = statsLabelData.makeKeys();
|
||||||
|
|
||||||
|
for (String grpName : groupNames) {
|
||||||
|
for (String subKey : subKeys) {
|
||||||
|
keysArray.add(grpName + ":" + subKey);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return keysArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the group and group names map.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public LinkedHashMap<String, List<String>> getGroupAndNamesMap() {
|
||||||
|
LinkedHashMap<String, List<String>> groupMap = new LinkedHashMap<String, List<String>>();
|
||||||
|
|
||||||
|
groupMap.put(group, groupNames);
|
||||||
|
|
||||||
|
if (statsLabelData != null) {
|
||||||
|
LinkedHashMap<String, List<String>> tmpMap = statsLabelData
|
||||||
|
.getGroupAndNamesMap();
|
||||||
|
for (String s : tmpMap.keySet()) {
|
||||||
|
groupMap.put(s, tmpMap.get(s));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return groupMap;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,287 @@
|
||||||
|
/**
|
||||||
|
* This software was developed and / or modified by Raytheon Company,
|
||||||
|
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||||
|
*
|
||||||
|
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||||
|
* This software product contains export-restricted data whose
|
||||||
|
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||||
|
* to non-U.S. persons whether in the United States or abroad requires
|
||||||
|
* an export license or other authorization.
|
||||||
|
*
|
||||||
|
* Contractor Name: Raytheon Company
|
||||||
|
* Contractor Address: 6825 Pine Street, Suite 340
|
||||||
|
* Mail Stop B8
|
||||||
|
* Omaha, NE 68106
|
||||||
|
* 402.291.0100
|
||||||
|
*
|
||||||
|
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||||
|
* further licensing information.
|
||||||
|
**/
|
||||||
|
package com.raytheon.uf.common.stats.util;
|
||||||
|
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import com.raytheon.uf.common.serialization.ISerializableObject;
|
||||||
|
import com.raytheon.uf.common.serialization.annotations.DynamicSerialize;
|
||||||
|
import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement;
|
||||||
|
import com.raytheon.uf.common.time.util.TimeUtil;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Utility class for data size conversions. KB vs MB vs GB
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
*
|
||||||
|
* SOFTWARE HISTORY
|
||||||
|
*
|
||||||
|
* Date Ticket# Engineer Description
|
||||||
|
* ------------ ---------- ----------- --------------------------
|
||||||
|
* Nov 14, 2012 728 mpduff Initial creation.
|
||||||
|
*
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* @author mpduff
|
||||||
|
* @version 1.0
|
||||||
|
*/
|
||||||
|
@DynamicSerialize
|
||||||
|
public class UnitUtils implements ISerializableObject {
|
||||||
|
/** Bytes per Kilobyte */
|
||||||
|
private static final double BYTES_PER_KILOBYTE = 1024.0;
|
||||||
|
|
||||||
|
/** Different unit types for statistics */
|
||||||
|
public static enum UnitTypes {
|
||||||
|
DATA_SIZE, TIME, COUNT
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Data Size Conversions
|
||||||
|
*/
|
||||||
|
public static enum DataSize {
|
||||||
|
KB("KB", BYTES_PER_KILOBYTE), MB("MB", BYTES_PER_KILOBYTE
|
||||||
|
* BYTES_PER_KILOBYTE), GB("GB", BYTES_PER_KILOBYTE
|
||||||
|
* BYTES_PER_KILOBYTE * BYTES_PER_KILOBYTE);
|
||||||
|
|
||||||
|
private final String unit;
|
||||||
|
|
||||||
|
private final double conversion;
|
||||||
|
|
||||||
|
private static Set<String> dataUnits;
|
||||||
|
|
||||||
|
private DataSize(String unit, double conversion) {
|
||||||
|
this.unit = unit;
|
||||||
|
this.conversion = conversion;
|
||||||
|
populateSet();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void populateSet() {
|
||||||
|
dataUnits = new HashSet<String>();
|
||||||
|
dataUnits.add("KB");
|
||||||
|
dataUnits.add("MB");
|
||||||
|
dataUnits.add("GB");
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDataUnit() {
|
||||||
|
return unit;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getConversion() {
|
||||||
|
return conversion;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Set<String> getDataUnits() {
|
||||||
|
return dataUnits;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Time Conversions.
|
||||||
|
*/
|
||||||
|
public static enum TimeConversion {
|
||||||
|
MS("ms", 1), Second("seconds", TimeUtil.MILLIS_PER_SECOND), Minute(
|
||||||
|
"minutes", TimeUtil.MILLIS_PER_MINUTE), Hour("hours",
|
||||||
|
TimeUtil.MILLIS_PER_HOUR);
|
||||||
|
|
||||||
|
private static Set<String> dataUnits;
|
||||||
|
|
||||||
|
private final String unit;
|
||||||
|
|
||||||
|
private final double conversion;
|
||||||
|
|
||||||
|
private TimeConversion(String unit, double conversion) {
|
||||||
|
this.unit = unit;
|
||||||
|
this.conversion = conversion;
|
||||||
|
populateSet();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void populateSet() {
|
||||||
|
dataUnits = new HashSet<String>();
|
||||||
|
dataUnits.add("seconds");
|
||||||
|
dataUnits.add("ms");
|
||||||
|
dataUnits.add("minutes");
|
||||||
|
dataUnits.add("hours");
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDataUnit() {
|
||||||
|
return unit;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getConversion() {
|
||||||
|
return conversion;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Set<String> getDataUnits() {
|
||||||
|
return dataUnits;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** The event type */
|
||||||
|
private String eventType;
|
||||||
|
|
||||||
|
/** The data type */
|
||||||
|
private String dataType;
|
||||||
|
|
||||||
|
/** The display unit */
|
||||||
|
@DynamicSerializeElement
|
||||||
|
private String displayUnit;
|
||||||
|
|
||||||
|
/** The unit type */
|
||||||
|
@DynamicSerializeElement
|
||||||
|
private UnitTypes unitType;
|
||||||
|
|
||||||
|
/** Copnversion factor */
|
||||||
|
@DynamicSerializeElement
|
||||||
|
private double conversion = 1;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*/
|
||||||
|
public UnitUtils() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*
|
||||||
|
* @param eventType
|
||||||
|
* event type
|
||||||
|
* @param dataType
|
||||||
|
* event attribute/data type
|
||||||
|
*/
|
||||||
|
public UnitUtils(String eventType, String dataType) {
|
||||||
|
this.eventType = eventType;
|
||||||
|
this.dataType = dataType;
|
||||||
|
// Default to count
|
||||||
|
this.unitType = UnitTypes.COUNT;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The largest value of the data set. This is used to determine which
|
||||||
|
* conversion to use if one is not specified.
|
||||||
|
*
|
||||||
|
* @param value
|
||||||
|
* Largest value of the data set
|
||||||
|
*
|
||||||
|
* @return The conversion factor
|
||||||
|
*/
|
||||||
|
public void setConversion(double value) {
|
||||||
|
// Which unit type is it?
|
||||||
|
if (unitType == UnitTypes.COUNT) {
|
||||||
|
conversion = 1;
|
||||||
|
} else if (unitType == UnitTypes.DATA_SIZE) {
|
||||||
|
if (value < DataSize.MB.getConversion()) {
|
||||||
|
conversion = DataSize.KB.getConversion();
|
||||||
|
} else if (value < DataSize.GB.getConversion()) {
|
||||||
|
conversion = DataSize.MB.getConversion();
|
||||||
|
} else if (value >= DataSize.GB.getConversion()) {
|
||||||
|
conversion = DataSize.GB.getConversion();
|
||||||
|
}
|
||||||
|
} else if (unitType == UnitTypes.TIME) {
|
||||||
|
if (value < TimeUtil.MILLIS_PER_MINUTE) {
|
||||||
|
conversion = TimeUtil.MILLIS_PER_SECOND;
|
||||||
|
} else if (value < TimeUtil.MILLIS_PER_HOUR) {
|
||||||
|
conversion = TimeUtil.MILLIS_PER_MINUTE;
|
||||||
|
} else {
|
||||||
|
conversion = TimeUtil.MILLIS_PER_SECOND;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the eventType
|
||||||
|
*/
|
||||||
|
public String getEventType() {
|
||||||
|
return eventType;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the dataType
|
||||||
|
*/
|
||||||
|
public String getDataType() {
|
||||||
|
return dataType;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the conversion
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public double getConversion() {
|
||||||
|
return conversion;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the unitType
|
||||||
|
*/
|
||||||
|
public UnitTypes getUnitType() {
|
||||||
|
return unitType;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param unitType
|
||||||
|
* the unitType to set
|
||||||
|
*/
|
||||||
|
public void setUnitType(UnitTypes unitType) {
|
||||||
|
this.unitType = unitType;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the displayUnit
|
||||||
|
*/
|
||||||
|
public String getDisplayUnit() {
|
||||||
|
return displayUnit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the display unit.
|
||||||
|
*
|
||||||
|
* @param displayUnit
|
||||||
|
*/
|
||||||
|
public void setDisplayUnit(String displayUnit) {
|
||||||
|
this.displayUnit = displayUnit;
|
||||||
|
|
||||||
|
// Determine the unitType
|
||||||
|
if (DataSize.getDataUnits().contains(displayUnit)) {
|
||||||
|
unitType = UnitTypes.DATA_SIZE;
|
||||||
|
} else if (TimeConversion.getDataUnits().contains(displayUnit)) {
|
||||||
|
unitType = UnitTypes.TIME;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (unitType == UnitTypes.DATA_SIZE) {
|
||||||
|
if (displayUnit.equals(DataSize.KB.getDataUnit())) {
|
||||||
|
conversion = DataSize.KB.getConversion();
|
||||||
|
} else if (displayUnit.equals(DataSize.MB.getDataUnit())) {
|
||||||
|
conversion = DataSize.MB.getConversion();
|
||||||
|
} else if (displayUnit.equals(DataSize.GB.getDataUnit())) {
|
||||||
|
conversion = DataSize.GB.getConversion();
|
||||||
|
}
|
||||||
|
} else if (unitType == UnitTypes.TIME) {
|
||||||
|
if (displayUnit.equals(TimeConversion.MS.getDataUnit())) {
|
||||||
|
conversion = 1;
|
||||||
|
} else if (displayUnit.equals(TimeConversion.Second.getDataUnit())) {
|
||||||
|
conversion = TimeUtil.MILLIS_PER_SECOND;
|
||||||
|
} else if (displayUnit.equals(TimeConversion.Minute.getDataUnit())) {
|
||||||
|
conversion = TimeUtil.MILLIS_PER_MINUTE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -56,6 +56,10 @@ public class StatisticsAggregate {
|
||||||
@DynamicSerializeElement
|
@DynamicSerializeElement
|
||||||
private String displayName;
|
private String displayName;
|
||||||
|
|
||||||
|
@XmlAttribute
|
||||||
|
@DynamicSerializeElement
|
||||||
|
private String displayUnit;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the field
|
* @return the field
|
||||||
*/
|
*/
|
||||||
|
@ -85,4 +89,18 @@ public class StatisticsAggregate {
|
||||||
public void setDisplayName(String displayName) {
|
public void setDisplayName(String displayName) {
|
||||||
this.displayName = displayName;
|
this.displayName = displayName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the displayUnit
|
||||||
|
*/
|
||||||
|
public String getDisplayUnit() {
|
||||||
|
return displayUnit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param displayUnit the displayUnit to set
|
||||||
|
*/
|
||||||
|
public void setDisplayUnit(String displayUnit) {
|
||||||
|
this.displayUnit = displayUnit;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,7 +20,9 @@
|
||||||
package com.raytheon.uf.common.stats.xml;
|
package com.raytheon.uf.common.stats.xml;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
import javax.xml.bind.annotation.XmlAccessType;
|
import javax.xml.bind.annotation.XmlAccessType;
|
||||||
import javax.xml.bind.annotation.XmlAccessorType;
|
import javax.xml.bind.annotation.XmlAccessorType;
|
||||||
|
@ -77,13 +79,13 @@ public class StatisticsConfig implements ISerializableObject {
|
||||||
* @return List<String> of categories
|
* @return List<String> of categories
|
||||||
*/
|
*/
|
||||||
public List<String> getCategories() {
|
public List<String> getCategories() {
|
||||||
List<String> categories = new ArrayList<String>();
|
Set<String> categories = new HashSet<String>();
|
||||||
if (events != null && events.size() > 0) {
|
if (events != null && events.size() > 0) {
|
||||||
for (StatisticsEvent event : events) {
|
for (StatisticsEvent event : events) {
|
||||||
categories.add(event.getCategory());
|
categories.add(event.getCategory());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return categories;
|
return new ArrayList<String>(categories);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,19 +1,19 @@
|
||||||
/**
|
/**
|
||||||
* This software was developed and / or modified by Raytheon Company,
|
* This software was developed and / or modified by Raytheon Company,
|
||||||
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||||
*
|
*
|
||||||
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||||
* This software product contains export-restricted data whose
|
* This software product contains export-restricted data whose
|
||||||
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||||
* to non-U.S. persons whether in the United States or abroad requires
|
* to non-U.S. persons whether in the United States or abroad requires
|
||||||
* an export license or other authorization.
|
* an export license or other authorization.
|
||||||
*
|
*
|
||||||
* Contractor Name: Raytheon Company
|
* Contractor Name: Raytheon Company
|
||||||
* Contractor Address: 6825 Pine Street, Suite 340
|
* Contractor Address: 6825 Pine Street, Suite 340
|
||||||
* Mail Stop B8
|
* Mail Stop B8
|
||||||
* Omaha, NE 68106
|
* Omaha, NE 68106
|
||||||
* 402.291.0100
|
* 402.291.0100
|
||||||
*
|
*
|
||||||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||||
* further licensing information.
|
* further licensing information.
|
||||||
**/
|
**/
|
||||||
|
@ -31,18 +31,19 @@ import com.raytheon.uf.common.time.SimulatedTime;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Utilities for time, some extracted from Util.
|
* Utilities for time, some extracted from Util.
|
||||||
*
|
*
|
||||||
* <pre>
|
* <pre>
|
||||||
*
|
*
|
||||||
* SOFTWARE HISTORY
|
* SOFTWARE HISTORY
|
||||||
* Date Ticket# Engineer Description
|
* Date Ticket# Engineer Description
|
||||||
* ------------ ---------- ----------- --------------------------
|
* ------------ ---------- ----------- --------------------------
|
||||||
* Feb 02, 2009 njensen Initial creation
|
* Feb 02, 2009 njensen Initial creation
|
||||||
* Sep 11, 2012 1154 djohnson Add MILLIS constants and isNewerDay().
|
* Sep 11, 2012 1154 djohnson Add MILLIS constants and isNewerDay().
|
||||||
* Nov 09, 2012 1322 djohnson Add SECONDS_PER_MINUTE.
|
* Nov 09, 2012 1322 djohnson Add SECONDS_PER_MINUTE.
|
||||||
*
|
* Nov 21, 2012 728 mpduff Added MILLIS_PER_MONTH.
|
||||||
|
*
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
* @author njensen
|
* @author njensen
|
||||||
* @version 1.0
|
* @version 1.0
|
||||||
*/
|
*/
|
||||||
|
@ -54,11 +55,11 @@ public class TimeUtil {
|
||||||
* only want to keep track of times in a conditional sense, such as if a
|
* only want to keep track of times in a conditional sense, such as if a
|
||||||
* logging priority is enabled. This is an example of the Null Object
|
* logging priority is enabled. This is an example of the Null Object
|
||||||
* pattern.
|
* pattern.
|
||||||
*
|
*
|
||||||
* @see http://en.wikipedia.org/wiki/Null_Object_pattern
|
* @see http://en.wikipedia.org/wiki/Null_Object_pattern
|
||||||
*
|
*
|
||||||
* @author djohnson
|
* @author djohnson
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
private static class NullClock extends AbstractTimer {
|
private static class NullClock extends AbstractTimer {
|
||||||
@Override
|
@Override
|
||||||
|
@ -70,9 +71,9 @@ public class TimeUtil {
|
||||||
/**
|
/**
|
||||||
* Delegates the retrieval of the current time to the system clock.
|
* Delegates the retrieval of the current time to the system clock.
|
||||||
* Production code will always use this.
|
* Production code will always use this.
|
||||||
*
|
*
|
||||||
* @author djohnson
|
* @author djohnson
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
private static class SystemTimeStrategy implements ITimeStrategy {
|
private static class SystemTimeStrategy implements ITimeStrategy {
|
||||||
@Override
|
@Override
|
||||||
|
@ -95,6 +96,8 @@ public class TimeUtil {
|
||||||
|
|
||||||
public static final long MILLIS_PER_WEEK = MILLIS_PER_DAY * 7;
|
public static final long MILLIS_PER_WEEK = MILLIS_PER_DAY * 7;
|
||||||
|
|
||||||
|
public static final long MILLIS_PER_MONTH = MILLIS_PER_DAY * 30;
|
||||||
|
|
||||||
public static final long MILLIS_PER_YEAR = 3600 * 24 * 1000 * 365;
|
public static final long MILLIS_PER_YEAR = 3600 * 24 * 1000 * 365;
|
||||||
|
|
||||||
public static final int SECONDS_PER_MINUTE = 60;
|
public static final int SECONDS_PER_MINUTE = 60;
|
||||||
|
@ -123,7 +126,7 @@ public class TimeUtil {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Converts a Calendar in the local time zone to a GMT date
|
* Converts a Calendar in the local time zone to a GMT date
|
||||||
*
|
*
|
||||||
* @param cal
|
* @param cal
|
||||||
* A Calendar object in the local time zone
|
* A Calendar object in the local time zone
|
||||||
* @return The GMT date
|
* @return The GMT date
|
||||||
|
@ -154,7 +157,7 @@ public class TimeUtil {
|
||||||
* configured the system to a specific time. Those purposes are handled by
|
* configured the system to a specific time. Those purposes are handled by
|
||||||
* the {@link SimulatedTime} class. The {@link Date} and {@link Calendar}
|
* the {@link SimulatedTime} class. The {@link Date} and {@link Calendar}
|
||||||
* returning methods in this class will delegate to {@link SimulatedTime}.
|
* returning methods in this class will delegate to {@link SimulatedTime}.
|
||||||
*
|
*
|
||||||
* @see {@link SimulatedTime}
|
* @see {@link SimulatedTime}
|
||||||
* @return the current time in milliseconds
|
* @return the current time in milliseconds
|
||||||
*/
|
*/
|
||||||
|
@ -164,7 +167,7 @@ public class TimeUtil {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Formats a calendar object into the following format yyyy-MM-dd_HH:mm:ss.S
|
* Formats a calendar object into the following format yyyy-MM-dd_HH:mm:ss.S
|
||||||
*
|
*
|
||||||
* @param cal
|
* @param cal
|
||||||
* The calendar to format
|
* The calendar to format
|
||||||
* @return The formatted result
|
* @return The formatted result
|
||||||
|
@ -182,7 +185,7 @@ public class TimeUtil {
|
||||||
/**
|
/**
|
||||||
* Retrieve date as a string in the index standard format: yyyy-MM-dd
|
* Retrieve date as a string in the index standard format: yyyy-MM-dd
|
||||||
* kk:mm:ss.SSS
|
* kk:mm:ss.SSS
|
||||||
*
|
*
|
||||||
* @param aCalendar
|
* @param aCalendar
|
||||||
* A Calendar instance
|
* A Calendar instance
|
||||||
* @return The formatted date string from the Calendar instance
|
* @return The formatted date string from the Calendar instance
|
||||||
|
@ -194,7 +197,7 @@ public class TimeUtil {
|
||||||
/**
|
/**
|
||||||
* Retrieve date as a string in the index standard format: yyyy-MM-dd
|
* Retrieve date as a string in the index standard format: yyyy-MM-dd
|
||||||
* kk:mm:ss.SSS
|
* kk:mm:ss.SSS
|
||||||
*
|
*
|
||||||
* @param aDate
|
* @param aDate
|
||||||
* A Date instance
|
* A Date instance
|
||||||
* @return The formatted date string from the Date instance
|
* @return The formatted date string from the Date instance
|
||||||
|
@ -225,7 +228,7 @@ public class TimeUtil {
|
||||||
* Retrieve a {@link ITimer} instance that will only actually keep track of
|
* Retrieve a {@link ITimer} instance that will only actually keep track of
|
||||||
* time if the specified priority level is enabled. This allows efficient
|
* time if the specified priority level is enabled. This allows efficient
|
||||||
* use of system resources, while calling code need not change.
|
* use of system resources, while calling code need not change.
|
||||||
*
|
*
|
||||||
* @param handler
|
* @param handler
|
||||||
* the handler to use to check for a priority level being enabled
|
* the handler to use to check for a priority level being enabled
|
||||||
* @param priority
|
* @param priority
|
||||||
|
@ -240,7 +243,7 @@ public class TimeUtil {
|
||||||
/**
|
/**
|
||||||
* Retrieve a {@link ITimer} that allows the demarcation of arbitrary start
|
* Retrieve a {@link ITimer} that allows the demarcation of arbitrary start
|
||||||
* and stop times.
|
* and stop times.
|
||||||
*
|
*
|
||||||
* @return a {@link ITimer}
|
* @return a {@link ITimer}
|
||||||
*/
|
*/
|
||||||
public static ITimer getTimer() {
|
public static ITimer getTimer() {
|
||||||
|
@ -250,7 +253,7 @@ public class TimeUtil {
|
||||||
/**
|
/**
|
||||||
* Check whether the time represented by a {@link Date} is a new day
|
* Check whether the time represented by a {@link Date} is a new day
|
||||||
* compared to another {@link Date} object.
|
* compared to another {@link Date} object.
|
||||||
*
|
*
|
||||||
* @param earlierDate
|
* @param earlierDate
|
||||||
* the earlier date
|
* the earlier date
|
||||||
* @param laterDate
|
* @param laterDate
|
||||||
|
@ -277,7 +280,7 @@ public class TimeUtil {
|
||||||
* Return a new {@link Calendar} instance. This method delegates to the
|
* Return a new {@link Calendar} instance. This method delegates to the
|
||||||
* {@link SimulatedTime} class to determine the currently configured system
|
* {@link SimulatedTime} class to determine the currently configured system
|
||||||
* time.
|
* time.
|
||||||
*
|
*
|
||||||
* @see {@link SimulatedTime}
|
* @see {@link SimulatedTime}
|
||||||
* @return the calendar
|
* @return the calendar
|
||||||
*/
|
*/
|
||||||
|
@ -291,7 +294,7 @@ public class TimeUtil {
|
||||||
* Return a new {@link Calendar} instance for the specified {@link TimeZone}
|
* Return a new {@link Calendar} instance for the specified {@link TimeZone}
|
||||||
* . This method delegates to the {@link SimulatedTime} class to determine
|
* . This method delegates to the {@link SimulatedTime} class to determine
|
||||||
* the currently configured system time.
|
* the currently configured system time.
|
||||||
*
|
*
|
||||||
* @param timeZone
|
* @param timeZone
|
||||||
* the time zone
|
* the time zone
|
||||||
* @see {@link SimulatedTime}
|
* @see {@link SimulatedTime}
|
||||||
|
@ -307,7 +310,7 @@ public class TimeUtil {
|
||||||
* Return a new {@link Date} instance. This method delegates to the
|
* Return a new {@link Date} instance. This method delegates to the
|
||||||
* {@link SimulatedTime} class to determine the currently configured system
|
* {@link SimulatedTime} class to determine the currently configured system
|
||||||
* time.
|
* time.
|
||||||
*
|
*
|
||||||
* @see {@link SimulatedTime}
|
* @see {@link SimulatedTime}
|
||||||
* @return the current {@link Date}
|
* @return the current {@link Date}
|
||||||
*/
|
*/
|
||||||
|
@ -319,7 +322,7 @@ public class TimeUtil {
|
||||||
* Return a new ImmutableDate. This method delegates to the
|
* Return a new ImmutableDate. This method delegates to the
|
||||||
* {@link SimulatedTime} class to determine the currently configured system
|
* {@link SimulatedTime} class to determine the currently configured system
|
||||||
* time.
|
* time.
|
||||||
*
|
*
|
||||||
* @see {@link SimulatedTime}
|
* @see {@link SimulatedTime}
|
||||||
* @return an immutable date for the current time
|
* @return an immutable date for the current time
|
||||||
*/
|
*/
|
||||||
|
|
17
edexOsgi/com.raytheon.uf.edex.registry.feature/.project
Normal file
17
edexOsgi/com.raytheon.uf.edex.registry.feature/.project
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<projectDescription>
|
||||||
|
<name>com.raytheon.uf.edex.registry.feature</name>
|
||||||
|
<comment></comment>
|
||||||
|
<projects>
|
||||||
|
</projects>
|
||||||
|
<buildSpec>
|
||||||
|
<buildCommand>
|
||||||
|
<name>org.eclipse.pde.FeatureBuilder</name>
|
||||||
|
<arguments>
|
||||||
|
</arguments>
|
||||||
|
</buildCommand>
|
||||||
|
</buildSpec>
|
||||||
|
<natures>
|
||||||
|
<nature>org.eclipse.pde.FeatureNature</nature>
|
||||||
|
</natures>
|
||||||
|
</projectDescription>
|
|
@ -0,0 +1,13 @@
|
||||||
|
<beans
|
||||||
|
xmlns="http://www.springframework.org/schema/beans"
|
||||||
|
xmlns:amq="http://activemq.apache.org/schema/core"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
|
||||||
|
http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd">
|
||||||
|
|
||||||
|
<bean id="statsHandler" class="com.raytheon.uf.edex.stats.handler.GraphDataHandler"/>
|
||||||
|
<bean factory-bean="handlerRegistry" factory-method="register">
|
||||||
|
<constructor-arg value="com.raytheon.uf.common.stats.GraphDataRequest"/>
|
||||||
|
<constructor-arg ref="statsHandler"/>
|
||||||
|
</bean>
|
||||||
|
</beans>
|
|
@ -0,0 +1,322 @@
|
||||||
|
/**
|
||||||
|
* This software was developed and / or modified by Raytheon Company,
|
||||||
|
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||||
|
*
|
||||||
|
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||||
|
* This software product contains export-restricted data whose
|
||||||
|
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||||
|
* to non-U.S. persons whether in the United States or abroad requires
|
||||||
|
* an export license or other authorization.
|
||||||
|
*
|
||||||
|
* Contractor Name: Raytheon Company
|
||||||
|
* Contractor Address: 6825 Pine Street, Suite 340
|
||||||
|
* Mail Stop B8
|
||||||
|
* Omaha, NE 68106
|
||||||
|
* 402.291.0100
|
||||||
|
*
|
||||||
|
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||||
|
* further licensing information.
|
||||||
|
**/
|
||||||
|
package com.raytheon.uf.edex.stats.data;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.TreeMap;
|
||||||
|
import java.util.TreeSet;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
import com.google.common.annotations.VisibleForTesting;
|
||||||
|
import com.raytheon.uf.common.stats.AggregateRecord;
|
||||||
|
import com.raytheon.uf.common.stats.data.GraphData;
|
||||||
|
import com.raytheon.uf.common.stats.data.StatsBin;
|
||||||
|
import com.raytheon.uf.common.stats.data.StatsData;
|
||||||
|
import com.raytheon.uf.common.stats.data.StatsLabelData;
|
||||||
|
import com.raytheon.uf.common.stats.util.UnitUtils;
|
||||||
|
import com.raytheon.uf.common.time.TimeRange;
|
||||||
|
import com.raytheon.uf.common.time.util.TimeUtil;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Accumulates the statistics data.
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
*
|
||||||
|
* SOFTWARE HISTORY
|
||||||
|
*
|
||||||
|
* Date Ticket# Engineer Description
|
||||||
|
* ------------ ---------- ----------- --------------------------
|
||||||
|
* Nov 15, 2012 728 mpduff Initial creation
|
||||||
|
*
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* @author mpduff
|
||||||
|
* @version 1.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class StatsDataAccumulator {
|
||||||
|
private final Pattern COLON_PATTERN = Pattern.compile(":");
|
||||||
|
|
||||||
|
private final Pattern DASH_PATTERN = Pattern.compile("-");
|
||||||
|
|
||||||
|
private final String COLON = ":";
|
||||||
|
|
||||||
|
/** List of records */
|
||||||
|
private AggregateRecord[] records;
|
||||||
|
|
||||||
|
/** List of groups */
|
||||||
|
@VisibleForTesting
|
||||||
|
List<String> groups;
|
||||||
|
|
||||||
|
/** TimeRange oject */
|
||||||
|
private TimeRange timeRange;
|
||||||
|
|
||||||
|
/** Event type */
|
||||||
|
private String eventType;
|
||||||
|
|
||||||
|
/** Event data type/attribute */
|
||||||
|
private String dataType;
|
||||||
|
|
||||||
|
/** Display unit */
|
||||||
|
private String displayUnit;
|
||||||
|
|
||||||
|
/** Data's timestep */
|
||||||
|
private long timeStep;
|
||||||
|
|
||||||
|
/** Stats data map */
|
||||||
|
@VisibleForTesting
|
||||||
|
final Map<String, StatsData> statsDataMap = new HashMap<String, StatsData>();
|
||||||
|
|
||||||
|
/** Map of time in ms -> StatsBin objects */
|
||||||
|
@VisibleForTesting
|
||||||
|
final Map<Long, StatsBin> bins = new TreeMap<Long, StatsBin>();
|
||||||
|
|
||||||
|
/** Map of group name -> group members */
|
||||||
|
@VisibleForTesting
|
||||||
|
Map<String, Set<String>> groupMemberMap = new HashMap<String, Set<String>>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the AggregateRecord[]
|
||||||
|
*
|
||||||
|
* @param records
|
||||||
|
* array of AggregateRecord objects
|
||||||
|
*/
|
||||||
|
public void setRecords(AggregateRecord[] records) {
|
||||||
|
this.records = records;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set up the grouping objects.
|
||||||
|
*/
|
||||||
|
@VisibleForTesting
|
||||||
|
public void setupGroupings() {
|
||||||
|
for (AggregateRecord aggRec : records) {
|
||||||
|
String grouping = aggRec.getGrouping();
|
||||||
|
String[] groupString = DASH_PATTERN.split(grouping);
|
||||||
|
String group;
|
||||||
|
String member;
|
||||||
|
for (String grp : groupString) {
|
||||||
|
String[] parts = COLON_PATTERN.split(grp);
|
||||||
|
group = parts[0];
|
||||||
|
member = parts[1];
|
||||||
|
if (!groupMemberMap.containsKey(group)) {
|
||||||
|
groupMemberMap.put(group, new TreeSet<String>());
|
||||||
|
}
|
||||||
|
|
||||||
|
groupMemberMap.get(group).add(member);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
groups = new ArrayList<String>(groupMemberMap.keySet());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the GraphData object
|
||||||
|
*
|
||||||
|
* @param groups
|
||||||
|
* List of groups
|
||||||
|
* @return The GraphData object
|
||||||
|
*/
|
||||||
|
public GraphData getGraphData(List<String> groups) {
|
||||||
|
// Create the StatsLableData object
|
||||||
|
// Create the keys (owner:plugin:provider)
|
||||||
|
// Loop backwards over the data
|
||||||
|
StatsLabelData prevLabelData = null;
|
||||||
|
StatsLabelData statsLabelData = null;
|
||||||
|
UnitUtils unitUtils = new UnitUtils(eventType, dataType);
|
||||||
|
unitUtils.setDisplayUnit(displayUnit);
|
||||||
|
|
||||||
|
for (int i = groups.size() - 1; i >= 0; i--) {
|
||||||
|
String group = groups.get(i);
|
||||||
|
statsLabelData = new StatsLabelData(group, new ArrayList<String>(
|
||||||
|
groupMemberMap.get(group)));
|
||||||
|
if (prevLabelData != null) {
|
||||||
|
statsLabelData.setStatsLabelData(prevLabelData);
|
||||||
|
}
|
||||||
|
prevLabelData = statsLabelData;
|
||||||
|
}
|
||||||
|
|
||||||
|
gather(unitUtils, groups);
|
||||||
|
|
||||||
|
// StatsLabelData is created and holds all the keys
|
||||||
|
GraphData graphData = new GraphData();
|
||||||
|
graphData.setStatsLabelData(statsLabelData);
|
||||||
|
graphData.setDisplayUnit(displayUnit);
|
||||||
|
graphData.setStatsDataMap(statsDataMap);
|
||||||
|
graphData.setTimeRange(timeRange);
|
||||||
|
graphData.setKeys(new ArrayList<String>(this.statsDataMap.keySet()));
|
||||||
|
graphData.setUnitUtils(unitUtils);
|
||||||
|
graphData.setKeySequence(groups);
|
||||||
|
|
||||||
|
return graphData;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create the StatsDataMap keys
|
||||||
|
*
|
||||||
|
* @param unitUtils
|
||||||
|
* UnitUtils object
|
||||||
|
* @param groups
|
||||||
|
* List of groups
|
||||||
|
*/
|
||||||
|
@VisibleForTesting
|
||||||
|
void createStatsDataMap(UnitUtils unitUtils, List<String> groups) {
|
||||||
|
Map<String, String> keySequenceMap = new LinkedHashMap<String, String>();
|
||||||
|
for (String key : groups) {
|
||||||
|
keySequenceMap.put(key, "");
|
||||||
|
}
|
||||||
|
|
||||||
|
String builtKey = "";
|
||||||
|
for (AggregateRecord record : records) {
|
||||||
|
if (record.getEventType().equals(eventType)
|
||||||
|
&& record.getField().equals(dataType)) {
|
||||||
|
|
||||||
|
// Have a matching record
|
||||||
|
for (String key : keySequenceMap.keySet()) {
|
||||||
|
keySequenceMap.put(key, "");
|
||||||
|
}
|
||||||
|
String[] groupings = DASH_PATTERN.split(record.getGrouping());
|
||||||
|
|
||||||
|
for (String grouping : groupings) {
|
||||||
|
String[] parts = COLON_PATTERN.split(grouping);
|
||||||
|
String group = parts[0];
|
||||||
|
String groupMember = parts[1];
|
||||||
|
|
||||||
|
for (String key : keySequenceMap.keySet()) {
|
||||||
|
if (group.equals(key)) {
|
||||||
|
keySequenceMap.put(key, keySequenceMap.get(key)
|
||||||
|
.concat(groupMember + COLON));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (String key : keySequenceMap.keySet()) {
|
||||||
|
builtKey = builtKey.concat(keySequenceMap.get(key));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (builtKey.length() != 0) {
|
||||||
|
// Drop the last ":"
|
||||||
|
builtKey = builtKey.substring(0, builtKey.length() - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!statsDataMap.containsKey(builtKey)) {
|
||||||
|
statsDataMap.put(builtKey, new StatsData(builtKey,
|
||||||
|
timeStep, this.timeRange, unitUtils));
|
||||||
|
}
|
||||||
|
|
||||||
|
statsDataMap.get(builtKey).addRecord(record);
|
||||||
|
builtKey = "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gather the data together in each bin.
|
||||||
|
*
|
||||||
|
* @param unitUtils
|
||||||
|
* UnitUtils object
|
||||||
|
* @param groups
|
||||||
|
* List of groups
|
||||||
|
*/
|
||||||
|
private void gather(UnitUtils unitUtils, List<String> groups) {
|
||||||
|
createStatsDataMap(unitUtils, groups);
|
||||||
|
calculateBins();
|
||||||
|
for (String key : statsDataMap.keySet()) {
|
||||||
|
StatsData data = statsDataMap.get(key);
|
||||||
|
data.setBins(bins);
|
||||||
|
data.accumulate(key);
|
||||||
|
statsDataMap.put(key, data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculate the bins for the graph.
|
||||||
|
*/
|
||||||
|
@VisibleForTesting
|
||||||
|
void calculateBins() {
|
||||||
|
bins.clear();
|
||||||
|
|
||||||
|
long duration = timeRange.getDuration();
|
||||||
|
long startMillis = timeRange.getStart().getTime();
|
||||||
|
long numBins = duration / (timeStep * TimeUtil.MILLIS_PER_MINUTE);
|
||||||
|
for (long i = 0; i < numBins; i++) {
|
||||||
|
StatsBin sb = new StatsBin();
|
||||||
|
sb.setBinMillis(startMillis
|
||||||
|
+ (i * timeStep * TimeUtil.MILLIS_PER_MINUTE));
|
||||||
|
bins.put(i, sb);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param timeRange
|
||||||
|
* the timeRange to set
|
||||||
|
*/
|
||||||
|
public void setTimeRange(TimeRange timeRange) {
|
||||||
|
this.timeRange = timeRange;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the timeRange
|
||||||
|
*/
|
||||||
|
public TimeRange getTimeRange() {
|
||||||
|
return timeRange;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param eventType
|
||||||
|
* the eventType to set
|
||||||
|
*/
|
||||||
|
public void setEventType(String eventType) {
|
||||||
|
this.eventType = eventType;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param dataType
|
||||||
|
* the dataType to set
|
||||||
|
*/
|
||||||
|
public void setDataType(String dataType) {
|
||||||
|
this.dataType = dataType;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the display units.
|
||||||
|
*
|
||||||
|
* @param displayUnit
|
||||||
|
* the displayUnit to set
|
||||||
|
*/
|
||||||
|
public void setDisplayUnits(String displayUnit) {
|
||||||
|
this.displayUnit = displayUnit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TimeStep in minutes
|
||||||
|
*
|
||||||
|
* @param timeStep
|
||||||
|
*/
|
||||||
|
public void setTimeStep(int timeStep) {
|
||||||
|
this.timeStep = timeStep;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,220 @@
|
||||||
|
/**
|
||||||
|
* This software was developed and / or modified by Raytheon Company,
|
||||||
|
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||||
|
*
|
||||||
|
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||||
|
* This software product contains export-restricted data whose
|
||||||
|
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||||
|
* to non-U.S. persons whether in the United States or abroad requires
|
||||||
|
* an export license or other authorization.
|
||||||
|
*
|
||||||
|
* Contractor Name: Raytheon Company
|
||||||
|
* Contractor Address: 6825 Pine Street, Suite 340
|
||||||
|
* Mail Stop B8
|
||||||
|
* Omaha, NE 68106
|
||||||
|
* 402.291.0100
|
||||||
|
*
|
||||||
|
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||||
|
* further licensing information.
|
||||||
|
**/
|
||||||
|
package com.raytheon.uf.edex.stats.handler;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Calendar;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.TimeZone;
|
||||||
|
|
||||||
|
import com.raytheon.uf.common.dataquery.db.QueryParam.QueryOperand;
|
||||||
|
import com.raytheon.uf.common.serialization.comm.IRequestHandler;
|
||||||
|
import com.raytheon.uf.common.stats.AggregateRecord;
|
||||||
|
import com.raytheon.uf.common.stats.GraphDataRequest;
|
||||||
|
import com.raytheon.uf.common.stats.GraphDataResponse;
|
||||||
|
import com.raytheon.uf.common.stats.data.GraphData;
|
||||||
|
import com.raytheon.uf.common.stats.xml.StatisticsAggregate;
|
||||||
|
import com.raytheon.uf.common.stats.xml.StatisticsConfig;
|
||||||
|
import com.raytheon.uf.common.stats.xml.StatisticsEvent;
|
||||||
|
import com.raytheon.uf.common.time.util.TimeUtil;
|
||||||
|
import com.raytheon.uf.edex.database.dao.CoreDao;
|
||||||
|
import com.raytheon.uf.edex.database.dao.DaoConfig;
|
||||||
|
import com.raytheon.uf.edex.database.query.DatabaseQuery;
|
||||||
|
import com.raytheon.uf.edex.stats.data.StatsDataAccumulator;
|
||||||
|
import com.raytheon.uf.edex.stats.util.ConfigLoader;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Graph Data Request Handler.
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
*
|
||||||
|
* SOFTWARE HISTORY
|
||||||
|
*
|
||||||
|
* Date Ticket# Engineer Description
|
||||||
|
* ------------ ---------- ----------- --------------------------
|
||||||
|
* Sep 11, 2012 728 mpduff Initial creation
|
||||||
|
*
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* @author mpduff
|
||||||
|
* @version 1.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class GraphDataHandler implements IRequestHandler<GraphDataRequest> {
|
||||||
|
/** Aggregate Record DAO */
|
||||||
|
private final CoreDao dao = new CoreDao(DaoConfig.forClass("metadata",
|
||||||
|
AggregateRecord.class));
|
||||||
|
|
||||||
|
private static final String START_DATE = "startDate";
|
||||||
|
|
||||||
|
private static final String END_DATE = "endDate";
|
||||||
|
|
||||||
|
private static final String EVENT_TYPE = "eventType";
|
||||||
|
|
||||||
|
private static final String FIELD = "field";
|
||||||
|
|
||||||
|
private static final String COUNT = "COUNT";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor.
|
||||||
|
*/
|
||||||
|
public GraphDataHandler() {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public GraphDataResponse handleRequest(GraphDataRequest request)
|
||||||
|
throws Exception {
|
||||||
|
GraphDataResponse response;
|
||||||
|
|
||||||
|
if (request.isMetaDataRequest()) {
|
||||||
|
response = getMetaData();
|
||||||
|
} else {
|
||||||
|
response = getGraphData(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the statistical configuration objects and add them to the response.
|
||||||
|
*
|
||||||
|
* @return GraphDataResponse
|
||||||
|
*
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
private GraphDataResponse getMetaData() throws Exception {
|
||||||
|
ConfigLoader loader = new ConfigLoader();
|
||||||
|
loader.load();
|
||||||
|
List<StatisticsConfig> configList = loader.getConfigurations();
|
||||||
|
GraphDataResponse response = new GraphDataResponse();
|
||||||
|
response.setConfigList(configList);
|
||||||
|
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the Graph Data object and add it to the response.
|
||||||
|
*
|
||||||
|
* @param request
|
||||||
|
* The request object
|
||||||
|
* @return GraphDataResponse
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
private GraphDataResponse getGraphData(GraphDataRequest request)
|
||||||
|
throws Exception {
|
||||||
|
GraphDataResponse response = new GraphDataResponse();
|
||||||
|
DatabaseQuery query = new DatabaseQuery(AggregateRecord.class.getName());
|
||||||
|
Calendar start = convertToCalendar(request.getTimeRange().getStart());
|
||||||
|
Calendar end = convertToCalendar(request.getTimeRange().getEnd());
|
||||||
|
query.addQueryParam(START_DATE, start, QueryOperand.GREATERTHANEQUALS);
|
||||||
|
query.addQueryParam(END_DATE, end, QueryOperand.LESSTHANEQUALS);
|
||||||
|
|
||||||
|
if (request.getEventType() != null) {
|
||||||
|
query.addQueryParam(EVENT_TYPE, request.getEventType(),
|
||||||
|
QueryOperand.EQUALS);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (request.getField() != null) {
|
||||||
|
query.addQueryParam(FIELD, request.getField(),
|
||||||
|
QueryOperand.EQUALS);
|
||||||
|
}
|
||||||
|
|
||||||
|
List<?> results = dao.queryByCriteria(query);
|
||||||
|
|
||||||
|
if (!results.isEmpty()) {
|
||||||
|
List<AggregateRecord> arList = new ArrayList<AggregateRecord>();
|
||||||
|
for (int i = 0; i < results.size(); i++) {
|
||||||
|
if (results.get(i) instanceof AggregateRecord) {
|
||||||
|
arList.add((AggregateRecord) results.get(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
String displayUnit = getDisplayUnit(request.getCategory(),
|
||||||
|
request.getEventType(), request.getDataType());
|
||||||
|
|
||||||
|
StatsDataAccumulator accum = new StatsDataAccumulator();
|
||||||
|
accum.setRecords(arList.toArray(new AggregateRecord[arList.size()]));
|
||||||
|
accum.setDisplayUnits(displayUnit);
|
||||||
|
accum.setEventType(request.getEventType());
|
||||||
|
accum.setDataType(request.getField());
|
||||||
|
accum.setTimeRange(request.getTimeRange());
|
||||||
|
accum.setTimeStep(request.getTimeStep());
|
||||||
|
accum.setupGroupings();
|
||||||
|
|
||||||
|
GraphData graphData = accum.getGraphData(request.getGrouping());
|
||||||
|
|
||||||
|
response.setGraphData(graphData);
|
||||||
|
}
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert a Date object to Calendar object.
|
||||||
|
*
|
||||||
|
* @param date
|
||||||
|
* @return Calendar object
|
||||||
|
*/
|
||||||
|
private Calendar convertToCalendar(Date date) {
|
||||||
|
Calendar cal = TimeUtil.newCalendar(TimeZone.getTimeZone("GMT"));
|
||||||
|
cal.setTimeInMillis(date.getTime());
|
||||||
|
|
||||||
|
return cal;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the display unit.
|
||||||
|
*
|
||||||
|
* @param dataType
|
||||||
|
* @param type
|
||||||
|
* @param category
|
||||||
|
* @return The display unit, NONE if no units
|
||||||
|
*/
|
||||||
|
private String getDisplayUnit(String category, String type, String dataType)
|
||||||
|
throws Exception {
|
||||||
|
ConfigLoader loader = new ConfigLoader();
|
||||||
|
loader.load();
|
||||||
|
List<StatisticsConfig> configList = loader.getConfigurations();
|
||||||
|
|
||||||
|
String unit = COUNT;
|
||||||
|
for (StatisticsConfig config : configList) {
|
||||||
|
for (String cat : config.getCategories()) {
|
||||||
|
if (cat.equals(category)) {
|
||||||
|
for (StatisticsEvent event : config.getEvents()) {
|
||||||
|
if (event.getType().equals(type)) {
|
||||||
|
for (StatisticsAggregate agg : event
|
||||||
|
.getAggregateList()) {
|
||||||
|
if (agg.getField().equals(dataType)) {
|
||||||
|
return agg.getDisplayUnit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return unit;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -36,23 +36,22 @@ import com.raytheon.uf.common.stats.xml.StatisticsConfig;
|
||||||
import com.raytheon.uf.common.stats.xml.StatisticsEvent;
|
import com.raytheon.uf.common.stats.xml.StatisticsEvent;
|
||||||
import com.raytheon.uf.common.status.IUFStatusHandler;
|
import com.raytheon.uf.common.status.IUFStatusHandler;
|
||||||
import com.raytheon.uf.common.status.UFStatus;
|
import com.raytheon.uf.common.status.UFStatus;
|
||||||
import com.raytheon.uf.edex.stats.xml.Statistics;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Loads StatisticsConfig files from localization.
|
* Loads StatisticsConfig files from localization.
|
||||||
*
|
*
|
||||||
* <pre>
|
* <pre>
|
||||||
*
|
*
|
||||||
* SOFTWARE HISTORY
|
* SOFTWARE HISTORY
|
||||||
* Date Ticket# Engineer Description
|
* Date Ticket# Engineer Description
|
||||||
* ------------ ---------- ----------- --------------------------
|
* ------------ ---------- ----------- --------------------------
|
||||||
* Aug 21, 2012 jsanchez Updated error handling and validated config files.
|
* Aug 21, 2012 jsanchez Updated error handling and validated config files.
|
||||||
* Nov 07, 2012 1317 mpduff Update config files.
|
* Nov 07, 2012 1317 mpduff Update config files.
|
||||||
*
|
*
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
* @author jsanchez
|
* @author jsanchez
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class ConfigLoader {
|
public class ConfigLoader {
|
||||||
|
|
||||||
|
@ -62,8 +61,7 @@ public class ConfigLoader {
|
||||||
private static final JAXBManager jaxbManager;
|
private static final JAXBManager jaxbManager;
|
||||||
static {
|
static {
|
||||||
try {
|
try {
|
||||||
jaxbManager = new JAXBManager(StatisticsConfig.class,
|
jaxbManager = new JAXBManager(StatisticsConfig.class);
|
||||||
Statistics.class);
|
|
||||||
} catch (JAXBException e) {
|
} catch (JAXBException e) {
|
||||||
throw new ExceptionInInitializerError(e);
|
throw new ExceptionInInitializerError(e);
|
||||||
}
|
}
|
||||||
|
@ -77,7 +75,7 @@ public class ConfigLoader {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a list of all StatisticsConfig files.
|
* Returns a list of all StatisticsConfig files.
|
||||||
*
|
*
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public List<StatisticsConfig> getConfigurations() {
|
public List<StatisticsConfig> getConfigurations() {
|
||||||
|
@ -115,7 +113,7 @@ public class ConfigLoader {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Removes the aggregate if its not a numerical parameter.
|
* Removes the aggregate if its not a numerical parameter.
|
||||||
*
|
*
|
||||||
* @param config
|
* @param config
|
||||||
*/
|
*/
|
||||||
private StatisticsConfig validateAggregates(StatisticsConfig config)
|
private StatisticsConfig validateAggregates(StatisticsConfig config)
|
||||||
|
|
|
@ -1,19 +1,19 @@
|
||||||
/**
|
/**
|
||||||
* This software was developed and / or modified by Raytheon Company,
|
* This software was developed and / or modified by Raytheon Company,
|
||||||
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||||
*
|
*
|
||||||
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||||
* This software product contains export-restricted data whose
|
* This software product contains export-restricted data whose
|
||||||
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||||
* to non-U.S. persons whether in the United States or abroad requires
|
* to non-U.S. persons whether in the United States or abroad requires
|
||||||
* an export license or other authorization.
|
* an export license or other authorization.
|
||||||
*
|
*
|
||||||
* Contractor Name: Raytheon Company
|
* Contractor Name: Raytheon Company
|
||||||
* Contractor Address: 6825 Pine Street, Suite 340
|
* Contractor Address: 6825 Pine Street, Suite 340
|
||||||
* Mail Stop B8
|
* Mail Stop B8
|
||||||
* Omaha, NE 68106
|
* Omaha, NE 68106
|
||||||
* 402.291.0100
|
* 402.291.0100
|
||||||
*
|
*
|
||||||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||||
* further licensing information.
|
* further licensing information.
|
||||||
**/
|
**/
|
||||||
|
@ -31,19 +31,19 @@ import com.raytheon.uf.common.serialization.annotations.DynamicSerialize;
|
||||||
import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement;
|
import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* <pre>
|
* <pre>
|
||||||
*
|
*
|
||||||
* SOFTWARE HISTORY
|
* SOFTWARE HISTORY
|
||||||
* Date Ticket# Engineer Description
|
* Date Ticket# Engineer Description
|
||||||
* ------------ ---------- ----------- --------------------------
|
* ------------ ---------- ----------- --------------------------
|
||||||
* Aug 21, 2012 jsanchez Made serializable.
|
* Aug 21, 2012 jsanchez Made serializable.
|
||||||
*
|
*
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
* @author jsanchez
|
* @author jsanchez
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
@DynamicSerialize
|
@DynamicSerialize
|
||||||
@XmlAccessorType(XmlAccessType.NONE)
|
@XmlAccessorType(XmlAccessType.NONE)
|
||||||
|
@ -58,6 +58,10 @@ public class Aggregate {
|
||||||
@DynamicSerializeElement
|
@DynamicSerializeElement
|
||||||
private Unit<?> unit = Unit.ONE;
|
private Unit<?> unit = Unit.ONE;
|
||||||
|
|
||||||
|
@XmlAttribute
|
||||||
|
@DynamicSerializeElement
|
||||||
|
private String displayName;
|
||||||
|
|
||||||
/** the name of the statistic function */
|
/** the name of the statistic function */
|
||||||
@XmlElement(name = "function")
|
@XmlElement(name = "function")
|
||||||
@DynamicSerializeElement
|
@DynamicSerializeElement
|
||||||
|
@ -94,4 +98,19 @@ public class Aggregate {
|
||||||
this.functions = functions;
|
this.functions = functions;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param displayName
|
||||||
|
* the displayName to set
|
||||||
|
*/
|
||||||
|
public void setDisplayName(String displayName) {
|
||||||
|
this.displayName = displayName;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the displayName
|
||||||
|
*/
|
||||||
|
public String getDisplayName() {
|
||||||
|
return displayName;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,19 +1,19 @@
|
||||||
/**
|
/**
|
||||||
* This software was developed and / or modified by Raytheon Company,
|
* This software was developed and / or modified by Raytheon Company,
|
||||||
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||||
*
|
*
|
||||||
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||||
* This software product contains export-restricted data whose
|
* This software product contains export-restricted data whose
|
||||||
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||||
* to non-U.S. persons whether in the United States or abroad requires
|
* to non-U.S. persons whether in the United States or abroad requires
|
||||||
* an export license or other authorization.
|
* an export license or other authorization.
|
||||||
*
|
*
|
||||||
* Contractor Name: Raytheon Company
|
* Contractor Name: Raytheon Company
|
||||||
* Contractor Address: 6825 Pine Street, Suite 340
|
* Contractor Address: 6825 Pine Street, Suite 340
|
||||||
* Mail Stop B8
|
* Mail Stop B8
|
||||||
* Omaha, NE 68106
|
* Omaha, NE 68106
|
||||||
* 402.291.0100
|
* 402.291.0100
|
||||||
*
|
*
|
||||||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||||
* further licensing information.
|
* further licensing information.
|
||||||
**/
|
**/
|
||||||
|
@ -27,19 +27,19 @@ import com.raytheon.uf.common.serialization.annotations.DynamicSerialize;
|
||||||
import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement;
|
import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* <pre>
|
* <pre>
|
||||||
*
|
*
|
||||||
* SOFTWARE HISTORY
|
* SOFTWARE HISTORY
|
||||||
* Date Ticket# Engineer Description
|
* Date Ticket# Engineer Description
|
||||||
* ------------ ---------- ----------- --------------------------
|
* ------------ ---------- ----------- --------------------------
|
||||||
* Aug 21, 2012 jsanchez Made serializable.
|
* Aug 21, 2012 jsanchez Made serializable.
|
||||||
*
|
*
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
* @author jsanchez
|
* @author jsanchez
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
@DynamicSerialize
|
@DynamicSerialize
|
||||||
@XmlAccessorType(XmlAccessType.NONE)
|
@XmlAccessorType(XmlAccessType.NONE)
|
||||||
|
@ -52,6 +52,10 @@ public class Item {
|
||||||
@DynamicSerializeElement
|
@DynamicSerializeElement
|
||||||
private String result;
|
private String result;
|
||||||
|
|
||||||
|
@XmlAttribute
|
||||||
|
@DynamicSerializeElement
|
||||||
|
private String displayName;
|
||||||
|
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
@ -68,4 +72,18 @@ public class Item {
|
||||||
this.result = result;
|
this.result = result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param displayName the displayName to set
|
||||||
|
*/
|
||||||
|
public void setDisplayName(String displayName) {
|
||||||
|
this.displayName = displayName;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the displayName
|
||||||
|
*/
|
||||||
|
public String getDisplayName() {
|
||||||
|
return displayName;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,8 +4,8 @@
|
||||||
displayName="Processing Events" category="Data Ingest Events">
|
displayName="Processing Events" category="Data Ingest Events">
|
||||||
<statisticsGroup name="pluginName" displayName="Data Type" />
|
<statisticsGroup name="pluginName" displayName="Data Type" />
|
||||||
<statisticsAggregate field="processingTime"
|
<statisticsAggregate field="processingTime"
|
||||||
displayName="Processing Time" unit="ms" />
|
displayName="Processing Time" displayUnit="ms" />
|
||||||
<statisticsAggregate field="processingLatency"
|
<statisticsAggregate field="processingLatency"
|
||||||
displayName="Processing Latency" unit="ms" />
|
displayName="Processing Latency" displayUnit="ms" />
|
||||||
</statisticsEvent>
|
</statisticsEvent>
|
||||||
</statisticsConfig>
|
</statisticsConfig>
|
||||||
|
|
Loading…
Add table
Reference in a new issue