Primefaces 5.0图表 - 如何从数据库值动态创建图表模型和系列

时间:2016-06-09 22:48:36

标签: java mysql jsf primefaces charts

我正在尝试创建动态响应数据库中有关图表类型,图表模型和图表系列的值的图表。

我看到的大多数示例和问题似乎只是静态定义图表模型和图表系列。我想动态控制显示哪种类型的图表,图表模型和系列完全通过更改数据库中的值(通过后台或内容管理界面)显示。我已经开发了后台内容管理系统(CMS)。

这个问题是关于如何使PF展示示例或API适应完全动态的模型,让后台定义图表的类型,模型和系列。

以下示例尝试从3个mySql表生成条形图:

1)Endataset:包含由主键'idmid'定义的数据集的表 2)Endataseries:包含与Endataset具有OneToMany关系的数据系列的表 - 由'recid'定义 3)Endatapoint:表格,其中包含由'pointid'

定义的实际数据值(数字和日期)

我想根据后台设置的内容,为每个数据集(idmid)返回一个BarChartModel和ChartSeries作为不同图表的列表。换句话说,我想根据数据库中的许多值(数据集)动态创建图表模型和系列。我可以使用下面的示例返回图表,但它显示了2个相同模型中的3个系列,而不是一个模型中的2个系列和第二个模型中的1个系列(这是我的目标)。

我的jsf:

 <p:dataGrid id="cgridtest" value="#{chartTestBean.testTopList}" var="chars">
  <p:panel>
  <p:chart id="gridcharts" type="#{chartTestBean.chartType}" 
   model="#{chartTestBean.testModel}"style="width: 150px; height: 150px"/>
    </p:panel>
   <h:outputText value="#{chars.idmid}"/>
   </p:dataGrid>

bean方法:

public List<Endataset> getTestTopList() {
    testTopList = processChartList();
    return testTopList;
}

public List<Endataset> processChartList() {
    chartType = "bar";
    orig = guestChartFacade.findAll();
    sers = new ArrayList();
    for (int n = 0; n < orig.size(); n++) {
        idmid = orig.get(n).getIdmid();
        selJoin = guestChartFacade.find(idmid);

        startDate = selJoin.getStartdate();
        sers.add(idmid);
    }

    dsetList = setfacade.findTopsRange(sers);
    testTopList = new ArrayList();
    barmod = new ArrayList();
    for (int d = 0; d < dsetList.size(); d++) {

        testModel = new BarChartModel();
        chartSer = new ChartSeries();
        idmid = dsetList.get(d).getIdmid();
        selSet = setfacade.find(idmid);

        testTopList.add(selSet);

        barmod.add(testModel);

        showMods();

    }
    return testTopList;
}

public BarChartModel showMods() {

    for (BarChartModel t : barmod) {

        testModel = t;
        pointList = new ArrayList();

        pointList = pointFacade.pointRangeIdmid(idmid, startDate);

        for (Endatapoint p : pointList) {
            chartSer.set(p.getRecords().getSeriesname(), p.getActualnum());

        }
        testModel.addSeries(chartSer);

        return testModel;
    }
    return null;
}

以下示例旨在返回给定日期两家公司的股价。第三个系列应该在单独的图表模型中返回,但如下所示,所有3个系列都出现在单个模型中,这表明没有为每个数据集创建单独的BarChartModel实例。非常感谢有关如何使用此示例为每个数据集创建单独的图表模型的任何指导。在此先感谢您的帮助。

enter image description here

1 个答案:

答案 0 :(得分:0)

经过一些研究后,答案似乎是为您要创建的每种类型的图表使用单独的模型。在下面的例子中,我正在为Barchart和linechart创建模型,可以扩展为使用PF支持的任何其他图表类型。在EL我正在调用列表数组(即[0]),但这不是必需的,只是我的偏好。我还扩展了PF BarChartModel类(ExtendedBarChartModel),但是如果使用标准的BarChartModel,该示例工作正常。

希望这有帮助,欢迎任何反馈:

<p:dataGrid id="modellist" value="#{chartTestBean.xbarmod[0]}" var="barmd">
<p:chart id="gridchart" type="bar" model="#{barmd}" style="width: 150px; height: 150px"/>
</p:dataGrid>

<p:dataGrid id="linegrid" value="#{chartTestBean.linemodelList[0]}" var="linemod">
<p:chart id="linechart" type="line" model="#{linemod}" style="width: 150px; height: 150px"/> 
</p:dataGrid>
.... Other chart models as needed here

条形图模型的bean方法:

public List<ExtendedBarModel> ModelList() {
    xbarmod = new ArrayList();
    sers = new ArrayList();

    //chartType = "bar";
    orig = guestChartFacade.findAll();

    for (Enguestjoinchart j : orig) {
        if (j.getCharttype().equals("bar")) {
            setChartType("bar");
            showBar = true;
            idmid = j.getIdmid();
            selJoin = guestChartFacade.find(idmid);
            startDate = selJoin.getStartdate();
            sers.add(idmid);
        }
    }

    dsetList = setfacade.findTopsRange(sers);

    processModelList();
    return xbarmod;
}


public ExtendedBarModel processModelList() {
    for (int i = 0; i < dsetList.size(); i++) {

        idmid = dsetList.get(i).getIdmid();

        pointList = pointFacade.pointRangeIdmid(idmid, startDate);
        xtestmodel = new ExtendedBarModel("Barmodel " + dsetList.get(i).getIdmid());

        chartSer = new ChartSeries();
        for (Endatapoint p : pointList) {
            chartSer.set(p.getRecords().getSeriesname(), p.getActualnum());

        }
        xtestmodel.addSeries(chartSer);
        xbarmod.add(xtestmodel);
    }

    for (ExtendedBarModel b : xbarmod) {
        xtestmodel = b;
        return xtestmodel;
    }
    return null;
}

对于折线图:

public List<LineChartModel> makelinelistModel() {
    linemodelList = new ArrayList();
    linesers = new ArrayList();

    orig = guestChartFacade.findAll();

    for (Enguestjoinchart w : orig) {
        if (w.getCharttype().equals("line")) {
            idmidLine = w.getIdmid();
            selJoinLine = guestChartFacade.find(idmidLine);

            startDateLine = guestChartFacade.findStart(idmidLine);

            endDateLine = guestChartFacade.findEnd(idmidLine);
            linesers.add(idmidLine);
            showLine = true;
        }
    }

    if (linesers.size()==0) {
        dsetlineList = null;
        linemodelList = null;

    } 
    else {
       dsetlineList = setfacade.findTopsRange(linesers);
        processLineModelList();
    }
    return linemodelList;

}

public LineChartModel processLineModelList() {
    for (int i = 0; i < dsetlineList.size(); i++) {

        idmidLine = dsetlineList.get(i).getIdmid();
        pointListLine = pointFacade.pointLineRange(idmidLine, startDateLine, endDateLine);
        linemodel = new LineChartModel();

        chartSerLine = new ChartSeries();
        Map<Object, Number> datMap = new HashMap();
        DateAxis axis = new DateAxis();

        for (Endatapoint p : pointListLine) {
            chartSerLine.set(p.getPointdate().toString(), p.getActualnum());
            linemodel.addSeries(chartSerLine);

        }

        linemodelList.add(linemodel);
        linemodel.getAxes().put(AxisType.X, axis);
    }

    for (LineChartModel m : linemodelList) {
        linemodel = m;
        return linemodel;
    }
    return linemodel;
}

.... Other chart models