From dfba9f38a1092a93444a7fb7b4b63e9fc33a5cb7 Mon Sep 17 00:00:00 2001 From: "olau@iola.dk" Date: Tue, 26 Feb 2008 13:49:48 +0000 Subject: [PATCH] Documented the date support, tweaking the API a bit in the process, deprecated noTicks in favour of a numerical parameter to ticks git-svn-id: https://flot.googlecode.com/svn/trunk@44 1e0a6537-2640-0410-bfb7-f154510ff394 --- API.txt | 165 ++++++++++++++++++------ TODO | 7 +- examples/setting-options.html | 2 +- examples/time.html | 8 +- examples/visitors.html | 4 +- examples/zooming.html | 8 +- jquery.flot.js | 229 ++++++++++++++++++---------------- 7 files changed, 261 insertions(+), 162 deletions(-) diff --git a/API.txt b/API.txt index dd376f7..931f08c 100644 --- a/API.txt +++ b/API.txt @@ -36,6 +36,13 @@ E.g. [ [1, 3], [2, 14.01], [3.5, 3.14] ] +Note that to simplify the internal logic in Flot both the x and y +values must be numbers, even if specifying time series (see below for +how to do this). If you put in something else, e.g. a string, the plot +function fails with strange errors. This is a common problem because +you might accidentally retrieve data from the database as strings and +serialize them directly to JSON without noticing the wrong type. + The format of a single series object is as follows: { @@ -74,6 +81,11 @@ as the default options passed in via the options parameter in the plot commmand. When you specify them for a specific data series, they will override the default options for the plot for that data series. +Here's a complete example of a simple data specification: + + [ { label: "Foo", data: [ [10, 1], [17, -14], [30, 5] ] }, + { label: "Bar", data: [ [11, 13], [19, 11], [30, -7] ] } ] + Plot Options ------------ @@ -93,14 +105,14 @@ Customizing the legend ====================== legend: { - show: boolean, - labelFormatter: null or (fn: string -> string), - labelBoxBorderColor: color, - noColumns: number, - position: "ne" or "nw" or "se" or "sw", - margin: number of pixels, - backgroundColor: null or color, - backgroundOpacity: number in 0.0 - 1.0, + show: boolean + labelFormatter: null or (fn: string -> string) + labelBoxBorderColor: color + noColumns: number + position: "ne" or "nw" or "se" or "sw" + margin: number of pixels + backgroundColor: null or color + backgroundOpacity: number in 0.0 - 1.0 container: null or jQuery object } @@ -131,19 +143,22 @@ Customizing the axes ==================== xaxis, yaxis: { - ticks: null or ticks array or (fn: range -> ticks array), - noTicks: number, - tickFormatter: fn: number, object -> string, - tickDecimals: null or number, - min: null or number, - max: null or number, + mode: null or "time" + min: null or number + max: null or number autoscaleMargin: null or number + ticks: null or number or ticks array or (fn: range -> ticks array) + tickFormatter: (fn: number, object -> string) or string + tickDecimals: null or number } -The two axes have the same kind of options. The most import are -"min"/"max" that specifies the precise minimum/maximum value on the -scale. If you don't specify a value, it will automatically be chosen -by a scaling algorithm based on the minimum/maximum data values. +The two axes have the same kind of options. The "mode" option +determines how the data is interpreted, the default of null means as +decimal numbers. Use "time" for time series data, see the next section. + +The options "min"/"max" are the precise minimum/maximum value on the +scale. If you don't specify either of them, a value will automatically +be chosen based on the minimum/maximum data values. The "autoscaleMargin" is a bit esoteric: it's the fraction of margin that the scaling algorithm will add to avoid that the outermost points @@ -153,23 +168,23 @@ specified, the plot will furthermore extend the axis end-point to the nearest whole tick. The default value is "null" for the x axis and 0.02 for the y axis which seems appropriate for most cases. -The rest of the options deal with the ticks. If you don't specify any -ticks, a tick generator algorithm will make some for you based on the -number of ticks setting, "noTicks". The algorithm always tries to -generate reasonably round tick values so even if you ask for 3 ticks, -you might get 5 if that fits better with the rounding. Never set -"noTicks" to 0, that will just break the auto-detection stuff. If you -don't want ticks, provide an empty "ticks" array as described below. +The rest of the options deal with the ticks. + +If you don't specify any ticks, a tick generator algorithm will make +some for you. You can tweak how many it tries to generate by setting +"ticks" to a number. The algorithm always tries to generate reasonably +round tick values so even if you ask for 3 ticks, you might get 5 if +that fits better with the rounding. If you don't want ticks, set +"ticks" to 0 or an empty array. You can control how the ticks look like with "tickDecimals", the number of decimals to display (default is auto-detected), or by -providing a function to "tickFormatter". +providing a function as "tickFormatter". The tick formatter function +gets two argument, the tick value and an optional "axis" object with +information, and should return a string. The default formatter looks +like this: -The tick formatter function gets two argument, the tick value and an -optional "axis" object with information, and should return a string. -The default formatter looks like this: - - function defaultTickFormatter(val, axis) { + function formatter(val, axis) { return val.toFixed(axis.tickDecimals); } @@ -189,8 +204,8 @@ custom formatter: } -If you want to override the tick algorithm, you can manually specify -"ticks" which should be an array of tick values, either like this: +If you want to override the tick algorithm, you can specify an array +to "ticks", either like this: ticks: [0, 1.2, 2.4] @@ -198,10 +213,6 @@ Or like this (you can mix the two if you like): ticks: [[0, "zero"], [1.2, "one mark"], [2.4, "two marks"]] -You can disable the ticks by providing an empty array: - - ticks: [] - For extra flexibility you can specify a function as the "ticks" parameter. The function will be called with an object with the axis min and max and should return a ticks array. Here's a simplistic tick @@ -221,8 +232,84 @@ axis for trigonometric functions: return res; } -Note that the scaling and tick algorithms don't work with time series -yet. + +Time series data +================ + +The time series support in Flot is based on Javascript timestamps, +i.e. everywhere a time value is expected or passed over, a Javascript +timestamp number is used. This is not the same as a Date object. A +Javascript timestamp is the number of milliseconds since January 1, +1970 00:00:00. This is almost the same as Unix timestamps, except it's +in milliseconds, so remember to multiply by 1000! + +You can see a timestamp by outputting + + (new Date()).getTime() + +In PHP you can get an appropriate timestamp with +'strtotime("2002-02-20") * 1000', in Python with +'time.mktime(datetime_object.timetuple()) * 1000', in .NET with +something like: + + public static int GetJavascriptTimestamp(System.DateTime input) + { + System.TimeSpan span = new System.TimeSpan(System.DateTime.Parse("1/1/1970").Ticks); + System.DateTime time = input.Subtract(span); + return (int)(time.Ticks / 10000); + } + +Once you've got the timestamps into the data and specified "time" as +the axis mode, Flot will automatically generate relevant ticks and +format them. As always, you can tweak the ticks via the "ticks" +option. Again the values should be timestamps, not Date objects! + +Formatting is controlled separately through the following axis +options: + + xaxis, yaxis: { + timeformat: null or format string + monthNames: null or array of size 12 of strings + } + +Here "timeformat" is a format string to use. You might use it like +this: + + xaxis: { + mode: "time", + timeformat: "%y/%m/%d" + } + +This will result in tick labels like "2000/12/24". The following +specifiers are supported + + %h': hours + %H': hours (left-padded with a zero) + %M': minutes (left-padded with a zero) + %S': seconds (left-padded with a zero) + %d': day of month (1-31) + %m': month (1-12) + %y': year (four digits) + %b': month name (customizable) + +You can customize the month names with the "monthNames" option. For +instance, for Danish you might specify: + + monthName: ["jan", "feb", "mar", "apr", "maj", "jun", "jul", "aug", "sep", "okt", "nov", "dec"] + +If everything else fails, you can control the formatting by specifying +a custom tick formatter function as usual. Here's a simple example +which will format December 24 as 24/12: + + tickFormatter: function (val, axis) { + var d = new Date(val); + return d.getDate() + "/" + (d.getMonth() + 1); + } + +For the time mode the axis object contains an additional +"tickSizeUnit" which is one of "second", "minute", "hour", "day", +"month" and "year". So if axis.tickSize is 2 and axis.tickSizeUnit is +"day", the ticks have been produced with two days in-between. Customizing the data series diff --git a/TODO b/TODO index 07f34b8..8089b73 100644 --- a/TODO +++ b/TODO @@ -2,10 +2,9 @@ These are mostly ideas, that they're written down here is no guarantee that they'll ever be done. If you want something done, feel free to say why or come up with a patch. :-) -handling time data - - dataformat - - axis adjustment - - tick generation +pending + - split out autoscaleMargin into a snapToTicks + - autodetect a sensible ticks setting grid configuration - how ticks look like diff --git a/examples/setting-options.html b/examples/setting-options.html index 3166a6a..31dd798 100644 --- a/examples/setting-options.html +++ b/examples/setting-options.html @@ -48,7 +48,7 @@ $(function () { ticks: [0, [Math.PI/2, "\u03c0/2"], [Math.PI, "\u03c0"], [Math.PI * 3/2, "3\u03c0/2"], [Math.PI * 2, "2\u03c0"]] }, yaxis: { - noTicks: 10, + ticks: 10, min: -2, max: 2 }, diff --git a/examples/time.html b/examples/time.html index d2c2da3..aed6e0a 100644 --- a/examples/time.html +++ b/examples/time.html @@ -32,15 +32,15 @@ $(function () { var d = [[-373597200000, 315.71], [-370918800000, 317.45], [-368326800000, 317.50], [-363056400000, 315.86], [-360378000000, 314.93], [-357699600000, 313.19], [-352429200000, 313.34], [-349837200000, 314.67], [-347158800000, 315.58], [-344480400000, 316.47], [-342061200000, 316.65], [-339382800000, 317.71], [-336790800000, 318.29], [-334112400000, 318.16], [-331520400000, 316.55], [-328842000000, 314.80], [-326163600000, 313.84], [-323571600000, 313.34], [-320893200000, 314.81], [-318301200000, 315.59], [-315622800000, 316.43], [-312944400000, 316.97], [-310438800000, 317.58], [-307760400000, 319.03], [-305168400000, 320.03], [-302490000000, 319.59], [-299898000000, 318.18], [-297219600000, 315.91], [-294541200000, 314.16], [-291949200000, 313.83], [-289270800000, 315.00], [-286678800000, 316.19], [-284000400000, 316.89], [-281322000000, 317.70], [-278902800000, 318.54], [-276224400000, 319.48], [-273632400000, 320.58], [-270954000000, 319.78], [-268362000000, 318.58], [-265683600000, 316.79], [-263005200000, 314.99], [-260413200000, 315.31], [-257734800000, 316.10], [-255142800000, 317.01], [-252464400000, 317.94], [-249786000000, 318.56], [-247366800000, 319.69], [-244688400000, 320.58], [-242096400000, 321.01], [-239418000000, 320.61], [-236826000000, 319.61], [-234147600000, 317.40], [-231469200000, 316.26], [-228877200000, 315.42], [-226198800000, 316.69], [-223606800000, 317.69], [-220928400000, 318.74], [-218250000000, 319.08], [-215830800000, 319.86], [-213152400000, 321.39], [-210560400000, 322.24], [-207882000000, 321.47], [-205290000000, 319.74], [-202611600000, 317.77], [-199933200000, 316.21], [-197341200000, 315.99], [-194662800000, 317.07], [-192070800000, 318.36], [-189392400000, 319.57], [-178938000000, 322.23], [-176259600000, 321.89], [-173667600000, 320.44], [-170989200000, 318.70], [-168310800000, 316.70], [-165718800000, 316.87], [-163040400000, 317.68], [-160448400000, 318.71], [-157770000000, 319.44], [-155091600000, 320.44], [-152672400000, 320.89], [-149994000000, 322.13], [-147402000000, 322.16], [-144723600000, 321.87], [-142131600000, 321.21], [-139453200000, 318.87], [-136774800000, 317.81], [-134182800000, 317.30], [-131504400000, 318.87], [-128912400000, 319.42], [-126234000000, 320.62], [-123555600000, 321.59], [-121136400000, 322.39], [-118458000000, 323.70], [-115866000000, 324.07], [-113187600000, 323.75], [-110595600000, 322.40], [-107917200000, 320.37], [-105238800000, 318.64], [-102646800000, 318.10], [-99968400000, 319.79], [-97376400000, 321.03], [-94698000000, 322.33], [-92019600000, 322.50], [-89600400000, 323.04], [-86922000000, 324.42], [-84330000000, 325.00], [-81651600000, 324.09], [-79059600000, 322.55], [-76381200000, 320.92], [-73702800000, 319.26], [-71110800000, 319.39], [-68432400000, 320.72], [-65840400000, 321.96], [-63162000000, 322.57], [-60483600000, 323.15], [-57978000000, 323.89], [-55299600000, 325.02], [-52707600000, 325.57], [-50029200000, 325.36], [-47437200000, 324.14], [-44758800000, 322.11], [-42080400000, 320.33], [-39488400000, 320.25], [-36810000000, 321.32], [-34218000000, 322.90], [-31539600000, 324.00], [-28861200000, 324.42], [-26442000000, 325.64], [-23763600000, 326.66], [-21171600000, 327.38], [-18493200000, 326.70], [-15901200000, 325.89], [-13222800000, 323.67], [-10544400000, 322.38], [-7952400000, 321.78], [-5274000000, 322.85], [-2682000000, 324.12], [-3600000, 325.06], [2674800000, 325.98], [5094000000, 326.93], [7772400000, 328.13], [10364400000, 328.07], [13042800000, 327.66], [15634800000, 326.35], [18313200000, 324.69], [20991600000, 323.10], [23583600000, 323.07], [26262000000, 324.01], [28854000000, 325.13], [31532400000, 326.17], [34210800000, 326.68], [36630000000, 327.18], [39308400000, 327.78], [41900400000, 328.92], [44578800000, 328.57], [47170800000, 327.37], [49849200000, 325.43], [52527600000, 323.36], [55119600000, 323.56], [57798000000, 324.80], [60390000000, 326.01], [63068400000, 326.77], [65746800000, 327.63], [68252400000, 327.75], [70930800000, 329.72], [73522800000, 330.07], [76201200000, 329.09], [78793200000, 328.05], [81471600000, 326.32], [84150000000, 324.84], [86742000000, 325.20], [89420400000, 326.50], [92012400000, 327.55], [94690800000, 328.54], [97369200000, 329.56], [99788400000, 330.30], [102466800000, 331.50], [105058800000, 332.48], [107737200000, 332.07], [110329200000, 330.87], [113007600000, 329.31], [115686000000, 327.51], [118278000000, 327.18], [120956400000, 328.16], [123548400000, 328.64], [126226800000, 329.35], [128905200000, 330.71], [131324400000, 331.48], [134002800000, 332.65], [136594800000, 333.16], [139273200000, 332.06], [141865200000, 330.99], [144543600000, 329.17], [147222000000, 327.41], [149814000000, 327.20], [152492400000, 328.33], [155084400000, 329.50], [157762800000, 330.68], [160441200000, 331.41], [162860400000, 331.85], [165538800000, 333.29], [168130800000, 333.91], [170809200000, 333.40], [173401200000, 331.78], [176079600000, 329.88], [178758000000, 328.57], [181350000000, 328.46], [184028400000, 329.26], [189298800000, 331.71], [191977200000, 332.76], [194482800000, 333.48], [197161200000, 334.78], [199753200000, 334.78], [202431600000, 334.17], [205023600000, 332.78], [207702000000, 330.64], [210380400000, 328.95], [212972400000, 328.77], [215650800000, 330.23], [218242800000, 331.69], [220921200000, 332.70], [223599600000, 333.24], [226018800000, 334.96], [228697200000, 336.04], [231289200000, 336.82], [233967600000, 336.13], [236559600000, 334.73], [239238000000, 332.52], [241916400000, 331.19], [244508400000, 331.19], [247186800000, 332.35], [249778800000, 333.47], [252457200000, 335.11], [255135600000, 335.26], [257554800000, 336.60], [260233200000, 337.77], [262825200000, 338.00], [265503600000, 337.99], [268095600000, 336.48], [270774000000, 334.37], [273452400000, 332.27], [276044400000, 332.41], [278722800000, 333.76], [281314800000, 334.83], [283993200000, 336.21], [286671600000, 336.64], [289090800000, 338.12], [291769200000, 339.02], [294361200000, 339.02], [297039600000, 339.20], [299631600000, 337.58], [302310000000, 335.55], [304988400000, 333.89], [307580400000, 334.14], [310258800000, 335.26], [312850800000, 336.71], [315529200000, 337.81], [318207600000, 338.29], [320713200000, 340.04], [323391600000, 340.86], [325980000000, 341.47], [328658400000, 341.26], [331250400000, 339.29], [333928800000, 337.60], [336607200000, 336.12], [339202800000, 336.08], [341881200000, 337.22], [344473200000, 338.34], [347151600000, 339.36], [349830000000, 340.51], [352249200000, 341.57], [354924000000, 342.56], [357516000000, 343.01], [360194400000, 342.47], [362786400000, 340.71], [365464800000, 338.52], [368143200000, 336.96], [370738800000, 337.13], [373417200000, 338.58], [376009200000, 339.89], [378687600000, 340.93], [381366000000, 341.69], [383785200000, 342.69], [389052000000, 344.30], [391730400000, 343.43], [394322400000, 341.88], [397000800000, 339.89], [399679200000, 337.95], [402274800000, 338.10], [404953200000, 339.27], [407545200000, 340.67], [410223600000, 341.42], [412902000000, 342.68], [415321200000, 343.46], [417996000000, 345.10], [420588000000, 345.76], [423266400000, 345.36], [425858400000, 343.91], [428536800000, 342.05], [431215200000, 340.00], [433810800000, 340.12], [436489200000, 341.33], [439081200000, 342.94], [441759600000, 343.87], [444438000000, 344.60], [446943600000, 345.20], [452210400000, 347.36], [454888800000, 346.74], [457480800000, 345.41], [460159200000, 343.01], [462837600000, 341.23], [465433200000, 341.52], [468111600000, 342.86], [470703600000, 344.41], [473382000000, 345.09], [476060400000, 345.89], [478479600000, 347.49], [481154400000, 348.00], [483746400000, 348.75], [486424800000, 348.19], [489016800000, 346.54], [491695200000, 344.63], [494373600000, 343.03], [496969200000, 342.92], [499647600000, 344.24], [502239600000, 345.62], [504918000000, 346.43], [507596400000, 346.94], [510015600000, 347.88], [512690400000, 349.57], [515282400000, 350.35], [517960800000, 349.72], [520552800000, 347.78], [523231200000, 345.86], [525909600000, 344.84], [528505200000, 344.32], [531183600000, 345.67], [533775600000, 346.88], [536454000000, 348.19], [539132400000, 348.55], [541551600000, 349.52], [544226400000, 351.12], [546818400000, 351.84], [549496800000, 351.49], [552088800000, 349.82], [554767200000, 347.63], [557445600000, 346.38], [560041200000, 346.49], [562719600000, 347.75], [565311600000, 349.03], [567990000000, 350.20], [570668400000, 351.61], [573174000000, 352.22], [575848800000, 353.53], [578440800000, 354.14], [581119200000, 353.62], [583711200000, 352.53], [586389600000, 350.41], [589068000000, 348.84], [591663600000, 348.94], [594342000000, 350.04], [596934000000, 351.29], [599612400000, 352.72], [602290800000, 353.10], [604710000000, 353.65], [607384800000, 355.43], [609976800000, 355.70], [612655200000, 355.11], [615247200000, 353.79], [617925600000, 351.42], [620604000000, 349.81], [623199600000, 350.11], [625878000000, 351.26], [628470000000, 352.63], [631148400000, 353.64], [633826800000, 354.72], [636246000000, 355.49], [638920800000, 356.09], [641512800000, 357.08], [644191200000, 356.11], [646783200000, 354.70], [649461600000, 352.68], [652140000000, 351.05], [654735600000, 351.36], [657414000000, 352.81], [660006000000, 354.22], [662684400000, 354.85], [665362800000, 355.66], [667782000000, 357.04], [670456800000, 358.40], [673048800000, 359.00], [675727200000, 357.99], [678319200000, 356.00], [680997600000, 353.78], [683676000000, 352.20], [686271600000, 352.22], [688950000000, 353.70], [691542000000, 354.98], [694220400000, 356.09], [696898800000, 356.85], [699404400000, 357.73], [702079200000, 358.91], [704671200000, 359.45], [707349600000, 359.19], [709941600000, 356.72], [712620000000, 354.79], [715298400000, 352.79], [717894000000, 353.20], [720572400000, 354.15], [723164400000, 355.39], [725842800000, 356.77], [728521200000, 357.17], [730940400000, 358.26], [733615200000, 359.16], [736207200000, 360.07], [738885600000, 359.41], [741477600000, 357.44], [744156000000, 355.30], [746834400000, 353.87], [749430000000, 354.04], [752108400000, 355.27], [754700400000, 356.70], [757378800000, 358.00], [760057200000, 358.81], [762476400000, 359.68], [765151200000, 361.13], [767743200000, 361.48], [770421600000, 360.60], [773013600000, 359.20], [775692000000, 357.23], [778370400000, 355.42], [780966000000, 355.89], [783644400000, 357.41], [786236400000, 358.74], [788914800000, 359.73], [791593200000, 360.61], [794012400000, 361.58], [796687200000, 363.05], [799279200000, 363.62], [801957600000, 363.03], [804549600000, 361.55], [807228000000, 358.94], [809906400000, 357.93], [812502000000, 357.80], [815180400000, 359.22], [817772400000, 360.44], [820450800000, 361.83], [823129200000, 362.95], [825634800000, 363.91], [828309600000, 364.28], [830901600000, 364.94], [833580000000, 364.70], [836172000000, 363.31], [838850400000, 361.15], [841528800000, 359.40], [844120800000, 359.34], [846802800000, 360.62], [849394800000, 361.96], [852073200000, 362.81], [854751600000, 363.87], [857170800000, 364.25], [859845600000, 366.02], [862437600000, 366.46], [865116000000, 365.32], [867708000000, 364.07], [870386400000, 361.95], [873064800000, 360.06], [875656800000, 360.49], [878338800000, 362.19], [880930800000, 364.12], [883609200000, 364.99], [886287600000, 365.82], [888706800000, 366.95], [891381600000, 368.42], [893973600000, 369.33], [896652000000, 368.78], [899244000000, 367.59], [901922400000, 365.84], [904600800000, 363.83], [907192800000, 364.18], [909874800000, 365.34], [912466800000, 366.93], [915145200000, 367.94], [917823600000, 368.82], [920242800000, 369.46], [922917600000, 370.77], [925509600000, 370.66], [928188000000, 370.10], [930780000000, 369.08], [933458400000, 366.66], [936136800000, 364.60], [938728800000, 365.17], [941410800000, 366.51], [944002800000, 367.89], [946681200000, 369.04], [949359600000, 369.35], [951865200000, 370.38], [954540000000, 371.63], [957132000000, 371.32], [959810400000, 371.53], [962402400000, 369.75], [965080800000, 368.23], [967759200000, 366.87], [970351200000, 366.94], [973033200000, 368.27], [975625200000, 369.64], [978303600000, 370.46], [980982000000, 371.44], [983401200000, 372.37], [986076000000, 373.33], [988668000000, 373.77], [991346400000, 373.09], [993938400000, 371.51], [996616800000, 369.55], [999295200000, 368.12], [1001887200000, 368.38], [1004569200000, 369.66], [1007161200000, 371.11], [1009839600000, 372.36], [1012518000000, 373.09], [1014937200000, 373.81], [1017612000000, 374.93], [1020204000000, 375.58], [1022882400000, 375.44], [1025474400000, 373.86], [1028152800000, 371.77], [1030831200000, 370.73], [1033423200000, 370.50], [1036105200000, 372.18], [1038697200000, 373.70], [1041375600000, 374.92], [1044054000000, 375.62], [1046473200000, 376.51], [1049148000000, 377.75], [1051740000000, 378.54], [1054418400000, 378.20], [1057010400000, 376.68], [1059688800000, 374.43], [1062367200000, 373.11], [1064959200000, 373.10], [1067641200000, 374.77], [1070233200000, 375.97], [1072911600000, 377.03], [1075590000000, 377.87], [1078095600000, 378.88], [1080770400000, 380.42], [1083362400000, 380.62], [1086040800000, 379.70], [1088632800000, 377.43], [1091311200000, 376.32], [1093989600000, 374.19], [1096581600000, 374.47], [1099263600000, 376.15], [1101855600000, 377.51], [1104534000000, 378.43], [1107212400000, 379.70], [1109631600000, 380.92], [1112306400000, 382.18], [1114898400000, 382.45], [1117576800000, 382.14], [1120168800000, 380.60], [1122847200000, 378.64], [1125525600000, 376.73], [1128117600000, 376.84], [1130799600000, 378.29], [1133391600000, 380.06], [1136070000000, 381.40], [1138748400000, 382.20], [1141167600000, 382.66], [1143842400000, 384.69], [1146434400000, 384.94], [1149112800000, 384.01], [1151704800000, 382.14], [1154383200000, 380.31], [1157061600000, 378.81], [1159653600000, 379.03], [1162335600000, 380.17], [1164927600000, 381.85], [1167606000000, 382.94], [1170284400000, 383.86], [1172703600000, 384.49], [1175378400000, 386.37], [1177970400000, 386.54], [1180648800000, 385.98], [1183240800000, 384.36], [1185919200000, 381.85], [1188597600000, 380.74], [1191189600000, 381.15], [1193871600000, 382.38], [1196463600000, 383.94], [1199142000000, 385.44]]; - $.plot($("#placeholder"), [d], { xaxis: { datatype: "time" } }); + $.plot($("#placeholder"), [d], { xaxis: { mode: "time" } }); $("#whole").click(function () { - $.plot($("#placeholder"), [d], { xaxis: { datatype: "time" } }); + $.plot($("#placeholder"), [d], { xaxis: { mode: "time" } }); }); $("#nineties").click(function () { $.plot($("#placeholder"), [d], { xaxis: { - datatype: "time", + mode: "time", min: (new Date("1990/01/01")).getTime(), max: (new Date("2000/01/01")).getTime() } }); @@ -48,7 +48,7 @@ $(function () { $("#ninetynine").click(function () { $.plot($("#placeholder"), [d], { xaxis: { - datatype: "time", + mode: "time", min: (new Date("1999/01/01")).getTime(), max: (new Date("2000/01/01")).getTime() } }); diff --git a/examples/visitors.html b/examples/visitors.html index 483ff13..2236991 100644 --- a/examples/visitors.html +++ b/examples/visitors.html @@ -43,7 +43,7 @@ $(function () { } var options = { - xaxis: { datatype: "time" }, + xaxis: { mode: "time" }, selection: { mode: "x" }, grid: { coloredAreas: weekendAreas } }; @@ -53,7 +53,7 @@ $(function () { var overview = $.plot($("#overview"), [d], { lines: { show: true, lineWidth: 1 }, shadowSize: 0, - xaxis: { ticks: [], datatype: "time" }, + xaxis: { ticks: [], mode: "time" }, yaxis: { ticks: [], min: 0, max: 4000 }, selection: { mode: "x" } }); diff --git a/examples/zooming.html b/examples/zooming.html index c4ea52a..ecc242d 100644 --- a/examples/zooming.html +++ b/examples/zooming.html @@ -21,7 +21,7 @@

-

The selection support makes even +

The selection support makes pretty advanced zooming schemes possible. With a few lines of code, the small overview plot to the right has been connected to the large plot. Try selecting a rectangle on either of them.

@@ -43,7 +43,7 @@ $(function () { legend: { show: false }, lines: { show: true }, points: { show: true }, - yaxis: { noTicks: 10 }, + yaxis: { ticks: 10 }, selection: { mode: "xy" } }; @@ -56,8 +56,8 @@ $(function () { legend: { show: true, container: $("#overviewLegend") }, lines: { show: true, lineWidth: 1 }, shadowSize: 0, - xaxis: { noTicks: 4 }, - yaxis: { noTicks: 3, min: -2, max: 2 }, + xaxis: { ticks: 4 }, + yaxis: { ticks: 3, min: -2, max: 2 }, grid: { color: "#999" }, selection: { mode: "xy" } }); diff --git a/jquery.flot.js b/jquery.flot.js index 5d993bb..bfa298f 100644 --- a/jquery.flot.js +++ b/jquery.flot.js @@ -7,7 +7,7 @@ (function($) { function Plot(target_, data_, options_) { // data is on the form: - // [ series1 series2 ... ] + // [ series1, series2 ... ] // where series is either just the data as [ [x1, y1], [x2, y2], ... ] // or { data: [ [x1, y1], [x2, y2], ... ], label: "some label" } @@ -27,19 +27,21 @@ backgroundOpacity: 0.85 // set to 0 to avoid background }, xaxis: { - ticks: null, // either [1, 3] or [[1, "a"], 3] or fn: axis info -> ticks - noTicks: 5, // approximate number of ticks for auto-ticks - tickFormatter: null, // fn: number -> string or format string if datatype is date - tickDecimals: null, // no. of decimals, null means auto - datatype: "number", // one of "number", "time" + mode: null, // null or "time" min: null, // min. value to show, null means set automatically max: null, // max. value to show, null means set automatically - autoscaleMargin: null // margin in % to add if auto-setting min/max + autoscaleMargin: null, // margin in % to add if auto-setting min/max + ticks: null, // either [1, 3] or [[1, "a"], 3] or (fn: axis info -> ticks) or app. number of ticks for auto-ticks + tickFormatter: null, // fn: number -> string + + // mode specific options + tickDecimals: null, // no. of decimals, null means auto + + monthNames: null, // list of names of months + timeformat: null, // format string to use }, yaxis: { - noTicks: 5, ticks: null, - datatype: "number", autoscaleMargin: 0.02 }, points: { @@ -75,12 +77,7 @@ mode: null, // one of null, "x", "y" or "xy" color: "#e8cfac" }, - shadowSize: 4, - datatype: { - time: { - monthNames: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"] - } - } + shadowSize: 4 }; var canvas = null, overlay = null; var ctx = null, octx = null; @@ -98,16 +95,6 @@ var hozScale = 0; var vertScale = 0; - // map of app. size of time units in milliseconds - var timeUnitSize = { - "second": 1000, - "minute": 60 * 1000, - "hour": 60 * 60 * 1000, - "day": 24 * 60 * 60 * 1000, - "month": 30 * 24 * 60 * 60 * 1000, - "year": 365.2425 * 24 * 60 * 60 * 1000 - }; - // initialize series = parseData(data_); parseOptions(options_); @@ -117,11 +104,11 @@ bindEvents(); findDataRanges(); setRange(xaxis, options.xaxis); - setTickSize(xaxis, options.xaxis); + prepareTickGeneration(xaxis, options.xaxis); setTicks(xaxis, options.xaxis); extendXRangeIfNeededByBar(); setRange(yaxis, options.yaxis); - setTickSize(yaxis, options.yaxis); + prepareTickGeneration(yaxis, options.yaxis); setTicks(yaxis, options.yaxis); setSpacing(); draw(); @@ -152,6 +139,12 @@ function parseOptions(o) { $.extend(true, options, o); + + // backwards compatibility, to be removed in future + if (options.xaxis.noTicks && options.xaxis.ticks == null) + options.xaxis.ticks = options.xaxis.noTicks; + if (options.yaxis.noTicks && options.yaxis.ticks == null) + options.yaxis.ticks = options.yaxis.noTicks; } function constructCanvas() { @@ -263,12 +256,66 @@ axis.max = max; } - function setTickSize(axis, axisOptions) { - var delta = (axis.max - axis.min) / axisOptions.noTicks; + function prepareTickGeneration(axis, axisOptions) { + var noTicks = 5; + if (typeof axisOptions.ticks == "number" && axisOptions.ticks > 0) + noTicks = axisOptions.ticks; + + var delta = (axis.max - axis.min) / noTicks; var size, generator, unit = "", formatter, i; - if (axisOptions.datatype == "time") { + if (axisOptions.mode == "time") { // pretty handling of time + + function formatDate(d, fmt, monthNames) { + var leftPad = function(n) { + n = "" + n; + return n.length == 1 ? "0" + n : n; + }; + + var r = []; + var escape = false; + if (monthNames == null) + monthNames = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]; + for (var i = 0; i < fmt.length; ++i) { + var c = fmt.charAt(i); + + if (escape) { + switch (c) { + case 'h': c = "" + d.getHours(); break; + case 'H': c = leftPad(d.getHours()); break; + case 'M': c = leftPad(d.getMinutes()); break; + case 'S': c = leftPad(d.getSeconds()); break; + case 'd': c = "" + d.getDate(); break; + case 'm': c = "" + (d.getMonth() + 1); break; + case 'y': c = "" + d.getFullYear(); break; + case 'b': c = "" + monthNames[d.getMonth()]; break; + default: c; + } + r.push(c); + escape = false; + } + else { + if (c == "%") + escape = true; + else + r.push(c); + } + } + return r.join(""); + } + + + // map of app. size of time units in milliseconds + var timeUnitSize = { + "second": 1000, + "minute": 60 * 1000, + "hour": 60 * 60 * 1000, + "day": 24 * 60 * 60 * 1000, + "month": 30 * 24 * 60 * 60 * 1000, + "year": 365.2425 * 24 * 60 * 60 * 1000 + }; + // the allowed tick sizes, after 1 year we use // an integer algorithm @@ -339,9 +386,8 @@ //console.log(d, "month", axis.tickSize) if (axis.tickSize < 1) { // a bit complicated - we'll divide the month - // up but we need to take care - // of fractions so we don't end up in the - // middle of a day + // up but we need to take care of fractions + // so we don't end up in the middle of a day d.setDate(1); var start = d.getTime(); d.setMonth(d.getMonth() + 1); @@ -400,37 +446,37 @@ size *= magn; } - if (typeof axisOptions.tickFormatter == "string") - formatter = function (v, axis) { - return formatDate(new Date(v), axisOptions.tickFormatter); - }; - else - formatter = function (v, axis) { - var d = new Date(v); - var t = axis.tickSize * timeUnitSize[axis.tickSizeUnit]; - var span = axis.max - axis.min; - - if (t < timeUnitSize.minute) - fmt = "%h:%M:%S"; - else if (t < timeUnitSize.day) { - if (span < 2 * timeUnitSize.day) - fmt = "%h:%M"; - else + formatter = function (v, axis) { + var d = new Date(v); + + // first check global format + if (axisOptions.timeformat != null) + return formatDate(d, axisOptions.timeformat, axisOptions.monthNames); + + var t = axis.tickSize * timeUnitSize[axis.tickSizeUnit]; + var span = axis.max - axis.min; + + if (t < timeUnitSize.minute) + fmt = "%h:%M:%S"; + else if (t < timeUnitSize.day) { + if (span < 2 * timeUnitSize.day) + fmt = "%h:%M"; + else fmt = "%b %d %h:%M"; - } - else if (t < timeUnitSize.month) - fmt = "%b %d"; - else if (t < timeUnitSize.year) { - if (span < timeUnitSize.year) - fmt = "%b"; - else - fmt = "%b %y"; - } + } + else if (t < timeUnitSize.month) + fmt = "%b %d"; + else if (t < timeUnitSize.year) { + if (span < timeUnitSize.year) + fmt = "%b"; else - fmt = "%y"; - - return formatDate(d, fmt); - }; + fmt = "%b %y"; + } + else + fmt = "%y"; + + return formatDate(d, fmt, axisOptions.monthNames); + }; } else { // pretty rounding of base-10 numbers @@ -480,7 +526,6 @@ axis.tickSize = size; axis.tickGenerator = generator; axis.tickSizeUnit = unit; - axis.datatype = axisOptions.datatype; if ($.isFunction(axisOptions.tickFormatter)) axis.tickFormatter = function (v, axis) { return "" + axisOptions.tickFormatter(v, axis); }; else @@ -500,10 +545,15 @@ } function setTicks(axis, axisOptions) { - var i, v; axis.ticks = []; - - if (axisOptions.ticks) { + + if (axisOptions.ticks == null) + axis.ticks = axis.tickGenerator(axis); + else if (typeof axisOptions.ticks == "number") { + if (axisOptions.ticks > 0) + axis.ticks = axis.tickGenerator(axis); + } + else if (axisOptions.ticks) { var ticks = axisOptions.ticks; if ($.isFunction(ticks)) @@ -511,10 +561,11 @@ ticks = ticks({ min: axis.min, max: axis.max }); // clean up the user-supplied ticks, copy them over + var i, v; for (i = 0; i < ticks.length; ++i) { var label = null; var t = ticks[i]; - if (typeof(t) == "object") { + if (typeof t == "object") { v = t[0]; if (t.length > 1) label = t[1]; @@ -526,10 +577,8 @@ axis.ticks[i] = { v: v, label: label }; } } - else - axis.ticks = axis.tickGenerator(axis); - if (axisOptions.autoscaleMargin != null) { + if (axisOptions.autoscaleMargin != null && axis.ticks.length > 0) { if (axisOptions.min == null) axis.min = axis.ticks[0].v; if (axisOptions.max == null && axis.ticks.length > 1) @@ -714,7 +763,7 @@ var sc = series[i].color; if (sc != null) { --neededColors; - if (typeof(sc) == "number") + if (typeof sc == "number") assignedColors.push(sc); else usedColors.push(parseColor(series[i].color)); @@ -764,7 +813,7 @@ s.color = colors[colori].toString(); ++colori; } - else if (typeof(s.color) == "number") + else if (typeof s.color == "number") s.color = colors[s.color].toString(); // copy the rest @@ -1435,42 +1484,6 @@ return Math.abs(selection.second.x - selection.first.x) >= minSize && Math.abs(selection.second.y - selection.first.y) >= minSize; } - - function formatDate(d, s) { - var leftPad = function(n) { - n = "" + n; - return n.length == 1 ? "0" + n : n; - }; - - var r = []; - var escape = false; - for (var i = 0; i < s.length; ++i) { - var c = s.charAt(i); - - if (escape) { - switch (c) { - case 'h': c = "" + d.getHours(); break; - case 'H': c = leftPad(d.getHours()); break; - case 'M': c = leftPad(d.getMinutes()); break; - case 'S': c = leftPad(d.getSeconds()); break; - case 'd': c = "" + d.getDate(); break; - case 'm': c = "" + (d.getMonth() + 1); break; - case 'y': c = "" + d.getFullYear(); break; - case 'b': c = "" + options.datatype.time.monthNames[d.getMonth()]; break; - default: c; - } - r.push(c); - escape = false; - } - else { - if (c == "%") - escape = true; - else - r.push(c); - } - } - return r.join(""); - } } $.plot = function(target, data, options) {