com.icesoft.faces.component.outputchart.OutputChart Maven / Gradle / Ivy
Show all versions of icefaces-compat Show documentation
/*
* Copyright 2004-2012 ICEsoft Technologies Canada Corp.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an "AS
* IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied. See the License for the specific language
* governing permissions and limitations under the License.
*/
package com.icesoft.faces.component.outputchart;
import com.icesoft.faces.component.CSS_DEFAULT;
import com.icesoft.faces.component.ext.HtmlCommandButton;
import com.icesoft.faces.component.ext.renderkit.FormRenderer;
import com.icesoft.faces.component.ext.taglib.Util;
import com.icesoft.faces.context.DOMContext;
import org.krysalis.jcharts.Chart;
import org.krysalis.jcharts.imageMap.ImageMapArea;
import org.w3c.dom.Element;
import org.w3c.dom.Text;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.el.MethodBinding;
import javax.faces.el.ValueBinding;
import javax.faces.event.AbortProcessingException;
import javax.faces.event.ActionEvent;
import javax.faces.event.FacesEvent;
import javax.faces.event.ActionListener;
import java.beans.Beans;
import java.io.IOException;
import java.io.Serializable;
import java.net.URI;
import java.util.Iterator;
import java.util.Map;
import org.icefaces.impl.util.DOMUtils;
public class OutputChart extends HtmlCommandButton implements Serializable {
public static final String SCATTER_PLOT_CHART_TYPE = "scatterplot";
public static String AREA_CHART_TYPE = "area";
public static String AREA_STACKED_CHART_TYPE = "areastacked";
public static String BAR_CHART_TYPE = "bar";
public static String BAR_CLUSTERED_CHART_TYPE = "barclustered";
public static String BAR_STACKED_CHART_TYPE = "barstacked";
public static String LINE_CHART_TYPE = "line";
public static String PIE2D_CHART_TYPE = "pie2D";
public static String PIE3D_CHART_TYPE = "pie3D";
public static String POINT_CHART_TYPE = "point";
public static String STOCK_CHART_TYPE = "stock";
public static String CUSTOM_CHART_TYPE = "custom";
public static String DEFAULT_CHART_TYPE = BAR_CHART_TYPE;
private static int COMPONENT_ID = 0;
private static int CLIENT_SIDE_IMAGE_MAP_KEY = 1;
private static String DEFAULT_HEIGHT = "400";
private static String DEFAULT_WIDTH = "400";
private static String DEFAULT_CHART_TITLE = "Default Chart title";
private static String DEFAULT_YAXIS_TITLE = "Default Y title";
private static String DEFAULT_XAXIS_TITLE = "Default X title";
private static String DEFAULT_DATA = "20, 30, 40";
static String ICE_CHART_COMPONENT = "iceChartComponent";
private transient int imageCounter = 0;
private String width;
private String height;
private boolean render = false;
private String chartTitle;
private Object data;
private Object labels;
private Object colors;
private Object shapes;
private Object xaxisLabels;
private String xaxisTitle;
private String yaxisTitle;
private String style = null;
private String styleClass = null;
private Object legendPlacement;
private Object legendColumns;
private boolean horizontal;
private boolean horizontalSet;
private URI chartURI;
private ChartResource chartResource;
public OutputChart() {
setRendererType("com.icesoft.faces.OutputChartRenderer");
}
/**
*Return the value of the labels
property.
*/
public Object getLabels() {
if (labels != null) {
return labels;
}
ValueBinding vb = getValueBinding("labels");
return vb != null ? vb.getValue(getFacesContext()) : null;
}
/**
* Set the value of the labels
property.
*/
public void setLabels(Object labels) {
this.labels = labels;
}
/**
*Return a boolean flag which tells if the chart can have a
*clientSideImageMap or not.
*/
public boolean isClientSideImageMap() {
if (hasActionListener() &&
(!getType().equalsIgnoreCase(AREA_CHART_TYPE) &&
!getType().equalsIgnoreCase(AREA_STACKED_CHART_TYPE))) {
return true;
} else {
return false;
}
}
protected boolean hasActionListener() {
MethodBinding actionListener = getActionListener();
if( actionListener != null ) {
return true;
}
ActionListener[] actionListeners = getActionListeners();
if( actionListeners != null && actionListeners.length > 0 ) {
return true;
}
return false;
}
/**
*Return the value of the data
property.
*/
public Object getData() {
if (data != null) {
return data;
}
ValueBinding vb = getValueBinding("data");
if (vb != null) {
return vb.getValue(getFacesContext());
} else {
if(!Beans.isDesignTime()){
setChartTitle(getChartTitle() + " with default data");
}
return DEFAULT_DATA;
}
}
/**
* Set the value of the data
property.
*/
public void setData(Object data) {
this.data = data;
}
/**
*Return the value of the colors
property.
*/
public Object getColors() {
if (colors != null) {
return colors;
}
ValueBinding vb = getValueBinding("colors");
return vb != null ? vb.getValue(getFacesContext()) : null;
}
/**
* Set the value of the colors
property.
*/
public void setColors(Object colors) {
this.colors = colors;
}
/**
*Return the value of the shapes
property.
*/
public Object getShapes() {
if (shapes != null) {
return shapes;
}
ValueBinding vb = getValueBinding("shapes");
return vb != null ? vb.getValue(getFacesContext()) : null;
}
/**
* Set the value of the shapes
property.
*/
public void setShapes(Object shapes) {
this.shapes = shapes;
}
/**
*Return the value of the xaxisTitle
property.
*/
public String getXaxisTitle() {
if (xaxisTitle != null) {
return xaxisTitle;
}
ValueBinding vb = getValueBinding("xaxisTitle");
return vb != null ? (String) vb.getValue(getFacesContext()) :
DEFAULT_XAXIS_TITLE;
}
/**
* Set the value of the xaxisTitle
property.
*/
public void setXaxisTitle(String xaxisTitle) {
this.xaxisTitle = xaxisTitle;
}
/**
*Return the value of the yaxisTitle
property.
*/
public String getYaxisTitle() {
if (yaxisTitle != null) {
return yaxisTitle;
}
ValueBinding vb = getValueBinding("yaxisTitle");
return vb != null ? (String) vb.getValue(getFacesContext()) :
DEFAULT_YAXIS_TITLE;
}
/**
* Set the value of the yaxisTitle
property.
*/
public void setYaxisTitle(String yaxisTitle) {
this.yaxisTitle = yaxisTitle;
}
/**
*Return the value of the xaxisLabels
property.
*/
public Object getXaxisLabels() {
if (xaxisLabels != null) {
return xaxisLabels;
}
ValueBinding vb = getValueBinding("xaxisLabels");
return vb != null ? vb.getValue(getFacesContext()) : null;
}
/**
* Set the value of the xaxisLabels
property.
*/
public void setXaxisLabels(Object xaxisLabels) {
this.xaxisLabels = xaxisLabels;
}
/**
*Return the value of the chartTitle
property.
*/
public String getChartTitle() {
if (chartTitle != null) {
return chartTitle;
}
ValueBinding vb = getValueBinding("chartTitle");
return vb != null ? (String) vb.getValue(getFacesContext()) :
DEFAULT_CHART_TITLE;
}
/**
* Set the value of the chartTitle
property.
*/
public void setChartTitle(String chartTitle) {
this.chartTitle = chartTitle;
}
/**
*Return the value of the width
property.
*/
public String getWidth() {
if (width != null) {
return width;
}
ValueBinding vb = getValueBinding("width");
return vb != null ? (String) vb.getValue(getFacesContext()) :
DEFAULT_WIDTH;
}
/**
* Set the value of the width
property.
*/
public void setWidth(String width) {
this.width = width;
}
/**
*Return the value of the height
property.
*/
public String getHeight() {
if (height != null) {
return height;
}
ValueBinding vb = getValueBinding("height");
return vb != null ? (String) vb.getValue(getFacesContext()) :
DEFAULT_HEIGHT;
}
/**
* Set the value of the height
property.
*/
public void setHeight(String height) {
this.height = height;
}
private MethodBinding renderOnSubmitMethodBinding;
public void setRenderOnSubmit(MethodBinding renderOnSubmit) {
renderOnSubmitMethodBinding = renderOnSubmit;
}
public MethodBinding getRenderOnSubmit() {
return renderOnSubmitMethodBinding;
}
public Boolean evaluateRenderOnSubmit(FacesContext context) {
if (renderOnSubmitMethodBinding != null) {
Boolean b = (Boolean) renderOnSubmitMethodBinding.invoke(
context, new Object[]{this});
return b;
}
return Boolean.FALSE;
}
/*
* (non-Javadoc)
* @see javax.faces.component.UIComponent#decode(javax.faces.context.FacesContext)
*/
public void decode(FacesContext context) {
Map requestParameterMap =
context.getExternalContext().getRequestParameterMap();
String chartComponentRequestIdentifier = (String) requestParameterMap
.get(OutputChart.ICE_CHART_COMPONENT);
if (chartComponentRequestIdentifier != null) {
String[] submittedValue =
chartComponentRequestIdentifier.split("id-key");
if (submittedValue[COMPONENT_ID].equals(getClientId(context))) {
ImageMapArea area = (ImageMapArea) getGeneratedImageMapArea()
.get(submittedValue[CLIENT_SIDE_IMAGE_MAP_KEY]);
if (area != null) {
setClickedImageMapArea(area);
queueEvent(new ActionEvent(this));
}
}
}
super.decode(context);
}
/**
*Return the value of the chart
property.
*/
public Chart getChart() {
return getAbstractChart().getChart();
}
/**
* Set the value of the chart
property.
*/
public void setChart(Chart chart) {
getAbstractChart().setChart(chart);
}
public void render() {
render = true;
}
public boolean isRender() {
return render;
}
private String type = null;
/**
* Set the value of the type
property.
*/
public void setType(String type) {
this.type = type;
}
/**
*Return the value of the type
property.
*/
public String getType() {
if (type != null) {
return type;
}
ValueBinding vb = getValueBinding("type");
return vb != null ? (String) vb.getValue(getFacesContext()) :
DEFAULT_CHART_TYPE;
}
Map getGeneratedImageMapArea() {
return getAbstractChart().getGeneratedImageMapArea();
}
/**
*Return the value of the data
property.
*/
public ImageMapArea getClickedImageMapArea() {
return getAbstractChart().getClickedImageMapArea();
}
public void setClickedImageMapArea(ImageMapArea clickedImageMapArea) {
getAbstractChart().setClickedImageMapArea(clickedImageMapArea);
}
void generateClientSideImageMap(DOMContext domContext, Element map) {
if (isClientSideImageMap()) {
String clientId = getClientId();
int i = 0;
Iterator area = getGeneratedImageMapArea().values().iterator();
while (area.hasNext()) {
ImageMapArea areaMap = (ImageMapArea) area.next();
//unescape overall insertion, but ensure label is escaped
String hiddenValue = "document.forms['" +
getParentFormId() + "']['" + ICE_CHART_COMPONENT +
"'].value='";
Text areaNode = domContext.createTextNodeUnescaped(areaMap.toHTML(
"id='"+ clientId + i++ + "' "+
"title ='" + DOMUtils.escapeAnsi(areaMap.getLengendLabel()) +
"' href=\"javascript:;\" onclick=\"" + hiddenValue + getClientId(getFacesContext()) +
"id-key" + areaMap.hashCode() +
"';iceSubmitPartial(document.forms['" +
getParentFormId() + "'],this,event);" + hiddenValue + "'; return false;\""));
map.appendChild(areaNode);
}
} else {
//logging client side image Map was not enabled
}
}
//cache parentFormId, if ClientSideImageMap is required
private String parentFormId;
private String getParentFormId() {
if (parentFormId != null) {
return parentFormId;
}
UIComponent uiForm = FormRenderer.findForm(this);
if (uiForm == null) {
//TODO logging and exception
//The component must have to be a decendent of the for element, inorder to use clientSideImageMap
return null;
}
return (parentFormId = uiForm.getClientId(getFacesContext()));
}
/**
* Set the value of the styleClass
property.
*/
public void setStyleClass(String styleClass) {
this.styleClass = styleClass;
}
/**
* Return the value of the styleClass
property.
*/
public String getStyleClass() {
return Util.getQualifiedStyleClass(this,
styleClass,
CSS_DEFAULT.OUTPUT_CHART_DEFAULT_STYLE_CLASS,
"styleClass");
}
/**
* Set the value of the style
property.
*/
public void setStyle(String style) {
this.style = style;
}
/**
* Return the value of the style
property.
*/
public String getStyle() {
if (style != null) {
return style;
}
ValueBinding vb = getValueBinding("style");
return vb != null ? (String) vb.getValue(getFacesContext()) : null;
}
/**
*Return the value of the legendLabel
property.
*/
public Object getLegendPlacement() {
if (legendPlacement != null) {
return legendPlacement;
}
ValueBinding vb = getValueBinding("legendPlacement");
return vb != null ? vb.getValue(getFacesContext()) : "bottom";
}
/**
* Set the value of the legendPlacement
property.
*/
public void setLegendPlacement(Object legendPlacement) {
this.legendPlacement = legendPlacement;
}
/**
*Return the value of the legendColumns
property.
*/
public Object getLegendColumns() {
if (legendColumns != null) {
return legendColumns;
}
ValueBinding vb = getValueBinding("legendColumns");
return vb != null ? vb.getValue(getFacesContext()) : "0";
}
/**
* Set the value of the legendColumns
property.
*/
public void setLegendColumns(Object legendColumns) {
this.legendColumns = legendColumns;
}
public boolean isHorizontal() {
if (this.horizontalSet) {
return (this.horizontal);
}
ValueBinding vb = getValueBinding("horizontal");
if (vb != null) {
return (Boolean.TRUE.equals(vb.getValue(getFacesContext())));
} else {
return (this.horizontal);
}
}
public void setHorizontal(boolean horizontal) {
if (horizontal != this.horizontal) {
this.horizontal = horizontal;
}
this.horizontalSet = true;
}
AbstractChart createAbstractChart() throws Throwable {
return (AbstractChart)this.getAttributes().put(getClientId(getFacesContext()), AbstractChart.createChart(this));
}
AbstractChart getAbstractChart() {
Object abstractChart = this.getAttributes().get(getClientId(getFacesContext()));
return (abstractChart != null)? (AbstractChart)abstractChart : null;
}
/**
* Gets the state of the instance as a Serializable
* Object.
*/
public Object saveState(FacesContext context) {
Object values[] = new Object[24];
values[0] = super.saveState(context);
// values[1] = new Integer(imageCounter);
values[2] = width;
values[3] = height;
values[4] = render ? Boolean.TRUE : Boolean.FALSE;
values[5] = chartTitle;
values[6] = data;
values[7] = labels;
values[8] = colors;
values[9] = shapes;
values[10] = xaxisLabels;
values[11] = xaxisTitle;
values[12] = yaxisTitle;
values[13] = style;
values[14] = styleClass;
values[15] = legendPlacement;
values[16] = legendColumns;
values[17] = horizontal ? Boolean.TRUE : Boolean.FALSE;
values[18] = horizontalSet ? Boolean.TRUE : Boolean.FALSE;
values[19] = chartURI;
values[20] = chartResource;
values[21] = saveAttachedState(context, renderOnSubmitMethodBinding);
values[22] = type;
values[23] = parentFormId;
return ((Object) (values));
}
/**
* Perform any processing required to restore the state from the entries
* in the state Object.
*/
public void restoreState(FacesContext context, Object state) {
Object values[] = (Object[]) state;
super.restoreState(context, values[0]);
// imageCounter = ((Integer) values[1]).intValue();
width = (String) values[2];
height = (String) values[3];
render = ((Boolean) values[4]).booleanValue();
chartTitle = (String) values[5];
data = values[6];
labels = values[7];
colors = values[8];
shapes = values[9];
xaxisLabels = values[10];
xaxisTitle = (String) values[11];
yaxisTitle = (String) values[12];
style = (String) values[13];
styleClass = (String) values[14];
legendPlacement = values[15];
legendColumns = values[16];
horizontal = ((Boolean) values[17]).booleanValue();
horizontalSet = ((Boolean) values[18]).booleanValue();
chartURI = (URI) values[19];
chartResource = (ChartResource) values[20];
renderOnSubmitMethodBinding = (MethodBinding) restoreAttachedState(context, values[21]);
type = (String) values[22];
parentFormId = (String) values[23];
}
public ChartResource getChartResource() {
return chartResource;
}
public void setChartResource(ChartResource chartResource) {
this.chartResource = chartResource;
}
public URI getChartURI() {
return chartURI;
}
public void setChartURI(URI chartURI) {
this.chartURI = chartURI;
}
}