Primefaces p:对话框中的Google Chart

时间:2012-12-13 15:25:06

标签: java jsf primefaces google-visualization

基于此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

感谢您的帮助!

0 个答案:

没有答案