Commit 463789de by Alex Rhodes

Added pie chart support, incomplete, needs all base features of slice and…

Added pie chart support, incomplete, needs all base features of slice and piechart objects implemented in builder
parent 2cbb6532
......@@ -6,20 +6,20 @@
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8">
<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
<attributes>
<attribute name="maven.pomderived" value="true"/>
<attribute name="org.eclipse.jst.component.dependency" value="/WEB-INF/lib"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.jst.server.core.container/org.eclipse.jst.server.tomcat.runtimeTarget/Apache Tomcat v7.0">
<classpathentry kind="con" path="org.eclipse.jst.server.core.container/org.eclipse.jst.server.tomcat.runtimeTarget/Apache Tomcat v8.0">
<attributes>
<attribute name="owner.project.facets" value="jst.web"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7">
<attributes>
<attribute name="maven.pomderived" value="true"/>
<attribute name="org.eclipse.jst.component.dependency" value="/WEB-INF/lib"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.jdt.USER_LIBRARY/JSF 2.2 (Mojarra 2.2.0)">
......
<?xml version="1.0" encoding="UTF-8"?><project-modules id="moduleCoreId" project-version="1.5.0">
<wb-module deploy-name="GoogleChartsJSF">
<wb-module deploy-name="GoogleChartsJSF-0.0.1-SNAPSHOT">
<wb-resource deploy-path="/" source-path="/target/m2e-wtp/web-resources"/>
<wb-resource deploy-path="/" source-path="/WebContent" tag="defaultRootSource"/>
<wb-resource deploy-path="/WEB-INF/classes" source-path="/src"/>
......
<?xml version="1.0" encoding="UTF-8"?>
<faceted-project>
<runtime name="Apache Tomcat v7.0"/>
<runtime name="Apache Tomcat v8.0"/>
<fixed facet="jst.web"/>
<fixed facet="wst.jsdt.web"/>
<fixed facet="java"/>
<installed facet="java" version="1.8"/>
<installed facet="jst.web" version="3.0"/>
<installed facet="wst.jsdt.web" version="1.0"/>
<installed facet="jst.jsf" version="2.2"/>
<installed facet="java" version="1.7"/>
</faceted-project>
......@@ -10,7 +10,8 @@
<h:head>
</h:head>
<h:body>
<gc:googleChart type="combo" value="#{googleChartBean.chart}"/>
<gc:googleChart type="combo" value="#{googleChartBean.combo}"/>
<gc:googleChart type="pie" value="#{googleChartBean.pie}"/>
</h:body>
</html>
......@@ -6,12 +6,15 @@ package com.alexscottrhodes.builder;
import java.util.ArrayList;
import java.util.Date;
import com.alexscottrhodes.chartModel.GoogleChartCore;
import com.alexscottrhodes.chartModel.GoogleComboChart;
import com.alexscottrhodes.chartModel.GooglePieChart;
import com.alexscottrhodes.chartModel.components.PieSlice;
import com.alexscottrhodes.constructionModel.ChartSeries;
import com.alexscottrhodes.enums.AxisType;
import com.alexscottrhodes.enums.SeriesType;
import com.alexscottrhodes.exceptions.AxesException;
import com.alexscottrhodes.exceptions.ChartException;
import com.alexscottrhodes.exceptions.PieChartException;
/**
* This class contains methods to render the chart object JS
......@@ -25,7 +28,7 @@ public class Builder {
* @param gcc a GoogleChartCore object representing the chart
* @return a String to render
*/
public String buildComboChart(GoogleChartCore gcc){
public String buildComboChart(GoogleComboChart gcc){
//Verify at least one Axis is provided
if(gcc.getAxes().get(AxisType.X).size()==0){
throw new AxesException("No x axis provided.");
......@@ -173,18 +176,139 @@ public class Builder {
width = 1100;
}
String footer = "" +
"var chart = new google.visualization.ComboChart(document.getElementById('j_id_comboChartTarget'));"+
"var chart = new google.visualization.ComboChart(document.getElementById('"+gcc.getId()+"_comboChartTarget'));"+
"chart.draw(data,options);"+
"});"+
"} "+
"}); "+
"</script>"+
"<div style='width:"+width+"px;height:"+height+"px;clear:both' id='j_id_comboChartTarget'></div>";
"<div style='width:"+width+"px;height:"+height+"px;clear:both' id='"+gcc.getId()+"_comboChartTarget'></div>";
String result = header + dataRows + options + footer;
return result;
}
public String buildPieChart(GooglePieChart gpc){
//verify data was named
if(gpc.getDataName()==null){
throw new PieChartException("No data name provided.");
}
if(gpc.getDataType()==null){
throw new PieChartException("No data type provided.");
}
if(gpc.getSlices().size()<1){
throw new PieChartException("No data slices provided.");
}
if(gpc.getDonutHoleSize()!=0 && (gpc.getDonutHoleSize()<0.2 || gpc.getDonutHoleSize() > 1)){
throw new PieChartException("Donut hole size invalid.");
}
//Script header dynamically checks for and loads required Google API JS files while avoiding duplicate call exceptions
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(){";
//Data section of the chart
String dataRows="var data = google.visualization.arrayToDataTable([";
String colNames = "['" + gpc.getDataName() + "','"+gpc.getDataType() + "'],";
dataRows += colNames;
for(PieSlice s : gpc.getSlices()){
String row = "[";
row +="'"+s.getName()+"'";
row += ",";
row+= s.getValue();
row += "],";
dataRows += row;
}
dataRows = dataRows.substring(0,dataRows.lastIndexOf(','));
dataRows += "]);";
//Options seciton of the chart
String options = "var options = {";
if(gpc.getTitle() != null && gpc.getTitle() != ""){
options += "title: '" + gpc.getTitle() + "',";
}
options += "titleTextStyle:{";
if(gpc.getTitleColor() != null){
options+= "color: '"+gpc.getTitleColor()+"',";
options+= "bold:" + gpc.isTitleBold();
}
options+="},";
options+="pieStartAngle: " + gpc.getRotation() + ",";
if(gpc.getDonutHoleSize() != 0){
options+="pieHole:" + gpc.getDonutHoleSize() +",";
}
options+= "is3d:" + gpc.isIs3d() + ",";
String slices = "slices : {";
for(int i = 0; i < gpc.getSlices().size();i++){
PieSlice p = gpc.getSlices().get(i);
slices+= i+": {offset:" + p.getOffset() + "},";
}
slices = slices.substring(0, slices.lastIndexOf(","));
slices += "}";
options += slices + "};";
//Footer contains dynamically ID'd div to render the chart in
int height = gpc.getHeight();
int width = gpc.getWidth();
if(height == 0){
height = 500;
}
if(width == 0){
width = 1100;
}
String footer = "" +
"var chart = new google.visualization.PieChart(document.getElementById('"+gpc.getId()+"_pieChartTarget'));"+
"chart.draw(data,options);"+
"});"+
"} "+
"}); "+
"</script>"+
"<div style='width:"+width+"px;height:"+height+"px;clear:both' id='"+gpc.getId()+"_pieChartTarget'></div>";
String result = header + dataRows + options + footer;
System.out.println(result);
return result;
}
......
......@@ -10,7 +10,7 @@ import com.alexscottrhodes.constructionModel.ChartSeries;
import com.alexscottrhodes.enums.AxisType;
import com.alexscottrhodes.enums.CurveType;
public class GoogleChartCore {
public class GoogleComboChart {
private String id;
private String title;
private int width;
......@@ -24,7 +24,7 @@ public class GoogleChartCore {
private String verticalAxisLabel;
private CurveType curveType = CurveType.DEFAULT;
public GoogleChartCore(){
public GoogleComboChart(){
seriesList = new ArrayList<ChartSeries>();
axes = new HashMap<AxisType, ArrayList<ChartSeries>>();
axes.put(AxisType.X, new ArrayList<ChartSeries>());
......
package com.alexscottrhodes.chartModel;
import java.util.ArrayList;
import com.alexscottrhodes.chartModel.components.PieSlice;
public class GooglePieChart {
String id;
private String title;
private String dataType;
private String dataName;
private String titleColor;
private boolean titleBold;
private ArrayList<PieSlice> slices = new ArrayList<PieSlice>();
private int width;
private int height;
private boolean is3d;
private double donutHoleSize;
private int rotation;
public GooglePieChart(String dataName, String dataType){
this.dataName = dataName;
this.dataType = dataType;
}
public void addSlice(PieSlice slice){
slices.add(slice);
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getTitleColor() {
return titleColor;
}
public void setTitleColor(String titleColor) {
this.titleColor = titleColor;
}
public boolean isTitleBold() {
return titleBold;
}
public void setTitleBold(boolean titleBold) {
this.titleBold = titleBold;
}
public ArrayList<PieSlice> getSlices() {
return slices;
}
public void setSlices(ArrayList<PieSlice> slices) {
this.slices = slices;
}
public int getWidth() {
return width;
}
public void setWidth(int width) {
this.width = width;
}
public int getHeight() {
return height;
}
public void setHeight(int height) {
this.height = height;
}
public boolean isIs3d() {
return is3d;
}
public void setIs3d(boolean is3d) {
this.is3d = is3d;
}
public void setDonutHoleSize(double d) {
this.donutHoleSize = d;
}
public int getRotation() {
return rotation;
}
public void setRotation(int rotation) {
this.rotation = rotation;
}
public String getDataType() {
return dataType;
}
public void setDataType(String dataType) {
this.dataType = dataType;
}
public String getDataName() {
return dataName;
}
public void setDataName(String dataName) {
this.dataName = dataName;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public double getDonutHoleSize() {
return donutHoleSize;
}
}
package com.alexscottrhodes.chartModel.components;
public class PieSlice {
private double value;
private String name;
private boolean visible = true;
private String color;
private boolean showText = true;
private double offset;
public PieSlice(String name, double value){
this.name = name;
this.value = value;
}
public PieSlice(String name, int value){
this.name = name;
this.value = value;
}
public boolean isVisible() {
return visible;
}
public void setVisible(boolean visible) {
this.visible = visible;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
public boolean isShowText() {
return showText;
}
public void setShowText(boolean showText) {
this.showText = showText;
}
public void setOffset(double offset) {
this.offset = offset;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getValue() {
return value;
}
public void setValue(double value) {
this.value = value;
}
public double getOffset() {
return offset;
}
}
package com.alexscottrhodes.demo;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.Random;
import com.alexscottrhodes.chartModel.GoogleComboChart;
import com.alexscottrhodes.chartModel.GooglePieChart;
import com.alexscottrhodes.chartModel.components.PieSlice;
import com.alexscottrhodes.constructionModel.ChartSeries;
import com.alexscottrhodes.enums.AxisType;
import com.alexscottrhodes.enums.CurveType;
import com.alexscottrhodes.enums.SeriesDisplayType;
import com.alexscottrhodes.enums.SeriesType;
public class Charts {
public static GoogleComboChart getComboChart() {
GoogleComboChart gcc;
gcc = new GoogleComboChart();
gcc.setTitle("This is the Title");
gcc.setTitleBold(true); // Bolded title
gcc.setTitleColor("#59b300"); // Green title
gcc.setCurveType(CurveType.FUNCTION); // Smoothed curve
gcc.setHeight(800);
gcc.setWidth(1200);
gcc.setVerticalAxisLabel("Y-Axis vals"); // Label for Y-axis
gcc.setIndexLine(50, "Target Amount"); // add an index line
ChartSeries s = new ChartSeries(SeriesType.NUMBER); // Add a series of
// numbers
s.setDisplayType(SeriesDisplayType.LINE); // Make this series a line
s.setLabel("A line of values over time.");
for (Integer i : getRandVals()) {
s.addPoint(i); // Populate with some random numbers
}
ChartSeries t = new ChartSeries(SeriesType.NUMBER); // Add a series of
// numbers
t.setDisplayType(SeriesDisplayType.BAR); // Make this series bars
t.setLabel("A second set of values over time");
for (Integer i : getRandVals()) {
t.addPoint(i); // Populate with some random numbers
}
ChartSeries x = new ChartSeries(SeriesType.DATE); // Add a series of
// Dates
x.setDateFormat("yyyy-MM-dd"); // Format the date output
x.setLabel("Date - X-axis vals");
for (Date d : getDates()) {
x.addPoint(d); // Populate with some dates
}
gcc.addSeries(s); // Add series S
gcc.addSeries(t);// Add series T
gcc.addAxisSeries(x, AxisType.X); // Add the X-axis
return gcc;
}
public static GooglePieChart getPieChart(){
GooglePieChart gpc = new GooglePieChart("Activity","Time Spent");
gpc.setDataName("Activity");
gpc.setDataType("Time spent");
gpc.setHeight(900);
gpc.setWidth(700);
gpc.setIs3d(true);
gpc.setRotation(45);
gpc.setTitle("Debugging Code");
gpc.setTitleBold(true);
gpc.setTitleColor("#ff6600");
PieSlice p = new PieSlice("Googling",20);
p.setOffset(0.4);
PieSlice q = new PieSlice("Stack Exchange",30);
q.setOffset(0.2);
PieSlice r = new PieSlice("Stepping Through",40);
PieSlice s = new PieSlice("Crying", 10);
gpc.addSlice(p);
gpc.addSlice(q);
gpc.addSlice(r);
gpc.addSlice(s);
return gpc;
}
// Utility to get some random numbers
public static ArrayList<Integer> getRandVals() {
Random r = new Random();
ArrayList<Integer> result = new ArrayList<Integer>();
for (int i = 0; i < 10; i++) {
result.add(r.nextInt(100 - 10) + 10);
}
return result;
}
// Utility to get some dates
public static ArrayList<Date> getDates() {
ArrayList<Date> result = new ArrayList<Date>();
Calendar c = Calendar.getInstance();
c.setTime(new Date());
for (int i = 0; i < 10; i++) {
c.add(Calendar.DATE, 7);
result.add(c.getTime());
}
return result;
}
}
package com.alexscottrhodes.demo;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.Random;
import javax.annotation.PostConstruct;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import com.alexscottrhodes.chartModel.GoogleChartCore;
import com.alexscottrhodes.constructionModel.ChartSeries;
import com.alexscottrhodes.enums.AxisType;
import com.alexscottrhodes.enums.CurveType;
import com.alexscottrhodes.enums.SeriesDisplayType;
import com.alexscottrhodes.enums.SeriesType;
import com.alexscottrhodes.chartModel.GoogleComboChart;
import com.alexscottrhodes.chartModel.GooglePieChart;
@ManagedBean
@ViewScoped
public class GoogleChartBean {
private GoogleChartCore gcc;
private GoogleComboChart gcc;
private GooglePieChart gpc;
@PostConstruct
public void init(){
gcc = new GoogleChartCore();
gcc.setTitle("This is the Title");
gcc.setTitleBold(true); //Bolded title
gcc.setTitleColor("#59b300"); //Green title
gcc.setCurveType(CurveType.FUNCTION); //Smoothed curve
gcc.setHeight(800);
gcc.setWidth(1200);
gcc.setVerticalAxisLabel("Y-Axis vals"); //Label for Y-axis
gcc.setIndexLine(50, "Target Amount"); // add an index line
ChartSeries s = new ChartSeries(SeriesType.NUMBER); //Add a series of numbers
s.setDisplayType(SeriesDisplayType.LINE); //Make this series a line
s.setLabel("A line of values over time.");
for(Integer i : getRandVals()){
s.addPoint(i); //Populate with some random numbers
}
ChartSeries t = new ChartSeries(SeriesType.NUMBER); //Add a series of numbers
t.setDisplayType(SeriesDisplayType.BAR); //Make this series bars
t.setLabel("A second set of values over time");
for(Integer i : getRandVals()){
t.addPoint(i); //Populate with some random numbers
}
ChartSeries x = new ChartSeries(SeriesType.DATE); //Add a series of Dates
x.setDateFormat("yyyy-MM-dd"); //Format the date output
x.setLabel("Date - X-axis vals");
for(Date d : getDates()){
x.addPoint(d); //Populate with some dates
}
gcc = Charts.getComboChart();
gpc = Charts.getPieChart();
gcc.addSeries(s); //Add series S
gcc.addSeries(t);//Add series T
gcc.addAxisSeries(x,AxisType.X); //Add the X-axis
}
//Return the chart to render
public GoogleChartCore getChart(){
public GoogleComboChart getCombo(){
return gcc;
}
//Utility to get some random numbers
public ArrayList<Integer> getRandVals(){
Random r = new Random();
ArrayList<Integer> result = new ArrayList<Integer>();
for(int i = 0; i < 10; i++){
result.add(r.nextInt(100-10) + 10);
}
return result;
public GooglePieChart getPie(){
return gpc;
}
//Utility to get some dates
public ArrayList<Date> getDates(){
ArrayList<Date> result = new ArrayList<Date>();
Calendar c = Calendar.getInstance();
c.setTime(new Date());
for(int i = 0; i < 10; i++){
c.add(Calendar.DATE, 7);
result.add(c.getTime());
}
return result;
}
}
package com.alexscottrhodes.exceptions;
/**
* An exception thrown from construction of pie chart
* @author Alex Rhodes
*/
public class PieChartException extends RuntimeException{
private static final long serialVersionUID = 1L;
//No overrides
public PieChartException(String string) {
super(string);
}
public PieChartException(Throwable t){
super(t);
}
public PieChartException(String string, Throwable t){
super(string,t);
}
}
......@@ -11,64 +11,76 @@ import javax.faces.context.FacesContext;
import javax.faces.context.ResponseWriter;
import com.alexscottrhodes.builder.Builder;
import com.alexscottrhodes.chartModel.GoogleChartCore;
import com.alexscottrhodes.chartModel.GoogleComboChart;
import com.alexscottrhodes.chartModel.GooglePieChart;
import com.alexscottrhodes.exceptions.ChartException;
/**
* Tag handler for the google charts API wrapper.
*
* @author Alex Rhodes
*
*/
@FacesComponent(tagName="googleChart",createTag = true, namespace="http://alexscottrhodes.com/facelets", value="com.alexscottrhodes.googleChart")
public class GoogleChartTagHandler extends UIComponentBase{
@FacesComponent(tagName = "googleChart", createTag = true, namespace = "http://alexscottrhodes.com/facelets", value = "com.alexscottrhodes.googleChart")
public class GoogleChartTagHandler extends UIComponentBase {
@Override
public String getFamily() {
return "com.alexscottrhodes.googleChart";
}
@Override
public void encodeEnd(FacesContext context) throws IOException{
GoogleChartCore gcc = null;
public void encodeEnd(FacesContext context) throws IOException {
GoogleComboChart gcc = null;
GooglePieChart gpc = null;
ResponseWriter writer = context.getResponseWriter();
String output = null;
String id = "";
try{
try {
id = (String) this.getAttributes().get("id");
}catch(Exception e){
} catch (Exception e) {
throw new ChartException("No ID Specified");
}
//Collect parameters
// Collect parameters
String typeString = (String) getAttributes().get("type");
Object chartObject = getAttributes().get("value");
if(typeString == null){
if (typeString == null) {
throw new ChartException("Invalid or missing chart type.");
}
//Cast to appropriate chart model
if(typeString.equals("combo")){
// Cast to appropriate chart model
if (typeString.equals("combo")) {
try{
gcc = (GoogleChartCore) chartObject;
try {
gcc = (GoogleComboChart) chartObject;
gcc.setId(id);
}catch(Exception e){
} catch (Exception e) {
throw new ChartException("Invalid chart model.");
}
Builder b = new Builder();
try{
try {
output = b.buildComboChart(gcc);
}catch(Exception e){
} catch (Exception e) {
throw new ChartException("Error rendering.");
}
}
else if (typeString.equals("pie")) {
try {
gpc = (GooglePieChart) chartObject;
gpc.setId(id);
} catch (Exception e) {
throw new ChartException("Invalid chart model.");
}
Builder b = new Builder();
output = b.buildPieChart(gpc);
}
else{
else {
throw new ChartException("Invalid chart type:" + typeString);
}
writer.write(output);
}
}
\ No newline at end of file
Manifest-Version: 1.0
Built-By: arhodes
Build-Jdk: 1.8.0_92
Built-By: Alex
Build-Jdk: 1.8.0_51
Created-By: Maven Integration for Eclipse
#Generated by Maven Integration for Eclipse
#Fri Jul 22 09:47:45 MST 2016
#Mon Jul 25 17:13:43 MST 2016
version=0.0.1-SNAPSHOT
groupId=com.alexscottrhodes
m2e.projectName=googlechartjsf
m2e.projectLocation=C\:\\workspace\\googlechartjsf
m2e.projectLocation=E\:\\Portfolio Workspace\\googlechartjsf
artifactId=GoogleChartsJSF
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