/*
* RHQ Management Platform
* Copyright (C) 2005-2013 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.admin.storage;
import static org.rhq.coregui.client.admin.storage.StorageNodeDatasource.DONT_MISS_ME_CLASS;
import static org.rhq.coregui.client.admin.storage.StorageNodeDatasource.OK_CLASS;
import static org.rhq.coregui.client.admin.storage.StorageNodeDatasource.WARN_CLASS;
import java.util.List;
import java.util.Map;
import com.google.gwt.user.client.Random;
import com.google.gwt.user.client.Timer;
import com.smartgwt.client.types.Autofit;
import com.smartgwt.client.widgets.grid.ListGrid;
import com.smartgwt.client.widgets.grid.ListGridField;
import com.smartgwt.client.widgets.grid.ListGridRecord;
import com.smartgwt.client.widgets.grid.events.DataArrivedEvent;
import com.smartgwt.client.widgets.grid.events.DataArrivedHandler;
import org.rhq.core.domain.measurement.composite.MeasurementDataNumericHighLowComposite;
import org.rhq.coregui.client.admin.storage.StorageNodeDatasource.StorageNodeLoadCompositeDatasource;
import org.rhq.coregui.client.util.BrowserUtility;
import org.rhq.coregui.client.util.enhanced.EnhancedUtility;
import org.rhq.coregui.client.util.enhanced.EnhancedVLayout;
/**
* The component for displaying the StorageNodeLoadComposite data.
*
* @author Jirka Kremser
*/
public class StorageNodeLoadComponent extends EnhancedVLayout {
private final ListGrid loadGrid;
private Map<String, List<MeasurementDataNumericHighLowComposite>> sparkLineData;
public StorageNodeLoadComponent(final int storageNodeId,
Map<String, List<MeasurementDataNumericHighLowComposite>> sparkLineData) {
super(5);
setPadding(5);
this.sparkLineData = sparkLineData;
final boolean showSparkLine = sparkLineData != null && !sparkLineData.isEmpty();
loadGrid = new ListGrid() {
@Override
protected String getCellCSSText(ListGridRecord record, int rowNum, int colNum) {
if ("avg".equals(getFieldName(colNum))
&& (StorageNodeLoadCompositeDatasource.KEY_HEAP_PERCENTAGE.equals(record.getAttribute("id"))
|| StorageNodeLoadCompositeDatasource.KEY_DATA_DISK_SPACE_PERCENTAGE.equals(record
.getAttribute("id")) || StorageNodeLoadCompositeDatasource.KEY_TOTAL_DISK_SPACE_PERCENTAGE
.equals(record.getAttribute("id")))) {
if (record.getAttributeAsFloat("avgFloat") > .85) {
return DONT_MISS_ME_CLASS;
} else if (record.getAttributeAsFloat("avgFloat") > .7) {
return WARN_CLASS;
} else {
return OK_CLASS;
}
} else if ("max".equals(getFieldName(colNum))
&& StorageNodeLoadCompositeDatasource.KEY_FREE_DISK_TO_DATA_SIZE_RATIO.equals(record
.getAttribute("id"))) {
if (record.getAttributeAsFloat("avgFloat") < .7) {
return DONT_MISS_ME_CLASS;
} else if (record.getAttributeAsFloat("avgFloat") < 1.5) {
return WARN_CLASS;
} else {
return OK_CLASS;
}
} else {
return super.getCellCSSText(record, rowNum, colNum);
}
}
};
loadGrid
.setID(EnhancedUtility.getSafeId(this.getClass().getName() + storageNodeId + "_" + Random.nextDouble()));
loadGrid.setWidth100();
loadGrid.setHeight(200);
loadGrid.setAutoFitData(Autofit.VERTICAL);
StorageNodeLoadCompositeDatasource datasource = StorageNodeLoadCompositeDatasource.getInstance(storageNodeId);
List<ListGridField> fields = datasource.getListGridFields();
if (showSparkLine) {
fields.add(0, new ListGridField("sparkline", MSG.view_adminTopology_storageNodes_detail_chart(), 75));
}
loadGrid.setFields(fields.toArray(new ListGridField[fields.size()]));
loadGrid.setHoverWidth(300);
loadGrid.setDataSource(datasource);
loadGrid.setAutoFetchData(true);
// loadGrid.fetchData();
if (showSparkLine) {
loadGrid.addDataArrivedHandler(new DataArrivedHandler() {
@Override
public void onDataArrived(DataArrivedEvent event) {
showSparkLineGraphs();
loadGrid.redraw();
}
});
}
addMember(loadGrid);
}
private void showSparkLineGraphs() {
ListGridRecord[] records = loadGrid.getRecords();
for (int i = 0; i < records.length; i++) {
String metricName = records[i].getAttributeAsString("id");
boolean someChartedData = false;
List<MeasurementDataNumericHighLowComposite> data = sparkLineData.get(metricName);
// locate last and minimum values.
double lastValue = -1;
double minValue = Double.MAX_VALUE;
if (data != null) {
for (MeasurementDataNumericHighLowComposite d : data) {
if ((!Double.isNaN(d.getValue())) && (!String.valueOf(d.getValue()).contains("NaN"))) {
if (d.getValue() < minValue) {
minValue = d.getValue();
}
lastValue = d.getValue();
}
}
}
// if graph content returned
someChartedData = lastValue != -1;
// collapse the data into comma delimited list for consumption by third party javascript library (jquery.sparkline)
StringBuilder commaDelimitedList = new StringBuilder();
for (MeasurementDataNumericHighLowComposite d : data) {
if ((!Double.isNaN(d.getValue())) && (!String.valueOf(d.getValue()).contains("NaN"))) {
commaDelimitedList.append(d.getValue()).append(",");
}
}
if (commaDelimitedList.length() > 0) {
commaDelimitedList = commaDelimitedList.deleteCharAt(commaDelimitedList.length() - 1);
}
if (!commaDelimitedList.toString().contains(",")) {
// prepend another value just so we have 2 values and it will graph
commaDelimitedList.insert(0, "0,");
}
if (someChartedData) {
String contents = "<span id='sparkline_" + metricName + "' class='dynamicsparkline' width='70' "
+ "values='" + commaDelimitedList.toString() + "'>...</span>";
records[i].setAttribute("sparkline", contents);
}
}
loadGrid.setData(records);
new Timer() {
@Override
public void run() {
BrowserUtility.graphSparkLines();
scheduleRepeating(5000);
}
}.schedule(150);
}
}