ご清聴ありがとうございました。
Google GeoCharts をレンダリングする JSF 2.0 カスタム コンポーネントを作成しました。そのため、レンダラーは最後に JavaScript と div を書き込むだけです。
コンポーネントはそれを行うことで正常に動作します。しかし、私の要件は、GeoChart が ajax リクエストを使用してその値を変更する必要があるということです。これを行うには、geoChart の ID を属性「更新」に入れて、primefaces コマンド ボタンを使用しています。
問題は、コマンド ボタンをクリックしても GeoChart が更新されないことです。
私は Maven アーキタイプ (myfaces-archetype-jsfcomponents20) を使用して、いくつかの構成ファイルの自動生成を許可しています。したがって、クラスと注釈に書き込むだけです。これらのクラスは、UIComponent と Renderer です。
このコードを GlassFish 3.1 と Mojarra 2.1.6 で実行しています
これらのクラスのコード:
UI コンポーネント:
@JSFComponent(
name = "processum:geochart",
clazz = "org.processum.component.gchart.GoogleChart",
tagClass = "org.processum.component.gchart.GoogleChartTag")
abstract class AbstractGoogleChart extends UIComponentBase {
public static final String COMPONENT_TYPE = "org.processum.GoogleChart";
public static final String DEFAULT_RENDERER_TYPE = "org.processum.GoogleChartRenderer";
public static final String COMPONENT_FAMILY = "javax.faces.Output";
/**
*
* GoogleChartModel
*/
@JSFProperty
public abstract GoogleGeoChartModel getModel();
}
レンダラー:
@JSFRenderer(
renderKitId = "HTML_BASIC",
family = "javax.faces.Output",
type = "org.processum.GoogleChartRenderer")
public class GoogleChartRenderer extends Renderer {
@Override
public void encodeEnd(FacesContext context, UIComponent component) throws IOException {
GoogleChart chart = (GoogleChart) component;
String divId = (String) component.getClientId() + "chartDiv";
GoogleGeoChartModel model = chart.getModel();
ResponseWriter writer = context.getResponseWriter();
writer.write("<script type='text/javascript'>"
+ "google.load('visualization', '1', {'packages': ['geochart']});"
+ "google.setOnLoadCallback(initGeoMap);"
+ "function initGeoMap() {"
+ "var data = google.visualization.arrayToDataTable(["
+ "[");
StringBuilder data = new StringBuilder();
for (String header : model.getHeaders()) {
data.append("\'").append(header).append("\'").append(",");
}
data.deleteCharAt(data.length() - 1).append("],");
for (String[] value : model.getValues()) {
data.append("[");
for (int i = 0; i < value.length; i++) {
if (i == 0) {
data.append("\'").append(value[i]).append("\'");
} else {
data.append(value[i]);
}
data.append(",");
}
data.deleteCharAt(data.length() - 1).append("],");
}
data.deleteCharAt(data.length() - 1);
writer.write(data.toString());
writer.write("]);");
writer.write("var options = {"
+ "region: 'CO',"
+ "displayMode: 'markers'"
+ "};"
+ "var chart = new google.visualization.GeoChart(document.getElementById(\'" + divId + "\'));"
+ "chart.draw(data, options);"
+ "};"
+ "</script>"
+ "<div id=\"" + divId + "\"/>");
}
}
XHTML:
<h:form>
<div id="anotherContent" style="width: 900px; height: 500px;">
<h:panelGroup id="chartCont" layout="block">
<processum:geochart id="chart" model="#{chartBackBean.model}"/>
</h:panelGroup>
</div>
<p:commandButton id="change" value="Cambio" actionListener="#{chartBackBean.change}" update="chart"/>
</h:form>
いくつかのデバッグ:
ajax リクエストは適切にトリガーされます。マネージド Bean は、GoogleGeoChartModel を新しい値で更新します。次に、制御フローはチャートの新しい値を「エンコード」する Renderer に進みます (つまり、encondeEnd が再度呼び出されます)。ただし、この新しい「エンコンディング」はブラウザに描画されません。
html には 2 つの JSF コンポーネントがあります。カスタム コンポーネントと ah:panelGroup。primefaces ボタンの「更新」属性にチャートの div の ID を入力してから ajax リクエストをトリガーすると、チャートは変更されません。しかし、代わりに h:panelGroup の id を入れると、チャートの div が消えます。