From 5afb1f1639339cc5cf2a21aa015e6eed82003cb8 Mon Sep 17 00:00:00 2001 From: Petr Shevtsov Date: Mon, 26 Jan 2015 16:42:21 +0300 Subject: [PATCH 01/11] Initial commit --- extras/ribbon.js | 79 ++++++++++++++++++++++++++ tests/ribbon.html | 142 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 221 insertions(+) create mode 100644 extras/ribbon.js create mode 100644 tests/ribbon.html diff --git a/extras/ribbon.js b/extras/ribbon.js new file mode 100644 index 000000000..131c88e50 --- /dev/null +++ b/extras/ribbon.js @@ -0,0 +1,79 @@ +/** + * @license + * Copyright 2015 Petr Shevtsov (petr.shevtsov@gmail.com) + * MIT-licensed (http://opensource.org/licenses/MIT) + */ + +/*global Dygraph:false */ + +Dygraph.Plugins.Ribbon = (function() { + "use strict"; + + var ribbon = function(options) { + options = options || {}; + + this.ribbonData_ = options.data || null; + this.ribbonDataParser_ = options.parser || null; + this.ribbonOptions_ = options.options || {}; + + var defaultOptions = { + palette: [ + "transparent", + "#ef2929", + "#8ae234" + ], + height: 1, + position: 0 + }; + + this.ribbonOptions_ = Dygraph.update(defaultOptions, this.ribbonOptions_); + this.ribbonOptions_.height = Math.min(this.ribbonOptions_.height, 1); + this.ribbonOptions_.height = Math.max(this.ribbonOptions_.height, 0); + this.ribbonOptions_.position = Math.min(this.ribbonOptions_.position, 1); + this.ribbonOptions_.position = Math.max(this.ribbonOptions_.position, 0); + }; + + ribbon.prototype.toString = function() { + return "Ribbon Plugin"; + }; + + ribbon.prototype.activate = function(g) { + if (this.ribbonData_ !== null || this.ribbonDataParser_ !== null) { + return { + willDrawChart: this.willDrawChart + }; + } + }; + + ribbon.prototype.decodeColor = function(val) { + var max = Math.max.apply(null, this.ribbonData_); + val = val / max; + var idx = Math.ceil((this.ribbonOptions_.palette.length - 1) * val); + + return this.ribbonOptions_.palette[idx]; + }; + + ribbon.prototype.willDrawChart = function(e) { + var g = e.dygraph; + var layout = g.layout_; + var points = layout.points[0]; + var area = layout.getPlotArea(); + if (this.ribbonData_ === null) { + this.ribbonData_ = this.ribbonDataParser_(g.rawData_, g); + } + for (var i = 0; i < points.length; i++) { + var point = points[i]; + var nextpoint = points[i + 1]; + + var left = g.toDomCoords(point.xval, 0)[0]; + var right = (nextpoint === undefined) ? g.canvas_.width : g.toDomCoords(nextpoint.xval, 0)[0]; + var color = this.decodeColor(this.ribbonData_[point.idx]); + var y = area.h * (1 - this.ribbonOptions_.height) + area.y; + var h = (area.h - area.h * this.ribbonOptions_.position) - y; + g.hidden_ctx_.fillStyle = color; + g.hidden_ctx_.fillRect(left, y, right - left, h); + } + }; + + return ribbon; +})(); diff --git a/tests/ribbon.html b/tests/ribbon.html new file mode 100644 index 000000000..cf630db2d --- /dev/null +++ b/tests/ribbon.html @@ -0,0 +1,142 @@ + + + + Colored Ribbon demo + + + + +

Colored Ribbon demo

+ +

Colored Ribbon with default options

+
+ +

Colored Ribbon with Encoded colors in data column

+
+ +

Colored Ribbon with customized height

+
+ +

Colored Ribbon with customized position

+
+ +

Colored Ribbon with customized colors

+
+ + + + From ebbb35db14fbcce24ea935f747bdaed7d9bf58fc Mon Sep 17 00:00:00 2001 From: Petr Shevtsov Date: Mon, 26 Jan 2015 18:07:07 +0300 Subject: [PATCH 02/11] Plugin's options reference --- extras/ribbon.js | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/extras/ribbon.js b/extras/ribbon.js index 131c88e50..466012573 100644 --- a/extras/ribbon.js +++ b/extras/ribbon.js @@ -2,6 +2,25 @@ * @license * Copyright 2015 Petr Shevtsov (petr.shevtsov@gmail.com) * MIT-licensed (http://opensource.org/licenses/MIT) + * + * Plugin options: + * + * `data`: Array of numeric values (0-1) corresponding to the position + * in the pallete interval. + * + * `parser`: Function (`function (data, dygraph)`) returning the array of numeric + * values. Function arguments: raw data, dygraph instance. + * + * `options`: Object with the following properties: + * + * `palette`: Colors Array. Default: ["transparent", "#ef2929", "#8ae234"] + * + * `height`: Value (0-1) representing the height of the ribbon: 1 - full height, + * 0.5 - 50% height and so on. + * + * `position`: Value (0-1) representing the start position of the ribbon: + * 0 - start from the bottom of chart, 0.25 - start from the 25% of the chart + * height and so on. */ /*global Dygraph:false */ From 1bd787635b7166e449a264592f1ceda419c10e3a Mon Sep 17 00:00:00 2001 From: Petr Shevtsov Date: Wed, 28 Jan 2015 16:10:22 +0300 Subject: [PATCH 03/11] Rename some options parameters names Rename `height` and `position` parameter names into `top` and `bottom` correspondingly. --- extras/ribbon.js | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/extras/ribbon.js b/extras/ribbon.js index 466012573..16eeb87ca 100644 --- a/extras/ribbon.js +++ b/extras/ribbon.js @@ -15,12 +15,11 @@ * * `palette`: Colors Array. Default: ["transparent", "#ef2929", "#8ae234"] * - * `height`: Value (0-1) representing the height of the ribbon: 1 - full height, - * 0.5 - 50% height and so on. + * `top`: Value (0-1) representing the top of the ribbon: 1 - height of the chart, + * 0.5 - 50% height of the chart and so on. * - * `position`: Value (0-1) representing the start position of the ribbon: - * 0 - start from the bottom of chart, 0.25 - start from the 25% of the chart - * height and so on. + * `bottom`: Value (0-1) representing the bottom of the ribbon: + * 0 - the bottom of chart, 0.25 - 25% of the chart height and so on. */ /*global Dygraph:false */ @@ -41,15 +40,18 @@ Dygraph.Plugins.Ribbon = (function() { "#ef2929", "#8ae234" ], - height: 1, - position: 0 + top: 1, + bottom: 0 }; this.ribbonOptions_ = Dygraph.update(defaultOptions, this.ribbonOptions_); - this.ribbonOptions_.height = Math.min(this.ribbonOptions_.height, 1); - this.ribbonOptions_.height = Math.max(this.ribbonOptions_.height, 0); - this.ribbonOptions_.position = Math.min(this.ribbonOptions_.position, 1); - this.ribbonOptions_.position = Math.max(this.ribbonOptions_.position, 0); + this.ribbonOptions_.top = Math.min(this.ribbonOptions_.top, 1); + this.ribbonOptions_.top = Math.max(this.ribbonOptions_.top, 0); + this.ribbonOptions_.bottom = Math.min(this.ribbonOptions_.bottom, 1); + this.ribbonOptions_.bottom = Math.max(this.ribbonOptions_.bottom, 0); + + this.ribbonOptions_.top = Math.max(this.ribbonOptions_.top, this.ribbonOptions_.bottom); + this.ribbonOptions_.bottom = Math.min(this.ribbonOptions_.top, this.ribbonOptions_.bottom); }; ribbon.prototype.toString = function() { @@ -87,8 +89,8 @@ Dygraph.Plugins.Ribbon = (function() { var left = g.toDomCoords(point.xval, 0)[0]; var right = (nextpoint === undefined) ? g.canvas_.width : g.toDomCoords(nextpoint.xval, 0)[0]; var color = this.decodeColor(this.ribbonData_[point.idx]); - var y = area.h * (1 - this.ribbonOptions_.height) + area.y; - var h = (area.h - area.h * this.ribbonOptions_.position) - y; + var y = area.h * (1 - this.ribbonOptions_.top) + area.y; + var h = (area.h - area.h * this.ribbonOptions_.bottom) - y; g.hidden_ctx_.fillStyle = color; g.hidden_ctx_.fillRect(left, y, right - left, h); } From 88ed607f0042a6b68ea974cc340bce36468010a5 Mon Sep 17 00:00:00 2001 From: Petr Shevtsov Date: Mon, 23 Mar 2015 23:04:04 +0300 Subject: [PATCH 04/11] Spelling --- extras/ribbon.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extras/ribbon.js b/extras/ribbon.js index 16eeb87ca..342025001 100644 --- a/extras/ribbon.js +++ b/extras/ribbon.js @@ -6,7 +6,7 @@ * Plugin options: * * `data`: Array of numeric values (0-1) corresponding to the position - * in the pallete interval. + * in the palette interval. * * `parser`: Function (`function (data, dygraph)`) returning the array of numeric * values. Function arguments: raw data, dygraph instance. From 7cb2000ff03d7c1538e7067b39bce3c7168a6a5c Mon Sep 17 00:00:00 2001 From: Petr Shevtsov Date: Mon, 23 Mar 2015 23:11:35 +0300 Subject: [PATCH 05/11] Adding missing values to prevent error messages --- tests/ribbon.html | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/ribbon.html b/tests/ribbon.html index cf630db2d..498a7ca4a 100644 --- a/tests/ribbon.html +++ b/tests/ribbon.html @@ -52,15 +52,15 @@

Colored Ribbon with customized colors

function data_color() { return "Date,High,Low,Color\n" + - "20070101,62,39\n" + + "20070101,62,39,0\n" + "20070102,62,44,0.5\n" + "20070103,62,42,0.5\n" + "20070104,57,45,1\n" + "20070105,54,44,1\n" + "20070106,55,36,1\n" + - "20070107,62,45\n" + - "20070108,66,48\n" + - "20070109,63,39\n" + + "20070107,62,45,0\n" + + "20070108,66,48,0\n" + + "20070109,63,39,0\n" + "20070110,57,37,0.5\n"; } From bb299e71621163c8ce6d20878d3bf657124ae981 Mon Sep 17 00:00:00 2001 From: Petr Shevtsov Date: Mon, 23 Mar 2015 23:12:13 +0300 Subject: [PATCH 06/11] Hide colors column --- tests/ribbon.html | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/ribbon.html b/tests/ribbon.html index 498a7ca4a..088d648e3 100644 --- a/tests/ribbon.html +++ b/tests/ribbon.html @@ -84,6 +84,7 @@

Colored Ribbon with customized colors

document.getElementById("div_g2"), data_color, { + visibility: [true, true, false], // Hide colors column plugins: [ribbon] } ); From 3d346fd0a116557222d899f74085f1ab6bb1c4f6 Mon Sep 17 00:00:00 2001 From: Petr Shevtsov Date: Mon, 23 Mar 2015 23:12:29 +0300 Subject: [PATCH 07/11] Use new parameter names --- tests/ribbon.html | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/ribbon.html b/tests/ribbon.html index 088d648e3..69bbd20c1 100644 --- a/tests/ribbon.html +++ b/tests/ribbon.html @@ -92,7 +92,7 @@

Colored Ribbon with customized colors

ribbon = new Dygraph.Plugins.Ribbon({ data: [0, 0.5, 0.5, 1, 1, 1, 0, 0, 0, 0.5], options: { - height: 0.75 + top: 0.75 } }); @@ -107,8 +107,8 @@

Colored Ribbon with customized colors

ribbon = new Dygraph.Plugins.Ribbon({ data: [0, 0.5, 0.5, 1, 1, 1, 0, 0, 0, 0.5], options: { - height: 0.75, - position: 0.25 + top: 0.75, + bottom: 0.25 } }); From 25751f74d8467ff829fa1125f04dce3de4b1bbba Mon Sep 17 00:00:00 2001 From: Petr Shevtsov Date: Mon, 8 Jun 2015 22:51:59 +0300 Subject: [PATCH 08/11] Move extras/ribbon.js to src/extras/ribbon.js --- {extras => src/extras}/ribbon.js | 0 tests/ribbon.html | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename {extras => src/extras}/ribbon.js (100%) diff --git a/extras/ribbon.js b/src/extras/ribbon.js similarity index 100% rename from extras/ribbon.js rename to src/extras/ribbon.js diff --git a/tests/ribbon.html b/tests/ribbon.html index 69bbd20c1..bb0000763 100644 --- a/tests/ribbon.html +++ b/tests/ribbon.html @@ -3,7 +3,7 @@ Colored Ribbon demo - +

Colored Ribbon demo

From c342d03cf87ebe548ec4bdaac65d63c86ba11906 Mon Sep 17 00:00:00 2001 From: Petr Shevtsov Date: Mon, 8 Jun 2015 23:04:27 +0300 Subject: [PATCH 09/11] Update documentation --- src/extras/ribbon.js | 37 +++++++++++++++++++++++++++---------- 1 file changed, 27 insertions(+), 10 deletions(-) diff --git a/src/extras/ribbon.js b/src/extras/ribbon.js index 342025001..92ed03174 100644 --- a/src/extras/ribbon.js +++ b/src/extras/ribbon.js @@ -3,23 +3,40 @@ * Copyright 2015 Petr Shevtsov (petr.shevtsov@gmail.com) * MIT-licensed (http://opensource.org/licenses/MIT) * + * Ribbon is a horizontal band of colors that runs through the chart. It can be useful + * to visualize categorical variables (http://en.wikipedia.org/wiki/Categorical_variable) + * that change over time (along the x-axis). For example multiple states of economy + * like "bust", "recession", "recovery", "boom" can be encoded as [0, 1, 2, 3] + * respectively (or normalized as [0, 0.33, 0.66, 1]) and assigned colors + * ["red","orange","green","purple"]. + * * Plugin options: * - * `data`: Array of numeric values (0-1) corresponding to the position - * in the palette interval. + * `data`: Array of numeric values in the range from 0 to 1. Ribbon data array + * must be of same length as number of rows of Dygraph raw data table. + * Each of the values (0-1) scales to a position in the palette array scale + * (see palette argument below). For example, if palette is defined as + * ["transparent", "#ef2929", "#8ae234"], then 0 is the leftmost position ("#ef2929") + * on the palette scale, 1 is the rightmost position ("#8ae234") and 0.5 is the middle + * position ("#ef2929"). * - * `parser`: Function (`function (data, dygraph)`) returning the array of numeric - * values. Function arguments: raw data, dygraph instance. + * `parser`: Function (function (data, dygraph)) returning the array of numeric values. + * Function arguments: raw data, dygraph instance. Provide it if the ribbon data, + * i.e. encodings are part of the dygraph raw data table rather than supplied separately + * through ribbon data argument. * - * `options`: Object with the following properties: + * `options`: Object with the following properties: * - * `palette`: Colors Array. Default: ["transparent", "#ef2929", "#8ae234"] + * - `palette`: array of hexadecimal color codes. + * Default: ["transparent", "#ef2929", "#8ae234"]. + * Pick colors from e.g. http://www.w3schools.com/tags/ref_colorpicker.asp * - * `top`: Value (0-1) representing the top of the ribbon: 1 - height of the chart, - * 0.5 - 50% height of the chart and so on. + * - `top`: vertical position of the top edge of the ribbon relative to chart height. + * Value in the range from 0 (bottom edge of the chart) to 1 (top edge of the chart). + * E.g. 0.5 places the top edge of the ribbon at the 50% height of the chart. * - * `bottom`: Value (0-1) representing the bottom of the ribbon: - * 0 - the bottom of chart, 0.25 - 25% of the chart height and so on. + * - `bottom`: vertical position of the bottom edge of the ribbon relative to chart + * height. See top. */ /*global Dygraph:false */ From c324557272088fc2463ccf129e2ee37eeb99cd5c Mon Sep 17 00:00:00 2001 From: Petr Shevtsov Date: Mon, 28 Dec 2015 03:49:24 +0300 Subject: [PATCH 10/11] Reimplement update function --- src/extras/ribbon.js | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/extras/ribbon.js b/src/extras/ribbon.js index 92ed03174..ca1a2f39e 100644 --- a/src/extras/ribbon.js +++ b/src/extras/ribbon.js @@ -61,7 +61,18 @@ Dygraph.Plugins.Ribbon = (function() { bottom: 0 }; - this.ribbonOptions_ = Dygraph.update(defaultOptions, this.ribbonOptions_); + function update(self, o) { + if (typeof(o) != 'undefined' && o !== null) { + for (var k in o) { + if (o.hasOwnProperty(k)) { + self[k] = o[k]; + } + } + } + return self; + } + + this.ribbonOptions_ = update(defaultOptions, this.ribbonOptions_); this.ribbonOptions_.top = Math.min(this.ribbonOptions_.top, 1); this.ribbonOptions_.top = Math.max(this.ribbonOptions_.top, 0); this.ribbonOptions_.bottom = Math.min(this.ribbonOptions_.bottom, 1); From 058cd6301e08262bc2ad3673bd4bea4b51879fb5 Mon Sep 17 00:00:00 2001 From: Petr Shevtsov Date: Mon, 28 Dec 2015 03:50:19 +0300 Subject: [PATCH 11/11] Update path to dygraphs.js --- tests/ribbon.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/ribbon.html b/tests/ribbon.html index bb0000763..87cf21424 100644 --- a/tests/ribbon.html +++ b/tests/ribbon.html @@ -2,7 +2,7 @@ Colored Ribbon demo - +