简体   繁体   中英

Correctly displaying and using Primefaces bar chart from database

I'm having a hard time understanding how to display PF charts from the database. The PF user documentation mostly covers examples of how to statically produce charts (ie: by hard coding values). On this site, I've only seen a few questions here about how to produce PF charts from database. I found this question helpful:

PrimeFaces Chart From Database

But it doesn't really explain the logic and the methods needed to correctly implement PF charts from DB. I tried the following example myself. The view is:

<p:panel>
<p:barChart value="#{rigtestBean.cartChart}"/>
</p:panel>

The managed bean method:

public CartesianChartModel createRigTestModel() {
    cartChart = new CartesianChartModel();
    ChartSeries rigs = new ChartSeries();
    List<Rigtest> rList = rigFacade.findAll();
    Map<Object, Number> rigMap = new HashMap<>();        
    for(Rigtest o: rList) {

        rigMap.put(o.getCountry().getCountryname(), o.getRignum());

        rigs.setData(rigMap) ;
        cartChart.addSeries(rigs);

    }
    return cartChart;

}

The above interacts with a table called RigTest which has the following values (country name, number of rigs, date):

Country name: USA, USA, France, France Rig numbers: 2, 20, 40, 200

When running the code, only two data points are picked up in the resulting graph. These are 2 and 200 and the rest of the chart series seems to be ignored. The debugger shows that the map is being populated correctly and the Chart series ('rigs') is also populated correctly. This suggests that the problem is in the way I am adding the series to the CartesianChartrmodel instance ('cartChart'). Would really appreciate any advice on where I'm going wrong. On a wider issue, any advice of where I can read some material on implementing PF charts from CRUD operations using JPA. Thanks in advance.

Kukeltje's comments helped me find the answer. In my original method, initialization of the CartesianChartModel happened at the beginning of the method. Since this create method is called by the bean getter method, initializing the model instance at the beginning of the create seems to have several looping effects, causing the enhanced for loop to treat each record in the map as a series. This means 6 records are looped 36 times, 7 records 49 time and so on.

Initializing the model instance AFTER the the for loop and population of the map seems to fix the problem and result in the right number of records in the bar chart.

public void createRigTestModel() {

    ChartSeries rigs = new ChartSeries();

    List<Rigtest> rList = rigFacade.findAll();

    Map<Object, Number> rigMap = new HashMap<>();
    for (Rigtest o : rList) {

        rigMap.put(o.getRigtestid(), o.getRignum());

        cartChart = new CartesianChartModel();
        rigs.setData(rigMap);
        cartChart.addSeries(rigs);

    }

}

If you want to display a bar chart, for example, a chartseries could be a set of bars. So, you have to set the data for each bar inside the for..loop and after this loop add the chartseries to the model. You can add many series (set of bars) to the chartmodel.

The code could be:

public CartesianChartModel createRigTestModel() {
 cartChart = new CartesianChartModel();
 ChartSeries rigs = new ChartSeries();
 List<Rigtest> rList = rigFacade.findAll();

 for(Rigtest o: rList) {
    rigs.set(o.getCountry().getCountryname(), o.getRignum());       
 }
 cartChart.addSeries(rigs);

 return cartChart;

}

I hope this helps.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM