You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@couchdb.apache.org by de...@apache.org on 2014/03/31 21:45:55 UTC
[01/41] couchdb commit: updated refs/heads/Update-Sidebar-Ui to
c1e1423
Repository: couchdb
Updated Branches:
refs/heads/Update-Sidebar-Ui f364947e0 -> c1e142377 (forced update)
Fix error message in database permissions
Show the message from the server instead of the whole JSON as text
Project: http://git-wip-us.apache.org/repos/asf/couchdb/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb/commit/7dba4223
Tree: http://git-wip-us.apache.org/repos/asf/couchdb/tree/7dba4223
Diff: http://git-wip-us.apache.org/repos/asf/couchdb/diff/7dba4223
Branch: refs/heads/Update-Sidebar-Ui
Commit: 7dba422367222b2f75e20e55ab2b4b09df7167b2
Parents: bef40dc
Author: Robert Kowalski <ro...@kowalski.gd>
Authored: Wed Mar 19 20:30:58 2014 +0100
Committer: Robert Kowalski <ro...@kowalski.gd>
Committed: Wed Mar 19 20:31:25 2014 +0100
----------------------------------------------------------------------
src/fauxton/app/addons/permissions/views.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/couchdb/blob/7dba4223/src/fauxton/app/addons/permissions/views.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/permissions/views.js b/src/fauxton/app/addons/permissions/views.js
index eb5a378..43f5aab 100644
--- a/src/fauxton/app/addons/permissions/views.js
+++ b/src/fauxton/app/addons/permissions/views.js
@@ -148,7 +148,7 @@ function (app, FauxtonAPI, Permissions ) {
});
}, function (xhr) {
FauxtonAPI.addNotification({
- msg: 'Could not update permissions - reason: ' + xhr.responseText,
+ msg: 'Could not update permissions - reason: ' + xhr.responseJSON.reason,
type: 'error'
});
});
[02/41] couchdb commit: updated refs/heads/Update-Sidebar-Ui to
c1e1423
Posted by de...@apache.org.
Keys validation, textarea and cleanup
Project: http://git-wip-us.apache.org/repos/asf/couchdb/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb/commit/3be8c85b
Tree: http://git-wip-us.apache.org/repos/asf/couchdb/tree/3be8c85b
Diff: http://git-wip-us.apache.org/repos/asf/couchdb/diff/3be8c85b
Branch: refs/heads/Update-Sidebar-Ui
Commit: 3be8c85bde6d4ee513a736cdaf7d7aaf171d825d
Parents: 65c814a
Author: Garren Smith <ga...@gmail.com>
Authored: Thu Mar 20 18:35:43 2014 +0200
Committer: suelockwood <de...@apache.org>
Committed: Thu Mar 20 15:06:02 2014 -0400
----------------------------------------------------------------------
.../addons/documents/assets/less/documents.less | 16 +++++
src/fauxton/app/addons/documents/resources.js | 23 ++++---
.../documents/templates/advanced_options.html | 10 +--
src/fauxton/app/addons/documents/views.js | 69 +++++++++++++++-----
4 files changed, 90 insertions(+), 28 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/couchdb/blob/3be8c85b/src/fauxton/app/addons/documents/assets/less/documents.less
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/documents/assets/less/documents.less b/src/fauxton/app/addons/documents/assets/less/documents.less
index 61d864b..36429ff 100644
--- a/src/fauxton/app/addons/documents/assets/less/documents.less
+++ b/src/fauxton/app/addons/documents/assets/less/documents.less
@@ -39,6 +39,10 @@ button.beautify {
}
+#query div.controls-group.well{
+ height: 150px;
+}
+
/** used in all_docs_list.html **/
.view {
table td div {
@@ -97,3 +101,15 @@ button.beautify {
height: 688px;
font-size: 16px;
}
+
+#keys-input {
+ display: inline-block;
+ width: 35%;
+}
+
+#keys-error {
+ display: inline-block;
+}
+
+
+
http://git-wip-us.apache.org/repos/asf/couchdb/blob/3be8c85b/src/fauxton/app/addons/documents/resources.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/documents/resources.js b/src/fauxton/app/addons/documents/resources.js
index 6f4323a..efd7f69 100644
--- a/src/fauxton/app/addons/documents/resources.js
+++ b/src/fauxton/app/addons/documents/resources.js
@@ -468,14 +468,21 @@ function(app, FauxtonAPI) {
if (this.skipFirstItem) {
rows = rows.splice(1);
}
- return _.map(rows, function(row) {
- return {
- _id: row.id,
- _rev: row.value.rev,
- value: row.value,
- key: row.key,
- doc: row.doc || undefined
- };
+
+ // remove any query errors that may return without doc info
+ // important for when querying keys on all docs
+ var noQueryErrors = _.filter(rows, function(row){
+ return row.value;
+ });
+
+ return _.map(noQueryErrors, function(row) {
+ return {
+ _id: row.id,
+ _rev: row.value.rev,
+ value: row.value,
+ key: row.key,
+ doc: row.doc || undefined
+ };
});
}
}));
http://git-wip-us.apache.org/repos/asf/couchdb/blob/3be8c85b/src/fauxton/app/addons/documents/templates/advanced_options.html
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/documents/templates/advanced_options.html b/src/fauxton/app/addons/documents/templates/advanced_options.html
index 8acf30a..d8d57cd 100644
--- a/src/fauxton/app/addons/documents/templates/advanced_options.html
+++ b/src/fauxton/app/addons/documents/templates/advanced_options.html
@@ -28,7 +28,8 @@ the License.
<div class="controls-group well">
<div class="row-fluid" id="js-showKeys">
<div class="controls controls-row">
- <input name="keys" class="input-xxlarge" type="text" placeholder="Enter a key, an array of keys. This must be valid JSON.">
+ <textarea id="keys-input" name="keys" class="input-xxlarge" rows="5" type="text" placeholder="Enter a key, an array of keys. This must be valid JSON."></textarea>
+ <div id="keys-error" class="inline-block js-keys-error"></div>
</div>
</div>
<div class="row-fluid hide" id="js-showStartEnd">
@@ -48,7 +49,7 @@ the License.
<div class="controls-group">
<label class="drop-down inline">
Limit:
- <select name="limit" class="input-small" disabled>
+ <select name="limit" class="input-small">
<option>5</option>
<option>10</option>
<option selected="selected">20</option>
@@ -59,10 +60,9 @@ the License.
</select>
</label>
<label for="skipRows" class="inline drop-down">
- Skip
- <input name="skip" class="input-large" type="text" id="skipRows" disabled placeholder="Number of rows to skip">
+ Skip:
+ <input name="skip" class="input-large" type="text" id="skipRows" placeholder="Number of rows to skip">
</label>
- <span class="js-disabled-message"> Limit & and Skip are disabled when using Keys.</span>
<div class="checkbox inline">
<input id="check1" type="checkbox" name="include_docs" value="true">
http://git-wip-us.apache.org/repos/asf/couchdb/blob/3be8c85b/src/fauxton/app/addons/documents/views.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/documents/views.js b/src/fauxton/app/addons/documents/views.js
index 1e7addf..cc23e19 100644
--- a/src/fauxton/app/addons/documents/views.js
+++ b/src/fauxton/app/addons/documents/views.js
@@ -1107,13 +1107,13 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
showKeys: function(){
this.$("#js-showKeys, .js-disabled-message").show();
- this.$('[name="skip"],[name="startkey"],[name="limit"],[name="endkey"],[name="inclusive_end"]').attr("disabled","true");
+ this.$('[name="startkey"],[name="endkey"],[name="inclusive_end"]').attr("disabled","true");
this.$('[name="keys"]').removeAttr("disabled");
},
showStartEnd: function(){
this.$("#js-showStartEnd").show();
- this.$('[name="skip"],[name="startkey"],[name="limit"],[name="endkey"],[name="inclusive_end"]').removeAttr("disabled");
+ this.$('[name="startkey"],[name="endkey"],[name="inclusive_end"]').removeAttr("disabled");
this.$('.js-disabled-message').hide();
this.$('[name="keys"]').attr("disabled","true");
},
@@ -1132,33 +1132,62 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
this.hasReduce = hasReduce;
this.render();
},
- validateKeys: function(val){
- return JSON.parse(val);
+
+ parseJSON: function (value) {
+ try {
+ return JSON.parse(value);
+ } catch(e) {
+ return undefined;
+ }
+ },
+
+ validateKeys: function(param){
+ var errorMsg = false,
+ parsedValue = this.parseJSON(param.value);
+
+ if (_.isUndefined(parsedValue)) {
+ errorMsg = "Keys must be valid json.";
+ } else if (!_.isArray(parsedValue)) {
+ errorMsg = "Keys values must be in an array. E.g [1,2,3]";
+ }
+
+ if (errorMsg) {
+ this.$('.js-keys-error').empty();
+ FauxtonAPI.addNotification({
+ type: "error",
+ msg: errorMsg,
+ clear: false,
+ selector: '.js-keys-error'
+ });
+ return false;
+ }
+
+ return true;
},
queryParams: function () {
- var $form = this.$(".js-view-query-update");
+ var $form = this.$(".js-view-query-update"),
+ keysParam = false;
var params = _.reduce($form.serializeArray(), function(params, param) {
if (!param.value) { return params; }
if (param.name === "limit" && param.value === 'None') { return params; }
+ if (param.name === "keys") { keysParam = param; }
params.push(param);
return params;
}, []);
+
+ if (keysParam && !this.validateKeys(keysParam)) { return false; }
+
// Validate *key* params to ensure they're valid JSON
var keyParams = ["keys","startkey","endkey"];
var errorParams = _.filter(params, function(param) {
- if (_.contains(keyParams, param.name)) {
- try {
- JSON.parse(param.value);
- return false;
- } catch(e) {
+ if (_.contains(keyParams, param.name) && _.isUndefined(this.parseJSON(param.value))) {
return true;
}
- } else {
+
return false;
- }
- });
+ }, this);
return {params: params, errorParams: errorParams};
},
@@ -1222,6 +1251,10 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
}
this.updateFiltersFor(key, $ele);
break;
+ case "key":
+ case "keys":
+ $form.find("textarea[name='"+key+"']").val(val);
+ break;
default:
$form.find("input[name='"+key+"']").val(val);
break;
@@ -1231,11 +1264,15 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
updateView: function (event) {
event.preventDefault();
- this.updateViewFn(event, this.queryParams());
+ var params = this.queryParams();
+ if (!params) { return;}
+ this.updateViewFn(event, params);
},
previewView: function (event) {
- this.previewFn(event, this.queryParams());
+ var params = this.queryParams();
+ if (!params) { return;}
+ this.previewFn(event, params);
},
serialize: function () {
@@ -1615,6 +1652,8 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
},
toggleIndexNav: function (event) {
+ $('#dashboard-content').scrollTop(0); //scroll up
+
var $targetId = this.$(event.target).attr('id'),
$previousTab = this.$(this.$('li.active a').attr('href')),
$targetTab = this.$(this.$(event.target).attr('href'));
[32/41] couchdb commit: updated refs/heads/Update-Sidebar-Ui to
c1e1423
Posted by de...@apache.org.
docs: clarify that .d and multiple .ini files only apply to unix
- closes COUCHDB-2104
Thanks Ole Johan for reporting this
Project: http://git-wip-us.apache.org/repos/asf/couchdb/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb/commit/282cddf1
Tree: http://git-wip-us.apache.org/repos/asf/couchdb/tree/282cddf1
Diff: http://git-wip-us.apache.org/repos/asf/couchdb/diff/282cddf1
Branch: refs/heads/Update-Sidebar-Ui
Commit: 282cddf1f6ac6cb37f6b14e2aa8beeb585b3b91e
Parents: e3d5d12
Author: Dave Cottlehuber <dc...@apache.org>
Authored: Wed Mar 26 21:12:19 2014 +0100
Committer: Dave Cottlehuber <dc...@apache.org>
Committed: Wed Mar 26 21:12:19 2014 +0100
----------------------------------------------------------------------
share/doc/src/config/intro.rst | 31 ++++++++++++++++++++-----------
1 file changed, 20 insertions(+), 11 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/couchdb/blob/282cddf1/share/doc/src/config/intro.rst
----------------------------------------------------------------------
diff --git a/share/doc/src/config/intro.rst b/share/doc/src/config/intro.rst
index c528f74..835643a 100644
--- a/share/doc/src/config/intro.rst
+++ b/share/doc/src/config/intro.rst
@@ -23,6 +23,14 @@ Introduction Into Configuring
Configuration files
-------------------
+.. warning::
+ The following section covering load order of config files
+ applies only to UNIX-ish systems.
+ For Windows, only the provided ``default.ini`` and ``local.ini``
+ files are relevant. These can of course have content
+ appended, which achieves the same type of functionality
+ as outlined for UNIX-ish systems below.
+
By default, CouchDB reads configuration files from the following locations,
in the following order:
@@ -148,7 +156,7 @@ Setting parameters via the HTTP API
Alternatively, configuration parameters could be set via the
:ref:`HTTP API <api/config>`. This API allows to change CouchDB configuration
-on-fly without need for server restart::
+on-the-fly without requiring a server restart::
curl -X PUT http://localhost:5984/_config/uuids/algorithm -d '"random"'
@@ -157,16 +165,17 @@ In the response the old parameter's value returns::
"sequential"
You should be careful with changing configuration via the HTTP API since it's
-easy to make CouchDB unavailable. For instance, you'd like to change the
-:option:`httpd/bind_address` for new one::
+easy to make CouchDB unavailable. For instance, if you'd like to change the
+:option:`httpd/bind_address` for a new one::
curl -X PUT http://localhost:5984/_config/httpd/bind_address -d '"10.10.0.128"'
-However, if you would made a typo or the specified IP address is not available
-from your network, you'll make CouchDB unavailable for you in both cases and
-you will have the only way to fix the problem by edit the configuration file
-and restart the server. To protect yourself against such accidents you may
-setup the :option:`httpd/config_whitelist` of configuration parameters that
-are allowed to edit via the HTTP API. For others you'll need to directly edit
-the configuration file so you may quick fix any problems that had occurred due
-to misconfiguring.
+However, if you make a typo, or the specified IP address is not available
+from your network, CouchDB will be unavailable for you in both cases and
+the only way to resolve this will be by remoting into the server, correcting
+the errant file, and restarting CouchDB. To protect yourself against such
+accidents you may set the :option:`httpd/config_whitelist` of permitted
+configuration parameters for updates via the HTTP API. Once this option is set,
+further changes to non-whitelisted parameters must take place via the
+configuration file, and in most cases, also requires a server restart before
+hand-edited options take effect.
[36/41] couchdb commit: updated refs/heads/Update-Sidebar-Ui to
c1e1423
Posted by de...@apache.org.
s/401/403
Project: http://git-wip-us.apache.org/repos/asf/couchdb/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb/commit/8b429c83
Tree: http://git-wip-us.apache.org/repos/asf/couchdb/tree/8b429c83
Diff: http://git-wip-us.apache.org/repos/asf/couchdb/diff/8b429c83
Branch: refs/heads/Update-Sidebar-Ui
Commit: 8b429c8362505a59e5332bd4c9d93142d495f01a
Parents: 83cc813
Author: Robert Newson <rn...@apache.org>
Authored: Thu Mar 27 13:19:46 2014 +0000
Committer: Robert Newson <rn...@apache.org>
Committed: Thu Mar 27 13:19:46 2014 +0000
----------------------------------------------------------------------
share/www/script/test/uuids.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/couchdb/blob/8b429c83/share/www/script/test/uuids.js
----------------------------------------------------------------------
diff --git a/share/www/script/test/uuids.js b/share/www/script/test/uuids.js
index 0f141a9..d304c4e 100644
--- a/share/www/script/test/uuids.js
+++ b/share/www/script/test/uuids.js
@@ -82,7 +82,7 @@ couchTests.uuids = function(debug) {
// test max_uuid_count
var xhr = CouchDB.request("GET", "/_uuids?count=1001");
- TEquals(401, xhr.status, "should error when count > max_count");
+ TEquals(403, xhr.status, "should error when count > max_count");
run_on_modified_server([{
"section": "uuids",
[26/41] couchdb commit: updated refs/heads/Update-Sidebar-Ui to
c1e1423
Posted by de...@apache.org.
moving myself from THANKS to AUTHORS
Project: http://git-wip-us.apache.org/repos/asf/couchdb/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb/commit/35a03037
Tree: http://git-wip-us.apache.org/repos/asf/couchdb/tree/35a03037
Diff: http://git-wip-us.apache.org/repos/asf/couchdb/diff/35a03037
Branch: refs/heads/Update-Sidebar-Ui
Commit: 35a030378f032ec1839b8f0c35a8191c261a2005
Parents: 7296e53
Author: BigBlueHat <by...@bigbluehat.com>
Authored: Tue Mar 25 15:55:16 2014 -0400
Committer: BigBlueHat <by...@bigbluehat.com>
Committed: Tue Mar 25 15:55:16 2014 -0400
----------------------------------------------------------------------
AUTHORS | 1 +
THANKS.in | 1 -
2 files changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/couchdb/blob/35a03037/AUTHORS
----------------------------------------------------------------------
diff --git a/AUTHORS b/AUTHORS
index dd0260a..ab48b58 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -28,5 +28,6 @@ documentation or developing software. Some of these people are:
* Sue Lockwood <de...@apache.org>
* Andy Wenk <an...@apache.org>
* Klaus Trainer <kl...@apache.org>
+ * Benjamin Young <bi...@apache.org>
For a list of other credits see the `THANKS` file.
http://git-wip-us.apache.org/repos/asf/couchdb/blob/35a03037/THANKS.in
----------------------------------------------------------------------
diff --git a/THANKS.in b/THANKS.in
index bdfb3cd..b3e5cc8 100644
--- a/THANKS.in
+++ b/THANKS.in
@@ -66,7 +66,6 @@ suggesting improvements or submitting changes. Some of these people are:
* David Davis <xa...@xantus.org>
* Juuso Väänänen <ju...@vaananen.org>
* Jeff Zellner <je...@gmail.com>
- * Benjamin Young <by...@bigbluehat.com>
* Gabriel Farrell <gs...@gmail.com>
* Mike Leddy <mi...@loop.com.br>
* Wayne Conrad <wa...@databill.com>
[20/41] Updating d3 to v3.4.3 and nv.d3 to v1.1.15
Posted by de...@apache.org.
http://git-wip-us.apache.org/repos/asf/couchdb/blob/95d6d6b0/src/fauxton/assets/js/libs/nv.d3.js
----------------------------------------------------------------------
diff --git a/src/fauxton/assets/js/libs/nv.d3.js b/src/fauxton/assets/js/libs/nv.d3.js
index 936b406..4ddf400 100755
--- a/src/fauxton/assets/js/libs/nv.d3.js
+++ b/src/fauxton/assets/js/libs/nv.d3.js
@@ -2,14 +2,15 @@
var nv = window.nv || {};
-nv.version = '0.0.1a';
+
+nv.version = '1.1.15b';
nv.dev = true //set false when in production
window.nv = nv;
-nv.tooltip = {}; // For the tooltip system
-nv.utils = {}; // Utility subsystem
-nv.models = {}; //stores all the possible models/components
+nv.tooltip = nv.tooltip || {}; // For the tooltip system
+nv.utils = nv.utils || {}; // Utility subsystem
+nv.models = nv.models || {}; //stores all the possible models/components
nv.charts = {}; //stores all the ready to use charts
nv.graphs = []; //stores all the graphs currently on the page
nv.logs = {}; //stores some statistics and potential error messages
@@ -35,10 +36,13 @@ if (nv.dev) {
// Public Core NV functions
// Logs all arguments, and returns the last so you can test things in place
+// Note: in IE8 console.log is an object not a function, and if modernizr is used
+// then calling Function.prototype.bind with with anything other than a function
+// causes a TypeError to be thrown.
nv.log = function() {
if (nv.dev && console.log && console.log.apply)
console.log.apply(console, arguments)
- else if (nv.dev && console.log && Function.prototype.bind) {
+ else if (nv.dev && typeof console.log == "function" && Function.prototype.bind) {
var log = Function.prototype.bind.call(console.log, console);
log.apply(console, arguments);
}
@@ -64,7 +68,10 @@ nv.render = function render(step) {
nv.render.queue.splice(0, i);
if (nv.render.queue.length) setTimeout(arguments.callee, 0);
- else { nv.render.active = false; nv.dispatch.render_end(); }
+ else {
+ nv.dispatch.render_end();
+ nv.render.active = false;
+ }
}, 0);
};
@@ -117,137 +124,744 @@ d3.time.monthEnds = d3_time_range(d3.time.monthEnd, function(date) {
}
);
+/* Utility class to handle creation of an interactive layer.
+This places a rectangle on top of the chart. When you mouse move over it, it sends a dispatch
+containing the X-coordinate. It can also render a vertical line where the mouse is located.
+
+dispatch.elementMousemove is the important event to latch onto. It is fired whenever the mouse moves over
+the rectangle. The dispatch is given one object which contains the mouseX/Y location.
+It also has 'pointXValue', which is the conversion of mouseX to the x-axis scale.
+*/
+nv.interactiveGuideline = function() {
+ "use strict";
+ var tooltip = nv.models.tooltip();
+ //Public settings
+ var width = null
+ , height = null
+ //Please pass in the bounding chart's top and left margins
+ //This is important for calculating the correct mouseX/Y positions.
+ , margin = {left: 0, top: 0}
+ , xScale = d3.scale.linear()
+ , yScale = d3.scale.linear()
+ , dispatch = d3.dispatch('elementMousemove', 'elementMouseout','elementDblclick')
+ , showGuideLine = true
+ , svgContainer = null
+ //Must pass in the bounding chart's <svg> container.
+ //The mousemove event is attached to this container.
+ ;
+
+ //Private variables
+ var isMSIE = navigator.userAgent.indexOf("MSIE") !== -1 //Check user-agent for Microsoft Internet Explorer.
+ ;
+
+
+ function layer(selection) {
+ selection.each(function(data) {
+ var container = d3.select(this);
+
+ var availableWidth = (width || 960), availableHeight = (height || 400);
+
+ var wrap = container.selectAll("g.nv-wrap.nv-interactiveLineLayer").data([data]);
+ var wrapEnter = wrap.enter()
+ .append("g").attr("class", " nv-wrap nv-interactiveLineLayer");
+
+
+ wrapEnter.append("g").attr("class","nv-interactiveGuideLine");
+
+ if (!svgContainer) {
+ return;
+ }
+
+ function mouseHandler() {
+ var d3mouse = d3.mouse(this);
+ var mouseX = d3mouse[0];
+ var mouseY = d3mouse[1];
+ var subtractMargin = true;
+ var mouseOutAnyReason = false;
+ if (isMSIE) {
+ /*
+ D3.js (or maybe SVG.getScreenCTM) has a nasty bug in Internet Explorer 10.
+ d3.mouse() returns incorrect X,Y mouse coordinates when mouse moving
+ over a rect in IE 10.
+ However, d3.event.offsetX/Y also returns the mouse coordinates
+ relative to the triggering <rect>. So we use offsetX/Y on IE.
+ */
+ mouseX = d3.event.offsetX;
+ mouseY = d3.event.offsetY;
+
+ /*
+ On IE, if you attach a mouse event listener to the <svg> container,
+ it will actually trigger it for all the child elements (like <path>, <circle>, etc).
+ When this happens on IE, the offsetX/Y is set to where ever the child element
+ is located.
+ As a result, we do NOT need to subtract margins to figure out the mouse X/Y
+ position under this scenario. Removing the line below *will* cause
+ the interactive layer to not work right on IE.
+ */
+ if(d3.event.target.tagName !== "svg")
+ subtractMargin = false;
+
+ if (d3.event.target.className.baseVal.match("nv-legend"))
+ mouseOutAnyReason = true;
+
+ }
+
+ if(subtractMargin) {
+ mouseX -= margin.left;
+ mouseY -= margin.top;
+ }
+
+ /* If mouseX/Y is outside of the chart's bounds,
+ trigger a mouseOut event.
+ */
+ if (mouseX < 0 || mouseY < 0
+ || mouseX > availableWidth || mouseY > availableHeight
+ || (d3.event.relatedTarget && d3.event.relatedTarget.ownerSVGElement === undefined)
+ || mouseOutAnyReason
+ )
+ {
+ if (isMSIE) {
+ if (d3.event.relatedTarget
+ && d3.event.relatedTarget.ownerSVGElement === undefined
+ && d3.event.relatedTarget.className.match(tooltip.nvPointerEventsClass)) {
+ return;
+ }
+ }
+ dispatch.elementMouseout({
+ mouseX: mouseX,
+ mouseY: mouseY
+ });
+ layer.renderGuideLine(null); //hide the guideline
+ return;
+ }
+
+ var pointXValue = xScale.invert(mouseX);
+ dispatch.elementMousemove({
+ mouseX: mouseX,
+ mouseY: mouseY,
+ pointXValue: pointXValue
+ });
+
+ //If user double clicks the layer, fire a elementDblclick dispatch.
+ if (d3.event.type === "dblclick") {
+ dispatch.elementDblclick({
+ mouseX: mouseX,
+ mouseY: mouseY,
+ pointXValue: pointXValue
+ });
+ }
+ }
+
+ svgContainer
+ .on("mousemove",mouseHandler, true)
+ .on("mouseout" ,mouseHandler,true)
+ .on("dblclick" ,mouseHandler)
+ ;
+
+ //Draws a vertical guideline at the given X postion.
+ layer.renderGuideLine = function(x) {
+ if (!showGuideLine) return;
+ var line = wrap.select(".nv-interactiveGuideLine")
+ .selectAll("line")
+ .data((x != null) ? [nv.utils.NaNtoZero(x)] : [], String);
+
+ line.enter()
+ .append("line")
+ .attr("class", "nv-guideline")
+ .attr("x1", function(d) { return d;})
+ .attr("x2", function(d) { return d;})
+ .attr("y1", availableHeight)
+ .attr("y2",0)
+ ;
+ line.exit().remove();
+
+ }
+ });
+ }
+
+ layer.dispatch = dispatch;
+ layer.tooltip = tooltip;
+
+ layer.margin = function(_) {
+ if (!arguments.length) return margin;
+ margin.top = typeof _.top != 'undefined' ? _.top : margin.top;
+ margin.left = typeof _.left != 'undefined' ? _.left : margin.left;
+ return layer;
+ };
+
+ layer.width = function(_) {
+ if (!arguments.length) return width;
+ width = _;
+ return layer;
+ };
+
+ layer.height = function(_) {
+ if (!arguments.length) return height;
+ height = _;
+ return layer;
+ };
+
+ layer.xScale = function(_) {
+ if (!arguments.length) return xScale;
+ xScale = _;
+ return layer;
+ };
+
+ layer.showGuideLine = function(_) {
+ if (!arguments.length) return showGuideLine;
+ showGuideLine = _;
+ return layer;
+ };
+
+ layer.svgContainer = function(_) {
+ if (!arguments.length) return svgContainer;
+ svgContainer = _;
+ return layer;
+ };
+
+
+ return layer;
+};
+
+/* Utility class that uses d3.bisect to find the index in a given array, where a search value can be inserted.
+This is different from normal bisectLeft; this function finds the nearest index to insert the search value.
+
+For instance, lets say your array is [1,2,3,5,10,30], and you search for 28.
+Normal d3.bisectLeft will return 4, because 28 is inserted after the number 10. But interactiveBisect will return 5
+because 28 is closer to 30 than 10.
+
+Unit tests can be found in: interactiveBisectTest.html
+
+Has the following known issues:
+ * Will not work if the data points move backwards (ie, 10,9,8,7, etc) or if the data points are in random order.
+ * Won't work if there are duplicate x coordinate values.
+*/
+nv.interactiveBisect = function (values, searchVal, xAccessor) {
+ "use strict";
+ if (! values instanceof Array) return null;
+ if (typeof xAccessor !== 'function') xAccessor = function(d,i) { return d.x;}
+
+ var bisect = d3.bisector(xAccessor).left;
+ var index = d3.max([0, bisect(values,searchVal) - 1]);
+ var currentValue = xAccessor(values[index], index);
+ if (typeof currentValue === 'undefined') currentValue = index;
+
+ if (currentValue === searchVal) return index; //found exact match
-/*****
- * A no-frills tooltip implementation.
- *****/
+ var nextIndex = d3.min([index+1, values.length - 1]);
+ var nextValue = xAccessor(values[nextIndex], nextIndex);
+ if (typeof nextValue === 'undefined') nextValue = nextIndex;
+ if (Math.abs(nextValue - searchVal) >= Math.abs(currentValue - searchVal))
+ return index;
+ else
+ return nextIndex
+};
+
+/*
+Returns the index in the array "values" that is closest to searchVal.
+Only returns an index if searchVal is within some "threshold".
+Otherwise, returns null.
+*/
+nv.nearestValueIndex = function (values, searchVal, threshold) {
+ "use strict";
+ var yDistMax = Infinity, indexToHighlight = null;
+ values.forEach(function(d,i) {
+ var delta = Math.abs(searchVal - d);
+ if ( delta <= yDistMax && delta < threshold) {
+ yDistMax = delta;
+ indexToHighlight = i;
+ }
+ });
+ return indexToHighlight;
+};/* Tooltip rendering model for nvd3 charts.
+window.nv.models.tooltip is the updated,new way to render tooltips.
+window.nv.tooltip.show is the old tooltip code.
+window.nv.tooltip.* also has various helper methods.
+*/
(function() {
+ "use strict";
+ window.nv.tooltip = {};
+
+ /* Model which can be instantiated to handle tooltip rendering.
+ Example usage:
+ var tip = nv.models.tooltip().gravity('w').distance(23)
+ .data(myDataObject);
+
+ tip(); //just invoke the returned function to render tooltip.
+ */
+ window.nv.models.tooltip = function() {
+ var content = null //HTML contents of the tooltip. If null, the content is generated via the data variable.
+ , data = null /* Tooltip data. If data is given in the proper format, a consistent tooltip is generated.
+ Format of data:
+ {
+ key: "Date",
+ value: "August 2009",
+ series: [
+ {
+ key: "Series 1",
+ value: "Value 1",
+ color: "#000"
+ },
+ {
+ key: "Series 2",
+ value: "Value 2",
+ color: "#00f"
+ }
+ ]
- var nvtooltip = window.nv.tooltip = {};
+ }
- nvtooltip.show = function(pos, content, gravity, dist, parentContainer, classes) {
+ */
+ , gravity = 'w' //Can be 'n','s','e','w'. Determines how tooltip is positioned.
+ , distance = 50 //Distance to offset tooltip from the mouse location.
+ , snapDistance = 25 //Tolerance allowed before tooltip is moved from its current position (creates 'snapping' effect)
+ , fixedTop = null //If not null, this fixes the top position of the tooltip.
+ , classes = null //Attaches additional CSS classes to the tooltip DIV that is created.
+ , chartContainer = null //Parent DIV, of the SVG Container that holds the chart.
+ , tooltipElem = null //actual DOM element representing the tooltip.
+ , position = {left: null, top: null} //Relative position of the tooltip inside chartContainer.
+ , enabled = true //True -> tooltips are rendered. False -> don't render tooltips.
+ //Generates a unique id when you create a new tooltip() object
+ , id = "nvtooltip-" + Math.floor(Math.random() * 100000)
+ ;
+
+ //CSS class to specify whether element should not have mouse events.
+ var nvPointerEventsClass = "nv-pointer-events-none";
+
+ //Format function for the tooltip values column
+ var valueFormatter = function(d,i) {
+ return d;
+ };
- var container = document.createElement('div');
- container.className = 'nvtooltip ' + (classes ? classes : 'xy-tooltip');
+ //Format function for the tooltip header value.
+ var headerFormatter = function(d) {
+ return d;
+ };
- gravity = gravity || 's';
- dist = dist || 20;
+ //By default, the tooltip model renders a beautiful table inside a DIV.
+ //You can override this function if a custom tooltip is desired.
+ var contentGenerator = function(d) {
+ if (content != null) return content;
+
+ if (d == null) return '';
+
+ var table = d3.select(document.createElement("table"));
+ var theadEnter = table.selectAll("thead")
+ .data([d])
+ .enter().append("thead");
+ theadEnter.append("tr")
+ .append("td")
+ .attr("colspan",3)
+ .append("strong")
+ .classed("x-value",true)
+ .html(headerFormatter(d.value));
+
+ var tbodyEnter = table.selectAll("tbody")
+ .data([d])
+ .enter().append("tbody");
+ var trowEnter = tbodyEnter.selectAll("tr")
+ .data(function(p) { return p.series})
+ .enter()
+ .append("tr")
+ .classed("highlight", function(p) { return p.highlight})
+ ;
+
+ trowEnter.append("td")
+ .classed("legend-color-guide",true)
+ .append("div")
+ .style("background-color", function(p) { return p.color});
+ trowEnter.append("td")
+ .classed("key",true)
+ .html(function(p) {return p.key});
+ trowEnter.append("td")
+ .classed("value",true)
+ .html(function(p,i) { return valueFormatter(p.value,i) });
+
+
+ trowEnter.selectAll("td").each(function(p) {
+ if (p.highlight) {
+ var opacityScale = d3.scale.linear().domain([0,1]).range(["#fff",p.color]);
+ var opacity = 0.6;
+ d3.select(this)
+ .style("border-bottom-color", opacityScale(opacity))
+ .style("border-top-color", opacityScale(opacity))
+ ;
+ }
+ });
- var body = parentContainer;
- if ( !parentContainer || parentContainer.tagName.match(/g|svg/i)) {
- //If the parent element is an SVG element, place tooltip in the <body> element.
- body = document.getElementsByTagName('body')[0];
- }
+ var html = table.node().outerHTML;
+ if (d.footer !== undefined)
+ html += "<div class='footer'>" + d.footer + "</div>";
+ return html;
- container.innerHTML = content;
- container.style.left = 0;
- container.style.top = 0;
- container.style.opacity = 0;
-
- body.appendChild(container);
-
- var height = parseInt(container.offsetHeight),
- width = parseInt(container.offsetWidth),
- windowWidth = nv.utils.windowSize().width,
- windowHeight = nv.utils.windowSize().height,
- scrollTop = window.scrollY,
- scrollLeft = window.scrollX,
- left, top;
-
- windowHeight = window.innerWidth >= document.body.scrollWidth ? windowHeight : windowHeight - 16;
- windowWidth = window.innerHeight >= document.body.scrollHeight ? windowWidth : windowWidth - 16;
-
- var tooltipTop = function ( Elem ) {
- var offsetTop = top;
- do {
- if( !isNaN( Elem.offsetTop ) ) {
- offsetTop += (Elem.offsetTop);
+ };
+
+ var dataSeriesExists = function(d) {
+ if (d && d.series && d.series.length > 0) return true;
+
+ return false;
+ };
+
+ //In situations where the chart is in a 'viewBox', re-position the tooltip based on how far chart is zoomed.
+ function convertViewBoxRatio() {
+ if (chartContainer) {
+ var svg = d3.select(chartContainer);
+ if (svg.node().tagName !== "svg") {
+ svg = svg.select("svg");
+ }
+ var viewBox = (svg.node()) ? svg.attr('viewBox') : null;
+ if (viewBox) {
+ viewBox = viewBox.split(' ');
+ var ratio = parseInt(svg.style('width')) / viewBox[2];
+
+ position.left = position.left * ratio;
+ position.top = position.top * ratio;
+ }
}
- } while( Elem = Elem.offsetParent );
- return offsetTop;
- }
+ }
- var tooltipLeft = function ( Elem ) {
- var offsetLeft = left;
- do {
- if( !isNaN( Elem.offsetLeft ) ) {
- offsetLeft += (Elem.offsetLeft);
+ //Creates new tooltip container, or uses existing one on DOM.
+ function getTooltipContainer(newContent) {
+ var body;
+ if (chartContainer)
+ body = d3.select(chartContainer);
+ else
+ body = d3.select("body");
+
+ var container = body.select(".nvtooltip");
+ if (container.node() === null) {
+ //Create new tooltip div if it doesn't exist on DOM.
+ container = body.append("div")
+ .attr("class", "nvtooltip " + (classes? classes: "xy-tooltip"))
+ .attr("id",id)
+ ;
}
- } while( Elem = Elem.offsetParent );
- return offsetLeft;
- }
+
- switch (gravity) {
- case 'e':
- left = pos[0] - width - dist;
- top = pos[1] - (height / 2);
- var tLeft = tooltipLeft(container);
- var tTop = tooltipTop(container);
- if (tLeft < scrollLeft) left = pos[0] + dist > scrollLeft ? pos[0] + dist : scrollLeft - tLeft + left;
- if (tTop < scrollTop) top = scrollTop - tTop + top;
- if (tTop + height > scrollTop + windowHeight) top = scrollTop + windowHeight - tTop + top - height;
- break;
- case 'w':
- left = pos[0] + dist;
- top = pos[1] - (height / 2);
- if (tLeft + width > windowWidth) left = pos[0] - width - dist;
- if (tTop < scrollTop) top = scrollTop + 5;
- if (tTop + height > scrollTop + windowHeight) top = scrollTop - height - 5;
- break;
- case 'n':
- left = pos[0] - (width / 2) - 5;
- top = pos[1] + dist;
- var tLeft = tooltipLeft(container);
- var tTop = tooltipTop(container);
- if (tLeft < scrollLeft) left = scrollLeft + 5;
- if (tLeft + width > windowWidth) left = left - width/2 + 5;
- if (tTop + height > scrollTop + windowHeight) top = scrollTop + windowHeight - tTop + top - height;
- break;
- case 's':
- left = pos[0] - (width / 2);
- top = pos[1] - height - dist;
- var tLeft = tooltipLeft(container);
- var tTop = tooltipTop(container);
- if (tLeft < scrollLeft) left = scrollLeft + 5;
- if (tLeft + width > windowWidth) left = left - width/2 + 5;
- if (scrollTop > tTop) top = scrollTop;
- break;
- }
+ container.node().innerHTML = newContent;
+ container.style("top",0).style("left",0).style("opacity",0);
+ container.selectAll("div, table, td, tr").classed(nvPointerEventsClass,true)
+ container.classed(nvPointerEventsClass,true);
+ return container.node();
+ }
+
- container.style.left = left+'px';
- container.style.top = top+'px';
- container.style.opacity = 1;
- container.style.position = 'absolute'; //fix scroll bar issue
- container.style.pointerEvents = 'none'; //fix scroll bar issue
+ //Draw the tooltip onto the DOM.
+ function nvtooltip() {
+ if (!enabled) return;
+ if (!dataSeriesExists(data)) return;
+
+ convertViewBoxRatio();
+
+ var left = position.left;
+ var top = (fixedTop != null) ? fixedTop : position.top;
+ var container = getTooltipContainer(contentGenerator(data));
+ tooltipElem = container;
+ if (chartContainer) {
+ var svgComp = chartContainer.getElementsByTagName("svg")[0];
+ var boundRect = (svgComp) ? svgComp.getBoundingClientRect() : chartContainer.getBoundingClientRect();
+ var svgOffset = {left:0,top:0};
+ if (svgComp) {
+ var svgBound = svgComp.getBoundingClientRect();
+ var chartBound = chartContainer.getBoundingClientRect();
+ var svgBoundTop = svgBound.top;
+
+ //Defensive code. Sometimes, svgBoundTop can be a really negative
+ // number, like -134254. That's a bug.
+ // If such a number is found, use zero instead. FireFox bug only
+ if (svgBoundTop < 0) {
+ var containerBound = chartContainer.getBoundingClientRect();
+ svgBoundTop = (Math.abs(svgBoundTop) > containerBound.height) ? 0 : svgBoundTop;
+ }
+ svgOffset.top = Math.abs(svgBoundTop - chartBound.top);
+ svgOffset.left = Math.abs(svgBound.left - chartBound.left);
+ }
+ //If the parent container is an overflow <div> with scrollbars, subtract the scroll offsets.
+ //You need to also add any offset between the <svg> element and its containing <div>
+ //Finally, add any offset of the containing <div> on the whole page.
+ left += chartContainer.offsetLeft + svgOffset.left - 2*chartContainer.scrollLeft;
+ top += chartContainer.offsetTop + svgOffset.top - 2*chartContainer.scrollTop;
+ }
- return container;
- };
+ if (snapDistance && snapDistance > 0) {
+ top = Math.floor(top/snapDistance) * snapDistance;
+ }
- nvtooltip.cleanup = function() {
+ nv.tooltip.calcTooltipPosition([left,top], gravity, distance, container);
+ return nvtooltip;
+ };
- // Find the tooltips, mark them for removal by this class (so others cleanups won't find it)
- var tooltips = document.getElementsByClassName('nvtooltip');
- var purging = [];
- while(tooltips.length) {
- purging.push(tooltips[0]);
- tooltips[0].style.transitionDelay = '0 !important';
- tooltips[0].style.opacity = 0;
- tooltips[0].className = 'nvtooltip-pending-removal';
- }
+ nvtooltip.nvPointerEventsClass = nvPointerEventsClass;
+
+ nvtooltip.content = function(_) {
+ if (!arguments.length) return content;
+ content = _;
+ return nvtooltip;
+ };
+ //Returns tooltipElem...not able to set it.
+ nvtooltip.tooltipElem = function() {
+ return tooltipElem;
+ };
- setTimeout(function() {
+ nvtooltip.contentGenerator = function(_) {
+ if (!arguments.length) return contentGenerator;
+ if (typeof _ === 'function') {
+ contentGenerator = _;
+ }
+ return nvtooltip;
+ };
- while (purging.length) {
- var removeMe = purging.pop();
- removeMe.parentNode.removeChild(removeMe);
- }
- }, 500);
+ nvtooltip.data = function(_) {
+ if (!arguments.length) return data;
+ data = _;
+ return nvtooltip;
+ };
+
+ nvtooltip.gravity = function(_) {
+ if (!arguments.length) return gravity;
+ gravity = _;
+ return nvtooltip;
+ };
+
+ nvtooltip.distance = function(_) {
+ if (!arguments.length) return distance;
+ distance = _;
+ return nvtooltip;
+ };
+
+ nvtooltip.snapDistance = function(_) {
+ if (!arguments.length) return snapDistance;
+ snapDistance = _;
+ return nvtooltip;
+ };
+
+ nvtooltip.classes = function(_) {
+ if (!arguments.length) return classes;
+ classes = _;
+ return nvtooltip;
+ };
+
+ nvtooltip.chartContainer = function(_) {
+ if (!arguments.length) return chartContainer;
+ chartContainer = _;
+ return nvtooltip;
+ };
+
+ nvtooltip.position = function(_) {
+ if (!arguments.length) return position;
+ position.left = (typeof _.left !== 'undefined') ? _.left : position.left;
+ position.top = (typeof _.top !== 'undefined') ? _.top : position.top;
+ return nvtooltip;
+ };
+
+ nvtooltip.fixedTop = function(_) {
+ if (!arguments.length) return fixedTop;
+ fixedTop = _;
+ return nvtooltip;
+ };
+
+ nvtooltip.enabled = function(_) {
+ if (!arguments.length) return enabled;
+ enabled = _;
+ return nvtooltip;
+ };
+
+ nvtooltip.valueFormatter = function(_) {
+ if (!arguments.length) return valueFormatter;
+ if (typeof _ === 'function') {
+ valueFormatter = _;
+ }
+ return nvtooltip;
+ };
+
+ nvtooltip.headerFormatter = function(_) {
+ if (!arguments.length) return headerFormatter;
+ if (typeof _ === 'function') {
+ headerFormatter = _;
+ }
+ return nvtooltip;
+ };
+
+ //id() is a read-only function. You can't use it to set the id.
+ nvtooltip.id = function() {
+ return id;
+ };
+
+
+ return nvtooltip;
+ };
+
+
+ //Original tooltip.show function. Kept for backward compatibility.
+ // pos = [left,top]
+ nv.tooltip.show = function(pos, content, gravity, dist, parentContainer, classes) {
+
+ //Create new tooltip div if it doesn't exist on DOM.
+ var container = document.createElement('div');
+ container.className = 'nvtooltip ' + (classes ? classes : 'xy-tooltip');
+
+ var body = parentContainer;
+ if ( !parentContainer || parentContainer.tagName.match(/g|svg/i)) {
+ //If the parent element is an SVG element, place tooltip in the <body> element.
+ body = document.getElementsByTagName('body')[0];
+ }
+
+ container.style.left = 0;
+ container.style.top = 0;
+ container.style.opacity = 0;
+ container.innerHTML = content;
+ body.appendChild(container);
+
+ //If the parent container is an overflow <div> with scrollbars, subtract the scroll offsets.
+ if (parentContainer) {
+ pos[0] = pos[0] - parentContainer.scrollLeft;
+ pos[1] = pos[1] - parentContainer.scrollTop;
+ }
+ nv.tooltip.calcTooltipPosition(pos, gravity, dist, container);
+ };
+
+ //Looks up the ancestry of a DOM element, and returns the first NON-svg node.
+ nv.tooltip.findFirstNonSVGParent = function(Elem) {
+ while(Elem.tagName.match(/^g|svg$/i) !== null) {
+ Elem = Elem.parentNode;
+ }
+ return Elem;
};
+ //Finds the total offsetTop of a given DOM element.
+ //Looks up the entire ancestry of an element, up to the first relatively positioned element.
+ nv.tooltip.findTotalOffsetTop = function ( Elem, initialTop ) {
+ var offsetTop = initialTop;
+
+ do {
+ if( !isNaN( Elem.offsetTop ) ) {
+ offsetTop += (Elem.offsetTop);
+ }
+ } while( Elem = Elem.offsetParent );
+ return offsetTop;
+ };
+
+ //Finds the total offsetLeft of a given DOM element.
+ //Looks up the entire ancestry of an element, up to the first relatively positioned element.
+ nv.tooltip.findTotalOffsetLeft = function ( Elem, initialLeft) {
+ var offsetLeft = initialLeft;
+
+ do {
+ if( !isNaN( Elem.offsetLeft ) ) {
+ offsetLeft += (Elem.offsetLeft);
+ }
+ } while( Elem = Elem.offsetParent );
+ return offsetLeft;
+ };
+
+ //Global utility function to render a tooltip on the DOM.
+ //pos = [left,top] coordinates of where to place the tooltip, relative to the SVG chart container.
+ //gravity = how to orient the tooltip
+ //dist = how far away from the mouse to place tooltip
+ //container = tooltip DIV
+ nv.tooltip.calcTooltipPosition = function(pos, gravity, dist, container) {
+
+ var height = parseInt(container.offsetHeight),
+ width = parseInt(container.offsetWidth),
+ windowWidth = nv.utils.windowSize().width,
+ windowHeight = nv.utils.windowSize().height,
+ scrollTop = window.pageYOffset,
+ scrollLeft = window.pageXOffset,
+ left, top;
+
+ windowHeight = window.innerWidth >= document.body.scrollWidth ? windowHeight : windowHeight - 16;
+ windowWidth = window.innerHeight >= document.body.scrollHeight ? windowWidth : windowWidth - 16;
+
+ gravity = gravity || 's';
+ dist = dist || 20;
+
+ var tooltipTop = function ( Elem ) {
+ return nv.tooltip.findTotalOffsetTop(Elem, top);
+ };
+
+ var tooltipLeft = function ( Elem ) {
+ return nv.tooltip.findTotalOffsetLeft(Elem,left);
+ };
+
+ switch (gravity) {
+ case 'e':
+ left = pos[0] - width - dist;
+ top = pos[1] - (height / 2);
+ var tLeft = tooltipLeft(container);
+ var tTop = tooltipTop(container);
+ if (tLeft < scrollLeft) left = pos[0] + dist > scrollLeft ? pos[0] + dist : scrollLeft - tLeft + left;
+ if (tTop < scrollTop) top = scrollTop - tTop + top;
+ if (tTop + height > scrollTop + windowHeight) top = scrollTop + windowHeight - tTop + top - height;
+ break;
+ case 'w':
+ left = pos[0] + dist;
+ top = pos[1] - (height / 2);
+ var tLeft = tooltipLeft(container);
+ var tTop = tooltipTop(container);
+ if (tLeft + width > windowWidth) left = pos[0] - width - dist;
+ if (tTop < scrollTop) top = scrollTop + 5;
+ if (tTop + height > scrollTop + windowHeight) top = scrollTop + windowHeight - tTop + top - height;
+ break;
+ case 'n':
+ left = pos[0] - (width / 2) - 5;
+ top = pos[1] + dist;
+ var tLeft = tooltipLeft(container);
+ var tTop = tooltipTop(container);
+ if (tLeft < scrollLeft) left = scrollLeft + 5;
+ if (tLeft + width > windowWidth) left = left - width/2 + 5;
+ if (tTop + height > scrollTop + windowHeight) top = scrollTop + windowHeight - tTop + top - height;
+ break;
+ case 's':
+ left = pos[0] - (width / 2);
+ top = pos[1] - height - dist;
+ var tLeft = tooltipLeft(container);
+ var tTop = tooltipTop(container);
+ if (tLeft < scrollLeft) left = scrollLeft + 5;
+ if (tLeft + width > windowWidth) left = left - width/2 + 5;
+ if (scrollTop > tTop) top = scrollTop;
+ break;
+ case 'none':
+ left = pos[0];
+ top = pos[1] - dist;
+ var tLeft = tooltipLeft(container);
+ var tTop = tooltipTop(container);
+ break;
+ }
+
+
+ container.style.left = left+'px';
+ container.style.top = top+'px';
+ container.style.opacity = 1;
+ container.style.position = 'absolute';
+
+ return container;
+ };
+
+ //Global utility function to remove tooltips from the DOM.
+ nv.tooltip.cleanup = function() {
+
+ // Find the tooltips, mark them for removal by this class (so others cleanups won't find it)
+ var tooltips = document.getElementsByClassName('nvtooltip');
+ var purging = [];
+ while(tooltips.length) {
+ purging.push(tooltips[0]);
+ tooltips[0].style.transitionDelay = '0 !important';
+ tooltips[0].style.opacity = 0;
+ tooltips[0].className = 'nvtooltip-pending-removal';
+ }
+
+ setTimeout(function() {
+
+ while (purging.length) {
+ var removeMe = purging.pop();
+ removeMe.parentNode.removeChild(removeMe);
+ }
+ }, 500);
+ };
})();
@@ -282,6 +896,7 @@ nv.utils.windowSize = function() {
// Easy way to bind multiple functions to window.onresize
// TODO: give a way to remove a function after its bound, other than removing all of them
nv.utils.windowResize = function(fun){
+ if (fun === undefined) return;
var oldresize = window.onresize;
window.onresize = function(e) {
@@ -356,20 +971,53 @@ nv.utils.pjax = function(links, content) {
}
/* For situations where we want to approximate the width in pixels for an SVG:text element.
-Most common instance is when the element is in a display:none; container.
+Most common instance is when the element is in a display:none; container.
Forumla is : text.length * font-size * constant_factor
*/
nv.utils.calcApproxTextWidth = function (svgTextElem) {
- if (svgTextElem instanceof d3.selection) {
+ if (typeof svgTextElem.style === 'function'
+ && typeof svgTextElem.text === 'function') {
var fontSize = parseInt(svgTextElem.style("font-size").replace("px",""));
var textLength = svgTextElem.text().length;
- return textLength * fontSize * 0.5;
+ return textLength * fontSize * 0.5;
}
return 0;
};
-nv.models.axis = function() {
+/* Numbers that are undefined, null or NaN, convert them to zeros.
+*/
+nv.utils.NaNtoZero = function(n) {
+ if (typeof n !== 'number'
+ || isNaN(n)
+ || n === null
+ || n === Infinity) return 0;
+
+ return n;
+};
+
+/*
+Snippet of code you can insert into each nv.models.* to give you the ability to
+do things like:
+chart.options({
+ showXAxis: true,
+ tooltips: true
+});
+
+To enable in the chart:
+chart.options = nv.utils.optionsFunc.bind(chart);
+*/
+nv.utils.optionsFunc = function(args) {
+ if (args) {
+ d3.map(args).forEach((function(key,value) {
+ if (typeof this[key] === "function") {
+ this[key](value);
+ }
+ }).bind(this));
+ }
+ return this;
+};nv.models.axis = function() {
+ "use strict";
//============================================================
// Public Variables with Default Settings
//------------------------------------------------------------
@@ -389,6 +1037,7 @@ nv.models.axis = function() {
, staggerLabels = false
, isOrdinal = false
, ticks = null
+ , axisLabelDistance = 12 //The larger this number is, the closer the axis label is to the axis.
;
axis
@@ -434,8 +1083,7 @@ nv.models.axis = function() {
//TODO: consider calculating width/height based on whether or not label is added, for reference in charts using this component
- d3.transition(g)
- .call(axis);
+ g.transition().call(axis);
scale0 = scale0 || axis.scale();
@@ -465,14 +1113,14 @@ nv.models.axis = function() {
return 'translate(' + scale(d) + ',0)'
})
.select('text')
- .attr('dy', '0em')
+ .attr('dy', '-0.5em')
.attr('y', -axis.tickPadding())
.attr('text-anchor', 'middle')
.text(function(d,i) {
var v = fmt(d);
return ('' + v).match('NaN') ? '' : v;
});
- d3.transition(axisMaxMin)
+ axisMaxMin.transition()
.attr('transform', function(d,i) {
return 'translate(' + scale.range()[i] + ',0)'
});
@@ -494,7 +1142,7 @@ nv.models.axis = function() {
//Rotate all xTicks
xTicks
.attr('transform', function(d,i,j) { return 'rotate(' + rotateLabels + ' 0,0)' })
- .attr('text-anchor', rotateLabels%360 > 0 ? 'start' : 'end');
+ .style('text-anchor', rotateLabels%360 > 0 ? 'start' : 'end');
}
axisLabel.enter().append('text').attr('class', 'nv-axislabel');
var w = (scale.range().length==2) ? scale.range()[1] : (scale.range()[scale.range().length-1]+(scale.range()[1]-scale.range()[0]));
@@ -517,12 +1165,12 @@ nv.models.axis = function() {
.attr('dy', '.71em')
.attr('y', axis.tickPadding())
.attr('transform', function(d,i,j) { return 'rotate(' + rotateLabels + ' 0,0)' })
- .attr('text-anchor', rotateLabels ? (rotateLabels%360 > 0 ? 'start' : 'end') : 'middle')
+ .style('text-anchor', rotateLabels ? (rotateLabels%360 > 0 ? 'start' : 'end') : 'middle')
.text(function(d,i) {
var v = fmt(d);
return ('' + v).match('NaN') ? '' : v;
});
- d3.transition(axisMaxMin)
+ axisMaxMin.transition()
.attr('transform', function(d,i) {
//return 'translate(' + scale.range()[i] + ',0)'
//return 'translate(' + scale(d) + ',0)'
@@ -537,7 +1185,7 @@ nv.models.axis = function() {
case 'right':
axisLabel.enter().append('text').attr('class', 'nv-axislabel');
axisLabel
- .attr('text-anchor', rotateYLabel ? 'middle' : 'begin')
+ .style('text-anchor', rotateYLabel ? 'middle' : 'begin')
.attr('transform', rotateYLabel ? 'rotate(90)' : '')
.attr('y', rotateYLabel ? (-Math.max(margin.right,width) + 12) : -10) //TODO: consider calculating this based on largest tick width... OR at least expose this on chart
.attr('x', rotateYLabel ? (scale.range()[0] / 2) : axis.tickPadding());
@@ -555,12 +1203,12 @@ nv.models.axis = function() {
.attr('dy', '.32em')
.attr('y', 0)
.attr('x', axis.tickPadding())
- .attr('text-anchor', 'start')
+ .style('text-anchor', 'start')
.text(function(d,i) {
var v = fmt(d);
return ('' + v).match('NaN') ? '' : v;
});
- d3.transition(axisMaxMin)
+ axisMaxMin.transition()
.attr('transform', function(d,i) {
return 'translate(0,' + scale.range()[i] + ')'
})
@@ -579,9 +1227,9 @@ nv.models.axis = function() {
*/
axisLabel.enter().append('text').attr('class', 'nv-axislabel');
axisLabel
- .attr('text-anchor', rotateYLabel ? 'middle' : 'end')
+ .style('text-anchor', rotateYLabel ? 'middle' : 'end')
.attr('transform', rotateYLabel ? 'rotate(-90)' : '')
- .attr('y', rotateYLabel ? (-Math.max(margin.left,width) + 12) : -10) //TODO: consider calculating this based on largest tick width... OR at least expose this on chart
+ .attr('y', rotateYLabel ? (-Math.max(margin.left,width) + axisLabelDistance) : -10) //TODO: consider calculating this based on largest tick width... OR at least expose this on chart
.attr('x', rotateYLabel ? (-scale.range()[0] / 2) : -axis.tickPadding());
if (showMaxMin) {
var axisMaxMin = wrap.selectAll('g.nv-axisMaxMin')
@@ -602,7 +1250,7 @@ nv.models.axis = function() {
var v = fmt(d);
return ('' + v).match('NaN') ? '' : v;
});
- d3.transition(axisMaxMin)
+ axisMaxMin.transition()
.attr('transform', function(d,i) {
return 'translate(0,' + scale.range()[i] + ')'
})
@@ -623,7 +1271,7 @@ nv.models.axis = function() {
if (scale(d) < scale.range()[1] + 10 || scale(d) > scale.range()[0] - 10) { // 10 is assuming text height is 16... if d is 0, leave it!
if (d > 1e-10 || d < -1e-10) // accounts for minor floating point errors... though could be problematic if the scale is EXTREMELY SMALL
d3.select(this).attr('opacity', 0);
-
+
d3.select(this).select('text').attr('opacity', 0); // Don't remove the ZERO line!!
}
});
@@ -688,6 +1336,8 @@ nv.models.axis = function() {
d3.rebind(chart, axis, 'orient', 'tickValues', 'tickSubdivide', 'tickSize', 'tickPadding', 'tickFormat');
d3.rebind(chart, scale, 'domain', 'range', 'rangeBand', 'rangeBands'); //these are also accessible by chart.scale(), but added common ones directly for ease of use
+ chart.options = nv.utils.optionsFunc.bind(chart);
+
chart.margin = function(_) {
if(!arguments.length) return margin;
margin.top = typeof _.top != 'undefined' ? _.top : margin.top;
@@ -760,71 +1410,79 @@ nv.models.axis = function() {
return chart;
};
+ chart.axisLabelDistance = function(_) {
+ if (!arguments.length) return axisLabelDistance;
+ axisLabelDistance = _;
+ return chart;
+ };
//============================================================
return chart;
}
-
-// Chart design based on the recommendations of Stephen Few. Implementation
-// based on the work of Clint Ivy, Jamie Love, and Jason Davies.
-// http://projects.instantcognition.com/protovis/bulletchart/
-
-nv.models.bullet = function() {
-
+//TODO: consider deprecating and using multibar with single series for this
+nv.models.historicalBar = function() {
+ "use strict";
//============================================================
// Public Variables with Default Settings
//------------------------------------------------------------
var margin = {top: 0, right: 0, bottom: 0, left: 0}
- , orient = 'left' // TODO top & bottom
- , reverse = false
- , ranges = function(d) { return d.ranges }
- , markers = function(d) { return d.markers }
- , measures = function(d) { return d.measures }
- , forceX = [0] // List of numbers to Force into the X scale (ie. 0, or a max / min, etc.)
- , width = 380
- , height = 30
- , tickFormat = null
- , color = nv.utils.getColor(['#1f77b4'])
- , dispatch = d3.dispatch('elementMouseover', 'elementMouseout')
+ , width = 960
+ , height = 500
+ , id = Math.floor(Math.random() * 10000) //Create semi-unique ID in case user doesn't select one
+ , x = d3.scale.linear()
+ , y = d3.scale.linear()
+ , getX = function(d) { return d.x }
+ , getY = function(d) { return d.y }
+ , forceX = []
+ , forceY = [0]
+ , padData = false
+ , clipEdge = true
+ , color = nv.utils.defaultColor()
+ , xDomain
+ , yDomain
+ , xRange
+ , yRange
+ , dispatch = d3.dispatch('chartClick', 'elementClick', 'elementDblClick', 'elementMouseover', 'elementMouseout')
+ , interactive = true
;
//============================================================
function chart(selection) {
- selection.each(function(d, i) {
+ selection.each(function(data) {
var availableWidth = width - margin.left - margin.right,
availableHeight = height - margin.top - margin.bottom,
container = d3.select(this);
- var rangez = ranges.call(this, d, i).slice().sort(d3.descending),
- markerz = markers.call(this, d, i).slice().sort(d3.descending),
- measurez = measures.call(this, d, i).slice().sort(d3.descending);
-
//------------------------------------------------------------
// Setup Scales
- // Compute the new x-scale.
- var x1 = d3.scale.linear()
- .domain( d3.extent(d3.merge([forceX, rangez])) )
- .range(reverse ? [availableWidth, 0] : [0, availableWidth]);
+ x .domain(xDomain || d3.extent(data[0].values.map(getX).concat(forceX) ))
- // Retrieve the old x-scale, if this is an update.
- var x0 = this.__chart__ || d3.scale.linear()
- .domain([0, Infinity])
- .range(x1.range());
+ if (padData)
+ x.range(xRange || [availableWidth * .5 / data[0].values.length, availableWidth * (data[0].values.length - .5) / data[0].values.length ]);
+ else
+ x.range(xRange || [0, availableWidth]);
- // Stash the new scale.
- this.__chart__ = x1;
+ y .domain(yDomain || d3.extent(data[0].values.map(getY).concat(forceY) ))
+ .range(yRange || [availableHeight, 0]);
+ // If scale's domain don't have a range, slightly adjust to make one... so a chart can show a single data point
- var rangeMin = d3.min(rangez), //rangez[2]
- rangeMax = d3.max(rangez), //rangez[0]
- rangeAvg = rangez[1];
+ if (x.domain()[0] === x.domain()[1])
+ x.domain()[0] ?
+ x.domain([x.domain()[0] - x.domain()[0] * 0.01, x.domain()[1] + x.domain()[1] * 0.01])
+ : x.domain([-1,1]);
+
+ if (y.domain()[0] === y.domain()[1])
+ y.domain()[0] ?
+ y.domain([y.domain()[0] + y.domain()[0] * 0.01, y.domain()[1] - y.domain()[1] * 0.01])
+ : y.domain([-1,1]);
//------------------------------------------------------------
@@ -832,63 +1490,397 @@ nv.models.bullet = function() {
//------------------------------------------------------------
// Setup containers and skeleton of chart
- var wrap = container.selectAll('g.nv-wrap.nv-bullet').data([d]);
- var wrapEnter = wrap.enter().append('g').attr('class', 'nvd3 nv-wrap nv-bullet');
+ var wrap = container.selectAll('g.nv-wrap.nv-historicalBar-' + id).data([data[0].values]);
+ var wrapEnter = wrap.enter().append('g').attr('class', 'nvd3 nv-wrap nv-historicalBar-' + id);
+ var defsEnter = wrapEnter.append('defs');
var gEnter = wrapEnter.append('g');
var g = wrap.select('g');
- gEnter.append('rect').attr('class', 'nv-range nv-rangeMax');
- gEnter.append('rect').attr('class', 'nv-range nv-rangeAvg');
- gEnter.append('rect').attr('class', 'nv-range nv-rangeMin');
- gEnter.append('rect').attr('class', 'nv-measure');
- gEnter.append('path').attr('class', 'nv-markerTriangle');
+ gEnter.append('g').attr('class', 'nv-bars');
wrap.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');
//------------------------------------------------------------
+ container
+ .on('click', function(d,i) {
+ dispatch.chartClick({
+ data: d,
+ index: i,
+ pos: d3.event,
+ id: id
+ });
+ });
- var w0 = function(d) { return Math.abs(x0(d) - x0(0)) }, // TODO: could optimize by precalculating x0(0) and x1(0)
- w1 = function(d) { return Math.abs(x1(d) - x1(0)) };
- var xp0 = function(d) { return d < 0 ? x0(d) : x0(0) },
- xp1 = function(d) { return d < 0 ? x1(d) : x1(0) };
+ defsEnter.append('clipPath')
+ .attr('id', 'nv-chart-clip-path-' + id)
+ .append('rect');
- g.select('rect.nv-rangeMax')
- .attr('height', availableHeight)
- .attr('width', w1(rangeMax > 0 ? rangeMax : rangeMin))
- .attr('x', xp1(rangeMax > 0 ? rangeMax : rangeMin))
- .datum(rangeMax > 0 ? rangeMax : rangeMin)
- /*
- .attr('x', rangeMin < 0 ?
- rangeMax > 0 ?
- x1(rangeMin)
- : x1(rangeMax)
- : x1(0))
- */
+ wrap.select('#nv-chart-clip-path-' + id + ' rect')
+ .attr('width', availableWidth)
+ .attr('height', availableHeight);
- g.select('rect.nv-rangeAvg')
- .attr('height', availableHeight)
- .attr('width', w1(rangeAvg))
- .attr('x', xp1(rangeAvg))
- .datum(rangeAvg)
- /*
- .attr('width', rangeMax <= 0 ?
- x1(rangeMax) - x1(rangeAvg)
- : x1(rangeAvg) - x1(rangeMin))
- .attr('x', rangeMax <= 0 ?
- x1(rangeAvg)
- : x1(rangeMin))
- */
+ g .attr('clip-path', clipEdge ? 'url(#nv-chart-clip-path-' + id + ')' : '');
- g.select('rect.nv-rangeMin')
- .attr('height', availableHeight)
- .attr('width', w1(rangeMax))
- .attr('x', xp1(rangeMax))
- .attr('width', w1(rangeMax > 0 ? rangeMin : rangeMax))
- .attr('x', xp1(rangeMax > 0 ? rangeMin : rangeMax))
- .datum(rangeMax > 0 ? rangeMin : rangeMax)
+
+
+ var bars = wrap.select('.nv-bars').selectAll('.nv-bar')
+ .data(function(d) { return d }, function(d,i) {return getX(d,i)});
+
+ bars.exit().remove();
+
+
+ var barsEnter = bars.enter().append('rect')
+ //.attr('class', function(d,i,j) { return (getY(d,i) < 0 ? 'nv-bar negative' : 'nv-bar positive') + ' nv-bar-' + j + '-' + i })
+ .attr('x', 0 )
+ .attr('y', function(d,i) { return nv.utils.NaNtoZero(y(Math.max(0, getY(d,i)))) })
+ .attr('height', function(d,i) { return nv.utils.NaNtoZero(Math.abs(y(getY(d,i)) - y(0))) })
+ .attr('transform', function(d,i) { return 'translate(' + (x(getX(d,i)) - availableWidth / data[0].values.length * .45) + ',0)'; })
+ .on('mouseover', function(d,i) {
+ if (!interactive) return;
+ d3.select(this).classed('hover', true);
+ dispatch.elementMouseover({
+ point: d,
+ series: data[0],
+ pos: [x(getX(d,i)), y(getY(d,i))], // TODO: Figure out why the value appears to be shifted
+ pointIndex: i,
+ seriesIndex: 0,
+ e: d3.event
+ });
+
+ })
+ .on('mouseout', function(d,i) {
+ if (!interactive) return;
+ d3.select(this).classed('hover', false);
+ dispatch.elementMouseout({
+ point: d,
+ series: data[0],
+ pointIndex: i,
+ seriesIndex: 0,
+ e: d3.event
+ });
+ })
+ .on('click', function(d,i) {
+ if (!interactive) return;
+ dispatch.elementClick({
+ //label: d[label],
+ value: getY(d,i),
+ data: d,
+ index: i,
+ pos: [x(getX(d,i)), y(getY(d,i))],
+ e: d3.event,
+ id: id
+ });
+ d3.event.stopPropagation();
+ })
+ .on('dblclick', function(d,i) {
+ if (!interactive) return;
+ dispatch.elementDblClick({
+ //label: d[label],
+ value: getY(d,i),
+ data: d,
+ index: i,
+ pos: [x(getX(d,i)), y(getY(d,i))],
+ e: d3.event,
+ id: id
+ });
+ d3.event.stopPropagation();
+ });
+
+ bars
+ .attr('fill', function(d,i) { return color(d, i); })
+ .attr('class', function(d,i,j) { return (getY(d,i) < 0 ? 'nv-bar negative' : 'nv-bar positive') + ' nv-bar-' + j + '-' + i })
+ .transition()
+ .attr('transform', function(d,i) { return 'translate(' + (x(getX(d,i)) - availableWidth / data[0].values.length * .45) + ',0)'; })
+ //TODO: better width calculations that don't assume always uniform data spacing;w
+ .attr('width', (availableWidth / data[0].values.length) * .9 );
+
+
+ bars.transition()
+ .attr('y', function(d,i) {
+ var rval = getY(d,i) < 0 ?
+ y(0) :
+ y(0) - y(getY(d,i)) < 1 ?
+ y(0) - 1 :
+ y(getY(d,i));
+ return nv.utils.NaNtoZero(rval);
+ })
+ .attr('height', function(d,i) { return nv.utils.NaNtoZero(Math.max(Math.abs(y(getY(d,i)) - y(0)),1)) });
+
+ });
+
+ return chart;
+ }
+
+ //Create methods to allow outside functions to highlight a specific bar.
+ chart.highlightPoint = function(pointIndex, isHoverOver) {
+ d3.select(".nv-historicalBar-" + id)
+ .select(".nv-bars .nv-bar-0-" + pointIndex)
+ .classed("hover", isHoverOver)
+ ;
+ };
+
+ chart.clearHighlights = function() {
+ d3.select(".nv-historicalBar-" + id)
+ .select(".nv-bars .nv-bar.hover")
+ .classed("hover", false)
+ ;
+ };
+ //============================================================
+ // Expose Public Variables
+ //------------------------------------------------------------
+
+ chart.dispatch = dispatch;
+
+ chart.options = nv.utils.optionsFunc.bind(chart);
+
+ chart.x = function(_) {
+ if (!arguments.length) return getX;
+ getX = _;
+ return chart;
+ };
+
+ chart.y = function(_) {
+ if (!arguments.length) return getY;
+ getY = _;
+ return chart;
+ };
+
+ chart.margin = function(_) {
+ if (!arguments.length) return margin;
+ margin.top = typeof _.top != 'undefined' ? _.top : margin.top;
+ margin.right = typeof _.right != 'undefined' ? _.right : margin.right;
+ margin.bottom = typeof _.bottom != 'undefined' ? _.bottom : margin.bottom;
+ margin.left = typeof _.left != 'undefined' ? _.left : margin.left;
+ return chart;
+ };
+
+ chart.width = function(_) {
+ if (!arguments.length) return width;
+ width = _;
+ return chart;
+ };
+
+ chart.height = function(_) {
+ if (!arguments.length) return height;
+ height = _;
+ return chart;
+ };
+
+ chart.xScale = function(_) {
+ if (!arguments.length) return x;
+ x = _;
+ return chart;
+ };
+
+ chart.yScale = function(_) {
+ if (!arguments.length) return y;
+ y = _;
+ return chart;
+ };
+
+ chart.xDomain = function(_) {
+ if (!arguments.length) return xDomain;
+ xDomain = _;
+ return chart;
+ };
+
+ chart.yDomain = function(_) {
+ if (!arguments.length) return yDomain;
+ yDomain = _;
+ return chart;
+ };
+
+ chart.xRange = function(_) {
+ if (!arguments.length) return xRange;
+ xRange = _;
+ return chart;
+ };
+
+ chart.yRange = function(_) {
+ if (!arguments.length) return yRange;
+ yRange = _;
+ return chart;
+ };
+
+ chart.forceX = function(_) {
+ if (!arguments.length) return forceX;
+ forceX = _;
+ return chart;
+ };
+
+ chart.forceY = function(_) {
+ if (!arguments.length) return forceY;
+ forceY = _;
+ return chart;
+ };
+
+ chart.padData = function(_) {
+ if (!arguments.length) return padData;
+ padData = _;
+ return chart;
+ };
+
+ chart.clipEdge = function(_) {
+ if (!arguments.length) return clipEdge;
+ clipEdge = _;
+ return chart;
+ };
+
+ chart.color = function(_) {
+ if (!arguments.length) return color;
+ color = nv.utils.getColor(_);
+ return chart;
+ };
+
+ chart.id = function(_) {
+ if (!arguments.length) return id;
+ id = _;
+ return chart;
+ };
+
+ chart.interactive = function(_) {
+ if(!arguments.length) return interactive;
+ interactive = false;
+ return chart;
+ };
+
+ //============================================================
+
+
+ return chart;
+}
+
+// Chart design based on the recommendations of Stephen Few. Implementation
+// based on the work of Clint Ivy, Jamie Love, and Jason Davies.
+// http://projects.instantcognition.com/protovis/bulletchart/
+
+nv.models.bullet = function() {
+ "use strict";
+ //============================================================
+ // Public Variables with Default Settings
+ //------------------------------------------------------------
+
+ var margin = {top: 0, right: 0, bottom: 0, left: 0}
+ , orient = 'left' // TODO top & bottom
+ , reverse = false
+ , ranges = function(d) { return d.ranges }
+ , markers = function(d) { return d.markers }
+ , measures = function(d) { return d.measures }
+ , rangeLabels = function(d) { return d.rangeLabels ? d.rangeLabels : [] }
+ , markerLabels = function(d) { return d.markerLabels ? d.markerLabels : [] }
+ , measureLabels = function(d) { return d.measureLabels ? d.measureLabels : [] }
+ , forceX = [0] // List of numbers to Force into the X scale (ie. 0, or a max / min, etc.)
+ , width = 380
+ , height = 30
+ , tickFormat = null
+ , color = nv.utils.getColor(['#1f77b4'])
+ , dispatch = d3.dispatch('elementMouseover', 'elementMouseout')
+ ;
+
+ //============================================================
+
+
+ function chart(selection) {
+ selection.each(function(d, i) {
+ var availableWidth = width - margin.left - margin.right,
+ availableHeight = height - margin.top - margin.bottom,
+ container = d3.select(this);
+
+ var rangez = ranges.call(this, d, i).slice().sort(d3.descending),
+ markerz = markers.call(this, d, i).slice().sort(d3.descending),
+ measurez = measures.call(this, d, i).slice().sort(d3.descending),
+ rangeLabelz = rangeLabels.call(this, d, i).slice(),
+ markerLabelz = markerLabels.call(this, d, i).slice(),
+ measureLabelz = measureLabels.call(this, d, i).slice();
+
+
+ //------------------------------------------------------------
+ // Setup Scales
+
+ // Compute the new x-scale.
+ var x1 = d3.scale.linear()
+ .domain( d3.extent(d3.merge([forceX, rangez])) )
+ .range(reverse ? [availableWidth, 0] : [0, availableWidth]);
+
+ // Retrieve the old x-scale, if this is an update.
+ var x0 = this.__chart__ || d3.scale.linear()
+ .domain([0, Infinity])
+ .range(x1.range());
+
+ // Stash the new scale.
+ this.__chart__ = x1;
+
+
+ var rangeMin = d3.min(rangez), //rangez[2]
+ rangeMax = d3.max(rangez), //rangez[0]
+ rangeAvg = rangez[1];
+
+ //------------------------------------------------------------
+
+
+ //------------------------------------------------------------
+ // Setup containers and skeleton of chart
+
+ var wrap = container.selectAll('g.nv-wrap.nv-bullet').data([d]);
+ var wrapEnter = wrap.enter().append('g').attr('class', 'nvd3 nv-wrap nv-bullet');
+ var gEnter = wrapEnter.append('g');
+ var g = wrap.select('g');
+
+ gEnter.append('rect').attr('class', 'nv-range nv-rangeMax');
+ gEnter.append('rect').attr('class', 'nv-range nv-rangeAvg');
+ gEnter.append('rect').attr('class', 'nv-range nv-rangeMin');
+ gEnter.append('rect').attr('class', 'nv-measure');
+ gEnter.append('path').attr('class', 'nv-markerTriangle');
+
+ wrap.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');
+
+ //------------------------------------------------------------
+
+
+
+ var w0 = function(d) { return Math.abs(x0(d) - x0(0)) }, // TODO: could optimize by precalculating x0(0) and x1(0)
+ w1 = function(d) { return Math.abs(x1(d) - x1(0)) };
+ var xp0 = function(d) { return d < 0 ? x0(d) : x0(0) },
+ xp1 = function(d) { return d < 0 ? x1(d) : x1(0) };
+
+
+ g.select('rect.nv-rangeMax')
+ .attr('height', availableHeight)
+ .attr('width', w1(rangeMax > 0 ? rangeMax : rangeMin))
+ .attr('x', xp1(rangeMax > 0 ? rangeMax : rangeMin))
+ .datum(rangeMax > 0 ? rangeMax : rangeMin)
+ /*
+ .attr('x', rangeMin < 0 ?
+ rangeMax > 0 ?
+ x1(rangeMin)
+ : x1(rangeMax)
+ : x1(0))
+ */
+
+ g.select('rect.nv-rangeAvg')
+ .attr('height', availableHeight)
+ .attr('width', w1(rangeAvg))
+ .attr('x', xp1(rangeAvg))
+ .datum(rangeAvg)
+ /*
+ .attr('width', rangeMax <= 0 ?
+ x1(rangeMax) - x1(rangeAvg)
+ : x1(rangeAvg) - x1(rangeMin))
+ .attr('x', rangeMax <= 0 ?
+ x1(rangeAvg)
+ : x1(rangeMin))
+ */
+
+ g.select('rect.nv-rangeMin')
+ .attr('height', availableHeight)
+ .attr('width', w1(rangeMax))
+ .attr('x', xp1(rangeMax))
+ .attr('width', w1(rangeMax > 0 ? rangeMin : rangeMax))
+ .attr('x', xp1(rangeMax > 0 ? rangeMin : rangeMax))
+ .datum(rangeMax > 0 ? rangeMin : rangeMax)
/*
.attr('width', rangeMax <= 0 ?
x1(rangeAvg) - x1(rangeMin)
@@ -909,14 +1901,14 @@ nv.models.bullet = function() {
.on('mouseover', function() {
dispatch.elementMouseover({
value: measurez[0],
- label: 'Current',
+ label: measureLabelz[0] || 'Current',
pos: [x1(measurez[0]), availableHeight/2]
})
})
.on('mouseout', function() {
dispatch.elementMouseout({
value: measurez[0],
- label: 'Current'
+ label: measureLabelz[0] || 'Current'
})
})
@@ -928,14 +1920,14 @@ nv.models.bullet = function() {
.on('mouseover', function() {
dispatch.elementMouseover({
value: markerz[0],
- label: 'Previous',
+ label: markerLabelz[0] || 'Previous',
pos: [x1(markerz[0]), availableHeight/2]
})
})
.on('mouseout', function() {
dispatch.elementMouseout({
value: markerz[0],
- label: 'Previous'
+ label: markerLabelz[0] || 'Previous'
})
});
} else {
@@ -945,7 +1937,7 @@ nv.models.bullet = function() {
wrap.selectAll('.nv-range')
.on('mouseover', function(d,i) {
- var label = !i ? "Maximum" : i == 1 ? "Mean" : "Minimum";
+ var label = rangeLabelz[i] || (!i ? "Maximum" : i == 1 ? "Mean" : "Minimum");
dispatch.elementMouseover({
value: d,
@@ -954,7 +1946,7 @@ nv.models.bullet = function() {
})
})
.on('mouseout', function(d,i) {
- var label = !i ? "Maximum" : i == 1 ? "Mean" : "Minimum";
+ var label = rangeLabelz[i] || (!i ? "Maximum" : i == 1 ? "Mean" : "Minimum");
dispatch.elementMouseout({
value: d,
@@ -1068,6 +2060,8 @@ nv.models.bullet = function() {
chart.dispatch = dispatch;
+ chart.options = nv.utils.optionsFunc.bind(chart);
+
// left, right, top, bottom
chart.orient = function(_) {
if (!arguments.length) return orient;
@@ -1148,7 +2142,7 @@ nv.models.bullet = function() {
// based on the work of Clint Ivy, Jamie Love, and Jason Davies.
// http://projects.instantcognition.com/protovis/bulletchart/
nv.models.bulletChart = function() {
-
+ "use strict";
//============================================================
// Public Variables with Default Settings
//------------------------------------------------------------
@@ -1403,6 +2397,8 @@ nv.models.bulletChart = function() {
d3.rebind(chart, bullet, 'color');
+ chart.options = nv.utils.optionsFunc.bind(chart);
+
// left, right, top, bottom
chart.orient = function(x) {
if (!arguments.length) return orient;
@@ -1486,7 +2482,7 @@ nv.models.bulletChart = function() {
nv.models.cumulativeLineChart = function() {
-
+ "use strict";
//============================================================
// Public Variables with Default Settings
//------------------------------------------------------------
@@ -1496,6 +2492,7 @@ nv.models.cumulativeLineChart = function() {
, yAxis = nv.models.axis()
, legend = nv.models.legend()
, controls = nv.models.legend()
+ , interactiveLayer = nv.interactiveGuideline()
;
var margin = {top: 30, right: 30, bottom: 50, left: 60}
@@ -1503,8 +2500,12 @@ nv.models.cumulativeLineChart = function() {
, width = null
, height = null
, showLegend = true
+ , showXAxis = true
+ , showYAxis = true
+ , rightAlignYAxis = false
, tooltips = true
, showControls = true
+ , useInteractiveGuideline = false
, rescaleY = true
, tooltip = function(key, x, y, e, graph) {
return '<h3>' + key + '</h3>' +
@@ -1518,6 +2519,8 @@ nv.models.cumulativeLineChart = function() {
, noData = 'No Data Available.'
, average = function(d) { return d.average }
, dispatch = d3.dispatch('tooltipShow', 'tooltipHide', 'stateChange', 'changeState')
+ , transitionDuration = 250
+ , noErrorCheck = false //if set to TRUE, will bypass an error check in the indexify function.
;
xAxis
@@ -1525,11 +2528,11 @@ nv.models.cumulativeLineChart = function() {
.tickPadding(7)
;
yAxis
- .orient('left')
+ .orient((rightAlignYAxis) ? 'right' : 'left')
;
//============================================================
-
+ controls.updateState(false);
//============================================================
// Private Variables
@@ -1549,36 +2552,8 @@ nv.models.cumulativeLineChart = function() {
nv.tooltip.show([left, top], content, null, null, offsetElement);
};
-/*
- //Moved to see if we can get better behavior to fix issue #315
- var indexDrag = d3.behavior.drag()
- .on('dragstart', dragStart)
- .on('drag', dragMove)
- .on('dragend', dragEnd);
-
- function dragStart(d,i) {
- d3.select(chart.container)
- .style('cursor', 'ew-resize');
- }
-
- function dragMove(d,i) {
- d.x += d3.event.dx;
- d.i = Math.round(dx.invert(d.x));
-
- d3.select(this).attr('transform', 'translate(' + dx(d.i) + ',0)');
- chart.update();
- }
-
- function dragEnd(d,i) {
- d3.select(chart.container)
- .style('cursor', 'auto');
- chart.update();
- }
-*/
-
//============================================================
-
function chart(selection) {
selection.each(function(data) {
var container = d3.select(this).classed('nv-chart-' + id, true),
@@ -1590,7 +2565,7 @@ nv.models.cumulativeLineChart = function() {
- margin.top - margin.bottom;
- chart.update = function() { container.transition().call(chart) };
+ chart.update = function() { container.transition().duration(transitionDuration).call(chart) };
chart.container = this;
//set state.disabled
@@ -1633,9 +2608,6 @@ nv.models.cumulativeLineChart = function() {
dispatch.stateChange(state);
}
-
-
-
//------------------------------------------------------------
// Display No Data message if there's nothing to show.
@@ -1705,21 +2677,20 @@ nv.models.cumulativeLineChart = function() {
//------------------------------------------------------------
// Setup containers and skeleton of chart
-
+ var interactivePointerEvents = (useInteractiveGuideline) ? "none" : "all";
var wrap = container.selectAll('g.nv-wrap.nv-cumulativeLine').data([data]);
var gEnter = wrap.enter().append('g').attr('class', 'nvd3 nv-wrap nv-cumulativeLine').append('g');
var g = wrap.select('g');
- gEnter.append('g').attr('class', 'nv-x nv-axis');
+ gEnter.append('g').attr('class', 'nv-interactive');
+ gEnter.append('g').attr('class', 'nv-x nv-axis').style("pointer-events","none");
gEnter.append('g').attr('class', 'nv-y nv-axis');
gEnter.append('g').attr('class', 'nv-background');
- gEnter.append('g').attr('class', 'nv-linesWrap');
- gEnter.append('g').attr('class', 'nv-avgLinesWrap');
+ gEnter.append('g').attr('class', 'nv-linesWrap').style("pointer-events",interactivePointerEvents);
+ gEnter.append('g').attr('class', 'nv-avgLinesWrap').style("pointer-events","none");
gEnter.append('g').attr('class', 'nv-legendWrap');
gEnter.append('g').attr('class', 'nv-controlsWrap');
- //------------------------------------------------------------
-
//------------------------------------------------------------
// Legend
@@ -1732,7 +2703,7 @@ nv.models.cumulativeLineChart = function() {
.call(legend);
if ( margin.top != legend.height()) {
- margin.top = legend.height() + legend.legendBelowPadding();// added legend.legendBelowPadding to allow for more spacing
+ margin.top = legend.height();
availableHeight = (height || parseInt(container.style('height')) || 400)
- margin.top - margin.bottom;
}
@@ -1752,7 +2723,13 @@ nv.models.cumulativeLineChart = function() {
{ key: 'Re-scale y-axis', disabled: !rescaleY }
];
- controls.width(140).color(['#444', '#444', '#444']);
+ controls
+ .width(140)
+ .color(['#444', '#444', '#444'])
+ .rightAlign(false)
+ .margin({top: 5, right: 0, bottom: 5, left: 20})
+ ;
+
g.select('.nv-controlsWrap')
.datum(controlsData)
.attr('transform', 'translate(0,' + (-margin.top) +')')
@@ -1764,6 +2741,10 @@ nv.models.cumulativeLineChart = function() {
wrap.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');
+ if (rightAlignYAxis) {
+ g.select(".nv-y.nv-axis")
+ .attr("transform", "translate(" + availableWidth + ",0)");
+ }
// Show error if series goes below 100%
var tempDisabled = data.filter(function(d) { return d.tempDisabled });
@@ -1780,6 +2761,18 @@ nv.models.cumulativeLineChart = function() {
//------------------------------------------------------------
// Main Chart Component(s)
+ //------------------------------------------------------------
+ //Set up interactive layer
+ if (useInteractiveGuideline) {
+ interactiveLayer
+ .width(availableWidth)
+ .height(availableHeight)
+ .margin({left:margin.left,top:margin.top})
+ .svgContainer(container)
+ .xScale(x);
+ wrap.select(".nv-interactive").call(interactiveLayer);
+ }
+
gEnter.select('.nv-background')
.append('rect');
@@ -1818,6 +2811,14 @@ nv.models.cumulativeLineChart = function() {
var avgLines = g.select(".nv-avgLinesWrap").selectAll("line")
.data(avgLineData, function(d) { return d.key; });
+ var getAvgLineY = function(d) {
+ //If average lines go off the svg element, clamp them to the svg bounds.
+ var yVal = y(average(d));
+ if (yVal < 0) return 0;
+ if (yVal > availableHeight) return availableHeight;
+ return yVal;
+ };
+
avgLines.enter()
.append('line')
.style('stroke-width',2)
@@ -1827,14 +2828,20 @@ nv.models.cumulativeLineChart = function() {
})
.attr('x1',0)
.attr('x2',availableWidth)
- .attr('y1', function(d) { return y(average(d)); })
- .attr('y2', function(d) { return y(average(d)); });
+ .attr('y1', getAvgLineY)
+ .attr('y2', getAvgLineY);
avgLines
+ .style('stroke-opacity',function(d){
+ //If average lines go offscreen, make them transparent
+ var yVal = y(average(d));
+ if (yVal < 0 || yVal > availableHeight) return 0;
+ return 1;
+ })
.attr('x1',0)
.attr('x2',availableWidth)
- .attr('y1', function(d) { return y(average(d)); })
- .attr('y2', function(d) { return y(average(d)); });
+ .attr('y1', getAvgLineY)
+ .attr('y2', getAvgLineY);
avgLines.exit().remove();
@@ -1847,6 +2854,7 @@ nv.models.cumulativeLineChart = function() {
.attr('x', -2)
.attr('fill', 'red')
.attr('fill-opacity', .5)
+ .style("pointer-events","all")
.call(indexDrag)
indexLine
@@ -1859,26 +2867,29 @@ nv.models.cumulativeLineChart = function() {
//------------------------------------------------------------
// Setup Axes
- xAxis
- .scale(x)
- //Suggest how many ticks based on the chart width and D3 should listen (70 is the optimal number for MM/DD/YY dates)
- .ticks( Math.min(data[0].values.length,availableWidth/70) )
- .tickSize(-availableHeight, 0);
-
- g.select('.nv-x.nv-axis')
- .attr('transform', 'translate(0,' + y.range()[0] + ')');
- d3.transition(g.select('.nv-x.nv-axis'))
- .call(xAxis);
+ if (showXAxis) {
+ xAxis
+ .scale(x)
+ //Suggest how many ticks based on the chart width and D3 should listen (70 is the optimal number for MM/DD/YY dates)
+ .ticks( Math.min(data[0].values.length,availableWidth/70) )
+ .tickSize(-availableHeight, 0);
+ g.select('.nv-x.nv-axis')
+ .attr('transform', 'translate(0,' + y.range()[0] + ')');
+ d3.transition(g.select('.nv-x.nv-axis'))
+ .call(xAxis);
+ }
- yAxis
- .scale(y)
- .ticks( availableHeight / 36 )
- .tickSize( -availableWidth, 0);
- d3.transition(g.select('.nv-y.nv-axis'))
- .call(yAxis);
+ if (showYAxis) {
+ yAxis
+ .scale(y)
+ .ticks( availableHeight / 36 )
+ .tickSize( -availableWidth, 0);
+ d3.transition(g.select('.nv-y.nv-axis'))
+ .call(yAxis);
+ }
//------------------------------------------------------------
@@ -1891,7 +2902,12 @@ nv.models.cumulativeLineChart = function() {
indexLine
.data([index]);
- container.call(chart);
+ //When dragging the index line, turn off line transitions.
+ // Then turn them back on when done dragging.
+ var oldDuration = chart.transitionDuration();
+ chart.transitionDuration(0);
+ chart.update();
+ chart.transitionDuration(oldDuration);
}
g.select('.nv-background rect')
@@ -1917,61 +2933,79 @@ nv.models.cumulativeLineChart = function() {
updateZero();
});
- controls.dispatch.on('legendClick', function(d,i) {
+ controls.dispatch.on('legendClick', function(d,i) {
d.disabled = !d.disabled;
rescaleY = !d.disabled;
state.rescaleY = rescaleY;
dispatch.stateChange(state);
-
- //selection.transition().call(chart);
chart.update();
});
- legend.dispatch.on('legendClick', function(d,i) {
- d.disabled = !d.disabled;
-
- if (!data.filter(function(d) { return !d.disabled }).length) {
- data.map(function(d) {
- d.disabled = false;
- wrap.selectAll('.nv-series').classed('disabled', false);
- return d;
- });
- }
-
- state.disabled = data.map(function(d) { return !!d.disabled });
+ legend.dispatch.on('stateChange', function(newState) {
+ state.disabled = newState.disabled;
dispatch.stateChange(state);
-
- //selection.transition().call(chart);
chart.update();
});
- legend.dispatch.on('legendDblclick', function(d) {
- //Double clicking should always enable current series, and disabled all others.
- data.forEach(function(d) {
- d.disabled = true;
+ interactiveLayer.dispatch.on('elementMousemove', function(e) {
+ lines.clearHighlights();
+ var singlePoint, pointIndex, pointXLocation, allData = [];
+
+
+ data
+ .filter(function(series, i) {
+ series.seriesIndex = i;
+ return !series.disabled;
+ })
+ .forEach(function(series,i) {
+ pointIndex = nv.interactiveBisect(series.values, e.pointXValue, chart.x());
+ lines.highlightPoint(i, pointIndex, true);
+ var point = series.values[pointIndex];
+ if (typeof point === 'undefined') return;
+ if (typeof singlePoint === 'undefined') singlePoint = point;
+ if (typeof pointXLocation === 'undefined') pointXLocation = chart.xScale()(chart.x()(point,pointIndex));
+ allData.push({
+ key: series.key,
+ value: chart.y()(point, pointIndex),
+ color: color(series,series.seriesIndex)
+ });
});
- d.disabled = false;
- state.disabled = data.map(function(d) { return !!d.disabled });
- dispatch.stateChange(state);
- chart.update();
- });
+ //Highlight the tooltip entry based on which point the mouse is closest to.
+ if (allData.length > 2) {
+ var yValue = chart.yScale().invert(e.mouseY);
+ var domainExtent = Math.abs(chart.yScale().domain()[0] - chart.yScale().domain()[1]);
+ var threshold = 0.03 * domainExtent;
+ var indexToHighlight = nv.nearestValueIndex(allData.map(function(d){return d.value}),yValue,threshold);
+ if (indexToHighlight !== null)
+ allData[indexToHighlight].highlight = true;
+ }
+ var xValue = xAxis.tickFormat()(chart.x()(singlePoint,pointIndex), pointIndex);
+ interactiveLayer.tooltip
+ .position({left: pointXLocation + margin.left, top: e.mouseY + margin.top})
+ .chartContainer(that.parentNode)
+ .enabled(tooltips)
+ .valueFormatter(function(d,i) {
+ return yAxis.tickFormat()(d);
+ })
+ .data(
+ {
+ value: xValue,
+ series: allData
+ }
+ )();
+
+ interactiveLayer.renderGuideLine(pointXLocation);
-/*
- //
- legend.dispatch.on('legendMouseover', function(d, i) {
- d.hover = true;
- selection.transition().call(chart)
});
- legend.dispatch.on('legendMouseout', function(d, i) {
- d.hover = false;
- selection.transition().call(chart)
+ interactiveLayer.dispatch.on("elementMouseout",function(e) {
+ dispatch.tooltipHide();
+ lines.clearHighlights();
});
-*/
dispatch.on('tooltipShow', function(e) {
if (tooltips) showTooltip(e, that.parentNode);
@@ -2046,8 +3080,11 @@ nv.models.cumulativeLineChart = function() {
chart.legend = legend;
chart.xAxis = xAxis;
chart.yAxis = yAxis;
+ chart.interactiveLayer = interactiveLayer;
+
+ d3.rebind(chart, lines, 'defined', 'isArea', 'x', 'y', 'xScale','yScale', 'size', 'xDomain', 'yDomain', 'xRange', 'yRange', 'forceX', 'forceY', 'interactive', 'clipEdge', 'clipVoronoi','useVoronoi', 'id');
- d3.rebind(chart, lines, 'defined', 'isArea', 'x', 'y', 'size', 'xDomain', 'yDomain', 'forceX', 'forceY', 'interactive', 'clipEdge', 'clipVoronoi', 'id');
+ chart.options = nv.utils.optionsFunc.bind(chart);
chart.margin = function(_) {
if (!arguments.length) return margin;
@@ -2079,8 +3116,8 @@ nv.models.cumulativeLineChart = function() {
chart.rescaleY = function(_) {
if (!arguments.length) return rescaleY;
- rescaleY = _
- return rescaleY;
+ rescaleY = _;
+ return chart;
};
chart.showControls = function(_) {
@@ -2089,12 +3126,41 @@ nv.models.cumulativeLineChart = function() {
return chart;
};
+ chart.useInteractiveGuideline = function(_) {
+ if(!arguments.length) return useInteractiveGuideline;
+ useInteractiveGuideline = _;
+ if (_ === true) {
+ chart.interactive(false);
+ chart.useVoronoi(false);
+ }
+ return chart;
+ };
+
chart.showLegend = function(_) {
if (!arguments.length) return showLegend;
showLegend = _;
return chart;
};
+ chart.showXAxis = function(_) {
+ if (!arguments.length) return showXAxis;
+ showXAxis = _;
+ return chart;
+ };
+
+ chart.showYAxis = function(_) {
+ if (!arguments.length) return showYAxis;
+ showYAxis = _;
+ return chart;
+ };
+
+ chart.rightAlignYAxis = function(_) {
+ if(!arguments.length) return rightAlignYAxis;
+ rightAlignYAxis = _;
+ yAxis.orient( (_) ? 'right' : 'left');
+ return chart;
+ };
+
chart.tooltips = function(_) {
if (!arguments.length) return tooltips;
tooltips = _;
@@ -2131,6 +3197,18 @@ nv.models.cumulativeLineChart = function() {
return chart;
};
+ chart.transitionDuration = function(_) {
+ if (!arguments.length) return transitionDuration;
+ transitionDuration = _;
+ return chart;
+ };
+
+ chart.noErrorCheck = function(_) {
+ if (!arguments.length) return noErrorCheck;
+ noErrorCheck = _;
+ return chart;
+ };
+
//============================================================
@@ -2144,11 +3222,16 @@ nv.models.cumulativeLineChart = function() {
if (!line.values) {
return line;
}
- var v = lines.y()(line.values[idx], idx);
+ var indexValue = line.values[idx];
+ if (indexValue == null) {
+ return line;
+ }
+ var v = lines.y()(indexValue, idx);
//TODO: implement check below, and disable series if series loses 100% or more cause divide by 0 issue
- if (v < -.95) {
+ if (v < -.95 && !noErrorCheck) {
//if a series loses more than 100%, calculations fail.. anything close can cause major distortion (but is mathematically correct till it hits 100)
+
line.tempDisabled = true;
return line;
}
@@ -2171,7 +3254,7 @@ nv.models.cumulativeLineChart = function() {
}
//TODO: consider deprecating by adding necessary features to multiBar model
nv.models.discreteBar = function() {
-
+ "use strict";
//============================================================
// Public Variables with Default Settings
//------------------------------------------------------------
@@ -2190,6 +3273,8 @@ nv.models.discreteBar = function() {
, valueFormat = d3.format(',.2f')
, xDomain
, yDomain
+ , xRange
+ , yRange
, dispatch = d3.dispatch('chartClick', 'elementClick', 'elementDblClick', 'elementMouseover', 'elementMouseout')
, rectClass = 'discreteBar'
;
@@ -2214,12 +3299,10 @@ nv.models.discreteBar = function() {
//add series index to each data point for reference
- data = data.map(function(series, i) {
- series.values = series.values.map(function(point) {
+ data.forEach(function(series, i) {
+ series.values.forEach(function(point) {
point.series = i;
- return point;
});
- return series;
});
@@ -2235,14 +3318,14 @@ nv.models.discreteBar = function() {
});
x .domain(xDomain || d3.merge(seriesData).map(function(d) { return d.x }))
- .rangeBands([0, availableWidth], .1);
+ .rangeBands(xRange || [0, availableWidth], .1);
y .domain(yDomain || d3.extent(d3.merge(seriesData).map(function(d) { return d.y }).concat(forceY)));
// If showValues, pad the Y axis range to account for label height
- if (showValues) y.range([availableHeight - (y.domain()[0] < 0 ? 12 : 0), y.domain()[1] > 0 ? 12 : 0]);
- else y.range([availableHeight, 0]);
+ if (showValues) y.range(yRange || [availableHeight - (y.domain()[0] < 0 ? 12 : 0), y.domain()[1] > 0 ? 12 : 0]);
+ else y.range(yRange || [availableHeight, 0]);
//store old scales if they exist
x0 = x0 || x;
@@ -2273,14 +3356,16 @@ nv.models.discreteBar = function() {
groups.enter().append('g')
.style('stroke-opacity', 1e-6)
.style('fill-opacity', 1e-6);
- d3.transition(groups.exit())
+ groups.exit()
+ .transition()
.style('stroke-opacity', 1e-6)
.style('fill-opacity', 1e-6)
.remove();
groups
.attr('class', function(d,i) { return 'nv-group nv-series-' + i })
.classed('hover', function(d) { return d.hover });
- d3.transition(groups)
+ groups
+ .transition()
.style('stroke-opacity', 1)
.style('fill-opacity', .75);
@@ -2293,7 +3378,7 @@ nv.models.discreteBar = function() {
var barsEnter = bars.enter().append('g')
.attr('transform', function(d,i,j) {
- return 'translate(' + (x(getX(d,i)) + x.rangeBand() * .05 ) + ', ' + y(0) + ')'
+ return 'translate(' + (x(getX(d,i)) + x.rangeBand() * .05 ) + ', ' + y(0) + ')'
})
.on('mouseover', function(d,i) { //TODO: figure out why j works above, but not here
d3.select(this).classed('hover', true);
@@ -2350,10 +3435,15 @@ nv.models.discreteBar = function() {
if (showValues) {
barsEnter.append('text')
.attr('text-anchor', 'middle')
+ ;
+
bars.select('text')
+ .text(function(d,i) { return valueFormat(getY(d,i)) })
+ .transition()
.attr('x', x.rangeBand() * .9 / 2)
.attr('y', function(d,i) { return getY(d,i) < 0 ? y(getY(d,i)) - y(0) + 12 : -4 })
- .text(function(d,i) { return
<TRUNCATED>
[31/41] couchdb commit: updated refs/heads/Update-Sidebar-Ui to
c1e1423
Posted by de...@apache.org.
s/teh/the in json-structure
Project: http://git-wip-us.apache.org/repos/asf/couchdb/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb/commit/e3d5d12f
Tree: http://git-wip-us.apache.org/repos/asf/couchdb/tree/e3d5d12f
Diff: http://git-wip-us.apache.org/repos/asf/couchdb/diff/e3d5d12f
Branch: refs/heads/Update-Sidebar-Ui
Commit: e3d5d12fe9c5c55de549591bf72241c8228018d5
Parents: 597b8d1
Author: BigBlueHat <by...@bigbluehat.com>
Authored: Wed Mar 26 09:46:00 2014 -0400
Committer: BigBlueHat <by...@bigbluehat.com>
Committed: Wed Mar 26 09:46:00 2014 -0400
----------------------------------------------------------------------
share/doc/src/json-structure.rst | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/couchdb/blob/e3d5d12f/share/doc/src/json-structure.rst
----------------------------------------------------------------------
diff --git a/share/doc/src/json-structure.rst b/share/doc/src/json-structure.rst
index 68137d2..addc5ac 100644
--- a/share/doc/src/json-structure.rst
+++ b/share/doc/src/json-structure.rst
@@ -357,7 +357,7 @@ Request object
+--------------------------------+---------------------------------------------+
| query | URL query parameters `object`. |
| | Note that multiple keys are not supported |
-| | and teh last key value suppresses others. |
+| | and the last key value suppresses others. |
+--------------------------------+---------------------------------------------+
| requested_path | List of actual requested path section. |
+--------------------------------+---------------------------------------------+
[34/41] couchdb commit: updated refs/heads/Update-Sidebar-Ui to
c1e1423
Posted by de...@apache.org.
Fix Fauxton dependancie issues
I've modified nv.d3 to be an amd module. This isn't pretty but it's the
best fix, otherwise we cannot use this library.
I've also added a new config in settings.json.default for couchapp
deployment as the current release config doesn't work with a couchapp
Project: http://git-wip-us.apache.org/repos/asf/couchdb/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb/commit/27cc89cb
Tree: http://git-wip-us.apache.org/repos/asf/couchdb/tree/27cc89cb
Diff: http://git-wip-us.apache.org/repos/asf/couchdb/diff/27cc89cb
Branch: refs/heads/Update-Sidebar-Ui
Commit: 27cc89cb7c306f72c2746b5ea3736bd94f17cebf
Parents: c84a71c
Author: Garren Smith <ga...@gmail.com>
Authored: Thu Mar 27 11:04:49 2014 +0200
Committer: Garren Smith <ga...@gmail.com>
Committed: Thu Mar 27 11:12:15 2014 +0200
----------------------------------------------------------------------
src/Makefile.am | 1 -
src/fauxton/Gruntfile.js | 8 ++------
src/fauxton/app/config.js | 5 +----
src/fauxton/assets/js/libs/d3.global.js | 18 ------------------
src/fauxton/assets/js/libs/nv.d3.js | 7 ++++++-
src/fauxton/settings.json.default | 16 ++++++++++++++++
6 files changed, 25 insertions(+), 30 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/couchdb/blob/27cc89cb/src/Makefile.am
----------------------------------------------------------------------
diff --git a/src/Makefile.am b/src/Makefile.am
index ccf6ccd..e1007f9 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -251,7 +251,6 @@ FAUXTON_FILES = \
fauxton/assets/js/libs/backbone.js \
fauxton/assets/js/libs/bootstrap.js \
fauxton/assets/js/libs/d3.js \
- fauxton/assets/js/libs/d3.global.js \
fauxton/assets/js/libs/jquery.js \
fauxton/assets/js/libs/lodash.js \
fauxton/assets/js/libs/nv.d3.js \
http://git-wip-us.apache.org/repos/asf/couchdb/blob/27cc89cb/src/fauxton/Gruntfile.js
----------------------------------------------------------------------
diff --git a/src/fauxton/Gruntfile.js b/src/fauxton/Gruntfile.js
index 49c082e..29111eb 100644
--- a/src/fauxton/Gruntfile.js
+++ b/src/fauxton/Gruntfile.js
@@ -349,11 +349,6 @@ module.exports = function(grunt) {
}
},
gen_initialize: templateSettings,
- /*gen_initialize: {
- "default": {
- src: "settings.json"
- }
- },*/
mkcouchdb: couch_config,
rmcouchdb: couch_config,
@@ -448,6 +443,7 @@ module.exports = function(grunt) {
grunt.registerTask('watchRun', ['clean:watch', 'dependencies', 'jshint']);
// build a release
grunt.registerTask('release', ['clean' ,'dependencies', "gen_initialize:release", 'jshint', 'build', 'minify', 'copy:dist', 'copy:ace']);
+ grunt.registerTask('couchapp_release', ['clean' ,'dependencies', "gen_initialize:couchapp", 'jshint', 'build', 'minify', 'copy:dist', 'copy:ace']);
/*
* Install into CouchDB in either debug, release, or couchapp mode
@@ -457,7 +453,7 @@ module.exports = function(grunt) {
// make a minimized install that is server by mochiweb under _utils
grunt.registerTask('couchdb', ['release', 'copy:couchdb']);
// make an install that can be deployed as a couchapp
- grunt.registerTask('couchapp_setup', ['release']);
+ grunt.registerTask('couchapp_setup', ['couchapp_release']);
// install fauxton as couchapp
grunt.registerTask('couchapp_install', ['rmcouchdb:fauxton', 'mkcouchdb:fauxton', 'couchapp:fauxton']);
// setup and install fauxton as couchapp
http://git-wip-us.apache.org/repos/asf/couchdb/blob/27cc89cb/src/fauxton/app/config.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/config.js b/src/fauxton/app/config.js
index 3ed1c31..4a2f136 100644
--- a/src/fauxton/app/config.js
+++ b/src/fauxton/app/config.js
@@ -30,8 +30,7 @@ require.config({
spin: "../assets/js/libs/spin.min",
d3: "../assets/js/libs/d3",
"nv.d3": "../assets/js/libs/nv.d3",
- "ace":"../assets/js/libs/ace",
- "d3.global": "../assets/js/libs/d3.global"
+ "ace":"../assets/js/libs/ace"
},
baseUrl: '/',
@@ -55,8 +54,6 @@ require.config({
exports: "Bootstrap"
},
- "nv.d3": ["d3.global"],
-
"plugins/prettify": [],
"plugins/beautify": [],
http://git-wip-us.apache.org/repos/asf/couchdb/blob/27cc89cb/src/fauxton/assets/js/libs/d3.global.js
----------------------------------------------------------------------
diff --git a/src/fauxton/assets/js/libs/d3.global.js b/src/fauxton/assets/js/libs/d3.global.js
deleted file mode 100644
index 9f38d04..0000000
--- a/src/fauxton/assets/js/libs/d3.global.js
+++ /dev/null
@@ -1,18 +0,0 @@
-// Licensed under the Apache License, Version 2.0 (the "License"); you may not
-// use this file except in compliance with the License. You may obtain a copy of
-// the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations under
-// the License.
-
-// Set the require.js configuration for your application.
-
-define("d3.global", ["d3"], function(_) {
- //get that global back
- d3 = _;
-});
http://git-wip-us.apache.org/repos/asf/couchdb/blob/27cc89cb/src/fauxton/assets/js/libs/nv.d3.js
----------------------------------------------------------------------
diff --git a/src/fauxton/assets/js/libs/nv.d3.js b/src/fauxton/assets/js/libs/nv.d3.js
index 4ddf400..409dc65 100755
--- a/src/fauxton/assets/js/libs/nv.d3.js
+++ b/src/fauxton/assets/js/libs/nv.d3.js
@@ -1,3 +1,5 @@
+//this is a hacky fix because nv.d3 doesn't support requirejs
+define("nvd3", ["d3"], function (d3) {
(function(){
var nv = window.nv || {};
@@ -14366,4 +14368,7 @@ nv.models.stackedAreaChart = function() {
return chart;
}
-})();
\ No newline at end of file
+})();
+
+return window.nv;
+});
http://git-wip-us.apache.org/repos/asf/couchdb/blob/27cc89cb/src/fauxton/settings.json.default
----------------------------------------------------------------------
diff --git a/src/fauxton/settings.json.default b/src/fauxton/settings.json.default
index 1bc88f6..eedf2f1 100644
--- a/src/fauxton/settings.json.default
+++ b/src/fauxton/settings.json.default
@@ -46,7 +46,23 @@
"host": "../..",
"version": "1.0"
}
+ },
+ "couchapp": {
+ "src": "assets/index.underscore",
+ "dest": "dist/debug/index.html",
+ "variables": {
+ "requirejs": "./js/require.js",
+ "css": "./css/index.css",
+ "base": null,
+ "cachebuster": "?v1.0"
+ },
+ "app": {
+ "root": "/",
+ "host": "../../..",
+ "version": "1.0"
+ }
}
+
},
"couch_config": {
[41/41] couchdb commit: updated refs/heads/Update-Sidebar-Ui to
c1e1423
Posted by de...@apache.org.
remove filter by in active tasks
Fix Active Tasks sidebar
dom cleanup
sidebar ui
Make Sidebar show all design doc functions
Project: http://git-wip-us.apache.org/repos/asf/couchdb/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb/commit/c1e14237
Tree: http://git-wip-us.apache.org/repos/asf/couchdb/tree/c1e14237
Diff: http://git-wip-us.apache.org/repos/asf/couchdb/diff/c1e14237
Branch: refs/heads/Update-Sidebar-Ui
Commit: c1e142377265d35db484fa342538322c7cd1bee6
Parents: ce352c8
Author: suelockwood <de...@apache.org>
Authored: Mon Mar 31 14:56:07 2014 -0400
Committer: suelockwood <de...@apache.org>
Committed: Mon Mar 31 15:45:38 2014 -0400
----------------------------------------------------------------------
.../app/addons/activetasks/templates/tabs.html | 11 +-
src/fauxton/app/addons/activetasks/views.js | 2 +
.../addons/documents/assets/less/documents.less | 47 +++++-
src/fauxton/app/addons/documents/routes.js | 56 +++++--
.../templates/add_new_ddoc_fn_dropdown.html | 28 ++++
.../documents/templates/attachments_footer.html | 20 +++
.../documents/templates/design_doc_menu.html | 24 +++
.../templates/design_doc_selector.html | 3 +
.../documents/templates/index_menu_item.html | 4 +-
.../app/addons/documents/templates/sidebar.html | 41 ++---
src/fauxton/app/addons/documents/views.js | 151 +++++++++++++-----
src/fauxton/app/templates/layouts/two_pane.html | 1 -
.../assets/less/bootstrap/dropdowns.less | 33 +++-
src/fauxton/assets/less/bootstrap/navs.less | 3 -
.../assets/less/bootstrap/variables.less | 8 +-
src/fauxton/assets/less/fauxton.less | 157 ++++++++++---------
src/fauxton/assets/less/variables.less | 1 +
17 files changed, 407 insertions(+), 183 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/couchdb/blob/c1e14237/src/fauxton/app/addons/activetasks/templates/tabs.html
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/activetasks/templates/tabs.html b/src/fauxton/app/addons/activetasks/templates/tabs.html
index 5869748..624c386 100644
--- a/src/fauxton/app/addons/activetasks/templates/tabs.html
+++ b/src/fauxton/app/addons/activetasks/templates/tabs.html
@@ -14,14 +14,6 @@ the License.
-
-
-<div id="sidenav">
- <header class="row-fluid">
- <h3>Filter by: </h3>
- </header>
-
- <nav>
<ul class="task-tabs nav nav-list">
<% for (var filter in filters) { %>
<li data-type="<%=filter%>">
@@ -42,5 +34,4 @@ the License.
<label for="pollingRange"><span>5</span> second(s)</label>
</li>
</ul>
- </nav>
-</div>
+
http://git-wip-us.apache.org/repos/asf/couchdb/blob/c1e14237/src/fauxton/app/addons/activetasks/views.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/activetasks/views.js b/src/fauxton/app/addons/activetasks/views.js
index b0940bf..453069f 100644
--- a/src/fauxton/app/addons/activetasks/views.js
+++ b/src/fauxton/app/addons/activetasks/views.js
@@ -29,6 +29,8 @@ function (app, FauxtonAPI, activetasks) {
Views.Events = _.extend(Events, Backbone.Events);
Views.TabMenu = FauxtonAPI.View.extend({
+ tagName: "nav",
+ className: "sidenav",
template: "addons/activetasks/templates/tabs",
events: {
"click .task-tabs li": "requestByType",
http://git-wip-us.apache.org/repos/asf/couchdb/blob/c1e14237/src/fauxton/app/addons/documents/assets/less/documents.less
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/documents/assets/less/documents.less b/src/fauxton/app/addons/documents/assets/less/documents.less
index 36429ff..f00b674 100644
--- a/src/fauxton/app/addons/documents/assets/less/documents.less
+++ b/src/fauxton/app/addons/documents/assets/less/documents.less
@@ -35,7 +35,7 @@ button.beautify {
#select-per-page {
margin-top: 10px;
}
-
+
}
@@ -112,4 +112,49 @@ button.beautify {
}
+.sidenav{
+ margin-bottom: 40px;
+ li.nav-header {
+ position: relative;
+ .accordion-body{
+ color: #eee;
+ margin-left: 0;
+ li a{
+ padding-left: 55px;
+ }
+ }
+ > span{
+ display: block;
+ padding: 10px 13px 10px 30px;
+ color: #333333;
+ border-bottom: 1px solid #989898;
+ &:before{
+ font-size: 12px;
+ padding-right: 10px;
+ }
+ &.down:before {
+ transform:rotate(90deg);
+ -ms-transform:rotate(90deg); /* IE 9 */
+ -webkit-transform:rotate(90deg); /* Opera, Chrome, and Safari */
+ }
+ }
+ div.new-button {
+ position: absolute;
+ top: 2px;
+ right: 15px;
+ .dropdown-menu{
+ left: -57px;
+ padding-bottom: 0;
+ }
+ .dropdown-toggle{
+ text-decoration: none;
+ }
+ > a {
+ border-bottom: none;
+ text-decoration: none;
+ font-size: 16px;
+ }
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/couchdb/blob/c1e14237/src/fauxton/app/addons/documents/routes.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/documents/routes.js b/src/fauxton/app/addons/documents/routes.js
index 699a496..90cf8b2 100644
--- a/src/fauxton/app/addons/documents/routes.js
+++ b/src/fauxton/app/addons/documents/routes.js
@@ -90,7 +90,7 @@ function(app, FauxtonAPI, Documents, Databases) {
database = this.database;
doc.copy(newId).then(function () {
- doc.set({_id: newId});
+ doc.set({_id: newId});
docView.forceRender();
FauxtonAPI.navigate('/database/' + database.safeID() + '/' + app.utils.safeURLName(newId), {trigger: true});
FauxtonAPI.addNotification({
@@ -143,12 +143,25 @@ function(app, FauxtonAPI, Documents, Databases) {
layout: "with_tabs_sidebar",
selectedHeader: "Databases",
routes: {
- "database/:database/_all_docs(:extra)": "allDocs",
- "database/:database/_design/:ddoc/_view/:view": {
+ "database/:database/_all_docs(:extra)": "allDocs",
+ "database/:database/_design/:ddoc/_views/:view": {
route: "viewFn",
roles: ['_admin']
},
- "database/:database/new_view": "newViewEditor"
+ "database/:database/_design/:ddoc/_lists/:fn": {
+ route: "tempFn",
+ roles: ['_admin']
+ },
+ "database/:database/_design/:ddoc/_filters/:fn": {
+ route: "tempFn",
+ roles: ['_admin']
+ },
+ "database/:database/_design/:ddoc/_show/:fn": {
+ route: "tempFn",
+ roles: ['_admin']
+ },
+ "database/:database/new_view": "newViewEditor",
+ "database/:database/new_view/:designDoc": "newViewEditor"
},
events: {
@@ -181,6 +194,16 @@ function(app, FauxtonAPI, Documents, Databases) {
}));
},
+ tempFn: function(databaseName, ddoc, fn){
+ this.setView("#dashboard-upper-content", new Documents.Views.temp({}));
+ this.crumbs = function () {
+ return [
+ {"name": this.data.database.id, "link": Databases.databaseUrl(this.data.database)},
+ ];
+ };
+
+ },
+
establish: function () {
return this.data.designDocs.fetch();
},
@@ -194,7 +217,7 @@ function(app, FauxtonAPI, Documents, Databases) {
},
/*
- * docParams are the options collection uses to fetch from the server
+ * docParams are the options collection uses to fetch from the server
* urlParams are what are shown in the url and to the user
* They are not the same when paginating
*/
@@ -259,7 +282,7 @@ function(app, FauxtonAPI, Documents, Databases) {
view: view,
params: docParams
});
-
+
this.viewEditor = this.setView("#dashboard-upper-content", new Documents.Views.ViewEditor({
model: this.data.database,
ddocs: this.data.designDocs,
@@ -274,7 +297,7 @@ function(app, FauxtonAPI, Documents, Databases) {
this.documentsView = this.createViewDocumentsView({
designDoc: decodeDdoc,
- docParams: docParams,
+ docParams: docParams,
urlParams: urlParams,
database: this.data.database,
indexedDocs: this.data.indexedDocs,
@@ -302,7 +325,7 @@ function(app, FauxtonAPI, Documents, Databases) {
};
},
- createViewDocumentsView: function (options) {
+ createViewDocumentsView: function (options) {
return this.setView("#dashboard-lower-content", new Documents.Views.AllDocsList({
database: options.database,
@@ -315,13 +338,14 @@ function(app, FauxtonAPI, Documents, Databases) {
}));
},
- newViewEditor: function () {
+ newViewEditor: function (database, designDoc) {
var params = app.getParams();
this.toolsView && this.toolsView.remove();
this.documentsView && this.documentsView.remove();
this.viewEditor = this.setView("#dashboard-upper-content", new Documents.Views.ViewEditor({
+ currentddoc: "_design/"+designDoc || "",
ddocs: this.data.designDocs,
params: params,
database: this.data.database,
@@ -365,7 +389,7 @@ function(app, FauxtonAPI, Documents, Databases) {
if (!this.documentsView) {
this.documentsView = this.createViewDocumentsView({
designDoc: ddoc,
- docParams: docParams,
+ docParams: docParams,
urlParams: urlParams,
database: this.data.database,
indexedDocs: this.indexedDocs,
@@ -427,14 +451,14 @@ function(app, FauxtonAPI, Documents, Databases) {
urlParams = Documents.QueryParams.parse(urlParams);
if (options.direction === 'next') {
- params = Documents.paginate.next(collection.toJSON(),
+ params = Documents.paginate.next(collection.toJSON(),
collection.params,
- options.perPage,
+ options.perPage,
!!collection.isAllDocs);
} else {
- params = Documents.paginate.previous(collection.toJSON(),
- collection.params,
- options.perPage,
+ params = Documents.paginate.previous(collection.toJSON(),
+ collection.params,
+ options.perPage,
!!collection.isAllDocs);
}
@@ -473,7 +497,7 @@ function(app, FauxtonAPI, Documents, Databases) {
} else {
storedPerPage = parseInt(storedPerPage, 10);
}
- }
+ }
if (!urlParams.limit || urlParams.limit > storedPerPage) {
return storedPerPage;
http://git-wip-us.apache.org/repos/asf/couchdb/blob/c1e14237/src/fauxton/app/addons/documents/templates/add_new_ddoc_fn_dropdown.html
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/documents/templates/add_new_ddoc_fn_dropdown.html b/src/fauxton/app/addons/documents/templates/add_new_ddoc_fn_dropdown.html
new file mode 100644
index 0000000..daf3864
--- /dev/null
+++ b/src/fauxton/app/addons/documents/templates/add_new_ddoc_fn_dropdown.html
@@ -0,0 +1,28 @@
+<!--
+Licensed under the Apache License, Version 2.0 (the "License"); you may not
+use this file except in compliance with the License. You may obtain a copy of
+the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+License for the specific language governing permissions and limitations under
+the License.
+-->
+
+<div class="dropdown">
+ <a class="dropdown-toggle icon fonticon-circle-plus" data-toggle="dropdown" href="#" data-bypass="true"></a>
+ <ul class="dropdown-menu arrow" role="menu" aria-labelledby="dLabel">
+ <% if (full){ %>
+ <li><a class="icon fonticon-replication" href="#replicate/<%=database.id%>">Replicate</a><li>
+ <li><a class="icon fonticon-trash" href="#" data-bypass="true">Delete</a><li>
+ <%}%>
+ <li class="header-label">Add new</li>
+ <li><a class="icon fonticon-circle-plus" href="#<%= database.url('app') %>/new_view/<%=ddocSafe%>">Secondary View</a><li>
+ <li><a class="icon fonticon-circle-plus" href="#<%= database.url('app') %>/new_filter/<%=ddocSafe%>">Filter Function</a><li>
+ <li><a class="icon fonticon-circle-plus" href="#<%= database.url('app') %>/new_show/<%=ddocSafe%>">Show Function</a><li>
+ <li><a class="icon fonticon-circle-plus" href="#<%= database.url('app') %>/new_list/<%=ddocSafe%>">List function</a><li>
+ </ul>
+</div>
http://git-wip-us.apache.org/repos/asf/couchdb/blob/c1e14237/src/fauxton/app/addons/documents/templates/attachments_footer.html
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/documents/templates/attachments_footer.html b/src/fauxton/app/addons/documents/templates/attachments_footer.html
new file mode 100644
index 0000000..31bd5a5
--- /dev/null
+++ b/src/fauxton/app/addons/documents/templates/attachments_footer.html
@@ -0,0 +1,20 @@
+<!--
+Licensed under the Apache License, Version 2.0 (the "License"); you may not
+use this file except in compliance with the License. You may obtain a copy of
+the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+License for the specific language governing permissions and limitations under
+the License.
+-->
+
+<ul>
+ <li> attachment 1</li>
+ <li> attachment 2 </li>
+ <li> attachment 3</li>
+ <li> attachment 4</li>
+</ul>
http://git-wip-us.apache.org/repos/asf/couchdb/blob/c1e14237/src/fauxton/app/addons/documents/templates/design_doc_menu.html
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/documents/templates/design_doc_menu.html b/src/fauxton/app/addons/documents/templates/design_doc_menu.html
new file mode 100644
index 0000000..ee45ed6
--- /dev/null
+++ b/src/fauxton/app/addons/documents/templates/design_doc_menu.html
@@ -0,0 +1,24 @@
+<!--
+Licensed under the Apache License, Version 2.0 (the "License"); you may not
+use this file except in compliance with the License. You may obtain a copy of
+the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+License for the specific language governing permissions and limitations under
+the License.
+-->
+<li class="nav-header">
+ <span class="fonticon-play js-collapse-toggle" data-toggle="collapse" data-target="#<%=designDoc%>">
+ <%= designDoc%>
+ </span>
+ <div class="new-button">
+
+ </div>
+
+ <ul class="accordion-body collapse" id="<%=designDoc%>">
+ </ul>
+</li>
http://git-wip-us.apache.org/repos/asf/couchdb/blob/c1e14237/src/fauxton/app/addons/documents/templates/design_doc_selector.html
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/documents/templates/design_doc_selector.html b/src/fauxton/app/addons/documents/templates/design_doc_selector.html
index 7bbe310..0a5bee2 100644
--- a/src/fauxton/app/addons/documents/templates/design_doc_selector.html
+++ b/src/fauxton/app/addons/documents/templates/design_doc_selector.html
@@ -16,7 +16,10 @@ the License.
<select id="ddoc">
<optgroup label="Select a document">
<option value="new-doc">New document</option>
+
<% ddocs.each(function(ddoc) { %>
+ <%= ddoc.id %>
+ <%= ddocName %>
<% if (ddoc.id === ddocName) { %>
<option selected="selected" value="<%= ddoc.id %>"><%= ddoc.id %></option>
<% } else { %>
http://git-wip-us.apache.org/repos/asf/couchdb/blob/c1e14237/src/fauxton/app/addons/documents/templates/index_menu_item.html
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/documents/templates/index_menu_item.html b/src/fauxton/app/addons/documents/templates/index_menu_item.html
index 7ca9012..77b51d0 100644
--- a/src/fauxton/app/addons/documents/templates/index_menu_item.html
+++ b/src/fauxton/app/addons/documents/templates/index_menu_item.html
@@ -12,6 +12,6 @@ License for the specific language governing permissions and limitations under
the License.
-->
-<a id="<%= ddoc_clean %>_<%= index_clean %>" href="#database/<%= database_encoded %>/_design/<%= ddoc_encoded %>/_view/<%= index_encoded %>" class="toggle-view">
- <%= ddoc %><span class="divider">/</span><%= index %>
+<a id="<%= ddoc_clean %>_<%= index_clean %>" href="#database/<%= database_encoded %>/_design/<%= ddoc_encoded %>/_<%=type%>/<%= index_encoded %>" class="toggle-view">
+ <%= index %>
</a>
http://git-wip-us.apache.org/repos/asf/couchdb/blob/c1e14237/src/fauxton/app/addons/documents/templates/sidebar.html
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/documents/templates/sidebar.html b/src/fauxton/app/addons/documents/templates/sidebar.html
index 750cd30..59d76e1 100644
--- a/src/fauxton/app/addons/documents/templates/sidebar.html
+++ b/src/fauxton/app/addons/documents/templates/sidebar.html
@@ -11,34 +11,17 @@ WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
License for the specific language governing permissions and limitations under
the License.
-->
-
-<div id="sidenav">
- <header class="row-fluid">
+<!-- <header class="row-fluid">
<div class="span12">
- <div class="btn-group">
- <button class="btn dropdown-toggle dropdown-toggle-btn" data-toggle="dropdown">
- Docs
- <span class="caret"></span>
- </button>
- <ul class="dropdown-menu">
- <!-- dropdown menu links -->
- <li><a href="<%= db_url %>"><i class="icon icon-file"></i> Docs</a></li>
- <li><a href="<%= permissions_url %>"><i class="icon icon-lock"></i> Permissions</a></li>
- <li><a href="<%= changes_url %>"><i class="icon icon-forward"></i> Changes</a></li>
- <% _.each(docLinks, function (link) { %>
- <li><a href="<%= database_url + '/' + link.url %>"><i class="icon <%= link.icon %>"></i> <%= link.title %></a></li>
- <% }); %>
- </ul>
- </div>
<div class="btn-group">
<button class="btn dropdown-toggle dropdown-toggle-btn" data-toggle="dropdown">
- New
+ Create New
<span class="caret"></span>
</button>
<ul class="dropdown-menu">
<!-- dropdown menu links -->
- <li>
+<!-- <li>
<a id="doc" href="#<%= database.url('app') %>/new">Document</a>
</li>
<li>
@@ -51,18 +34,18 @@ the License.
</div>
<button id="delete-database" class="btn pull-right"><i class="icon-trash"></i> Database</button>
</div>
- </header>
+ </header> -->
+
- <nav>
<ul class="nav nav-list">
+ <li><a id="changes" href="<%= permissions_url %>">Permissions</a><li>
+ <li><a id="changes" href="<%= changes_url %>">Changes</a><li>
+ <% _.each(docLinks, function (link) { %>
+ <li><a href="<%= database_url + '/' + link.url %>"><%= link.title %></a></li>
+ <% }); %>
+
<li class="active"><a id="all-docs" href="#<%= database.url('index') %>" class="toggle-view"> All documents</a></li>
<li><a id="design-docs" href='#<%= database.url("index") %>?startkey="_design"&endkey="_e"' class="toggle-view"> All design docs</a></li>
</ul>
- <ul class="nav nav-list views">
- <li class="nav-header">Secondary Indexes</li>
- <li><a id="new-view" href="#<%= database.url('app') %>/new_view" class="new"><i class="icon-plus"></i> New</a></li>
- </ul>
- <div id="extension-navs"></div>
- </nav>
+
<div id="delete-db-modal"> </div>
-</div>
http://git-wip-us.apache.org/repos/asf/couchdb/blob/c1e14237/src/fauxton/app/addons/documents/views.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/documents/views.js b/src/fauxton/app/addons/documents/views.js
index cc23e19..6153e40 100644
--- a/src/fauxton/app/addons/documents/views.js
+++ b/src/fauxton/app/addons/documents/views.js
@@ -387,10 +387,12 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
this.ddoc = options.ddoc;
this.database = options.database;
this.selected = !! options.selected;
+ this.selector = options.selector;
},
serialize: function() {
return {
+ type: this.selector,
index: this.index,
ddoc: this.ddoc,
database: this.database,
@@ -405,7 +407,7 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
afterRender: function() {
if (this.selected) {
- $("#sidenav ul.nav-list li").removeClass("active");
+ $(".sidenav ul.nav-list li").removeClass("active");
this.$el.addClass("active");
}
}
@@ -418,7 +420,7 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
this.newView = options.newView || false;
this.pagination = options.pagination;
_.bindAll(this);
-
+
this._perPage = options.perPageDefault || 20;
this.listenTo(this.collection, 'totalRows:decrement', this.render);
},
@@ -1098,7 +1100,7 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
//highlight current
this.$(".toggle-btns > label").removeClass('active');
this.$(e.currentTarget).addClass("active");
-
+
this.$("[id^='js-show']").hide();
//show section & disable what needs to be disabled
@@ -1148,7 +1150,7 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
if (_.isUndefined(parsedValue)) {
errorMsg = "Keys must be valid json.";
} else if (!_.isArray(parsedValue)) {
- errorMsg = "Keys values must be in an array. E.g [1,2,3]";
+ errorMsg = "Keys values must be in an array. E.g [1,2,3]";
}
if (errorMsg) {
@@ -1162,7 +1164,7 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
return false;
}
- return true;
+ return true;
},
queryParams: function () {
var $form = this.$(".js-view-query-update"),
@@ -1251,8 +1253,8 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
}
this.updateFiltersFor(key, $ele);
break;
- case "key":
- case "keys":
+ case "key":
+ case "keys":
$form.find("textarea[name='"+key+"']").val(val);
break;
default:
@@ -1373,6 +1375,7 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
this.ddocs = options.ddocs;
this.params = options.params;
this.database = options.database;
+ this.currentDdoc = options.currentddoc;
if (this.newView) {
this.viewName = 'newView';
} else {
@@ -1653,7 +1656,7 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
toggleIndexNav: function (event) {
$('#dashboard-content').scrollTop(0); //scroll up
-
+
var $targetId = this.$(event.target).attr('id'),
$previousTab = this.$(this.$('li.active a').attr('href')),
$targetTab = this.$(this.$(event.target).attr('href'));
@@ -1662,7 +1665,7 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
$previousTab.removeAttr('style');
}
//stop polling
- this.ddocInfoView.stopRefreshInterval();
+ this.ddocInfoView.stopRefreshInterval();
if ($targetId === 'index-nav') {
if (this.newView) { return; }
@@ -1674,8 +1677,8 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
} else if ($targetId === "meta-nav"){
if (!$("#ddoc-info").is(":visible")){
this.ddocInfoView.startRefreshInterval();
- }
- $targetTab.toggle('slow');
+ }
+ $targetTab.toggle('slow');
} else {
$targetTab.toggle('slow');
}
@@ -1722,7 +1725,7 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
renderDdocInfo: function(){
if(this.ddocInfoView){
this.ddocInfoView.remove();
- }
+ }
if (this.newView) { return; }
this.ddocInfoView = this.setView('#ddoc-info', new Views.DdocInfo({model: this.ddocInfo }));
@@ -1743,12 +1746,12 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
var ddocDecode = decodeURIComponent(this.ddocID);
this.model = this.ddocs.get(ddocDecode).dDocModel();
this.reduceFunStr = this.model.viewHasReduce(this.viewName);
-
+
}
this.designDocSelector = this.setView('.design-doc-group', new Views.DesignDocSelector({
collection: this.ddocs,
- ddocName: this.model.id,
+ ddocName: this.currentDdoc || this.model.id,
database: this.database
}));
@@ -1852,6 +1855,8 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
Views.Sidebar = FauxtonAPI.View.extend({
template: "addons/documents/templates/sidebar",
+ className: "sidenav",
+ tagName: "nav",
events: {
"click button#delete-database": "showDeleteDatabaseModal"
},
@@ -1885,17 +1890,6 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
};
},
- buildIndexList: function(collection, selector, design){
- _.each(_.keys(collection), function(key){
- var selected = this.ddocID == "_design/"+design;
- this.insertView("ul.nav." + selector, new Views.IndexItem({
- ddoc: design,
- index: key,
- database: this.collection.database.id,
- selected: selected && key == this.currView
- }));
- }, this);
- },
beforeRender: function(manage) {
this.deleteDBModal = this.setView(
@@ -1903,21 +1897,14 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
new Views.DeleteDBModal({database: this.database})
);
- var sidebarListViews = FauxtonAPI.getExtensions('sidebar:list');
- _.each(sidebarListViews, function (view) {
- var extension = this.insertView('#extension-navs', view);
- extension.update(this.database, this.collection, this.viewName);
- extension.render();
- }, this);
-
this.collection.each(function(design) {
if (design.has('doc')){
- var ddoc = design.id.replace(/^_design\//,"");
- if (design.get('doc').views){
- this.buildIndexList(design.get('doc').views, "views", ddoc);
- }
+ this.insertView(new Views.DdocSidenav({
+ model: design,
+ collection: this.collection
+ }));
}
- }, this);
+ },this);
},
@@ -1934,6 +1921,72 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
}
});
+
+ Views.DdocSidenav = FauxtonAPI.View.extend({
+ tagName: "ul",
+ className: "nav nav-list",
+ template: "addons/documents/templates/design_doc_menu",
+ events: {
+ "click button": "no",
+ "click .js-collapse-toggle": "toggleArrow"
+ },
+ initialize: function(){
+
+ },
+ toggleArrow: function(e){
+ this.$(e.currentTarget).toggleClass("down");
+ },
+ no: function(event){
+ event.preventDefault();
+ alert("no");
+ },
+ buildIndexList: function(collection, selector){
+ var design = this.model.id.replace(/^_design\//,"");
+ _.each(_.keys(collection[selector]), function(key){
+ this.insertView(".accordion-body", new Views.IndexItem({
+ selector: selector,
+ ddoc: design,
+ index: key,
+ database: this.model.collection.database.id
+ }));
+ }, this);
+ },
+
+ serialize: function(){
+ var ddocName = this.model.id.replace(/^_design\//,"");
+ return{
+ database: this.collection.database,
+ designDoc: ddocName
+ };
+ },
+ beforeRender: function(manage) {
+ var ddocDocs = this.model.get("doc");
+ var ddocName = this.model.id.replace(/^_design\//,"");
+
+ var sidebarListTypes = FauxtonAPI.getExtensions('sidebar:list');
+ if (ddocDocs){
+ //Views
+ this.buildIndexList(ddocDocs, "views");
+ //lists
+ this.buildIndexList(ddocDocs, "lists");
+ //show
+ this.buildIndexList(ddocDocs, "show");
+ //filters
+ this.buildIndexList(ddocDocs, "filters");
+ //extensions
+ _.each(sidebarListTypes, function (type) {
+ this.buildIndexList(ddocDocs, type);
+ },this);
+ }
+ this.insertView(".new-button", new Views.newMenuDropdown({
+ database: this.collection.database,
+ ddocSafeName: app.utils.safeURLName(ddocName),
+ fullMenu: false
+ }));
+
+ }
+ });
+
Views.Indexed = FauxtonAPI.View.extend({});
Views.Changes = FauxtonAPI.View.extend({
@@ -1960,6 +2013,30 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
}
});
+
+ Views.newMenuDropdown = FauxtonAPI.View.extend({
+ template: "addons/documents/templates/add_new_ddoc_fn_dropdown",
+ tagName: "div",
+ className: "dropdown",
+ initialize: function(options){
+ this.database = options.database;
+ this.fullMenu = options.fullMenu;
+ this.ddocSafeName = options.ddocSafeName || "";
+ },
+ serialize: function(){
+ return {
+ database: this.database,
+ ddocSafe: this.ddocSafeName,
+ full: this.fullMenu
+ };
+ }
+ });
+
+
+
+ Views.temp = FauxtonAPI.View.extend({
+ });
+
Views.DdocInfo = FauxtonAPI.View.extend({
template: "addons/documents/templates/ddoc_info",
http://git-wip-us.apache.org/repos/asf/couchdb/blob/c1e14237/src/fauxton/app/templates/layouts/two_pane.html
----------------------------------------------------------------------
diff --git a/src/fauxton/app/templates/layouts/two_pane.html b/src/fauxton/app/templates/layouts/two_pane.html
index 0c3165e..031ad12 100644
--- a/src/fauxton/app/templates/layouts/two_pane.html
+++ b/src/fauxton/app/templates/layouts/two_pane.html
@@ -22,7 +22,6 @@ the License.
<div class="row-fluid content-area">
- <div id="tabs" class="row"></div>
<div id="left-content" class="span6"></div>
<div id="right-content" class="span6"></div>
</div>
http://git-wip-us.apache.org/repos/asf/couchdb/blob/c1e14237/src/fauxton/assets/less/bootstrap/dropdowns.less
----------------------------------------------------------------------
diff --git a/src/fauxton/assets/less/bootstrap/dropdowns.less b/src/fauxton/assets/less/bootstrap/dropdowns.less
index 9e47b47..0425077 100644
--- a/src/fauxton/assets/less/bootstrap/dropdowns.less
+++ b/src/fauxton/assets/less/bootstrap/dropdowns.less
@@ -39,6 +39,7 @@
// The dropdown menu (ul)
// ----------------------
.dropdown-menu {
+
position: absolute;
top: 100%;
left: 0;
@@ -46,7 +47,6 @@
display: none; // none by default, but block on "open" of the menu
float: left;
min-width: 160px;
- padding: 5px 0;
margin: 2px 0 0; // override default ul
list-style: none;
background-color: @dropdownBackground;
@@ -54,8 +54,6 @@
border: 1px solid @dropdownBorder;
*border-right-width: 2px;
*border-bottom-width: 2px;
- .border-radius(6px);
- .box-shadow(0 5px 10px rgba(0,0,0,.2));
-webkit-background-clip: padding-box;
-moz-background-clip: padding;
background-clip: padding-box;
@@ -65,7 +63,29 @@
right: 0;
left: auto;
}
-
+ li.header-label{
+ background-color: #1A1A1A;
+ color: #676767;
+ padding: 3px 20px;
+ font-size: 13px;
+ }
+ &.arrow {
+ &:before{
+ content: "";
+ display: block;
+ position: absolute;
+ border-style: solid;
+ top: -20px;
+ left: 50%;
+ width: 0;
+ height: 0;
+ margin-left: -10px;
+ border-left: 10px solid transparent;
+ border-right: 10px solid transparent;
+ border-bottom: 10px solid #2b2f33;
+ border-top: 10px solid transparent;
+ }
+ }
// Dividers (basically an hr) within the dropdown
.divider {
.nav-divider(@dropdownDividerTop, @dropdownDividerBottom);
@@ -73,6 +93,10 @@
// Links within the dropdown menu
> li > a {
+ &.icon:before{
+ padding-right: 5px;
+ }
+ font-size: 12px;
display: block;
padding: 3px 20px;
clear: both;
@@ -80,6 +104,7 @@
line-height: @baseLineHeight;
color: @dropdownLinkColor;
white-space: nowrap;
+ border-bottom: 1px solid #1A1A1A;
}
}
http://git-wip-us.apache.org/repos/asf/couchdb/blob/c1e14237/src/fauxton/assets/less/bootstrap/navs.less
----------------------------------------------------------------------
diff --git a/src/fauxton/assets/less/bootstrap/navs.less b/src/fauxton/assets/less/bootstrap/navs.less
index 01cd805..0013179 100644
--- a/src/fauxton/assets/less/bootstrap/navs.less
+++ b/src/fauxton/assets/less/bootstrap/navs.less
@@ -37,12 +37,9 @@
.nav-header {
display: block;
padding: 3px 15px;
- font-size: 11px;
- font-weight: bold;
line-height: @baseLineHeight;
color: @grayLight;
text-shadow: 0 1px 0 rgba(255,255,255,.5);
- text-transform: uppercase;
}
// Space them out when they follow another list item (link)
.nav li + .nav-header {
http://git-wip-us.apache.org/repos/asf/couchdb/blob/c1e14237/src/fauxton/assets/less/bootstrap/variables.less
----------------------------------------------------------------------
diff --git a/src/fauxton/assets/less/bootstrap/variables.less b/src/fauxton/assets/less/bootstrap/variables.less
index 31c131b..f52b2cb 100644
--- a/src/fauxton/assets/less/bootstrap/variables.less
+++ b/src/fauxton/assets/less/bootstrap/variables.less
@@ -119,12 +119,12 @@
// Dropdowns
// -------------------------
-@dropdownBackground: @white;
+@dropdownBackground: #2B2F33;
@dropdownBorder: rgba(0,0,0,.2);
-@dropdownDividerTop: #e5e5e5;
-@dropdownDividerBottom: @white;
+@dropdownDividerTop: #1A1A1A;
+@dropdownDividerBottom: #1A1A1A;
-@dropdownLinkColor: @grayDark;
+@dropdownLinkColor: #D9D9D9;
@dropdownLinkColorHover: @white;
@dropdownLinkColorActive: @white;
http://git-wip-us.apache.org/repos/asf/couchdb/blob/c1e14237/src/fauxton/assets/less/fauxton.less
----------------------------------------------------------------------
diff --git a/src/fauxton/assets/less/fauxton.less b/src/fauxton/assets/less/fauxton.less
index 229075b..2fba9df 100644
--- a/src/fauxton/assets/less/fauxton.less
+++ b/src/fauxton/assets/less/fauxton.less
@@ -357,7 +357,7 @@ table.databases {
background: url(../img/couchdb-site.png) no-repeat 0 0;
display: block;
height: 100%;
- width: 100%;
+ width: 100%;
}
.burger{
.transition(all @transitionSpeed @transitionEaseType);
@@ -468,7 +468,7 @@ table.databases {
background-color: @bottomNav;
&.active{
background-color:@linkRed;
- }
+ }
&:hover{
background-color: @navBGHover;
}
@@ -527,12 +527,15 @@ table.databases {
padding: 0px;
bottom: 0px;
top: 60px;
- position: absolute;
+ position: fixed;
overflow-x: hidden;
overflow-y: auto;
- left: @sidebarWidth;
+ left: @sidebarWidth+@navWidth;
right: 0;
.box-sizing(border-box);
+ .closeMenu & {
+ left: @sidebarWidth+@collapsedNavWidth;
+ }
}
> div.inner {
display: block;
@@ -636,7 +639,7 @@ table.databases {
}
}
-#sidenav{
+.sidenav{
padding: 0;
header {
width: @sidebarWidth;
@@ -644,46 +647,48 @@ table.databases {
background: transparent url('../img/linen.png') repeat 0 0;
.topmenu-defaults;
}
- nav {
- .nav-list{
- .divider {
- border: none;
- }
- li.active a {
- background-color: @darkRed;
- color: #fff;
- }
- a{
- display: block;
- padding: 10px 5px 10px 15px;
- color: #333333;
- border-bottom: 1px solid #989898;
- .divider {
- background: none;
- color: #ccc;
- padding: 0 2px;
- }
- }
- .nav-header{
- background-color: #B2B2B2;
- padding: 5px;
- text-shadow: none;
- color: #333333;
- border-bottom: 1px solid #989898;
+ .nav-list{
+ .divider {
+ border: none;
+ }
+ li.active a {
+ background-color: @darkRed;
+ color: #fff;
+ }
+ > li > a{
+ padding: 10px 13px 10px 30px;
+ border-bottom: 1px solid #989898;
+ }
+ .dropdown-menu {
+ a {
+ color: #d9d9d9;
}
+ }
+ a{
+ display: block;
+ padding: 10px 5px 10px 15px;
+ color: #333333;
+ .divider {
+ background: none;
+ color: #ccc;
+ padding: 0 2px;
+ }
+ }
+ .nav-header{
+ padding: 0px;
+ text-shadow: none;
+ color: #333333;
+ margin-bottom: -4px;
}
}
}
+
#sidebar-content {
-.box-shadow(-7px 0 15px -6px #000);
position: absolute;
- bottom: 0px;
top: 60px;
width: @sidebarWidth;
left: 0;
- overflow-x: hidden;
- overflow-y: auto;
background-color: @secondarySidebar;
> div.inner {
display: block;
@@ -749,14 +754,14 @@ table.databases {
.custom-inputs{
- input[type=radio],
- input[type=checkbox] {
- display: none;
- }
+ input[type=radio],
+ input[type=checkbox] {
+ display: none;
+ }
- .checkbox label:before {
- border-radius: 3px;
- }
+ .checkbox label:before {
+ border-radius: 3px;
+ }
.controls > .radio:first-child, .controls > .checkbox:first-child {
padding-top: 15px;
@@ -769,42 +774,42 @@ table.databases {
vertical-align: middle;
}
- input[type=checkbox]:checked + label:before {
+ input[type=checkbox]:checked + label:before {
/*content: "\2713"; */
- content: "\00d7";
- text-shadow: 1px 1px 1px rgba(0, 0, 0, .2);
+ content: "\00d7";
+ text-shadow: 1px 1px 1px rgba(0, 0, 0, .2);
font-size: 16px;
- background-color: @red;
- color: white;
- text-align: center;
- line-height: 15px;
- }
-
- label:before {
- content: "";
- display: inline-block;
-
- width: 16px;
- height: 16px;
-
- margin-right: 10px;
- position: absolute;
- left: 0;
- bottom: 1px;
- background-color: #aaa;
- box-shadow: inset 0px 2px 3px 0px rgba(0, 0, 0, .3), 0px 1px 0px 0px rgba(255, 255, 255, .8);
- }
-
- .radio label:before {
- border-radius: 8px;
- }
-
- input[type=radio]:checked + label:before {
- content: "\2022";
- color: #f3f3f3;
- font-size: 30px;
- text-align: center;
- line-height: 18px;
+ background-color: @red;
+ color: white;
+ text-align: center;
+ line-height: 15px;
+ }
+
+ label:before {
+ content: "";
+ display: inline-block;
+
+ width: 16px;
+ height: 16px;
+
+ margin-right: 10px;
+ position: absolute;
+ left: 0;
+ bottom: 1px;
+ background-color: #aaa;
+ box-shadow: inset 0px 2px 3px 0px rgba(0, 0, 0, .3), 0px 1px 0px 0px rgba(255, 255, 255, .8);
+ }
+
+ .radio label:before {
+ border-radius: 8px;
+ }
+
+ input[type=radio]:checked + label:before {
+ content: "\2022";
+ color: #f3f3f3;
+ font-size: 30px;
+ text-align: center;
+ line-height: 18px;
}
label.drop-down{
http://git-wip-us.apache.org/repos/asf/couchdb/blob/c1e14237/src/fauxton/assets/less/variables.less
----------------------------------------------------------------------
diff --git a/src/fauxton/assets/less/variables.less b/src/fauxton/assets/less/variables.less
index 34f8b90..ab479a8 100644
--- a/src/fauxton/assets/less/variables.less
+++ b/src/fauxton/assets/less/variables.less
@@ -54,6 +54,7 @@
@sidebarBG: #F2F2F2;
@sidebarWidth: 330px;
+
@NavIconActive: #ffffff;
@NavIcon: @brown;
[37/41] couchdb commit: updated refs/heads/Update-Sidebar-Ui to
c1e1423
Posted by de...@apache.org.
minor documentation fix
Project: http://git-wip-us.apache.org/repos/asf/couchdb/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb/commit/053b471a
Tree: http://git-wip-us.apache.org/repos/asf/couchdb/tree/053b471a
Diff: http://git-wip-us.apache.org/repos/asf/couchdb/diff/053b471a
Branch: refs/heads/Update-Sidebar-Ui
Commit: 053b471a4f89420d2863842cc38354a3906af496
Parents: 8b429c8
Author: Andy Wenk <an...@apache.org>
Authored: Thu Mar 27 21:07:03 2014 +0100
Committer: Andy Wenk <an...@apache.org>
Committed: Thu Mar 27 21:07:03 2014 +0100
----------------------------------------------------------------------
share/doc/src/install/freebsd.rst | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/couchdb/blob/053b471a/share/doc/src/install/freebsd.rst
----------------------------------------------------------------------
diff --git a/share/doc/src/install/freebsd.rst b/share/doc/src/install/freebsd.rst
index b82edd1..85b74b5 100644
--- a/share/doc/src/install/freebsd.rst
+++ b/share/doc/src/install/freebsd.rst
@@ -37,7 +37,7 @@ supported by the start script (defaults shown)::
couchdb_enablelogs="YES"
couchdb_user="couchdb"
-After enabling couchdb rc service use the following to start CouchDB::
+After enabling the couchdb rc service use the following command to start CouchDB::
/usr/local/etc/rc.d/couchdb start
[13/41] couchdb commit: updated refs/heads/Update-Sidebar-Ui to
c1e1423
Posted by de...@apache.org.
Merge branch 'fix/build2' of https://github.com/robertkowalski/couchdb
This closes #190
Project: http://git-wip-us.apache.org/repos/asf/couchdb/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb/commit/a7a6d2ee
Tree: http://git-wip-us.apache.org/repos/asf/couchdb/tree/a7a6d2ee
Diff: http://git-wip-us.apache.org/repos/asf/couchdb/diff/a7a6d2ee
Branch: refs/heads/Update-Sidebar-Ui
Commit: a7a6d2eec4d79dc12afed7cffbc5e4dc4c45e42f
Parents: 89eb4a6 5bdfa6c
Author: Andy Wenk <an...@apache.org>
Authored: Fri Mar 21 21:45:45 2014 +0100
Committer: Andy Wenk <an...@apache.org>
Committed: Fri Mar 21 21:45:45 2014 +0100
----------------------------------------------------------------------
----------------------------------------------------------------------
[22/41] couchdb commit: updated refs/heads/Update-Sidebar-Ui to
c1e1423
Posted by de...@apache.org.
Updating d3 to v3.4.3 and nv.d3 to v1.1.15
Project: http://git-wip-us.apache.org/repos/asf/couchdb/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb/commit/95d6d6b0
Tree: http://git-wip-us.apache.org/repos/asf/couchdb/tree/95d6d6b0
Diff: http://git-wip-us.apache.org/repos/asf/couchdb/diff/95d6d6b0
Branch: refs/heads/Update-Sidebar-Ui
Commit: 95d6d6b035242d9a203b2df3af342274b29f98b1
Parents: 0fb5aa9
Author: Christian Hogan <gi...@infliction.org>
Authored: Fri Mar 21 13:42:04 2014 -0400
Committer: suelockwood <de...@apache.org>
Committed: Tue Mar 25 15:19:17 2014 -0400
----------------------------------------------------------------------
src/fauxton/assets/css/nv.d3.css | 191 +-
src/fauxton/assets/js/libs/d3.js | 14721 +++++++++++++++++------------
src/fauxton/assets/js/libs/nv.d3.js | 4536 +++++----
3 files changed, 11530 insertions(+), 7918 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/couchdb/blob/95d6d6b0/src/fauxton/assets/css/nv.d3.css
----------------------------------------------------------------------
diff --git a/src/fauxton/assets/css/nv.d3.css b/src/fauxton/assets/css/nv.d3.css
index 28ccd05..cae8348 100644
--- a/src/fauxton/assets/css/nv.d3.css
+++ b/src/fauxton/assets/css/nv.d3.css
@@ -10,6 +10,18 @@
overflow: hidden;
}
+/********************
+ Box shadow and border radius styling
+*/
+.nvtooltip.with-3d-shadow, .with-3d-shadow .nvtooltip {
+ -moz-box-shadow: 0 5px 10px rgba(0,0,0,.2);
+ -webkit-box-shadow: 0 5px 10px rgba(0,0,0,.2);
+ box-shadow: 0 5px 10px rgba(0,0,0,.2);
+
+ -webkit-border-radius: 6px;
+ -moz-border-radius: 6px;
+ border-radius: 6px;
+}
/********************
* TOOLTIP CSS
@@ -17,31 +29,18 @@
.nvtooltip {
position: absolute;
- background-color: rgba(255,255,255,1);
- padding: 10px;
- border: 1px solid #ddd;
+ background-color: rgba(255,255,255,1.0);
+ padding: 1px;
+ border: 1px solid rgba(0,0,0,.2);
z-index: 10000;
font-family: Arial;
font-size: 13px;
-
- transition: opacity 500ms linear;
- -moz-transition: opacity 500ms linear;
- -webkit-transition: opacity 500ms linear;
-
- transition-delay: 500ms;
- -moz-transition-delay: 500ms;
- -webkit-transition-delay: 500ms;
-
- -moz-box-shadow: 4px 4px 8px rgba(0,0,0,.5);
- -webkit-box-shadow: 4px 4px 8px rgba(0,0,0,.5);
- box-shadow: 4px 4px 8px rgba(0,0,0,.5);
-
- -moz-border-radius: 10px;
- border-radius: 10px;
-
+ text-align: left;
pointer-events: none;
+ white-space: nowrap;
+
-webkit-touch-callout: none;
-webkit-user-select: none;
-khtml-user-select: none;
@@ -50,15 +49,42 @@
user-select: none;
}
+/*Give tooltips that old fade in transition by
+ putting a "with-transitions" class on the container div.
+*/
+.nvtooltip.with-transitions, .with-transitions .nvtooltip {
+ transition: opacity 250ms linear;
+ -moz-transition: opacity 250ms linear;
+ -webkit-transition: opacity 250ms linear;
+
+ transition-delay: 250ms;
+ -moz-transition-delay: 250ms;
+ -webkit-transition-delay: 250ms;
+}
+
+.nvtooltip.x-nvtooltip,
+.nvtooltip.y-nvtooltip {
+ padding: 8px;
+}
+
.nvtooltip h3 {
margin: 0;
- padding: 0;
+ padding: 4px 14px;
+ line-height: 18px;
+ font-weight: normal;
+ background-color: rgba(247,247,247,0.75);
text-align: center;
+
+ border-bottom: 1px solid #ebebeb;
+
+ -webkit-border-radius: 5px 5px 0 0;
+ -moz-border-radius: 5px 5px 0 0;
+ border-radius: 5px 5px 0 0;
}
.nvtooltip p {
margin: 0;
- padding: 0;
+ padding: 5px 14px;
text-align: center;
}
@@ -67,6 +93,45 @@
margin: 2px 0;
}
+.nvtooltip table {
+ margin: 6px;
+ border-spacing:0;
+}
+
+
+.nvtooltip table td {
+ padding: 2px 9px 2px 0;
+ vertical-align: middle;
+}
+
+.nvtooltip table td.key {
+ font-weight:normal;
+}
+.nvtooltip table td.value {
+ text-align: right;
+ font-weight: bold;
+}
+
+.nvtooltip table tr.highlight td {
+ padding: 1px 9px 1px 0;
+ border-bottom-style: solid;
+ border-bottom-width: 1px;
+ border-top-style: solid;
+ border-top-width: 1px;
+}
+
+.nvtooltip table td.legend-color-guide div {
+ width: 8px;
+ height: 8px;
+ vertical-align: middle;
+}
+
+.nvtooltip .footer {
+ padding: 3px;
+ text-align: center;
+}
+
+
.nvtooltip-pending-removal {
position: absolute;
pointer-events: none;
@@ -110,7 +175,7 @@ svg .title {
.nvd3.nv-noData {
font-size: 18px;
- font-weight: bolf;
+ font-weight: bold;
}
@@ -142,6 +207,9 @@ svg .title {
/**********
* Axes
*/
+.nvd3 .nv-axis {
+ pointer-events:none;
+}
.nvd3 .nv-axis path {
fill: none;
@@ -160,12 +228,12 @@ svg .title {
.nvd3 .nv-axis line {
fill: none;
- stroke: #000;
- stroke-opacity: .25;
+ stroke: #e5e5e5;
shape-rendering: crispEdges;
}
-.nvd3 .nv-axis line.zero {
+.nvd3 .nv-axis .zero line,
+/*this selector may not be necessary*/ .nvd3 .nv-axis line.zero {
stroke-opacity: .75;
}
@@ -209,7 +277,7 @@ svg .title {
-webkit-transition: fill-opacity 250ms linear;
}
-.nvd3 .nv-bars rect:hover {
+.nvd3 .nv-bars rect.hover {
fill-opacity: 1;
}
@@ -259,7 +327,6 @@ svg .title {
.nvd3.nv-pie path {
stroke-opacity: 0;
-
transition: fill-opacity 250ms linear, stroke-width 250ms linear, stroke-opacity 250ms linear;
-moz-transition: fill-opacity 250ms linear, stroke-width 250ms linear, stroke-opacity 250ms linear;
-webkit-transition: fill-opacity 250ms linear, stroke-width 250ms linear, stroke-opacity 250ms linear;
@@ -279,12 +346,10 @@ svg .title {
.nvd3.nv-pie .hover path {
fill-opacity: .7;
-/*
- stroke-width: 6px;
- stroke-opacity: 1;
-*/
}
-
+.nvd3.nv-pie .nv-label {
+ pointer-events: none;
+}
.nvd3.nv-pie .nv-label rect {
fill-opacity: 0;
stroke-opacity: 0;
@@ -296,7 +361,7 @@ svg .title {
.nvd3 .nv-groups path.nv-line {
fill: none;
- stroke-width: 2.5px;
+ stroke-width: 1.5px;
/*
stroke-linecap: round;
shape-rendering: geometricPrecision;
@@ -311,6 +376,11 @@ svg .title {
*/
}
+.nvd3 .nv-groups path.nv-line.nv-thin-line {
+ stroke-width: 1px;
+}
+
+
.nvd3 .nv-groups path.nv-area {
stroke: none;
/*
@@ -350,17 +420,18 @@ svg .title {
}
-.nvd3 .nv-groups .nv-point {
+.with-transitions .nvd3 .nv-groups .nv-point {
transition: stroke-width 250ms linear, stroke-opacity 250ms linear;
-moz-transition: stroke-width 250ms linear, stroke-opacity 250ms linear;
-webkit-transition: stroke-width 250ms linear, stroke-opacity 250ms linear;
+
}
.nvd3.nv-scatter .nv-groups .nv-point.hover,
.nvd3 .nv-groups .nv-point.hover {
- stroke-width: 20px;
- fill-opacity: .5 !important;
- stroke-opacity: .5 !important;
+ stroke-width: 7px;
+ fill-opacity: .95 !important;
+ stroke-opacity: .95 !important;
}
@@ -457,11 +528,12 @@ svg .title {
fill-opacity: 0;
}
+/*
.nvd3.nv-stackedarea .nv-groups .nv-point.hover {
stroke-width: 20px;
stroke-opacity: .75;
fill-opacity: 1;
-}
+}*/
@@ -496,7 +568,7 @@ svg .title {
.nvd3.nv-bullet .nv-range {
- fill: #999;
+ fill: #bababa;
fill-opacity: .4;
}
.nvd3.nv-bullet .nv-range:hover {
@@ -653,4 +725,45 @@ svg .title {
*/
}
+/**********
+* Parallel Coordinates
+*/
+
+.nvd3 .background path {
+ fill: none;
+ stroke: #ccc;
+ stroke-opacity: .4;
+ shape-rendering: crispEdges;
+}
+
+.nvd3 .foreground path {
+ fill: none;
+ stroke: steelblue;
+ stroke-opacity: .7;
+}
+
+.nvd3 .brush .extent {
+ fill-opacity: .3;
+ stroke: #fff;
+ shape-rendering: crispEdges;
+}
+.nvd3 .axis line, .axis path {
+ fill: none;
+ stroke: #000;
+ shape-rendering: crispEdges;
+}
+
+.nvd3 .axis text {
+ text-shadow: 0 1px 0 #fff;
+}
+
+/****
+Interactive Layer
+*/
+.nvd3 .nv-interactiveGuideLine {
+ pointer-events:none;
+}
+.nvd3 line.nv-guideline {
+ stroke: #ccc;
+}
\ No newline at end of file
[38/41] couchdb commit: updated refs/heads/Update-Sidebar-Ui to
c1e1423
Posted by de...@apache.org.
change the documentation for unix
the testsuite in Futon is not linked anymore (/_utils/couch_tests.html)
but there is the verify installation page. Changed the docs accordingly.
Project: http://git-wip-us.apache.org/repos/asf/couchdb/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb/commit/81266c0a
Tree: http://git-wip-us.apache.org/repos/asf/couchdb/tree/81266c0a
Diff: http://git-wip-us.apache.org/repos/asf/couchdb/diff/81266c0a
Branch: refs/heads/Update-Sidebar-Ui
Commit: 81266c0a26158955645ec121e5c76263830dabb0
Parents: 053b471
Author: Andy Wenk <an...@apache.org>
Authored: Thu Mar 27 21:17:05 2014 +0100
Committer: Andy Wenk <an...@apache.org>
Committed: Thu Mar 27 21:17:05 2014 +0100
----------------------------------------------------------------------
share/doc/src/install/unix.rst | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/couchdb/blob/81266c0a/share/doc/src/install/unix.rst
----------------------------------------------------------------------
diff --git a/share/doc/src/install/unix.rst b/share/doc/src/install/unix.rst
index da4e5bd..05e0459 100644
--- a/share/doc/src/install/unix.rst
+++ b/share/doc/src/install/unix.rst
@@ -175,7 +175,9 @@ To check that everything has worked, point your web browser to::
http://127.0.0.1:5984/_utils/index.html
-From here you should run the test suite in Firefox.
+From here you should verify your installation by pointing your web browser to::
+
+ http://localhost:5984/_utils/verify_install.html
Security Considerations
-----------------------
[12/41] couchdb commit: updated refs/heads/Update-Sidebar-Ui to
c1e1423
Posted by de...@apache.org.
Fauxton: fix global var
Project: http://git-wip-us.apache.org/repos/asf/couchdb/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb/commit/89eb4a6d
Tree: http://git-wip-us.apache.org/repos/asf/couchdb/tree/89eb4a6d
Diff: http://git-wip-us.apache.org/repos/asf/couchdb/diff/89eb4a6d
Branch: refs/heads/Update-Sidebar-Ui
Commit: 89eb4a6d627e1f4e15a998319ac92210e7a1faba
Parents: 35390c8
Author: Robert Kowalski <ro...@kowalski.gd>
Authored: Fri Mar 21 20:49:41 2014 +0100
Committer: Robert Kowalski <ro...@kowalski.gd>
Committed: Fri Mar 21 20:49:41 2014 +0100
----------------------------------------------------------------------
src/fauxton/app/addons/activetasks/views.js | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/couchdb/blob/89eb4a6d/src/fauxton/app/addons/activetasks/views.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/activetasks/views.js b/src/fauxton/app/addons/activetasks/views.js
index 1da8f52..b0940bf 100644
--- a/src/fauxton/app/addons/activetasks/views.js
+++ b/src/fauxton/app/addons/activetasks/views.js
@@ -58,8 +58,8 @@ function (app, FauxtonAPI, activetasks) {
},
requestByType: function(e){
- var currentTarget = e.currentTarget;
- datatype = this.$(currentTarget).attr("data-type");
+ var currentTarget = e.currentTarget,
+ datatype = this.$(currentTarget).attr("data-type");
this.$('.task-tabs').find('li').removeClass('active');
this.$(currentTarget).addClass('active');
@@ -119,8 +119,9 @@ function (app, FauxtonAPI, activetasks) {
currentView = this.options.currentView;
},
sortByType: function(e){
- var currentTarget = e.currentTarget;
- datatype = $(currentTarget).attr("data-type");
+ var currentTarget = e.currentTarget,
+ datatype = $(currentTarget).attr("data-type");
+
this.collection.sortByColumn(datatype);
this.render();
},
[05/41] couchdb commit: updated refs/heads/Update-Sidebar-Ui to
c1e1423
Posted by de...@apache.org.
update documentation
explain better what happens with the view index when documents
in a view are being processed
Project: http://git-wip-us.apache.org/repos/asf/couchdb/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb/commit/fb59ccae
Tree: http://git-wip-us.apache.org/repos/asf/couchdb/tree/fb59ccae
Diff: http://git-wip-us.apache.org/repos/asf/couchdb/diff/fb59ccae
Branch: refs/heads/Update-Sidebar-Ui
Commit: fb59ccae8d90f6407e5b9d08a302f909778db9b7
Parents: 3be8c85
Author: Andy Wenk <an...@apache.org>
Authored: Thu Mar 20 23:52:26 2014 +0100
Committer: Andy Wenk <an...@apache.org>
Committed: Thu Mar 20 23:52:26 2014 +0100
----------------------------------------------------------------------
share/doc/src/intro/overview.rst | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/couchdb/blob/fb59ccae/share/doc/src/intro/overview.rst
----------------------------------------------------------------------
diff --git a/share/doc/src/intro/overview.rst b/share/doc/src/intro/overview.rst
index f94d656..4e3b72c 100644
--- a/share/doc/src/intro/overview.rst
+++ b/share/doc/src/intro/overview.rst
@@ -198,9 +198,10 @@ simultaneous client readers, who can read and query the view while the index
is concurrently being refreshed for other clients without causing problems
for the readers.
-As documents are examined, their previous row values are removed from the
-view indexes, if they exist. If the document is selected by a view function,
-the function results are inserted into the view as a new row.
+As documents are processed by the view engine through your 'map' and 'reduce'
+functions, their previous row values are removed from the view indexes, if
+they exist. If the document is selected by a view function, the function results
+are inserted into the view as a new row.
When view index changes are written to disk, the updates are always appended
at the end of the file, serving to both reduce disk head seek times during
[10/41] couchdb commit: updated refs/heads/Update-Sidebar-Ui to
c1e1423
Posted by de...@apache.org.
Fauxton: Fix tests
Project: http://git-wip-us.apache.org/repos/asf/couchdb/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb/commit/5bdfa6c4
Tree: http://git-wip-us.apache.org/repos/asf/couchdb/tree/5bdfa6c4
Diff: http://git-wip-us.apache.org/repos/asf/couchdb/diff/5bdfa6c4
Branch: refs/heads/Update-Sidebar-Ui
Commit: 5bdfa6c41c1dfd9782907b513954cdbd0b6edaa2
Parents: ca5913e
Author: Robert Kowalski <ro...@kowalski.gd>
Authored: Fri Mar 21 17:49:15 2014 +0100
Committer: Robert Kowalski <ro...@kowalski.gd>
Committed: Fri Mar 21 17:49:15 2014 +0100
----------------------------------------------------------------------
.../app/addons/config/tests/resourcesSpec.js | 20 ++++++++++++++++----
1 file changed, 16 insertions(+), 4 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/couchdb/blob/5bdfa6c4/src/fauxton/app/addons/config/tests/resourcesSpec.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/config/tests/resourcesSpec.js b/src/fauxton/app/addons/config/tests/resourcesSpec.js
index c78bc85..1cc9e62 100644
--- a/src/fauxton/app/addons/config/tests/resourcesSpec.js
+++ b/src/fauxton/app/addons/config/tests/resourcesSpec.js
@@ -28,7 +28,10 @@ define([
});
tabMenu = new Views.TableRow({
- model: optionModel
+ model: optionModel,
+ uniqueName: function () {
+ return false;
+ }
});
});
@@ -47,8 +50,12 @@ define([
var renderSpy = sinon.stub(tabMenu, 'render');
var saveSpy = sinon.stub(optionModel, 'save');
- tabMenu.$('.js-edit-value').trigger('dblclick');
- tabMenu.$('.js-save-value').trigger('click');
+ var $fields = tabMenu.$('.js-edit-value').filter(function (el) {
+ return $(this).find('[name="value"]').length;
+ });
+
+ $fields.find('.js-edit-value').trigger('dblclick');
+ $fields.find('.js-save-value').trigger('click');
assert.ok(renderSpy.calledOnce);
assert.ok(saveSpy.calledOnce);
@@ -60,7 +67,12 @@ define([
var e = $.Event("keyup");
e.keyCode = 13;
- tabMenu.$('.js-value-input').trigger(e);
+
+ var $fields = tabMenu.$('.js-edit-value').filter(function (el) {
+ return $(this).find('[name="value"]').length;
+ });
+
+ $fields.find('.js-value-input').trigger(e);
assert.ok(renderSpy.calledOnce);
assert.ok(saveSpy.calledOnce);
[39/41] couchdb commit: updated refs/heads/Update-Sidebar-Ui to
c1e1423
Posted by de...@apache.org.
moving myself from THANKS to AUTHORS
Project: http://git-wip-us.apache.org/repos/asf/couchdb/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb/commit/238f78ed
Tree: http://git-wip-us.apache.org/repos/asf/couchdb/tree/238f78ed
Diff: http://git-wip-us.apache.org/repos/asf/couchdb/diff/238f78ed
Branch: refs/heads/Update-Sidebar-Ui
Commit: 238f78ed36f256de31b660b537c1d4c6008a0627
Parents: 81266c0
Author: Robert Kowalski <ro...@kowalski.gd>
Authored: Sat Mar 29 17:44:51 2014 +0100
Committer: Robert Kowalski <ro...@kowalski.gd>
Committed: Sat Mar 29 17:45:38 2014 +0100
----------------------------------------------------------------------
AUTHORS | 1 +
THANKS.in | 1 -
2 files changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/couchdb/blob/238f78ed/AUTHORS
----------------------------------------------------------------------
diff --git a/AUTHORS b/AUTHORS
index ab48b58..a3c9ee5 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -29,5 +29,6 @@ documentation or developing software. Some of these people are:
* Andy Wenk <an...@apache.org>
* Klaus Trainer <kl...@apache.org>
* Benjamin Young <bi...@apache.org>
+ * Robert Kowalski <ro...@kowalski.gd>
For a list of other credits see the `THANKS` file.
http://git-wip-us.apache.org/repos/asf/couchdb/blob/238f78ed/THANKS.in
----------------------------------------------------------------------
diff --git a/THANKS.in b/THANKS.in
index b3e5cc8..8b2a34f 100644
--- a/THANKS.in
+++ b/THANKS.in
@@ -91,7 +91,6 @@ suggesting improvements or submitting changes. Some of these people are:
* Tim Blair
* Tady Walsh <he...@tady.me>
* Sam Rijs <re...@awesam.de>
- * Robert Kowalski <ro...@kowalski.gd>
# Authors from commit 6c976bd and onwards are auto-inserted. If you are merging
# a commit from a non-committer, you should not add an entry to this file. When
# `bootstrap` is run, the actual THANKS file will be generated.
[17/41] couchdb commit: updated refs/heads/Update-Sidebar-Ui to
c1e1423
Posted by de...@apache.org.
Improving misleading example. Do not emit(foo, doc)!
Project: http://git-wip-us.apache.org/repos/asf/couchdb/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb/commit/0f7be287
Tree: http://git-wip-us.apache.org/repos/asf/couchdb/tree/0f7be287
Diff: http://git-wip-us.apache.org/repos/asf/couchdb/diff/0f7be287
Branch: refs/heads/Update-Sidebar-Ui
Commit: 0f7be287d6a9358d960beb17b16ad7b5e20bd360
Parents: 0e8c178
Author: Joan Touzet <wo...@apache.org>
Authored: Fri Mar 21 19:44:58 2014 -0400
Committer: Joan Touzet <wo...@apache.org>
Committed: Fri Mar 21 19:44:58 2014 -0400
----------------------------------------------------------------------
share/doc/src/couchapp/views/collation.rst | 15 ++++++++++-----
1 file changed, 10 insertions(+), 5 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/couchdb/blob/0f7be287/share/doc/src/couchapp/views/collation.rst
----------------------------------------------------------------------
diff --git a/share/doc/src/couchapp/views/collation.rst b/share/doc/src/couchapp/views/collation.rst
index 9fa8513..06c4c6d 100644
--- a/share/doc/src/couchapp/views/collation.rst
+++ b/share/doc/src/couchapp/views/collation.rst
@@ -28,7 +28,7 @@ property serves as the key, thus the result will be sorted by ``LastName``:
function(doc) {
if (doc.Type == "customer") {
- emit(doc.LastName, {FirstName: doc.FirstName, Address: doc.Address});
+ emit(doc.LastName, null);
}
}
@@ -49,12 +49,17 @@ associated orders. The values 0 and 1 for the sorting token are arbitrary.
function(doc) {
if (doc.Type == "customer") {
- emit([doc._id, 0], doc);
+ emit([doc._id, 0], null);
} else if (doc.Type == "order") {
- emit([doc.customer_id, 1], doc);
+ emit([doc.customer_id, 1], null);
}
}
+To list a specific customer with ``_id`` XYZ, and all of that customer's orders, limit the startkey and endkey ranges to cover only documents for that customer's ``_id``::
+
+ startkey=["XYZ"]&endkey=["XYZ", {}]
+
+It is not recommended to emit the document itself in the view. Instead, to include the bodies of the documents when requesting the view, request the view with ``?include_docs=true``.
Sorting by Dates
================
@@ -67,14 +72,14 @@ the following emit function would sort by date:
.. code-block:: javascript
- emit(Date.parse(doc.created_at).getTime(), doc);
+ emit(Date.parse(doc.created_at).getTime(), null);
Alternatively, if you use a date format which sorts lexicographically,
such as ``"2013/06/09 13:52:11 +0000"`` you can just
.. code-block:: javascript
- emit(doc.created_at, doc);
+ emit(doc.created_at, null);
and avoid the conversion. As a bonus, this date format is compatible with the
JavaScript date parser, so you can use ``new Date(doc.created_at)`` in your
[30/41] couchdb commit: updated refs/heads/Update-Sidebar-Ui to
c1e1423
Posted by de...@apache.org.
fixed _update function example
It was only checking for req.id existance (it should
always be included in the request) and not its truthiness.
Project: http://git-wip-us.apache.org/repos/asf/couchdb/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb/commit/597b8d16
Tree: http://git-wip-us.apache.org/repos/asf/couchdb/tree/597b8d16
Diff: http://git-wip-us.apache.org/repos/asf/couchdb/diff/597b8d16
Branch: refs/heads/Update-Sidebar-Ui
Commit: 597b8d1611e951cbff0a8f9521bae2c0694baa5d
Parents: 827b848
Author: BigBlueHat <by...@bigbluehat.com>
Authored: Wed Mar 26 09:38:57 2014 -0400
Committer: BigBlueHat <by...@bigbluehat.com>
Committed: Wed Mar 26 09:38:57 2014 -0400
----------------------------------------------------------------------
share/doc/src/couchapp/ddocs.rst | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/couchdb/blob/597b8d16/share/doc/src/couchapp/ddocs.rst
----------------------------------------------------------------------
diff --git a/share/doc/src/couchapp/ddocs.rst b/share/doc/src/couchapp/ddocs.rst
index 754b9b7..4f4664a 100644
--- a/share/doc/src/couchapp/ddocs.rst
+++ b/share/doc/src/couchapp/ddocs.rst
@@ -419,7 +419,7 @@ The basic example that demonstrates all use-cases of update handlers below:
function(doc, req){
if (!doc){
- if ('id' in req){
+ if ('id' in req && req['id']){
// create new document
return [{'_id': req['id']}, 'New World']
}
[40/41] couchdb commit: updated refs/heads/Update-Sidebar-Ui to
c1e1423
Posted by de...@apache.org.
Fauxton: fix tests for Auth
Project: http://git-wip-us.apache.org/repos/asf/couchdb/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb/commit/ce352c8d
Tree: http://git-wip-us.apache.org/repos/asf/couchdb/tree/ce352c8d
Diff: http://git-wip-us.apache.org/repos/asf/couchdb/diff/ce352c8d
Branch: refs/heads/Update-Sidebar-Ui
Commit: ce352c8d9a537574408d4fac69590384211b1203
Parents: 238f78e
Author: Robert Kowalski <ro...@kowalski.gd>
Authored: Sun Mar 30 01:58:23 2014 +0100
Committer: Robert Kowalski <ro...@kowalski.gd>
Committed: Sun Mar 30 03:59:19 2014 +0200
----------------------------------------------------------------------
src/fauxton/app/addons/auth/test/baseSpec.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/couchdb/blob/ce352c8d/src/fauxton/app/addons/auth/test/baseSpec.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/auth/test/baseSpec.js b/src/fauxton/app/addons/auth/test/baseSpec.js
index 1525306..ad92ec8 100644
--- a/src/fauxton/app/addons/auth/test/baseSpec.js
+++ b/src/fauxton/app/addons/auth/test/baseSpec.js
@@ -27,7 +27,7 @@ define([
FauxtonAPI.auth = new Auth();
Base.initialize();
FauxtonAPI.auth.authDeniedCb();
- assert.ok(navigateSpy.withArgs('/noAccess', {replace: true}).calledOnce);
+ assert.ok(navigateSpy.withArgs('/noAccess?urlback=', {replace: true}).calledOnce);
});
});
});
[07/41] couchdb commit: updated refs/heads/Update-Sidebar-Ui to
c1e1423
Posted by de...@apache.org.
Fauxton: Fire authenticated event when user is authenticated
Project: http://git-wip-us.apache.org/repos/asf/couchdb/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb/commit/f2153c0f
Tree: http://git-wip-us.apache.org/repos/asf/couchdb/tree/f2153c0f
Diff: http://git-wip-us.apache.org/repos/asf/couchdb/diff/f2153c0f
Branch: refs/heads/Update-Sidebar-Ui
Commit: f2153c0f99050775e3ee1ddb94d9e68848010361
Parents: f0cdb70
Author: Garren Smith <ga...@gmail.com>
Authored: Fri Mar 21 11:31:15 2014 +0200
Committer: Garren Smith <ga...@gmail.com>
Committed: Fri Mar 21 11:31:15 2014 +0200
----------------------------------------------------------------------
src/fauxton/app/addons/auth/base.js | 2 ++
1 file changed, 2 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/couchdb/blob/f2153c0f/src/fauxton/app/addons/auth/base.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/auth/base.js b/src/fauxton/app/addons/auth/base.js
index 3354f53..c7bbb04 100644
--- a/src/fauxton/app/addons/auth/base.js
+++ b/src/fauxton/app/addons/auth/base.js
@@ -39,8 +39,10 @@ function(app, FauxtonAPI, Auth) {
var deferred = $.Deferred();
if (session.isAdminParty()) {
+ session.trigger("authenticated");
deferred.resolve();
} else if(session.matchesRoles(roles)) {
+ session.trigger("authenticated");
deferred.resolve();
} else {
deferred.reject();
[29/41] couchdb commit: updated refs/heads/Update-Sidebar-Ui to
c1e1423
Posted by de...@apache.org.
Readd 'Could not create admin.' to the beginning of the error message
was removed in b63ff1b50b7bde0c8f1f95988d076dda63f41fed
Project: http://git-wip-us.apache.org/repos/asf/couchdb/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb/commit/827b8489
Tree: http://git-wip-us.apache.org/repos/asf/couchdb/tree/827b8489
Diff: http://git-wip-us.apache.org/repos/asf/couchdb/diff/827b8489
Branch: refs/heads/Update-Sidebar-Ui
Commit: 827b84891d5c16a4e5c2b692d3694fe2ba4a1210
Parents: 1fb7cea
Author: Robert Kowalski <ro...@kowalski.gd>
Authored: Tue Mar 25 22:05:19 2014 +0100
Committer: Garren Smith <ga...@gmail.com>
Committed: Wed Mar 26 10:17:51 2014 +0200
----------------------------------------------------------------------
src/fauxton/app/addons/auth/resources.js | 18 +++++++++++++-----
1 file changed, 13 insertions(+), 5 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/couchdb/blob/827b8489/src/fauxton/app/addons/auth/resources.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/auth/resources.js b/src/fauxton/app/addons/auth/resources.js
index edfd708..ba3a438 100644
--- a/src/fauxton/app/addons/auth/resources.js
+++ b/src/fauxton/app/addons/auth/resources.js
@@ -20,7 +20,7 @@ function (app, FauxtonAPI, CouchdbSession) {
var Auth = new FauxtonAPI.addon();
- var promiseErrorHandler = function (xhr, type, msg) {
+ var errorHandler = function (xhr, type, msg) {
msg = xhr;
if (arguments.length === 3) {
msg = xhr.responseJSON.reason;
@@ -72,7 +72,8 @@ function (app, FauxtonAPI, CouchdbSession) {
passwordsNotMatch: 'Passwords do not match.',
loggedIn: 'You have been logged in.',
adminCreated: 'CouchDB admin created',
- changePassword: 'Your password has been updated.'
+ changePassword: 'Your password has been updated.',
+ adminCreationFailedPrefix: 'Could not create admin.'
}, options.messages);
},
@@ -245,7 +246,14 @@ function (app, FauxtonAPI, CouchdbSession) {
}
});
- promise.fail(promiseErrorHandler);
+ promise.fail(function (xhr, type, msg) {
+ msg = xhr;
+ if (arguments.length === 3) {
+ msg = xhr.responseJSON.reason;
+ }
+ msg = FauxtonAPI.session.messages.adminCreationFailedPrefix + ' ' + msg;
+ errorHandler(msg);
+ });
}
});
@@ -279,7 +287,7 @@ function (app, FauxtonAPI, CouchdbSession) {
FauxtonAPI.navigate('/');
});
- promise.fail(promiseErrorHandler);
+ promise.fail(errorHandler);
}
});
@@ -306,7 +314,7 @@ function (app, FauxtonAPI, CouchdbSession) {
that.$('#password-confirm').val('');
});
- promise.fail(promiseErrorHandler);
+ promise.fail(errorHandler);
}
});
[16/41] couchdb commit: updated refs/heads/Update-Sidebar-Ui to
c1e1423
Posted by de...@apache.org.
Fix error message
Small typo in the error message. Was ?=rev but should
read ?rev=
Project: http://git-wip-us.apache.org/repos/asf/couchdb/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb/commit/0e8c1787
Tree: http://git-wip-us.apache.org/repos/asf/couchdb/tree/0e8c1787
Diff: http://git-wip-us.apache.org/repos/asf/couchdb/diff/0e8c1787
Branch: refs/heads/Update-Sidebar-Ui
Commit: 0e8c1787a043a01c6daba9fa574c418b49ca1916
Parents: 2925614
Author: Andy Wenk <an...@apache.org>
Authored: Fri Mar 21 23:16:55 2014 +0100
Committer: Andy Wenk <an...@apache.org>
Committed: Fri Mar 21 23:16:55 2014 +0100
----------------------------------------------------------------------
src/couchdb/couch_httpd_db.erl | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/couchdb/blob/0e8c1787/src/couchdb/couch_httpd_db.erl
----------------------------------------------------------------------
diff --git a/src/couchdb/couch_httpd_db.erl b/src/couchdb/couch_httpd_db.erl
index 0a7c17c..6940e47 100644
--- a/src/couchdb/couch_httpd_db.erl
+++ b/src/couchdb/couch_httpd_db.erl
@@ -44,7 +44,7 @@ handle_request(#httpd{path_parts=[DbName|RestParts],method=Method,
case couch_httpd:qs_value(Req, "rev", false) of
false -> delete_db_req(Req, DbName);
_Rev -> throw({bad_request,
- "You tried to DELETE a database with a ?=rev parameter. "
+ "You tried to DELETE a database with a ?rev= parameter. "
++ "Did you mean to DELETE a document instead?"})
end;
{_, []} ->
[24/41] couchdb commit: updated refs/heads/Update-Sidebar-Ui to
c1e1423
Posted by de...@apache.org.
Updating d3 license year to match d3's official license.
Project: http://git-wip-us.apache.org/repos/asf/couchdb/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb/commit/b1255309
Tree: http://git-wip-us.apache.org/repos/asf/couchdb/tree/b1255309
Diff: http://git-wip-us.apache.org/repos/asf/couchdb/diff/b1255309
Branch: refs/heads/Update-Sidebar-Ui
Commit: b1255309eca961d188d40ef509e7541a3d4ad14e
Parents: 6301060
Author: Christian Hogan <gi...@infliction.org>
Authored: Fri Mar 21 16:31:07 2014 -0400
Committer: suelockwood <de...@apache.org>
Committed: Tue Mar 25 15:19:18 2014 -0400
----------------------------------------------------------------------
LICENSE | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/couchdb/blob/b1255309/LICENSE
----------------------------------------------------------------------
diff --git a/LICENSE b/LICENSE
index 6ae7303..21cfb8c 100644
--- a/LICENSE
+++ b/LICENSE
@@ -689,7 +689,7 @@ For src/fauxton/assets/less/bootstrap
For src/fauxton/assets/js/libs/d3.js
- Copyright (c) 2012, Michael Bostock
+ Copyright (c) 2010-2014, Michael Bostock
All rights reserved.
Redistribution and use in source and binary forms, with or without
[19/41] couchdb commit: updated refs/heads/Update-Sidebar-Ui to
c1e1423
Posted by de...@apache.org.
Configurable upper bound to _uuids count parameter
Project: http://git-wip-us.apache.org/repos/asf/couchdb/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb/commit/0fb5aa9e
Tree: http://git-wip-us.apache.org/repos/asf/couchdb/tree/0fb5aa9e
Diff: http://git-wip-us.apache.org/repos/asf/couchdb/diff/0fb5aa9e
Branch: refs/heads/Update-Sidebar-Ui
Commit: 0fb5aa9e67bd291ca2638dba961f4ddd3f6ccb3e
Parents: 198bea3
Author: Robert Newson <rn...@apache.org>
Authored: Tue Mar 25 15:02:50 2014 +0000
Committer: Robert Newson <rn...@apache.org>
Committed: Tue Mar 25 16:16:18 2014 +0000
----------------------------------------------------------------------
etc/couchdb/default.ini.tpl.in | 2 ++
share/www/script/test/uuids.js | 4 ++++
src/couchdb/couch_httpd_misc_handlers.erl | 5 +++++
3 files changed, 11 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/couchdb/blob/0fb5aa9e/etc/couchdb/default.ini.tpl.in
----------------------------------------------------------------------
diff --git a/etc/couchdb/default.ini.tpl.in b/etc/couchdb/default.ini.tpl.in
index fd953c2..32537e0 100644
--- a/etc/couchdb/default.ini.tpl.in
+++ b/etc/couchdb/default.ini.tpl.in
@@ -217,6 +217,8 @@ algorithm = sequential
; The utc_id_suffix value will be appended to uuids generated by the utc_id algorithm.
; Replicating instances should have unique utc_id_suffix values to ensure uniqueness of utc_id ids.
utc_id_suffix =
+# Maximum number of UUIDs retrievable from /_uuids in a single request
+max_count = 1000
[stats]
; rate is in milliseconds
http://git-wip-us.apache.org/repos/asf/couchdb/blob/0fb5aa9e/share/www/script/test/uuids.js
----------------------------------------------------------------------
diff --git a/share/www/script/test/uuids.js b/share/www/script/test/uuids.js
index 6f5d223..0f141a9 100644
--- a/share/www/script/test/uuids.js
+++ b/share/www/script/test/uuids.js
@@ -80,6 +80,10 @@ couchTests.uuids = function(debug) {
}
};
+ // test max_uuid_count
+ var xhr = CouchDB.request("GET", "/_uuids?count=1001");
+ TEquals(401, xhr.status, "should error when count > max_count");
+
run_on_modified_server([{
"section": "uuids",
"key": "algorithm",
http://git-wip-us.apache.org/repos/asf/couchdb/blob/0fb5aa9e/src/couchdb/couch_httpd_misc_handlers.erl
----------------------------------------------------------------------
diff --git a/src/couchdb/couch_httpd_misc_handlers.erl b/src/couchdb/couch_httpd_misc_handlers.erl
index 96a05c6..67e3a12 100644
--- a/src/couchdb/couch_httpd_misc_handlers.erl
+++ b/src/couchdb/couch_httpd_misc_handlers.erl
@@ -105,7 +105,12 @@ handle_restart_req(Req) ->
handle_uuids_req(#httpd{method='GET'}=Req) ->
+ Max = list_to_integer(couch_config:get("uuids","max","1000")),
Count = list_to_integer(couch_httpd:qs_value(Req, "count", "1")),
+ case Count > Max of
+ true -> throw({forbidden, <<"count parameter too large">>});
+ false -> ok
+ end,
UUIDs = [couch_uuids:new() || _ <- lists:seq(1, Count)],
Etag = couch_httpd:make_etag(UUIDs),
couch_httpd:etag_respond(Req, Etag, fun() ->
[06/41] couchdb commit: updated refs/heads/Update-Sidebar-Ui to
c1e1423
Posted by de...@apache.org.
some minor documentatiom fixes
Project: http://git-wip-us.apache.org/repos/asf/couchdb/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb/commit/f0cdb701
Tree: http://git-wip-us.apache.org/repos/asf/couchdb/tree/f0cdb701
Diff: http://git-wip-us.apache.org/repos/asf/couchdb/diff/f0cdb701
Branch: refs/heads/Update-Sidebar-Ui
Commit: f0cdb701d268870a4157d76286269ed6fe4f0ead
Parents: fb59cca
Author: Andy Wenk <an...@apache.org>
Authored: Fri Mar 21 00:22:06 2014 +0100
Committer: Andy Wenk <an...@apache.org>
Committed: Fri Mar 21 00:22:06 2014 +0100
----------------------------------------------------------------------
share/doc/src/intro/overview.rst | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/couchdb/blob/f0cdb701/share/doc/src/intro/overview.rst
----------------------------------------------------------------------
diff --git a/share/doc/src/intro/overview.rst b/share/doc/src/intro/overview.rst
index 4e3b72c..7804cf9 100644
--- a/share/doc/src/intro/overview.rst
+++ b/share/doc/src/intro/overview.rst
@@ -261,9 +261,9 @@ updates, ensuring security and data validation in a shared, distributed system.
Distributed Updates and Replication
===================================
-CouchDB is a peer-based distributed database system, it allows for users and
-servers to access and update the same shared data while disconnected and then
-bi-directionally replicate those changes later.
+CouchDB is a peer-based distributed database system. It allows users and servers
+to access and update the same shared data while disconnected. Those changes can
+then be replicated bi-directionally later.
The CouchDB document storage, view and security models are designed to work
together to make true bi-directional replication efficient and reliable.
[27/41] couchdb commit: updated refs/heads/Update-Sidebar-Ui to
c1e1423
Posted by de...@apache.org.
put back JSON return value in collation example
Originally removed in 0f7be287d6a9358d960beb17b16ad7b5e20bd360
Project: http://git-wip-us.apache.org/repos/asf/couchdb/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb/commit/bea5c947
Tree: http://git-wip-us.apache.org/repos/asf/couchdb/tree/bea5c947
Diff: http://git-wip-us.apache.org/repos/asf/couchdb/diff/bea5c947
Branch: refs/heads/Update-Sidebar-Ui
Commit: bea5c947d1c832f0054ae5d22376ebfbf37a366c
Parents: 35a0303
Author: BigBlueHat <by...@bigbluehat.com>
Authored: Tue Mar 25 16:45:28 2014 -0400
Committer: BigBlueHat <by...@bigbluehat.com>
Committed: Tue Mar 25 16:45:28 2014 -0400
----------------------------------------------------------------------
share/doc/src/couchapp/views/collation.rst | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/couchdb/blob/bea5c947/share/doc/src/couchapp/views/collation.rst
----------------------------------------------------------------------
diff --git a/share/doc/src/couchapp/views/collation.rst b/share/doc/src/couchapp/views/collation.rst
index 06c4c6d..9c2f5c7 100644
--- a/share/doc/src/couchapp/views/collation.rst
+++ b/share/doc/src/couchapp/views/collation.rst
@@ -28,7 +28,7 @@ property serves as the key, thus the result will be sorted by ``LastName``:
function(doc) {
if (doc.Type == "customer") {
- emit(doc.LastName, null);
+ emit(doc.LastName, {FirstName: doc.FirstName, Address: doc.Address});
}
}
[33/41] couchdb commit: updated refs/heads/Update-Sidebar-Ui to
c1e1423
Posted by de...@apache.org.
Fix the build for the d3 update
Project: http://git-wip-us.apache.org/repos/asf/couchdb/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb/commit/c84a71cb
Tree: http://git-wip-us.apache.org/repos/asf/couchdb/tree/c84a71cb
Diff: http://git-wip-us.apache.org/repos/asf/couchdb/diff/c84a71cb
Branch: refs/heads/Update-Sidebar-Ui
Commit: c84a71cb9b3d8fd20fe7b8df0a320152e035d6e2
Parents: 282cddf
Author: suelockwood <de...@apache.org>
Authored: Wed Mar 26 21:12:19 2014 +0100
Committer: suelockwood <de...@apache.org>
Committed: Wed Mar 26 16:48:55 2014 -0400
----------------------------------------------------------------------
src/Makefile.am | 1 +
src/fauxton/app/config.js | 8 ++------
src/fauxton/assets/js/libs/d3.global.js | 18 ++++++++++++++++++
3 files changed, 21 insertions(+), 6 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/couchdb/blob/c84a71cb/src/Makefile.am
----------------------------------------------------------------------
diff --git a/src/Makefile.am b/src/Makefile.am
index e1007f9..ccf6ccd 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -251,6 +251,7 @@ FAUXTON_FILES = \
fauxton/assets/js/libs/backbone.js \
fauxton/assets/js/libs/bootstrap.js \
fauxton/assets/js/libs/d3.js \
+ fauxton/assets/js/libs/d3.global.js \
fauxton/assets/js/libs/jquery.js \
fauxton/assets/js/libs/lodash.js \
fauxton/assets/js/libs/nv.d3.js \
http://git-wip-us.apache.org/repos/asf/couchdb/blob/c84a71cb/src/fauxton/app/config.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/config.js b/src/fauxton/app/config.js
index d33f3b8..3ed1c31 100644
--- a/src/fauxton/app/config.js
+++ b/src/fauxton/app/config.js
@@ -30,7 +30,8 @@ require.config({
spin: "../assets/js/libs/spin.min",
d3: "../assets/js/libs/d3",
"nv.d3": "../assets/js/libs/nv.d3",
- "ace":"../assets/js/libs/ace"
+ "ace":"../assets/js/libs/ace",
+ "d3.global": "../assets/js/libs/d3.global"
},
baseUrl: '/',
@@ -63,8 +64,3 @@ require.config({
}
});
-define("d3.global", ["d3"], function(_) {
- d3 = _;
-});
-
-require(["d3", "nv.d3"], function(d3, nvd3) {});
http://git-wip-us.apache.org/repos/asf/couchdb/blob/c84a71cb/src/fauxton/assets/js/libs/d3.global.js
----------------------------------------------------------------------
diff --git a/src/fauxton/assets/js/libs/d3.global.js b/src/fauxton/assets/js/libs/d3.global.js
new file mode 100644
index 0000000..9f38d04
--- /dev/null
+++ b/src/fauxton/assets/js/libs/d3.global.js
@@ -0,0 +1,18 @@
+// Licensed under the Apache License, Version 2.0 (the "License"); you may not
+// use this file except in compliance with the License. You may obtain a copy of
+// the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
+
+// Set the require.js configuration for your application.
+
+define("d3.global", ["d3"], function(_) {
+ //get that global back
+ d3 = _;
+});
[03/41] couchdb commit: updated refs/heads/Update-Sidebar-Ui to
c1e1423
Posted by de...@apache.org.
Remove Stale for all docs, but keep it for indexes
Project: http://git-wip-us.apache.org/repos/asf/couchdb/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb/commit/65c814a9
Tree: http://git-wip-us.apache.org/repos/asf/couchdb/tree/65c814a9
Diff: http://git-wip-us.apache.org/repos/asf/couchdb/diff/65c814a9
Branch: refs/heads/Update-Sidebar-Ui
Commit: 65c814a9deb12f3c0fcbfc6c742683c3fcc7e08c
Parents: eaaa8f0
Author: suelockwood <de...@apache.org>
Authored: Wed Mar 19 20:30:58 2014 +0100
Committer: suelockwood <de...@apache.org>
Committed: Thu Mar 20 15:06:02 2014 -0400
----------------------------------------------------------------------
.../app/addons/documents/templates/advanced_options.html | 6 ++++++
1 file changed, 6 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/couchdb/blob/65c814a9/src/fauxton/app/addons/documents/templates/advanced_options.html
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/documents/templates/advanced_options.html b/src/fauxton/app/addons/documents/templates/advanced_options.html
index 4ca8f12..8acf30a 100644
--- a/src/fauxton/app/addons/documents/templates/advanced_options.html
+++ b/src/fauxton/app/addons/documents/templates/advanced_options.html
@@ -105,6 +105,12 @@ the License.
<label for="check6">Update Sequence</label>
</div>
+ <% if (showPreview) { %>
+ <div class="checkbox inline">
+ <input id="check7" name="stale" type="checkbox" value="true">
+ <label for="check7">Stale</label>
+ </div>
+ <% } %>
</div>
[04/41] couchdb commit: updated refs/heads/Update-Sidebar-Ui to
c1e1423
Posted by de...@apache.org.
Cleaning up query options UI
null object fix.
Improved key support
initial linking with paginate
Fix linting issue
Project: http://git-wip-us.apache.org/repos/asf/couchdb/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb/commit/eaaa8f06
Tree: http://git-wip-us.apache.org/repos/asf/couchdb/tree/eaaa8f06
Diff: http://git-wip-us.apache.org/repos/asf/couchdb/diff/eaaa8f06
Branch: refs/heads/Update-Sidebar-Ui
Commit: eaaa8f06304bba8b33785168a557ef0f50d3f3ce
Parents: 7dba422
Author: suelockwood <de...@apache.org>
Authored: Wed Mar 19 20:30:58 2014 +0100
Committer: suelockwood <de...@apache.org>
Committed: Thu Mar 20 15:06:02 2014 -0400
----------------------------------------------------------------------
.../addons/documents/assets/less/documents.less | 7 +
.../documents/templates/advanced_options.html | 145 +++++++++++--------
src/fauxton/app/addons/documents/views.js | 91 +++++++++---
3 files changed, 160 insertions(+), 83 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/couchdb/blob/eaaa8f06/src/fauxton/app/addons/documents/assets/less/documents.less
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/documents/assets/less/documents.less b/src/fauxton/app/addons/documents/assets/less/documents.less
index c30a9af..61d864b 100644
--- a/src/fauxton/app/addons/documents/assets/less/documents.less
+++ b/src/fauxton/app/addons/documents/assets/less/documents.less
@@ -23,6 +23,12 @@ button.beautify {
margin-top: 20px;
}
+.toggle-btns {
+ label{
+ margin-right: 0;
+ }
+}
+
#per-page {
float: right;
@@ -32,6 +38,7 @@ button.beautify {
}
+
/** used in all_docs_list.html **/
.view {
table td div {
http://git-wip-us.apache.org/repos/asf/couchdb/blob/eaaa8f06/src/fauxton/app/addons/documents/templates/advanced_options.html
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/documents/templates/advanced_options.html b/src/fauxton/app/addons/documents/templates/advanced_options.html
index e282c62..4ca8f12 100644
--- a/src/fauxton/app/addons/documents/templates/advanced_options.html
+++ b/src/fauxton/app/addons/documents/templates/advanced_options.html
@@ -13,78 +13,103 @@ the License.
-->
<div class="errors-container"></div>
<form class="js-view-query-update custom-inputs">
- <div class="controls-group">
- <div class="row-fluid">
+
+<!-- tabs for choosing Keys or Start & end -->
+
+ <div class="btn-group toggle-btns">
+ <label for="showKeys" class="drop-down btn active">
+ Specific Keys
+ </label>
+ <label for="showStartEnd" class="drop-down btn">
+ Bounded Queries
+ </label>
+ </div>
+
+ <div class="controls-group well">
+ <div class="row-fluid" id="js-showKeys">
<div class="controls controls-row">
- <input name="key" class="span6" type="text" placeholder="Key">
- <input name="keys" class="span6" type="text" placeholder="Keys">
+ <input name="keys" class="input-xxlarge" type="text" placeholder="Enter a key, an array of keys. This must be valid JSON.">
</div>
</div>
- <div class="row-fluid">
+ <div class="row-fluid hide" id="js-showStartEnd">
<div class="controls controls-row">
- <input name="startkey" class="span6" type="text" placeholder="Start Key">
+ <input name="startkey" class="span6" type="text" placeholder="Start Key" disabled>
<input name="endkey" class="span6" type="text" placeholder="End Key">
</div>
+ <div class="controls controls-row checkbox inline">
+ <input id="check5" name="inclusive_end" type="checkbox" value="false" disabled>
+ <label for="check5">Disable Inclusive End</label>
+ </div>
</div>
</div>
+
+<!-- Limit and Skip are conditional -->
+
<div class="controls-group">
- <div class="row-fluid">
- <div class="controls controls-row">
- <div class="checkbox inline">
- <input id="check1" type="checkbox" name="include_docs" value="true">
- <label name="include_docs" for="check1">Include Docs</label>
- <% if (hasReduce) { %>
- <input id="check2" name="reduce" type="checkbox" value="true">
- <label for="check2">Reduce</label>
- </div>
- <label id="select1" class="drop-down inline">
- Group Level:
- <select id="select1" disabled name="group_level" class="input-small">
- <option value="0">None</option>
- <option value="1">1</option>
- <option value="2">2</option>
- <option value="3">3</option>
- <option value="4">4</option>
- <option value="5">5</option>
- <option value="6">6</option>
- <option value="7">7</option>
- <option value="8">8</option>
- <option value="9">9</option>
- <option value="999" selected="selected">exact</option>
- </select>
- </label>
- <% } else{ %>
- </div>
- <% } %>
+ <label class="drop-down inline">
+ Limit:
+ <select name="limit" class="input-small" disabled>
+ <option>5</option>
+ <option>10</option>
+ <option selected="selected">20</option>
+ <option>30</option>
+ <option>50</option>
+ <option>100</option>
+ <option>500</option>
+ </select>
+ </label>
+ <label for="skipRows" class="inline drop-down">
+ Skip
+ <input name="skip" class="input-large" type="text" id="skipRows" disabled placeholder="Number of rows to skip">
+ </label>
+ <span class="js-disabled-message"> Limit & and Skip are disabled when using Keys.</span>
- <div class="checkbox inline">
- <input id="check3" name="stale" type="checkbox" value="ok">
- <label for="check3">Stale</label>
- <input id="check4" name="descending" type="checkbox" value="true">
- <label for="check4">Descending</label>
- </div>
- <label class="drop-down inline">
- Limit:
- <select name="limit" class="input-small">
- <option>5</option>
- <option>10</option>
- <option >20</option>
- <option>30</option>
- <option>50</option>
- <option >100</option>
- <option>500</option>
- <option selected="selected">None</option>
- </select>
- </label>
- <div class="checkbox inline">
- <input id="check5" name="inclusive_end" type="checkbox" value="false">
- <label for="check5">Disable Inclusive End</label>
- <input id="check6" name="update_seq" type="checkbox" value="true">
- <label for="check6">Update Sequence</label>
- </div>
+ <div class="checkbox inline">
+ <input id="check1" type="checkbox" name="include_docs" value="true">
+ <label name="include_docs" for="check1">Include Docs (show the entire doc body)</label>
</div>
- </div>
+
+ <% if (hasReduce) { %>
+ <div class="checkbox inline">
+ <input id="check2" name="reduce" type="checkbox" value="true">
+ <label for="check2">Reduce</label>
+ </div>
+ <label id="select1" class="drop-down inline">
+ Group Level:
+ <select id="select1" disabled name="group_level" class="input-small">
+ <option value="0">None</option>
+ <option value="1">1</option>
+ <option value="2">2</option>
+ <option value="3">3</option>
+ <option value="4">4</option>
+ <option value="5">5</option>
+ <option value="6">6</option>
+ <option value="7">7</option>
+ <option value="8">8</option>
+ <option value="9">9</option>
+ <option value="999" selected="selected">exact</option>
+ </select>
+ </label>
+ <% } %>
+
+ <label id="select2" class="drop-down inline">
+ Order:
+ <select id="select2" name="descending" class="input-large">
+ <option value="false">Accending</option>
+ <option value="true">Descending</option>
+ </select>
+ </label>
+
+ <div class="checkbox inline">
+ <input id="check6" name="update_seq" type="checkbox" value="true">
+ <label for="check6">Update Sequence</label>
+ </div>
+
</div>
+
+
+
+
<div class="controls-group">
<div class="row-fluid">
<div id="button-options" class="controls controls-row">
http://git-wip-us.apache.org/repos/asf/couchdb/blob/eaaa8f06/src/fauxton/app/addons/documents/views.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/documents/views.js b/src/fauxton/app/addons/documents/views.js
index f29ebaa..1e7addf 100644
--- a/src/fauxton/app/addons/documents/views.js
+++ b/src/fauxton/app/addons/documents/views.js
@@ -335,7 +335,8 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
this.model.destroy().then(function(resp) {
FauxtonAPI.addNotification({
- msg: "Succesfully destroyed your doc"
+ msg: "Succesfully destroyed your doc",
+ clear: true
});
that.$el.fadeOut(function () {
that.remove();
@@ -348,7 +349,8 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
}, function(resp) {
FauxtonAPI.addNotification({
msg: "Failed to destroy your doc!",
- type: "error"
+ type: "error",
+ clear: true
});
});
}
@@ -518,13 +520,15 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
return FauxtonAPI.addNotification({
msg: "JSON Parse Error on field: "+param.name,
type: "error",
- selector: ".advanced-options .errors-container"
+ selector: ".advanced-options .errors-container",
+ clear: true
});
});
FauxtonAPI.addNotification({
msg: "Make sure that strings are properly quoted and any other values are valid JSON structures",
type: "warning",
- selector: ".advanced-options .errors-container"
+ selector: ".advanced-options .errors-container",
+ clear: true
});
return false;
@@ -580,7 +584,7 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
this.ddocID = options.ddocInfo.id;
}
this.newView = options.newView || false;
- this.docParams = options.docParams;
+ this.docParams = options.docParams || {};
this.params = options.params || {};
this.expandDocs = true;
this.perPageDefault = this.docParams.limit || 20;
@@ -597,7 +601,8 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
// This should just throw a notification, not break the page
FauxtonAPI.addNotification({
msg: "Bad Request",
- type: "error"
+ type: "error",
+ clear: true
});
//now redirect back to alldocs
@@ -668,7 +673,8 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
}, function(resp) {
FauxtonAPI.addNotification({
msg: "Failed to destroy your doc!",
- type: "error"
+ type: "error",
+ clear: true
});
});
}, this);
@@ -771,7 +777,8 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
if (this.model.isNewDoc()) {
FauxtonAPI.addNotification({
msg: 'This document has not been saved yet.',
- type: 'warning'
+ type: 'warning',
+ clear: true
});
return;
}
@@ -784,13 +791,15 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
this.model.destroy().then(function(resp) {
FauxtonAPI.addNotification({
- msg: "Succesfully destroyed your doc"
+ msg: "Succesfully destroyed your doc",
+ clear: true
});
FauxtonAPI.navigate(database.url("index"));
}, function(resp) {
FauxtonAPI.addNotification({
msg: "Failed to destroy your doc!",
- type: "error"
+ type: "error",
+ clear: true
});
});
},
@@ -808,7 +817,8 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
if (this.model.isNewDoc()) {
FauxtonAPI.addNotification({
msg: 'Please save the document before uploading an attachment.',
- type: 'warning'
+ type: 'warning',
+ clear: true
});
return;
}
@@ -819,7 +829,8 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
if (this.model.isNewDoc()) {
FauxtonAPI.addNotification({
msg: 'Please save the document before duplicating it.',
- type: 'warning'
+ type: 'warning',
+ clear: true
});
return;
}
@@ -891,14 +902,16 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
notification = FauxtonAPI.addNotification({
msg: "Cannot save: " + 'Cannot change a documents _id, try Duplicate doc instead!',
type: "error",
- selector: "#doc .errors-container"
+ selector: "#doc .errors-container",
+ clear: true
});
delete this.model.validationError;
} else {
notification = FauxtonAPI.addNotification({
msg: "Please fix the JSON errors and try again.",
type: "error",
- selector: "#doc .errors-container"
+ selector: "#doc .errors-container",
+ clear: true
});
}
},
@@ -988,7 +1001,8 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
editor.setValue(JSON.stringify(changedDoc, null, " "));
FauxtonAPI.addNotification({
type: "error",
- msg: "Cannot remove a documents Id or Revision."
+ msg: "Cannot remove a documents Id or Revision.",
+ clear: true
});
});
},
@@ -1008,7 +1022,8 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
saveDoc: function(event) {
FauxtonAPI.addNotification({
type: "warning",
- msg: "Save functionality coming soon."
+ msg: "Save functionality coming soon.",
+ clear: true
});
},
@@ -1073,7 +1088,34 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
"change form.js-view-query-update input": "updateFilters",
"change form.js-view-query-update select": "updateFilters",
"submit form.js-view-query-update": "updateView",
- "click button.preview": "previewView"
+ "click button.preview": "previewView",
+ "click .toggle-btns > label": "toggleQuery"
+ },
+
+ toggleQuery: function(e){
+ e.preventDefault();
+ var showFunctionName =this.$(e.currentTarget).attr("for");
+ //highlight current
+ this.$(".toggle-btns > label").removeClass('active');
+ this.$(e.currentTarget).addClass("active");
+
+ this.$("[id^='js-show']").hide();
+
+ //show section & disable what needs to be disabled
+ this[showFunctionName]();
+ },
+
+ showKeys: function(){
+ this.$("#js-showKeys, .js-disabled-message").show();
+ this.$('[name="skip"],[name="startkey"],[name="limit"],[name="endkey"],[name="inclusive_end"]').attr("disabled","true");
+ this.$('[name="keys"]').removeAttr("disabled");
+ },
+
+ showStartEnd: function(){
+ this.$("#js-showStartEnd").show();
+ this.$('[name="skip"],[name="startkey"],[name="limit"],[name="endkey"],[name="inclusive_end"]').removeAttr("disabled");
+ this.$('.js-disabled-message').hide();
+ this.$('[name="keys"]').attr("disabled","true");
},
beforeRender: function () {
@@ -1090,20 +1132,21 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
this.hasReduce = hasReduce;
this.render();
},
-
+ validateKeys: function(val){
+ return JSON.parse(val);
+ },
queryParams: function () {
var $form = this.$(".js-view-query-update");
- // Ignore params without a value
+
var params = _.reduce($form.serializeArray(), function(params, param) {
if (!param.value) { return params; }
if (param.name === "limit" && param.value === 'None') { return params; }
-
params.push(param);
return params;
}, []);
// Validate *key* params to ensure they're valid JSON
- var keyParams = ["key","keys","startkey","endkey"];
+ var keyParams = ["keys","startkey","endkey"];
var errorParams = _.filter(params, function(param) {
if (_.contains(keyParams, param.name)) {
try {
@@ -1140,7 +1183,8 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
var notification = FauxtonAPI.addNotification({
msg: "include_docs has been disabled as you cannot include docs on a reduced view",
type: "warn",
- selector: ".view.show .all-docs-list.errors-container"
+ selector: ".view.show .all-docs-list.errors-container",
+ clear: true
});
}
$form.find("input[name=include_docs]").prop("disabled", true);
@@ -1161,13 +1205,13 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
var $ele;
switch (key) {
case "limit":
+ case "descending":
case "group_level":
if (!val) { return; }
$form.find("select[name='"+key+"']").val(val);
break;
case "include_docs":
case "stale":
- case "descending":
case "inclusive_end":
$form.find("input[name='"+key+"']").prop('checked', true);
break;
@@ -1186,6 +1230,7 @@ function(app, FauxtonAPI, Components, Documents, Databases, pouchdb, resizeColum
},
updateView: function (event) {
+ event.preventDefault();
this.updateViewFn(event, this.queryParams());
},
[15/41] couchdb commit: updated refs/heads/Update-Sidebar-Ui to
c1e1423
Posted by de...@apache.org.
fix documentation
explain why the HTTP status code 400 will be returned when ?rev=
is included in the request URL
Project: http://git-wip-us.apache.org/repos/asf/couchdb/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb/commit/29256149
Tree: http://git-wip-us.apache.org/repos/asf/couchdb/tree/29256149
Diff: http://git-wip-us.apache.org/repos/asf/couchdb/diff/29256149
Branch: refs/heads/Update-Sidebar-Ui
Commit: 29256149029714af6379dadd62022ee6f46b58ec
Parents: ebbee3c
Author: Andy Wenk <an...@nms.de>
Authored: Fri Mar 21 22:57:04 2014 +0100
Committer: Andy Wenk <an...@nms.de>
Committed: Fri Mar 21 22:57:04 2014 +0100
----------------------------------------------------------------------
share/doc/src/api/database/common.rst | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/couchdb/blob/29256149/share/doc/src/api/database/common.rst
----------------------------------------------------------------------
diff --git a/share/doc/src/api/database/common.rst b/share/doc/src/api/database/common.rst
index f715c70..a1483d9 100644
--- a/share/doc/src/api/database/common.rst
+++ b/share/doc/src/api/database/common.rst
@@ -223,6 +223,12 @@
Deletes the specified database, and all the documents and attachments
contained within it.
+ .. note::
+
+ To avoid deleting a database, CouchDB will respond with the HTTP status code 400
+ when the request URL includes a ?rev= parameter. This suggests that one wants to delete
+ a document but forgot to add the document id to the URL.
+
:param db: Database name
:<header Accept: - :mimetype:`application/json`
- :mimetype:`text/plain`
@@ -230,7 +236,7 @@
- :mimetype:`text/plain; charset=utf-8`
:>json boolean ok: Operation status
:code 200: Database removed successfully
- :code 400: Invalid database name
+ :code 400: Invalid database name or forgotten document id by accident
:code 401: CouchDB Server Administrator privileges required
:code 404: Database doesn't exist
[11/41] couchdb commit: updated refs/heads/Update-Sidebar-Ui to
c1e1423
Posted by de...@apache.org.
Fauxton: Config test fixes
Project: http://git-wip-us.apache.org/repos/asf/couchdb/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb/commit/35390c83
Tree: http://git-wip-us.apache.org/repos/asf/couchdb/tree/35390c83
Diff: http://git-wip-us.apache.org/repos/asf/couchdb/diff/35390c83
Branch: refs/heads/Update-Sidebar-Ui
Commit: 35390c833333a7b5935b34da47be9a1696c845f7
Parents: f2153c0
Author: Robert Kowalski <ro...@kowalski.gd>
Authored: Fri Mar 21 17:49:15 2014 +0100
Committer: suelockwood <de...@apache.org>
Committed: Fri Mar 21 13:35:43 2014 -0400
----------------------------------------------------------------------
.../app/addons/config/tests/resourcesSpec.js | 20 ++++++++--
src/fauxton/app/addons/config/views.js | 39 ++++++++++----------
2 files changed, 36 insertions(+), 23 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/couchdb/blob/35390c83/src/fauxton/app/addons/config/tests/resourcesSpec.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/config/tests/resourcesSpec.js b/src/fauxton/app/addons/config/tests/resourcesSpec.js
index c78bc85..1cc9e62 100644
--- a/src/fauxton/app/addons/config/tests/resourcesSpec.js
+++ b/src/fauxton/app/addons/config/tests/resourcesSpec.js
@@ -28,7 +28,10 @@ define([
});
tabMenu = new Views.TableRow({
- model: optionModel
+ model: optionModel,
+ uniqueName: function () {
+ return false;
+ }
});
});
@@ -47,8 +50,12 @@ define([
var renderSpy = sinon.stub(tabMenu, 'render');
var saveSpy = sinon.stub(optionModel, 'save');
- tabMenu.$('.js-edit-value').trigger('dblclick');
- tabMenu.$('.js-save-value').trigger('click');
+ var $fields = tabMenu.$('.js-edit-value').filter(function (el) {
+ return $(this).find('[name="value"]').length;
+ });
+
+ $fields.find('.js-edit-value').trigger('dblclick');
+ $fields.find('.js-save-value').trigger('click');
assert.ok(renderSpy.calledOnce);
assert.ok(saveSpy.calledOnce);
@@ -60,7 +67,12 @@ define([
var e = $.Event("keyup");
e.keyCode = 13;
- tabMenu.$('.js-value-input').trigger(e);
+
+ var $fields = tabMenu.$('.js-edit-value').filter(function (el) {
+ return $(this).find('[name="value"]').length;
+ });
+
+ $fields.find('.js-value-input').trigger(e);
assert.ok(renderSpy.calledOnce);
assert.ok(saveSpy.calledOnce);
http://git-wip-us.apache.org/repos/asf/couchdb/blob/35390c83/src/fauxton/app/addons/config/views.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/config/views.js b/src/fauxton/app/addons/config/views.js
index 8453d90..7952182 100644
--- a/src/fauxton/app/addons/config/views.js
+++ b/src/fauxton/app/addons/config/views.js
@@ -80,28 +80,29 @@ function(app, FauxtonAPI, Config, Components) {
return {option: this.model.toJSON()};
},
saveAndRender: function (event) {
- var options = {};
- $input = this.$(event.currentTarget).parents('td').find(".js-value-input");
- options[$input.attr('name')] = $input.val();
-
- if ($input.attr('name')==='name'){
- if (this.uniqueName($input.val())){
- this.error = FauxtonAPI.addNotification({
- msg: "This config already exists, enter a unique name",
- type: "error",
- clear: true
- });
- } else {
- var newModel = this.model.clone();
- newModel.save(options);
- this.model.destroy();
- this.model = newModel;
- this.render();
- }
+ var options = {},
+ $input = this.$(event.currentTarget).parents('td').find(".js-value-input");
+
+ options[$input.attr('name')] = $input.val();
+
+ if ($input.attr('name')==='name'){
+ if (this.uniqueName($input.val())){
+ this.error = FauxtonAPI.addNotification({
+ msg: "This config already exists, enter a unique name",
+ type: "error",
+ clear: true
+ });
} else {
+ var newModel = this.model.clone();
+ newModel.save(options);
+ this.model.destroy();
+ this.model = newModel;
+ this.render();
+ }
+ } else {
this.model.save(options);
this.render();
- }
+ }
}
});
[21/41] Updating d3 to v3.4.3 and nv.d3 to v1.1.15
Posted by de...@apache.org.
http://git-wip-us.apache.org/repos/asf/couchdb/blob/95d6d6b0/src/fauxton/assets/js/libs/d3.js
----------------------------------------------------------------------
diff --git a/src/fauxton/assets/js/libs/d3.js b/src/fauxton/assets/js/libs/d3.js
index 44fc0b0..b57c8d0 100644
--- a/src/fauxton/assets/js/libs/d3.js
+++ b/src/fauxton/assets/js/libs/d3.js
@@ -1,4 +1,223 @@
-(function() {
+!function() {
+ var d3 = {
+ version: "3.4.3"
+ };
+ if (!Date.now) Date.now = function() {
+ return +new Date();
+ };
+ var d3_arraySlice = [].slice, d3_array = function(list) {
+ return d3_arraySlice.call(list);
+ };
+ var d3_document = document, d3_documentElement = d3_document.documentElement, d3_window = window;
+ try {
+ d3_array(d3_documentElement.childNodes)[0].nodeType;
+ } catch (e) {
+ d3_array = function(list) {
+ var i = list.length, array = new Array(i);
+ while (i--) array[i] = list[i];
+ return array;
+ };
+ }
+ try {
+ d3_document.createElement("div").style.setProperty("opacity", 0, "");
+ } catch (error) {
+ var d3_element_prototype = d3_window.Element.prototype, d3_element_setAttribute = d3_element_prototype.setAttribute, d3_element_setAttributeNS = d3_element_prototype.setAttributeNS, d3_style_prototype = d3_window.CSSStyleDeclaration.prototype, d3_style_setProperty = d3_style_prototype.setProperty;
+ d3_element_prototype.setAttribute = function(name, value) {
+ d3_element_setAttribute.call(this, name, value + "");
+ };
+ d3_element_prototype.setAttributeNS = function(space, local, value) {
+ d3_element_setAttributeNS.call(this, space, local, value + "");
+ };
+ d3_style_prototype.setProperty = function(name, value, priority) {
+ d3_style_setProperty.call(this, name, value + "", priority);
+ };
+ }
+ d3.ascending = function(a, b) {
+ return a < b ? -1 : a > b ? 1 : a >= b ? 0 : NaN;
+ };
+ d3.descending = function(a, b) {
+ return b < a ? -1 : b > a ? 1 : b >= a ? 0 : NaN;
+ };
+ d3.min = function(array, f) {
+ var i = -1, n = array.length, a, b;
+ if (arguments.length === 1) {
+ while (++i < n && !((a = array[i]) != null && a <= a)) a = undefined;
+ while (++i < n) if ((b = array[i]) != null && a > b) a = b;
+ } else {
+ while (++i < n && !((a = f.call(array, array[i], i)) != null && a <= a)) a = undefined;
+ while (++i < n) if ((b = f.call(array, array[i], i)) != null && a > b) a = b;
+ }
+ return a;
+ };
+ d3.max = function(array, f) {
+ var i = -1, n = array.length, a, b;
+ if (arguments.length === 1) {
+ while (++i < n && !((a = array[i]) != null && a <= a)) a = undefined;
+ while (++i < n) if ((b = array[i]) != null && b > a) a = b;
+ } else {
+ while (++i < n && !((a = f.call(array, array[i], i)) != null && a <= a)) a = undefined;
+ while (++i < n) if ((b = f.call(array, array[i], i)) != null && b > a) a = b;
+ }
+ return a;
+ };
+ d3.extent = function(array, f) {
+ var i = -1, n = array.length, a, b, c;
+ if (arguments.length === 1) {
+ while (++i < n && !((a = c = array[i]) != null && a <= a)) a = c = undefined;
+ while (++i < n) if ((b = array[i]) != null) {
+ if (a > b) a = b;
+ if (c < b) c = b;
+ }
+ } else {
+ while (++i < n && !((a = c = f.call(array, array[i], i)) != null && a <= a)) a = undefined;
+ while (++i < n) if ((b = f.call(array, array[i], i)) != null) {
+ if (a > b) a = b;
+ if (c < b) c = b;
+ }
+ }
+ return [ a, c ];
+ };
+ d3.sum = function(array, f) {
+ var s = 0, n = array.length, a, i = -1;
+ if (arguments.length === 1) {
+ while (++i < n) if (!isNaN(a = +array[i])) s += a;
+ } else {
+ while (++i < n) if (!isNaN(a = +f.call(array, array[i], i))) s += a;
+ }
+ return s;
+ };
+ function d3_number(x) {
+ return x != null && !isNaN(x);
+ }
+ d3.mean = function(array, f) {
+ var n = array.length, a, m = 0, i = -1, j = 0;
+ if (arguments.length === 1) {
+ while (++i < n) if (d3_number(a = array[i])) m += (a - m) / ++j;
+ } else {
+ while (++i < n) if (d3_number(a = f.call(array, array[i], i))) m += (a - m) / ++j;
+ }
+ return j ? m : undefined;
+ };
+ d3.quantile = function(values, p) {
+ var H = (values.length - 1) * p + 1, h = Math.floor(H), v = +values[h - 1], e = H - h;
+ return e ? v + e * (values[h] - v) : v;
+ };
+ d3.median = function(array, f) {
+ if (arguments.length > 1) array = array.map(f);
+ array = array.filter(d3_number);
+ return array.length ? d3.quantile(array.sort(d3.ascending), .5) : undefined;
+ };
+ d3.bisector = function(f) {
+ return {
+ left: function(a, x, lo, hi) {
+ if (arguments.length < 3) lo = 0;
+ if (arguments.length < 4) hi = a.length;
+ while (lo < hi) {
+ var mid = lo + hi >>> 1;
+ if (f.call(a, a[mid], mid) < x) lo = mid + 1; else hi = mid;
+ }
+ return lo;
+ },
+ right: function(a, x, lo, hi) {
+ if (arguments.length < 3) lo = 0;
+ if (arguments.length < 4) hi = a.length;
+ while (lo < hi) {
+ var mid = lo + hi >>> 1;
+ if (x < f.call(a, a[mid], mid)) hi = mid; else lo = mid + 1;
+ }
+ return lo;
+ }
+ };
+ };
+ var d3_bisector = d3.bisector(function(d) {
+ return d;
+ });
+ d3.bisectLeft = d3_bisector.left;
+ d3.bisect = d3.bisectRight = d3_bisector.right;
+ d3.shuffle = function(array) {
+ var m = array.length, t, i;
+ while (m) {
+ i = Math.random() * m-- | 0;
+ t = array[m], array[m] = array[i], array[i] = t;
+ }
+ return array;
+ };
+ d3.permute = function(array, indexes) {
+ var i = indexes.length, permutes = new Array(i);
+ while (i--) permutes[i] = array[indexes[i]];
+ return permutes;
+ };
+ d3.pairs = function(array) {
+ var i = 0, n = array.length - 1, p0, p1 = array[0], pairs = new Array(n < 0 ? 0 : n);
+ while (i < n) pairs[i] = [ p0 = p1, p1 = array[++i] ];
+ return pairs;
+ };
+ d3.zip = function() {
+ if (!(n = arguments.length)) return [];
+ for (var i = -1, m = d3.min(arguments, d3_zipLength), zips = new Array(m); ++i < m; ) {
+ for (var j = -1, n, zip = zips[i] = new Array(n); ++j < n; ) {
+ zip[j] = arguments[j][i];
+ }
+ }
+ return zips;
+ };
+ function d3_zipLength(d) {
+ return d.length;
+ }
+ d3.transpose = function(matrix) {
+ return d3.zip.apply(d3, matrix);
+ };
+ d3.keys = function(map) {
+ var keys = [];
+ for (var key in map) keys.push(key);
+ return keys;
+ };
+ d3.values = function(map) {
+ var values = [];
+ for (var key in map) values.push(map[key]);
+ return values;
+ };
+ d3.entries = function(map) {
+ var entries = [];
+ for (var key in map) entries.push({
+ key: key,
+ value: map[key]
+ });
+ return entries;
+ };
+ d3.merge = function(arrays) {
+ var n = arrays.length, m, i = -1, j = 0, merged, array;
+ while (++i < n) j += arrays[i].length;
+ merged = new Array(j);
+ while (--n >= 0) {
+ array = arrays[n];
+ m = array.length;
+ while (--m >= 0) {
+ merged[--j] = array[m];
+ }
+ }
+ return merged;
+ };
+ var abs = Math.abs;
+ d3.range = function(start, stop, step) {
+ if (arguments.length < 3) {
+ step = 1;
+ if (arguments.length < 2) {
+ stop = start;
+ start = 0;
+ }
+ }
+ if ((stop - start) / step === Infinity) throw new Error("infinite range");
+ var range = [], k = d3_range_integerScale(abs(step)), i = -1, j;
+ start *= k, stop *= k, step *= k;
+ if (step < 0) while ((j = start + step * ++i) > stop) range.push(j / k); else while ((j = start + step * ++i) < stop) range.push(j / k);
+ return range;
+ };
+ function d3_range_integerScale(x) {
+ var k = 1;
+ while (x * k % 1) k *= 10;
+ return k;
+ }
function d3_class(ctor, properties) {
try {
for (var key in properties) {
@@ -11,60 +230,206 @@
ctor.prototype = properties;
}
}
- function d3_arrayCopy(pseudoarray) {
- var i = -1, n = pseudoarray.length, array = [];
- while (++i < n) array.push(pseudoarray[i]);
- return array;
+ d3.map = function(object) {
+ var map = new d3_Map();
+ if (object instanceof d3_Map) object.forEach(function(key, value) {
+ map.set(key, value);
+ }); else for (var key in object) map.set(key, object[key]);
+ return map;
+ };
+ function d3_Map() {}
+ d3_class(d3_Map, {
+ has: d3_map_has,
+ get: function(key) {
+ return this[d3_map_prefix + key];
+ },
+ set: function(key, value) {
+ return this[d3_map_prefix + key] = value;
+ },
+ remove: d3_map_remove,
+ keys: d3_map_keys,
+ values: function() {
+ var values = [];
+ this.forEach(function(key, value) {
+ values.push(value);
+ });
+ return values;
+ },
+ entries: function() {
+ var entries = [];
+ this.forEach(function(key, value) {
+ entries.push({
+ key: key,
+ value: value
+ });
+ });
+ return entries;
+ },
+ size: d3_map_size,
+ empty: d3_map_empty,
+ forEach: function(f) {
+ for (var key in this) if (key.charCodeAt(0) === d3_map_prefixCode) f.call(this, key.substring(1), this[key]);
+ }
+ });
+ var d3_map_prefix = "\x00", d3_map_prefixCode = d3_map_prefix.charCodeAt(0);
+ function d3_map_has(key) {
+ return d3_map_prefix + key in this;
}
- function d3_arraySlice(pseudoarray) {
- return Array.prototype.slice.call(pseudoarray);
+ function d3_map_remove(key) {
+ key = d3_map_prefix + key;
+ return key in this && delete this[key];
}
- function d3_Map() {}
- function d3_identity(d) {
- return d;
+ function d3_map_keys() {
+ var keys = [];
+ this.forEach(function(key) {
+ keys.push(key);
+ });
+ return keys;
}
- function d3_this() {
- return this;
+ function d3_map_size() {
+ var size = 0;
+ for (var key in this) if (key.charCodeAt(0) === d3_map_prefixCode) ++size;
+ return size;
}
- function d3_true() {
+ function d3_map_empty() {
+ for (var key in this) if (key.charCodeAt(0) === d3_map_prefixCode) return false;
return true;
}
- function d3_functor(v) {
- return typeof v === "function" ? v : function() {
- return v;
+ d3.nest = function() {
+ var nest = {}, keys = [], sortKeys = [], sortValues, rollup;
+ function map(mapType, array, depth) {
+ if (depth >= keys.length) return rollup ? rollup.call(nest, array) : sortValues ? array.sort(sortValues) : array;
+ var i = -1, n = array.length, key = keys[depth++], keyValue, object, setter, valuesByKey = new d3_Map(), values;
+ while (++i < n) {
+ if (values = valuesByKey.get(keyValue = key(object = array[i]))) {
+ values.push(object);
+ } else {
+ valuesByKey.set(keyValue, [ object ]);
+ }
+ }
+ if (mapType) {
+ object = mapType();
+ setter = function(keyValue, values) {
+ object.set(keyValue, map(mapType, values, depth));
+ };
+ } else {
+ object = {};
+ setter = function(keyValue, values) {
+ object[keyValue] = map(mapType, values, depth);
+ };
+ }
+ valuesByKey.forEach(setter);
+ return object;
+ }
+ function entries(map, depth) {
+ if (depth >= keys.length) return map;
+ var array = [], sortKey = sortKeys[depth++];
+ map.forEach(function(key, keyMap) {
+ array.push({
+ key: key,
+ values: entries(keyMap, depth)
+ });
+ });
+ return sortKey ? array.sort(function(a, b) {
+ return sortKey(a.key, b.key);
+ }) : array;
+ }
+ nest.map = function(array, mapType) {
+ return map(mapType, array, 0);
};
- }
- function d3_rebind(target, source, method) {
- return function() {
- var value = method.apply(source, arguments);
- return arguments.length ? target : value;
+ nest.entries = function(array) {
+ return entries(map(d3.map, array, 0), 0);
};
+ nest.key = function(d) {
+ keys.push(d);
+ return nest;
+ };
+ nest.sortKeys = function(order) {
+ sortKeys[keys.length - 1] = order;
+ return nest;
+ };
+ nest.sortValues = function(order) {
+ sortValues = order;
+ return nest;
+ };
+ nest.rollup = function(f) {
+ rollup = f;
+ return nest;
+ };
+ return nest;
+ };
+ d3.set = function(array) {
+ var set = new d3_Set();
+ if (array) for (var i = 0, n = array.length; i < n; ++i) set.add(array[i]);
+ return set;
+ };
+ function d3_Set() {}
+ d3_class(d3_Set, {
+ has: d3_map_has,
+ add: function(value) {
+ this[d3_map_prefix + value] = true;
+ return value;
+ },
+ remove: function(value) {
+ value = d3_map_prefix + value;
+ return value in this && delete this[value];
+ },
+ values: d3_map_keys,
+ size: d3_map_size,
+ empty: d3_map_empty,
+ forEach: function(f) {
+ for (var value in this) if (value.charCodeAt(0) === d3_map_prefixCode) f.call(this, value.substring(1));
+ }
+ });
+ d3.behavior = {};
+ d3.rebind = function(target, source) {
+ var i = 1, n = arguments.length, method;
+ while (++i < n) target[method = arguments[i]] = d3_rebind(target, source, source[method]);
+ return target;
+ };
+ function d3_rebind(target, source, method) {
+ return function() {
+ var value = method.apply(source, arguments);
+ return value === source ? target : value;
+ };
+ }
+ function d3_vendorSymbol(object, name) {
+ if (name in object) return name;
+ name = name.charAt(0).toUpperCase() + name.substring(1);
+ for (var i = 0, n = d3_vendorPrefixes.length; i < n; ++i) {
+ var prefixName = d3_vendorPrefixes[i] + name;
+ if (prefixName in object) return prefixName;
+ }
}
- function d3_number(x) {
- return x != null && !isNaN(x);
- }
- function d3_zipLength(d) {
- return d.length;
- }
- function d3_splitter(d) {
- return d == null;
- }
- function d3_collapse(s) {
- return s.trim().replace(/\s+/g, " ");
- }
- function d3_range_integerScale(x) {
- var k = 1;
- while (x * k % 1) k *= 10;
- return k;
- }
+ var d3_vendorPrefixes = [ "webkit", "ms", "moz", "Moz", "o", "O" ];
+ function d3_noop() {}
+ d3.dispatch = function() {
+ var dispatch = new d3_dispatch(), i = -1, n = arguments.length;
+ while (++i < n) dispatch[arguments[i]] = d3_dispatch_event(dispatch);
+ return dispatch;
+ };
function d3_dispatch() {}
+ d3_dispatch.prototype.on = function(type, listener) {
+ var i = type.indexOf("."), name = "";
+ if (i >= 0) {
+ name = type.substring(i + 1);
+ type = type.substring(0, i);
+ }
+ if (type) return arguments.length < 2 ? this[type].on(name) : this[type].on(name, listener);
+ if (arguments.length === 2) {
+ if (listener == null) for (type in this) {
+ if (this.hasOwnProperty(type)) this[type].on(name, null);
+ }
+ return this;
+ }
+ };
function d3_dispatch_event(dispatch) {
+ var listeners = [], listenerByName = new d3_Map();
function event() {
var z = listeners, i = -1, n = z.length, l;
while (++i < n) if (l = z[i].on) l.apply(this, arguments);
return dispatch;
}
- var listeners = [], listenerByName = new d3_Map;
event.on = function(name, listener) {
var l = listenerByName.get(name), i;
if (arguments.length < 2) return l && l.on;
@@ -80,82 +445,8 @@
};
return event;
}
- function d3_format_precision(x, p) {
- return p - (x ? 1 + Math.floor(Math.log(x + Math.pow(10, 1 + Math.floor(Math.log(x) / Math.LN10) - p)) / Math.LN10) : 1);
- }
- function d3_format_typeDefault(x) {
- return x + "";
- }
- function d3_format_group(value) {
- var i = value.lastIndexOf("."), f = i >= 0 ? value.substring(i) : (i = value.length, ""), t = [];
- while (i > 0) t.push(value.substring(i -= 3, i + 3));
- return t.reverse().join(",") + f;
- }
- function d3_formatPrefix(d, i) {
- var k = Math.pow(10, Math.abs(8 - i) * 3);
- return {
- scale: i > 8 ? function(d) {
- return d / k;
- } : function(d) {
- return d * k;
- },
- symbol: d
- };
- }
- function d3_ease_clamp(f) {
- return function(t) {
- return t <= 0 ? 0 : t >= 1 ? 1 : f(t);
- };
- }
- function d3_ease_reverse(f) {
- return function(t) {
- return 1 - f(1 - t);
- };
- }
- function d3_ease_reflect(f) {
- return function(t) {
- return .5 * (t < .5 ? f(2 * t) : 2 - f(2 - 2 * t));
- };
- }
- function d3_ease_identity(t) {
- return t;
- }
- function d3_ease_poly(e) {
- return function(t) {
- return Math.pow(t, e);
- };
- }
- function d3_ease_sin(t) {
- return 1 - Math.cos(t * Math.PI / 2);
- }
- function d3_ease_exp(t) {
- return Math.pow(2, 10 * (t - 1));
- }
- function d3_ease_circle(t) {
- return 1 - Math.sqrt(1 - t * t);
- }
- function d3_ease_elastic(a, p) {
- var s;
- if (arguments.length < 2) p = .45;
- if (arguments.length < 1) {
- a = 1;
- s = p / 4;
- } else s = p / (2 * Math.PI) * Math.asin(1 / a);
- return function(t) {
- return 1 + a * Math.pow(2, 10 * -t) * Math.sin((t - s) * 2 * Math.PI / p);
- };
- }
- function d3_ease_back(s) {
- if (!s) s = 1.70158;
- return function(t) {
- return t * t * ((s + 1) * t - s);
- };
- }
- function d3_ease_bounce(t) {
- return t < 1 / 2.75 ? 7.5625 * t * t : t < 2 / 2.75 ? 7.5625 * (t -= 1.5 / 2.75) * t + .75 : t < 2.5 / 2.75 ? 7.5625 * (t -= 2.25 / 2.75) * t + .9375 : 7.5625 * (t -= 2.625 / 2.75) * t + .984375;
- }
- function d3_eventCancel() {
- d3.event.stopPropagation();
+ d3.event = null;
+ function d3_eventPreventDefault() {
d3.event.preventDefault();
}
function d3_eventSource() {
@@ -164,7 +455,7 @@
return e;
}
function d3_eventDispatch(target) {
- var dispatch = new d3_dispatch, i = 0, n = arguments.length;
+ var dispatch = new d3_dispatch(), i = 0, n = arguments.length;
while (++i < n) dispatch[arguments[i]] = d3_dispatch_event(dispatch);
dispatch.of = function(thiz, argumentz) {
return function(e1) {
@@ -180,204 +471,114 @@
};
return dispatch;
}
- function d3_transform(m) {
- var r0 = [ m.a, m.b ], r1 = [ m.c, m.d ], kx = d3_transformNormalize(r0), kz = d3_transformDot(r0, r1), ky = d3_transformNormalize(d3_transformCombine(r1, r0, -kz)) || 0;
- if (r0[0] * r1[1] < r1[0] * r0[1]) {
- r0[0] *= -1;
- r0[1] *= -1;
- kx *= -1;
- kz *= -1;
- }
- this.rotate = (kx ? Math.atan2(r0[1], r0[0]) : Math.atan2(-r1[0], r1[1])) * d3_transformDegrees;
- this.translate = [ m.e, m.f ];
- this.scale = [ kx, ky ];
- this.skew = ky ? Math.atan2(kz, ky) * d3_transformDegrees : 0;
- }
- function d3_transformDot(a, b) {
- return a[0] * b[0] + a[1] * b[1];
- }
- function d3_transformNormalize(a) {
- var k = Math.sqrt(d3_transformDot(a, a));
- if (k) {
- a[0] /= k;
- a[1] /= k;
- }
- return k;
- }
- function d3_transformCombine(a, b, k) {
- a[0] += k * b[0];
- a[1] += k * b[1];
- return a;
- }
- function d3_interpolateByName(name) {
- return name == "transform" ? d3.interpolateTransform : d3.interpolate;
+ d3.requote = function(s) {
+ return s.replace(d3_requote_re, "\\$&");
+ };
+ var d3_requote_re = /[\\\^\$\*\+\?\|\[\]\(\)\.\{\}]/g;
+ var d3_subclass = {}.__proto__ ? function(object, prototype) {
+ object.__proto__ = prototype;
+ } : function(object, prototype) {
+ for (var property in prototype) object[property] = prototype[property];
+ };
+ function d3_selection(groups) {
+ d3_subclass(groups, d3_selectionPrototype);
+ return groups;
}
- function d3_uninterpolateNumber(a, b) {
- b = b - (a = +a) ? 1 / (b - a) : 0;
- return function(x) {
- return (x - a) * b;
+ var d3_select = function(s, n) {
+ return n.querySelector(s);
+ }, d3_selectAll = function(s, n) {
+ return n.querySelectorAll(s);
+ }, d3_selectMatcher = d3_documentElement[d3_vendorSymbol(d3_documentElement, "matchesSelector")], d3_selectMatches = function(n, s) {
+ return d3_selectMatcher.call(n, s);
+ };
+ if (typeof Sizzle === "function") {
+ d3_select = function(s, n) {
+ return Sizzle(s, n)[0] || null;
};
- }
- function d3_uninterpolateClamp(a, b) {
- b = b - (a = +a) ? 1 / (b - a) : 0;
- return function(x) {
- return Math.max(0, Math.min(1, (x - a) * b));
+ d3_selectAll = function(s, n) {
+ return Sizzle.uniqueSort(Sizzle(s, n));
};
+ d3_selectMatches = Sizzle.matchesSelector;
}
- function d3_Color() {}
- function d3_rgb(r, g, b) {
- return new d3_Rgb(r, g, b);
- }
- function d3_Rgb(r, g, b) {
- this.r = r;
- this.g = g;
- this.b = b;
- }
- function d3_rgb_hex(v) {
- return v < 16 ? "0" + Math.max(0, v).toString(16) : Math.min(255, v).toString(16);
- }
- function d3_rgb_parse(format, rgb, hsl) {
- var r = 0, g = 0, b = 0, m1, m2, name;
- m1 = /([a-z]+)\((.*)\)/i.exec(format);
- if (m1) {
- m2 = m1[2].split(",");
- switch (m1[1]) {
- case "hsl":
- {
- return hsl(parseFloat(m2[0]), parseFloat(m2[1]) / 100, parseFloat(m2[2]) / 100);
- }
- case "rgb":
- {
- return rgb(d3_rgb_parseNumber(m2[0]), d3_rgb_parseNumber(m2[1]), d3_rgb_parseNumber(m2[2]));
+ d3.selection = function() {
+ return d3_selectionRoot;
+ };
+ var d3_selectionPrototype = d3.selection.prototype = [];
+ d3_selectionPrototype.select = function(selector) {
+ var subgroups = [], subgroup, subnode, group, node;
+ selector = d3_selection_selector(selector);
+ for (var j = -1, m = this.length; ++j < m; ) {
+ subgroups.push(subgroup = []);
+ subgroup.parentNode = (group = this[j]).parentNode;
+ for (var i = -1, n = group.length; ++i < n; ) {
+ if (node = group[i]) {
+ subgroup.push(subnode = selector.call(node, node.__data__, i, j));
+ if (subnode && "__data__" in node) subnode.__data__ = node.__data__;
+ } else {
+ subgroup.push(null);
}
}
}
- if (name = d3_rgb_names.get(format)) return rgb(name.r, name.g, name.b);
- if (format != null && format.charAt(0) === "#") {
- if (format.length === 4) {
- r = format.charAt(1);
- r += r;
- g = format.charAt(2);
- g += g;
- b = format.charAt(3);
- b += b;
- } else if (format.length === 7) {
- r = format.substring(1, 3);
- g = format.substring(3, 5);
- b = format.substring(5, 7);
- }
- r = parseInt(r, 16);
- g = parseInt(g, 16);
- b = parseInt(b, 16);
- }
- return rgb(r, g, b);
+ return d3_selection(subgroups);
+ };
+ function d3_selection_selector(selector) {
+ return typeof selector === "function" ? selector : function() {
+ return d3_select(selector, this);
+ };
}
- function d3_rgb_hsl(r, g, b) {
- var min = Math.min(r /= 255, g /= 255, b /= 255), max = Math.max(r, g, b), d = max - min, h, s, l = (max + min) / 2;
- if (d) {
- s = l < .5 ? d / (max + min) : d / (2 - max - min);
- if (r == max) h = (g - b) / d + (g < b ? 6 : 0); else if (g == max) h = (b - r) / d + 2; else h = (r - g) / d + 4;
- h *= 60;
- } else {
- s = h = 0;
+ d3_selectionPrototype.selectAll = function(selector) {
+ var subgroups = [], subgroup, node;
+ selector = d3_selection_selectorAll(selector);
+ for (var j = -1, m = this.length; ++j < m; ) {
+ for (var group = this[j], i = -1, n = group.length; ++i < n; ) {
+ if (node = group[i]) {
+ subgroups.push(subgroup = d3_array(selector.call(node, node.__data__, i, j)));
+ subgroup.parentNode = node;
+ }
+ }
}
- return d3_hsl(h, s, l);
+ return d3_selection(subgroups);
+ };
+ function d3_selection_selectorAll(selector) {
+ return typeof selector === "function" ? selector : function() {
+ return d3_selectAll(selector, this);
+ };
}
- function d3_rgb_lab(r, g, b) {
- r = d3_rgb_xyz(r);
- g = d3_rgb_xyz(g);
- b = d3_rgb_xyz(b);
- var x = d3_xyz_lab((.4124564 * r + .3575761 * g + .1804375 * b) / d3_lab_X), y = d3_xyz_lab((.2126729 * r + .7151522 * g + .072175 * b) / d3_lab_Y), z = d3_xyz_lab((.0193339 * r + .119192 * g + .9503041 * b) / d3_lab_Z);
- return d3_lab(116 * y - 16, 500 * (x - y), 200 * (y - z));
- }
- function d3_rgb_xyz(r) {
- return (r /= 255) <= .04045 ? r / 12.92 : Math.pow((r + .055) / 1.055, 2.4);
- }
- function d3_rgb_parseNumber(c) {
- var f = parseFloat(c);
- return c.charAt(c.length - 1) === "%" ? Math.round(f * 2.55) : f;
- }
- function d3_hsl(h, s, l) {
- return new d3_Hsl(h, s, l);
- }
- function d3_Hsl(h, s, l) {
- this.h = h;
- this.s = s;
- this.l = l;
- }
- function d3_hsl_rgb(h, s, l) {
- function v(h) {
- if (h > 360) h -= 360; else if (h < 0) h += 360;
- if (h < 60) return m1 + (m2 - m1) * h / 60;
- if (h < 180) return m2;
- if (h < 240) return m1 + (m2 - m1) * (240 - h) / 60;
- return m1;
+ var d3_nsPrefix = {
+ svg: "http://www.w3.org/2000/svg",
+ xhtml: "http://www.w3.org/1999/xhtml",
+ xlink: "http://www.w3.org/1999/xlink",
+ xml: "http://www.w3.org/XML/1998/namespace",
+ xmlns: "http://www.w3.org/2000/xmlns/"
+ };
+ d3.ns = {
+ prefix: d3_nsPrefix,
+ qualify: function(name) {
+ var i = name.indexOf(":"), prefix = name;
+ if (i >= 0) {
+ prefix = name.substring(0, i);
+ name = name.substring(i + 1);
+ }
+ return d3_nsPrefix.hasOwnProperty(prefix) ? {
+ space: d3_nsPrefix[prefix],
+ local: name
+ } : name;
}
- function vv(h) {
- return Math.round(v(h) * 255);
+ };
+ d3_selectionPrototype.attr = function(name, value) {
+ if (arguments.length < 2) {
+ if (typeof name === "string") {
+ var node = this.node();
+ name = d3.ns.qualify(name);
+ return name.local ? node.getAttributeNS(name.space, name.local) : node.getAttribute(name);
+ }
+ for (value in name) this.each(d3_selection_attr(value, name[value]));
+ return this;
}
- var m1, m2;
- h = h % 360;
- if (h < 0) h += 360;
- s = s < 0 ? 0 : s > 1 ? 1 : s;
- l = l < 0 ? 0 : l > 1 ? 1 : l;
- m2 = l <= .5 ? l * (1 + s) : l + s - l * s;
- m1 = 2 * l - m2;
- return d3_rgb(vv(h + 120), vv(h), vv(h - 120));
- }
- function d3_hcl(h, c, l) {
- return new d3_Hcl(h, c, l);
- }
- function d3_Hcl(h, c, l) {
- this.h = h;
- this.c = c;
- this.l = l;
- }
- function d3_hcl_lab(h, c, l) {
- return d3_lab(l, Math.cos(h *= Math.PI / 180) * c, Math.sin(h) * c);
- }
- function d3_lab(l, a, b) {
- return new d3_Lab(l, a, b);
- }
- function d3_Lab(l, a, b) {
- this.l = l;
- this.a = a;
- this.b = b;
- }
- function d3_lab_rgb(l, a, b) {
- var y = (l + 16) / 116, x = y + a / 500, z = y - b / 200;
- x = d3_lab_xyz(x) * d3_lab_X;
- y = d3_lab_xyz(y) * d3_lab_Y;
- z = d3_lab_xyz(z) * d3_lab_Z;
- return d3_rgb(d3_xyz_rgb(3.2404542 * x - 1.5371385 * y - .4985314 * z), d3_xyz_rgb(-.969266 * x + 1.8760108 * y + .041556 * z), d3_xyz_rgb(.0556434 * x - .2040259 * y + 1.0572252 * z));
- }
- function d3_lab_hcl(l, a, b) {
- return d3_hcl(Math.atan2(b, a) / Math.PI * 180, Math.sqrt(a * a + b * b), l);
- }
- function d3_lab_xyz(x) {
- return x > .206893034 ? x * x * x : (x - 4 / 29) / 7.787037;
- }
- function d3_xyz_lab(x) {
- return x > .008856 ? Math.pow(x, 1 / 3) : 7.787037 * x + 4 / 29;
- }
- function d3_xyz_rgb(r) {
- return Math.round(255 * (r <= .00304 ? 12.92 * r : 1.055 * Math.pow(r, 1 / 2.4) - .055));
- }
- function d3_selection(groups) {
- d3_arraySubclass(groups, d3_selectionPrototype);
- return groups;
- }
- function d3_selection_selector(selector) {
- return function() {
- return d3_select(selector, this);
- };
- }
- function d3_selection_selectorAll(selector) {
- return function() {
- return d3_selectAll(selector, this);
- };
- }
+ return this.each(d3_selection_attr(name, value));
+ };
function d3_selection_attr(name, value) {
+ name = d3.ns.qualify(name);
function attrNull() {
this.removeAttribute(name);
}
@@ -398,13 +599,37 @@
var x = value.apply(this, arguments);
if (x == null) this.removeAttributeNS(name.space, name.local); else this.setAttributeNS(name.space, name.local, x);
}
- name = d3.ns.qualify(name);
return value == null ? name.local ? attrNullNS : attrNull : typeof value === "function" ? name.local ? attrFunctionNS : attrFunction : name.local ? attrConstantNS : attrConstant;
}
+ function d3_collapse(s) {
+ return s.trim().replace(/\s+/g, " ");
+ }
+ d3_selectionPrototype.classed = function(name, value) {
+ if (arguments.length < 2) {
+ if (typeof name === "string") {
+ var node = this.node(), n = (name = d3_selection_classes(name)).length, i = -1;
+ if (value = node.classList) {
+ while (++i < n) if (!value.contains(name[i])) return false;
+ } else {
+ value = node.getAttribute("class");
+ while (++i < n) if (!d3_selection_classedRe(name[i]).test(value)) return false;
+ }
+ return true;
+ }
+ for (value in name) this.each(d3_selection_classed(value, name[value]));
+ return this;
+ }
+ return this.each(d3_selection_classed(name, value));
+ };
function d3_selection_classedRe(name) {
return new RegExp("(?:^|\\s+)" + d3.requote(name) + "(?:\\s+|$)", "g");
}
+ function d3_selection_classes(name) {
+ return name.trim().split(/^|\s+/);
+ }
function d3_selection_classed(name, value) {
+ name = d3_selection_classes(name).map(d3_selection_classedName);
+ var n = name.length;
function classedConstant() {
var i = -1;
while (++i < n) name[i](this, value);
@@ -413,27 +638,34 @@
var i = -1, x = value.apply(this, arguments);
while (++i < n) name[i](this, x);
}
- name = name.trim().split(/\s+/).map(d3_selection_classedName);
- var n = name.length;
return typeof value === "function" ? classedFunction : classedConstant;
}
function d3_selection_classedName(name) {
var re = d3_selection_classedRe(name);
return function(node, value) {
if (c = node.classList) return value ? c.add(name) : c.remove(name);
- var c = node.className, cb = c.baseVal != null, cv = cb ? c.baseVal : c;
+ var c = node.getAttribute("class") || "";
if (value) {
re.lastIndex = 0;
- if (!re.test(cv)) {
- cv = d3_collapse(cv + " " + name);
- if (cb) c.baseVal = cv; else node.className = cv;
- }
- } else if (cv) {
- cv = d3_collapse(cv.replace(re, " "));
- if (cb) c.baseVal = cv; else node.className = cv;
+ if (!re.test(c)) node.setAttribute("class", d3_collapse(c + " " + name));
+ } else {
+ node.setAttribute("class", d3_collapse(c.replace(re, " ")));
}
};
}
+ d3_selectionPrototype.style = function(name, value, priority) {
+ var n = arguments.length;
+ if (n < 3) {
+ if (typeof name !== "string") {
+ if (n < 2) value = "";
+ for (priority in name) this.each(d3_selection_style(priority, name[priority], value));
+ return this;
+ }
+ if (n < 2) return d3_window.getComputedStyle(this.node(), null).getPropertyValue(name);
+ priority = "";
+ }
+ return this.each(d3_selection_style(name, value, priority));
+ };
function d3_selection_style(name, value, priority) {
function styleNull() {
this.style.removeProperty(name);
@@ -447,6 +679,14 @@
}
return value == null ? styleNull : typeof value === "function" ? styleFunction : styleConstant;
}
+ d3_selectionPrototype.property = function(name, value) {
+ if (arguments.length < 2) {
+ if (typeof name === "string") return this.node()[name];
+ for (value in name) this.each(d3_selection_property(value, name[value]));
+ return this;
+ }
+ return this.each(d3_selection_property(name, value));
+ };
function d3_selection_property(name, value) {
function propertyNull() {
delete this[name];
@@ -460,2648 +700,5021 @@
}
return value == null ? propertyNull : typeof value === "function" ? propertyFunction : propertyConstant;
}
- function d3_selection_dataNode(data) {
- return {
- __data__: data
- };
- }
- function d3_selection_filter(selector) {
- return function() {
- return d3_selectMatches(this, selector);
- };
- }
- function d3_selection_sortComparator(comparator) {
- if (!arguments.length) comparator = d3.ascending;
- return function(a, b) {
- return comparator(a && a.__data__, b && b.__data__);
+ d3_selectionPrototype.text = function(value) {
+ return arguments.length ? this.each(typeof value === "function" ? function() {
+ var v = value.apply(this, arguments);
+ this.textContent = v == null ? "" : v;
+ } : value == null ? function() {
+ this.textContent = "";
+ } : function() {
+ this.textContent = value;
+ }) : this.node().textContent;
+ };
+ d3_selectionPrototype.html = function(value) {
+ return arguments.length ? this.each(typeof value === "function" ? function() {
+ var v = value.apply(this, arguments);
+ this.innerHTML = v == null ? "" : v;
+ } : value == null ? function() {
+ this.innerHTML = "";
+ } : function() {
+ this.innerHTML = value;
+ }) : this.node().innerHTML;
+ };
+ d3_selectionPrototype.append = function(name) {
+ name = d3_selection_creator(name);
+ return this.select(function() {
+ return this.appendChild(name.apply(this, arguments));
+ });
+ };
+ function d3_selection_creator(name) {
+ return typeof name === "function" ? name : (name = d3.ns.qualify(name)).local ? function() {
+ return this.ownerDocument.createElementNS(name.space, name.local);
+ } : function() {
+ return this.ownerDocument.createElementNS(this.namespaceURI, name);
};
}
- function d3_selection_on(type, listener, capture) {
- function onRemove() {
- var wrapper = this[name];
- if (wrapper) {
- this.removeEventListener(type, wrapper, wrapper.$);
- delete this[name];
- }
- }
- function onAdd() {
- function wrapper(e) {
- var o = d3.event;
- d3.event = e;
- args[0] = node.__data__;
- try {
- listener.apply(node, args);
- } finally {
- d3.event = o;
+ d3_selectionPrototype.insert = function(name, before) {
+ name = d3_selection_creator(name);
+ before = d3_selection_selector(before);
+ return this.select(function() {
+ return this.insertBefore(name.apply(this, arguments), before.apply(this, arguments) || null);
+ });
+ };
+ d3_selectionPrototype.remove = function() {
+ return this.each(function() {
+ var parent = this.parentNode;
+ if (parent) parent.removeChild(this);
+ });
+ };
+ d3_selectionPrototype.data = function(value, key) {
+ var i = -1, n = this.length, group, node;
+ if (!arguments.length) {
+ value = new Array(n = (group = this[0]).length);
+ while (++i < n) {
+ if (node = group[i]) {
+ value[i] = node.__data__;
}
}
- var node = this, args = arguments;
- onRemove.call(this);
- this.addEventListener(type, this[name] = wrapper, wrapper.$ = capture);
- wrapper._ = listener;
- }
- var name = "__on" + type, i = type.indexOf(".");
- if (i > 0) type = type.substring(0, i);
- return listener ? onAdd : onRemove;
- }
- function d3_selection_each(groups, callback) {
- for (var j = 0, m = groups.length; j < m; j++) {
- for (var group = groups[j], i = 0, n = group.length, node; i < n; i++) {
- if (node = group[i]) callback(node, i, j);
- }
+ return value;
}
- return groups;
- }
- function d3_selection_enter(selection) {
- d3_arraySubclass(selection, d3_selection_enterPrototype);
- return selection;
- }
- function d3_transition(groups, id, time) {
- d3_arraySubclass(groups, d3_transitionPrototype);
- var tweens = new d3_Map, event = d3.dispatch("start", "end"), ease = d3_transitionEase;
- groups.id = id;
- groups.time = time;
- groups.tween = function(name, tween) {
- if (arguments.length < 2) return tweens.get(name);
- if (tween == null) tweens.remove(name); else tweens.set(name, tween);
- return groups;
- };
- groups.ease = function(value) {
- if (!arguments.length) return ease;
- ease = typeof value === "function" ? value : d3.ease.apply(d3, arguments);
- return groups;
- };
- groups.each = function(type, listener) {
- if (arguments.length < 2) return d3_transition_each.call(groups, type);
- event.on(type, listener);
- return groups;
- };
- d3.timer(function(elapsed) {
- return d3_selection_each(groups, function(node, i, j) {
- function start(elapsed) {
- if (lock.active > id) return stop();
- lock.active = id;
- tweens.forEach(function(key, value) {
- if (value = value.call(node, d, i)) {
- tweened.push(value);
- }
- });
- event.start.call(node, d, i);
- if (!tick(elapsed)) d3.timer(tick, 0, time);
- return 1;
+ function bind(group, groupData) {
+ var i, n = group.length, m = groupData.length, n0 = Math.min(n, m), updateNodes = new Array(m), enterNodes = new Array(m), exitNodes = new Array(n), node, nodeData;
+ if (key) {
+ var nodeByKeyValue = new d3_Map(), dataByKeyValue = new d3_Map(), keyValues = [], keyValue;
+ for (i = -1; ++i < n; ) {
+ keyValue = key.call(node = group[i], node.__data__, i);
+ if (nodeByKeyValue.has(keyValue)) {
+ exitNodes[i] = node;
+ } else {
+ nodeByKeyValue.set(keyValue, node);
+ }
+ keyValues.push(keyValue);
}
- function tick(elapsed) {
- if (lock.active !== id) return stop();
- var t = (elapsed - delay) / duration, e = ease(t), n = tweened.length;
- while (n > 0) {
- tweened[--n].call(node, e);
+ for (i = -1; ++i < m; ) {
+ keyValue = key.call(groupData, nodeData = groupData[i], i);
+ if (node = nodeByKeyValue.get(keyValue)) {
+ updateNodes[i] = node;
+ node.__data__ = nodeData;
+ } else if (!dataByKeyValue.has(keyValue)) {
+ enterNodes[i] = d3_selection_dataNode(nodeData);
}
- if (t >= 1) {
- stop();
- d3_transitionId = id;
- event.end.call(node, d, i);
- d3_transitionId = 0;
- return 1;
+ dataByKeyValue.set(keyValue, nodeData);
+ nodeByKeyValue.remove(keyValue);
+ }
+ for (i = -1; ++i < n; ) {
+ if (nodeByKeyValue.has(keyValues[i])) {
+ exitNodes[i] = group[i];
}
}
- function stop() {
- if (!--lock.count) delete node.__transition__;
- return 1;
+ } else {
+ for (i = -1; ++i < n0; ) {
+ node = group[i];
+ nodeData = groupData[i];
+ if (node) {
+ node.__data__ = nodeData;
+ updateNodes[i] = node;
+ } else {
+ enterNodes[i] = d3_selection_dataNode(nodeData);
+ }
}
- var tweened = [], delay = node.delay, duration = node.duration, lock = (node = node.node).__transition__ || (node.__transition__ = {
- active: 0,
- count: 0
- }), d = node.__data__;
- ++lock.count;
- delay <= elapsed ? start(elapsed) : d3.timer(start, delay, time);
- });
- }, 0, time);
- return groups;
+ for (;i < m; ++i) {
+ enterNodes[i] = d3_selection_dataNode(groupData[i]);
+ }
+ for (;i < n; ++i) {
+ exitNodes[i] = group[i];
+ }
+ }
+ enterNodes.update = updateNodes;
+ enterNodes.parentNode = updateNodes.parentNode = exitNodes.parentNode = group.parentNode;
+ enter.push(enterNodes);
+ update.push(updateNodes);
+ exit.push(exitNodes);
+ }
+ var enter = d3_selection_enter([]), update = d3_selection([]), exit = d3_selection([]);
+ if (typeof value === "function") {
+ while (++i < n) {
+ bind(group = this[i], value.call(group, group.parentNode.__data__, i));
+ }
+ } else {
+ while (++i < n) {
+ bind(group = this[i], value);
+ }
+ }
+ update.enter = function() {
+ return enter;
+ };
+ update.exit = function() {
+ return exit;
+ };
+ return update;
+ };
+ function d3_selection_dataNode(data) {
+ return {
+ __data__: data
+ };
+ }
+ d3_selectionPrototype.datum = function(value) {
+ return arguments.length ? this.property("__data__", value) : this.property("__data__");
+ };
+ d3_selectionPrototype.filter = function(filter) {
+ var subgroups = [], subgroup, group, node;
+ if (typeof filter !== "function") filter = d3_selection_filter(filter);
+ for (var j = 0, m = this.length; j < m; j++) {
+ subgroups.push(subgroup = []);
+ subgroup.parentNode = (group = this[j]).parentNode;
+ for (var i = 0, n = group.length; i < n; i++) {
+ if ((node = group[i]) && filter.call(node, node.__data__, i, j)) {
+ subgroup.push(node);
+ }
+ }
+ }
+ return d3_selection(subgroups);
+ };
+ function d3_selection_filter(selector) {
+ return function() {
+ return d3_selectMatches(this, selector);
+ };
+ }
+ d3_selectionPrototype.order = function() {
+ for (var j = -1, m = this.length; ++j < m; ) {
+ for (var group = this[j], i = group.length - 1, next = group[i], node; --i >= 0; ) {
+ if (node = group[i]) {
+ if (next && next !== node.nextSibling) next.parentNode.insertBefore(node, next);
+ next = node;
+ }
+ }
+ }
+ return this;
+ };
+ d3_selectionPrototype.sort = function(comparator) {
+ comparator = d3_selection_sortComparator.apply(this, arguments);
+ for (var j = -1, m = this.length; ++j < m; ) this[j].sort(comparator);
+ return this.order();
+ };
+ function d3_selection_sortComparator(comparator) {
+ if (!arguments.length) comparator = d3.ascending;
+ return function(a, b) {
+ return a && b ? comparator(a.__data__, b.__data__) : !a - !b;
+ };
}
- function d3_transition_each(callback) {
- var id = d3_transitionId, ease = d3_transitionEase, delay = d3_transitionDelay, duration = d3_transitionDuration;
- d3_transitionId = this.id;
- d3_transitionEase = this.ease();
- d3_selection_each(this, function(node, i, j) {
- d3_transitionDelay = node.delay;
- d3_transitionDuration = node.duration;
- callback.call(node = node.node, node.__data__, i, j);
+ d3_selectionPrototype.each = function(callback) {
+ return d3_selection_each(this, function(node, i, j) {
+ callback.call(node, node.__data__, i, j);
});
- d3_transitionId = id;
- d3_transitionEase = ease;
- d3_transitionDelay = delay;
- d3_transitionDuration = duration;
+ };
+ function d3_selection_each(groups, callback) {
+ for (var j = 0, m = groups.length; j < m; j++) {
+ for (var group = groups[j], i = 0, n = group.length, node; i < n; i++) {
+ if (node = group[i]) callback(node, i, j);
+ }
+ }
+ return groups;
+ }
+ d3_selectionPrototype.call = function(callback) {
+ var args = d3_array(arguments);
+ callback.apply(args[0] = this, args);
return this;
+ };
+ d3_selectionPrototype.empty = function() {
+ return !this.node();
+ };
+ d3_selectionPrototype.node = function() {
+ for (var j = 0, m = this.length; j < m; j++) {
+ for (var group = this[j], i = 0, n = group.length; i < n; i++) {
+ var node = group[i];
+ if (node) return node;
+ }
+ }
+ return null;
+ };
+ d3_selectionPrototype.size = function() {
+ var n = 0;
+ this.each(function() {
+ ++n;
+ });
+ return n;
+ };
+ function d3_selection_enter(selection) {
+ d3_subclass(selection, d3_selection_enterPrototype);
+ return selection;
}
- function d3_tweenNull(d, i, a) {
- return a != "" && d3_tweenRemove;
+ var d3_selection_enterPrototype = [];
+ d3.selection.enter = d3_selection_enter;
+ d3.selection.enter.prototype = d3_selection_enterPrototype;
+ d3_selection_enterPrototype.append = d3_selectionPrototype.append;
+ d3_selection_enterPrototype.empty = d3_selectionPrototype.empty;
+ d3_selection_enterPrototype.node = d3_selectionPrototype.node;
+ d3_selection_enterPrototype.call = d3_selectionPrototype.call;
+ d3_selection_enterPrototype.size = d3_selectionPrototype.size;
+ d3_selection_enterPrototype.select = function(selector) {
+ var subgroups = [], subgroup, subnode, upgroup, group, node;
+ for (var j = -1, m = this.length; ++j < m; ) {
+ upgroup = (group = this[j]).update;
+ subgroups.push(subgroup = []);
+ subgroup.parentNode = group.parentNode;
+ for (var i = -1, n = group.length; ++i < n; ) {
+ if (node = group[i]) {
+ subgroup.push(upgroup[i] = subnode = selector.call(group.parentNode, node.__data__, i, j));
+ subnode.__data__ = node.__data__;
+ } else {
+ subgroup.push(null);
+ }
+ }
+ }
+ return d3_selection(subgroups);
+ };
+ d3_selection_enterPrototype.insert = function(name, before) {
+ if (arguments.length < 2) before = d3_selection_enterInsertBefore(this);
+ return d3_selectionPrototype.insert.call(this, name, before);
+ };
+ function d3_selection_enterInsertBefore(enter) {
+ var i0, j0;
+ return function(d, i, j) {
+ var group = enter[j].update, n = group.length, node;
+ if (j != j0) j0 = j, i0 = 0;
+ if (i >= i0) i0 = i + 1;
+ while (!(node = group[i0]) && ++i0 < n) ;
+ return node;
+ };
}
- function d3_tweenByName(b, name) {
- return d3.tween(b, d3_interpolateByName(name));
+ d3_selectionPrototype.transition = function() {
+ var id = d3_transitionInheritId || ++d3_transitionId, subgroups = [], subgroup, node, transition = d3_transitionInherit || {
+ time: Date.now(),
+ ease: d3_ease_cubicInOut,
+ delay: 0,
+ duration: 250
+ };
+ for (var j = -1, m = this.length; ++j < m; ) {
+ subgroups.push(subgroup = []);
+ for (var group = this[j], i = -1, n = group.length; ++i < n; ) {
+ if (node = group[i]) d3_transitionNode(node, i, id, transition);
+ subgroup.push(node);
+ }
+ }
+ return d3_transition(subgroups, id);
+ };
+ d3_selectionPrototype.interrupt = function() {
+ return this.each(d3_selection_interrupt);
+ };
+ function d3_selection_interrupt() {
+ var lock = this.__transition__;
+ if (lock) ++lock.active;
}
- function d3_timer_step() {
- var elapsed, now = Date.now(), t1 = d3_timer_queue;
- while (t1) {
- elapsed = now - t1.then;
- if (elapsed >= t1.delay) t1.flush = t1.callback(elapsed);
- t1 = t1.next;
+ d3.select = function(node) {
+ var group = [ typeof node === "string" ? d3_select(node, d3_document) : node ];
+ group.parentNode = d3_documentElement;
+ return d3_selection([ group ]);
+ };
+ d3.selectAll = function(nodes) {
+ var group = d3_array(typeof nodes === "string" ? d3_selectAll(nodes, d3_document) : nodes);
+ group.parentNode = d3_documentElement;
+ return d3_selection([ group ]);
+ };
+ var d3_selectionRoot = d3.select(d3_documentElement);
+ d3_selectionPrototype.on = function(type, listener, capture) {
+ var n = arguments.length;
+ if (n < 3) {
+ if (typeof type !== "string") {
+ if (n < 2) listener = false;
+ for (capture in type) this.each(d3_selection_on(capture, type[capture], listener));
+ return this;
+ }
+ if (n < 2) return (n = this.node()["__on" + type]) && n._;
+ capture = false;
}
- var delay = d3_timer_flush() - now;
- if (delay > 24) {
- if (isFinite(delay)) {
- clearTimeout(d3_timer_timeout);
- d3_timer_timeout = setTimeout(d3_timer_step, delay);
+ return this.each(d3_selection_on(type, listener, capture));
+ };
+ function d3_selection_on(type, listener, capture) {
+ var name = "__on" + type, i = type.indexOf("."), wrap = d3_selection_onListener;
+ if (i > 0) type = type.substring(0, i);
+ var filter = d3_selection_onFilters.get(type);
+ if (filter) type = filter, wrap = d3_selection_onFilter;
+ function onRemove() {
+ var l = this[name];
+ if (l) {
+ this.removeEventListener(type, l, l.$);
+ delete this[name];
}
- d3_timer_interval = 0;
- } else {
- d3_timer_interval = 1;
- d3_timer_frame(d3_timer_step);
}
+ function onAdd() {
+ var l = wrap(listener, d3_array(arguments));
+ onRemove.call(this);
+ this.addEventListener(type, this[name] = l, l.$ = capture);
+ l._ = listener;
+ }
+ function removeAll() {
+ var re = new RegExp("^__on([^.]+)" + d3.requote(type) + "$"), match;
+ for (var name in this) {
+ if (match = name.match(re)) {
+ var l = this[name];
+ this.removeEventListener(match[1], l, l.$);
+ delete this[name];
+ }
+ }
+ }
+ return i ? listener ? onAdd : onRemove : listener ? d3_noop : removeAll;
}
- function d3_timer_flush() {
- var t0 = null, t1 = d3_timer_queue, then = Infinity;
- while (t1) {
- if (t1.flush) {
- delete d3_timer_byId[t1.callback.id];
- t1 = t0 ? t0.next = t1.next : d3_timer_queue = t1.next;
- } else {
- then = Math.min(then, t1.then + t1.delay);
- t1 = (t0 = t1).next;
+ var d3_selection_onFilters = d3.map({
+ mouseenter: "mouseover",
+ mouseleave: "mouseout"
+ });
+ d3_selection_onFilters.forEach(function(k) {
+ if ("on" + k in d3_document) d3_selection_onFilters.remove(k);
+ });
+ function d3_selection_onListener(listener, argumentz) {
+ return function(e) {
+ var o = d3.event;
+ d3.event = e;
+ argumentz[0] = this.__data__;
+ try {
+ listener.apply(this, argumentz);
+ } finally {
+ d3.event = o;
+ }
+ };
+ }
+ function d3_selection_onFilter(listener, argumentz) {
+ var l = d3_selection_onListener(listener, argumentz);
+ return function(e) {
+ var target = this, related = e.relatedTarget;
+ if (!related || related !== target && !(related.compareDocumentPosition(target) & 8)) {
+ l.call(target, e);
}
+ };
+ }
+ var d3_event_dragSelect = "onselectstart" in d3_document ? null : d3_vendorSymbol(d3_documentElement.style, "userSelect"), d3_event_dragId = 0;
+ function d3_event_dragSuppress() {
+ var name = ".dragsuppress-" + ++d3_event_dragId, click = "click" + name, w = d3.select(d3_window).on("touchmove" + name, d3_eventPreventDefault).on("dragstart" + name, d3_eventPreventDefault).on("selectstart" + name, d3_eventPreventDefault);
+ if (d3_event_dragSelect) {
+ var style = d3_documentElement.style, select = style[d3_event_dragSelect];
+ style[d3_event_dragSelect] = "none";
}
- return then;
+ return function(suppressClick) {
+ w.on(name, null);
+ if (d3_event_dragSelect) style[d3_event_dragSelect] = select;
+ if (suppressClick) {
+ function off() {
+ w.on(click, null);
+ }
+ w.on(click, function() {
+ d3_eventPreventDefault();
+ off();
+ }, true);
+ setTimeout(off, 0);
+ }
+ };
}
+ d3.mouse = function(container) {
+ return d3_mousePoint(container, d3_eventSource());
+ };
+ var d3_mouse_bug44083 = /WebKit/.test(d3_window.navigator.userAgent) ? -1 : 0;
function d3_mousePoint(container, e) {
+ if (e.changedTouches) e = e.changedTouches[0];
var svg = container.ownerSVGElement || container;
if (svg.createSVGPoint) {
var point = svg.createSVGPoint();
- if (d3_mouse_bug44083 < 0 && (window.scrollX || window.scrollY)) {
- svg = d3.select(document.body).append("svg").style("position", "absolute").style("top", 0).style("left", 0);
+ if (d3_mouse_bug44083 < 0 && (d3_window.scrollX || d3_window.scrollY)) {
+ svg = d3.select("body").append("svg").style({
+ position: "absolute",
+ top: 0,
+ left: 0,
+ margin: 0,
+ padding: 0,
+ border: "none"
+ }, "important");
var ctm = svg[0][0].getScreenCTM();
d3_mouse_bug44083 = !(ctm.f || ctm.e);
svg.remove();
}
- if (d3_mouse_bug44083) {
- point.x = e.pageX;
- point.y = e.pageY;
- } else {
- point.x = e.clientX;
- point.y = e.clientY;
- }
+ if (d3_mouse_bug44083) point.x = e.pageX, point.y = e.pageY; else point.x = e.clientX,
+ point.y = e.clientY;
point = point.matrixTransform(container.getScreenCTM().inverse());
return [ point.x, point.y ];
}
var rect = container.getBoundingClientRect();
return [ e.clientX - rect.left - container.clientLeft, e.clientY - rect.top - container.clientTop ];
}
- function d3_noop() {}
- function d3_scaleExtent(domain) {
- var start = domain[0], stop = domain[domain.length - 1];
- return start < stop ? [ start, stop ] : [ stop, start ];
- }
- function d3_scaleRange(scale) {
- return scale.rangeExtent ? scale.rangeExtent() : d3_scaleExtent(scale.range());
- }
- function d3_scale_nice(domain, nice) {
- var i0 = 0, i1 = domain.length - 1, x0 = domain[i0], x1 = domain[i1], dx;
- if (x1 < x0) {
- dx = i0, i0 = i1, i1 = dx;
- dx = x0, x0 = x1, x1 = dx;
- }
- if (nice = nice(x1 - x0)) {
- domain[i0] = nice.floor(x0);
- domain[i1] = nice.ceil(x1);
+ d3.touches = function(container, touches) {
+ if (arguments.length < 2) touches = d3_eventSource().touches;
+ return touches ? d3_array(touches).map(function(touch) {
+ var point = d3_mousePoint(container, touch);
+ point.identifier = touch.identifier;
+ return point;
+ }) : [];
+ };
+ d3.behavior.drag = function() {
+ var event = d3_eventDispatch(drag, "drag", "dragstart", "dragend"), origin = null, mousedown = dragstart(d3_noop, d3.mouse, "mousemove", "mouseup"), touchstart = dragstart(touchid, touchposition, "touchmove", "touchend");
+ function drag() {
+ this.on("mousedown.drag", mousedown).on("touchstart.drag", touchstart);
}
- return domain;
- }
- function d3_scale_niceDefault() {
- return Math;
- }
- function d3_scale_linear(domain, range, interpolate, clamp) {
- function rescale() {
- var linear = Math.min(domain.length, range.length) > 2 ? d3_scale_polylinear : d3_scale_bilinear, uninterpolate = clamp ? d3_uninterpolateClamp : d3_uninterpolateNumber;
- output = linear(domain, range, uninterpolate, interpolate);
- input = linear(range, domain, uninterpolate, d3.interpolate);
- return scale;
+ function touchid() {
+ return d3.event.changedTouches[0].identifier;
}
- function scale(x) {
- return output(x);
+ function touchposition(parent, id) {
+ return d3.touches(parent).filter(function(p) {
+ return p.identifier === id;
+ })[0];
}
- var output, input;
- scale.invert = function(y) {
- return input(y);
- };
- scale.domain = function(x) {
- if (!arguments.length) return domain;
- domain = x.map(Number);
- return rescale();
- };
- scale.range = function(x) {
- if (!arguments.length) return range;
- range = x;
- return rescale();
- };
- scale.rangeRound = function(x) {
- return scale.range(x).interpolate(d3.interpolateRound);
- };
- scale.clamp = function(x) {
- if (!arguments.length) return clamp;
- clamp = x;
- return rescale();
- };
- scale.interpolate = function(x) {
- if (!arguments.length) return interpolate;
- interpolate = x;
- return rescale();
- };
- scale.ticks = function(m) {
- return d3_scale_linearTicks(domain, m);
- };
- scale.tickFormat = function(m) {
- return d3_scale_linearTickFormat(domain, m);
- };
- scale.nice = function() {
- d3_scale_nice(domain, d3_scale_linearNice);
- return rescale();
- };
- scale.copy = function() {
- return d3_scale_linear(domain, range, interpolate, clamp);
+ function dragstart(id, position, move, end) {
+ return function() {
+ var target = this, parent = target.parentNode, event_ = event.of(target, arguments), eventTarget = d3.event.target, eventId = id(), drag = eventId == null ? "drag" : "drag-" + eventId, origin_ = position(parent, eventId), dragged = 0, offset, w = d3.select(d3_window).on(move + "." + drag, moved).on(end + "." + drag, ended), dragRestore = d3_event_dragSuppress();
+ if (origin) {
+ offset = origin.apply(target, arguments);
+ offset = [ offset.x - origin_[0], offset.y - origin_[1] ];
+ } else {
+ offset = [ 0, 0 ];
+ }
+ event_({
+ type: "dragstart"
+ });
+ function moved() {
+ var p = position(parent, eventId), dx = p[0] - origin_[0], dy = p[1] - origin_[1];
+ dragged |= dx | dy;
+ origin_ = p;
+ event_({
+ type: "drag",
+ x: p[0] + offset[0],
+ y: p[1] + offset[1],
+ dx: dx,
+ dy: dy
+ });
+ }
+ function ended() {
+ w.on(move + "." + drag, null).on(end + "." + drag, null);
+ dragRestore(dragged && d3.event.target === eventTarget);
+ event_({
+ type: "dragend"
+ });
+ }
+ };
+ }
+ drag.origin = function(x) {
+ if (!arguments.length) return origin;
+ origin = x;
+ return drag;
};
- return rescale();
+ return d3.rebind(drag, event, "on");
+ };
+ var π = Math.PI, τ = 2 * π, halfπ = π / 2, ε = 1e-6, ε2 = ε * ε, d3_radians = π / 180, d3_degrees = 180 / π;
+ function d3_sgn(x) {
+ return x > 0 ? 1 : x < 0 ? -1 : 0;
}
- function d3_scale_linearRebind(scale, linear) {
- return d3.rebind(scale, linear, "range", "rangeRound", "interpolate", "clamp");
+ function d3_cross2d(a, b, c) {
+ return (b[0] - a[0]) * (c[1] - a[1]) - (b[1] - a[1]) * (c[0] - a[0]);
}
- function d3_scale_linearNice(dx) {
- dx = Math.pow(10, Math.round(Math.log(dx) / Math.LN10) - 1);
- return dx && {
- floor: function(x) {
- return Math.floor(x / dx) * dx;
- },
- ceil: function(x) {
- return Math.ceil(x / dx) * dx;
- }
- };
+ function d3_acos(x) {
+ return x > 1 ? 0 : x < -1 ? π : Math.acos(x);
}
- function d3_scale_linearTickRange(domain, m) {
- var extent = d3_scaleExtent(domain), span = extent[1] - extent[0], step = Math.pow(10, Math.floor(Math.log(span / m) / Math.LN10)), err = m / span * step;
- if (err <= .15) step *= 10; else if (err <= .35) step *= 5; else if (err <= .75) step *= 2;
- extent[0] = Math.ceil(extent[0] / step) * step;
- extent[1] = Math.floor(extent[1] / step) * step + step * .5;
- extent[2] = step;
- return extent;
+ function d3_asin(x) {
+ return x > 1 ? halfπ : x < -1 ? -halfπ : Math.asin(x);
}
- function d3_scale_linearTicks(domain, m) {
- return d3.range.apply(d3, d3_scale_linearTickRange(domain, m));
+ function d3_sinh(x) {
+ return ((x = Math.exp(x)) - 1 / x) / 2;
}
- function d3_scale_linearTickFormat(domain, m) {
- return d3.format(",." + Math.max(0, -Math.floor(Math.log(d3_scale_linearTickRange(domain, m)[2]) / Math.LN10 + .01)) + "f");
+ function d3_cosh(x) {
+ return ((x = Math.exp(x)) + 1 / x) / 2;
}
- function d3_scale_bilinear(domain, range, uninterpolate, interpolate) {
- var u = uninterpolate(domain[0], domain[1]), i = interpolate(range[0], range[1]);
- return function(x) {
- return i(u(x));
- };
+ function d3_tanh(x) {
+ return ((x = Math.exp(2 * x)) - 1) / (x + 1);
}
- function d3_scale_polylinear(domain, range, uninterpolate, interpolate) {
- var u = [], i = [], j = 0, k = Math.min(domain.length, range.length) - 1;
- if (domain[k] < domain[0]) {
- domain = domain.slice().reverse();
- range = range.slice().reverse();
- }
- while (++j <= k) {
- u.push(uninterpolate(domain[j - 1], domain[j]));
- i.push(interpolate(range[j - 1], range[j]));
- }
- return function(x) {
- var j = d3.bisect(domain, x, 1, k) - 1;
- return i[j](u[j](x));
- };
+ function d3_haversin(x) {
+ return (x = Math.sin(x / 2)) * x;
}
- function d3_scale_log(linear, log) {
- function scale(x) {
- return linear(log(x));
+ var ρ = Math.SQRT2, ρ2 = 2, ρ4 = 4;
+ d3.interpolateZoom = function(p0, p1) {
+ var ux0 = p0[0], uy0 = p0[1], w0 = p0[2], ux1 = p1[0], uy1 = p1[1], w1 = p1[2];
+ var dx = ux1 - ux0, dy = uy1 - uy0, d2 = dx * dx + dy * dy, d1 = Math.sqrt(d2), b0 = (w1 * w1 - w0 * w0 + ρ4 * d2) / (2 * w0 * ρ2 * d1), b1 = (w1 * w1 - w0 * w0 - ρ4 * d2) / (2 * w1 * ρ2 * d1), r0 = Math.log(Math.sqrt(b0 * b0 + 1) - b0), r1 = Math.log(Math.sqrt(b1 * b1 + 1) - b1), dr = r1 - r0, S = (dr || Math.log(w1 / w0)) / ρ;
+ function interpolate(t) {
+ var s = t * S;
+ if (dr) {
+ var coshr0 = d3_cosh(r0), u = w0 / (ρ2 * d1) * (coshr0 * d3_tanh(ρ * s + r0) - d3_sinh(r0));
+ return [ ux0 + u * dx, uy0 + u * dy, w0 * coshr0 / d3_cosh(ρ * s + r0) ];
+ }
+ return [ ux0 + t * dx, uy0 + t * dy, w0 * Math.exp(ρ * s) ];
}
- var pow = log.pow;
- scale.invert = function(x) {
- return pow(linear.invert(x));
- };
- scale.domain = function(x) {
- if (!arguments.length) return linear.domain().map(pow);
- log = x[0] < 0 ? d3_scale_logn : d3_scale_logp;
- pow = log.pow;
- linear.domain(x.map(log));
- return scale;
- };
- scale.nice = function() {
- linear.domain(d3_scale_nice(linear.domain(), d3_scale_niceDefault));
- return scale;
- };
- scale.ticks = function() {
- var extent = d3_scaleExtent(linear.domain()), ticks = [];
- if (extent.every(isFinite)) {
- var i = Math.floor(extent[0]), j = Math.ceil(extent[1]), u = pow(extent[0]), v = pow(extent[1]);
- if (log === d3_scale_logn) {
- ticks.push(pow(i));
- for (; i++ < j; ) for (var k = 9; k > 0; k--) ticks.push(pow(i) * k);
+ interpolate.duration = S * 1e3;
+ return interpolate;
+ };
+ d3.behavior.zoom = function() {
+ var view = {
+ x: 0,
+ y: 0,
+ k: 1
+ }, translate0, center, size = [ 960, 500 ], scaleExtent = d3_behavior_zoomInfinity, mousedown = "mousedown.zoom", mousemove = "mousemove.zoom", mouseup = "mouseup.zoom", mousewheelTimer, touchstart = "touchstart.zoom", touchtime, event = d3_eventDispatch(zoom, "zoomstart", "zoom", "zoomend"), x0, x1, y0, y1;
+ function zoom(g) {
+ g.on(mousedown, mousedowned).on(d3_behavior_zoomWheel + ".zoom", mousewheeled).on(mousemove, mousewheelreset).on("dblclick.zoom", dblclicked).on(touchstart, touchstarted);
+ }
+ zoom.event = function(g) {
+ g.each(function() {
+ var event_ = event.of(this, arguments), view1 = view;
+ if (d3_transitionInheritId) {
+ d3.select(this).transition().each("start.zoom", function() {
+ view = this.__chart__ || {
+ x: 0,
+ y: 0,
+ k: 1
+ };
+ zoomstarted(event_);
+ }).tween("zoom:zoom", function() {
+ var dx = size[0], dy = size[1], cx = dx / 2, cy = dy / 2, i = d3.interpolateZoom([ (cx - view.x) / view.k, (cy - view.y) / view.k, dx / view.k ], [ (cx - view1.x) / view1.k, (cy - view1.y) / view1.k, dx / view1.k ]);
+ return function(t) {
+ var l = i(t), k = dx / l[2];
+ this.__chart__ = view = {
+ x: cx - l[0] * k,
+ y: cy - l[1] * k,
+ k: k
+ };
+ zoomed(event_);
+ };
+ }).each("end.zoom", function() {
+ zoomended(event_);
+ });
} else {
- for (; i < j; i++) for (var k = 1; k < 10; k++) ticks.push(pow(i) * k);
- ticks.push(pow(i));
+ this.__chart__ = view;
+ zoomstarted(event_);
+ zoomed(event_);
+ zoomended(event_);
}
- for (i = 0; ticks[i] < u; i++) {}
- for (j = ticks.length; ticks[j - 1] > v; j--) {}
- ticks = ticks.slice(i, j);
- }
- return ticks;
- };
- scale.tickFormat = function(n, format) {
- if (arguments.length < 2) format = d3_scale_logFormat;
- if (arguments.length < 1) return format;
- var k = Math.max(.1, n / scale.ticks().length), f = log === d3_scale_logn ? (e = -1e-12, Math.floor) : (e = 1e-12, Math.ceil), e;
- return function(d) {
- return d / pow(f(log(d) + e)) <= k ? format(d) : "";
- };
- };
- scale.copy = function() {
- return d3_scale_log(linear.copy(), log);
- };
- return d3_scale_linearRebind(scale, linear);
- }
- function d3_scale_logp(x) {
- return Math.log(x < 0 ? 0 : x) / Math.LN10;
- }
- function d3_scale_logn(x) {
- return -Math.log(x > 0 ? 0 : -x) / Math.LN10;
- }
- function d3_scale_pow(linear, exponent) {
- function scale(x) {
- return linear(powp(x));
- }
- var powp = d3_scale_powPow(exponent), powb = d3_scale_powPow(1 / exponent);
- scale.invert = function(x) {
- return powb(linear.invert(x));
- };
- scale.domain = function(x) {
- if (!arguments.length) return linear.domain().map(powb);
- linear.domain(x.map(powp));
- return scale;
- };
- scale.ticks = function(m) {
- return d3_scale_linearTicks(scale.domain(), m);
- };
- scale.tickFormat = function(m) {
- return d3_scale_linearTickFormat(scale.domain(), m);
- };
- scale.nice = function() {
- return scale.domain(d3_scale_nice(scale.domain(), d3_scale_linearNice));
- };
- scale.exponent = function(x) {
- if (!arguments.length) return exponent;
- var domain = scale.domain();
- powp = d3_scale_powPow(exponent = x);
- powb = d3_scale_powPow(1 / exponent);
- return scale.domain(domain);
- };
- scale.copy = function() {
- return d3_scale_pow(linear.copy(), exponent);
- };
- return d3_scale_linearRebind(scale, linear);
- }
- function d3_scale_powPow(e) {
- return function(x) {
- return x < 0 ? -Math.pow(-x, e) : Math.pow(x, e);
- };
- }
- function d3_scale_ordinal(domain, ranger) {
- function scale(x) {
- return range[((index.get(x) || index.set(x, domain.push(x))) - 1) % range.length];
- }
- function steps(start, step) {
- return d3.range(domain.length).map(function(i) {
- return start + step * i;
});
- }
- var index, range, rangeBand;
- scale.domain = function(x) {
- if (!arguments.length) return domain;
- domain = [];
- index = new d3_Map;
- var i = -1, n = x.length, xi;
- while (++i < n) if (!index.has(xi = x[i])) index.set(xi, domain.push(xi));
- return scale[ranger.t].apply(scale, ranger.a);
};
- scale.range = function(x) {
- if (!arguments.length) return range;
- range = x;
- rangeBand = 0;
- ranger = {
- t: "range",
- a: arguments
+ zoom.translate = function(_) {
+ if (!arguments.length) return [ view.x, view.y ];
+ view = {
+ x: +_[0],
+ y: +_[1],
+ k: view.k
};
- return scale;
+ rescale();
+ return zoom;
};
- scale.rangePoints = function(x, padding) {
- if (arguments.length < 2) padding = 0;
- var start = x[0], stop = x[1], step = (stop - start) / (Math.max(1, domain.length - 1) + padding);
- range = steps(domain.length < 2 ? (start + stop) / 2 : start + step * padding / 2, step);
- rangeBand = 0;
- ranger = {
- t: "rangePoints",
- a: arguments
+ zoom.scale = function(_) {
+ if (!arguments.length) return view.k;
+ view = {
+ x: view.x,
+ y: view.y,
+ k: +_
};
- return scale;
+ rescale();
+ return zoom;
};
- scale.rangeBands = function(x, padding, outerPadding) {
- if (arguments.length < 2) padding = 0;
- if (arguments.length < 3) outerPadding = padding;
- var reverse = x[1] < x[0], start = x[reverse - 0], stop = x[1 - reverse], step = (stop - start) / (domain.length - padding + 2 * outerPadding);
- range = steps(start + step * outerPadding, step);
- if (reverse) range.reverse();
- rangeBand = step * (1 - padding);
- ranger = {
- t: "rangeBands",
- a: arguments
- };
- return scale;
+ zoom.scaleExtent = function(_) {
+ if (!arguments.length) return scaleExtent;
+ scaleExtent = _ == null ? d3_behavior_zoomInfinity : [ +_[0], +_[1] ];
+ return zoom;
};
- scale.rangeRoundBands = function(x, padding, outerPadding) {
- if (arguments.length < 2) padding = 0;
- if (arguments.length < 3) outerPadding = padding;
- var reverse = x[1] < x[0], start = x[reverse - 0], stop = x[1 - reverse], step = Math.floor((stop - start) / (domain.length - padding + 2 * outerPadding)), error = stop - start - (domain.length - padding) * step;
- range = steps(start + Math.round(error / 2), step);
- if (reverse) range.reverse();
- rangeBand = Math.round(step * (1 - padding));
- ranger = {
- t: "rangeRoundBands",
- a: arguments
- };
- return scale;
+ zoom.center = function(_) {
+ if (!arguments.length) return center;
+ center = _ && [ +_[0], +_[1] ];
+ return zoom;
};
- scale.rangeBand = function() {
- return rangeBand;
+ zoom.size = function(_) {
+ if (!arguments.length) return size;
+ size = _ && [ +_[0], +_[1] ];
+ return zoom;
};
- scale.rangeExtent = function() {
- return d3_scaleExtent(ranger.a[0]);
+ zoom.x = function(z) {
+ if (!arguments.length) return x1;
+ x1 = z;
+ x0 = z.copy();
+ view = {
+ x: 0,
+ y: 0,
+ k: 1
+ };
+ return zoom;
};
- scale.copy = function() {
- return d3_scale_ordinal(domain, ranger);
+ zoom.y = function(z) {
+ if (!arguments.length) return y1;
+ y1 = z;
+ y0 = z.copy();
+ view = {
+ x: 0,
+ y: 0,
+ k: 1
+ };
+ return zoom;
};
- return scale.domain(domain);
- }
- function d3_scale_quantile(domain, range) {
+ function location(p) {
+ return [ (p[0] - view.x) / view.k, (p[1] - view.y) / view.k ];
+ }
+ function point(l) {
+ return [ l[0] * view.k + view.x, l[1] * view.k + view.y ];
+ }
+ function scaleTo(s) {
+ view.k = Math.max(scaleExtent[0], Math.min(scaleExtent[1], s));
+ }
+ function translateTo(p, l) {
+ l = point(l);
+ view.x += p[0] - l[0];
+ view.y += p[1] - l[1];
+ }
function rescale() {
- var k = 0, n = domain.length, q = range.length;
- thresholds = [];
- while (++k < q) thresholds[k - 1] = d3.quantile(domain, k / q);
- return scale;
+ if (x1) x1.domain(x0.range().map(function(x) {
+ return (x - view.x) / view.k;
+ }).map(x0.invert));
+ if (y1) y1.domain(y0.range().map(function(y) {
+ return (y - view.y) / view.k;
+ }).map(y0.invert));
}
- function scale(x) {
- if (isNaN(x = +x)) return NaN;
- return range[d3.bisect(thresholds, x)];
+ function zoomstarted(event) {
+ event({
+ type: "zoomstart"
+ });
}
- var thresholds;
- scale.domain = function(x) {
- if (!arguments.length) return domain;
- domain = x.filter(function(d) {
- return !isNaN(d);
- }).sort(d3.ascending);
- return rescale();
- };
- scale.range = function(x) {
- if (!arguments.length) return range;
- range = x;
- return rescale();
- };
- scale.quantiles = function() {
- return thresholds;
- };
- scale.copy = function() {
- return d3_scale_quantile(domain, range);
- };
- return rescale();
- }
- function d3_scale_quantize(x0, x1, range) {
- function scale(x) {
- return range[Math.max(0, Math.min(i, Math.floor(kx * (x - x0))))];
- }
- function rescale() {
- kx = range.length / (x1 - x0);
- i = range.length - 1;
- return scale;
- }
- var kx, i;
- scale.domain = function(x) {
- if (!arguments.length) return [ x0, x1 ];
- x0 = +x[0];
- x1 = +x[x.length - 1];
- return rescale();
- };
- scale.range = function(x) {
- if (!arguments.length) return range;
- range = x;
- return rescale();
- };
- scale.copy = function() {
- return d3_scale_quantize(x0, x1, range);
- };
- return rescale();
- }
- function d3_scale_threshold(domain, range) {
- function scale(x) {
- return range[d3.bisect(domain, x)];
+ function zoomed(event) {
+ rescale();
+ event({
+ type: "zoom",
+ scale: view.k,
+ translate: [ view.x, view.y ]
+ });
}
- scale.domain = function(_) {
- if (!arguments.length) return domain;
- domain = _;
- return scale;
- };
- scale.range = function(_) {
- if (!arguments.length) return range;
- range = _;
- return scale;
- };
- scale.copy = function() {
- return d3_scale_threshold(domain, range);
- };
- return scale;
- }
- function d3_scale_identity(domain) {
- function identity(x) {
- return +x;
+ function zoomended(event) {
+ event({
+ type: "zoomend"
+ });
}
- identity.invert = identity;
- identity.domain = identity.range = function(x) {
- if (!arguments.length) return domain;
- domain = x.map(identity);
- return identity;
- };
- identity.ticks = function(m) {
- return d3_scale_linearTicks(domain, m);
- };
- identity.tickFormat = function(m) {
- return d3_scale_linearTickFormat(domain, m);
- };
- identity.copy = function() {
- return d3_scale_identity(domain);
- };
- return identity;
- }
- function d3_svg_arcInnerRadius(d) {
- return d.innerRadius;
- }
- function d3_svg_arcOuterRadius(d) {
- return d.outerRadius;
- }
- function d3_svg_arcStartAngle(d) {
- return d.startAngle;
- }
- function d3_svg_arcEndAngle(d) {
- return d.endAngle;
- }
- function d3_svg_line(projection) {
- function line(data) {
- function segment() {
- segments.push("M", interpolate(projection(points), tension));
+ function mousedowned() {
+ var target = this, event_ = event.of(target, arguments), eventTarget = d3.event.target, dragged = 0, w = d3.select(d3_window).on(mousemove, moved).on(mouseup, ended), l = location(d3.mouse(target)), dragRestore = d3_event_dragSuppress();
+ d3_selection_interrupt.call(target);
+ zoomstarted(event_);
+ function moved() {
+ dragged = 1;
+ translateTo(d3.mouse(target), l);
+ zoomed(event_);
+ }
+ function ended() {
+ w.on(mousemove, d3_window === target ? mousewheelreset : null).on(mouseup, null);
+ dragRestore(dragged && d3.event.target === eventTarget);
+ zoomended(event_);
+ }
+ }
+ function touchstarted() {
+ var target = this, event_ = event.of(target, arguments), locations0 = {}, distance0 = 0, scale0, eventId = d3.event.changedTouches[0].identifier, touchmove = "touchmove.zoom-" + eventId, touchend = "touchend.zoom-" + eventId, w = d3.select(d3_window).on(touchmove, moved).on(touchend, ended), t = d3.select(target).on(mousedown, null).on(touchstart, started), dragRestore = d3_event_dragSuppress();
+ d3_selection_interrupt.call(target);
+ started();
+ zoomstarted(event_);
+ function relocate() {
+ var touches = d3.touches(target);
+ scale0 = view.k;
+ touches.forEach(function(t) {
+ if (t.identifier in locations0) locations0[t.identifier] = location(t);
+ });
+ return touches;
}
- var segments = [], points = [], i = -1, n = data.length, d, fx = d3_functor(x), fy = d3_functor(y);
- while (++i < n) {
- if (defined.call(this, d = data[i], i)) {
- points.push([ +fx.call(this, d, i), +fy.call(this, d, i) ]);
- } else if (points.length) {
- segment();
- points = [];
+ function started() {
+ var changed = d3.event.changedTouches;
+ for (var i = 0, n = changed.length; i < n; ++i) {
+ locations0[changed[i].identifier] = null;
+ }
+ var touches = relocate(), now = Date.now();
+ if (touches.length === 1) {
+ if (now - touchtime < 500) {
+ var p = touches[0], l = locations0[p.identifier];
+ scaleTo(view.k * 2);
+ translateTo(p, l);
+ d3_eventPreventDefault();
+ zoomed(event_);
+ }
+ touchtime = now;
+ } else if (touches.length > 1) {
+ var p = touches[0], q = touches[1], dx = p[0] - q[0], dy = p[1] - q[1];
+ distance0 = dx * dx + dy * dy;
}
}
- if (points.length) segment();
- return segments.length ? segments.join("") : null;
+ function moved() {
+ var touches = d3.touches(target), p0, l0, p1, l1;
+ for (var i = 0, n = touches.length; i < n; ++i, l1 = null) {
+ p1 = touches[i];
+ if (l1 = locations0[p1.identifier]) {
+ if (l0) break;
+ p0 = p1, l0 = l1;
+ }
+ }
+ if (l1) {
+ var distance1 = (distance1 = p1[0] - p0[0]) * distance1 + (distance1 = p1[1] - p0[1]) * distance1, scale1 = distance0 && Math.sqrt(distance1 / distance0);
+ p0 = [ (p0[0] + p1[0]) / 2, (p0[1] + p1[1]) / 2 ];
+ l0 = [ (l0[0] + l1[0]) / 2, (l0[1] + l1[1]) / 2 ];
+ scaleTo(scale1 * scale0);
+ }
+ touchtime = null;
+ translateTo(p0, l0);
+ zoomed(event_);
+ }
+ function ended() {
+ if (d3.event.touches.length) {
+ var changed = d3.event.changedTouches;
+ for (var i = 0, n = changed.length; i < n; ++i) {
+ delete locations0[changed[i].identifier];
+ }
+ for (var identifier in locations0) {
+ return void relocate();
+ }
+ }
+ w.on(touchmove, null).on(touchend, null);
+ t.on(mousedown, mousedowned).on(touchstart, touchstarted);
+ dragRestore();
+ zoomended(event_);
+ }
+ }
+ function mousewheeled() {
+ var event_ = event.of(this, arguments);
+ if (mousewheelTimer) clearTimeout(mousewheelTimer); else d3_selection_interrupt.call(this),
+ zoomstarted(event_);
+ mousewheelTimer = setTimeout(function() {
+ mousewheelTimer = null;
+ zoomended(event_);
+ }, 50);
+ d3_eventPreventDefault();
+ var point = center || d3.mouse(this);
+ if (!translate0) translate0 = location(point);
+ scaleTo(Math.pow(2, d3_behavior_zoomDelta() * .002) * view.k);
+ translateTo(point, translate0);
+ zoomed(event_);
+ }
+ function mousewheelreset() {
+ translate0 = null;
}
- var x = d3_svg_lineX, y = d3_svg_lineY, defined = d3_true, interpolate = d3_svg_lineLinear, interpolateKey = interpolate.key, tension = .7;
- line.x = function(_) {
- if (!arguments.length) return x;
- x = _;
- return line;
- };
- line.y = function(_) {
- if (!arguments.length) return y;
- y = _;
- return line;
- };
- line.defined = function(_) {
- if (!arguments.length) return defined;
- defined = _;
- return line;
- };
- line.interpolate = function(_) {
- if (!arguments.length) return interpolateKey;
- if (typeof _ === "function") interpolateKey = interpolate = _; else interpolateKey = (interpolate = d3_svg_lineInterpolators.get(_) || d3_svg_lineLinear).key;
- return line;
- };
- line.tension = function(_) {
- if (!arguments.length) return tension;
- tension = _;
- return line;
- };
- return line;
+ function dblclicked() {
+ var event_ = event.of(this, arguments), p = d3.mouse(this), l = location(p), k = Math.log(view.k) / Math.LN2;
+ zoomstarted(event_);
+ scaleTo(Math.pow(2, d3.event.shiftKey ? Math.ceil(k) - 1 : Math.floor(k) + 1));
+ translateTo(p, l);
+ zoomed(event_);
+ zoomended(event_);
+ }
+ return d3.rebind(zoom, event, "on");
+ };
+ var d3_behavior_zoomInfinity = [ 0, Infinity ];
+ var d3_behavior_zoomDelta, d3_behavior_zoomWheel = "onwheel" in d3_document ? (d3_behavior_zoomDelta = function() {
+ return -d3.event.deltaY * (d3.event.deltaMode ? 120 : 1);
+ }, "wheel") : "onmousewheel" in d3_document ? (d3_behavior_zoomDelta = function() {
+ return d3.event.wheelDelta;
+ }, "mousewheel") : (d3_behavior_zoomDelta = function() {
+ return -d3.event.detail;
+ }, "MozMousePixelScroll");
+ function d3_Color() {}
+ d3_Color.prototype.toString = function() {
+ return this.rgb() + "";
+ };
+ d3.hsl = function(h, s, l) {
+ return arguments.length === 1 ? h instanceof d3_Hsl ? d3_hsl(h.h, h.s, h.l) : d3_rgb_parse("" + h, d3_rgb_hsl, d3_hsl) : d3_hsl(+h, +s, +l);
+ };
+ function d3_hsl(h, s, l) {
+ return new d3_Hsl(h, s, l);
}
- function d3_svg_lineX(d) {
- return d[0];
+ function d3_Hsl(h, s, l) {
+ this.h = h;
+ this.s = s;
+ this.l = l;
}
- function d3_svg_lineY(d) {
- return d[1];
+ var d3_hslPrototype = d3_Hsl.prototype = new d3_Color();
+ d3_hslPrototype.brighter = function(k) {
+ k = Math.pow(.7, arguments.length ? k : 1);
+ return d3_hsl(this.h, this.s, this.l / k);
+ };
+ d3_hslPrototype.darker = function(k) {
+ k = Math.pow(.7, arguments.length ? k : 1);
+ return d3_hsl(this.h, this.s, k * this.l);
+ };
+ d3_hslPrototype.rgb = function() {
+ return d3_hsl_rgb(this.h, this.s, this.l);
+ };
+ function d3_hsl_rgb(h, s, l) {
+ var m1, m2;
+ h = isNaN(h) ? 0 : (h %= 360) < 0 ? h + 360 : h;
+ s = isNaN(s) ? 0 : s < 0 ? 0 : s > 1 ? 1 : s;
+ l = l < 0 ? 0 : l > 1 ? 1 : l;
+ m2 = l <= .5 ? l * (1 + s) : l + s - l * s;
+ m1 = 2 * l - m2;
+ function v(h) {
+ if (h > 360) h -= 360; else if (h < 0) h += 360;
+ if (h < 60) return m1 + (m2 - m1) * h / 60;
+ if (h < 180) return m2;
+ if (h < 240) return m1 + (m2 - m1) * (240 - h) / 60;
+ return m1;
+ }
+ function vv(h) {
+ return Math.round(v(h) * 255);
+ }
+ return d3_rgb(vv(h + 120), vv(h), vv(h - 120));
}
- function d3_svg_lineLinear(points) {
- return points.join("L");
+ d3.hcl = function(h, c, l) {
+ return arguments.length === 1 ? h instanceof d3_Hcl ? d3_hcl(h.h, h.c, h.l) : h instanceof d3_Lab ? d3_lab_hcl(h.l, h.a, h.b) : d3_lab_hcl((h = d3_rgb_lab((h = d3.rgb(h)).r, h.g, h.b)).l, h.a, h.b) : d3_hcl(+h, +c, +l);
+ };
+ function d3_hcl(h, c, l) {
+ return new d3_Hcl(h, c, l);
}
- function d3_svg_lineLinearClosed(points) {
- return d3_svg_lineLinear(points) + "Z";
+ function d3_Hcl(h, c, l) {
+ this.h = h;
+ this.c = c;
+ this.l = l;
}
- function d3_svg_lineStepBefore(points) {
- var i = 0, n = points.length, p = points[0], path = [ p[0], ",", p[1] ];
- while (++i < n) path.push("V", (p = points[i])[1], "H", p[0]);
- return path.join("");
+ var d3_hclPrototype = d3_Hcl.prototype = new d3_Color();
+ d3_hclPrototype.brighter = function(k) {
+ return d3_hcl(this.h, this.c, Math.min(100, this.l + d3_lab_K * (arguments.length ? k : 1)));
+ };
+ d3_hclPrototype.darker = function(k) {
+ return d3_hcl(this.h, this.c, Math.max(0, this.l - d3_lab_K * (arguments.length ? k : 1)));
+ };
+ d3_hclPrototype.rgb = function() {
+ return d3_hcl_lab(this.h, this.c, this.l).rgb();
+ };
+ function d3_hcl_lab(h, c, l) {
+ if (isNaN(h)) h = 0;
+ if (isNaN(c)) c = 0;
+ return d3_lab(l, Math.cos(h *= d3_radians) * c, Math.sin(h) * c);
}
- function d3_svg_lineStepAfter(points) {
- var i = 0, n = points.length, p = points[0], path = [ p[0], ",", p[1] ];
- while (++i < n) path.push("H", (p = points[i])[0], "V", p[1]);
- return path.join("");
+ d3.lab = function(l, a, b) {
+ return arguments.length === 1 ? l instanceof d3_Lab ? d3_lab(l.l, l.a, l.b) : l instanceof d3_Hcl ? d3_hcl_lab(l.l, l.c, l.h) : d3_rgb_lab((l = d3.rgb(l)).r, l.g, l.b) : d3_lab(+l, +a, +b);
+ };
+ function d3_lab(l, a, b) {
+ return new d3_Lab(l, a, b);
}
- function d3_svg_lineCardinalOpen(points, tension) {
- return points.length < 4 ? d3_svg_lineLinear(points) : points[1] + d3_svg_lineHermite(points.slice(1, points.length - 1), d3_svg_lineCardinalTangents(points, tension));
+ function d3_Lab(l, a, b) {
+ this.l = l;
+ this.a = a;
+ this.b = b;
}
- function d3_svg_lineCardinalClosed(points, tension) {
- return points.length < 3 ? d3_svg_lineLinear(points) : points[0] + d3_svg_lineHermite((points.push(points[0]), points), d3_svg_lineCardinalTangents([ points[points.length - 2] ].concat(points, [ points[1] ]), tension));
+ var d3_lab_K = 18;
+ var d3_lab_X = .95047, d3_lab_Y = 1, d3_lab_Z = 1.08883;
+ var d3_labPrototype = d3_Lab.prototype = new d3_Color();
+ d3_labPrototype.brighter = function(k) {
+ return d3_lab(Math.min(100, this.l + d3_lab_K * (arguments.length ? k : 1)), this.a, this.b);
+ };
+ d3_labPrototype.darker = function(k) {
+ return d3_lab(Math.max(0, this.l - d3_lab_K * (arguments.length ? k : 1)), this.a, this.b);
+ };
+ d3_labPrototype.rgb = function() {
+ return d3_lab_rgb(this.l, this.a, this.b);
+ };
+ function d3_lab_rgb(l, a, b) {
+ var y = (l + 16) / 116, x = y + a / 500, z = y - b / 200;
+ x = d3_lab_xyz(x) * d3_lab_X;
+ y = d3_lab_xyz(y) * d3_lab_Y;
+ z = d3_lab_xyz(z) * d3_lab_Z;
+ return d3_rgb(d3_xyz_rgb(3.2404542 * x - 1.5371385 * y - .4985314 * z), d3_xyz_rgb(-.969266 * x + 1.8760108 * y + .041556 * z), d3_xyz_rgb(.0556434 * x - .2040259 * y + 1.0572252 * z));
}
- function d3_svg_lineCardinal(points, tension, closed) {
- return points.length < 3 ? d3_svg_lineLinear(points) : points[0] + d3_svg_lineHermite(points, d3_svg_lineCardinalTangents(points, tension));
+ function d3_lab_hcl(l, a, b) {
+ return l > 0 ? d3_hcl(Math.atan2(b, a) * d3_degrees, Math.sqrt(a * a + b * b), l) : d3_hcl(NaN, NaN, l);
}
- function d3_svg_lineHermite(points, tangents) {
- if (tangents.length < 1 || points.length != tangents.length && points.length != tangents.length + 2) {
- return d3_svg_lineLinear(points);
- }
- var quad = points.length != tangents.length, path = "", p0 = points[0], p = points[1], t0 = tangents[0], t = t0, pi = 1;
- if (quad) {
- path += "Q" + (p[0] - t0[0] * 2 / 3) + "," + (p[1] - t0[1] * 2 / 3) + "," + p[0] + "," + p[1];
- p0 = points[1];
- pi = 2;
- }
- if (tangents.length > 1) {
- t = tangents[1];
- p = points[pi];
- pi++;
- path += "C" + (p0[0] + t0[0]) + "," + (p0[1] + t0[1]) + "," + (p[0] - t[0]) + "," + (p[1] - t[1]) + "," + p[0] + "," + p[1];
- for (var i = 2; i < tangents.length; i++, pi++) {
- p = points[pi];
- t = tangents[i];
- path += "S" + (p[0] - t[0]) + "," + (p[1] - t[1]) + "," + p[0] + "," + p[1];
- }
- }
- if (quad) {
- var lp = points[pi];
- path += "Q" + (p[0] + t[0] * 2 / 3) + "," + (p[1] + t[1] * 2 / 3) + "," + lp[0] + "," + lp[1];
- }
- return path;
+ function d3_lab_xyz(x) {
+ return x > .206893034 ? x * x * x : (x - 4 / 29) / 7.787037;
}
- function d3_svg_lineCardinalTangents(points, tension) {
- var tangents = [], a = (1 - tension) / 2, p0, p1 = points[0], p2 = points[1], i = 1, n = points.length;
- while (++i < n) {
- p0 = p1;
- p1 = p2;
- p2 = points[i];
- tangents.push([ a * (p2[0] - p0[0]), a * (p2[1] - p0[1]) ]);
- }
- return tangents;
+ function d3_xyz_lab(x) {
+ return x > .008856 ? Math.pow(x, 1 / 3) : 7.787037 * x + 4 / 29;
}
- function d3_svg_lineBasis(points) {
- if (points.length < 3) return d3_svg_lineLinear(points);
- var i = 1, n = points.length, pi = points[0], x0 = pi[0], y0 = pi[1], px = [ x0, x0, x0, (pi = points[1])[0] ], py = [ y0, y0, y0, pi[1] ], path = [ x0, ",", y0 ];
- d3_svg_lineBasisBezier(path, px, py);
- while (++i < n) {
- pi = points[i];
- px.shift();
- px.push(pi[0]);
- py.shift();
- py.push(pi[1]);
- d3_svg_lineBasisBezier(path, px, py);
- }
- i = -1;
- while (++i < 2) {
- px.shift();
- px.push(pi[0]);
- py.shift();
- py.push(pi[1]);
- d3_svg_lineB
<TRUNCATED>
[08/41] couchdb commit: updated refs/heads/Update-Sidebar-Ui to
c1e1423
Posted by de...@apache.org.
Fauxton: fix intendation
Project: http://git-wip-us.apache.org/repos/asf/couchdb/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb/commit/e7763dfb
Tree: http://git-wip-us.apache.org/repos/asf/couchdb/tree/e7763dfb
Diff: http://git-wip-us.apache.org/repos/asf/couchdb/diff/e7763dfb
Branch: refs/heads/Update-Sidebar-Ui
Commit: e7763dfb2d2ad8119ee883002e60ec7edde791c7
Parents: f2153c0
Author: Robert Kowalski <ro...@kowalski.gd>
Authored: Fri Mar 21 17:25:17 2014 +0100
Committer: Robert Kowalski <ro...@kowalski.gd>
Committed: Fri Mar 21 17:27:50 2014 +0100
----------------------------------------------------------------------
src/fauxton/app/addons/config/views.js | 37 +++++++++++++++--------------
1 file changed, 19 insertions(+), 18 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/couchdb/blob/e7763dfb/src/fauxton/app/addons/config/views.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/config/views.js b/src/fauxton/app/addons/config/views.js
index 8453d90..9f427ac 100644
--- a/src/fauxton/app/addons/config/views.js
+++ b/src/fauxton/app/addons/config/views.js
@@ -81,27 +81,28 @@ function(app, FauxtonAPI, Config, Components) {
},
saveAndRender: function (event) {
var options = {};
- $input = this.$(event.currentTarget).parents('td').find(".js-value-input");
- options[$input.attr('name')] = $input.val();
-
- if ($input.attr('name')==='name'){
- if (this.uniqueName($input.val())){
- this.error = FauxtonAPI.addNotification({
- msg: "This config already exists, enter a unique name",
- type: "error",
- clear: true
- });
- } else {
- var newModel = this.model.clone();
- newModel.save(options);
- this.model.destroy();
- this.model = newModel;
- this.render();
- }
+ $input = this.$(event.currentTarget).parents('td').find(".js-value-input");
+
+ options[$input.attr('name')] = $input.val();
+
+ if ($input.attr('name')==='name'){
+ if (this.uniqueName($input.val())){
+ this.error = FauxtonAPI.addNotification({
+ msg: "This config already exists, enter a unique name",
+ type: "error",
+ clear: true
+ });
} else {
+ var newModel = this.model.clone();
+ newModel.save(options);
+ this.model.destroy();
+ this.model = newModel;
+ this.render();
+ }
+ } else {
this.model.save(options);
this.render();
- }
+ }
}
});
[18/41] couchdb commit: updated refs/heads/Update-Sidebar-Ui to
c1e1423
Posted by de...@apache.org.
Fauxton: Redirected to correct page after login
Fixes COUCHDB-2209
Project: http://git-wip-us.apache.org/repos/asf/couchdb/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb/commit/198bea34
Tree: http://git-wip-us.apache.org/repos/asf/couchdb/tree/198bea34
Diff: http://git-wip-us.apache.org/repos/asf/couchdb/diff/198bea34
Branch: refs/heads/Update-Sidebar-Ui
Commit: 198bea3479dfecac13ab1a3e95f902b8eba02f7d
Parents: 0f7be28
Author: Garren Smith <ga...@gmail.com>
Authored: Tue Mar 25 17:54:33 2014 +0200
Committer: Garren Smith <ga...@gmail.com>
Committed: Tue Mar 25 17:54:33 2014 +0200
----------------------------------------------------------------------
src/fauxton/app/addons/auth/base.js | 3 ++-
src/fauxton/app/addons/auth/resources.js | 21 +++++++++++++++++++-
src/fauxton/app/addons/auth/routes.js | 13 ++++++++++--
.../app/addons/auth/templates/noAccess.html | 4 +++-
src/fauxton/app/core/auth.js | 2 --
5 files changed, 36 insertions(+), 7 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/couchdb/blob/198bea34/src/fauxton/app/addons/auth/base.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/auth/base.js b/src/fauxton/app/addons/auth/base.js
index c7bbb04..b8545fc 100644
--- a/src/fauxton/app/addons/auth/base.js
+++ b/src/fauxton/app/addons/auth/base.js
@@ -52,7 +52,8 @@ function(app, FauxtonAPI, Auth) {
};
var authDenied = function () {
- FauxtonAPI.navigate('/noAccess', {replace: true});
+ var url = window.location.hash.replace('#','');
+ FauxtonAPI.navigate('/noAccess?urlback=' + url, {replace: true});
};
FauxtonAPI.auth.registerAuth(auth);
http://git-wip-us.apache.org/repos/asf/couchdb/blob/198bea34/src/fauxton/app/addons/auth/resources.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/auth/resources.js b/src/fauxton/app/addons/auth/resources.js
index 71744e3..edfd708 100644
--- a/src/fauxton/app/addons/auth/resources.js
+++ b/src/fauxton/app/addons/auth/resources.js
@@ -252,6 +252,9 @@ function (app, FauxtonAPI, CouchdbSession) {
Auth.LoginView = FauxtonAPI.View.extend({
template: 'addons/auth/templates/login',
+ initialize: function (options) {
+ this.urlBack = options.urlBack || "";
+ },
events: {
"submit #login": "login"
@@ -263,10 +266,16 @@ function (app, FauxtonAPI, CouchdbSession) {
var that = this,
username = this.$('#username').val(),
password = this.$('#password').val(),
+ urlBack = this.urlBack,
promise = this.model.login(username, password);
promise.then(function () {
FauxtonAPI.addNotification({msg: FauxtonAPI.session.messages.loggedIn });
+
+ if (urlBack) {
+ return FauxtonAPI.navigate(urlBack);
+ }
+
FauxtonAPI.navigate('/');
});
@@ -346,7 +355,17 @@ function (app, FauxtonAPI, CouchdbSession) {
});
Auth.NoAccessView = FauxtonAPI.View.extend({
- template: "addons/auth/templates/noAccess"
+ template: "addons/auth/templates/noAccess",
+
+ initialize: function (options) {
+ this.urlBack = options.urlBack || "";
+ },
+
+ serialize: function () {
+ return {
+ urlBack: this.urlBack
+ };
+ }
});
return Auth;
http://git-wip-us.apache.org/repos/asf/couchdb/blob/198bea34/src/fauxton/app/addons/auth/routes.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/auth/routes.js b/src/fauxton/app/addons/auth/routes.js
index fe40a77..74395e8 100644
--- a/src/fauxton/app/addons/auth/routes.js
+++ b/src/fauxton/app/addons/auth/routes.js
@@ -21,15 +21,21 @@ function(app, FauxtonAPI, Auth) {
layout: 'one_pane',
routes: {
+ 'login?*extra': 'login',
'login': 'login',
'logout': 'logout',
'createAdmin': 'createAdmin',
+ 'noAccess?*extra': 'noAccess',
'noAccess': 'noAccess'
},
login: function () {
+ var urlBack = app.getParams().urlback;
this.crumbs = [{name: 'Login', link:"#"}];
- this.setView('#dashboard-content', new Auth.LoginView({model: FauxtonAPI.session}));
+ this.setView('#dashboard-content', new Auth.LoginView({
+ model: FauxtonAPI.session,
+ urlBack: urlBack
+ }));
},
logout: function () {
@@ -50,8 +56,11 @@ function(app, FauxtonAPI, Auth) {
},
noAccess: function () {
+ var urlBack = app.getParams().urlback;
this.crumbs = [{name: 'Access Denied', link:"#"}];
- this.setView('#dashboard-content', new Auth.NoAccessView());
+ this.setView('#dashboard-content', new Auth.NoAccessView({
+ urlBack: urlBack
+ }));
this.apiUrl = 'noAccess';
},
});
http://git-wip-us.apache.org/repos/asf/couchdb/blob/198bea34/src/fauxton/app/addons/auth/templates/noAccess.html
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/auth/templates/noAccess.html b/src/fauxton/app/addons/auth/templates/noAccess.html
index ceff992..ffa736e 100644
--- a/src/fauxton/app/addons/auth/templates/noAccess.html
+++ b/src/fauxton/app/addons/auth/templates/noAccess.html
@@ -15,6 +15,8 @@ the License.
<div class="span12">
<h2> Access Denied </h2>
- <p> You do not have permission to view this page. <br/> You might need to <a href="#login"> login </a> to view this page/ </p>
+ <p> You do not have permission to view this page. <br/>
+ You might need to <a href="#login<% if (urlBack){ %>?urlback=<%=urlBack%> <% } %> "> login </a> to view this page/
+ </p>
</div>
http://git-wip-us.apache.org/repos/asf/couchdb/blob/198bea34/src/fauxton/app/core/auth.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/core/auth.js b/src/fauxton/app/core/auth.js
index 15cf566..19e4a8c 100644
--- a/src/fauxton/app/core/auth.js
+++ b/src/fauxton/app/core/auth.js
@@ -60,8 +60,6 @@ function(FauxtonAPI, Backbone) {
}
});
-// FauxtonAPI.auth = new Auth();
-
return Auth;
});
[25/41] couchdb commit: updated refs/heads/Update-Sidebar-Ui to
c1e1423
Posted by de...@apache.org.
Require.js config to support d3 v3 update.
Project: http://git-wip-us.apache.org/repos/asf/couchdb/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb/commit/6301060f
Tree: http://git-wip-us.apache.org/repos/asf/couchdb/tree/6301060f
Diff: http://git-wip-us.apache.org/repos/asf/couchdb/diff/6301060f
Branch: refs/heads/Update-Sidebar-Ui
Commit: 6301060fdbb9d5505ffd43f8b0df52b6c303b6ef
Parents: 95d6d6b
Author: Christian Hogan <gi...@infliction.org>
Authored: Fri Mar 21 15:02:28 2014 -0400
Committer: suelockwood <de...@apache.org>
Committed: Tue Mar 25 15:19:18 2014 -0400
----------------------------------------------------------------------
src/fauxton/app/config.js | 8 ++++++++
1 file changed, 8 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/couchdb/blob/6301060f/src/fauxton/app/config.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/config.js b/src/fauxton/app/config.js
index 98be9c6..d33f3b8 100644
--- a/src/fauxton/app/config.js
+++ b/src/fauxton/app/config.js
@@ -53,6 +53,8 @@ require.config({
deps: ["jquery"],
exports: "Bootstrap"
},
+
+ "nv.d3": ["d3.global"],
"plugins/prettify": [],
"plugins/beautify": [],
@@ -60,3 +62,9 @@ require.config({
"plugins/jquery.form": ["jquery"]
}
});
+
+define("d3.global", ["d3"], function(_) {
+ d3 = _;
+});
+
+require(["d3", "nv.d3"], function(d3, nvd3) {});
[09/41] couchdb commit: updated refs/heads/Update-Sidebar-Ui to
c1e1423
Posted by de...@apache.org.
Fauxton: fix global var
Project: http://git-wip-us.apache.org/repos/asf/couchdb/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb/commit/ca5913ed
Tree: http://git-wip-us.apache.org/repos/asf/couchdb/tree/ca5913ed
Diff: http://git-wip-us.apache.org/repos/asf/couchdb/diff/ca5913ed
Branch: refs/heads/Update-Sidebar-Ui
Commit: ca5913eda5cb2d70d38ed7ed286bfd835a2b303d
Parents: e7763df
Author: Robert Kowalski <ro...@kowalski.gd>
Authored: Fri Mar 21 17:25:52 2014 +0100
Committer: Robert Kowalski <ro...@kowalski.gd>
Committed: Fri Mar 21 17:27:58 2014 +0100
----------------------------------------------------------------------
src/fauxton/app/addons/config/views.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/couchdb/blob/ca5913ed/src/fauxton/app/addons/config/views.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/config/views.js b/src/fauxton/app/addons/config/views.js
index 9f427ac..7952182 100644
--- a/src/fauxton/app/addons/config/views.js
+++ b/src/fauxton/app/addons/config/views.js
@@ -80,7 +80,7 @@ function(app, FauxtonAPI, Config, Components) {
return {option: this.model.toJSON()};
},
saveAndRender: function (event) {
- var options = {};
+ var options = {},
$input = this.$(event.currentTarget).parents('td').find(".js-value-input");
options[$input.attr('name')] = $input.val();
[23/41] couchdb commit: updated refs/heads/Update-Sidebar-Ui to
c1e1423
Posted by de...@apache.org.
Updating pie chart to reflect nvd3's removal of pie.values(), tweaking CSS to make pie chart fit all nice like.
Project: http://git-wip-us.apache.org/repos/asf/couchdb/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb/commit/7296e53c
Tree: http://git-wip-us.apache.org/repos/asf/couchdb/tree/7296e53c
Diff: http://git-wip-us.apache.org/repos/asf/couchdb/diff/7296e53c
Branch: refs/heads/Update-Sidebar-Ui
Commit: 7296e53c8dcd5d69d83bd04a4421887390c06816
Parents: b125530
Author: Christian Hogan <gi...@infliction.org>
Authored: Tue Mar 25 14:43:36 2014 -0400
Committer: suelockwood <de...@apache.org>
Committed: Tue Mar 25 15:19:18 2014 -0400
----------------------------------------------------------------------
src/fauxton/app/addons/stats/assets/less/stats.less | 5 +++++
src/fauxton/app/addons/stats/templates/pie_table.html | 6 +++++-
src/fauxton/app/addons/stats/views.js | 7 +++----
3 files changed, 13 insertions(+), 5 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/couchdb/blob/7296e53c/src/fauxton/app/addons/stats/assets/less/stats.less
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/stats/assets/less/stats.less b/src/fauxton/app/addons/stats/assets/less/stats.less
index 7ec88b9..43ddb3b 100644
--- a/src/fauxton/app/addons/stats/assets/less/stats.less
+++ b/src/fauxton/app/addons/stats/assets/less/stats.less
@@ -13,3 +13,8 @@
.datatypes {
padding: 0 15px;
}
+
+.span5 {
+ height:450px;
+ min-width: 450px;
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/couchdb/blob/7296e53c/src/fauxton/app/addons/stats/templates/pie_table.html
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/stats/templates/pie_table.html b/src/fauxton/app/addons/stats/templates/pie_table.html
index 1fa781a..8c4682c 100644
--- a/src/fauxton/app/addons/stats/templates/pie_table.html
+++ b/src/fauxton/app/addons/stats/templates/pie_table.html
@@ -46,5 +46,9 @@ the License.
</table>
</div>
- <svg id="<%= datatype %>_graph"></svg>
+ <div class="span5">
+ <center>
+ <svg id="<%= datatype %>_graph"></svg>
+ </center>
+ </div>
</div>
http://git-wip-us.apache.org/repos/asf/couchdb/blob/7296e53c/src/fauxton/app/addons/stats/views.js
----------------------------------------------------------------------
diff --git a/src/fauxton/app/addons/stats/views.js b/src/fauxton/app/addons/stats/views.js
index 9dd9cbc..c8374ad 100644
--- a/src/fauxton/app/addons/stats/views.js
+++ b/src/fauxton/app/addons/stats/views.js
@@ -70,21 +70,20 @@ function(app, FauxtonAPI,Stats) {
series = _.sortBy(series, function(d){return -d.y;});
nv.addGraph(function() {
- var width = 550,
- height = 400;
+ var width = 440,
+ height = 440;
var chart = nv.models.pieChart()
.x(function(d) { return d.key; })
.y(function(d) { return d.y; })
.showLabels(true)
.showLegend(false)
- .values(function(d) { return d; })
.color(d3.scale.category10().range())
.width(width)
.height(height);
d3.select(chartelem)
- .datum([series])
+ .datum(series)
.transition().duration(300)
.attr('width', width)
.attr('height', height)
[28/41] couchdb commit: updated refs/heads/Update-Sidebar-Ui to
c1e1423
Posted by de...@apache.org.
clarified what a complex key is in view collation
Project: http://git-wip-us.apache.org/repos/asf/couchdb/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb/commit/1fb7cea2
Tree: http://git-wip-us.apache.org/repos/asf/couchdb/tree/1fb7cea2
Diff: http://git-wip-us.apache.org/repos/asf/couchdb/diff/1fb7cea2
Branch: refs/heads/Update-Sidebar-Ui
Commit: 1fb7cea25b60585b16bdd786cd3e2b299fa384df
Parents: bea5c94
Author: BigBlueHat <by...@bigbluehat.com>
Authored: Tue Mar 25 16:45:50 2014 -0400
Committer: BigBlueHat <by...@bigbluehat.com>
Committed: Tue Mar 25 16:45:54 2014 -0400
----------------------------------------------------------------------
share/doc/src/couchapp/views/collation.rst | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/couchdb/blob/1fb7cea2/share/doc/src/couchapp/views/collation.rst
----------------------------------------------------------------------
diff --git a/share/doc/src/couchapp/views/collation.rst b/share/doc/src/couchapp/views/collation.rst
index 9c2f5c7..9b11b15 100644
--- a/share/doc/src/couchapp/views/collation.rst
+++ b/share/doc/src/couchapp/views/collation.rst
@@ -32,8 +32,8 @@ property serves as the key, thus the result will be sorted by ``LastName``:
}
}
-CouchDB allows arbitrary JSON structures to be used as keys. You can use complex
-keys for fine-grained control over sorting and grouping.
+CouchDB allows arbitrary JSON structures to be used as keys. You can use JSON
+arrays as keys for fine-grained control over sorting and grouping.
Examples
========
[35/41] couchdb commit: updated refs/heads/Update-Sidebar-Ui to
c1e1423
Posted by de...@apache.org.
s/max/max_count
Project: http://git-wip-us.apache.org/repos/asf/couchdb/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb/commit/83cc8136
Tree: http://git-wip-us.apache.org/repos/asf/couchdb/tree/83cc8136
Diff: http://git-wip-us.apache.org/repos/asf/couchdb/diff/83cc8136
Branch: refs/heads/Update-Sidebar-Ui
Commit: 83cc8136158dd526b74e6953ef2012704298cf57
Parents: 27cc89c
Author: Robert Newson <rn...@apache.org>
Authored: Thu Mar 27 13:05:22 2014 +0000
Committer: Robert Newson <rn...@apache.org>
Committed: Thu Mar 27 13:06:16 2014 +0000
----------------------------------------------------------------------
src/couchdb/couch_httpd_misc_handlers.erl | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/couchdb/blob/83cc8136/src/couchdb/couch_httpd_misc_handlers.erl
----------------------------------------------------------------------
diff --git a/src/couchdb/couch_httpd_misc_handlers.erl b/src/couchdb/couch_httpd_misc_handlers.erl
index 67e3a12..c86f5c7 100644
--- a/src/couchdb/couch_httpd_misc_handlers.erl
+++ b/src/couchdb/couch_httpd_misc_handlers.erl
@@ -105,7 +105,7 @@ handle_restart_req(Req) ->
handle_uuids_req(#httpd{method='GET'}=Req) ->
- Max = list_to_integer(couch_config:get("uuids","max","1000")),
+ Max = list_to_integer(couch_config:get("uuids","max_count","1000")),
Count = list_to_integer(couch_httpd:qs_value(Req, "count", "1")),
case Count > Max of
true -> throw({forbidden, <<"count parameter too large">>});
[14/41] couchdb commit: updated refs/heads/Update-Sidebar-Ui to
c1e1423
Posted by de...@apache.org.
fix wording in json-structure
Project: http://git-wip-us.apache.org/repos/asf/couchdb/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb/commit/ebbee3c5
Tree: http://git-wip-us.apache.org/repos/asf/couchdb/tree/ebbee3c5
Diff: http://git-wip-us.apache.org/repos/asf/couchdb/diff/ebbee3c5
Branch: refs/heads/Update-Sidebar-Ui
Commit: ebbee3c58390430b5095ba9977720f7f409bab3f
Parents: a7a6d2e
Author: Andy Wenk <an...@nms.de>
Authored: Thu Jan 30 22:00:28 2014 +0100
Committer: Andy Wenk <an...@nms.de>
Committed: Fri Mar 21 22:54:29 2014 +0100
----------------------------------------------------------------------
share/doc/src/json-structure.rst | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/couchdb/blob/ebbee3c5/share/doc/src/json-structure.rst
----------------------------------------------------------------------
diff --git a/share/doc/src/json-structure.rst b/share/doc/src/json-structure.rst
index ab3ae45..68137d2 100644
--- a/share/doc/src/json-structure.rst
+++ b/share/doc/src/json-structure.rst
@@ -481,10 +481,10 @@ Response object
+--------------------------------+---------------------------------------------+
.. warning::
- The ``body``, ``base64`` and ``json`` object keys overlapp each other
- where in the last one wins. Since most implementations of key-value objects do
- not preserve the key order, confusing situations can emerge. The same applies,
- when they are mixed. Try to use only one of them.
+ The ``body``, ``base64`` and ``json`` object keys are overlapping each other
+ where the last one wins. Since most realizations of key-value objects do
+ not preserve the key order or if they are mixed, confusing situations can
+ occure. Try to use only one of them.
.. note::
Any custom property makes CouchDB raise an internal exception.