Commit 0512cdcc by Alex Rhodes

Refactor, dynamic script loading

parent 74be9459
/target/
<?xml version="1.0" encoding="UTF-8"?>
<pageflow:Pageflow xmlns:pageflow="http://www.sybase.com/suade/pageflow" id="pf14679051087010" configfile="/googlechartjsf/WebContent/META-INF/faces-config.xml"/>
...@@ -6,11 +6,12 @@ ...@@ -6,11 +6,12 @@
xmlns:f="http://java.sun.com/jsf/core" xmlns:f="http://java.sun.com/jsf/core"
xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:p="http://primefaces.org/ui" xmlns:p="http://primefaces.org/ui"
xmlns:gc="http://xmlns.alexscottrhodes.com/gchart"> xmlns:gc="http://alexscottrhodes.com/facelets">
<h:head> <h:head>
</h:head> </h:head>
<h:body> <h:body>
<gc:googleChart/> <gc:googleChart type="line" value="#{googleChartBean.lineChart}" rendered = "false"/>
</h:body> </h:body>
</html> </html>
\ No newline at end of file
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<groupId>com.alexscottrhodes</groupId> <groupId>com.alexscottrhodes</groupId>
<artifactId>GoogleChartsJSF</artifactId> <artifactId>GoogleChartsJSF</artifactId>
...@@ -12,11 +13,6 @@ ...@@ -12,11 +13,6 @@
<artifactId>primefaces</artifactId> <artifactId>primefaces</artifactId>
<version>5.3</version> <version>5.3</version>
</dependency> </dependency>
<dependency>
<groupId>org.primefaces.extensions</groupId>
<artifactId>all-themes</artifactId>
<version>1.0.8</version>
</dependency>
</dependencies> </dependencies>
<build> <build>
<sourceDirectory>src</sourceDirectory> <sourceDirectory>src</sourceDirectory>
......
<html>
<head>
<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
<script type="text/javascript">
google.charts.load('current', {'packages':['line']});
google.charts.setOnLoadCallback(drawChart);
function drawChart() {
var data = new google.visualization.DataTable();
data.addColumn('number', 'Day');
data.addColumn('number', 'Guardians of the Galaxy');
data.addColumn('number', 'The Avengers');
data.addColumn('number', 'Transformers: Age of Extinction');
data.addRows([
[1, 37.8, 80.8, 41.8],
[2, 30.9, 69.5, 32.4],
[3, 25.4, 57, 25.7],
[4, 11.7, 18.8, 10.5],
[5, 11.9, 17.6, 10.4],
[6, 8.8, 13.6, 7.7],
[7, 7.6, 12.3, 9.6],
[8, 12.3, 29.2, 10.6],
[9, 16.9, 42.9, 14.8],
[10, 12.8, 30.9, 11.6],
[11, 5.3, 7.9, 4.7],
[12, 6.6, 8.4, 5.2],
[13, 4.8, 6.3, 3.6],
[14, 4.2, 6.2, 3.4]
]);
var options = {
chart: {
title: 'Box Office Earnings in First Two Weeks of Opening',
subtitle: 'in millions of dollars (USD)'
},
width: 900,
height: 500,
axes: {
x: {
0: {side: 'top'}
}
}
};
var chart = new google.charts.Line(document.getElementById('line_top_x'));
chart.draw(data, options);
}
</script>
</head>
<body>
<div id="line_top_x"></div>
</body>
</html>
Manifest-Version: 1.0
Class-Path:
<?xml version="1.0" encoding="UTF-8"?>
<faces-config
xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-facesconfig_2_2.xsd"
version="2.2">
</faces-config>
...@@ -3,8 +3,13 @@ ...@@ -3,8 +3,13 @@
*/ */
package com.alexscottrhodes.builder; package com.alexscottrhodes.builder;
import com.alexscottrhodes.chartModel.GoogleLineChart; import java.util.ArrayList;
import java.util.Date;
import com.alexscottrhodes.chartModel.GoogleChartCore;
import com.alexscottrhodes.constructionModel.ChartSeries;
import com.alexscottrhodes.enums.AxisType; import com.alexscottrhodes.enums.AxisType;
import com.alexscottrhodes.enums.SeriesType;
import com.alexscottrhodes.exceptions.AxesException; import com.alexscottrhodes.exceptions.AxesException;
/** /**
...@@ -12,21 +17,153 @@ import com.alexscottrhodes.exceptions.AxesException; ...@@ -12,21 +17,153 @@ import com.alexscottrhodes.exceptions.AxesException;
* *
*/ */
public class Builder { public class Builder {
public String buildComboChart(GoogleChartCore gcc) throws Exception{
if(gcc.getAxes().get(AxisType.X).size()==0){
public String build(GoogleLineChart glc) throws AxesException{
String chart = "function drawChart() {";
chart+= "var data = new google.visualization.DataTable();";
if(glc.getAxes().get(AxisType.X).size()==0){
throw new AxesException("No x axis provided."); throw new AxesException("No x axis provided.");
} }
ArrayList<ChartSeries> data = new ArrayList<ChartSeries>();
data.addAll(gcc.getAxes().get(AxisType.X));
data.addAll(gcc.getSeriesList());
if(gcc.getIndexLineVal() != 0){
ChartSeries index = new ChartSeries(SeriesType.NUMBER);
int iter = gcc.getAxes().get(AxisType.X).get(0).getDataset().size();
for(int i = 0; i < iter; i++){
index.addPoint(gcc.getIndexLineVal());
}
index.setLabel(gcc.getIndexLineLabel());
data.add(index);
}
int size = 0;
String header = ""+
"<script>"+
"function loader(){"+
"var s = document.createElement(\"script\");"+
"s.src = \"https://www.gstatic.com/charts/loader.js\";"+
"if (s.addEventListener){"+
"window.gChartLoaded = true;"+
"s.addEventListener(\"load\", initGlobal, false);"+
"}else if (s.readyState){"+
"window.gChartLoaded = true;"+
"s.onreadystatechange = initGlobal;"+
"}"+
"document.getElementsByTagName('head')[0].appendChild(s);"+
"}"+
"if(typeof gChartLoaded == \"undefined\"){"+
"window.gChartLoaded = false;"+
"}"+
"if(typeof google == \"undefined\" && !window.gChartLoaded){"+
"loader();"+
"}"+
"function initGlobal(){"+
"window.gChartPackageLoaded = true;"+
"google.charts.load('current', {'packages':['corechart']});"+
"}"+
"</script>"+
"<script>"+
"var asyncLoopA = function(o){"+
"var loop = function(){"+
"if(typeof google != \"undefined\"){o.callback(); return;}"+
"o.asyncLoopFunc(loop);"+
"}\n"+
"loop();"+
"}\n"+
"asyncLoopA({"+
"asyncLoopFunc : function(loop){"+
" setTimeout(function(){loop();},0);"+
"},"+
"callback : function(){"+
" google.charts.setOnLoadCallback(function(){";
String dataRows="var data = google.visualization.arrayToDataTable([";
String colNames = "[";
for(ChartSeries s : data){
colNames += "'"+s.getLabel() + "',";
if(s.getDataset().size()>size){
size = s.getDataset().size();
}
}
colNames = colNames.substring(0, colNames.lastIndexOf(',')) + "],";
dataRows += colNames;
for(int i = 0 ; i < size; i++){
String row = "[";
for(ChartSeries s : data){
if(i< s.getDataset().size()){
if(s.getType()==SeriesType.NUMBER){
row+= s.getDataset().get(i);
}else if(s.getType()==SeriesType.DATE){
row+= "'" + s.getDateFormat().format((Date)s.getDataset().get(i)) + "'";
}else{
row+= "'" + s.getDataset().get(i) + "'";
}
}else{
row+="null";
}
row += ",";
}
row = row.substring(0, row.lastIndexOf(','));
row += "],";
dataRows += row;
}
dataRows = dataRows.substring(0,dataRows.lastIndexOf(','));
dataRows += "]);";
String options = "var options = {";
if(gcc.getTitle() != null && gcc.getTitle() != ""){
options += "title: '" + gcc.getTitle() + "',";
}
options += "titleTextStyle:{";
if(gcc.getTitleColor() != null){
options+= "color: '"+gcc.getTitleColor()+"',";
options+= "bold:" + gcc.isTitleBold();
}
options+="},";
ChartSeries x = gcc.getAxes().get(AxisType.X).get(0);
ArrayList<ChartSeries> yList = gcc.getAxes().get(AxisType.Y);
String yLabel = "";
if(yList != null && yList.size() > 0 && yList.get(0) != null){
yLabel = yList.get(0).getLabel();
}
if(yLabel == null || yLabel.equals("")){
yLabel = gcc.getVerticalAxisLabel();
}
if(yLabel == null){
yLabel = "";
}
options += "hAxis: {title:'"+x.getLabel()+"'},";
options += "vAxis: {title:'"+yLabel+"'},";
options += "seriesType: '" + x.getDisplayType().toString() + "',";
String innerSeries ="series:{";
for(int i = 0; i < gcc.getSeriesList().size(); i++){
ChartSeries s = gcc.getSeriesList().get(i);
innerSeries += i+": {type:'" + s.getDisplayType().toString()+"'},";
}
if(gcc.getIndexLineVal() != 0){
innerSeries += gcc.getSeriesList().size() + ": {type:'line',lineDashStyle: [5,8],color:'red' },";
}
innerSeries = innerSeries.substring(0,innerSeries.lastIndexOf(','));
innerSeries +="}";
options += innerSeries + "};";
return chart; String footer = "" +
"var chart = new google.visualization.ComboChart(document.getElementById('j_id_comboChartTarget'));"+
"chart.draw(data,options);"+
"});"+
"} "+
"}); "+
"</script>"+
"<div style='width:1400;height:700;clear:both' id='j_id_comboChartTarget'></div>";
String result = header + dataRows + options + footer;
return result;
} }
} }
/**
*
*/
package com.alexscottrhodes.chartModel; package com.alexscottrhodes.chartModel;
import java.util.ArrayList; import java.util.ArrayList;
...@@ -9,20 +6,20 @@ import java.util.HashMap; ...@@ -9,20 +6,20 @@ import java.util.HashMap;
import com.alexscottrhodes.constructionModel.ChartSeries; import com.alexscottrhodes.constructionModel.ChartSeries;
import com.alexscottrhodes.enums.AxisType; import com.alexscottrhodes.enums.AxisType;
/** public class GoogleChartCore {
* @author Alex Rhodes
*
*/
public class GoogleLineChart {
private String id; private String id;
private String title; private String title;
private String subtitle;
private int width; private int width;
private int height; private int height;
private int indexLineVal;
private String indexLineLabel;
private ArrayList<ChartSeries> seriesList; private ArrayList<ChartSeries> seriesList;
private HashMap<AxisType, ArrayList<ChartSeries>> axes; private HashMap<AxisType, ArrayList<ChartSeries>> axes;
private String titleColor;
private boolean titleBold;
private String verticalAxisLabel;
public GoogleLineChart(){ public GoogleChartCore(){
seriesList = new ArrayList<ChartSeries>(); seriesList = new ArrayList<ChartSeries>();
axes = new HashMap<AxisType, ArrayList<ChartSeries>>(); axes = new HashMap<AxisType, ArrayList<ChartSeries>>();
axes.put(AxisType.X, new ArrayList<ChartSeries>()); axes.put(AxisType.X, new ArrayList<ChartSeries>());
...@@ -49,12 +46,6 @@ public class GoogleLineChart { ...@@ -49,12 +46,6 @@ public class GoogleLineChart {
public void setTitle(String title) { public void setTitle(String title) {
this.title = title; this.title = title;
} }
public String getSubtitle() {
return subtitle;
}
public void setSubtitle(String subtitle) {
this.subtitle = subtitle;
}
public int getWidth() { public int getWidth() {
return width; return width;
} }
...@@ -82,7 +73,41 @@ public class GoogleLineChart { ...@@ -82,7 +73,41 @@ public class GoogleLineChart {
this.axes = axes; this.axes = axes;
} }
public boolean isTitleBold() {
return titleBold;
}
public void setTitleBold(boolean titleBold) {
this.titleBold = titleBold;
}
public String getTitleColor() {
return titleColor;
}
public void setTitleColor(String titleColor) {
this.titleColor = titleColor;
}
public String getVerticalAxisLabel() {
return verticalAxisLabel;
}
public void setVerticalAxisLabel(String verticalAxisLabel) {
this.verticalAxisLabel = verticalAxisLabel;
}
public void setIndexLine(int value, String label) {
this.indexLineVal = value;
this.indexLineLabel = label;
}
public String getIndexLineLabel() {
return indexLineLabel;
}
public int getIndexLineVal() {
return indexLineVal;
}
} }
...@@ -3,42 +3,83 @@ ...@@ -3,42 +3,83 @@
*/ */
package com.alexscottrhodes.constructionModel; package com.alexscottrhodes.constructionModel;
import java.text.SimpleDateFormat;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Date;
import com.alexscottrhodes.enums.SeriesDisplayType;
import com.alexscottrhodes.enums.SeriesType;
/** /**
* @author Alex Rhodes * @author Alex Rhodes
* *
*/ */
@SuppressWarnings("unchecked")
public class ChartSeries { public class ChartSeries {
private boolean axis; private String label = "";
private String label; private SeriesType type = SeriesType.STRING;
private ArrayList<Integer> dataset; private SeriesDisplayType displayType = SeriesDisplayType.BAR;
private ArrayList<String> axisDataset; private SimpleDateFormat simpleDateFormat = new SimpleDateFormat("MM-dd-yyyy hh:mm:ss");
public boolean isAxis() {
return axis;
} public ChartSeries(SeriesType type){
public void setAxis(boolean axis) { this.type = type;
this.axis = axis;
} }
@SuppressWarnings("rawtypes")
private ArrayList dataset = new ArrayList();
public String getLabel() { public String getLabel() {
return label; return label;
} }
public void setLabel(String label) { public void setLabel(String label) {
this.label = label; this.label = label;
} }
public ArrayList<Integer> getDataset() { @SuppressWarnings("rawtypes")
public ArrayList getDataset() {
return dataset; return dataset;
} }
public void setDataset(ArrayList<Integer> dataset) {
this.dataset = dataset;
public void addPoint(Integer point){
dataset.add(point);
}
public void addPoint(String point){
dataset.add(point);
}
public void addPoint(Date point){
try{
point = simpleDateFormat.parse(simpleDateFormat.format(point));
dataset.add(point);
}catch(Exception e){
try {
throw new Exception("Unable to parse date: " + point);
} catch (Exception e1) {
e1.printStackTrace();
} }
public ArrayList<String> getAxisDataset() {
return axisDataset;
} }
public void setAxisDataset(ArrayList<String> axisDataset) {
this.axisDataset = axisDataset;
} }
public void addPoint(Float point){
dataset.add(point);
}
public SeriesType getType(){
return type;
}
public SimpleDateFormat getDateFormat() {
return simpleDateFormat;
}
public void setDateFormat(String format) {
simpleDateFormat = new SimpleDateFormat(format);
}
public SeriesDisplayType getDisplayType() {
return displayType;
}
public void setDisplayType(SeriesDisplayType displayType) {
this.displayType = displayType;
}
} }
/**
*
*/
package com.alexscottrhodes.constructionModel;
import java.util.ArrayList;
/**
* @author Alex Rhodes
*
*/
public class DataModel {
private ArrayList<Integer> points;
public DataModel(){
points = new ArrayList<Integer>();
}
public void addPoint(Integer point){
points.add(point);
}
}
package com.alexscottrhodes.demo;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
@ManagedBean
@ViewScoped
public class GoogleChartBean {
}
...@@ -18,5 +18,8 @@ public enum AxisType { ...@@ -18,5 +18,8 @@ public enum AxisType {
this.name = name; this.name = name;
} }
public String getName(){
return name;
}
} }
package com.alexscottrhodes.enums;
public enum CurveType {
FUNCTION,
DEFAULT;
}
package com.alexscottrhodes.enums;
public enum SeriesDisplayType {
LINE("line"), BAR("bars"),AREA("area"), CANDLESTICKS("candlesticks"), STEPPED_AREA("steppedArea");
private String chartDef;
SeriesDisplayType(String chartDef){
this.chartDef = chartDef;
}
@Override
public String toString(){
return chartDef;
}
}
package com.alexscottrhodes.enums;
public enum SeriesType {
DATE("string"),STRING("string"),NUMBER("number");
private String chartDef;
private SeriesType(String def){
this.chartDef = def;
}
public String getDef(){
return chartDef;
}
}
...@@ -8,11 +8,21 @@ package com.alexscottrhodes.exceptions; ...@@ -8,11 +8,21 @@ package com.alexscottrhodes.exceptions;
* *
*/ */
public class AxesException extends Exception{ public class AxesException extends Exception{
private static final long serialVersionUID = 1L;
//No overrides
public AxesException(String string) { public AxesException(String string) {
super(string); super(string);
} }
private static final long serialVersionUID = 1L; public AxesException(Throwable t){
//No overrides super(t);
}
public AxesException(String string, Throwable t){
super(string,t);
}
} }
package com.alexscottrhodes.exceptions;
public class ChartException extends Exception{
private static final long serialVersionUID = 1L;
//No overrides
public ChartException(String string) {
super(string);
}
public ChartException(Throwable t){
super(t);
}
public ChartException(String string, Throwable t){
super(string,t);
}
}
...@@ -10,20 +10,79 @@ import javax.faces.component.UIComponentBase; ...@@ -10,20 +10,79 @@ import javax.faces.component.UIComponentBase;
import javax.faces.context.FacesContext; import javax.faces.context.FacesContext;
import javax.faces.context.ResponseWriter; import javax.faces.context.ResponseWriter;
import com.alexscottrhodes.builder.Builder;
import com.alexscottrhodes.chartModel.GoogleChartCore;
import com.alexscottrhodes.exceptions.ChartException;
/** /**
* Tag handler for the google charts API wrapper.
*
* @author Alex Rhodes * @author Alex Rhodes
* *
*/ */
@FacesComponent(value="com.alexscottrhodes.gchart", createTag = true, namespace="http://xmlns.alexscottrhodes.com/gchart",tagName="googleChart") @FacesComponent(tagName="googleChart",createTag = true, namespace="http://alexscottrhodes.com/facelets", value="com.alexscottrhodes.googleChart")
public class GoogleChartTagHandler extends UIComponentBase{ public class GoogleChartTagHandler extends UIComponentBase{
@Override @Override
public String getFamily() { public String getFamily() {
return "com.alexscottrhodes.gchart"; return "com.alexscottrhodes.googleChart";
} }
@Override @Override
public void encodeEnd(FacesContext context) throws IOException { public void encodeEnd(FacesContext context) throws IOException{
GoogleChartCore gcc = null;
ResponseWriter writer = context.getResponseWriter(); ResponseWriter writer = context.getResponseWriter();
writer.write("test"); String output = null;
String id = "";
try{
id = (String) this.getAttributes().get("id");
}catch(Exception e){
try{throw new Exception("No ID Specified");}catch(Exception ex){e.printStackTrace();}
}
//Collect parameters
String typeString = (String) getAttributes().get("type");
Object chartObject = getAttributes().get("value");
if(typeString == null){
try{
throw new ChartException("Invalid or missing chart type.");
}catch(Exception ex){
ex.printStackTrace();
}
}
//Cast to appropriate chart model
if(typeString.equals("combo")){
try{
gcc = (GoogleChartCore) chartObject;
gcc.setId(id);
}catch(Exception e){
try{
e.printStackTrace();
throw new ChartException("Invalid chart model.");
}catch(Exception ex){
ex.printStackTrace();
}
}
Builder b = new Builder();
try{
output = b.buildComboChart(gcc);
}catch(Exception e){
try{
e.printStackTrace();
throw e;}catch(Exception ex){}
}
}
else{
try{throw new ChartException("Invalid chart type:" + typeString);}catch(Exception e){}
}
writer.write(output);
} }
} }
\ No newline at end of file
Manifest-Version: 1.0 Manifest-Version: 1.0
Built-By: Alex Built-By: arhodes
Build-Jdk: 1.8.0_51 Build-Jdk: 1.8.0_92
Created-By: Maven Integration for Eclipse Created-By: Maven Integration for Eclipse
#Generated by Maven Integration for Eclipse #Generated by Maven Integration for Eclipse
#Fri Jun 24 16:24:18 MST 2016 #Thu Jul 14 13:19:00 MST 2016
version=0.0.1-SNAPSHOT version=0.0.1-SNAPSHOT
groupId=com.alexscottrhodes groupId=com.alexscottrhodes
m2e.projectName=GoogleChartsJSF m2e.projectName=googlechartjsf
m2e.projectLocation=C\:\\Users\\Alex\\workspace\\GoogleChartsJSF m2e.projectLocation=C\:\\workspace\\googlechartjsf
artifactId=GoogleChartsJSF artifactId=GoogleChartsJSF
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<groupId>com.alexscottrhodes</groupId> <groupId>com.alexscottrhodes</groupId>
<artifactId>GoogleChartsJSF</artifactId> <artifactId>GoogleChartsJSF</artifactId>
...@@ -12,11 +13,6 @@ ...@@ -12,11 +13,6 @@
<artifactId>primefaces</artifactId> <artifactId>primefaces</artifactId>
<version>5.3</version> <version>5.3</version>
</dependency> </dependency>
<dependency>
<groupId>org.primefaces.extensions</groupId>
<artifactId>all-themes</artifactId>
<version>1.0.8</version>
</dependency>
</dependencies> </dependencies>
<build> <build>
<sourceDirectory>src</sourceDirectory> <sourceDirectory>src</sourceDirectory>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment