/*
* RHQ Management Platform
* Copyright (C) 2005-2012 Red Hat, Inc.
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation version 2 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
package org.rhq.coregui.client.inventory.resource.detail.monitoring;
import com.google.gwt.user.client.Timer;
import com.smartgwt.client.widgets.HTMLFlow;
import org.rhq.coregui.client.GraphMarker;
import org.rhq.coregui.client.inventory.common.AbstractD3GraphListView;
import org.rhq.coregui.client.inventory.common.graph.Refreshable;
import org.rhq.coregui.client.inventory.common.graph.graphtype.StackedBarMetricGraphImpl;
import org.rhq.coregui.client.util.Log;
import org.rhq.coregui.client.util.enhanced.EnhancedVLayout;
/**
* A D3 graph implementation for graphing Resource metrics.
* Just the graph only. No avail graph no buttons just he graph.
*/
public class MetricD3Graph<T extends AbstractD3GraphListView> extends EnhancedVLayout implements Refreshable,GraphMarker {
protected StackedBarMetricGraphImpl graph;
private HTMLFlow graphDiv = null;
protected Timer refreshTimer;
private T d3GraphListView;
/**
* This constructor is for the use case in the Dashboard where we dont actually
* have a entity or measurement yet.
*/
public MetricD3Graph() {
super();
}
public MetricD3Graph(StackedBarMetricGraphImpl graph, T graphListView) {
super();
this.graph = graph;
this.d3GraphListView = graphListView;
setHeight100();
setWidth100();
}
/**
* Svg definitions for patterns and gradients to use on SVG shapes.
* @return xml String
*/
private static String getSvgDefs() {
return " <defs>"
+ " <linearGradient id=\"headerGrad\" x1=\"0%\" y1=\"0%\" x2=\"0%\" y2=\"100%\">"
+ " <stop offset=\"0%\" style=\"stop-color:#E6E6E6;stop-opacity:1\"/>"
+ " <stop offset=\"100%\" style=\"stop-color:#F0F0F0;stop-opacity:1\"/>"
+ " </linearGradient>"
+ " <pattern id=\"noDataStripes\" patternUnits=\"userSpaceOnUse\" x=\"0\" y=\"0\""
+ " width=\"6\" height=\"3\">"
+ " <path d=\"M 0 0 6 0\" style=\"stroke:#CCCCCC; fill:none;\"/>"
+ " </pattern>"
+ " <pattern id=\"unknownStripes\" patternUnits=\"userSpaceOnUse\" x=\"0\" y=\"0\""
+ " width=\"6\" height=\"3\">"
+ " <path d=\"M 0 0 6 0\" style=\"stroke:#2E9EC2; fill:none;\"/>"
+ " </pattern>"
+ "<pattern id=\"diagonalHatchFill\" patternUnits=\"userSpaceOnUse\" x=\"0\" y=\"0\" width=\"105\" height=\"105\">"
+ "<g style=\"fill:none; stroke:black; stroke-width:1\">"
+ "<path d=\"M0 90 l15,15\"/>"
+ "<path d=\"M0 75 l30,30\"/>"
+ "<path d=\"M0 60 l45,45\"/>"
+ "<path d=\"M0 45 l60,60\"/>"
+ "<path d=\"M0 30 l75,75\"/>"
+ "<path d=\"M0 15 l90,90\"/>"
+ "<path d=\"M0 0 l105,105\"/>"
+ "<path d=\"M15 0 l90,90\"/>"
+ "<path d=\"M30 0 l75,75\"/>"
+ "<path d=\"M45 0 l60,60\"/>"
+ "<path d=\"M60 0 l45,45\"/>"
+ "<path d=\"M75 0 l30,30\"/>"
+ "<path d=\"M90 0 l15,15\"/>"
+ "</g>"
+ "</pattern>"
+ "<pattern id=\"diagonalHatch\" patternUnits=\"userSpaceOnUse\" x=\"0\" y=\"0\" width=\"105\" height=\"105\">"
+ "<g style=\"fill:none; stroke:black; stroke-width:1\">" + "<path d=\"M0 90 l15,15\"/>"
+ "<path d=\"M0 75 l30,30\"/>" + "<path d=\"M0 60 l45,45\"/>" + "<path d=\"M0 45 l60,60\"/>"
+ "<path d=\"M0 30 l75,75\"/>" + "<path d=\"M0 15 l90,90\"/>" + "<path d=\"M0 0 l105,105\"/>"
+ "<path d=\"M15 0 l90,90\"/>" + "<path d=\"M30 0 l75,75\"/>" + "<path d=\"M45 0 l60,60\"/>"
+ "<path d=\"M60 0 l45,45\"/>" + "<path d=\"M75 0 l30,30\"/>" + "<path d=\"M90 0 l15,15\"/>" + "</g>"
+ "</pattern>"
+ "<pattern id=\"downStripes\" patternUnits=\"userSpaceOnUse\" x=\"0\" y=\"0\""
+ " width=\"6\" height=\"3\">"
+ "<path d=\"M 0 0 6 0\" style=\"stroke:#ff8a9a; fill:none;\"/>"
+ "</pattern>" + "</defs>";
}
@Override
protected void onDraw() {
super.onDraw();
if (graph.getDefinition() != null) {
drawGraph();
}
}
@Override
public void parentResized() {
super.parentResized();
removeMembers(getMembers());
drawGraph();
}
/**
* Setup the page elements especially the div and svg elements that serve as
* placeholders for the d3 stuff to grab onto and add svg tags to render the chart.
* Later the drawJsniChart() is called to actually fill in the div/svg element
* created here with the actual svg element.
*
*/
protected void drawGraph() {
final String divAndSvgDefs = createGraphMarker();
if (null != graphDiv) {
removeMember(graphDiv);
}
graphDiv = new HTMLFlow(divAndSvgDefs);
setupGraphDiv(graphDiv);
addMember(graphDiv);
drawJsniChart();
}
/**
* for subclasses to apply additional styling to graphDiv right before it get's drawn with SVG chart
* @param graphDiv
*/
protected void setupGraphDiv(HTMLFlow graphDiv) {
graphDiv.setWidth100();
graphDiv.setHeight100();
}
/**
* This is used to explicitly use the 2 phase creation of a graph separately.
* Used to add the chart to something custom.
* @return String Graph Marker to be filled in with drawJsniChart() later
*/
public String createGraphMarker() {
return createGraphMarkerTemplate(getFullChartId(), getHeight());
}
/**
* A static version of createGraphMarker that can be used when a MetricD3Graph is not
* instantiated.
* @param fullChartId
* @param height
* @return String chart marker
*/
public static String createGraphMarkerTemplate(String fullChartId, Integer height){
Log.debug("drawGraph marker in MetricD3Graph for: " + fullChartId);
StringBuilder divAndSvgDefs = new StringBuilder();
divAndSvgDefs
.append("<div id=\""
+ fullChartId
+ "\" ><svg xmlns=\"http://www.w3.org/2000/svg\" version=\"1.1\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" style=\"height:"
+ height + "px;\">");
divAndSvgDefs.append(getSvgDefs());
divAndSvgDefs.append("</svg>");
divAndSvgDefs.append("</div>");
return divAndSvgDefs.toString();
}
/**
* Delegate the call to rendering the JSNI chart.
* This way the chart type can be swapped out at any time.
*/
public void drawJsniChart() {
new Timer() {
@Override
public void run() {
graph.drawJsniChart();
}
}.schedule(200);
}
public String getFullChartId() {
String graphMarkerPrefix = graph.getMetricGraphData().isSummaryGraph() ? "sChart-" : "rChart-";
return graphMarkerPrefix + graph.getMetricGraphData().getChartId();
}
public Integer getChartHeight() {
return graph.getMetricGraphData().getChartHeight();
}
@Override
public void destroy() {
super.destroy();
}
@Override
public void hide() {
super.hide();
}
/**
* Allow the graph to refresh the whole d3GraphListView.
*/
public void refreshData(){
d3GraphListView.refreshData();
}
}