GChart is a JSF wrapper of the Google Charts API, the chart library used by Google Analytics and other Google services. It also provides an organizational chart and a geo chart.
The component needs a GChartModel, created with a GChartModelBuilder. The select AJAX event contains a JSONArray with the selected rows.
A chart can have multiple series: choose the right GChartType (COLUMN here) and fill more columns.
Google Charts is versatile: here it displays an organizational chart. A TreeNode can generate the GChartModel for this kind of chart.
A geo chart shows data about countries. Rows are added with simple strings or with java.util.Locale.
Due to the Google Charts Terms of Service it is not possible to download the library to a server: the API is loaded from the servers of Google, so the client must be connected to the internet for the component to work.
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div class="card">
<h5>Basic usage</h5>
<p>The component needs a <code>GChartModel</code>, created with a <code>GChartModelBuilder</code>. The <i>select</i> AJAX event contains a <code>JSONArray</code> with the selected rows.</p>
<h:form id="formBasic">
<p:messages id="messages"/>
<p:outputPanel id="container" layout="block">
<h:panelGrid columns="4">
<h:outputText value="Mushrooms"/>
<h:outputText value="Onions"/>
<h:outputText value="Type"/>
<h:panelGroup/>
<p:inputText converter="jakarta.faces.Integer" value="#{basicGChartController.mushrooms}"/>
<p:inputText converter="jakarta.faces.Integer" value="#{basicGChartController.onions}"/>
<h:selectOneMenu value="#{basicGChartController.chartType}">
<f:selectItems value="#{basicGChartController.types}"/>
</h:selectOneMenu>
<p:commandButton value="Generate" update="container messages" action="#{basicGChartController.generateModel}"/>
</h:panelGrid>
<pe:gChart value="#{basicGChartController.chart}" title="How Much Pizza I Ate Last Night">
<p:ajax listener="#{basicGChartController.onSelect}" update="messages"/>
</pe:gChart>
</p:outputPanel>
</h:form>
</div>
<div class="card">
<h5>Multiple Series</h5>
<p>A chart can have multiple series: choose the right <code>GChartType</code> (<code>COLUMN</code> here) and fill more columns.</p>
<h:form id="formMultiple">
<pe:gChart value="#{multipleSeriesGChartController.chart}" title="Company Performance"/>
</h:form>
</div>
<div class="card">
<h5>Organizational Chart</h5>
<p>Google Charts is versatile: here it displays an organizational chart. A <code>TreeNode</code> can generate the <code>GChartModel</code> for this kind of chart.</p>
<h:form id="formOrganizational">
<p:tabView>
<p:tab title="Standard">
<pe:gChart value="#{organizationalGChartController.standardModel}"/>
</p:tab>
<p:tab title="TreeDataModel">
<pe:gChart value="#{organizationalGChartController.treeModel}"/>
</p:tab>
</p:tabView>
</h:form>
</div>
<div class="card">
<h5>Geo Chart</h5>
<p>A geo chart shows data about countries. Rows are added with simple strings or with <code>java.util.Locale</code>.</p>
<h:form id="formGeochart">
<pe:gChart value="#{geoChartGChartController.chart}"/>
</h:form>
</div>
package org.primefaces.extensions.showcase.controller.gchart;
import java.io.Serial;
import java.io.Serializable;
import java.util.*;
import jakarta.annotation.PostConstruct;
import jakarta.enterprise.context.RequestScoped;
import jakarta.faces.application.FacesMessage;
import jakarta.faces.context.FacesContext;
import jakarta.inject.Named;
import org.primefaces.event.SelectEvent;
import org.primefaces.extensions.component.gchart.model.DefaultGChartModelColumn;
import org.primefaces.extensions.component.gchart.model.GChartModel;
import org.primefaces.extensions.component.gchart.model.GChartModelBuilder;
import org.primefaces.extensions.component.gchart.model.GChartType;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
@Named
@RequestScoped
public class BasicGChartController implements Serializable {
@Serial
private static final long serialVersionUID = 253762400419864192L;
private final Random random = new Random();
private int mushrooms = random.nextInt(10);
private int onions = random.nextInt(10);
private GChartType chartType = GChartType.PIE;
private GChartModel chartModel = null;
public GChartModel getChart() {
return chartModel;
}
@PostConstruct
public void generateModel() {
// tooltip use values
final HashMap<String, String> tooltip = new HashMap<>();
tooltip.put("text", "value");
// color each slice
final List<String> colors = Arrays.asList("#F39C12", "#7D3C98");
chartModel = new GChartModelBuilder().setChartType(getChartType())
.addOption("colors", colors)
.addOption("tooltip", tooltip)
.addOption("pieSliceText", "percentage")
.addColumns(new DefaultGChartModelColumn("Topping", "string"),
new DefaultGChartModelColumn("Slices", "number"))
.addRow("Mushrooms", mushrooms).addRow("Onions", onions).build();
}
public void onSelect(final SelectEvent event) {
final JsonArray value = (JsonArray) event.getObject();
if (value.size() > 0) {
final JsonElement element = value.get(0);
final String label = new ArrayList<>(getChart().getRows())
.get(element.getAsJsonObject().get("row").getAsInt()).getLabel();
FacesContext.getCurrentInstance().addMessage(null,
new FacesMessage(FacesMessage.SEVERITY_INFO, "You have selected: " + label, null));
}
}
public int getMushrooms() {
return mushrooms;
}
public void setMushrooms(final int mushrooms) {
this.mushrooms = mushrooms;
}
public int getOnions() {
return onions;
}
public void setOnions(final int onions) {
this.onions = onions;
}
public GChartType getChartType() {
return chartType;
}
public void setChartType(final GChartType chartType) {
this.chartType = chartType;
}
public List<GChartType> getTypes() {
return Arrays.asList(new GChartType[] {GChartType.AREA, GChartType.BAR, GChartType.COLUMN, GChartType.PIE, GChartType.LINE});
}
}
package org.primefaces.extensions.showcase.controller.gchart;
import java.io.Serial;
import java.io.Serializable;
import jakarta.annotation.PostConstruct;
import jakarta.enterprise.context.RequestScoped;
import jakarta.inject.Named;
import org.primefaces.extensions.component.gchart.model.GChartModel;
import org.primefaces.extensions.component.gchart.model.GChartModelBuilder;
import org.primefaces.extensions.component.gchart.model.GChartType;
@Named
@RequestScoped
public class MultipleSeriesGChartController implements Serializable {
@Serial
private static final long serialVersionUID = 253762400419864192L;
private GChartModel chartModel = null;
public GChartModel getChart() {
return chartModel;
}
@PostConstruct
public void generateModel() {
chartModel = new GChartModelBuilder().setChartType(GChartType.COLUMN).addColumns("Year", "Salves", "Expenses")
.addRow("2010", 1000, 400).addRow("2011", 1200, 800).addRow("2012", 2000, 1800)
.addRow("2013", 1500, 1800).addRow("2014", 1300, 1000).build();
}
}
package org.primefaces.extensions.showcase.controller.gchart;
import java.io.Serial;
import java.io.Serializable;
import jakarta.annotation.PostConstruct;
import jakarta.enterprise.context.RequestScoped;
import jakarta.inject.Named;
import org.primefaces.extensions.component.gchart.model.GChartModel;
import org.primefaces.extensions.component.gchart.model.GChartModelBuilder;
import org.primefaces.extensions.component.gchart.model.GChartType;
import org.primefaces.model.DefaultTreeNode;
import org.primefaces.model.TreeNode;
@Named
@RequestScoped
public class OrganizationalGChartController implements Serializable {
@Serial
private static final long serialVersionUID = 253762400419864192L;
private GChartModel standardModel = null;
private GChartModel treeModel = null;
public GChartModel getStandardModel() {
return standardModel;
}
public GChartModel getTreeModel() {
return treeModel;
}
@PostConstruct
public void generateModel() {
standardModel = new GChartModelBuilder().setChartType(GChartType.ORGANIZATIONAL).addColumns("Name", "Manager")
.addRow("Mike", "").addRow("Alice", "Mike").addRow("Jim", "Mike").addRow("Bob", "Alice")
.addOption("size", "large").build();
final TreeNode mike = new DefaultTreeNode("Mike");
treeModel = new GChartModelBuilder().setChartType(GChartType.ORGANIZATIONAL).addColumns("Name", "Manager")
.importTreeNode(mike).addOption("size", "large").build();
}
}
package org.primefaces.extensions.showcase.controller.gchart;
import java.io.Serial;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import jakarta.annotation.PostConstruct;
import jakarta.enterprise.context.RequestScoped;
import jakarta.inject.Named;
import org.primefaces.extensions.component.gchart.model.GChartModel;
import org.primefaces.extensions.component.gchart.model.GChartModelBuilder;
import org.primefaces.extensions.component.gchart.model.GChartType;
@Named
@RequestScoped
public class GeoChartGChartController implements Serializable {
@Serial
private static final long serialVersionUID = 253762400419864192L;
private GChartModel chartModel = null;
public GChartModel getChart() {
return chartModel;
}
@PostConstruct
public void generateModel() {
final Locale englishLocale = Locale.ENGLISH;
final Map<String, Object> colorAxis = new HashMap<String, Object>();
colorAxis.put("colors", new String[] {"white", "orange"});
chartModel = new GChartModelBuilder().setChartType(GChartType.GEO).addColumns("Country", "Popularity")
.addRow(Locale.GERMANY.getDisplayCountry(englishLocale), 1200)
.addRow(Locale.FRANCE.getDisplayCountry(englishLocale), 1800).addRow("Russia", 1800)
.addRow(Locale.ITALY.getDisplayCountry(englishLocale), 2000)
.addRow(Locale.CHINA.getDisplayCountry(englishLocale), 2200)
.addRow(Locale.US.getDisplayCountry(englishLocale), 2500).addOption("colorAxis", colorAxis).build();
}
}