7

I am using PrimeFaces 3.4.1 to plot time chart (Date on x-axis, int value on y-axis).

At the moment I have something like that:

xhtml:

<p:lineChart id="timeChart" value="#{myGraphBean.model}" legendPosition="e" title="Time Chart" minY="0" maxY="25" style="height:300px"/>

Java bean:

private final static int MAX_VALUE = 20;
private final static int NUMBER_OF_POINTS = 20;
private final static DateFormat dateFormat = new SimpleDateFormat("dd-MM-yy");

private void createLinearModel() {
    model = new CartesianChartModel();
    Calendar day = Calendar.getInstance();
    day.set(Calendar.HOUR_OF_DAY, 0);
    day.set(Calendar.MINUTE, 0);
    day.set(Calendar.SECOND, 0);
    day.set(Calendar.MILLISECOND, 0);
    LineChartSeries series = new LineChartSeries();
    series.setLabel("My series");
    for (int i = 0; i < NUMBER_OF_POINTS; i++) {
        series.set(dateFormat.format(day.getTime()), getRandomValue());
        day.add(Calendar.DAY_OF_MONTH, 1);
    }
    model.addSeries(series);
}

private int getRandomValue() {
    return rand.nextInt(MAX_VALUE);
}

So my bean just creates some random int value for each day. (My application produces actual data points, this is just a dummy example)

In my application, I am generating data over a long time, for example 6 months. With the way I am doing things now, I get horrible graphs like that:

Bad graph

What I would like to do:

I'd like to be able to keep my data point but only display a tick, let's say every month.

I have tried to change the tick on the x-axis following a few other posts (ex1, ex2) but I couldn't get it work.

Using the primefaces extender, I tried to use things like tickInterval: '1 month', setting the min attributes but nothing worked. In most of the case it would just break the graph

Questions:

  1. In the jqPlot doc, it says "Note, although jqPlot will parse most any human readable date, it is safest to use javascript time stamps when possible. Also, it is best to specify a date and time and not just a date alone. This is due to inconsistent browser handling of local time vs. UTC with bare dates." In my graph bean, shall I populate the series using a formatted date (String) following the javascript time stamp ("yyyy-MM-dd h:mma") or using a java.util.Date directly?

  2. How can I change the x-axis tick (for let's say 1 month), having a marker only every month, but still have the graph going through all the day points (i.e. I don't want to average my the points over the month)?

Community
  • 1
  • 1
phoenix7360
  • 2,807
  • 6
  • 30
  • 41

1 Answers1

6

In Java, fill your LineChartSeries objects with times in milliseconds using Date#getTime().

On the facelets side, download from jqPlot site and import the following jqPlot plugins:

<h:outputScript name="Javascript/jqplot.canvasAxisTickRenderer.js" />
<h:outputScript name="Javascript/jqplot.canvasAxisTickRenderer.min.js" />
<h:outputScript name="Javascript/jqplot.dateAxisRenderer.js" />
<h:outputScript name="Javascript/jqplot.dateAxisRenderer.min.js" />

And use this js extender for p:lineChart component:

function chartExtender() {
    this.cfg.axes = {
        xaxis : {
            renderer : $.jqplot.DateAxisRenderer, 
            rendererOptions : {
                tickRenderer:$.jqplot.CanvasAxisTickRenderer
            },
            tickOptions : { 
                fontSize:'10pt',
                fontFamily:'Tahoma', 
                angle:-40
            }
        },
        yaxis : {
            rendererOptions : {
                tickRenderer:$.jqplot.CanvasAxisTickRenderer
            },
            tickOptions: {
                fontSize:'10pt', 
                fontFamily:'Tahoma', 
                angle:30
            }
        }               
    };
    this.cfg.axes.xaxis.ticks = this.cfg.categories;
}

Useful links:

http://forum.primefaces.org/viewtopic.php?f=3&t=25289#p79916

http://forum.primefaces.org/viewtopic.php?f=3&t=23891&p=78637#p78637

perissf
  • 15,979
  • 14
  • 80
  • 117
  • thanks perissf. It may sound stupid but I'm not sure I managed to install jqplot. The tag that you propose cannot find the js files. I tried to download the jqplot as you suggested and tried to copy the sources in a few different places (src, src/main/ and src/main/webapp) but it didnt work. – phoenix7360 Jan 14 '13 at 15:12
  • 1
    As explained [here](http://www.mkyong.com/jsf2/resources-library-in-jsf-2-0/), you need to create a `resources` folder in the root folder (same folder level as `WEB-INF`). Put `Javascript` folder under resources. – perissf Jan 14 '13 at 15:24
  • Thanks, it works as a charm! I still get a big marker for every data point but I should be able to get it of them using the extender. – phoenix7360 Jan 14 '13 at 16:05
  • Be welcome! Regarding the marker I was able to get rid of it, but I don't have the code with me now. In case, let me know... – perissf Jan 14 '13 at 16:09
  • Actually I might need your help :P It's not as easy as I thought. I'm trying stuff like this.cfg.series = { markerRenderer: $.jqplot.MarkerRenderer, markerOptions:{ show: 'false' } }; but it's a complete guess. I'm not even sure there is a "this.cfg.series" property... – phoenix7360 Jan 14 '13 at 16:24
  • Simply use the attribute `showMarkers="false"` inside `p:lineChart` – perissf Jan 14 '13 at 17:29
  • You don't need the minified AND the non-minified JS. – WhyNotHugo Sep 19 '13 at 19:49