| 1 | /** |
| 2 | * @fileoverview Test cases for the option "connectSeparatedPoints" especially for the scenario where not every series has a value for each timestamp. |
| 3 | * |
| 4 | * @author julian.eichstaedt@ch.sauter-bc.com (Fr. Sauter AG) |
| 5 | */ |
| 6 | describe("connect-separated-points", function() { |
| 7 | |
| 8 | beforeEach(function() { |
| 9 | document.body.innerHTML = "<div id='graph'></div>"; |
| 10 | }); |
| 11 | |
| 12 | var origFunc = Dygraph.getContext; |
| 13 | |
| 14 | beforeEach(function() { |
| 15 | document.body.innerHTML = "<div id='graph'></div>"; |
| 16 | Dygraph.getContext = function(canvas) { |
| 17 | return new Proxy(origFunc(canvas)); |
| 18 | }; |
| 19 | }); |
| 20 | |
| 21 | afterEach(function() { |
| 22 | Dygraph.getContext = origFunc; |
| 23 | }); |
| 24 | |
| 25 | it('testEdgePointsSimple', function() { |
| 26 | var opts = { |
| 27 | width: 480, |
| 28 | height: 320, |
| 29 | labels: ["x", "series1", "series2", "additionalSeries"], |
| 30 | connectSeparatedPoints: true, |
| 31 | dateWindow: [2.5,7.5] |
| 32 | }; |
| 33 | |
| 34 | var data = [ |
| 35 | [0,-1,0,null], |
| 36 | [1,null,2,null], |
| 37 | [2,null,4,null], |
| 38 | [3,0.5,0,null], |
| 39 | [4,1,-1,5], |
| 40 | [5,2,-2,6], |
| 41 | [6,2.5,-2.5,7], |
| 42 | [7,3,-3,null], |
| 43 | [8,4,null,null], |
| 44 | [9,4,-10,null] |
| 45 | ]; |
| 46 | |
| 47 | var graph = document.getElementById("graph"); |
| 48 | var g = new Dygraph(graph, data, opts); |
| 49 | |
| 50 | var htx = g.hidden_ctx_; |
| 51 | |
| 52 | var attrs = {}; |
| 53 | |
| 54 | // Test if series1 is drawn correctly. |
| 55 | // ------------------------------------ |
| 56 | |
| 57 | // The first point of the first series |
| 58 | var x1 = data[0][0]; |
| 59 | var y1 = data[0][1]; |
| 60 | var xy1 = g.toDomCoords(x1, y1); |
| 61 | |
| 62 | // The next valid point of this series |
| 63 | var x2 = data[3][0]; |
| 64 | var y2 = data[3][1]; |
| 65 | var xy2 = g.toDomCoords(x2, y2); |
| 66 | |
| 67 | // Check if both points are connected at the left edge of the canvas and if the option "connectSeparatedPoints" works properly |
| 68 | // even if the point is outside the visible range and only one series has a valid value for this point. |
| 69 | CanvasAssertions.assertLineDrawn(htx, xy1, xy2, attrs); |
| 70 | |
| 71 | // Test if series2 is drawn correctly. |
| 72 | // ------------------------------------ |
| 73 | |
| 74 | // The last point of the second series. |
| 75 | var x2 = data[9][0]; |
| 76 | var y2 = data[9][2]; |
| 77 | var xy2 = g.toDomCoords(x2, y2); |
| 78 | |
| 79 | // The previous valid point of this series |
| 80 | var x1 = data[7][0]; |
| 81 | var y1 = data[7][2]; |
| 82 | var xy1 = g.toDomCoords(x1, y1); |
| 83 | |
| 84 | // Check if both points are connected at the right edge of the canvas and if the option "connectSeparatedPoints" works properly |
| 85 | // even if the point is outside the visible range and only one series has a valid value for this point. |
| 86 | CanvasAssertions.assertLineDrawn(htx, xy1, xy2, attrs); |
| 87 | }); |
| 88 | |
| 89 | it('testEdgePointsCustomBars', function() { |
| 90 | var opts = { |
| 91 | width: 480, |
| 92 | height: 320, |
| 93 | labels: ["x", "series1", "series2", "additionalSeries"], |
| 94 | connectSeparatedPoints: true, |
| 95 | dateWindow: [2.5,7.5], |
| 96 | customBars: true |
| 97 | }; |
| 98 | |
| 99 | var data = [ |
| 100 | [0,[4,5,6], [1,2,3], [null, null, null]], |
| 101 | [1,[null,null,null], [2,3,4], [null, null, null]], |
| 102 | [2,[null,null,null], [3,4,5], [null, null, null]], |
| 103 | [3,[0,1,2], [2,3,4], [null, null, null]], |
| 104 | [4,[1,2,3], [2,3,4], [4, 5, 6]], |
| 105 | [5,[1,2,3], [3,4,5], [4, 5, 6]], |
| 106 | [6,[0,1,2], [4,5,6], [5, 6, 7]], |
| 107 | [7,[0,1,2], [4,5,6], [null, null, null]], |
| 108 | [8,[2,3,4], [null,null,null], [null, null, null]], |
| 109 | [9,[0,1,2], [2,4,9], [null, null, null]] |
| 110 | |
| 111 | ]; |
| 112 | |
| 113 | var graph = document.getElementById("graph"); |
| 114 | var g = new Dygraph(graph, data, opts); |
| 115 | |
| 116 | var htx = g.hidden_ctx_; |
| 117 | |
| 118 | var attrs = {}; |
| 119 | |
| 120 | |
| 121 | // Test if values of the series1 are drawn correctly. |
| 122 | // ------------------------------------ |
| 123 | |
| 124 | // The first point of the first series |
| 125 | var x1 = data[0][0]; |
| 126 | var y1 = data[0][1][1]; |
| 127 | var xy1 = g.toDomCoords(x1, y1); |
| 128 | |
| 129 | // The next valid point of this series |
| 130 | var x2 = data[3][0]; |
| 131 | var y2 = data[3][1][1]; |
| 132 | var xy2 = g.toDomCoords(x2, y2); |
| 133 | |
| 134 | // Check if both points are connected at the left edge of the canvas and if the option "connectSeparatedPoints" works properly |
| 135 | // even if the point is outside the visible range and only one series has a valid value for this point. |
| 136 | CanvasAssertions.assertLineDrawn(htx, xy1, xy2, attrs); |
| 137 | |
| 138 | // Test if the custom bars of the series1 are drawn correctly |
| 139 | // -------------------------------------------- |
| 140 | |
| 141 | // The first min-point of this series |
| 142 | x1 = data[0][0]; |
| 143 | y1 = data[0][1][0]; |
| 144 | xy1 = g.toDomCoords(x1, y1); |
| 145 | |
| 146 | // The next valid min-point of the second series. |
| 147 | x2 = data[3][0]; |
| 148 | y2 = data[3][1][0]; |
| 149 | xy2 = g.toDomCoords(x2, y2); |
| 150 | |
| 151 | // Check if both points are connected at the left edge of the canvas and if the option "connectSeparatedPoints" works properly |
| 152 | // even if the point is outside the visible range and only one series has a valid value for this point. |
| 153 | CanvasAssertions.assertLineDrawn(htx, xy1, xy2, attrs); |
| 154 | |
| 155 | // The first max-point of this series |
| 156 | x1 = data[0][0]; |
| 157 | y1 = data[0][1][2]; |
| 158 | xy1 = g.toDomCoords(x1, y1); |
| 159 | |
| 160 | // The next valid max-point of the second series. |
| 161 | x2 = data[3][0]; |
| 162 | y2 = data[3][1][2]; |
| 163 | xy2 = g.toDomCoords(x2, y2); |
| 164 | |
| 165 | // Check if both points are connected at the left edge of the canvas and if the option "connectSeparatedPoints" works properly |
| 166 | // even if the point is outside the visible range and only one series has a valid value for this point. |
| 167 | CanvasAssertions.assertLineDrawn(htx, xy1, xy2, attrs); |
| 168 | |
| 169 | // Test if values of the series2 are drawn correctly. |
| 170 | // ------------------------------------ |
| 171 | |
| 172 | // The last point of the second series. |
| 173 | var x2 = data[9][0]; |
| 174 | var y2 = data[9][2][1]; |
| 175 | var xy2 = g.toDomCoords(x2, y2); |
| 176 | |
| 177 | // The previous valid point of this series |
| 178 | var x1 = data[7][0]; |
| 179 | var y1 = data[7][2][1]; |
| 180 | var xy1 = g.toDomCoords(x1, y1); |
| 181 | |
| 182 | // Check if both points are connected at the right edge of the canvas and if the option "connectSeparatedPoints" works properly |
| 183 | // even if the point is outside the visible range and only one series has a valid value for this point. |
| 184 | CanvasAssertions.assertLineDrawn(htx, xy1, xy2, attrs); |
| 185 | |
| 186 | // Test if the custom bars of the series2 are drawn correctly |
| 187 | // -------------------------------------------- |
| 188 | |
| 189 | // The last min-point of the second series. |
| 190 | x2 = data[9][0]; |
| 191 | y2 = data[9][2][0]; |
| 192 | xy2 = g.toDomCoords(x2, y2); |
| 193 | |
| 194 | // The previous valid min-point of this series |
| 195 | x1 = data[7][0]; |
| 196 | y1 = data[7][2][0]; |
| 197 | xy1 = g.toDomCoords(x1, y1); |
| 198 | |
| 199 | // Check if both points are connected at the right edge of the canvas and if the option "connectSeparatedPoints" works properly |
| 200 | // even if the point is outside the visible range and only one series has a valid value for this point. |
| 201 | CanvasAssertions.assertLineDrawn(htx, xy1, xy2, attrs); |
| 202 | |
| 203 | // The last max-point of the second series. |
| 204 | x2 = data[9][0]; |
| 205 | y2 = data[9][2][2]; |
| 206 | xy2 = g.toDomCoords(x2, y2); |
| 207 | |
| 208 | // The previous valid max-point of this series |
| 209 | x1 = data[7][0]; |
| 210 | y1 = data[7][2][2]; |
| 211 | xy1 = g.toDomCoords(x1, y1); |
| 212 | |
| 213 | // Check if both points are connected at the right edge of the canvas and if the option "connectSeparatedPoints" works properly |
| 214 | // even if the point is outside the visible range and only one series has a valid value for this point. |
| 215 | CanvasAssertions.assertLineDrawn(htx, xy1, xy2, attrs); |
| 216 | }); |
| 217 | |
| 218 | it('testEdgePointsErrorBars', function() { |
| 219 | var opts = { |
| 220 | width: 480, |
| 221 | height: 320, |
| 222 | labels: ["x", "series1", "series2", "seriesTestHelper"], |
| 223 | connectSeparatedPoints: true, |
| 224 | dateWindow: [2,7.5], |
| 225 | errorBars: true |
| 226 | |
| 227 | }; |
| 228 | |
| 229 | var data = [ |
| 230 | [0,[5,1], [2,1], [null,null]], |
| 231 | [1,[null,null], [3,1], [null,null]], |
| 232 | [2,[null,null], [4,1], [null,null]], |
| 233 | [3,[1,1], [3,1], [null,null]], |
| 234 | [4,[2,1], [3,1], [5,1]], |
| 235 | [5,[2,1], [4,1], [5,1]], |
| 236 | [6,[1,1], [5,1], [6,1]], |
| 237 | [7,[1,1], [5,1], [null,null]], |
| 238 | [8,[3,1], [null,null], [null,null]], |
| 239 | [9,[1,1], [4,1], [null,null]] |
| 240 | |
| 241 | ]; |
| 242 | |
| 243 | var graph = document.getElementById("graph"); |
| 244 | var g = new Dygraph(graph, data, opts); |
| 245 | |
| 246 | var htx = g.hidden_ctx_; |
| 247 | |
| 248 | var attrs = {}; |
| 249 | |
| 250 | |
| 251 | // Test if values of the series1 are drawn correctly. |
| 252 | // ------------------------------------ |
| 253 | |
| 254 | // The first point of the first series |
| 255 | var x1 = data[0][0]; |
| 256 | var y1 = data[0][1][0]; |
| 257 | var xy1 = g.toDomCoords(x1, y1); |
| 258 | |
| 259 | // The next valid point of this series |
| 260 | var x2 = data[3][0]; |
| 261 | var y2 = data[3][1][0]; |
| 262 | var xy2 = g.toDomCoords(x2, y2); |
| 263 | |
| 264 | // Check if both points are connected at the left edge of the canvas and if the option "connectSeparatedPoints" works properly |
| 265 | // even if the point is outside the visible range and only one series has a valid value for this point. |
| 266 | CanvasAssertions.assertLineDrawn(htx, xy1, xy2, attrs); |
| 267 | |
| 268 | // Test if the upper error bars of series1 are drawn correctly |
| 269 | // -------------------------------------------- |
| 270 | |
| 271 | // The first upper error-point of this series |
| 272 | x1 = data[0][0]; |
| 273 | var y1error = y1 + (data[0][1][1]*2); |
| 274 | xy1 = g.toDomCoords(x1, y1error); |
| 275 | |
| 276 | // The next valid upper error-point of the second series. |
| 277 | x2 = data[3][0]; |
| 278 | var y2error = y2 + (data[3][1][1]*2); |
| 279 | xy2 = g.toDomCoords(x2, y2error); |
| 280 | |
| 281 | // Check if both points are connected at the left edge of the canvas and if the option "connectSeparatedPoints" works properly |
| 282 | // even if the point is outside the visible range and only one series has a valid value for this point. |
| 283 | CanvasAssertions.assertLineDrawn(htx, xy1, xy2, attrs); |
| 284 | |
| 285 | // Test if the lower error bars of series1 are drawn correctly |
| 286 | // -------------------------------------------- |
| 287 | |
| 288 | // The first lower error-point of this series |
| 289 | x1 = data[0][0]; |
| 290 | y1error = y1 - (data[0][1][1]*2); |
| 291 | xy1 = g.toDomCoords(x1, y1error); |
| 292 | |
| 293 | //The next valid lower error-point of the second series. |
| 294 | x2 = data[3][0]; |
| 295 | y2error = y2 - (data[3][1][1]*2); |
| 296 | xy2 = g.toDomCoords(x2, y2error); |
| 297 | |
| 298 | // Check if both points are connected at the left edge of the canvas and if the option "connectSeparatedPoints" works properly |
| 299 | // even if the point is outside the visible range and only one series has a valid value for this point. |
| 300 | CanvasAssertions.assertLineDrawn(htx, xy1, xy2, attrs); |
| 301 | |
| 302 | |
| 303 | // Test if values of the series2 are drawn correctly. |
| 304 | // ------------------------------------ |
| 305 | |
| 306 | // The last point of this series |
| 307 | x2 = data[9][0]; |
| 308 | y2 = data[9][2][0]; |
| 309 | xy2 = g.toDomCoords(x2, y2); |
| 310 | |
| 311 | // The previous valid point of the first series |
| 312 | x1 = data[7][0]; |
| 313 | y1 = data[7][2][0]; |
| 314 | xy1 = g.toDomCoords(x1, y1); |
| 315 | |
| 316 | // Check if both points are connected at the right edge of the canvas and if the option "connectSeparatedPoints" works properly |
| 317 | // even if the point is outside the visible range and only one series has a valid value for this point. |
| 318 | CanvasAssertions.assertLineDrawn(htx, xy1, xy2, attrs); |
| 319 | |
| 320 | // Test if the upper error bars of series2 are drawn correctly |
| 321 | // -------------------------------------------- |
| 322 | |
| 323 | // The last upper error-point of the second series. |
| 324 | x2 = data[9][0]; |
| 325 | var y2error = y2 + (data[9][2][1]*2); |
| 326 | xy2 = g.toDomCoords(x2, y2error); |
| 327 | |
| 328 | // The previous valid upper error-point of this series |
| 329 | x1 = data[7][0]; |
| 330 | var y1error = y1 + (data[7][2][1]*2); |
| 331 | xy1 = g.toDomCoords(x1, y1error); |
| 332 | |
| 333 | // Check if both points are connected at the right edge of the canvas and if the option "connectSeparatedPoints" works properly |
| 334 | // even if the point is outside the visible range and only one series has a valid value for this point. |
| 335 | CanvasAssertions.assertLineDrawn(htx, xy1, xy2, attrs); |
| 336 | |
| 337 | // Test if the lower error bars of series1 are drawn correctly |
| 338 | // -------------------------------------------- |
| 339 | |
| 340 | // The last lower error-point of the second series. |
| 341 | x2 = data[9][0]; |
| 342 | y2error = y2 - (data[9][2][1]*2); |
| 343 | xy2 = g.toDomCoords(x2, y2error); |
| 344 | |
| 345 | // The previous valid lower error-point of this series |
| 346 | x1 = data[7][0]; |
| 347 | y1error = y1 - (data[7][2][1]*2); |
| 348 | xy1 = g.toDomCoords(x1, y1error); |
| 349 | |
| 350 | // Check if both points are connected at the right edge of the canvas and if the option "connectSeparatedPoints" works properly |
| 351 | // even if the point is outside the visible range and only one series has a valid value for this point. |
| 352 | CanvasAssertions.assertLineDrawn(htx, xy1, xy2, attrs); |
| 353 | }); |
| 354 | |
| 355 | it('testConnectSeparatedPointsPerSeries', function() { |
| 356 | var assertExpectedLinesDrawnPerSeries = function(htx, expectedSeries1, expectedSeries2, expectedSeries3) { |
| 357 | var expected = [expectedSeries1, expectedSeries2, expectedSeries3]; |
| 358 | var actual = [ |
| 359 | CanvasAssertions.numLinesDrawn(htx, "#ff0000"), |
| 360 | CanvasAssertions.numLinesDrawn(htx, "#00ff00"), |
| 361 | CanvasAssertions.numLinesDrawn(htx, "#0000ff")]; |
| 362 | assert.deepEqual(expected, actual); |
| 363 | } |
| 364 | |
| 365 | var g = new Dygraph(document.getElementById("graph"), |
| 366 | [ |
| 367 | [1, 10, 10, 10], |
| 368 | [2, 15, 11, 12], |
| 369 | [3, null, null, 12], |
| 370 | [4, 20, 14, null], |
| 371 | [5, 15, null, 17], |
| 372 | [6, 18, null, null], |
| 373 | [7, 12, 14, null] |
| 374 | ], |
| 375 | { |
| 376 | labels: ["Date","Series1","Series2","Series3"], |
| 377 | connectSeparatedPoints: false, |
| 378 | colors: ["#ff0000", "#00ff00", "#0000ff"] |
| 379 | }); |
| 380 | |
| 381 | var htx = g.hidden_ctx_; |
| 382 | assertExpectedLinesDrawnPerSeries(htx, 4, 1, 2); |
| 383 | |
| 384 | Proxy.reset(htx); |
| 385 | g.updateOptions({ |
| 386 | connectSeparatedPoints : true, |
| 387 | }); |
| 388 | assertExpectedLinesDrawnPerSeries(htx, 5, 3, 3); |
| 389 | |
| 390 | Proxy.reset(htx); |
| 391 | g.updateOptions({ |
| 392 | connectSeparatedPoints : false, |
| 393 | series : { |
| 394 | Series1 : { connectSeparatedPoints : true } |
| 395 | } |
| 396 | }); |
| 397 | assertExpectedLinesDrawnPerSeries(htx, 5, 1, 2); |
| 398 | |
| 399 | |
| 400 | Proxy.reset(htx); |
| 401 | g.updateOptions({ |
| 402 | connectSeparatedPoints : true, |
| 403 | series : { |
| 404 | Series1 : { connectSeparatedPoints : false } |
| 405 | } |
| 406 | }); |
| 407 | assertExpectedLinesDrawnPerSeries(htx, 4, 3, 3); |
| 408 | }); |
| 409 | |
| 410 | it('testNaNErrorBars', function() { |
| 411 | var data = [ |
| 412 | [0,[1,2,3]], |
| 413 | [1,[2,3,4]], |
| 414 | [2,[3,4,5]], |
| 415 | [3,[null,null,null]], |
| 416 | [4,[2,3,4]], |
| 417 | [5,[3,4,5]], |
| 418 | [6,[2,3,4]], |
| 419 | [7,[NaN,NaN,NaN]], |
| 420 | [8,[2,3,4]], |
| 421 | [9,[2,3,4]], |
| 422 | [10,[2,3,4]], |
| 423 | [11,[2,3,4]] |
| 424 | ]; |
| 425 | |
| 426 | var opts = { |
| 427 | labels: ["x", "y"], |
| 428 | colors: ["#ff0000"], |
| 429 | customBars: true, |
| 430 | connectSeparatedPoints: true |
| 431 | }; |
| 432 | |
| 433 | var graph = document.getElementById("graph"); |
| 434 | var g = new Dygraph(graph, data, opts); |
| 435 | |
| 436 | var htx = g.hidden_ctx_; |
| 437 | |
| 438 | var attrs = {}; |
| 439 | |
| 440 | // Line should be drawn across the null gap. |
| 441 | CanvasAssertions.assertLineDrawn(htx, |
| 442 | g.toDomCoords(data[2][0], data[2][1][1]), |
| 443 | g.toDomCoords(data[4][0], data[4][1][1]), |
| 444 | attrs); |
| 445 | |
| 446 | // No line across the NaN gap, and a single line (not two) |
| 447 | // across the null gap. |
| 448 | assert.equal(8, CanvasAssertions.numLinesDrawn(htx, '#ff0000')); |
| 449 | }); |
| 450 | |
| 451 | }); |