From 50522d1b2b07c6034be6304b8efc5dd3d154e2db Mon Sep 17 00:00:00 2001
From: simonkwesi <0x35@tylinar.de>
Date: Thu, 21 Jan 2016 21:18:41 +0100
Subject: [PATCH 01/54] Extended list of users
---
docs/users.html | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/docs/users.html b/docs/users.html
index 0f362c5a4..663036229 100644
--- a/docs/users.html
+++ b/docs/users.html
@@ -111,6 +111,17 @@
Known Users
+
+ Ghanastocks.net
+
+ Ghanastocks.net is a financial platform offering information on the stocks traded on the Ghana Stock Exchange.
+ Dygraphs is used to display the stock charts. On the front page a tiny preview graph with no interaction model and
+ labels is used, the quote pages uses a standard version of dygraphs and the detailed chart is displayed using two
+ dygraphs instances, one for the volume bars and one for the chart, which are synchronized through a custom highlight
+ callback.
+
+
+
Are you using dygraphs? Please let Dan know and he'll add your link here!
From 0d9ed3ab9f7fe2ea4102fca7d752656d80a9973a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=C3=9Cmit=20Seren?=
Date: Mon, 8 Feb 2016 13:04:32 +0100
Subject: [PATCH 02/54] Bugfix: Import missing dygraph-utils.js
The IFrameTarp.prototype.cover function calls `findPos` from the `dygraph-utils.js` file but does not import it.
This fixes #724
---
src/iframe-tarp.js | 2 ++
1 file changed, 2 insertions(+)
diff --git a/src/iframe-tarp.js b/src/iframe-tarp.js
index b6c3de1af..42100c668 100644
--- a/src/iframe-tarp.js
+++ b/src/iframe-tarp.js
@@ -23,6 +23,8 @@
*
* @constructor
*/
+import * as utils from './dygraph-utils';
+
function IFrameTarp() {
/** @type {Array.} */
this.tarps = [];
From 6813609a3d4529f2f2a89a10c7f910aca6d59ab4 Mon Sep 17 00:00:00 2001
From: Petr Shevtsov
Date: Fri, 26 Feb 2016 07:31:06 +0500
Subject: [PATCH 03/54] Update gallery.css
Fix #458
---
gallery/gallery.css | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/gallery/gallery.css b/gallery/gallery.css
index df899dfb4..2febc685f 100644
--- a/gallery/gallery.css
+++ b/gallery/gallery.css
@@ -122,7 +122,7 @@ a {
position: absolute;
left: 200px;
right: 10px;
- top: 100px;
+ top: 150px;
bottom: 10px;
}
From f1d5ee3e25241c0cbc194d5f300f2b025f92f777 Mon Sep 17 00:00:00 2001
From: Klaus Weidner
Date: Tue, 1 Mar 2016 13:57:05 -0800
Subject: [PATCH 04/54] Fix yRangePad for logscale graphs, add tests.
Also includes a minor refactor to consolidate duplicated code for
toDataCoord calculations on logscale axes.
Fixes issue #661.
---
auto_tests/tests/axis_labels.js | 27 ++++++++
auto_tests/tests/range_tests.js | 2 +-
auto_tests/tests/to_dom_coords.js | 14 ++++
src/dygraph-utils.js | 33 +++++++++
src/dygraph.js | 111 +++++++++---------------------
5 files changed, 108 insertions(+), 79 deletions(-)
diff --git a/auto_tests/tests/axis_labels.js b/auto_tests/tests/axis_labels.js
index 0af808522..c390392f2 100644
--- a/auto_tests/tests/axis_labels.js
+++ b/auto_tests/tests/axis_labels.js
@@ -687,6 +687,33 @@ it('testLogScale', function() {
assert.deepEqual(['0','200','400','600','800','1000'], Util.getYLabels());
});
+/**
+ * Verify that log scale axis range works with yRangePad.
+ *
+ * This is a regression test for https://github.com/danvk/dygraphs/issues/661 .
+ */
+it('testLogScalePad', function() {
+ var g = new Dygraph("graph",
+ [[0, 1e-5], [1, 0.25], [2, 1], [3, 3], [4, 10]], {
+ width: 250,
+ height: 130,
+ logscale: true,
+ yRangePad: 30,
+ axes: {y: {valueRange: [1, 10]}},
+ labels: ['X', 'Y']
+ });
+ var nonEmptyLabels = Util.getYLabels().filter(function(x) { return x.length > 0; });
+ assert.deepEqual(['1', '7', '30'], nonEmptyLabels);
+
+ g.updateOptions({ yRangePad: 10, axes: {y: {valueRange: [0.25005, 3]}} });
+ nonEmptyLabels = Util.getYLabels().filter(function(x) { return x.length > 0; });
+ assert.deepEqual(['0.4', '1', '3'], nonEmptyLabels);
+
+ g.updateOptions({ axes: {y: {valueRange: [0.01, 3]}} });
+ nonEmptyLabels = Util.getYLabels().filter(function(x) { return x.length > 0; });
+ assert.deepEqual(['0.01','0.1','0.7','5'], nonEmptyLabels);
+});
+
/**
* Verify that include zero range is properly specified.
*/
diff --git a/auto_tests/tests/range_tests.js b/auto_tests/tests/range_tests.js
index ff1018e15..19d429478 100644
--- a/auto_tests/tests/range_tests.js
+++ b/auto_tests/tests/range_tests.js
@@ -342,7 +342,7 @@ it('testLogscalePad', function() {
yRangePad: 30
},
[[-10, 10], [10, 10], [30, 1000]],
- [-10, 30], [5.01691, 1993.25801]);
+ [-10, 30], [5.623, 1778.279]);
});
/**
diff --git a/auto_tests/tests/to_dom_coords.js b/auto_tests/tests/to_dom_coords.js
index 454050115..e5bda3b19 100644
--- a/auto_tests/tests/to_dom_coords.js
+++ b/auto_tests/tests/to_dom_coords.js
@@ -225,6 +225,20 @@ it('testChartLogarithmic_YAxis', function() {
assert.deepEqual([400, 0], g.toDomCoords(10, 4));
assert.deepEqual([400, 400], g.toDomCoords(10, 1));
assert.deepEqual([400, 200], g.toDomCoords(10, 2));
+
+ // Verify that the margins are adjusted appropriately for yRangePad.
+ g.updateOptions({yRangePad: 40});
+ assertDeepCloseTo([0, 4], g.toDataCoords(0, 40), epsilon);
+ assertDeepCloseTo([0, 1], g.toDataCoords(0, 360), epsilon);
+ assertDeepCloseTo([10, 4], g.toDataCoords(400, 40), epsilon);
+ assertDeepCloseTo([10, 1], g.toDataCoords(400, 360), epsilon);
+ assertDeepCloseTo([10, 2], g.toDataCoords(400, 200), epsilon);
+
+ assertDeepCloseTo([0, 40], g.toDomCoords(0, 4), epsilon);
+ assertDeepCloseTo([0, 360], g.toDomCoords(0, 1), epsilon);
+ assertDeepCloseTo([400, 40], g.toDomCoords(10, 4), epsilon);
+ assertDeepCloseTo([400, 360], g.toDomCoords(10, 1), epsilon);
+ assertDeepCloseTo([400, 200], g.toDomCoords(10, 2), epsilon);
});
it('testChartLogarithmic_XAxis', function() {
diff --git a/src/dygraph-utils.js b/src/dygraph-utils.js
index c2ed9bb75..3a3e637b8 100644
--- a/src/dygraph-utils.js
+++ b/src/dygraph-utils.js
@@ -28,6 +28,39 @@ export var log10 = function(x) {
return Math.log(x) / LN_TEN;
};
+/**
+ * @private
+ * @param {number} r0
+ * @param {number} r1
+ * @param {number} pct
+ * @return {number}
+ */
+export var logRangeFraction = function(r0, r1, pct) {
+ // Computing the inverse of toPercentXCoord. The function was arrived at with
+ // the following steps:
+ //
+ // Original calcuation:
+ // pct = (log(x) - log(xRange[0])) / (log(xRange[1]) - log(xRange[0])));
+ //
+ // Multiply both sides by the right-side demoninator.
+ // pct * (log(xRange[1] - log(xRange[0]))) = log(x) - log(xRange[0])
+ //
+ // add log(xRange[0]) to both sides
+ // log(xRange[0]) + (pct * (log(xRange[1]) - log(xRange[0])) = log(x);
+ //
+ // Swap both sides of the equation,
+ // log(x) = log(xRange[0]) + (pct * (log(xRange[1]) - log(xRange[0]))
+ //
+ // Use both sides as the exponent in 10^exp and we're done.
+ // x = 10 ^ (log(xRange[0]) + (pct * (log(xRange[1]) - log(xRange[0])))
+
+ var logr0 = log10(r0);
+ var logr1 = log10(r1);
+ var exponent = logr0 + (pct * (logr1 - logr0));
+ var value = Math.pow(LOG_SCALE, exponent);
+ return value;
+};
+
/** A dotted line stroke pattern. */
export var DOTTED_LINE = [2, 2];
/** A dashed line stroke pattern. */
diff --git a/src/dygraph.js b/src/dygraph.js
index 41e5cc15a..e5053ba15 100644
--- a/src/dygraph.js
+++ b/src/dygraph.js
@@ -632,32 +632,8 @@ Dygraph.prototype.toDataXCoord = function(x) {
if (!this.attributes_.getForAxis("logscale", 'x')) {
return xRange[0] + (x - area.x) / area.w * (xRange[1] - xRange[0]);
} else {
- // TODO: remove duplicate code?
- // Computing the inverse of toDomCoord.
var pct = (x - area.x) / area.w;
-
- // Computing the inverse of toPercentXCoord. The function was arrived at with
- // the following steps:
- //
- // Original calcuation:
- // pct = (log(x) - log(xRange[0])) / (log(xRange[1]) - log(xRange[0])));
- //
- // Multiply both sides by the right-side demoninator.
- // pct * (log(xRange[1] - log(xRange[0]))) = log(x) - log(xRange[0])
- //
- // add log(xRange[0]) to both sides
- // log(xRange[0]) + (pct * (log(xRange[1]) - log(xRange[0])) = log(x);
- //
- // Swap both sides of the equation,
- // log(x) = log(xRange[0]) + (pct * (log(xRange[1]) - log(xRange[0]))
- //
- // Use both sides as the exponent in 10^exp and we're done.
- // x = 10 ^ (log(xRange[0]) + (pct * (log(xRange[1]) - log(xRange[0])))
- var logr0 = utils.log10(xRange[0]);
- var logr1 = utils.log10(xRange[1]);
- var exponent = logr0 + (pct * (logr1 - logr0));
- var value = Math.pow(utils.LOG_SCALE, exponent);
- return value;
+ return utils.logRangeFraction(xRange[0], xRange[1], pct);
}
};
@@ -681,32 +657,8 @@ Dygraph.prototype.toDataYCoord = function(y, axis) {
} else {
// Computing the inverse of toDomCoord.
var pct = (y - area.y) / area.h;
-
- // Computing the inverse of toPercentYCoord. The function was arrived at with
- // the following steps:
- //
- // Original calcuation:
- // pct = (log(yRange[1]) - log(y)) / (log(yRange[1]) - log(yRange[0]));
- //
- // Multiply both sides by the right-side demoninator.
- // pct * (log(yRange[1]) - log(yRange[0])) = log(yRange[1]) - log(y);
- //
- // subtract log(yRange[1]) from both sides.
- // (pct * (log(yRange[1]) - log(yRange[0]))) - log(yRange[1]) = -log(y);
- //
- // and multiply both sides by -1.
- // log(yRange[1]) - (pct * (logr1 - log(yRange[0])) = log(y);
- //
- // Swap both sides of the equation,
- // log(y) = log(yRange[1]) - (pct * (log(yRange[1]) - log(yRange[0])));
- //
- // Use both sides as the exponent in 10^exp and we're done.
- // y = 10 ^ (log(yRange[1]) - (pct * (log(yRange[1]) - log(yRange[0]))));
- var logr0 = utils.log10(yRange[0]);
- var logr1 = utils.log10(yRange[1]);
- var exponent = logr1 - (pct * (logr1 - logr0));
- var value = Math.pow(utils.LOG_SCALE, exponent);
- return value;
+ // Note reversed yRange, y1 is on top with pct==0.
+ return utils.logRangeFraction(yRange[1], yRange[0], pct);
}
};
@@ -2602,25 +2554,21 @@ Dygraph.prototype.computeYAxisRanges_ = function(extremes) {
}
}
- var maxAxisY, minAxisY;
- if (logscale) {
- if (ypadCompat) {
+ var maxAxisY = maxY, minAxisY = minY;
+ if (ypadCompat) {
+ if (logscale) {
maxAxisY = maxY + ypad * span;
minAxisY = minY;
} else {
- var logpad = Math.exp(Math.log(span) * ypad);
- maxAxisY = maxY * logpad;
- minAxisY = minY / logpad;
- }
- } else {
- maxAxisY = maxY + ypad * span;
- minAxisY = minY - ypad * span;
-
- // Backwards-compatible behavior: Move the span to start or end at zero if it's
- // close to zero, but not if avoidMinZero is set.
- if (ypadCompat && !this.getBooleanOption("avoidMinZero")) {
- if (minAxisY < 0 && minY >= 0) minAxisY = 0;
- if (maxAxisY > 0 && maxY <= 0) maxAxisY = 0;
+ maxAxisY = maxY + ypad * span;
+ minAxisY = minY - ypad * span;
+
+ // Backwards-compatible behavior: Move the span to start or end at zero if it's
+ // close to zero, but not if avoidMinZero is set.
+ if (!this.getBooleanOption("avoidMinZero")) {
+ if (minAxisY < 0 && minY >= 0) minAxisY = 0;
+ if (maxAxisY > 0 && maxY <= 0) maxAxisY = 0;
+ }
}
}
axis.extremeRange = [minAxisY, maxAxisY];
@@ -2634,21 +2582,28 @@ Dygraph.prototype.computeYAxisRanges_ = function(extremes) {
// This is a user-set value range for this axis.
var y0 = isNullUndefinedOrNaN(axis.valueRange[0]) ? axis.extremeRange[0] : axis.valueRange[0];
var y1 = isNullUndefinedOrNaN(axis.valueRange[1]) ? axis.extremeRange[1] : axis.valueRange[1];
- if (!ypadCompat) {
- if (axis.logscale) {
- var logpad = Math.exp(Math.log(span) * ypad);
- y0 *= logpad;
- y1 /= logpad;
- } else {
- span = y1 - y0;
- y0 -= span * ypad;
- y1 += span * ypad;
- }
- }
axis.computedValueRange = [y0, y1];
} else {
axis.computedValueRange = axis.extremeRange;
}
+ if (!axis.valueWindow && !ypadCompat) {
+ // When using yRangePad, adjust the upper/lower bounds to add
+ // padding unless the user has zoomed/panned the Y axis range.
+ if (logscale) {
+ y0 = axis.computedValueRange[0];
+ y1 = axis.computedValueRange[1];
+ var y0pct = ypad / (2 * ypad - 1);
+ var y1pct = (ypad - 1) / (2 * ypad - 1);
+ axis.computedValueRange[0] = utils.logRangeFraction(y0, y1, y0pct);
+ axis.computedValueRange[1] = utils.logRangeFraction(y0, y1, y1pct);
+ } else {
+ y0 = axis.computedValueRange[0];
+ y1 = axis.computedValueRange[1];
+ span = y1 - y0;
+ axis.computedValueRange[0] = y0 - span * ypad;
+ axis.computedValueRange[1] = y1 + span * ypad;
+ }
+ }
if (independentTicks) {
From 93ec1094eb75477b455efaa7adeb10190b87992b Mon Sep 17 00:00:00 2001
From: Dan Vanderkam
Date: Wed, 16 Mar 2016 12:43:48 -0400
Subject: [PATCH 05/54] Add new issue and PR templates
---
CONTRIBUTING.md => .github/CONTRIBUTING.md | 0
.github/ISSUE_TEMPLATE.md | 20 ++++++++++++++++++++
.github/PULL_REQUEST_TEMPLATE.md | 14 ++++++++++++++
3 files changed, 34 insertions(+)
rename CONTRIBUTING.md => .github/CONTRIBUTING.md (100%)
create mode 100644 .github/ISSUE_TEMPLATE.md
create mode 100644 .github/PULL_REQUEST_TEMPLATE.md
diff --git a/CONTRIBUTING.md b/.github/CONTRIBUTING.md
similarity index 100%
rename from CONTRIBUTING.md
rename to .github/CONTRIBUTING.md
diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md
new file mode 100644
index 000000000..75d0c7a6d
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE.md
@@ -0,0 +1,20 @@
+Filing a bug report? Please include the following:
+
+1. Link to a page which demonstrates the problem, preferably a jsfiddle (use http://dygraphs.com/fiddle as a template)
+2. Browser and Operating System that exhibit the problem
+3. Version of dygraphs that you're using
+
+It also helps if you include the non-compacted version of the JS on your
+page. For instance, instead of doing this:
+
+```html
+
+```
+
+do this:
+
+```html
+
+```
+
+This makes error messages and debugging simpler. The jsfiddle does this automatically.
diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md
new file mode 100644
index 000000000..474eeed5b
--- /dev/null
+++ b/.github/PULL_REQUEST_TEMPLATE.md
@@ -0,0 +1,14 @@
+Please read the guide to making dygraphs changes:
+http://dygraphs.com/changes.html
+
+Pull Requests will only be accepted if:
+
+- You clearly explain what you're adding and why you believe it's an
+ improvement. For example: "Fixes issue #123".
+- You adhere to the style of the rest of the dygraphs code base.
+- You write an `auto_test` for the code that you're adding.
+
+Be sure to document any new options you add. Also be aware that PRs which add
+options are likely to be rejected. dygraphs already has many options. If you
+can fit your feature into one of those or implement it as a plugin, it will be
+more likely to get merged.
From 902091b8b33555845682681f64048f7ed1811c27 Mon Sep 17 00:00:00 2001
From: Marcus Lewis
Date: Wed, 4 May 2016 20:03:36 -0700
Subject: [PATCH 06/54] Bugfix: Unwanted drawn point when prevCanvasX is 0
---
src/dygraph-canvas.js | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/src/dygraph-canvas.js b/src/dygraph-canvas.js
index 7ba66ffc8..bd37e67e0 100644
--- a/src/dygraph-canvas.js
+++ b/src/dygraph-canvas.js
@@ -220,18 +220,18 @@ DygraphCanvasRenderer._drawSeries = function(e,
prevCanvasX = prevCanvasY = null;
} else {
isIsolated = false;
- if (drawGapPoints || !prevCanvasX) {
+ if (drawGapPoints || prevCanvasX === null) {
iter.nextIdx_ = i;
iter.next();
nextCanvasY = iter.hasNext ? iter.peek.canvasy : null;
var isNextCanvasYNullOrNaN = nextCanvasY === null ||
nextCanvasY != nextCanvasY;
- isIsolated = (!prevCanvasX && isNextCanvasYNullOrNaN);
+ isIsolated = (prevCanvasX === null && isNextCanvasYNullOrNaN);
if (drawGapPoints) {
// Also consider a point to be "isolated" if it's adjacent to a
// null point, excluding the graph edges.
- if ((!first && !prevCanvasX) ||
+ if ((!first && prevCanvasX === null) ||
(iter.hasNext && isNextCanvasYNullOrNaN)) {
isIsolated = true;
}
From 401ff9f17c622f3173cc8d34cfcf3e444620d7d0 Mon Sep 17 00:00:00 2001
From: Marcus Lewis
Date: Thu, 5 May 2016 12:55:17 -0700
Subject: [PATCH 07/54] Add unit test to detect the "unwanted draw point"
---
auto_tests/tests/draw_gap_edge_points.js | 47 ++++++++++++++++++++++++
1 file changed, 47 insertions(+)
create mode 100644 auto_tests/tests/draw_gap_edge_points.js
diff --git a/auto_tests/tests/draw_gap_edge_points.js b/auto_tests/tests/draw_gap_edge_points.js
new file mode 100644
index 000000000..3d92b0f32
--- /dev/null
+++ b/auto_tests/tests/draw_gap_edge_points.js
@@ -0,0 +1,47 @@
+/**
+ * @fileoverview Test cases for the option "drawGapEdgePoints"
+ */
+
+import Dygraph from '../../src/dygraph';
+import * as utils from '../../src/dygraph-utils';
+
+describe("draw-gap-edge-points", function() {
+
+ cleanupAfterEach();
+
+ it("shouldn't draw any points by default", function() {
+ var called = false;
+ var g = new Dygraph(document.getElementById("graph"),
+ [[0, 0],
+ [1, 1],
+ [2, 2],
+ [3, 3],
+ [4, 4],
+ [5, 5]],
+ {labels: ['a', 'b'],
+ drawGapEdgePoints: true,
+ drawPointCallback: function() { called = true; }});
+
+ assert.isFalse(called);
+ });
+
+ it("shouldn't draw any points by default (no axes)", function() {
+ var called = false;
+ var g = new Dygraph(document.getElementById("graph"),
+ [[0, 0],
+ [1, 1],
+ [2, 2],
+ [3, 3],
+ [4, 4],
+ [5, 5]],
+ {labels: ['a', 'b'],
+ drawGapEdgePoints: true,
+ drawPointCallback: function() { called = true; },
+ axes: {
+ x: { drawAxis: false },
+ y: { drawAxis: false }
+ }});
+
+ assert.isFalse(called);
+ });
+});
From b55a71d768d2f8de62877c32b3aec9e9975ac389 Mon Sep 17 00:00:00 2001
From: Justin Standring
Date: Fri, 8 Jul 2016 16:05:40 -0700
Subject: [PATCH 08/54] Check for new options before updating synchronised
graphs (Fixes #760)
---
src/extras/synchronizer.js | 17 +++++++++++++++++
1 file changed, 17 insertions(+)
mode change 100644 => 100755 src/extras/synchronizer.js
diff --git a/src/extras/synchronizer.js b/src/extras/synchronizer.js
old mode 100644
new mode 100755
index bf5b6f34b..6f369f3a0
--- a/src/extras/synchronizer.js
+++ b/src/extras/synchronizer.js
@@ -153,6 +153,16 @@ var synchronize = function(/* dygraphs..., opts */) {
};
};
+function arraysAreEqual(a, b) {
+ if (!Array.isArray(a) || !Array.isArray(b)) return false;
+ var i = a.length;
+ if (i !== b.length) return false;
+ while (i--) {
+ if (a[i] !== b[i]) return false;
+ }
+ return true;
+}
+
function attachZoomHandlers(gs, syncOpts, prevCallbacks) {
var block = false;
for (var i = 0; i < gs.length; i++) {
@@ -173,6 +183,13 @@ function attachZoomHandlers(gs, syncOpts, prevCallbacks) {
}
continue;
}
+
+ // Only redraw if there are new options
+ if (arraysAreEqual(opts.dateWindow, gs[j].getOption('dateWindow')) &&
+ arraysAreEqual(opts.valueRange, gs[j].getOption('valueRange'))) {
+ continue;
+ }
+
gs[j].updateOptions(opts);
}
block = false;
From bd6ee5dcf9017abcbefa480e79756a6957c5c7ed Mon Sep 17 00:00:00 2001
From: Dan Vanderkam
Date: Tue, 2 Aug 2016 15:00:32 -0400
Subject: [PATCH 09/54] Implement tick.label_v.
---
src/dygraph-layout.js | 14 +++++++++-----
src/plugins/axes.js | 25 ++++++++++++-------------
src/plugins/grid.js | 14 ++++++++------
3 files changed, 29 insertions(+), 24 deletions(-)
diff --git a/src/dygraph-layout.js b/src/dygraph-layout.js
index 3bc91354e..c32a9e5c4 100644
--- a/src/dygraph-layout.js
+++ b/src/dygraph-layout.js
@@ -276,14 +276,16 @@ DygraphLayout.prototype._evaluateLineCharts = function() {
};
DygraphLayout.prototype._evaluateLineTicks = function() {
- var i, tick, label, pos;
+ var i, tick, label, pos, v, has_tick;
this.xticks = [];
for (i = 0; i < this.xTicks_.length; i++) {
tick = this.xTicks_[i];
label = tick.label;
- pos = this.dygraph_.toPercentXCoord(tick.v);
+ has_tick = !('label_v' in tick);
+ v = has_tick ? tick.v : tick.label_v;
+ pos = this.dygraph_.toPercentXCoord(v);
if ((pos >= 0.0) && (pos < 1.0)) {
- this.xticks.push([pos, label]);
+ this.xticks.push({pos, label, has_tick});
}
}
@@ -293,9 +295,11 @@ DygraphLayout.prototype._evaluateLineTicks = function() {
for (var j = 0; j < axis.ticks.length; j++) {
tick = axis.ticks[j];
label = tick.label;
- pos = this.dygraph_.toPercentYCoord(tick.v, i);
+ has_tick = !('label_v' in tick);
+ v = has_tick ? tick.v : tick.label_v;
+ pos = this.dygraph_.toPercentYCoord(v, i);
if ((pos > 0.0) && (pos <= 1.0)) {
- this.yticks.push([i, pos, label]);
+ this.yticks.push({axis: i, pos, label, has_tick});
}
}
}
diff --git a/src/plugins/axes.js b/src/plugins/axes.js
index e9135344b..f93f36fce 100644
--- a/src/plugins/axes.js
+++ b/src/plugins/axes.js
@@ -99,7 +99,7 @@ axes.prototype.willDrawChart = function(e) {
!g.getOptionForAxis('drawAxis', 'y2')) {
return;
}
-
+
// Round pixels to half-integer boundaries for crisper drawing.
function halfUp(x) { return Math.round(x) + 0.5; }
function halfDown(y){ return Math.round(y) - 0.5; }
@@ -170,21 +170,20 @@ axes.prototype.willDrawChart = function(e) {
if (layout.yticks && layout.yticks.length > 0) {
var num_axes = g.numAxes();
var getOptions = [makeOptionGetter('y'), makeOptionGetter('y2')];
- for (i = 0; i < layout.yticks.length; i++) {
- tick = layout.yticks[i];
- if (typeof(tick) == 'function') return; // <-- when would this happen?
+ for (var tick of layout.yticks) {
+ if (tick.label === undefined) continue; // this tick only has a grid line.
x = area.x;
var sgn = 1;
var prec_axis = 'y1';
var getAxisOption = getOptions[0];
- if (tick[0] == 1) { // right-side y-axis
+ if (tick.axis == 1) { // right-side y-axis
x = area.x + area.w;
sgn = -1;
prec_axis = 'y2';
getAxisOption = getOptions[1];
}
var fontSize = getAxisOption('axisLabelFontSize');
- y = area.y + tick[1] * area.h;
+ y = area.y + tick.pos * area.h;
/* Tick marks are currently clipped, so don't bother drawing them.
context.beginPath();
@@ -194,7 +193,7 @@ axes.prototype.willDrawChart = function(e) {
context.stroke();
*/
- label = makeDiv(tick[2], 'y', num_axes == 2 ? prec_axis : null);
+ label = makeDiv(tick.label, 'y', num_axes == 2 ? prec_axis : null);
var top = (y - fontSize / 2);
if (top < 0) top = 0;
@@ -203,10 +202,10 @@ axes.prototype.willDrawChart = function(e) {
} else {
label.style.top = top + 'px';
}
- if (tick[0] === 0) {
+ if (tick.axis === 0) {
label.style.left = (area.x - getAxisOption('axisLabelWidth') - getAxisOption('axisTickSize')) + 'px';
label.style.textAlign = 'right';
- } else if (tick[0] == 1) {
+ } else if (tick.axis == 1) {
label.style.left = (area.x + area.w +
getAxisOption('axisTickSize')) + 'px';
label.style.textAlign = 'left';
@@ -263,9 +262,9 @@ axes.prototype.willDrawChart = function(e) {
if (g.getOptionForAxis('drawAxis', 'x')) {
if (layout.xticks) {
var getAxisOption = makeOptionGetter('x');
- for (i = 0; i < layout.xticks.length; i++) {
- tick = layout.xticks[i];
- x = area.x + tick[0] * area.w;
+ for (var tick of layout.xticks) {
+ if (tick.label === undefined) continue; // this tick only has a grid line.
+ x = area.x + tick.pos * area.w;
y = area.y + area.h;
/* Tick marks are currently clipped, so don't bother drawing them.
@@ -276,7 +275,7 @@ axes.prototype.willDrawChart = function(e) {
context.stroke();
*/
- label = makeDiv(tick[1], 'x');
+ label = makeDiv(tick.label, 'x');
label.style.textAlign = 'center';
label.style.top = (y + getAxisOption('axisTickSize')) + 'px';
diff --git a/src/plugins/grid.js b/src/plugins/grid.js
index 16a83a2b8..25126db3c 100644
--- a/src/plugins/grid.js
+++ b/src/plugins/grid.js
@@ -62,9 +62,10 @@ grid.prototype.willDrawChart = function(e) {
ticks = layout.yticks;
ctx.save();
// draw grids for the different y axes
- for (i = 0; i < ticks.length; i++) {
- var axis = ticks[i][0];
- if(drawGrid[axis]) {
+ for (var tick of ticks) {
+ if (!tick.has_tick) continue;
+ var axis = tick.axis;
+ if (drawGrid[axis]) {
ctx.save();
if (stroking[axis]) {
if (ctx.setLineDash) ctx.setLineDash(strokePattern[axis]);
@@ -73,7 +74,7 @@ grid.prototype.willDrawChart = function(e) {
ctx.lineWidth = lineWidths[axis];
x = halfUp(area.x);
- y = halfDown(area.y + ticks[i][1] * area.h);
+ y = halfDown(area.y + tick.pos * area.h);
ctx.beginPath();
ctx.moveTo(x, y);
ctx.lineTo(x + area.w, y);
@@ -96,8 +97,9 @@ grid.prototype.willDrawChart = function(e) {
}
ctx.strokeStyle = g.getOptionForAxis('gridLineColor', 'x');
ctx.lineWidth = g.getOptionForAxis('gridLineWidth', 'x');
- for (i = 0; i < ticks.length; i++) {
- x = halfUp(area.x + ticks[i][0] * area.w);
+ for (var tick of ticks) {
+ if (!tick.has_tick) continue;
+ x = halfUp(area.x + tick.pos * area.w);
y = halfDown(area.y + area.h);
ctx.beginPath();
ctx.moveTo(x, y);
From ad739e06ecde73b8a05ff619fa901474b408ddaa Mon Sep 17 00:00:00 2001
From: Dan Vanderkam
Date: Tue, 2 Aug 2016 15:15:51 -0400
Subject: [PATCH 10/54] Demo of label_v
---
tests/label_v.html | 67 ++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 67 insertions(+)
create mode 100644 tests/label_v.html
diff --git a/tests/label_v.html b/tests/label_v.html
new file mode 100644
index 000000000..97c4730f0
--- /dev/null
+++ b/tests/label_v.html
@@ -0,0 +1,67 @@
+
+
+
+ demo
+
+
+
+
+
+
This demo shows how you can create labels and ticks independently of one another.
+
+
+
From 051a854a82738473230fd1c20b6c9cacb036269d Mon Sep 17 00:00:00 2001
From: Steve Jones
Date: Fri, 26 Aug 2016 17:48:09 +0200
Subject: [PATCH 11/54] Bug fix: indexFromSetName on invisible sets (#771)
* indexFromSetName works with trailing invisible sets
If the last set(s) have their visibility set to false, their names
would not be added to `setIndexByName_`, so `indexFromSetName` would
not be able to find them. This fixes that problem.
* Corrected test.
* Properly clone graph options
---
auto_tests/tests/data_api.js | 18 ++++++++++++++++++
src/dygraph.js | 7 +++----
2 files changed, 21 insertions(+), 4 deletions(-)
diff --git a/auto_tests/tests/data_api.js b/auto_tests/tests/data_api.js
index e692fc61e..631990980 100644
--- a/auto_tests/tests/data_api.js
+++ b/auto_tests/tests/data_api.js
@@ -4,6 +4,7 @@
* @author danvdk@gmail.com (Dan Vanderkam)
*/
import Dygraph from '../../src/dygraph';
+import * as utils from '../../src/dygraph-utils';
describe("data-api", function() {
cleanupAfterEach();
@@ -99,4 +100,21 @@ it('testGetRowForXDuplicates', function() {
assert.equal(5, g.getRowForX(9));
});
+// indexFromSeriesName should return a value even if the series is invisible
+// In 1.1.1, if you request the last set and it's invisible, the method returns undefined.
+it('testIndexFromSetNameOnInvisibleSet', function() {
+
+ var localOpts = utils.clone(opts);
+ localOpts.visibility = [true, false];
+
+ var g = new Dygraph(graphDiv, [
+ "x,y1,y2",
+ "1,1,1",
+ "2,2,2",
+ "3,3,3"
+ ].join('\n'), localOpts);
+
+ assert.equal(2, g.indexFromSetName("y2"));
+});
+
});
diff --git a/src/dygraph.js b/src/dygraph.js
index e5053ba15..ff3bcb666 100644
--- a/src/dygraph.js
+++ b/src/dygraph.js
@@ -2304,16 +2304,15 @@ Dygraph.prototype.drawGraph_ = function() {
this.setIndexByName_ = {};
var labels = this.attr_("labels");
- if (labels.length > 0) {
- this.setIndexByName_[labels[0]] = 0;
- }
var dataIdx = 0;
for (var i = 1; i < points.length; i++) {
- this.setIndexByName_[labels[i]] = i;
if (!this.visibility()[i - 1]) continue;
this.layout_.addDataset(labels[i], points[i]);
this.datasetIndex_[i] = dataIdx++;
}
+ for (var i = 0; i < labels.length; i++) {
+ this.setIndexByName_[labels[i]] = i;
+ }
this.computeYAxisRanges_(extremes);
this.layout_.setYAxes(this.axes_);
From 8cc4108bdb0db5006d794be50d1bbca9558373e9 Mon Sep 17 00:00:00 2001
From: Majlen
Date: Mon, 12 Sep 2016 17:43:49 +0200
Subject: [PATCH 12/54] Check that setRow is not negative, fixes #644. (#773)
Synchronization breaks up if this case is not checked. Fix has been
proposed in the bugreport.
---
src/dygraph.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/dygraph.js b/src/dygraph.js
index ff3bcb666..3ffc2e6cd 100644
--- a/src/dygraph.js
+++ b/src/dygraph.js
@@ -1813,7 +1813,7 @@ Dygraph.prototype.setSelection = function(row, opt_seriesName, opt_locked) {
// for. If it is, just use it, otherwise search the array for a point
// in the proper place.
var setRow = row - this.getLeftBoundary_(setIdx);
- if (setRow < points.length && points[setRow].idx == row) {
+ if (setRow >= 0 && setRow < points.length && points[setRow].idx == row) {
var point = points[setRow];
if (point.yval !== null) this.selPoints_.push(point);
} else {
From 2d0fdf6eb18eafde50830b8109f42e20b82247b1 Mon Sep 17 00:00:00 2001
From: Pierrick Koch
Date: Thu, 15 Sep 2016 15:23:48 +0200
Subject: [PATCH 13/54] Dygraph.dateString_: shows milliseconds if any. (#774)
* [utils] dateString_ display Milliseconds if any
* [utils] fix dateAxisLabelFormatter milliseconds
* [util] dateString_: compute ms in frac
* [utils] clean hmsString_ format
* [utils] add milliseconds padding in hmsString_
* [develop] add note on npm install
* [tests] add labelsDateMilliseconds test
* [utils] add millis in dateAxisLabelFormatter
* [tests] fix requested changes in labelsDateMillis
* [auto_tests] add date_formats testMillisecondsDate
---
DEVELOP.md | 4 +++
auto_tests/tests/date_formats.js | 8 +++++
src/dygraph-utils.js | 15 ++++++---
tests/labelsDateMilliseconds.html | 56 +++++++++++++++++++++++++++++++
4 files changed, 78 insertions(+), 5 deletions(-)
create mode 100644 tests/labelsDateMilliseconds.html
diff --git a/DEVELOP.md b/DEVELOP.md
index 9a13888c9..6eb43fb19 100644
--- a/DEVELOP.md
+++ b/DEVELOP.md
@@ -6,6 +6,10 @@ This is a step-by-step guide explaining how to do it.
### How-to
+To install dependencies, run
+
+ npm install
+
To build dygraphs, run
npm run build
diff --git a/auto_tests/tests/date_formats.js b/auto_tests/tests/date_formats.js
index f157b8dd4..5148fe7fb 100644
--- a/auto_tests/tests/date_formats.js
+++ b/auto_tests/tests/date_formats.js
@@ -36,4 +36,12 @@ it('testHyphenatedDate', function() {
assert.equal(Date.UTC(2000, 1, 2), utils.dateParser(str));
});
+it('testMillisecondsDate', function() {
+ // Format: YYYY-MM-DD HH:MM:SS.MS
+
+ // Midnight February 2, 2000 14:25:42.123 UTC
+ var ts = Date.UTC(2000, 1, 2, 14, 25, 42, 123);
+ assert.equal("2000/02/02 14:25:42.123", utils.dateString_(ts, true));
+});
+
});
diff --git a/src/dygraph-utils.js b/src/dygraph-utils.js
index 3a3e637b8..79215d4a5 100644
--- a/src/dygraph-utils.js
+++ b/src/dygraph-utils.js
@@ -362,10 +362,14 @@ export var DateAccessorsUTC = {
* @return {string} A time of the form "HH:MM" or "HH:MM:SS"
* @private
*/
-export function hmsString_(hh, mm, ss) {
+export function hmsString_(hh, mm, ss, ms) {
var ret = zeropad(hh) + ":" + zeropad(mm);
if (ss) {
ret += ":" + zeropad(ss);
+ if (ms) {
+ var str = "" + ms;
+ ret += "." + ('000'+str).substring(str.length);
+ }
}
return ret;
};
@@ -387,16 +391,17 @@ export function dateString_(time, utc) {
var hh = accessors.getHours(date);
var mm = accessors.getMinutes(date);
var ss = accessors.getSeconds(date);
+ var ms = accessors.getMilliseconds(date);
// Get a year string:
var year = "" + y;
// Get a 0 padded month string
var month = zeropad(m + 1); //months are 0-offset, sigh
// Get a 0 padded day string
var day = zeropad(d);
- var frac = hh * 3600 + mm * 60 + ss;
+ var frac = hh * 3600 + mm * 60 + ss + 1e-3 * ms;
var ret = year + "/" + month + "/" + day;
if (frac) {
- ret += " " + hmsString_(hh, mm, ss);
+ ret += " " + hmsString_(hh, mm, ss, ms);
}
return ret;
};
@@ -1213,7 +1218,7 @@ export function dateAxisLabelFormatter(date, granularity, opts) {
hours = accessors.getHours(date),
mins = accessors.getMinutes(date),
secs = accessors.getSeconds(date),
- millis = accessors.getSeconds(date);
+ millis = accessors.getMilliseconds(date);
if (granularity >= DygraphTickers.Granularity.DECADAL) {
return '' + year;
@@ -1225,7 +1230,7 @@ export function dateAxisLabelFormatter(date, granularity, opts) {
// e.g. '21 Jan' (%d%b)
return zeropad(day) + ' ' + SHORT_MONTH_NAMES_[month];
} else {
- return hmsString_(hours, mins, secs);
+ return hmsString_(hours, mins, secs, millis);
}
}
};
diff --git a/tests/labelsDateMilliseconds.html b/tests/labelsDateMilliseconds.html
new file mode 100644
index 000000000..332e8c41f
--- /dev/null
+++ b/tests/labelsDateMilliseconds.html
@@ -0,0 +1,56 @@
+
+
+
+ Milliseconds date labels
+
+
+
+
+
+
Milliseconds display in date and time labels
+
+
This shows how milliseconds are displayed when present.
+
+
+
+
+
You can check it by hovering over corresponding points and comparing
+ the value labels.
+
+
+
+
+
From f0e472002843b5e61aa9467f97f755280c91a46b Mon Sep 17 00:00:00 2001
From: Dan Vanderkam
Date: Wed, 28 Sep 2016 08:45:38 -0400
Subject: [PATCH 14/54] Use CSS for styling
---
auto_tests/coverage.html | 1 +
auto_tests/runner.html | 1 +
auto_tests/tests/axis_labels.js | 69 ---------------
auto_tests/tests/pathological_cases.js | 1 -
css/dygraph.css | 117 +++++++++++++++++++++++++
src/dygraph-default-attrs.js | 5 --
src/dygraph-options-reference.js | 18 ----
src/dygraph-utils.js | 3 -
src/dygraph.js | 75 +++-------------
src/plugins/annotations.js | 22 ++---
src/plugins/axes.js | 21 ++---
src/plugins/chart-labels.js | 16 +---
src/plugins/legend.js | 47 ++--------
13 files changed, 156 insertions(+), 240 deletions(-)
create mode 100644 css/dygraph.css
diff --git a/auto_tests/coverage.html b/auto_tests/coverage.html
index 04573478f..e8cd24ca4 100644
--- a/auto_tests/coverage.html
+++ b/auto_tests/coverage.html
@@ -3,6 +3,7 @@
dygraphs tests
+
diff --git a/auto_tests/runner.html b/auto_tests/runner.html
index c3a3d8797..2f48d5b86 100644
--- a/auto_tests/runner.html
+++ b/auto_tests/runner.html
@@ -3,6 +3,7 @@
dygraphs tests
+
diff --git a/auto_tests/tests/axis_labels.js b/auto_tests/tests/axis_labels.js
index c390392f2..5a631fa13 100644
--- a/auto_tests/tests/axis_labels.js
+++ b/auto_tests/tests/axis_labels.js
@@ -798,75 +798,6 @@ it('testAxisLabelFontSizeNull', function() {
assertFontSize(document.querySelectorAll(".dygraph-axis-label-y"), "14px");
});
-it('testAxisLabelColor', function() {
- var graph = document.getElementById("graph");
- var g = new Dygraph(graph, simpleData, {});
-
- // Be sure we're dealing with a black default.
- assert.equal("black", DEFAULT_ATTRS.axisLabelColor);
-
- var assertColor = function(selector, expected) {
- Util.assertStyleOfChildren(selector, "color", expected);
- }
-
- assertColor(document.querySelectorAll(".dygraph-axis-label-x"), "rgb(0, 0, 0)");
- assertColor(document.querySelectorAll(".dygraph-axis-label-y"), "rgb(0, 0, 0)");
-
- g.updateOptions({ axisLabelColor : "red"});
- assertColor(document.querySelectorAll(".dygraph-axis-label-x"), "rgb(255, 0, 0)");
- assertColor(document.querySelectorAll(".dygraph-axis-label-y"), "rgb(255, 0, 0)");
-
- g.updateOptions({
- axisLabelColor : null,
- axes : {
- x : { axisLabelColor : "blue" },
- }
- });
-
- assertColor(document.querySelectorAll(".dygraph-axis-label-x"), "rgb(0, 0, 255)");
- assertColor(document.querySelectorAll(".dygraph-axis-label-y"), "rgb(0, 0, 0)");
-
- g.updateOptions({
- axes : {
- y : { axisLabelColor : "green" },
- }
- });
-
- assertColor(document.querySelectorAll(".dygraph-axis-label-x"), "rgb(0, 0, 255)");
- assertColor(document.querySelectorAll(".dygraph-axis-label-y"), "rgb(0, 128, 0)");
-
- g.updateOptions({
- series : {
- Y2 : { axis : "y2" } // copy y2 series to y2 axis.
- },
- axes : {
- y2 : { axisLabelColor : "yellow" },
- }
- });
-
- assertColor(document.querySelectorAll(".dygraph-axis-label-x"), "rgb(0, 0, 255)");
- assertColor(document.querySelectorAll(".dygraph-axis-label-y1"), "rgb(0, 128, 0)");
- assertColor(document.querySelectorAll(".dygraph-axis-label-y2"), "rgb(255, 255, 0)");
-});
-
-it('testAxisLabelColorNull', function() {
- var graph = document.getElementById("graph");
- var g = new Dygraph(graph, simpleData,
- {
- axisLabelColor: null
- });
-
- var assertColor = function(selector, expected) {
- Util.assertStyleOfChildren(selector, "color", expected);
- }
-
- // Be sure we're dealing with a 14-point default.
- assert.equal(14, DEFAULT_ATTRS.axisLabelFontSize);
-
- assertColor(document.querySelectorAll(".dygraph-axis-label-x"), "rgb(0, 0, 0)");
- assertColor(document.querySelectorAll(".dygraph-axis-label-y"), "rgb(0, 0, 0)");
-});
-
/*
* This test shows that the label formatter overrides labelsKMB for all values.
*/
diff --git a/auto_tests/tests/pathological_cases.js b/auto_tests/tests/pathological_cases.js
index 0bcab0b79..0fab2008c 100644
--- a/auto_tests/tests/pathological_cases.js
+++ b/auto_tests/tests/pathological_cases.js
@@ -90,7 +90,6 @@ it('testCombinations', function() {
var opts = {
width: 300,
height: 150,
- labelsDivWidth: 100,
pointSize: 10
};
for (var key in base) {
diff --git a/css/dygraph.css b/css/dygraph.css
new file mode 100644
index 000000000..75d58685f
--- /dev/null
+++ b/css/dygraph.css
@@ -0,0 +1,117 @@
+/**
+ * Default styles for the dygraphs charting library.
+ */
+
+.dygraph-legend {
+ position: absolute;
+ font-size: 14px;
+ z-index: 10;
+ width: 250px; /* labelsDivWidth */
+ /*
+ dygraphs determines these based on the presence of chart labels.
+ It might make more sense to create a wrapper div around the chart proper.
+ top: 0px;
+ right: 2px;
+ */
+ background: white;
+ line-height: normal;
+ text-align: left;
+ overflow: hidden;
+}
+
+/* styles for a solid line in the legend */
+.dygraph-legend-line {
+ display: inline-block;
+ position: relative;
+ bottom: .5ex;
+ padding-left: 1em;
+ height: 1px;
+ border-bottom-width: 2px;
+ border-bottom-style: solid;
+ /* border-bottom-color is set based on the series color */
+}
+
+/* styles for a dashed line in the legend, e.g. when strokePattern is set */
+.dygraph-legend-dash {
+ display: inline-block;
+ position: relative;
+ bottom: .5ex;
+ height: 1px;
+ border-bottom-width: 2px;
+ border-bottom-style: solid;
+ /* border-bottom-color is set based on the series color */
+ /* margin-right is set based on the stroke pattern */
+ /* padding-left is set based on the stroke pattern */
+}
+
+.dygraph-roller {
+ position: absolute;
+ z-index: 10;
+}
+
+/* This class is shared by all annotations, including those with icons */
+.dygraph-annotation {
+ position: absolute;
+ z-index: 10;
+ overflow: hidden;
+}
+
+/* This class only applies to annotations without icons */
+/* Old class name: .dygraphDefaultAnnotation */
+.dygraph-default-annotation {
+ border: 1px solid black;
+ background-color: white;
+ text-align: center;
+}
+
+.dygraph-axis-label {
+ /* position: absolute; */
+ /* font-size: 14px; */
+ z-index: 10;
+ line-height: normal;
+ overflow: hidden;
+ color: black; /* replaces old axisLabelColor option */
+}
+
+.dygraph-axis-label-x {
+}
+
+.dygraph-axis-label-y {
+}
+
+.dygraph-axis-label-y2 {
+}
+
+.dygraph-title {
+ font-weight: bold;
+ z-index: 10;
+ text-align: center;
+ /* font-size: based on titleHeight option */
+}
+
+.dygraph-xlabel {
+ text-align: center;
+ /* font-size: based on xLabelHeight option */
+}
+
+/* For y-axis label */
+.dygraph-label-rotate-left {
+ text-align: center;
+ /* See http://caniuse.com/#feat=transforms2d */
+ transform: rotate(90deg);
+ -webkit-transform: rotate(90deg);
+ -moz-transform: rotate(90deg);
+ -o-transform: rotate(90deg);
+ -ms-transform: rotate(90deg);
+}
+
+/* For y2-axis label */
+.dygraph-label-rotate-right {
+ text-align: center;
+ /* See http://caniuse.com/#feat=transforms2d */
+ transform: rotate(-90deg);
+ -webkit-transform: rotate(-90deg);
+ -moz-transform: rotate(-90deg);
+ -o-transform: rotate(-90deg);
+ -ms-transform: rotate(-90deg);
+}
diff --git a/src/dygraph-default-attrs.js b/src/dygraph-default-attrs.js
index 5b7cb32f9..36cbd3e7f 100644
--- a/src/dygraph-default-attrs.js
+++ b/src/dygraph-default-attrs.js
@@ -12,10 +12,6 @@ var DEFAULT_ATTRS = {
highlightSeriesBackgroundAlpha: 0.5,
highlightSeriesBackgroundColor: 'rgb(255, 255, 255)',
- labelsDivWidth: 250,
- labelsDivStyles: {
- // TODO(danvk): move defaults from createStatusMessage_ here.
- },
labelsSeparateLines: false,
labelsShowZeroValues: true,
labelsKMB: false,
@@ -67,7 +63,6 @@ var DEFAULT_ATTRS = {
axisLineColor: "black",
axisLineWidth: 0.3,
gridLineWidth: 0.3,
- axisLabelColor: "black",
axisLabelWidth: 50,
gridLineColor: "rgb(128,128,128)",
diff --git a/src/dygraph-options-reference.js b/src/dygraph-options-reference.js
index 4b1a23bf6..73615c21d 100644
--- a/src/dygraph-options-reference.js
+++ b/src/dygraph-options-reference.js
@@ -41,12 +41,6 @@ OPTIONS_REFERENCE = //
"type": "integer",
"description": "The size of the dot to draw on each point in pixels (see drawPoints). A dot is always drawn when a point is \"isolated\", i.e. there is a missing point on either side of it. This also controls the size of those dots."
},
- "labelsDivStyles": {
- "default": "null",
- "labels": ["Legend"],
- "type": "{}",
- "description": "Additional styles to apply to the currently-highlighted points div. For example, { 'fontWeight': 'bold' } will make the labels bold. In general, it is better to use CSS to style the .dygraph-legend class than to use this property."
- },
"drawPoints": {
"default": "false",
"labels": ["Data Line display"],
@@ -439,12 +433,6 @@ OPTIONS_REFERENCE = //
"example": "[10, 110]",
"description": "Explicitly set the vertical range of the graph to [low, high]. This may be set on a per-axis basis to define each y-axis separately. If either limit is unspecified, it will be calculated automatically (e.g. [null, 30] to automatically calculate just the lower bound)"
},
- "labelsDivWidth": {
- "default": "250",
- "labels": ["Legend"],
- "type": "integer",
- "description": "Width (in pixels) of the div which shows information on the currently-highlighted points."
- },
"colorSaturation": {
"default": "1.0",
"labels": ["Data Series Colors"],
@@ -695,12 +683,6 @@ OPTIONS_REFERENCE = //
"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"],
diff --git a/src/dygraph-utils.js b/src/dygraph-utils.js
index 79215d4a5..8e972a6f1 100644
--- a/src/dygraph-utils.js
+++ b/src/dygraph-utils.js
@@ -837,7 +837,6 @@ var pixelSafeOptions = {
'annotationDblClickHandler': true,
'annotationMouseOutHandler': true,
'annotationMouseOverHandler': true,
- 'axisLabelColor': true,
'axisLineColor': true,
'axisLineWidth': true,
'clickCallback': true,
@@ -855,8 +854,6 @@ var pixelSafeOptions = {
'interactionModel': true,
'isZoomedIgnoreProgrammaticZoom': true,
'labelsDiv': true,
- 'labelsDivStyles': true,
- 'labelsDivWidth': true,
'labelsKMB': true,
'labelsKMG2': true,
'labelsSeparateLines': true,
diff --git a/src/dygraph.js b/src/dygraph.js
index 3ffc2e6cd..ce9f11072 100644
--- a/src/dygraph.js
+++ b/src/dygraph.js
@@ -1029,32 +1029,28 @@ Dygraph.prototype.getPropertiesForSeries = function(series_name) {
*/
Dygraph.prototype.createRollInterface_ = function() {
// Create a roller if one doesn't exist already.
- if (!this.roller_) {
- this.roller_ = document.createElement("input");
- this.roller_.type = "text";
- this.roller_.style.display = "none";
- this.graphDiv.appendChild(this.roller_);
+ var roller = this.roller_;
+ if (!roller) {
+ this.roller_ = roller = document.createElement("input");
+ roller.type = "text";
+ roller.style.display = "none";
+ roller.className = 'dygraph-roller';
+ this.graphDiv.appendChild(roller);
}
var display = this.getBooleanOption('showRoller') ? 'block' : 'none';
- var area = this.plotter_.area;
- var textAttr = { "position": "absolute",
- "zIndex": 10,
+ var area = this.getArea();
+ var textAttr = {
"top": (area.y + area.h - 25) + "px",
"left": (area.x + 1) + "px",
"display": display
- };
- this.roller_.size = "2";
- this.roller_.value = this.rollPeriod_;
- for (var name in textAttr) {
- if (textAttr.hasOwnProperty(name)) {
- this.roller_.style[name] = textAttr[name];
- }
- }
+ };
+ roller.size = "2";
+ roller.value = this.rollPeriod_;
+ utils.update(roller.style, textAttr);
- var dygraph = this;
- this.roller_.onchange = function() { dygraph.adjustRoll(dygraph.roller_.value); };
+ roller.onchange = () => this.adjustRoll(roller.value);
};
/**
@@ -3340,7 +3336,6 @@ Dygraph.prototype.size = function() {
*/
Dygraph.prototype.setAnnotations = function(ann, suppressDraw) {
// Only add the annotation CSS rule once we know it will be used.
- Dygraph.addAnnotationRule();
this.annotations_ = ann;
if (!this.layout_) {
console.warn("Tried to setAnnotations before dygraph was ready. " +
@@ -3430,48 +3425,6 @@ Dygraph.prototype.ready = function(callback) {
}
};
-/**
- * @private
- * Adds a default style for the annotation CSS classes to the document. This is
- * only executed when annotations are actually used. It is designed to only be
- * called once -- all calls after the first will return immediately.
- */
-Dygraph.addAnnotationRule = function() {
- // TODO(danvk): move this function into plugins/annotations.js?
- if (Dygraph.addedAnnotationCSS) return;
-
- var rule = "border: 1px solid black; " +
- "background-color: white; " +
- "text-align: center;";
-
- var styleSheetElement = document.createElement("style");
- styleSheetElement.type = "text/css";
- document.getElementsByTagName("head")[0].appendChild(styleSheetElement);
-
- // Find the first style sheet that we can access.
- // We may not add a rule to a style sheet from another domain for security
- // reasons. This sometimes comes up when using gviz, since the Google gviz JS
- // adds its own style sheets from google.com.
- for (var i = 0; i < document.styleSheets.length; i++) {
- if (document.styleSheets[i].disabled) continue;
- var mysheet = document.styleSheets[i];
- try {
- if (mysheet.insertRule) { // Firefox
- var idx = mysheet.cssRules ? mysheet.cssRules.length : 0;
- mysheet.insertRule(".dygraphDefaultAnnotation { " + rule + " }", idx);
- } else if (mysheet.addRule) { // IE
- mysheet.addRule(".dygraphDefaultAnnotation", rule);
- }
- Dygraph.addedAnnotationCSS = true;
- return;
- } catch(err) {
- // Was likely a security exception.
- }
- }
-
- console.warn("Unable to add default annotation CSS rule; display may be off.");
-};
-
/**
* Add an event handler. This event handler is kept until the graph is
* destroyed with a call to graph.destroy().
diff --git a/src/plugins/annotations.js b/src/plugins/annotations.js
index 46d08918e..87153c815 100644
--- a/src/plugins/annotations.js
+++ b/src/plugins/annotations.js
@@ -56,12 +56,6 @@ annotations.prototype.didDrawChart = function(e) {
if (!points || points.length === 0) return;
var containerDiv = e.canvas.parentNode;
- var annotationStyle = {
- "position": "absolute",
- "fontSize": g.getOption('axisLabelFontSize') + "px",
- "zIndex": 10,
- "overflow": "hidden"
- };
var bindEvt = function(eventName, classEventName, pt) {
return function(annotation_event) {
@@ -75,7 +69,7 @@ annotations.prototype.didDrawChart = function(e) {
};
// Add the annotations one-by-one.
- var area = e.dygraph.plotter_.area;
+ var area = e.dygraph.getArea();
// x-coord to sum of previous annotation's heights (used for stacking).
var xToUsedHeight = {};
@@ -93,18 +87,18 @@ annotations.prototype.didDrawChart = function(e) {
tick_height = a.tickHeight;
}
+ // TODO: deprecate axisLabelFontSize in favor of CSS
var div = document.createElement("div");
- for (var name in annotationStyle) {
- if (annotationStyle.hasOwnProperty(name)) {
- div.style[name] = annotationStyle[name];
- }
- }
+ div.style['fontSize'] = g.getOption('axisLabelFontSize') + "px";
+ var className = 'dygraph-annotation';
if (!a.hasOwnProperty('icon')) {
- div.className = "dygraphDefaultAnnotation";
+ // camelCase class names are deprecated.
+ className += ' dygraphDefaultAnnotation dygraph-default-annotation';
}
if (a.hasOwnProperty('cssClass')) {
- div.className += " " + a.cssClass;
+ className += " " + a.cssClass;
}
+ div.className = className;
var width = a.hasOwnProperty('width') ? a.width : 16;
var height = a.hasOwnProperty('height') ? a.height : 16;
diff --git a/src/plugins/axes.js b/src/plugins/axes.js
index f93f36fce..2d9e31f92 100644
--- a/src/plugins/axes.js
+++ b/src/plugins/axes.js
@@ -19,6 +19,8 @@ Options left to make axis-friendly.
('xAxisHeight')
*/
+import * as utils from '../dygraph-utils';
+
/**
* Draws the axes. This includes the labels on the x- and y-axes, as well
* as the tick marks on the axes.
@@ -115,19 +117,14 @@ axes.prototype.willDrawChart = function(e) {
return {
position: 'absolute',
fontSize: g.getOptionForAxis('axisLabelFontSize', axis) + 'px',
- zIndex: 10,
- color: g.getOptionForAxis('axisLabelColor', axis),
width: g.getOptionForAxis('axisLabelWidth', axis) + 'px',
- // height: g.getOptionForAxis('axisLabelFontSize', 'x') + 2 + "px",
- lineHeight: 'normal', // Something other than "normal" line-height screws up label positioning.
- overflow: 'hidden'
};
};
var labelStyles = {
- x : makeLabelStyle('x'),
- y : makeLabelStyle('y'),
- y2 : makeLabelStyle('y2')
+ x: makeLabelStyle('x'),
+ y: makeLabelStyle('y'),
+ y2: makeLabelStyle('y2')
};
var makeDiv = function(txt, axis, prec_axis) {
@@ -139,11 +136,8 @@ axes.prototype.willDrawChart = function(e) {
*/
var div = document.createElement('div');
var labelStyle = labelStyles[prec_axis == 'y2' ? 'y2' : axis];
- for (var name in labelStyle) {
- if (labelStyle.hasOwnProperty(name)) {
- div.style[name] = labelStyle[name];
- }
- }
+ utils.update(div.style, labelStyle);
+ // TODO: combine outer & inner divs
var inner_div = document.createElement('div');
inner_div.className = 'dygraph-axis-label' +
' dygraph-axis-label-' + axis +
@@ -202,6 +196,7 @@ axes.prototype.willDrawChart = function(e) {
} else {
label.style.top = top + 'px';
}
+ // TODO: replace these with css classes?
if (tick.axis === 0) {
label.style.left = (area.x - getAxisOption('axisLabelWidth') - getAxisOption('axisTickSize')) + 'px';
label.style.textAlign = 'right';
diff --git a/src/plugins/chart-labels.js b/src/plugins/chart-labels.js
index 5fbbdc5c8..2d09fc837 100644
--- a/src/plugins/chart-labels.js
+++ b/src/plugins/chart-labels.js
@@ -79,16 +79,8 @@ var createRotatedDiv = function(g, box, axis, classes, html) {
inner_div.style.height = box.w + 'px';
inner_div.style.top = (box.h / 2 - box.w / 2) + 'px';
inner_div.style.left = (box.w / 2 - box.h / 2) + 'px';
- inner_div.style.textAlign = 'center';
-
- // CSS rotation is an HTML5 feature which is not standardized. Hence every
- // browser has its own name for the CSS style.
- var val = 'rotate(' + (axis == 1 ? '-' : '') + '90deg)';
- inner_div.style.transform = val; // HTML5
- inner_div.style.WebkitTransform = val; // Safari/Chrome
- inner_div.style.MozTransform = val; // Firefox
- inner_div.style.OTransform = val; // Opera
- inner_div.style.msTransform = val; // IE9
+ // TODO: combine inner_div and class_div.
+ inner_div.className = 'dygraph-label-rotate-' + (axis == 1 ? 'right' : 'left');
var class_div = document.createElement("div");
class_div.className = classes;
@@ -108,10 +100,7 @@ chart_labels.prototype.layout = function(e) {
// QUESTION: should this return an absolutely-positioned div instead?
var title_rect = e.reserveSpaceTop(g.getOption('titleHeight'));
this.title_div_ = createDivInRect(title_rect);
- this.title_div_.style.textAlign = 'center';
this.title_div_.style.fontSize = (g.getOption('titleHeight') - 8) + 'px';
- this.title_div_.style.fontWeight = 'bold';
- this.title_div_.style.zIndex = 10;
var class_div = document.createElement("div");
class_div.className = 'dygraph-label dygraph-title';
@@ -123,7 +112,6 @@ chart_labels.prototype.layout = function(e) {
if (g.getOption('xlabel')) {
var x_rect = e.reserveSpaceBottom(g.getOption('xLabelHeight'));
this.xlabel_div_ = createDivInRect(x_rect);
- this.xlabel_div_.style.textAlign = 'center';
this.xlabel_div_.style.fontSize = (g.getOption('xLabelHeight') - 2) + 'px';
var class_div = document.createElement("div");
diff --git a/src/plugins/legend.js b/src/plugins/legend.js
index 96e68f433..8b9184120 100644
--- a/src/plugins/legend.js
+++ b/src/plugins/legend.js
@@ -35,9 +35,6 @@ Legend.prototype.toString = function() {
return "Legend Plugin";
};
-// (defined below)
-var generateLegendDashHTML;
-
/**
* This is called during the dygraph constructor, after options have been set
* but before the data is available.
@@ -52,7 +49,6 @@ var generateLegendDashHTML;
*/
Legend.prototype.activate = function(g) {
var div;
- var divWidth = g.getOption('labelsDivWidth');
var userLabelsDiv = g.getOption('labelsDiv');
if (userLabelsDiv && null !== userLabelsDiv) {
@@ -62,35 +58,8 @@ Legend.prototype.activate = function(g) {
div = userLabelsDiv;
}
} else {
- // Default legend styles. These can be overridden in CSS by adding
- // "!important" after your rule, e.g. "left: 30px !important;"
- var messagestyle = {
- "position": "absolute",
- "fontSize": "14px",
- "zIndex": 10,
- "width": divWidth + "px",
- "top": "0px",
- "left": (g.size().width - divWidth - 2) + "px",
- "background": "white",
- "lineHeight": "normal",
- "textAlign": "left",
- "overflow": "hidden"};
-
- // TODO(danvk): get rid of labelsDivStyles? CSS is better.
- utils.update(messagestyle, g.getOption('labelsDivStyles'));
div = document.createElement("div");
div.className = "dygraph-legend";
- for (var name in messagestyle) {
- if (!messagestyle.hasOwnProperty(name)) continue;
-
- try {
- div.style[name] = messagestyle[name];
- } catch (e) {
- console.warn("You are using unsupported css properties for your " +
- "browser in labelsDivStyles");
- }
- }
-
// TODO(danvk): come up with a cleaner way to expose this.
g.graphDiv.appendChild(div);
this.is_generated_div_ = true;
@@ -136,7 +105,7 @@ Legend.prototype.select = function(e) {
if (legendMode === 'follow') {
// create floating legend div
var area = e.dygraph.plotter_.area;
- var labelsDivWidth = e.dygraph.getOption('labelsDivWidth');
+ var labelsDivWidth = this.legend_div.offsetWidth;
var yAxisLabelWidth = e.dygraph.getOptionForAxis('axisLabelWidth', 'y');
// determine floating [left, top] coordinates of the legend div
// within the plotter_ area
@@ -195,10 +164,9 @@ Legend.prototype.predraw = function(e) {
// TODO(danvk): only use real APIs for this.
e.dygraph.graphDiv.appendChild(this.legend_div_);
var area = e.dygraph.getArea();
- var labelsDivWidth = e.dygraph.getOption("labelsDivWidth");
+ var labelsDivWidth = this.legend_div_.offsetWidth;
this.legend_div_.style.left = area.x + area.w - labelsDivWidth - 1 + "px";
this.legend_div_.style.top = area.y + "px";
- this.legend_div_.style.width = labelsDivWidth + "px";
};
/**
@@ -341,12 +309,10 @@ Legend.defaultFormatter = function(data) {
* @private
*/
// TODO(danvk): cache the results of this
-generateLegendDashHTML = function(strokePattern, color, oneEmWidth) {
+function generateLegendDashHTML(strokePattern, color, oneEmWidth) {
// Easy, common case: a solid line
if (!strokePattern || strokePattern.length <= 1) {
- return "";
+ return ``;
}
var i, j, paddingLeft, marginRight;
@@ -393,10 +359,7 @@ generateLegendDashHTML = function(strokePattern, color, oneEmWidth) {
// The repeated first segment has no right margin.
marginRight = 0;
}
- dash += "";
+ dash += ``;
}
}
return dash;
From 93a5bb4c827d6665f395c48b216438f95e94d76e Mon Sep 17 00:00:00 2001
From: Dan Vanderkam
Date: Wed, 28 Sep 2016 08:45:57 -0400
Subject: [PATCH 15/54] Use CSS for tests, gallery and docs
---
docs/annotations.html | 4 +++-
gallery/border.js | 2 +-
gallery/edge-padding.js | 2 +-
gallery/index.html | 1 +
gallery/range-selector.js | 9 ++++----
gallery/styled-chart-labels.js | 9 +-------
gallery/temperature-sf-ny.js | 3 +--
tests/annotation-native.html | 1 +
tests/annotation.html | 1 +
tests/avoidMinZero.html | 1 +
tests/border.html | 5 ++++-
tests/callback.html | 1 +
tests/century-scale.html | 1 +
tests/charting-combinations.html | 1 +
tests/color-cycle.html | 1 +
tests/color-visibility.html | 1 +
tests/connect-separated.html | 1 +
tests/crosshair.html | 1 +
tests/css-positioning.html | 1 +
tests/custom-bars.html | 1 +
tests/custom-circles.html | 1 +
tests/customLabel.html | 1 +
tests/customLabelCss3.html | 19 +++++++++-------
tests/dateWindow.html | 1 +
tests/daylight-savings.html | 1 +
tests/demo.html | 1 +
tests/dense-fill.html | 1 +
tests/draw-points.html | 1 +
tests/drawing.html | 1 +
tests/dygraph-many-points-benchmark.html | 1 +
tests/dygraph.html | 1 +
tests/dynamic-update.html | 1 +
tests/exported-symbols.html | 1 +
tests/fillGraph-alpha.html | 1 +
tests/fillGraph.html | 1 +
tests/fractions.html | 1 +
tests/grid_dot.html | 1 +
tests/gviz-infinity.html | 1 +
tests/gviz-selection.html | 1 +
tests/gviz.html | 1 +
tests/hairlines.html | 1 +
tests/highlighted-region.html | 1 +
tests/hourly.html | 1 +
tests/iframe.html | 1 +
tests/independent-series.html | 1 +
tests/interaction.html | 1 +
tests/is-zoomed-ignore-programmatic-zoom.html | 1 +
tests/is-zoomed.html | 1 +
tests/isolated-points.html | 1 +
tests/label-div.html | 1 +
tests/labelsDateUTC.html | 1 +
tests/labelsKMB.html | 1 +
tests/layout-options.html | 1 +
tests/legend-formatter.html | 1 +
tests/legend-values.html | 3 ++-
tests/linear-regression-addseries.html | 1 +
tests/linear-regression-fractions.html | 1 +
tests/linear-regression.html | 1 +
tests/link-interaction.html | 1 +
tests/logscale.html | 1 +
tests/missing-data.html | 1 +
tests/multi-scale.html | 1 +
tests/native-format.html | 1 +
tests/negative.html | 1 +
tests/no-range.html | 1 +
tests/no-visibility.html | 1 +
tests/number-format.html | 1 +
tests/numeric-axis.html | 1 +
tests/numeric-gviz.html | 1 +
tests/out-of-order.html | 1 +
tests/per-series.html | 1 +
tests/perf.html | 1 +
tests/plotter.html | 1 +
tests/plotters.html | 1 +
tests/plugins.html | 1 +
tests/range-selector.html | 22 ++++++++++++++-----
tests/resize.html | 1 +
tests/reverse-y-axis.html | 1 +
tests/series-highlight.html | 1 +
tests/small-range-zero.html | 1 +
tests/smooth-plots.html | 1 +
tests/spacing.html | 1 +
tests/stacked.html | 1 +
tests/steps.html | 1 +
tests/stock.html | 1 +
tests/straw-broom.html | 1 +
tests/styled-chart-labels.html | 13 +++++------
tests/synchronize.html | 1 +
tests/temperature-sf-ny.html | 6 +++--
tests/two-axes-vr.html | 1 +
tests/two-axes.html | 1 +
tests/unboxed-spark.html | 1 +
tests/underlay-callback.html | 1 +
tests/value-axis-formatters.html | 1 +
tests/visibility.html | 1 +
tests/x-axis-formatter.html | 1 +
tests/zero-series.html | 1 +
tests/zoom.html | 1 +
98 files changed, 140 insertions(+), 43 deletions(-)
diff --git a/docs/annotations.html b/docs/annotations.html
index 0a3ba17c4..9ed49b153 100644
--- a/docs/annotations.html
+++ b/docs/annotations.html
@@ -6,6 +6,9 @@
.annotation {
font-size: 12px !important;
}
+ .dygraph-legend {
+ width: 300px;
+ }
" +
" Mode:" +
" use {x,y}RangePad" +
@@ -39,7 +40,6 @@ Gallery.register(
var g = new Dygraph(gdiv, data, {
labels: ['x', 'A', 'B'],
- labelsDivWidth: 100,
gridLineColor: '#ccc',
includeZero: true,
width: 250,
diff --git a/gallery/index.html b/gallery/index.html
index c953deb37..a749cf000 100644
--- a/gallery/index.html
+++ b/gallery/index.html
@@ -2,6 +2,7 @@
Dygraphs Gallery
+
diff --git a/gallery/range-selector.js b/gallery/range-selector.js
index 09bfd49c3..e243b43b2 100644
--- a/gallery/range-selector.js
+++ b/gallery/range-selector.js
@@ -7,6 +7,11 @@ Gallery.register(
title: 'Demo of the Range Selector',
setup: function(parent) {
parent.innerHTML = [
+ "",
"
No roll period.
",
"",
"",
@@ -27,7 +32,6 @@ Gallery.register(
title: 'Daily Temperatures in New York vs. San Francisco',
ylabel: 'Temperature (F)',
legend: 'always',
- labelsDivStyles: { 'textAlign': 'right' },
showRangeSelector: true
}
);
@@ -41,7 +45,6 @@ Gallery.register(
title: 'Daily Temperatures in New York vs. San Francisco',
ylabel: 'Temperature (F)',
legend: 'always',
- labelsDivStyles: { 'textAlign': 'right' },
showRangeSelector: true,
rangeSelectorHeight: 30,
rangeSelectorPlotStrokeColor: 'yellow',
@@ -58,11 +61,9 @@ Gallery.register(
title: 'Nightly Temperatures in New York vs. San Francisco',
ylabel: 'Temperature (F)',
legend: 'always',
- labelsDivStyles: { 'textAlign': 'right', 'backgroundColor': '#101015' },
showRangeSelector: true,
rangeSelectorPlotFillColor: 'MediumSlateBlue',
rangeSelectorPlotFillGradientColor: 'rgba(123, 104, 238, 0)',
- axisLabelColor: 'white',
colorValue: 0.9,
fillAlpha: 0.4
}
diff --git a/gallery/styled-chart-labels.js b/gallery/styled-chart-labels.js
index 0268f6dcd..6f8c3b46a 100644
--- a/gallery/styled-chart-labels.js
+++ b/gallery/styled-chart-labels.js
@@ -6,6 +6,7 @@ Gallery.register(
title: 'Each chart label is styled independently with CSS',
setup: function(parent) {
parent.innerHTML = [
+ "",
"
This chart's labels are styled
",
"",
"
This version of the chart uses the default styles:
",
@@ -21,10 +22,6 @@ Gallery.register(
titleHeight: 32,
ylabel: 'Temperature (F)',
xlabel: 'Date (Ticks indicate the start of the indicated time period)',
- labelsDivStyles: {
- 'text-align': 'right',
- 'background': 'none'
- },
strokeWidth: 1.5
}
);
@@ -37,10 +34,6 @@ Gallery.register(
title: 'High and Low Temperatures (30-day average)',
ylabel: 'Temperature (F)',
xlabel: 'Date (Ticks indicate the start of the indicated time period)',
- labelsDivStyles: {
- 'text-align': 'right',
- 'background': 'none'
- },
strokeWidth: 1.5
}
);
diff --git a/gallery/temperature-sf-ny.js b/gallery/temperature-sf-ny.js
index f2c9ad134..7e4131016 100644
--- a/gallery/temperature-sf-ny.js
+++ b/gallery/temperature-sf-ny.js
@@ -8,6 +8,7 @@ Gallery.register(
title: 'Demo of a graph with many data points and custom error bars.',
setup: function(parent) {
parent.innerHTML = [
+ "",
"
Roll period of 14 timesteps.
",
"",
"
No roll period.
",
@@ -23,7 +24,6 @@ Gallery.register(
title: 'Daily Temperatures in New York vs. San Francisco',
ylabel: 'Temperature (F)',
legend: 'always',
- labelsDivStyles: { 'textAlign': 'right' }
}
);
new Dygraph(
@@ -36,7 +36,6 @@ Gallery.register(
title: 'Daily Temperatures in New York vs. San Francisco',
ylabel: 'Temperature (F)',
legend: 'always',
- labelsDivStyles: { 'textAlign': 'right' }
}
);
}
diff --git a/tests/annotation-native.html b/tests/annotation-native.html
index a00349706..4e4538d87 100644
--- a/tests/annotation-native.html
+++ b/tests/annotation-native.html
@@ -1,6 +1,7 @@
+
Native format annotations
diff --git a/tests/annotation.html b/tests/annotation.html
index 6d477e235..4cdcb101a 100644
--- a/tests/annotation.html
+++ b/tests/annotation.html
@@ -1,6 +1,7 @@
+
demo
-
-
-
-
-
-
-
isZoomedIgnoreProgrammaticZoom Option
-
- By default, when the dateWindow or updateOptions
- of a chart is changed programmatically by a call to updateOptions
- the zoomed flags (isZoomed) are changed. This is the same
- as manually zooming in using the mouse.
-
-
- Sometimes it may be desirable to change the display of the chart by
- manipulating the dateWindow and valueRange
- options but without changing the zoomed flags, for example where manual
- zooming is still required but where it is also desired that the zoomed
- flags drive display elements, but only for manual zooming.
-
-
- In this case isZoomedIgnoreProgrammaticZoom may be specified along with
- either the dateWindow or valueRange values to
- updateOptions and the zoomed flags will remain unaffected.
-
-
- The chart below may be manipulated to change the updateOptions
- using the Max and Min Y axis buttons and the dateWindow
- by using the Max and Min X axis buttons.
-
-
- Toggle the check box below to determine the difference in operation of the zoom flags
- when the date and value windows of the chart are changed using the arrows underneath.
-
-
Do not change zoom flags (isZoomedIgnoreProgrammaticZoom)
dygraphs is a fast, flexible open source JavaScript charting library.
-
+
@@ -33,14 +33,12 @@
-
diff --git a/tests/annotation-native.html b/tests/annotation-native.html
index 4e4538d87..53ce249e3 100644
--- a/tests/annotation-native.html
+++ b/tests/annotation-native.html
@@ -1,7 +1,7 @@
-
+
Native format annotations
diff --git a/tests/annotation.html b/tests/annotation.html
index 002d4ddce..c180070ff 100644
--- a/tests/annotation.html
+++ b/tests/annotation.html
@@ -1,15 +1,8 @@
-
+
demo
-
-
",
"",
"Zoom:",
"hour ",
@@ -14,7 +16,8 @@ Gallery.register(
"full ",
"Pan: ",
"left ",
- "right "].join("\n");
+ "right ",
+ ""].join("\n");
},
run: function() {
var r = [ ];
diff --git a/package.json b/package.json
index ededf3f19..5eb7b2493 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "dygraphs",
- "version": "2.0.0-rc2",
+ "version": "2.0.0-rc3",
"description": "dygraphs is a fast, flexible open source JavaScript charting library.",
"main": "index.es5",
"module": "index",
diff --git a/tests/link-interaction.html b/tests/link-interaction.html
index d2192fcfb..3a61efcea 100644
--- a/tests/link-interaction.html
+++ b/tests/link-interaction.html
@@ -4,7 +4,11 @@
noise
-
+
From 87ba46ff9fb4ff7a160859bd0498844c179ce21a Mon Sep 17 00:00:00 2001
From: Dan Vanderkam
Date: Wed, 28 Dec 2016 20:49:05 -0500
Subject: [PATCH 31/54] Rework the README a bit
---
README.md | 54 ++++++++++++++++++++++++++++++++++++++++++------------
1 file changed, 42 insertions(+), 12 deletions(-)
diff --git a/README.md b/README.md
index 8e639e510..e539994d9 100644
--- a/README.md
+++ b/README.md
@@ -7,18 +7,16 @@ The dygraphs JavaScript library produces interactive, zoomable charts of time se
Learn more about it at [dygraphs.com](http://www.dygraphs.com).
-Get help with dygraphs on
-[Stack Overflow](http://stackoverflow.com/questions/tagged/dygraphs) (preferred) and
-[Google Groups](http://groups.google.com/group/dygraphs-users)
+Get help with dygraphs by browsing the on [Stack Overflow][] (preferred) and [Google Groups][].
## Features
* Plots time series without using an external server or Flash
-* Supports [error bands](http://dygraphs.com/tests/legend-values.html) around data series
-* Interactive [pan and zoom](http://dygraphs.com/tests/link-interaction.html)
-* Displays values [on mouseover](http://dygraphs.com/tests/legend-values.html)
-* Adjustable [averaging period](http://dygraphs.com/tests/temperature-sf-ny.html)
-* Extensive set of [options](http://www.dygraphs.com/options.html) for customization.
-* Compatible with the [Google Visualization API](http://dygraphs.com/data.html#datatable)
+* Supports [error bands][] around data series
+* Interactive [pan and zoom][]
+* Displays values [on mouseover][]
+* Adjustable [averaging period][]
+* Extensive set of [options][] for customization.
+* Compatible with the [Google Visualization API][gviz]
## Minimal Example
```html
@@ -43,9 +41,27 @@ Get help with dygraphs on
```
-Learn more by reading [the tutorial](http://www.dygraphs.com/tutorial.html) and
-seeing demonstrations of what dygraphs can do in the
-[gallery](http://www.dygraphs.com/gallery).
+Learn more by reading [the tutorial][] and seeing demonstrations of what
+dygraphs can do in the [gallery][]. You can get `dygraph.js` and `dygraph.css`
+from [cdnjs][] or [from NPM][npm] (see below).
+
+## Usage with a module loader
+
+Get dygraphs from NPM:
+
+ npm install dygraphs
+
+You'll find pre-built JS & CSS files in `node_modules/dygraphs/dist`. If you're
+using a module bundler like browserify or webpack, you can import dygraphs:
+
+```js
+import Dygraph from 'dygraphs';
+// or: const Dygraph = require('dygraphs');
+
+const g = new Dygraph('graphdiv', data, { /* options */ });
+```
+
+Check out the [dygraphs-es6 repo][] for a fully-worked example.
## Development
@@ -60,3 +76,17 @@ Read more about the dygraphs development process in the [developer guide](/DEVEL
## License(s)
dygraphs is available under the MIT license, included in LICENSE.txt.
+
+[cdnjs]: https://cdnjs.com/libraries/dygraph
+[the tutorial]: http://www.dygraphs.com/tutorial.html
+[gallery]: http://www.dygraphs.com/gallery
+[error bands]: http://dygraphs.com/tests/legend-values.html
+[pan and zoom]: http://dygraphs.com/tests/link-interaction.html
+[on mouseover]: http://dygraphs.com/tests/legend-values.html
+[averaging period]: http://dygraphs.com/tests/temperature-sf-ny.html
+[options]: http://www.dygraphs.com/options.html
+[Stack Overflow]: http://stackoverflow.com/questions/tagged/dygraphs?sort=votes&pageSize=50
+[Google Groups]: http://groups.google.com/group/dygraphs-users
+[gviz]: http://dygraphs.com/data.html#datatable
+[npm]: https://www.npmjs.com/package/dygraphs
+[dygraphs-es6 repo]: https://github.com/danvk/dygraphs-es6
From f808e16e56550f5260f4cf8c335424925e23e6b5 Mon Sep 17 00:00:00 2001
From: Dan Vanderkam
Date: Sun, 8 Jan 2017 12:13:28 -0500
Subject: [PATCH 32/54] revert change to demo.html from 1.1.1
---
tests/demo.html | 1 -
1 file changed, 1 deletion(-)
diff --git a/tests/demo.html b/tests/demo.html
index 845e7eed7..83dff455e 100644
--- a/tests/demo.html
+++ b/tests/demo.html
@@ -46,7 +46,6 @@
Interactive out of the box: zoom, pan and mouseover are on by default.
Strong support for error bars / confidence intervals.
Highly customizable: using options and custom callbacks, you can make dygraphs do almost anything.
-
dygraphs is highly compatible: it works in all major browsers (including IE8). You can even pinch to zoom on mobile/tablet devices!
+
dygraphs is works in all recent browsers. You can even pinch to zoom on mobile/tablet devices!
There's an active community developing and supporting dygraphs.
diff --git a/src/dygraph.js b/src/dygraph.js
index 8e6d6e04c..d5036690e 100644
--- a/src/dygraph.js
+++ b/src/dygraph.js
@@ -3010,6 +3010,7 @@ Dygraph.prototype.parseDataTable_ = function(data) {
/**
* Signals to plugins that the chart data has updated.
* This happens after the data has updated but before the chart has redrawn.
+ * @private
*/
Dygraph.prototype.cascadeDataDidUpdateEvent_ = function() {
// TODO(danvk): there are some issues checking xAxisRange() and using
@@ -3142,6 +3143,7 @@ Dygraph.prototype.updateOptions = function(input_attrs, block_redraw) {
/**
* Make a copy of input attributes, removing file as a convenience.
+ * @private
*/
Dygraph.copyUserAttrs_ = function(attrs) {
var my_attrs = {};
From 0a31d41e94fae75808da6caa36e96fcdd40fd23f Mon Sep 17 00:00:00 2001
From: Dan Vanderkam
Date: Wed, 11 Jan 2017 11:52:45 -0500
Subject: [PATCH 34/54] =?UTF-8?q?Bump=20to=20version=202=20=F0=9F=8E=89?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
package.json | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/package.json b/package.json
index 5eb7b2493..b1ebdae04 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "dygraphs",
- "version": "2.0.0-rc3",
+ "version": "2.0.0",
"description": "dygraphs is a fast, flexible open source JavaScript charting library.",
"main": "index.es5",
"module": "index",
From aa0b189f8cb22d64ce65cc9b205c90f6e4fd1257 Mon Sep 17 00:00:00 2001
From: Dan Vanderkam
Date: Wed, 8 Feb 2017 13:20:36 -0500
Subject: [PATCH 35/54] Make dblclick event cancelable. (#840)
Add demo of how to restore the dygraphs 1.x zoom out behavior.
---
src/dygraph-interaction-model.js | 3 +-
src/dygraph.js | 1 +
tests/old-yrange-behavior.html | 64 ++++++++++++++++++++++++++++++++
3 files changed, 67 insertions(+), 1 deletion(-)
create mode 100644 tests/old-yrange-behavior.html
diff --git a/src/dygraph-interaction-model.js b/src/dygraph-interaction-model.js
index 349fd3e57..494b63849 100644
--- a/src/dygraph-interaction-model.js
+++ b/src/dygraph-interaction-model.js
@@ -706,7 +706,8 @@ DygraphInteraction.defaultModel = {
// Give plugins a chance to grab this event.
var e = {
canvasx: context.dragEndX,
- canvasy: context.dragEndY
+ canvasy: context.dragEndY,
+ cancelable: true,
};
if (g.cascadeEvents_('dblclick', e)) {
return;
diff --git a/src/dygraph.js b/src/dygraph.js
index d5036690e..61e96f7f2 100644
--- a/src/dygraph.js
+++ b/src/dygraph.js
@@ -1350,6 +1350,7 @@ Dygraph.prototype.resetZoom = function() {
const zoomCallback = this.getFunctionOption('zoomCallback');
// TODO(danvk): merge this block w/ the code below.
+ // TODO(danvk): factor out a generic, public zoomTo method.
if (!animatedZooms) {
this.dateWindow_ = null;
this.axes_.forEach(axis => {
diff --git a/tests/old-yrange-behavior.html b/tests/old-yrange-behavior.html
new file mode 100644
index 000000000..d70ff1a5b
--- /dev/null
+++ b/tests/old-yrange-behavior.html
@@ -0,0 +1,64 @@
+
+
+
+
+ Old y-axis range behavior
+
+
+
+
+
+
Old y-axis range behavior
+
In dygraphs 1.x, if you set a valueRange for the y-axis, zoomed in and then double-clicked to zoom out, then the chart would zoom out to the valueRange that you specified.
+
Starting with dygraphs 2, double-clicking will zoom out to the full range of the chart's data. This makes the x- and y-axes behave identically.
+
This demo shows you how to get the old behavior in dygraphs 2 using a plugin. View source to see how.
+
+
+
+
+
+
+
From c0e7b6254d879d6ccbfdd97b88eb904cc09cc9c1 Mon Sep 17 00:00:00 2001
From: klemens
Date: Tue, 14 Feb 2017 22:17:25 +0100
Subject: [PATCH 36/54] spelling fixes
---
docs/site.css | 2 +-
docs/ssi_server.py | 2 +-
gallery/number-format.js | 2 +-
scripts/check-no-only.sh | 2 +-
src/dygraph-options-reference.js | 2 +-
src/dygraph-utils.js | 6 +++---
src/dygraph.js | 2 +-
tests/number-format.html | 2 +-
8 files changed, 10 insertions(+), 10 deletions(-)
diff --git a/docs/site.css b/docs/site.css
index 58232d73e..308ba7ad7 100644
--- a/docs/site.css
+++ b/docs/site.css
@@ -32,7 +32,7 @@ body {
}
}
@media screen and (min-width: 768px) and (max-width: 992px) {
- /* The topnav drops down to the next line between these sizes. We must accomodate. */
+ /* The topnav drops down to the next line between these sizes. We must accommodate. */
body {
padding-top: 130px;
}
diff --git a/docs/ssi_server.py b/docs/ssi_server.py
index bf20b3837..d8386736e 100755
--- a/docs/ssi_server.py
+++ b/docs/ssi_server.py
@@ -9,7 +9,7 @@
-Run ./ssi_server.py in this directory and visit localhost:8000 for an exmaple.
+Run ./ssi_server.py in this directory and visit localhost:8000 for an example.
'''
import os
diff --git a/gallery/number-format.js b/gallery/number-format.js
index cc3d22fcb..e7d0d4039 100644
--- a/gallery/number-format.js
+++ b/gallery/number-format.js
@@ -5,7 +5,7 @@ Gallery.register(
name: 'Number formatting',
setup: function(parent) {
parent.innerHTML =
- "
The default formatting mimicks printf with %.pg where p is" +
+ "
The default formatting mimics printf with %.pg where p is" +
" the precision to use. It turns out that JavaScript's toPrecision()" +
" method is almost but not exactly equal to %g; they differ for values" +
" with small absolute values (10^-1 to 10^-5 or so), with toPrecision()" +
diff --git a/scripts/check-no-only.sh b/scripts/check-no-only.sh
index 0977ec109..dc47eeb96 100755
--- a/scripts/check-no-only.sh
+++ b/scripts/check-no-only.sh
@@ -1,5 +1,5 @@
#!/bin/bash
-# Checks that no ".only" has made it into tests. This should never be commited,
+# Checks that no ".only" has made it into tests. This should never be committed,
# since it will disable the vast majority of tests.
if grep -R '\.only(' auto_tests/tests; then
diff --git a/src/dygraph-options-reference.js b/src/dygraph-options-reference.js
index 4a066bb9f..3bf2a56a5 100644
--- a/src/dygraph-options-reference.js
+++ b/src/dygraph-options-reference.js
@@ -586,7 +586,7 @@ OPTIONS_REFERENCE = //
"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."
+ "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% passed the edges of the displayed values. null means no bounds."
},
"title": {
"labels": ["Chart labels"],
diff --git a/src/dygraph-utils.js b/src/dygraph-utils.js
index a9e4b221e..dabd4ea97 100644
--- a/src/dygraph-utils.js
+++ b/src/dygraph-utils.js
@@ -42,7 +42,7 @@ export var logRangeFraction = function(r0, r1, pct) {
// Original calcuation:
// pct = (log(x) - log(xRange[0])) / (log(xRange[1]) - log(xRange[0])));
//
- // Multiply both sides by the right-side demoninator.
+ // Multiply both sides by the right-side denominator.
// pct * (log(xRange[1] - log(xRange[0]))) = log(x) - log(xRange[0])
//
// add log(xRange[0]) to both sides
@@ -265,7 +265,7 @@ export function isValidPoint(p, opt_allowNaNY) {
};
/**
- * Number formatting function which mimicks the behavior of %g in printf, i.e.
+ * Number formatting function which mimics the behavior of %g in printf, i.e.
* either exponential or fixed format (without trailing 0s) is used depending on
* the length of the generated string. The advantage of this format is that
* there is a predictable upper bound on the resulting string length,
@@ -377,7 +377,7 @@ export function hmsString_(hh, mm, ss, ms) {
/**
* Convert a JS date (millis since epoch) to a formatted string.
* @param {number} time The JavaScript time value (ms since epoch)
- * @param {boolean} utc Wether output UTC or local time
+ * @param {boolean} utc Whether output UTC or local time
* @return {string} A date of one of these forms:
* "YYYY/MM/DD", "YYYY/MM/DD HH:MM" or "YYYY/MM/DD HH:MM:SS"
* @private
diff --git a/src/dygraph.js b/src/dygraph.js
index 61e96f7f2..ba4473925 100644
--- a/src/dygraph.js
+++ b/src/dygraph.js
@@ -3126,7 +3126,7 @@ Dygraph.prototype.updateOptions = function(input_attrs, block_redraw) {
if (file) {
// This event indicates that the data is about to change, but hasn't yet.
- // TODO(danvk): support cancelation of the update via this event.
+ // TODO(danvk): support cancellation of the update via this event.
this.cascadeEvents_('dataWillUpdate', {});
this.file_ = file;
diff --git a/tests/number-format.html b/tests/number-format.html
index f85cf02b6..f722ff25e 100644
--- a/tests/number-format.html
+++ b/tests/number-format.html
@@ -7,7 +7,7 @@
-
The default formatting mimicks printf with %.pg where p is
+
The default formatting mimics printf with %.pg where p is
the precision to use. It turns out that JavaScript's toPrecision()
method is almost but not exactly equal to %g; they differ for values
with small absolute values (10^-1 to 10^-5 or so), with toPrecision()
From f160e4ac8166f74d1f0e5604061564fbca5ba5a5 Mon Sep 17 00:00:00 2001
From: Drew Inglis
Date: Tue, 2 May 2017 17:10:40 -0400
Subject: [PATCH 37/54] Fix two inconsistencies in dygraph-externs.js (#859)
1. The second argument of getOption should be marked as optional per
jsdoc at: http://dygraphs.com/jsdoc/symbols/Dygraph.html#getOption
2. 'boolean' is typo'd as 'Boolean' in updateOptions.
---
dygraph-externs.js | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/dygraph-externs.js b/dygraph-externs.js
index 9cf956801..02330f8f5 100644
--- a/dygraph-externs.js
+++ b/dygraph-externs.js
@@ -40,7 +40,7 @@ Dygraph.prototype.isZoomed;
/** @type {function(): string} */
Dygraph.prototype.toString;
-/** @type {function(string, string)} */
+/** @type {function(string, string=)} */
Dygraph.prototype.getOption;
/** @type {function(): number} */
@@ -127,7 +127,7 @@ Dygraph.prototype.isSeriesLocked;
/** @type {function(): number} */
Dygraph.prototype.numAxes;
-/** @type {function(Object, Boolean=)} */
+/** @type {function(Object, boolean=)} */
Dygraph.prototype.updateOptions;
/** @type {function(number, number)} */
From 00eebc92ec7d1846599bf233dbc63b9ea3ac3095 Mon Sep 17 00:00:00 2001
From: Robert Konigsberg
Date: Tue, 2 May 2017 17:11:44 -0400
Subject: [PATCH 38/54] Make setAnnotations' boolean parameter optional. (#851)
---
dygraph-externs.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/dygraph-externs.js b/dygraph-externs.js
index 02330f8f5..e8e2c4203 100644
--- a/dygraph-externs.js
+++ b/dygraph-externs.js
@@ -142,7 +142,7 @@ Dygraph.prototype.visibility;
/** @type {function(number, boolean)} */
Dygraph.prototype.setVisibility;
-/** @type {function(Array.