0

基于此博客条目,我试图在 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

谢谢你的帮助 !

4

0 回答 0