dojo charting - 日期为X轴 - 绘制的日期不正确,与从后端检索的日期无关

时间:2015-01-02 17:49:55

标签: date charts dojo axis-labels jsonreststore

我们正在开发一个涉及使用dojo 10.0.3绘图的股票相关应用程序。由于应用程序的性质,我们需要使用日期作为X轴。

日期(X轴)和各种价格(Y轴)均来自通过Restful Web服务调用检索的后端数据库:

var jsonStore   = new JsonStore({"target": "/blah1/blah2", "idProperty": "date" });

以下是图表的代码段:

   function dateLabel (dateString) {

   // While date in the backend is integer, what is passed to this function is strangely
   // a string in the format of "1,415,232,000,000", irrelevant to the backend data.

       var dateInt = parseInt( ( dateString.replace(/,/g, "") ) );
       var dt = new Date(dateInt);
       return (dt.getMonth() + 1) + "/" + dt.getDate() + "/" + dt.getFullYear();       
   }

   var xOpts = {
                 "title"           : "Date",
                 "titleOrientation": "away",  // or "axis"
                 "titleGap"        : 10,                 

                 "majorLabels"     : true, 
                 "majorTicks"      : true, 
                 "majorTick"       : {"length": 10},
                 "majorTickStep"   : 31536000000,       /** 1 year  in milliseconds **/

                 "minorLabels"     : true, 
                 "minorTicks"      : true, 
                 "minorTick"       : {"length": 6},
                 "minorTickStep"   : 2419200000,        /** 4 weeks in milliseconds **/

                 "microTicks"      : true, 
                 "microTick"       : {"length": 3},
                 "microTickStep"   : 86400000,          /** 1 day   in milliseconds **/

                 "labelFunc"       : dateLabel
               }

   var chart = new Chart("chartNode"); 
   chart.addPlot("default", { "type": Lines,  "markers": true,  hAxis: "x",  vAxis: "y" } );
   chart.addAxis("x", xOpts);
   chart.addAxis("y", { vertical: true, fixLower: "major", fixUpper: "major" });   

   var tip = new Tooltip(chart,"default");
   var mag = new Magnify(chart,"default");

   var storeSeries = new StoreSeries(jsonStore, { query: { } }, {"x": "date", "y": "close"} );
   chart.addSeries("Close", storeSeries, strokeAndFill1 );

   chart.render();

虽然图表在Y轴方面是正确的,但在X轴上绘制的日期相当奇怪,并且它们与标记不对齐。

从Firebug,后端返回的json对象是:

[{"date":1414990800000,"open":164.25,"high":164.54,"low":163.38,"close":164.36,...},
 {"date":1415077200000,"open":164.34,"high":164.36,"low":162.24,"close":162.65,...},
 {"date":1415163600000,"open":163.13,"high":163.54,"low":161.56,"close":161.82,...},
 {"date":1415250000000,"open":161.28,"high":161.53,"low":160.05,"close":161.46,...},
 {"date":1415336400000,"open":161.42,"high":162.21,"low":160.85,"close":162.07,...}]

(The above "date" data correspond to Nov 3 ~ Nov 7, 2014, all at 0:00 AM GMT-5.) 

但是,传递给X轴计算函数dateLabel的日期是一个字符串:" 1,415,232,000,000" (即,2014年11月5日格林威治标准时间-15:00),这与后端数据无关。

问题是:

1) Why X-Axis behaves so strange? Why the data passed to the dateLabel function is not the date 
   returned from the web service call as defined in the StoreSeries? 

2) Currently in the plot, when the "marker" is clicked, it only shows the price. Is it possible
   to customize it to show both the date and the price? 

非常感谢您的帮助!

电话

1 个答案:

答案 0 :(得分:2)

回答我自己的问题:

已追溯到dojox源代码并找到了答案。与Axis-tick计算相关的源代码如下:


    var lowerBound = findString(kwArgs.fixLower, ["major"]) ?
            Math.floor(kwArgs.min / majorTick) * majorTick :
                findString(kwArgs.fixLower, ["minor"]) ?
                    Math.floor(kwArgs.min / minorTick) * minorTick :
                        findString(kwArgs.fixLower, ["micro"]) ?
                            Math.floor(kwArgs.min / microTick) * microTick : kwArgs.min,
        upperBound = findString(kwArgs.fixUpper, ["major"]) ?
            Math.ceil(kwArgs.max / majorTick) * majorTick :
                findString(kwArgs.fixUpper, ["minor"]) ?
                    Math.ceil(kwArgs.max / minorTick) * minorTick :
                        findString(kwArgs.fixUpper, ["micro"]) ?
                            Math.ceil(kwArgs.max / microTick) * microTick : kwArgs.max;

    if(kwArgs.useMin){ min = lowerBound; }
    if(kwArgs.useMax){ max = upperBound; }      

    var majorStart = (!majorTick || kwArgs.useMin && findString(kwArgs.fixLower, ["major"])) ?
            min : Math.ceil(min / majorTick) * majorTick,
        minorStart = (!minorTick || kwArgs.useMin && findString(kwArgs.fixLower, ["major", "minor"])) ?
            min : Math.ceil(min / minorTick) * minorTick,
        microStart = (! microTick || kwArgs.useMin && findString(kwArgs.fixLower, ["major", "minor", "micro"])) ?
            min : Math.ceil(min / microTick) * microTick,
        majorCount = !majorTick ? 0 : (kwArgs.useMax && findString(kwArgs.fixUpper, ["major"]) ?
            Math.round((max - majorStart) / majorTick) :
            Math.floor((max - majorStart) / majorTick)) + 1,
        minorCount = !minorTick ? 0 : (kwArgs.useMax && findString(kwArgs.fixUpper, ["major", "minor"]) ?
            Math.round((max - minorStart) / minorTick) :
            Math.floor((max - minorStart) / minorTick)) + 1,
        microCount = !microTick ? 0 : (kwArgs.useMax && findString(kwArgs.fixUpper, ["major", "minor", "micro"]) ?
            Math.round((max - microStart) / microTick) :
            Math.floor((max - microStart) / microTick)) + 1,
        minorPerMajor  = minorTick ? Math.round(majorTick / minorTick) : 0,
        microPerMinor  = microTick ? Math.round(minorTick / microTick) : 0,
        majorPrecision = majorTick ? Math.floor(Math.log(majorTick) / Math.LN10) : 0,
        minorPrecision = minorTick ? Math.floor(Math.log(minorTick) / Math.LN10) : 0,

其中,初始kwArgs.min(例如,1415250000000)和初始kwArgs.max(例如,1415336400000)是来自后端数据源的最小和最大时间点(自纪元以来的毫秒数);

和majorTick,minorTick& microTick是相应的滴答步骤。 (在我的故障排除案例中,我将majorTick设置为86400000,这是以毫秒为单位表示的一天,为简单起见,禁用了次要和微小滴答。)

从上面的源代码来看,似乎无论我配置X轴,dojox图表都不适合我的简单和常见的商业案例,其中日期需要用作X轴。在X轴上绘制的刻度线与图表上的标记不完全对齐。我必须提供自己的代码,或使用其他一些图表框架,如D3。

谢谢!