このブログ エントリに基づいて、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>
私のバッキングビーン:
@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 を実行しています。
ご協力いただきありがとうございます !