jqPlot / Primefaces扩展程序和日期值的问题

时间:2013-01-29 13:15:11

标签: jsf date charts primefaces jqplot

所以这就是事情。 我有很多持久的“快照”,其中包含一个java.sql.Timestamp和(为简单起见)一个int作为数据。

我有一个包含primefaces 3.4.1 <p:lineChart>的JSF页面,后面是一个包含图表模型的ManagedBean。

假设我然后选择一个时间范围并获取该范围之间的所有快照。 并使用所有时间戳(x轴)和所有整数(y轴)填充图表的数据模型。

所以我在填充时所做的是:

data = new HashMap<Object, Number>();        
List<Snapshot> allSnapshots = persistenceService.getAllSnapshots();
for(int i = 0; i < allSnapshots.size(); i++) {
    Snapshot s = allSnapshots.get(i);
    data.put(new Date(s.getTimestamp().getTime()), s.getData());
}
chartModel.getSeries().get(0).setData(data);

(注意:在示例代码中我只是获取所有快照,因为我很快就生成了一百个左右)。

我设置了这样的图表:

<p:lineChart id="chart" value="#{backingBean.chartModel}" xaxisAngle="-90">
   <f:convertDateTime pattern="HH:mm:ss"/>
</p:lineChart>

它工作正常但是当模型包含一百个数据点时,xaxis就会过度拥挤所有的标记。

然后我做的是使用primefaces'选项来使用jqplot扩展器功能。 所以我只添加extender="extend"作为图表的属性,其中extend是以下js函数:

function extend() {
      this.cfg.axes = {
          xaxis: {
              renderer: $.jqplot.DateAxisRenderer,
              rendererOptions: { tickRenderer: $.jqplot.CanvasAxisTickRenderer },
              tickOptions: {
                  showGridline: true,
                  formatString: '%H:%M',
                  angle: -90                        
             }         
         }
     }
}

这是它的当前版本.. 经过几个小时的阅读和反复试验,我仍然无法做到正确,因为以下事情永远都是对的:

  • 由于日期永远不会被转换,因此永远不会呈现刻度线。 目前这只是被忽略而且formatString本身就是 显示...
  • 在实际数据的左侧和右侧创建其他刻度线, 我不想那样。
  • 当我只提供autoscale: true作为jqplot扩展器的选项时, 我希望只是标记之间的间距变好。但是什么 然后发生的是,间距很酷但是原始日期 标签变成了从0开始到可用数据量的裸号......!?

我对这个问题感到有些厌倦.....也许我正在做一些根本错误的事情。否则我不知道为什么这么复杂。

感谢您的任何建议!

干杯

克里斯


编辑:

好的,感谢perissf,我查了一下:https://stackoverflow.com/a/14287971/870122

使用建议的扩展程序,我得到以下输出: http://www.abload.de/img/clipboard01y6sgj.png

(抱歉,由于新的用户限制,我无法直接发布图片: - /)

正如你所看到的那样,刻度线正确地呈现为HH:MM,这非常好。 但是你也可以看到另一个非常奇怪的问题:

快照的给定时间范围是

  • 开始时间:2013-01-28 13:01:25.415
  • 结束时间:2013-01-28 13:14:32.145

我使用System.currentTimeMillis()收集这些作为UTC时间戳,而在glassfish配置中将JVM设置为UTC。

正如您所注意到的,图中的数据点移动了一个小时,它们从14:01开始,看起来这些值已经自动转换为我当前的时区,即UTC + 1。但最左边的xaxis刻度位于13:00左右的原始UTC值附近。

我收集时间戳UTC,因为我不知道应用程序将在哪个实际时区运行,但我想显示“已翻译”的时间值。所以自动转换到我的时区是一个很好的功能,但xaxis缩放实际上并不好看和奇怪。

有什么建议我如何摆脱它?

干杯

克里斯


EDIT2:

在使用Firebug调试渲染页面的时候,我偶然发现了绘图对象中的jqplot内部变量,它们似乎包含了xaxis的最小值和最大值。 Min设置为原始的最小UTC值,大约为13:00,max设置为14:15左右的移位UTC + 1值。

不知何故,最小值不会相应地移动到自动时区调整。

所有其他值,即dataBounds,数据本身等,都会很好地移动一小时。

我在Bitbucket jqplot issue tracker

打开了一个问题

让我们看看。

再见

克里斯

2 个答案:

答案 0 :(得分:0)

我最终调试了jqplot渲染器并发现了导致此行为的一些代码行。

对于任何有兴趣的人,请在评论部分找到错误修正: Bitbucket issue tracker

感谢您的帮助

答案 1 :(得分:0)

我对此修复非常感兴趣,但BitBucket上的问题是在限制区域,所以我无法访问它。所以我自己尝试修复这个AxisDateRenderer,幸运的是我做了:)。

因此,Primefaces(6.0)图表使用旧版本的JQPlot库。此版本中的错误设置最小日期轴绑定不是第一个值,而是根据用户浏览器的区域设置时区更长的时间。例如,如果第一个值为12:00且GMT为GMT + 1,则日期轴最小值将为11:00而不是12:00!

minVale

以下行(在createTicks函数中)应该更换(请注意代码在下面写成)

ad = ad.getTime() + ad.getUtcOffset();

到下一行:

ad = Math.floor((ad.getTime() - ad.getUtcOffset())/r) * r + ad.getUtcOffset();

要更换的非缩小行:

min = min.getTime()  + min.getUtcOffset();

使用:

 min = Math.floor((min.getTime() - min.getUtcOffset())/tempti) * tempti + min.getUtcOffset();

请注意,我已尝试将Primefaces的chart.js更新为早期版本,但该图表不再有效。我将等待Primefaces的下一次更新,希望使用更新的版本。我也不知道Primefaces 6.0中使用了哪个版本的JQPlot