2

我们正在开发一个涉及使用 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 日 19:00 GMT-5),与后端数据无关。

问题是:

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? 

非常感谢您的帮助!

电话

4

1 回答 1

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。

谢谢!

于 2015-01-05T15:40:35.347 回答