基于此博客条目,我试图在 Primefaces 对话框中显示 Google 图表。
我的 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>
我的支持豆:
@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
谢谢你的帮助 !