<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[212997] trunk/Websites/perf.webkit.org</title>
</head>
<body>
<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; }
#msg dl a { font-weight: bold}
#msg dl a:link { color:#fc3; }
#msg dl a:active { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/212997">212997</a></dd>
<dt>Author</dt> <dd>rniwa@webkit.org</dd>
<dt>Date</dt> <dd>2017-02-25 00:02:02 -0800 (Sat, 25 Feb 2017)</dd>
</dl>
<h3>Log Message</h3>
<pre>REGRESSION(<a href="http://trac.webkit.org/projects/webkit/changeset/212853">r212853</a>): Comparisons to baseline no longer shows up
https://bugs.webkit.org/show_bug.cgi?id=168863
Reviewed by Joseph Pecoraro.
The bug was caused by ChartStatusView's code not being updated to use TimeSeriesView's.
Updated the code to use TimeSeriesView's methods to fix the bug.
Also made InteractiveTimeSeriesChart's currentPoint to return a (TimeSeriesView, point, isLocked) tuple
to consolidate it with lockedIndicator() to work towards making the baseline data points selectable.
* browser-tests/time-series-chart-tests.js: Updated the test cases to use currentIndicator, and added
test cases for newly added lastPointInTimeRange.
* public/v3/components/chart-pane.js:
(ChartPane.prototype.serializeState): Updated to use currentIndicator.
(ChartPane.prototype._renderFilteringPopover): Ditto.
* public/v3/components/chart-status-view.js:
(ChartStatusView.prototype.updateStatusIfNeeded): Use currentIndicator for an interative time series.
Fixed the non-interactive chart's code path for TimeSeriesView.
(ChartStatusView.prototype._computeChartStatus): Modernized the code.
(ChartStatusView.prototype._findLastPointPriorToTime): Deleted. Replaced by TimeSeriesView's
lastPointInTimeRange.
* public/v3/components/interactive-time-series-chart.js:
(InteractiveTimeSeriesChart.prototype.currentIndicator):
(InteractiveTimeSeriesChart.prototype.moveLockedIndicatorWithNotification):
(InteractiveTimeSeriesChart.prototype._renderChartContent):
(InteractiveTimeSeriesChart):
* public/v3/models/time-series.js:
(TimeSeriesView.prototype.lastPointInTimeRange): Added.
(TimeSeriesView.prototype._reverse): Added. Traverses the view in the reverse order.
* unit-tests/time-series-tests.js:</pre>
<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkWebsitesperfwebkitorgChangeLog">trunk/Websites/perf.webkit.org/ChangeLog</a></li>
<li><a href="#trunkWebsitesperfwebkitorgbrowserteststimeseriescharttestsjs">trunk/Websites/perf.webkit.org/browser-tests/time-series-chart-tests.js</a></li>
<li><a href="#trunkWebsitesperfwebkitorgpublicv3componentschartstatusviewjs">trunk/Websites/perf.webkit.org/public/v3/components/chart-status-view.js</a></li>
<li><a href="#trunkWebsitesperfwebkitorgpublicv3componentsinteractivetimeserieschartjs">trunk/Websites/perf.webkit.org/public/v3/components/interactive-time-series-chart.js</a></li>
<li><a href="#trunkWebsitesperfwebkitorgpublicv3modelstimeseriesjs">trunk/Websites/perf.webkit.org/public/v3/models/time-series.js</a></li>
<li><a href="#trunkWebsitesperfwebkitorgpublicv3pageschartpanejs">trunk/Websites/perf.webkit.org/public/v3/pages/chart-pane.js</a></li>
<li><a href="#trunkWebsitesperfwebkitorgunitteststimeseriestestsjs">trunk/Websites/perf.webkit.org/unit-tests/time-series-tests.js</a></li>
</ul>
</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkWebsitesperfwebkitorgChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Websites/perf.webkit.org/ChangeLog (212996 => 212997)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Websites/perf.webkit.org/ChangeLog        2017-02-25 07:53:35 UTC (rev 212996)
+++ trunk/Websites/perf.webkit.org/ChangeLog        2017-02-25 08:02:02 UTC (rev 212997)
</span><span class="lines">@@ -1,3 +1,41 @@
</span><ins>+2017-02-24 Ryosuke Niwa <rniwa@webkit.org>
+
+ REGRESSION(r212853): Comparisons to baseline no longer shows up
+ https://bugs.webkit.org/show_bug.cgi?id=168863
+
+ Reviewed by Joseph Pecoraro.
+
+ The bug was caused by ChartStatusView's code not being updated to use TimeSeriesView's.
+ Updated the code to use TimeSeriesView's methods to fix the bug.
+
+ Also made InteractiveTimeSeriesChart's currentPoint to return a (TimeSeriesView, point, isLocked) tuple
+ to consolidate it with lockedIndicator() to work towards making the baseline data points selectable.
+
+ * browser-tests/time-series-chart-tests.js: Updated the test cases to use currentIndicator, and added
+ test cases for newly added lastPointInTimeRange.
+
+ * public/v3/components/chart-pane.js:
+ (ChartPane.prototype.serializeState): Updated to use currentIndicator.
+ (ChartPane.prototype._renderFilteringPopover): Ditto.
+
+ * public/v3/components/chart-status-view.js:
+ (ChartStatusView.prototype.updateStatusIfNeeded): Use currentIndicator for an interative time series.
+ Fixed the non-interactive chart's code path for TimeSeriesView.
+ (ChartStatusView.prototype._computeChartStatus): Modernized the code.
+ (ChartStatusView.prototype._findLastPointPriorToTime): Deleted. Replaced by TimeSeriesView's
+ lastPointInTimeRange.
+
+ * public/v3/components/interactive-time-series-chart.js:
+ (InteractiveTimeSeriesChart.prototype.currentIndicator):
+ (InteractiveTimeSeriesChart.prototype.moveLockedIndicatorWithNotification):
+ (InteractiveTimeSeriesChart.prototype._renderChartContent):
+ (InteractiveTimeSeriesChart):
+
+ * public/v3/models/time-series.js:
+ (TimeSeriesView.prototype.lastPointInTimeRange): Added.
+ (TimeSeriesView.prototype._reverse): Added. Traverses the view in the reverse order.
+ * unit-tests/time-series-tests.js:
+
</ins><span class="cx"> 2017-02-23 Dewei Zhu <dewei_zhu@apple.com>
</span><span class="cx">
</span><span class="cx"> Rename 'commit_parent' in 'commits' table to 'commit_previous_commit'.
</span></span></pre></div>
<a id="trunkWebsitesperfwebkitorgbrowserteststimeseriescharttestsjs"></a>
<div class="modfile"><h4>Modified: trunk/Websites/perf.webkit.org/browser-tests/time-series-chart-tests.js (212996 => 212997)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Websites/perf.webkit.org/browser-tests/time-series-chart-tests.js        2017-02-25 07:53:35 UTC (rev 212996)
+++ trunk/Websites/perf.webkit.org/browser-tests/time-series-chart-tests.js        2017-02-25 08:02:02 UTC (rev 212997)
</span><span class="lines">@@ -1,3 +1,5 @@
</span><ins>+(() => {
+
</ins><span class="cx"> const scripts = [
</span><span class="cx"> '../shared/statistics.js',
</span><span class="cx"> 'instrumentation.js',
</span><span class="lines">@@ -923,7 +925,7 @@
</span><span class="cx">
</span><span class="cx"> describe('InteractiveTimeSeriesChart', () => {
</span><span class="cx">
</span><del>- it('should change the indicator to the point closest to the last mouse move position', () => {
</del><ins>+ it('should change the unlocked indicator to the point closest to the last mouse move position', () => {
</ins><span class="cx"> const context = new BrowsingContext();
</span><span class="cx"> return context.importScripts(scripts, 'ComponentBase', 'TimeSeriesChart', 'InteractiveTimeSeriesChart', 'MeasurementSet', 'MockRemoteAPI').then(() => {
</span><span class="cx"> const chart = createChartWithSampleCluster(context, {}, {interactiveChart: true, interactive: true});
</span><span class="lines">@@ -941,8 +943,7 @@
</span><span class="cx"> let canvas;
</span><span class="cx"> return waitForComponentsToRender(context).then(() => {
</span><span class="cx"> expect(chart.currentSelection()).to.be(null);
</span><del>- expect(chart.currentPoint()).to.be(null);
- expect(chart.lockedIndicator()).to.be(null);
</del><ins>+ expect(chart.currentIndicator()).to.be(null);
</ins><span class="cx"> expect(indicatorChangeCalls).to.be.eql([]);
</span><span class="cx">
</span><span class="cx"> canvas = chart.content().querySelector('canvas');
</span><span class="lines">@@ -955,10 +956,13 @@
</span><span class="cx"> expect(CanvasTest.hasCanvasBeenRedrawn(canvas)).to.be(true);
</span><span class="cx">
</span><span class="cx"> expect(chart.currentSelection()).to.be(null);
</span><del>- expect(chart.currentPoint()).to.not.be(null);
- expect(chart.lockedIndicator()).to.be(null);
- const lastPoint = chart.sampledTimeSeriesData('current').lastPoint();
- expect(chart.currentPoint()).to.be(lastPoint);
</del><ins>+ const indicator = chart.currentIndicator();
+ expect(indicator).to.not.be(null);
+ const currentView = chart.sampledTimeSeriesData('current');
+ const lastPoint = currentView.lastPoint();
+ expect(indicator.view).to.be(currentView);
+ expect(indicator.point).to.be(lastPoint);
+ expect(indicator.isLocked).to.be(false);
</ins><span class="cx"> expect(indicatorChangeCalls).to.be.eql([[lastPoint.id, false]]);
</span><span class="cx">
</span><span class="cx"> expect(selectionChangeCount).to.be(0);
</span><span class="lines">@@ -984,8 +988,7 @@
</span><span class="cx"> let canvas;
</span><span class="cx"> return waitForComponentsToRender(context).then(() => {
</span><span class="cx"> expect(chart.currentSelection()).to.be(null);
</span><del>- expect(chart.currentPoint()).to.be(null);
- expect(chart.lockedIndicator()).to.be(null);
</del><ins>+ expect(chart.currentIndicator()).to.be(null);
</ins><span class="cx"> expect(indicatorChangeCalls).to.be.eql([]);
</span><span class="cx"> canvas = chart.content().querySelector('canvas');
</span><span class="cx"> const rect = canvas.getBoundingClientRect();
</span><span class="lines">@@ -1003,10 +1006,13 @@
</span><span class="cx"> }).then(() => {
</span><span class="cx"> expect(CanvasTest.hasCanvasBeenRedrawn(canvas)).to.be(true);
</span><span class="cx">
</span><del>- const lastPoint = chart.sampledTimeSeriesData('current').lastPoint();
</del><ins>+ const currentView = chart.sampledTimeSeriesData('current');
+ const lastPoint = currentView.lastPoint();
</ins><span class="cx"> expect(chart.currentSelection()).to.be(null);
</span><del>- expect(chart.currentPoint()).to.be(lastPoint);
- expect(chart.lockedIndicator()).to.be(lastPoint);
</del><ins>+ const indicator = chart.currentIndicator();
+ expect(indicator.view).to.be(currentView);
+ expect(indicator.point).to.be(lastPoint);
+ expect(indicator.isLocked).to.be(true);
</ins><span class="cx"> expect(indicatorChangeCalls).to.be.eql([[lastPoint.id, false], [lastPoint.id, true]]);
</span><span class="cx">
</span><span class="cx"> expect(selectionChangeCount).to.be(0);
</span><span class="lines">@@ -1034,8 +1040,7 @@
</span><span class="cx"> let lastPoint;
</span><span class="cx"> return waitForComponentsToRender(context).then(() => {
</span><span class="cx"> expect(chart.currentSelection()).to.be(null);
</span><del>- expect(chart.currentPoint()).to.be(null);
- expect(chart.lockedIndicator()).to.be(null);
</del><ins>+ expect(chart.currentIndicator()).to.be(null);
</ins><span class="cx"> expect(indicatorChangeCalls).to.be.eql([]);
</span><span class="cx">
</span><span class="cx"> canvas = chart.content().querySelector('canvas');
</span><span class="lines">@@ -1047,10 +1052,13 @@
</span><span class="cx"> }).then(() => {
</span><span class="cx"> expect(CanvasTest.hasCanvasBeenRedrawn(canvas)).to.be(true);
</span><span class="cx">
</span><del>- lastPoint = chart.sampledTimeSeriesData('current').lastPoint();
</del><ins>+ const currentView = chart.sampledTimeSeriesData('current');
+ lastPoint = currentView.lastPoint();
</ins><span class="cx"> expect(chart.currentSelection()).to.be(null);
</span><del>- expect(chart.currentPoint()).to.be(lastPoint);
- expect(chart.lockedIndicator()).to.be(null);
</del><ins>+ const indicator = chart.currentIndicator();
+ expect(indicator.view).to.be(currentView);
+ expect(indicator.point).to.be(lastPoint);
+ expect(indicator.isLocked).to.be(false);
</ins><span class="cx"> expect(indicatorChangeCalls).to.be.eql([[lastPoint.id, false]]);
</span><span class="cx">
</span><span class="cx"> canvas.parentNode.dispatchEvent(new MouseEvent('mousemove', {target: canvas, clientX: rect.right + 50, clientY: rect.bottom + 50, composed: true, bubbles: true}));
</span><span class="lines">@@ -1062,8 +1070,7 @@
</span><span class="cx"> expect(CanvasTest.hasCanvasBeenRedrawn(canvas)).to.be(true);
</span><span class="cx">
</span><span class="cx"> expect(chart.currentSelection()).to.be(null);
</span><del>- expect(chart.currentPoint()).to.be(null);
- expect(chart.lockedIndicator()).to.be(null);
</del><ins>+ expect(chart.currentIndicator()).to.be(null);
</ins><span class="cx"> expect(indicatorChangeCalls).to.be.eql([[lastPoint.id, false], [null, false]]);
</span><span class="cx">
</span><span class="cx"> expect(selectionChangeCount).to.be(0);
</span><span class="lines">@@ -1088,11 +1095,11 @@
</span><span class="cx">
</span><span class="cx"> let canvas;
</span><span class="cx"> let rect;
</span><ins>+ let currentView;
</ins><span class="cx"> let lastPoint;
</span><span class="cx"> return waitForComponentsToRender(context).then(() => {
</span><span class="cx"> expect(chart.currentSelection()).to.be(null);
</span><del>- expect(chart.currentPoint()).to.be(null);
- expect(chart.lockedIndicator()).to.be(null);
</del><ins>+ expect(chart.currentIndicator()).to.be(null);
</ins><span class="cx"> expect(indicatorChangeCalls).to.be.eql([]);
</span><span class="cx">
</span><span class="cx"> canvas = chart.content().querySelector('canvas');
</span><span class="lines">@@ -1104,10 +1111,13 @@
</span><span class="cx"> }).then(() => {
</span><span class="cx"> expect(CanvasTest.hasCanvasBeenRedrawn(canvas)).to.be(true);
</span><span class="cx">
</span><del>- lastPoint = chart.sampledTimeSeriesData('current').lastPoint();
</del><ins>+ currentView = chart.sampledTimeSeriesData('current');
+ lastPoint = currentView.lastPoint();
</ins><span class="cx"> expect(chart.currentSelection()).to.be(null);
</span><del>- expect(chart.currentPoint()).to.be(lastPoint);
- expect(chart.lockedIndicator()).to.be(lastPoint);
</del><ins>+ const indicator = chart.currentIndicator();
+ expect(indicator.view).to.be(currentView);
+ expect(indicator.point).to.be(lastPoint);
+ expect(indicator.isLocked).to.be(true);
</ins><span class="cx"> expect(indicatorChangeCalls).to.be.eql([[lastPoint.id, true]]);
</span><span class="cx">
</span><span class="cx"> canvas.parentNode.dispatchEvent(new MouseEvent('mousemove', {target: canvas, clientX: rect.right + 50, clientY: rect.bottom + 50, composed: true, bubbles: true}));
</span><span class="lines">@@ -1119,8 +1129,10 @@
</span><span class="cx"> expect(CanvasTest.hasCanvasBeenRedrawn(canvas)).to.be(false);
</span><span class="cx">
</span><span class="cx"> expect(chart.currentSelection()).to.be(null);
</span><del>- expect(chart.currentPoint()).to.be(lastPoint);
- expect(chart.lockedIndicator()).to.be(lastPoint);
</del><ins>+ const indicator = chart.currentIndicator();
+ expect(indicator.view).to.be(currentView);
+ expect(indicator.point).to.be(lastPoint);
+ expect(indicator.isLocked).to.be(true);
</ins><span class="cx"> expect(indicatorChangeCalls).to.be.eql([[lastPoint.id, true]]);
</span><span class="cx">
</span><span class="cx"> expect(selectionChangeCount).to.be(0);
</span><span class="lines">@@ -1146,11 +1158,11 @@
</span><span class="cx"> let canvas;
</span><span class="cx"> let rect;
</span><span class="cx"> let y;
</span><ins>+ let currentView;
</ins><span class="cx"> let lastPoint;
</span><span class="cx"> return waitForComponentsToRender(context).then(() => {
</span><span class="cx"> expect(chart.currentSelection()).to.be(null);
</span><del>- expect(chart.currentPoint()).to.be(null);
- expect(chart.lockedIndicator()).to.be(null);
</del><ins>+ expect(chart.currentIndicator()).to.be(null);
</ins><span class="cx"> expect(indicatorChangeCalls).to.be.eql([]);
</span><span class="cx">
</span><span class="cx"> canvas = chart.content().querySelector('canvas');
</span><span class="lines">@@ -1163,10 +1175,13 @@
</span><span class="cx"> }).then(() => {
</span><span class="cx"> expect(CanvasTest.hasCanvasBeenRedrawn(canvas)).to.be(true);
</span><span class="cx">
</span><del>- lastPoint = chart.sampledTimeSeriesData('current').lastPoint();
</del><ins>+ currentView = chart.sampledTimeSeriesData('current');
+ lastPoint = currentView.lastPoint();
</ins><span class="cx"> expect(chart.currentSelection()).to.be(null);
</span><del>- expect(chart.currentPoint()).to.be(lastPoint);
- expect(chart.lockedIndicator()).to.be(lastPoint);
</del><ins>+ const indicator = chart.currentIndicator();
+ expect(indicator.view).to.be(currentView);
+ expect(indicator.point).to.be(lastPoint);
+ expect(indicator.isLocked).to.be(true);
</ins><span class="cx"> expect(indicatorChangeCalls).to.be.eql([[lastPoint.id, true]]);
</span><span class="cx">
</span><span class="cx"> canvas.dispatchEvent(new MouseEvent('click', {target: canvas, clientX: rect.left + 1, clientY: y, composed: true, bubbles: true}));
</span><span class="lines">@@ -1177,9 +1192,11 @@
</span><span class="cx"> expect(CanvasTest.hasCanvasBeenRedrawn(canvas)).to.be(true);
</span><span class="cx">
</span><span class="cx"> expect(chart.currentSelection()).to.be(null);
</span><del>- const firstPoint = chart.sampledTimeSeriesData('current').firstPoint();
- expect(chart.currentPoint()).to.be(firstPoint);
- expect(chart.lockedIndicator()).to.be(null);
</del><ins>+ const firstPoint = currentView.firstPoint();
+ const indicator = chart.currentIndicator();
+ expect(indicator.view).to.be(currentView);
+ expect(indicator.point).to.be(firstPoint);
+ expect(indicator.isLocked).to.be(false);
</ins><span class="cx"> expect(indicatorChangeCalls).to.be.eql([[lastPoint.id, true], [firstPoint.id, false]]);
</span><span class="cx">
</span><span class="cx"> expect(selectionChangeCount).to.be(0);
</span><span class="lines">@@ -1209,13 +1226,13 @@
</span><span class="cx"> let canvas;
</span><span class="cx"> let rect;
</span><span class="cx"> let y;
</span><ins>+ let currentView;
</ins><span class="cx"> let firstPoint;
</span><span class="cx"> let oldRange;
</span><span class="cx"> let newRange;
</span><span class="cx"> return waitForComponentsToRender(context).then(() => {
</span><span class="cx"> expect(chart.currentSelection()).to.be(null);
</span><del>- expect(chart.currentPoint()).to.be(null);
- expect(chart.lockedIndicator()).to.be(null);
</del><ins>+ expect(chart.currentIndicator()).to.be(null);
</ins><span class="cx"> expect(selectionChangeCalls).to.be.eql([]);
</span><span class="cx">
</span><span class="cx"> canvas = chart.content().querySelector('canvas');
</span><span class="lines">@@ -1228,10 +1245,13 @@
</span><span class="cx"> }).then(() => {
</span><span class="cx"> expect(CanvasTest.hasCanvasBeenRedrawn(canvas)).to.be(true);
</span><span class="cx">
</span><del>- firstPoint = chart.sampledTimeSeriesData('current').firstPoint();
</del><ins>+ currentView = chart.sampledTimeSeriesData('current');
+ firstPoint = currentView.firstPoint();
</ins><span class="cx"> expect(chart.currentSelection()).to.be(null);
</span><del>- expect(chart.currentPoint()).to.be(firstPoint);
- expect(chart.lockedIndicator()).to.be(null);
</del><ins>+ let indicator = chart.currentIndicator();
+ expect(indicator.view).to.be(currentView);
+ expect(indicator.point).to.be(firstPoint);
+ expect(indicator.isLocked).to.be(false);
</ins><span class="cx"> expect(indicatorChangeCalls).to.be.eql([[firstPoint.id, false]]);
</span><span class="cx"> expect(zoomButton.offsetHeight).to.be(0);
</span><span class="cx">
</span><span class="lines">@@ -1243,8 +1263,10 @@
</span><span class="cx"> expect(CanvasTest.hasCanvasBeenRedrawn(canvas)).to.be(false);
</span><span class="cx">
</span><span class="cx"> expect(chart.currentSelection()).to.be(null);
</span><del>- expect(chart.currentPoint()).to.be(firstPoint);
- expect(chart.lockedIndicator()).to.be(null);
</del><ins>+ let indicator = chart.currentIndicator();
+ expect(indicator.view).to.be(currentView);
+ expect(indicator.point).to.be(firstPoint);
+ expect(indicator.isLocked).to.be(false);
</ins><span class="cx"> expect(selectionChangeCalls).to.be.eql([]);
</span><span class="cx"> expect(indicatorChangeCalls).to.be.eql([[firstPoint.id, false]]);
</span><span class="cx"> expect(zoomButton.offsetHeight).to.be(0);
</span><span class="lines">@@ -1257,8 +1279,7 @@
</span><span class="cx"> expect(CanvasTest.hasCanvasBeenRedrawn(canvas)).to.be(true);
</span><span class="cx">
</span><span class="cx"> expect(chart.currentSelection()).to.not.be(null);
</span><del>- expect(chart.currentPoint()).to.be(null);
- expect(chart.lockedIndicator()).to.be(null);
</del><ins>+ expect(chart.currentIndicator()).to.be(null);
</ins><span class="cx"> expect(selectionChangeCalls.length).to.be(1);
</span><span class="cx"> oldRange = selectionChangeCalls[0][0];
</span><span class="cx"> expect(oldRange).to.be.eql(chart.currentSelection());
</span><span class="lines">@@ -1274,8 +1295,7 @@
</span><span class="cx"> expect(CanvasTest.hasCanvasBeenRedrawn(canvas)).to.be(true);
</span><span class="cx">
</span><span class="cx"> expect(chart.currentSelection()).to.not.be(null);
</span><del>- expect(chart.currentPoint()).to.be(null);
- expect(chart.lockedIndicator()).to.be(null);
</del><ins>+ expect(chart.currentIndicator()).to.be(null);
</ins><span class="cx"> expect(selectionChangeCalls.length).to.be(2);
</span><span class="cx"> newRange = selectionChangeCalls[1][0];
</span><span class="cx"> expect(newRange).to.be.eql(chart.currentSelection());
</span><span class="lines">@@ -1293,8 +1313,7 @@
</span><span class="cx"> expect(CanvasTest.hasCanvasBeenRedrawn(canvas)).to.be(true);
</span><span class="cx">
</span><span class="cx"> expect(chart.currentSelection()).to.be.eql(newRange);
</span><del>- expect(chart.currentPoint()).to.be(null);
- expect(chart.lockedIndicator()).to.be(null);
</del><ins>+ expect(chart.currentIndicator()).to.be(null);
</ins><span class="cx"> expect(selectionChangeCalls.length).to.be(3);
</span><span class="cx"> expect(selectionChangeCalls[2][0]).to.be.eql(newRange);
</span><span class="cx"> expect(selectionChangeCalls[2][1]).to.be(true);
</span><span class="lines">@@ -1337,8 +1356,7 @@
</span><span class="cx">
</span><span class="cx"> selection = chart.currentSelection();
</span><span class="cx"> expect(selection).to.not.be(null);
</span><del>- expect(chart.currentPoint()).to.be(null);
- expect(chart.lockedIndicator()).to.be(null);
</del><ins>+ expect(chart.currentIndicator()).to.be(null);
</ins><span class="cx"> expect(zoomButton.offsetHeight).to.not.be(0);
</span><span class="cx"> expect(zoomCalls).to.be.eql([]);
</span><span class="cx"> zoomButton.click();
</span><span class="lines">@@ -1383,8 +1401,7 @@
</span><span class="cx"> expect(CanvasTest.hasCanvasBeenRedrawn(canvas)).to.be(true);
</span><span class="cx">
</span><span class="cx"> expect(chart.currentSelection()).to.not.be(null);
</span><del>- expect(chart.currentPoint()).to.be(null);
- expect(chart.lockedIndicator()).to.be(null);
</del><ins>+ expect(chart.currentIndicator()).to.be(null);
</ins><span class="cx">
</span><span class="cx"> canvas.dispatchEvent(new MouseEvent('click', {target: canvas, clientX: rect.left + 1, clientY: y + 5, composed: true, bubbles: true}));
</span><span class="cx">
</span><span class="lines">@@ -1394,8 +1411,11 @@
</span><span class="cx"> expect(CanvasTest.hasCanvasBeenRedrawn(canvas)).to.be(true);
</span><span class="cx">
</span><span class="cx"> expect(chart.currentSelection()).to.be(null);
</span><del>- expect(chart.currentPoint()).to.be(chart.sampledTimeSeriesData('current').firstPoint());
- expect(chart.lockedIndicator()).to.be(null);
</del><ins>+ const currentView = chart.sampledTimeSeriesData('current');
+ const indicator = chart.currentIndicator();
+ expect(indicator.view).to.be(currentView);
+ expect(indicator.point).to.be(currentView.firstPoint());
+ expect(indicator.isLocked).to.be(false);
</ins><span class="cx"> });
</span><span class="cx"> });
</span><span class="cx"> });
</span><span class="lines">@@ -1460,3 +1480,5 @@
</span><span class="cx"> });
</span><span class="cx">
</span><span class="cx"> });
</span><ins>+
+})();
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="trunkWebsitesperfwebkitorgpublicv3componentschartstatusviewjs"></a>
<div class="modfile"><h4>Modified: trunk/Websites/perf.webkit.org/public/v3/components/chart-status-view.js (212996 => 212997)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Websites/perf.webkit.org/public/v3/components/chart-status-view.js        2017-02-25 07:53:35 UTC (rev 212996)
+++ trunk/Websites/perf.webkit.org/public/v3/components/chart-status-view.js        2017-02-25 08:02:02 UTC (rev 212997)
</span><span class="lines">@@ -60,15 +60,18 @@
</span><span class="cx"> previousPoint = view.firstPoint();
</span><span class="cx"> }
</span><span class="cx"> } else {
</span><del>- currentPoint = this._chart.currentPoint();
- previousPoint = this._chart.currentPoint(-1);
</del><ins>+ const indicator = this._chart.currentIndicator();
+ if (indicator) {
+ currentPoint = indicator.point;
+ previousPoint = indicator.view.previousPoint(currentPoint);
+ }
</ins><span class="cx"> }
</span><span class="cx"> } else {
</span><span class="cx"> var data = this._chart.sampledTimeSeriesData('current');
</span><span class="cx"> if (!data)
</span><span class="cx"> return false;
</span><del>- if (data.length)
- currentPoint = data[data.length - 1];
</del><ins>+ if (data.length())
+ currentPoint = data.lastPoint();
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> if (currentPoint == this._usedCurrentPoint && previousPoint == this._usedPreviousPoint)
</span><span class="lines">@@ -100,77 +103,55 @@
</span><span class="cx">
</span><span class="cx"> _computeChartStatus(metric, chart, currentPoint, previousPoint)
</span><span class="cx"> {
</span><del>- var currentTimeSeriesData = chart.sampledTimeSeriesData('current');
- var baselineTimeSeriesData = chart.sampledTimeSeriesData('baseline');
- var targetTimeSeriesData = chart.sampledTimeSeriesData('target');
- if (!currentTimeSeriesData)
- return null;
</del><ins>+ console.assert(currentPoint);
+ const baselineView = chart.sampledTimeSeriesData('baseline');
+ const targetView = chart.sampledTimeSeriesData('target');
</ins><span class="cx">
</span><del>- var formatter = metric.makeFormatter(3);
- var deltaFormatter = metric.makeFormatter(2, true);
</del><ins>+ const formatter = metric.makeFormatter(3);
+ const deltaFormatter = metric.makeFormatter(2, true);
+ const smallerIsBetter = metric.isSmallerBetter();
</ins><span class="cx">
</span><del>- if (!currentPoint)
- currentPoint = currentTimeSeriesData[currentTimeSeriesData.length - 1];
</del><ins>+ const labelForDiff = (diff, referencePoint, name, comparison) => {
+ const relativeDiff = Math.abs(diff * 100).toFixed(1);
+ const referenceValue = referencePoint ? ` (${formatter(referencePoint.value)})` : '';
+ return `${relativeDiff}% ${comparison} than ${name}${referenceValue}`;
+ };
</ins><span class="cx">
</span><del>- var baselinePoint = this._findLastPointPriorToTime(currentPoint, baselineTimeSeriesData);
- var diffFromBaseline = baselinePoint !== undefined ? (currentPoint.value - baselinePoint.value) / baselinePoint.value : undefined;
</del><ins>+ const baselinePoint = baselineView ? baselineView.lastPointInTimeRange(0, currentPoint.time) : null;
+ const targetPoint = targetView ? targetView.lastPointInTimeRange(0, currentPoint.time) : null;
</ins><span class="cx">
</span><del>- var targetPoint = this._findLastPointPriorToTime(currentPoint, targetTimeSeriesData);
- var diffFromTarget = targetPoint !== undefined ? (currentPoint.value - targetPoint.value) / targetPoint.value : undefined;
</del><ins>+ const diffFromBaseline = baselinePoint ? (currentPoint.value - baselinePoint.value) / baselinePoint.value : undefined;
+ const diffFromTarget = targetPoint ? (currentPoint.value - targetPoint.value) / targetPoint.value : undefined;
</ins><span class="cx">
</span><del>- var label = '';
- var className = '';
</del><ins>+ let label = null;
+ let comparison = null;
</ins><span class="cx">
</span><del>- function labelForDiff(diff, referencePoint, name, comparison)
- {
- var relativeDiff = Math.abs(diff * 100).toFixed(1);
- var referenceValue = referencePoint ? ` (${formatter(referencePoint.value)})` : '';
- return `${relativeDiff}% ${comparison} ${name}${referenceValue}`;
- }
-
- var smallerIsBetter = metric.isSmallerBetter();
</del><span class="cx"> if (diffFromBaseline !== undefined && diffFromTarget !== undefined) {
</span><span class="cx"> if (diffFromBaseline > 0 == smallerIsBetter) {
</span><del>- label = labelForDiff(diffFromBaseline, baselinePoint, 'baseline', 'worse than');
- className = 'worse';
</del><ins>+ comparison = 'worse';
+ label = labelForDiff(diffFromBaseline, baselinePoint, 'baseline', comparison);
</ins><span class="cx"> } else if (diffFromTarget < 0 == smallerIsBetter) {
</span><del>- label = labelForDiff(diffFromTarget, targetPoint, 'target', 'better than');
- className = 'better';
</del><ins>+ comparison = 'better';
+ label = labelForDiff(diffFromTarget, targetPoint, 'target', comparison);
</ins><span class="cx"> } else
</span><span class="cx"> label = labelForDiff(diffFromTarget, targetPoint, 'target', 'until');
</span><span class="cx"> } else if (diffFromBaseline !== undefined) {
</span><del>- className = diffFromBaseline > 0 == smallerIsBetter ? 'worse' : 'better';
- label = labelForDiff(diffFromBaseline, baselinePoint, 'baseline', className + ' than');
</del><ins>+ comparison = diffFromBaseline > 0 == smallerIsBetter ? 'worse' : 'better';
+ label = labelForDiff(diffFromBaseline, baselinePoint, 'baseline', comparison);
</ins><span class="cx"> } else if (diffFromTarget !== undefined) {
</span><del>- className = diffFromTarget < 0 == smallerIsBetter ? 'better' : 'worse';
- label = labelForDiff(diffFromTarget, targetPoint, 'target', className + ' than');
</del><ins>+ comparison = diffFromTarget < 0 == smallerIsBetter ? 'better' : 'worse';
+ label = labelForDiff(diffFromTarget, targetPoint, 'target', comparison);
</ins><span class="cx"> }
</span><span class="cx">
</span><del>- var valueDelta = null;
- var relativeDelta = null;
</del><ins>+ let valueDelta = null;
+ let relativeDelta = null;
</ins><span class="cx"> if (previousPoint) {
</span><span class="cx"> valueDelta = deltaFormatter(currentPoint.value - previousPoint.value);
</span><del>- var relativeDelta = (currentPoint.value - previousPoint.value) / previousPoint.value;
</del><ins>+ relativeDelta = (currentPoint.value - previousPoint.value) / previousPoint.value;
</ins><span class="cx"> relativeDelta = (relativeDelta * 100).toFixed(0) + '%';
</span><span class="cx"> }
</span><del>- return {
- className: className,
- label: label,
- currentValue: formatter(currentPoint.value),
- valueDelta: valueDelta,
- relativeDelta: relativeDelta,
- };
- }
</del><span class="cx">
</span><del>- _findLastPointPriorToTime(currentPoint, timeSeriesData)
- {
- if (!currentPoint || !timeSeriesData || !timeSeriesData.length)
- return undefined;
-
- var i = 0;
- while (i < timeSeriesData.length - 1 && timeSeriesData[i + 1].time < currentPoint.time)
- i++;
- return timeSeriesData[i];
</del><ins>+ return {className: comparison, label, currentValue: formatter(currentPoint.value), valueDelta, relativeDelta};
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> static htmlTemplate()
</span></span></pre></div>
<a id="trunkWebsitesperfwebkitorgpublicv3componentsinteractivetimeserieschartjs"></a>
<div class="modfile"><h4>Modified: trunk/Websites/perf.webkit.org/public/v3/components/interactive-time-series-chart.js (212996 => 212997)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Websites/perf.webkit.org/public/v3/components/interactive-time-series-chart.js        2017-02-25 07:53:35 UTC (rev 212996)
+++ trunk/Websites/perf.webkit.org/public/v3/components/interactive-time-series-chart.js        2017-02-25 08:02:02 UTC (rev 212997)
</span><span class="lines">@@ -16,22 +16,14 @@
</span><span class="cx"> this._renderedAnnotation = null;
</span><span class="cx"> }
</span><span class="cx">
</span><del>- currentPoint(diff)
</del><ins>+ currentIndicator()
</ins><span class="cx"> {
</span><span class="cx"> var id = this._indicatorID;
</span><span class="cx"> if (!id)
</span><span class="cx"> return null;
</span><span class="cx">
</span><del>- if (!this._sampledTimeSeriesData) {
- // FIXME: Why are we not using diff in this code path?
- this._ensureFetchedTimeSeries();
- for (var series of this._fetchedTimeSeries) {
- var point = series.findById(id);
- if (point)
- return point;
- }
</del><ins>+ if (!this._sampledTimeSeriesData)
</ins><span class="cx"> return null;
</span><del>- }
</del><span class="cx">
</span><span class="cx"> for (var view of this._sampledTimeSeriesData) {
</span><span class="cx"> if (!view)
</span><span class="lines">@@ -39,9 +31,7 @@
</span><span class="cx"> let point = view.findById(id);
</span><span class="cx"> if (!point)
</span><span class="cx"> continue;
</span><del>- if (!diff)
- return point;
- return (point && diff > 0 ? view.nextPoint(point) : view.previousPoint(point)) || point;
</del><ins>+ return {view, point, isLocked: this._indicatorIsLocked};
</ins><span class="cx"> }
</span><span class="cx"> return null;
</span><span class="cx"> }
</span><span class="lines">@@ -62,8 +52,6 @@
</span><span class="cx"> return selection && data ? data.firstPointInTimeRange(selection[0], selection[1]) : null;
</span><span class="cx"> }
</span><span class="cx">
</span><del>- lockedIndicator() { return this._indicatorIsLocked ? this.currentPoint() : null; }
-
</del><span class="cx"> setIndicator(id, shouldLock)
</span><span class="cx"> {
</span><span class="cx"> var selectionDidChange = !!this._sampledTimeSeriesData;
</span><span class="lines">@@ -81,16 +69,16 @@
</span><span class="cx">
</span><span class="cx"> moveLockedIndicatorWithNotification(forward)
</span><span class="cx"> {
</span><del>- if (!this._indicatorID || !this._indicatorIsLocked)
</del><ins>+ const indicator = this.currentIndicator();
+ if (!indicator || !indicator.isLocked)
</ins><span class="cx"> return false;
</span><del>-
</del><span class="cx"> console.assert(!this._selectionTimeRange);
</span><span class="cx">
</span><del>- var point = this.currentPoint(forward ? 1 : -1);
- if (!point || this._indicatorID == point.id)
</del><ins>+ const newPoint = forward ? indicator.view.nextPoint(indicator.point) : indicator.view.previousPoint(indicator.point);
+ if (!newPoint)
</ins><span class="cx"> return false;
</span><span class="cx">
</span><del>- this._indicatorID = point.id;
</del><ins>+ this._indicatorID = newPoint.id;
</ins><span class="cx"> this._lastMouseDownLocation = null;
</span><span class="cx"> this._forceRender = true;
</span><span class="cx">
</span><span class="lines">@@ -425,24 +413,22 @@
</span><span class="cx"> this._annotationLabel.style.display = 'none';
</span><span class="cx"> }
</span><span class="cx">
</span><del>- var indicator = this._options.indicator;
- if (this._indicatorID && indicator) {
- context.fillStyle = indicator.lineStyle;
- context.strokeStyle = indicator.lineStyle;
- context.lineWidth = indicator.lineWidth;
</del><ins>+ const indicatorOptions = this._options.indicator;
+ const indicator = this.currentIndicator();
+ if (indicator && indicatorOptions) {
+ context.fillStyle = indicatorOptions.lineStyle;
+ context.strokeStyle = indicatorOptions.lineStyle;
+ context.lineWidth = indicatorOptions.lineWidth;
</ins><span class="cx">
</span><del>- var point = this.currentPoint();
- if (point) {
- var x = metrics.timeToX(point.time);
- var y = metrics.valueToY(point.value);
</del><ins>+ const x = metrics.timeToX(indicator.point.time);
+ const y = metrics.valueToY(indicator.point.value);
</ins><span class="cx">
</span><del>- context.beginPath();
- context.moveTo(x, metrics.chartY);
- context.lineTo(x, metrics.chartY + metrics.chartHeight);
- context.stroke();
</del><ins>+ context.beginPath();
+ context.moveTo(x, metrics.chartY);
+ context.lineTo(x, metrics.chartY + metrics.chartHeight);
+ context.stroke();
</ins><span class="cx">
</span><del>- this._fillCircle(context, x, y, indicator.pointRadius);
- }
</del><ins>+ this._fillCircle(context, x, y, indicatorOptions.pointRadius);
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> var selectionOptions = this._options.selection;
</span></span></pre></div>
<a id="trunkWebsitesperfwebkitorgpublicv3modelstimeseriesjs"></a>
<div class="modfile"><h4>Modified: trunk/Websites/perf.webkit.org/public/v3/models/time-series.js (212996 => 212997)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Websites/perf.webkit.org/public/v3/models/time-series.js        2017-02-25 07:53:35 UTC (rev 212996)
+++ trunk/Websites/perf.webkit.org/public/v3/models/time-series.js        2017-02-25 08:02:02 UTC (rev 212997)
</span><span class="lines">@@ -205,6 +205,18 @@
</span><span class="cx"> return null;
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+ lastPointInTimeRange(startTime, endTime)
+ {
+ console.assert(startTime <= endTime);
+ for (let point of this._reverse()) {
+ if (point.time < startTime)
+ return null;
+ if (point.time <= endTime)
+ return point;
+ }
+ return null;
+ }
+
</ins><span class="cx"> [Symbol.iterator]()
</span><span class="cx"> {
</span><span class="cx"> const data = this._data;
</span><span class="lines">@@ -216,6 +228,22 @@
</span><span class="cx"> }
</span><span class="cx"> };
</span><span class="cx"> }
</span><ins>+
+ _reverse()
+ {
+ return {
+ [Symbol.iterator]: () => {
+ const data = this._data;
+ const end = this._startingIndex;
+ let i = this._afterEndingIndex;
+ return {
+ next() {
+ return {done: i-- == end, value: data[i]};
+ }
+ };
+ }
+ }
+ }
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> if (typeof module != 'undefined')
</span></span></pre></div>
<a id="trunkWebsitesperfwebkitorgpublicv3pageschartpanejs"></a>
<div class="modfile"><h4>Modified: trunk/Websites/perf.webkit.org/public/v3/pages/chart-pane.js (212996 => 212997)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Websites/perf.webkit.org/public/v3/pages/chart-pane.js        2017-02-25 07:53:35 UTC (rev 212996)
+++ trunk/Websites/perf.webkit.org/public/v3/pages/chart-pane.js        2017-02-25 08:02:02 UTC (rev 212997)
</span><span class="lines">@@ -92,11 +92,11 @@
</span><span class="cx"> var state = [this._platformId, this._metricId];
</span><span class="cx"> if (this._mainChart) {
</span><span class="cx"> var selection = this._mainChart.currentSelection();
</span><del>- var currentPoint = this._mainChart.currentPoint();
</del><ins>+ const indicator = this._mainChart.currentIndicator();
</ins><span class="cx"> if (selection)
</span><span class="cx"> state[2] = selection;
</span><del>- else if (this._mainChartIndicatorWasLocked && currentPoint)
- state[2] = currentPoint.id;
</del><ins>+ else if (indicator && indicator.isLocked)
+ state[2] = indicator.point.id;
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> var graphOptions = new Set;
</span><span class="lines">@@ -387,7 +387,8 @@
</span><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> var markAsOutlierButton = this.content().querySelector('.mark-as-outlier');
</span><del>- var firstSelectedPoint = this._mainChart.lockedIndicator();
</del><ins>+ const indicator = this._mainChart.currentIndicator();
+ let firstSelectedPoint = indicator && indicator.isLocked ? indicator.point : null;
</ins><span class="cx"> if (!firstSelectedPoint)
</span><span class="cx"> firstSelectedPoint = this._mainChart.firstSelectedPoint('current');
</span><span class="cx"> var alreayMarkedAsOutlier = firstSelectedPoint && firstSelectedPoint.markedOutlier;
</span></span></pre></div>
<a id="trunkWebsitesperfwebkitorgunitteststimeseriestestsjs"></a>
<div class="modfile"><h4>Modified: trunk/Websites/perf.webkit.org/unit-tests/time-series-tests.js (212996 => 212997)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Websites/perf.webkit.org/unit-tests/time-series-tests.js        2017-02-25 07:53:35 UTC (rev 212996)
+++ trunk/Websites/perf.webkit.org/unit-tests/time-series-tests.js        2017-02-25 08:02:02 UTC (rev 212997)
</span><span class="lines">@@ -326,6 +326,14 @@
</span><span class="cx"> assert.deepEqual(view.firstPointInTimeRange(fivePoints[3].time - 0.1, fivePoints[4].time), fivePoints[3]);
</span><span class="cx"> assert.deepEqual(view.firstPointInTimeRange(fivePoints[4].time, fivePoints[4].time), null);
</span><span class="cx">
</span><ins>+ assert.deepEqual(view.lastPointInTimeRange(fivePoints[0].time, fivePoints[4].time), fivePoints[3]);
+ assert.deepEqual(view.lastPointInTimeRange(fivePoints[1].time, fivePoints[4].time), fivePoints[3]);
+ assert.deepEqual(view.lastPointInTimeRange(fivePoints[1].time, fivePoints[1].time), fivePoints[1]);
+ assert.deepEqual(view.lastPointInTimeRange(fivePoints[0].time, fivePoints[0].time), null);
+ assert.deepEqual(view.lastPointInTimeRange(fivePoints[1].time + 0.1, fivePoints[2].time), null);
+ assert.deepEqual(view.lastPointInTimeRange(fivePoints[3].time - 0.1, fivePoints[4].time), fivePoints[3]);
+ assert.deepEqual(view.lastPointInTimeRange(fivePoints[4].time, fivePoints[4].time), null);
+
</ins><span class="cx"> assert.deepEqual([...view], [fivePoints[1], fivePoints[3]]);
</span><span class="cx"> });
</span><span class="cx"> });
</span><span class="lines">@@ -370,6 +378,14 @@
</span><span class="cx"> assert.deepEqual(view.firstPointInTimeRange(fivePoints[3].time - 0.1, fivePoints[4].time), fivePoints[3]);
</span><span class="cx"> assert.deepEqual(view.firstPointInTimeRange(fivePoints[4].time, fivePoints[4].time), null);
</span><span class="cx">
</span><ins>+ assert.deepEqual(view.lastPointInTimeRange(fivePoints[0].time, fivePoints[4].time), fivePoints[3]);
+ assert.deepEqual(view.lastPointInTimeRange(fivePoints[1].time, fivePoints[4].time), fivePoints[3]);
+ assert.deepEqual(view.lastPointInTimeRange(fivePoints[1].time, fivePoints[1].time), fivePoints[1]);
+ assert.deepEqual(view.lastPointInTimeRange(fivePoints[0].time, fivePoints[0].time), null);
+ assert.deepEqual(view.lastPointInTimeRange(fivePoints[1].time + 0.1, fivePoints[2].time), fivePoints[2]);
+ assert.deepEqual(view.lastPointInTimeRange(fivePoints[3].time - 0.1, fivePoints[4].time), fivePoints[3]);
+ assert.deepEqual(view.lastPointInTimeRange(fivePoints[4].time, fivePoints[4].time), null);
+
</ins><span class="cx"> assert.deepEqual([...view], fivePoints.slice(1, 4));
</span><span class="cx"> });
</span><span class="cx">
</span><span class="lines">@@ -406,6 +422,14 @@
</span><span class="cx"> assert.deepEqual(view.firstPointInTimeRange(fivePoints[3].time - 0.1, fivePoints[4].time), fivePoints[3]);
</span><span class="cx"> assert.deepEqual(view.firstPointInTimeRange(fivePoints[4].time, fivePoints[4].time), null);
</span><span class="cx">
</span><ins>+ assert.deepEqual(view.lastPointInTimeRange(fivePoints[0].time, fivePoints[4].time), fivePoints[3]);
+ assert.deepEqual(view.lastPointInTimeRange(fivePoints[1].time, fivePoints[4].time), fivePoints[3]);
+ assert.deepEqual(view.lastPointInTimeRange(fivePoints[1].time, fivePoints[1].time), null);
+ assert.deepEqual(view.lastPointInTimeRange(fivePoints[0].time, fivePoints[0].time), null);
+ assert.deepEqual(view.lastPointInTimeRange(fivePoints[1].time + 0.1, fivePoints[2].time), null);
+ assert.deepEqual(view.lastPointInTimeRange(fivePoints[3].time - 0.1, fivePoints[4].time), fivePoints[3]);
+ assert.deepEqual(view.lastPointInTimeRange(fivePoints[4].time, fivePoints[4].time), null);
+
</ins><span class="cx"> assert.deepEqual([...view], [fivePoints[3]]);
</span><span class="cx"> });
</span><span class="cx">
</span><span class="lines">@@ -442,6 +466,14 @@
</span><span class="cx"> assert.deepEqual(view.firstPointInTimeRange(fivePoints[3].time - 0.1, fivePoints[4].time), fivePoints[3]);
</span><span class="cx"> assert.deepEqual(view.firstPointInTimeRange(fivePoints[4].time, fivePoints[4].time), null);
</span><span class="cx">
</span><ins>+ assert.deepEqual(view.lastPointInTimeRange(fivePoints[0].time, fivePoints[4].time), fivePoints[3]);
+ assert.deepEqual(view.lastPointInTimeRange(fivePoints[1].time, fivePoints[4].time), fivePoints[3]);
+ assert.deepEqual(view.lastPointInTimeRange(fivePoints[1].time, fivePoints[1].time), null);
+ assert.deepEqual(view.lastPointInTimeRange(fivePoints[0].time, fivePoints[0].time), null);
+ assert.deepEqual(view.lastPointInTimeRange(fivePoints[1].time + 0.1, fivePoints[2].time), null);
+ assert.deepEqual(view.lastPointInTimeRange(fivePoints[3].time - 0.1, fivePoints[4].time), fivePoints[3]);
+ assert.deepEqual(view.lastPointInTimeRange(fivePoints[4].time, fivePoints[4].time), null);
+
</ins><span class="cx"> assert.deepEqual([...view], [fivePoints[3]]);
</span><span class="cx"> });
</span><span class="cx"> });
</span></span></pre>
</div>
</div>
</body>
</html>