基于此blog entry我正在尝试在Primefaces对话框中显示Google Chart。
我的xhtml文件:
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:p="http://primefaces.org/ui"
xmlns:c="http://java.sun.com/jsp/jstl/core"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:gc="http://mycompany.com/custom">
<h:head>
<title>Test Web</title>
</h:head>
<h:body>
<h:form>
<h:panelGrid columns="2" cellpadding="5">
<p:commandButton value="Load" actionListener="#{mainController.buildHistory}" update="@form :history" oncomplete="historyWidget.show();"/>
</h:panelGrid>
<gc:googleChart id="googleChart" divID="chart_div" model="#{mainController.chartModel}"/>
</h:form>
<p:dialog id="history" widgetVar="historyWidget">
<div id="chart_div" style="width: 900px; height: 500px; border:2px solid black;" />
</p:dialog>
</h:body>
我的支持bean:
@ManagedBean
@RequestScoped
public class MainController {
private GoogleChartModel chartModel;
public MainController() {
}
@PostConstruct
public void postConstruct() {
chartModel = new DefaultGoogleChartModel();
}
public void buildHistory() {
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date date = null;
try {
date = formatter.parse("2010-01-01 00:00:00");
Row row = new Row(date, "10");
chartModel.addRow(row);
date = formatter.parse("2010-02-01 00:00:00");
row = new Row(date, "20");
chartModel.addRow(row);
date = formatter.parse("2010-03-01 00:00:00");
row = new Row(date, "30");
chartModel.addRow(row);
date = formatter.parse("2011-04-01 00:00:00");
row = new Row(date, "40");
chartModel.addRow(row);
date = formatter.parse("2011-05-01 00:00:00");
row = new Row(date, "50");
chartModel.addRow(row);
} catch (ParseException ex) {
Logger.getLogger(MainController.class.getName()).log(Level.SEVERE, null, ex);
}
}
public GoogleChartModel getChartModel() {
return chartModel;
}
}
我的图表渲染器:
@FacesRenderer(componentFamily = "com.testweb.display",
rendererType = "googleChartRenderer")
public class ChartRenderer extends Renderer {
@Override
public void decode(FacesContext context, UIComponent component) {
System.out.println("decode");
super.decode(context, component);
}
protected FacesContext getFacesContext() {
return FacesContext.getCurrentInstance();
}
@Override
public void encodeBegin(FacesContext context, UIComponent component) throws IOException {
super.encodeBegin(context, component);
}
@Override
public void encodeEnd(FacesContext context, UIComponent component) throws IOException {
UIGoogleChart chart = (UIGoogleChart) component;
GoogleChartModel chartModel = (GoogleChartModel) chart.getAttributes().get("model");
String divId = (String) chart.getAttributes().get("divID");
ResponseWriter writer = context.getResponseWriter();
StringBuilder sb = new StringBuilder();
sb.append("<script type='text/javascript' src='http://www.google.com/jsapi'></script>");
sb.append("<script type='text/javascript'>");
sb.append("google.load('visualization', '1', {packages:['corechart']});");
sb.append("</script>");
sb.append("<script type='text/javascript'>");
sb.append("function drawChart() {");
sb.append("var data = new google.visualization.DataTable();");
sb.append("data.addColumn('date', 'Date');");
sb.append("data.addColumn('number', '');");
if (chartModel.getRows() != null && !chartModel.getRows().isEmpty()) {
sb.append("data.addRows([");
for (Row row : chartModel.getRows()) {
sb.append("[");
sb.append(row.getDate());
sb.append(",");
sb.append(row.getValue());
sb.append("],");
}
sb.append("]);");
}
sb.append("var chart = new google.visualization.LineChart(document.getElementById('");
sb.append(divId);
sb.append("')).draw(data, null);");
sb.append("}");
sb.append("google.setOnLoadCallback(drawChart);");
sb.append("</script>");
// System.out.println(sb.toString());
writer.write(sb.toString());
}
}
使用上面的代码,当我按下我的按钮时,对话框显示但是为空。方法buildHistory
在渲染器之前调用,但我的chartModel为空,即如果我查看源代码,则我的图表中没有添加任何行。但在这种特殊情况下,无论如何都应该显示一个空图表。
如果我将ajax="false"
添加到我的按钮,对话框根本不显示,但我的chartModel已填充,即在源代码中我看到我的图表的代码,如果我复制粘贴代码将图表转换为可用的HTML文件...
另请注意,如果我没有将图表放在对话框中,我会得到预期的结果:
<h:body>
<h:form>
<h:panelGrid columns="2" cellpadding="5">
<p:commandButton value="Load" actionListener="#{mainController.buildHistory}" ajax="false" update="@form :history" oncomplete="historyWidget.show();"/>
</h:panelGrid>
<gc:googleChart id="googleChart" divID="chart_div" model="#{mainController.chartModel}"/>
<div id="chart_div" style="width: 900px; height: 500px; border:2px solid black;" />
</h:form>
</h:body>
我错过了什么吗?有人可以给我一个暗示吗?
我正在运行Glassfish 3.1.1,JSF 2.1,Primefaces 3.4,Mojarra 2.1.6
感谢您的帮助!