Newer
Older
11001
11002
11003
11004
11005
11006
11007
11008
11009
11010
11011
11012
11013
11014
11015
11016
11017
11018
11019
11020
11021
11022
11023
11024
11025
11026
11027
11028
11029
11030
11031
11032
11033
11034
11035
11036
11037
11038
11039
11040
11041
11042
11043
11044
11045
11046
11047
11048
11049
11050
11051
11052
11053
11054
11055
11056
11057
11058
11059
11060
11061
11062
11063
11064
11065
11066
11067
11068
11069
11070
11071
11072
11073
11074
11075
11076
11077
11078
11079
11080
11081
11082
11083
11084
11085
11086
11087
11088
11089
11090
11091
11092
11093
11094
11095
11096
11097
11098
11099
11100
11101
11102
11103
11104
11105
11106
11107
11108
11109
11110
11111
11112
11113
11114
11115
11116
11117
11118
11119
11120
11121
11122
11123
11124
11125
11126
11127
11128
11129
11130
11131
11132
11133
11134
11135
11136
11137
11138
11139
11140
11141
11142
11143
11144
11145
11146
11147
11148
11149
11150
11151
11152
11153
11154
11155
11156
11157
11158
11159
11160
11161
11162
11163
11164
11165
11166
11167
11168
11169
11170
11171
11172
11173
11174
11175
11176
11177
11178
11179
11180
11181
11182
11183
11184
11185
11186
11187
11188
11189
11190
11191
11192
11193
11194
11195
11196
11197
11198
11199
11200
11201
11202
11203
11204
11205
11206
11207
11208
11209
11210
11211
11212
11213
11214
11215
11216
11217
11218
11219
11220
11221
11222
11223
11224
11225
11226
11227
11228
11229
11230
11231
11232
11233
11234
11235
11236
11237
11238
11239
11240
11241
11242
11243
11244
11245
11246
11247
11248
11249
11250
11251
11252
11253
11254
11255
11256
11257
11258
11259
11260
11261
11262
11263
11264
11265
11266
11267
11268
11269
11270
11271
11272
11273
11274
11275
11276
11277
11278
11279
11280
11281
11282
11283
11284
11285
11286
11287
11288
11289
11290
11291
11292
11293
11294
11295
11296
11297
11298
11299
11300
11301
11302
11303
11304
11305
11306
11307
11308
11309
11310
11311
11312
11313
11314
11315
11316
11317
11318
11319
11320
11321
11322
11323
11324
11325
11326
11327
11328
11329
11330
11331
11332
11333
11334
11335
11336
11337
11338
11339
11340
11341
11342
11343
11344
11345
11346
11347
11348
11349
11350
11351
11352
11353
11354
11355
11356
11357
11358
11359
11360
11361
11362
11363
11364
11365
11366
11367
11368
11369
11370
11371
11372
11373
11374
11375
11376
11377
11378
11379
11380
11381
11382
11383
11384
11385
11386
11387
11388
11389
11390
11391
11392
11393
11394
11395
11396
11397
11398
11399
11400
11401
11402
11403
11404
11405
11406
11407
11408
11409
11410
11411
11412
11413
11414
11415
11416
11417
11418
11419
11420
11421
11422
11423
11424
11425
11426
11427
11428
11429
11430
11431
11432
11433
11434
11435
11436
11437
11438
11439
11440
11441
11442
11443
11444
11445
11446
11447
11448
11449
11450
11451
11452
11453
11454
11455
11456
11457
11458
11459
11460
11461
11462
11463
11464
11465
11466
11467
11468
11469
11470
11471
11472
11473
11474
11475
11476
11477
11478
11479
11480
11481
11482
11483
11484
11485
11486
11487
11488
11489
11490
11491
11492
11493
11494
11495
11496
11497
11498
11499
11500
11501
11502
11503
11504
11505
11506
11507
11508
11509
11510
11511
11512
11513
11514
11515
11516
11517
11518
11519
11520
11521
11522
11523
11524
11525
11526
11527
11528
11529
11530
11531
11532
11533
11534
11535
11536
11537
11538
11539
11540
11541
11542
11543
11544
11545
11546
11547
11548
11549
11550
11551
11552
11553
11554
11555
11556
11557
11558
11559
11560
11561
11562
11563
11564
11565
11566
11567
11568
11569
11570
11571
11572
11573
11574
11575
11576
11577
11578
11579
11580
11581
11582
11583
11584
11585
11586
11587
11588
11589
11590
11591
11592
11593
11594
11595
11596
11597
11598
11599
11600
11601
11602
11603
11604
11605
11606
11607
11608
11609
11610
11611
11612
11613
11614
11615
11616
11617
11618
11619
11620
11621
11622
11623
11624
11625
11626
11627
11628
11629
11630
11631
11632
11633
11634
11635
11636
11637
11638
11639
11640
11641
11642
11643
11644
11645
11646
11647
11648
11649
11650
11651
11652
11653
11654
11655
11656
11657
11658
11659
11660
11661
11662
11663
11664
11665
11666
11667
11668
11669
11670
11671
11672
11673
11674
11675
11676
11677
11678
11679
11680
11681
11682
11683
11684
11685
11686
11687
11688
11689
11690
11691
11692
11693
11694
11695
11696
11697
11698
11699
11700
11701
11702
11703
11704
11705
11706
11707
11708
11709
11710
11711
11712
11713
11714
11715
11716
11717
11718
11719
11720
11721
11722
11723
11724
11725
11726
11727
11728
11729
11730
11731
11732
11733
11734
11735
11736
11737
11738
11739
11740
11741
11742
11743
11744
11745
11746
11747
11748
11749
11750
11751
11752
11753
11754
11755
11756
11757
11758
11759
11760
11761
11762
11763
11764
11765
11766
11767
11768
11769
11770
11771
11772
11773
11774
11775
11776
11777
11778
11779
11780
11781
11782
11783
11784
11785
11786
11787
11788
11789
11790
11791
11792
11793
11794
11795
11796
11797
11798
11799
11800
11801
11802
11803
11804
11805
11806
11807
11808
11809
11810
11811
11812
11813
11814
11815
11816
11817
11818
11819
11820
11821
11822
11823
11824
11825
11826
11827
11828
11829
11830
11831
11832
11833
11834
11835
11836
11837
11838
11839
11840
11841
11842
11843
11844
11845
11846
11847
11848
11849
11850
11851
11852
11853
11854
11855
11856
11857
11858
11859
11860
11861
11862
11863
11864
11865
11866
11867
11868
11869
11870
11871
11872
11873
11874
11875
11876
11877
11878
11879
11880
11881
11882
11883
11884
11885
11886
11887
11888
11889
11890
11891
11892
11893
11894
11895
11896
11897
11898
11899
11900
11901
11902
11903
11904
11905
11906
11907
11908
11909
11910
11911
11912
11913
11914
11915
11916
11917
11918
11919
11920
11921
11922
11923
11924
11925
11926
11927
11928
11929
11930
11931
11932
11933
11934
11935
11936
11937
11938
11939
11940
11941
11942
11943
11944
11945
11946
11947
11948
11949
11950
11951
11952
11953
11954
11955
11956
11957
11958
11959
11960
11961
11962
11963
11964
11965
11966
11967
11968
11969
11970
11971
11972
11973
11974
11975
11976
11977
11978
11979
11980
11981
11982
11983
11984
11985
11986
11987
11988
11989
11990
11991
11992
11993
11994
11995
11996
11997
11998
11999
12000
"default": "null",
"labels": ["Axis display", "Interactive Elements"],
"type": "float",
"description": "A value representing the farthest a graph may be panned, in percent of the display. For example, a value of 0.1 means that the graph can only be panned 10% pased the edges of the displayed values. null means no bounds."
},
"title": {
"labels": ["Chart labels"],
"type": "string",
"default": "null",
"description": "Text to display above the chart. You can supply any HTML for this value, not just text. If you wish to style it using CSS, use the 'dygraph-label' or 'dygraph-title' classes."
},
"titleHeight": {
"default": "18",
"labels": ["Chart labels"],
"type": "integer",
"description": "Height of the chart title, in pixels. This also controls the default font size of the title. If you style the title on your own, this controls how much space is set aside above the chart for the title's div."
},
"xlabel": {
"labels": ["Chart labels"],
"type": "string",
"default": "null",
"description": "Text to display below the chart's x-axis. You can supply any HTML for this value, not just text. If you wish to style it using CSS, use the 'dygraph-label' or 'dygraph-xlabel' classes."
},
"xLabelHeight": {
"labels": ["Chart labels"],
"type": "integer",
"default": "18",
"description": "Height of the x-axis label, in pixels. This also controls the default font size of the x-axis label. If you style the label on your own, this controls how much space is set aside below the chart for the x-axis label's div."
},
"ylabel": {
"labels": ["Chart labels"],
"type": "string",
"default": "null",
"description": "Text to display to the left of the chart's y-axis. You can supply any HTML for this value, not just text. If you wish to style it using CSS, use the 'dygraph-label' or 'dygraph-ylabel' classes. The text will be rotated 90 degrees by default, so CSS rules may behave in unintuitive ways. No additional space is set aside for a y-axis label. If you need more space, increase the width of the y-axis tick labels using the yAxisLabelWidth option. If you need a wider div for the y-axis label, either style it that way with CSS (but remember that it's rotated, so width is controlled by the 'height' property) or set the yLabelWidth option."
},
"y2label": {
"labels": ["Chart labels"],
"type": "string",
"default": "null",
"description": "Text to display to the right of the chart's secondary y-axis. This label is only displayed if a secondary y-axis is present. See <a href='http://dygraphs.com/tests/two-axes.html'>this test</a> for an example of how to do this. The comments for the 'ylabel' option generally apply here as well. This label gets a 'dygraph-y2label' instead of a 'dygraph-ylabel' class."
},
"yLabelWidth": {
"labels": ["Chart labels"],
"type": "integer",
"default": "18",
"description": "Width of the div which contains the y-axis label. Since the y-axis label appears rotated 90 degrees, this actually affects the height of its div."
},
"isZoomedIgnoreProgrammaticZoom" : {
"default": "false",
"labels": ["Zooming"],
"type": "boolean",
"description" : "When this option is passed to updateOptions() along with either the <code>dateWindow</code> or <code>valueRange</code> options, the zoom flags are not changed to reflect a zoomed state. This is primarily useful for when the display area of a chart is changed programmatically and also where manual zooming is allowed and use is made of the <code>isZoomed</code> method to determine this."
},
"drawXGrid": {
"default": "true",
"labels": ["Grid","Deprecated"],
"type": "boolean",
"description" : "Use the per-axis option drawGrid instead. Whether to display vertical gridlines under the chart."
},
"drawYGrid": {
"default": "true",
"labels": ["Grid","Deprecated"],
"type": "boolean",
"description" : "Use the per-axis option drawGrid instead. Whether to display horizontal gridlines under the chart."
},
"drawGrid": {
"default": "true for x and y, false for y2",
"labels": ["Grid"],
"type": "boolean",
"description" : "Whether to display gridlines in the chart. This may be set on a per-axis basis to define the visibility of each axis' grid separately."
},
"independentTicks": {
"default": "true for y, false for y2",
"labels": ["Axis display", "Grid"],
"type": "boolean",
"description" : "Only valid for y and y2, has no effect on x: This option defines whether the y axes should align their ticks or if they should be independent. Possible combinations: 1.) y=true, y2=false (default): y is the primary axis and the y2 ticks are aligned to the the ones of y. (only 1 grid) 2.) y=false, y2=true: y2 is the primary axis and the y ticks are aligned to the the ones of y2. (only 1 grid) 3.) y=true, y2=true: Both axis are independent and have their own ticks. (2 grids) 4.) y=false, y2=false: Invalid configuration causes an error."
},
"drawXAxis": {
"default": "true",
"labels": ["Axis display"],
"type": "boolean",
"description" : "Deprecated. Use axes : { x : { drawAxis } }."
},
"drawYAxis": {
"default": "true",
"labels": ["Axis display"],
"type": "boolean",
"description" : "Deprecated. Use axes : { y : { drawAxis } }."
},
"drawAxis": {
"default": "true for x and y, false for y2",
"labels": ["Axis display"],
"type": "boolean",
"description" : "Whether to draw the specified axis. This may be set on a per-axis basis to define the visibility of each axis separately. Setting this to false also prevents axis ticks from being drawn and reclaims the space for the chart grid/lines."
},
"gridLineWidth": {
"default": "0.3",
"labels": ["Grid"],
"type": "float",
"description" : "Thickness (in pixels) of the gridlines drawn under the chart. The vertical/horizontal gridlines can be turned off entirely by using the drawXGrid and drawYGrid options. This may be set on a per-axis basis to define each axis' grid separately."
},
"axisLineWidth": {
"default": "0.3",
"labels": ["Axis display"],
"type": "float",
"description" : "Thickness (in pixels) of the x- and y-axis lines."
},
"axisLineColor": {
"default": "black",
"labels": ["Axis display"],
"type": "string",
"description" : "Color of the x- and y-axis lines. Accepts any value which the HTML canvas strokeStyle attribute understands, e.g. 'black' or 'rgb(0, 100, 255)'."
},
"fillAlpha": {
"default": "0.15",
"labels": ["Error Bars", "Data Series Colors"],
"type": "float (0.0 - 1.0)",
"description" : "Error bars (or custom bars) for each series are drawn in the same color as the series, but with partial transparency. This sets the transparency. A value of 0.0 means that the error bars will not be drawn, whereas a value of 1.0 means that the error bars will be as dark as the line for the series itself. This can be used to produce chart lines whose thickness varies at each point."
},
"axisLabelColor": {
"default": "black",
"labels": ["Axis display"],
"type": "string",
"description" : "Color for x- and y-axis labels. This is a CSS color string."
},
"axisLabelWidth": {
"default": "50 (y-axis), 60 (x-axis)",
"labels": ["Axis display", "Chart labels"],
"type": "integer",
"description" : "Width (in pixels) of the containing divs for x- and y-axis labels. For the y-axis, this also controls the width of the y-axis. Note that for the x-axis, this is independent from pixelsPerLabel, which controls the spacing between labels."
},
"sigFigs" : {
"default": "null",
"labels": ["Value display/formatting"],
"type": "integer",
"description": "By default, dygraphs displays numbers with a fixed number of digits after the decimal point. If you'd prefer to have a fixed number of significant figures, set this option to that number of sig figs. A value of 2, for instance, would cause 1 to be display as 1.0 and 1234 to be displayed as 1.23e+3."
},
"digitsAfterDecimal" : {
"default": "2",
"labels": ["Value display/formatting"],
"type": "integer",
"description": "Unless it's run in scientific mode (see the <code>sigFigs</code> option), dygraphs displays numbers with <code>digitsAfterDecimal</code> digits after the decimal point. Trailing zeros are not displayed, so with a value of 2 you'll get '0', '0.1', '0.12', '123.45' but not '123.456' (it will be rounded to '123.46'). Numbers with absolute value less than 0.1^digitsAfterDecimal (i.e. those which would show up as '0.00') will be displayed in scientific notation."
},
"maxNumberWidth" : {
"default": "6",
"labels": ["Value display/formatting"],
"type": "integer",
"description": "When displaying numbers in normal (not scientific) mode, large numbers will be displayed with many trailing zeros (e.g. 100000000 instead of 1e9). This can lead to unwieldy y-axis labels. If there are more than <code>maxNumberWidth</code> digits to the left of the decimal in a number, dygraphs will switch to scientific notation, even when not operating in scientific mode. If you'd like to see all those digits, set this to something large, like 20 or 30."
},
"file": {
"default": "(set when constructed)",
"labels": ["Data"],
"type": "string (URL of CSV or CSV), GViz DataTable or 2D Array",
"description": "Sets the data being displayed in the chart. This can only be set when calling updateOptions; it cannot be set from the constructor. For a full description of valid data formats, see the <a href='http://dygraphs.com/data.html'>Data Formats</a> page."
},
"timingName": {
"default": "null",
"labels": [ "Debugging" ],
"type": "string",
"description": "Set this option to log timing information. The value of the option will be logged along with the timimg, so that you can distinguish multiple dygraphs on the same page."
},
"showRangeSelector": {
"default": "false",
"labels": ["Interactive Elements"],
"type": "boolean",
"description": "Show or hide the range selector widget."
},
"rangeSelectorHeight": {
"default": "40",
"labels": ["Interactive Elements"],
"type": "integer",
"description": "Height, in pixels, of the range selector widget. This option can only be specified at Dygraph creation time."
},
"rangeSelectorPlotStrokeColor": {
"default": "#808FAB",
"labels": ["Interactive Elements"],
"type": "string",
"description": "The range selector mini plot stroke color. This can be of the form \"#AABBCC\" or \"rgb(255,100,200)\" or \"yellow\". You can also specify null or \"\" to turn off stroke."
},
"rangeSelectorPlotFillColor": {
"default": "#A7B1C4",
"labels": ["Interactive Elements"],
"type": "string",
"description": "The range selector mini plot fill color. This can be of the form \"#AABBCC\" or \"rgb(255,100,200)\" or \"yellow\". You can also specify null or \"\" to turn off fill."
},
"showInRangeSelector": {
"default": "null",
"labels": ["Interactive Elements"],
"type": "boolean",
"description": "Mark this series for inclusion in the range selector. The mini plot curve will be an average of all such series. If this is not specified for any series, the default behavior is to average all the series. Setting it for one series will result in that series being charted alone in the range selector."
},
"animatedZooms": {
"default": "false",
"labels": ["Interactive Elements"],
"type": "boolean",
"description": "Set this option to animate the transition between zoom windows. Applies to programmatic and interactive zooms. Note that if you also set a drawCallback, it will be called several times on each zoom. If you set a zoomCallback, it will only be called after the animation is complete."
},
"plotter": {
"default": "[DygraphCanvasRenderer.Plotters.fillPlotter, DygraphCanvasRenderer.Plotters.errorPlotter, DygraphCanvasRenderer.Plotters.linePlotter]",
"labels": ["Data Line display"],
"type": "array or function",
"description": "A function (or array of functions) which plot each data series on the chart. TODO(danvk): more details! May be set per-series."
},
"axes": {
"default": "null",
"labels": ["Configuration"],
"type": "Object",
"description": "Defines per-axis options. Valid keys are 'x', 'y' and 'y2'. Only some options may be set on a per-axis basis. If an option may be set in this way, it will be noted on this page. See also documentation on <a href='http://dygraphs.com/per-axis.html'>per-series and per-axis options</a>."
},
"series": {
"default": "null",
"labels": ["Series"],
"type": "Object",
"description": "Defines per-series options. Its keys match the y-axis label names, and the values are dictionaries themselves that contain options specific to that series. When this option is missing, it falls back on the old-style of per-series options comingled with global options."
},
"plugins": {
"default": "[]",
"labels": ["Configuration"],
"type": "Array<plugin>",
"description": "Defines per-graph plugins. Useful for per-graph customization"
},
"dataHandler": {
"default": "(depends on data)",
"labels": ["Data"],
"type": "Dygraph.DataHandler",
"description": "Custom DataHandler. This is an advanced customization. See http://bit.ly/151E7Aq."
}
}
; // </JSON>
// NOTE: in addition to parsing as JS, this snippet is expected to be valid
// JSON. This assumption cannot be checked in JS, but it will be checked when
// documentation is generated by the generate-documentation.py script. For the
// most part, this just means that you should always use double quotes.
// Do a quick sanity check on the options reference.
(function() {
"use strict";
var warn = function(msg) { if (window.console) window.console.warn(msg); };
var flds = ['type', 'default', 'description'];
var valid_cats = [
'Annotations',
'Axis display',
'Chart labels',
'CSV parsing',
'Callbacks',
'Data',
'Data Line display',
'Data Series Colors',
'Error Bars',
'Grid',
'Interactive Elements',
'Legend',
'Overall display',
'Rolling Averages',
'Series',
'Value display/formatting',
'Zooming',
'Debugging',
'Configuration',
'Deprecated'
];
var i;
var cats = {};
for (i = 0; i < valid_cats.length; i++) cats[valid_cats[i]] = true;
for (var k in Dygraph.OPTIONS_REFERENCE) {
if (!Dygraph.OPTIONS_REFERENCE.hasOwnProperty(k)) continue;
var op = Dygraph.OPTIONS_REFERENCE[k];
for (i = 0; i < flds.length; i++) {
if (!op.hasOwnProperty(flds[i])) {
warn('Option ' + k + ' missing "' + flds[i] + '" property');
} else if (typeof(op[flds[i]]) != 'string') {
warn(k + '.' + flds[i] + ' must be of type string');
}
}
var labels = op.labels;
if (typeof(labels) !== 'object') {
warn('Option "' + k + '" is missing a "labels": [...] option');
} else {
for (i = 0; i < labels.length; i++) {
if (!cats.hasOwnProperty(labels[i])) {
warn('Option "' + k + '" has label "' + labels[i] +
'", which is invalid.');
}
}
}
}
})();
/**
* @license
* Copyright 2013 David Eberlein (david.eberlein@ch.sauter-bc.com)
* MIT-licensed (http://opensource.org/licenses/MIT)
*/
/**
* @fileoverview This file contains the managment of data handlers
* @author David Eberlein (david.eberlein@ch.sauter-bc.com)
*
* The idea is to define a common, generic data format that works for all data
* structures supported by dygraphs. To make this possible, the DataHandler
* interface is introduced. This makes it possible, that dygraph itself can work
* with the same logic for every data type independent of the actual format and
* the DataHandler takes care of the data format specific jobs.
* DataHandlers are implemented for all data types supported by Dygraphs and
* return Dygraphs compliant formats.
* By default the correct DataHandler is chosen based on the options set.
* Optionally the user may use his own DataHandler (similar to the plugin
* system).
*
*
* The unified data format returend by each handler is defined as so:
* series[n][point] = [x,y,(extras)]
*
* This format contains the common basis that is needed to draw a simple line
* series extended by optional extras for more complex graphing types. It
* contains a primitive x value as first array entry, a primitive y value as
* second array entry and an optional extras object for additional data needed.
*
* x must always be a number.
* y must always be a number, NaN of type number or null.
* extras is optional and must be interpreted by the DataHandler. It may be of
* any type.
*
* In practice this might look something like this:
* default: [x, yVal]
* errorBar / customBar: [x, yVal, [yTopVariance, yBottomVariance] ]
*
*/
/*global Dygraph:false */
/*global DygraphLayout:false */
/**
*
* The data handler is responsible for all data specific operations. All of the
* series data it receives and returns is always in the unified data format.
* Initially the unified data is created by the extractSeries method
* @constructor
*/
Dygraph.DataHandler = function () {
};
/**
* A collection of functions to create and retrieve data handlers.
* @type {Object.<!Dygraph.DataHandler>}
*/
Dygraph.DataHandlers = {};
(function() {
"use strict";
var handler = Dygraph.DataHandler;
/**
* X-value array index constant for unified data samples.
* @const
* @type {number}
*/
handler.X = 0;
/**
* Y-value array index constant for unified data samples.
* @const
* @type {number}
*/
handler.Y = 1;
/**
* Extras-value array index constant for unified data samples.
* @const
* @type {number}
*/
handler.EXTRAS = 2;
/**
* Extracts one series from the raw data (a 2D array) into an array of the
* unified data format.
* This is where undesirable points (i.e. negative values on log scales and
* missing values through which we wish to connect lines) are dropped.
* TODO(danvk): the "missing values" bit above doesn't seem right.
*
* @param {!Array.<Array>} rawData The raw data passed into dygraphs where
* rawData[i] = [x,ySeries1,...,ySeriesN].
* @param {!number} seriesIndex Index of the series to extract. All other
* series should be ignored.
* @param {!DygraphOptions} options Dygraph options.
* @return {Array.<[!number,?number,?]>} The series in the unified data format
* where series[i] = [x,y,{extras}].
*/
handler.prototype.extractSeries = function(rawData, seriesIndex, options) {
};
/**
* Converts a series to a Point array. The resulting point array must be
* returned in increasing order of idx property.
*
* @param {!Array.<[!number,?number,?]>} series The series in the unified
* data format where series[i] = [x,y,{extras}].
* @param {!string} setName Name of the series.
* @param {!number} boundaryIdStart Index offset of the first point, equal to the
* number of skipped points left of the date window minimum (if any).
* @return {!Array.<Dygraph.PointType>} List of points for this series.
*/
handler.prototype.seriesToPoints = function(series, setName, boundaryIdStart) {
// TODO(bhs): these loops are a hot-spot for high-point-count charts. In
// fact,
// on chrome+linux, they are 6 times more expensive than iterating through
// the
// points and drawing the lines. The brunt of the cost comes from allocating
// the |point| structures.
var points = [];
for ( var i = 0; i < series.length; ++i) {
var item = series[i];
var yraw = item[1];
var yval = yraw === null ? null : handler.parseFloat(yraw);
var point = {
x : NaN,
y : NaN,
xval : handler.parseFloat(item[0]),
yval : yval,
name : setName, // TODO(danvk): is this really necessary?
idx : i + boundaryIdStart
};
points.push(point);
}
this.onPointsCreated_(series, points);
return points;
};
/**
* Callback called for each series after the series points have been generated
* which will later be used by the plotters to draw the graph.
* Here data may be added to the seriesPoints which is needed by the plotters.
* The indexes of series and points are in sync meaning the original data
* sample for series[i] is points[i].
*
* @param {!Array.<[!number,?number,?]>} series The series in the unified
* data format where series[i] = [x,y,{extras}].
* @param {!Array.<Dygraph.PointType>} points The corresponding points passed
* to the plotter.
* @protected
*/
handler.prototype.onPointsCreated_ = function(series, points) {
};
/**
* Calculates the rolling average of a data set.
*
* @param {!Array.<[!number,?number,?]>} series The series in the unified
* data format where series[i] = [x,y,{extras}].
* @param {!number} rollPeriod The number of points over which to average the data
* @param {!DygraphOptions} options The dygraph options.
* @return {!Array.<[!number,?number,?]>} the rolled series.
*/
handler.prototype.rollingAverage = function(series, rollPeriod, options) {
};
/**
* Computes the range of the data series (including confidence intervals).
*
* @param {!Array.<[!number,?number,?]>} series The series in the unified
* data format where series[i] = [x, y, {extras}].
* @param {!Array.<number>} dateWindow The x-value range to display with
* the format: [min, max].
* @param {!DygraphOptions} options The dygraph options.
* @return {Array.<number>} The low and high extremes of the series in the
* given window with the format: [low, high].
*/
handler.prototype.getExtremeYValues = function(series, dateWindow, options) {
};
/**
* Callback called for each series after the layouting data has been
* calculated before the series is drawn. Here normalized positioning data
* should be calculated for the extras of each point.
*
* @param {!Array.<Dygraph.PointType>} points The points passed to
* the plotter.
* @param {!Object} axis The axis on which the series will be plotted.
* @param {!boolean} logscale Weather or not to use a logscale.
*/
handler.prototype.onLineEvaluated = function(points, axis, logscale) {
};
/**
* Helper method that computes the y value of a line defined by the points p1
* and p2 and a given x value.
*
* @param {!Array.<number>} p1 left point ([x,y]).
* @param {!Array.<number>} p2 right point ([x,y]).
* @param {!number} xValue The x value to compute the y-intersection for.
* @return {number} corresponding y value to x on the line defined by p1 and p2.
* @private
*/
handler.prototype.computeYInterpolation_ = function(p1, p2, xValue) {
var deltaY = p2[1] - p1[1];
var deltaX = p2[0] - p1[0];
var gradient = deltaY / deltaX;
var growth = (xValue - p1[0]) * gradient;
return p1[1] + growth;
};
/**
* Helper method that returns the first and the last index of the given series
* that lie inside the given dateWindow.
*
* @param {!Array.<[!number,?number,?]>} series The series in the unified
* data format where series[i] = [x,y,{extras}].
* @param {!Array.<number>} dateWindow The x-value range to display with
* the format: [min,max].
* @return {!Array.<[!number,?number,?]>} The samples of the series that
* are in the given date window.
* @private
*/
handler.prototype.getIndexesInWindow_ = function(series, dateWindow) {
var firstIdx = 0, lastIdx = series.length - 1;
if (dateWindow) {
var idx = 0;
var low = dateWindow[0];
var high = dateWindow[1];
// Start from each side of the array to minimize the performance
// needed.
while (idx < series.length - 1 && series[idx][0] < low) {
firstIdx++;
idx++;
}
idx = series.length - 1;
while (idx > 0 && series[idx][0] > high) {
lastIdx--;
idx--;
}
}
if (firstIdx <= lastIdx) {
return [ firstIdx, lastIdx ];
} else {
return [ 0, series.length - 1 ];
}
};
/**
* Optimized replacement for parseFloat, which was way too slow when almost
* all values were type number, with few edge cases, none of which were strings.
* @param {?number} val
* @return {number}
* @protected
*/
handler.parseFloat = function(val) {
// parseFloat(null) is NaN
if (val === null) {
return NaN;
}
// Assume it's a number or NaN. If it's something else, I'll be shocked.
return val;
};
})();
/**
* @license
* Copyright 2013 David Eberlein (david.eberlein@ch.sauter-bc.com)
* MIT-licensed (http://opensource.org/licenses/MIT)
*/
/**
* @fileoverview DataHandler default implementation used for simple line charts.
* @author David Eberlein (david.eberlein@ch.sauter-bc.com)
*/
(function() {
/*global Dygraph:false */
"use strict";
/**
* @constructor
* @extends Dygraph.DataHandler
*/
Dygraph.DataHandlers.DefaultHandler = function() {
};
var DefaultHandler = Dygraph.DataHandlers.DefaultHandler;
DefaultHandler.prototype = new Dygraph.DataHandler();
/** @inheritDoc */
DefaultHandler.prototype.extractSeries = function(rawData, i, options) {
// TODO(danvk): pre-allocate series here.
var series = [];
var logScale = options.get('logscale');
for ( var j = 0; j < rawData.length; j++) {
var x = rawData[j][0];
var point = rawData[j][i];
if (logScale) {
// On the log scale, points less than zero do not exist.
// This will create a gap in the chart.
if (point <= 0) {
point = null;
}
}
series.push([ x, point ]);
}
return series;
};
/** @inheritDoc */
DefaultHandler.prototype.rollingAverage = function(originalData, rollPeriod,
options) {
rollPeriod = Math.min(rollPeriod, originalData.length);
var rollingData = [];
var i, j, y, sum, num_ok;
// Calculate the rolling average for the first rollPeriod - 1 points
// where
// there is not enough data to roll over the full number of points
if (rollPeriod == 1) {
return originalData;
}
for (i = 0; i < originalData.length; i++) {
sum = 0;
num_ok = 0;
for (j = Math.max(0, i - rollPeriod + 1); j < i + 1; j++) {
y = originalData[j][1];
if (y === null || isNaN(y))
continue;
num_ok++;
sum += originalData[j][1];
}
if (num_ok) {
rollingData[i] = [ originalData[i][0], sum / num_ok ];
} else {
rollingData[i] = [ originalData[i][0], null ];
}
}
return rollingData;
};
/** @inheritDoc */
DefaultHandler.prototype.getExtremeYValues = function(series, dateWindow,
options) {
var minY = null, maxY = null, y;
var firstIdx = 0, lastIdx = series.length - 1;
for ( var j = firstIdx; j <= lastIdx; j++) {
y = series[j][1];
if (y === null || isNaN(y))
continue;
if (maxY === null || y > maxY) {
maxY = y;
}
if (minY === null || y < minY) {
minY = y;
}
}
return [ minY, maxY ];
};
})();
/**
* @license
* Copyright 2013 David Eberlein (david.eberlein@ch.sauter-bc.com)
* MIT-licensed (http://opensource.org/licenses/MIT)
*/
/**
* @fileoverview DataHandler implementation for the fractions option.
* @author David Eberlein (david.eberlein@ch.sauter-bc.com)
*/
(function() {
/*global Dygraph:false */
"use strict";
/**
* @extends Dygraph.DataHandlers.DefaultHandler
* @constructor
*/
Dygraph.DataHandlers.DefaultFractionHandler = function() {
};
var DefaultFractionHandler = Dygraph.DataHandlers.DefaultFractionHandler;
DefaultFractionHandler.prototype = new Dygraph.DataHandlers.DefaultHandler();
DefaultFractionHandler.prototype.extractSeries = function(rawData, i, options) {
// TODO(danvk): pre-allocate series here.
var series = [];
var x, y, point, num, den, value;
var mult = 100.0;
var logScale = options.get('logscale');
for ( var j = 0; j < rawData.length; j++) {
x = rawData[j][0];
point = rawData[j][i];
if (logScale && point !== null) {
// On the log scale, points less than zero do not exist.
// This will create a gap in the chart.
if (point[0] <= 0 || point[1] <= 0) {
point = null;
}
}
// Extract to the unified data format.
if (point !== null) {
num = point[0];
den = point[1];
if (num !== null && !isNaN(num)) {
value = den ? num / den : 0.0;
y = mult * value;
// preserve original values in extras for further filtering
series.push([ x, y, [ num, den ] ]);
} else {
series.push([ x, num, [ num, den ] ]);
}
} else {
series.push([ x, null, [ null, null ] ]);
}
}
return series;
};
DefaultFractionHandler.prototype.rollingAverage = function(originalData, rollPeriod,
options) {
rollPeriod = Math.min(rollPeriod, originalData.length);
var rollingData = [];
var i;
var num = 0;
var den = 0; // numerator/denominator
var mult = 100.0;
for (i = 0; i < originalData.length; i++) {
num += originalData[i][2][0];
den += originalData[i][2][1];
if (i - rollPeriod >= 0) {
num -= originalData[i - rollPeriod][2][0];
den -= originalData[i - rollPeriod][2][1];
}
var date = originalData[i][0];
var value = den ? num / den : 0.0;
rollingData[i] = [ date, mult * value ];
}
return rollingData;
};
})();
/**
* @license
* Copyright 2013 David Eberlein (david.eberlein@ch.sauter-bc.com)
* MIT-licensed (http://opensource.org/licenses/MIT)
*/
/**
* @fileoverview DataHandler base implementation for the "bar"
* data formats. This implementation must be extended and the
* extractSeries and rollingAverage must be implemented.
* @author David Eberlein (david.eberlein@ch.sauter-bc.com)
*/
(function() {
/*global Dygraph:false */
/*global DygraphLayout:false */
"use strict";
/**
* @constructor
* @extends {Dygraph.DataHandler}
*/
Dygraph.DataHandlers.BarsHandler = function() {
Dygraph.DataHandler.call(this);
};
Dygraph.DataHandlers.BarsHandler.prototype = new Dygraph.DataHandler();
// alias for the rest of the implementation
var BarsHandler = Dygraph.DataHandlers.BarsHandler;
// TODO(danvk): figure out why the jsdoc has to be copy/pasted from superclass.
// (I get closure compiler errors if this isn't here.)
/**
* @override
* @param {!Array.<Array>} rawData The raw data passed into dygraphs where
* rawData[i] = [x,ySeries1,...,ySeriesN].
* @param {!number} seriesIndex Index of the series to extract. All other
* series should be ignored.
* @param {!DygraphOptions} options Dygraph options.
* @return {Array.<[!number,?number,?]>} The series in the unified data format
* where series[i] = [x,y,{extras}].
*/
BarsHandler.prototype.extractSeries = function(rawData, seriesIndex, options) {
// Not implemented here must be extended
};
/**
* @override
* @param {!Array.<[!number,?number,?]>} series The series in the unified
* data format where series[i] = [x,y,{extras}].
* @param {!number} rollPeriod The number of points over which to average the data
* @param {!DygraphOptions} options The dygraph options.
* TODO(danvk): be more specific than "Array" here.
* @return {!Array.<[!number,?number,?]>} the rolled series.
*/
BarsHandler.prototype.rollingAverage =
function(series, rollPeriod, options) {
// Not implemented here, must be extended.
};
/** @inheritDoc */
BarsHandler.prototype.onPointsCreated_ = function(series, points) {
for (var i = 0; i < series.length; ++i) {
var item = series[i];
var point = points[i];
point.y_top = NaN;
point.y_bottom = NaN;
point.yval_minus = Dygraph.DataHandler.parseFloat(item[2][0]);
point.yval_plus = Dygraph.DataHandler.parseFloat(item[2][1]);
}
};
/** @inheritDoc */
BarsHandler.prototype.getExtremeYValues = function(series, dateWindow, options) {
var minY = null, maxY = null, y;
var firstIdx = 0;
var lastIdx = series.length - 1;
for ( var j = firstIdx; j <= lastIdx; j++) {
y = series[j][1];
if (y === null || isNaN(y)) continue;
var low = series[j][2][0];
var high = series[j][2][1];
if (low > y) low = y; // this can happen with custom bars,
if (high < y) high = y; // e.g. in tests/custom-bars.html
if (maxY === null || high > maxY) maxY = high;
if (minY === null || low < minY) minY = low;
}
return [ minY, maxY ];
};
/** @inheritDoc */
BarsHandler.prototype.onLineEvaluated = function(points, axis, logscale) {
var point;
for (var j = 0; j < points.length; j++) {
// Copy over the error terms
point = points[j];
point.y_top = DygraphLayout.calcYNormal_(axis, point.yval_minus, logscale);
point.y_bottom = DygraphLayout.calcYNormal_(axis, point.yval_plus, logscale);
}
};
})();
/**
* @license
* Copyright 2013 David Eberlein (david.eberlein@ch.sauter-bc.com)
* MIT-licensed (http://opensource.org/licenses/MIT)
*/
/**
* @fileoverview DataHandler implementation for the custom bars option.
* @author David Eberlein (david.eberlein@ch.sauter-bc.com)
*/
(function() {
/*global Dygraph:false */
"use strict";
/**
* @constructor
* @extends Dygraph.DataHandlers.BarsHandler
*/
Dygraph.DataHandlers.CustomBarsHandler = function() {
};
var CustomBarsHandler = Dygraph.DataHandlers.CustomBarsHandler;
CustomBarsHandler.prototype = new Dygraph.DataHandlers.BarsHandler();
/** @inheritDoc */
CustomBarsHandler.prototype.extractSeries = function(rawData, i, options) {
// TODO(danvk): pre-allocate series here.
var series = [];
var x, y, point;
var logScale = options.get('logscale');
for ( var j = 0; j < rawData.length; j++) {
x = rawData[j][0];
point = rawData[j][i];
if (logScale && point !== null) {
// On the log scale, points less than zero do not exist.
// This will create a gap in the chart.
if (point[0] <= 0 || point[1] <= 0 || point[2] <= 0) {
point = null;
}
}
// Extract to the unified data format.
if (point !== null) {
y = point[1];
if (y !== null && !isNaN(y)) {
series.push([ x, y, [ point[0], point[2] ] ]);
} else {
series.push([ x, y, [ y, y ] ]);
}
} else {
series.push([ x, null, [ null, null ] ]);
}
}
return series;
};
/** @inheritDoc */
CustomBarsHandler.prototype.rollingAverage =
function(originalData, rollPeriod, options) {
rollPeriod = Math.min(rollPeriod, originalData.length);
var rollingData = [];
var y, low, high, mid,count, i, extremes;
low = 0;
mid = 0;
high = 0;
count = 0;
for (i = 0; i < originalData.length; i++) {
y = originalData[i][1];
extremes = originalData[i][2];
rollingData[i] = originalData[i];
if (y !== null && !isNaN(y)) {
low += extremes[0];
mid += y;
high += extremes[1];
count += 1;
}
if (i - rollPeriod >= 0) {
var prev = originalData[i - rollPeriod];
if (prev[1] !== null && !isNaN(prev[1])) {
low -= prev[2][0];
mid -= prev[1];
high -= prev[2][1];
count -= 1;
}
}
if (count) {
rollingData[i] = [
originalData[i][0],
1.0 * mid / count,
[ 1.0 * low / count,
1.0 * high / count ] ];
} else {
rollingData[i] = [ originalData[i][0], null, [ null, null ] ];
}
}
return rollingData;
};
})();
/**
* @license
* Copyright 2013 David Eberlein (david.eberlein@ch.sauter-bc.com)
* MIT-licensed (http://opensource.org/licenses/MIT)
*/
/**
* @fileoverview DataHandler implementation for the error bars option.
* @author David Eberlein (david.eberlein@ch.sauter-bc.com)
*/
(function() {
/*global Dygraph:false */
"use strict";
/**
* @constructor
* @extends Dygraph.DataHandlers.BarsHandler
*/
Dygraph.DataHandlers.ErrorBarsHandler = function() {
};
var ErrorBarsHandler = Dygraph.DataHandlers.ErrorBarsHandler;
ErrorBarsHandler.prototype = new Dygraph.DataHandlers.BarsHandler();
/** @inheritDoc */
ErrorBarsHandler.prototype.extractSeries = function(rawData, i, options) {
// TODO(danvk): pre-allocate series here.
var series = [];
var x, y, variance, point;
var sigma = options.get("sigma");
var logScale = options.get('logscale');
for ( var j = 0; j < rawData.length; j++) {
x = rawData[j][0];
point = rawData[j][i];
if (logScale && point !== null) {
// On the log scale, points less than zero do not exist.
// This will create a gap in the chart.
if (point[0] <= 0 || point[0] - sigma * point[1] <= 0) {
point = null;
}
}