modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/detail/monitoring/table/CompositeGroupD3GraphListView.java
| 23
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/detail/monitoring/table/CompositeGroupD3MultiLineGraph.java
| 56
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/detail/monitoring/table/CompositeGroupNvD3MultiLineGraph.java
| 74
modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/CoreGUI.gwt.xml
| 1
modules/enterprise/gui/coregui/src/main/webapp/js/nv.d3.js
|13048 ----------
modules/enterprise/gui/coregui/src/main/webapp/js/nv.d3.min.js
| 6
6 files changed, 62 insertions(+), 13146 deletions(-)
New commits:
commit a05f4c169c67035d6466713be5a3a753f1119c8d
Author: Mike Thompson <mithomps(a)redhat.com>
Date: Tue Jul 9 13:02:08 2013 -0700
Remove nvd3.js charting library in favor of base d3.js.
diff --git
a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/detail/monitoring/table/CompositeGroupNvD3MultiLineGraph.java
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/detail/monitoring/table/CompositeGroupNvD3MultiLineGraph.java
deleted file mode 100644
index d2ae7ef..0000000
---
a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/detail/monitoring/table/CompositeGroupNvD3MultiLineGraph.java
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * RHQ Management Platform
- * Copyright (C) 2005-2012 Red Hat, Inc.
- * All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-package org.rhq.enterprise.gui.coregui.client.inventory.groups.detail.monitoring.table;
-
-
-
-/**
- * A MultiLine version of the Composite group single metric multiple resource charts.
- *
- * @author Mike Thompson
- */
-@Deprecated
-public final class CompositeGroupNvD3MultiLineGraph extends
CompositeGroupD3GraphListView
-{
-
- public CompositeGroupNvD3MultiLineGraph(int groupId, int defId, boolean isAutogroup)
- {
- super(groupId, defId, isAutogroup);
- }
-
-
-
- @Override
- public native void drawJsniChart() /*-{
- console.log("Draw nvd3 charts for composite multiline graph");
- var chartId =
this.@org.rhq.enterprise.gui.coregui.client.inventory.groups.detail.monitoring.table.CompositeGroupD3GraphListView::getChartId()(),
- chartHandle = "#mChart-"+chartId,
- chartSelection = chartHandle + " svg",
- yAxisUnits =
this.@org.rhq.enterprise.gui.coregui.client.inventory.groups.detail.monitoring.table.CompositeGroupD3GraphListView::getYAxisUnits()(),
- xAxisLabel =
this.@org.rhq.enterprise.gui.coregui.client.inventory.groups.detail.monitoring.table.CompositeGroupD3GraphListView::getXAxisTitle()(),
- xAxisTimeFormat =
this.@org.rhq.enterprise.gui.coregui.client.inventory.groups.detail.monitoring.table.CompositeGroupD3MultiLineGraph::getXAxisTimeFormatHoursMinutes()();
- json =
eval(this.@org.rhq.enterprise.gui.coregui.client.inventory.groups.detail.monitoring.table.CompositeGroupD3GraphListView::getJsonMetrics()());
-
- $wnd.nv.addGraph(function() {
- var chart = $wnd.nv.models.lineChart();
-
- chart.xAxis.axisLabel(xAxisLabel)
- .tickFormat(function(d) { return
$wnd.d3.time.format(xAxisTimeFormat)(new Date(d)) });
-
- chart.yAxis
- .axisLabel(yAxisUnits)
- .tickFormat($wnd.d3.format('.02f'));
-
- $wnd.d3.select(chartSelection)
- .datum(json)
- .transition().duration(300)
- .call(chart);
-
- $wnd.nv.utils.windowResize(chart.update);
-
- return chart;
- });
-
- }-*/;
-
-
-
-}
diff --git
a/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/CoreGUI.gwt.xml
b/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/CoreGUI.gwt.xml
index 51bec0a..8ef78e0 100644
---
a/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/CoreGUI.gwt.xml
+++
b/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/CoreGUI.gwt.xml
@@ -58,7 +58,6 @@
<script src="/coregui/js/jquery-1.7.2.min.js"/>
<script src="/coregui/js/jquery.sparkline-2.1.min.js"/>
<script src="/coregui/js/d3.v3.min.js"/>
- <script src="/coregui/js/nv.d3.min.js"/>
<script src="/coregui/js/jquery.tipsy.js"/>
diff --git a/modules/enterprise/gui/coregui/src/main/webapp/js/nv.d3.js
b/modules/enterprise/gui/coregui/src/main/webapp/js/nv.d3.js
deleted file mode 100755
index 62ca71e..0000000
--- a/modules/enterprise/gui/coregui/src/main/webapp/js/nv.d3.js
+++ /dev/null
@@ -1,13048 +0,0 @@
-(function(){
-
-var nv = window.nv || {};
-
-nv.version = '0.0.1a';
-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.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
-
-nv.dispatch = d3.dispatch('render_start', 'render_end');
-
-// *************************************************************************
-// Development render timers - disabled if dev = false
-
-if (nv.dev) {
- nv.dispatch.on('render_start', function(e) {
- nv.logs.startTime = +new Date();
- });
-
- nv.dispatch.on('render_end', function(e) {
- nv.logs.endTime = +new Date();
- nv.logs.totalTime = nv.logs.endTime - nv.logs.startTime;
- nv.log('total', nv.logs.totalTime); // used for development, to keep track of
graph generation times
- });
-}
-
-// ********************************************
-// Public Core NV functions
-
-// Logs all arguments, and returns the last so you can test things in place
-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) {
- var log = Function.prototype.bind.call(console.log, console);
- log.apply(console, arguments);
- }
- return arguments[arguments.length - 1];
-};
-
-
-nv.render = function render(step) {
- step = step || 1; // number of graphs to generate in each timeout loop
-
- nv.render.active = true;
- nv.dispatch.render_start();
-
- setTimeout(function() {
- var chart, graph;
-
- for (var i = 0; i < step && (graph = nv.render.queue[i]); i++) {
- chart = graph.generate();
- if (typeof graph.callback == typeof(Function)) graph.callback(chart);
- nv.graphs.push(chart);
- }
-
- nv.render.queue.splice(0, i);
-
- if (nv.render.queue.length) setTimeout(arguments.callee, 0);
- else { nv.render.active = false; nv.dispatch.render_end(); }
- }, 0);
-};
-
-nv.render.active = false;
-nv.render.queue = [];
-
-nv.addGraph = function(obj) {
- if (typeof arguments[0] === typeof(Function))
- obj = {generate: arguments[0], callback: arguments[1]};
-
- nv.render.queue.push(obj);
-
- if (!nv.render.active) nv.render();
-};
-
-nv.identity = function(d) { return d; };
-
-nv.strip = function(s) { return s.replace(/(\s|&)/g,''); };
-
-function daysInMonth(month,year) {
- return (new Date(year, month+1, 0)).getDate();
-}
-
-function d3_time_range(floor, step, number) {
- return function(t0, t1, dt) {
- var time = floor(t0), times = [];
- if (time < t0) step(time);
- if (dt > 1) {
- while (time < t1) {
- var date = new Date(+time);
- if ((number(date) % dt === 0)) times.push(date);
- step(time);
- }
- } else {
- while (time < t1) { times.push(new Date(+time)); step(time); }
- }
- return times;
- };
-}
-
-d3.time.monthEnd = function(date) {
- return new Date(date.getFullYear(), date.getMonth(), 0);
-};
-
-d3.time.monthEnds = d3_time_range(d3.time.monthEnd, function(date) {
- date.setUTCDate(date.getUTCDate() + 1);
- date.setDate(daysInMonth(date.getMonth() + 1, date.getFullYear()));
- }, function(date) {
- return date.getMonth();
- }
-);
-
-
-/*****
- * A no-frills tooltip implementation.
- *****/
-
-
-(function() {
-
- var nvtooltip = window.nv.tooltip = {};
-
- nvtooltip.show = function(pos, content, gravity, dist, parentContainer, classes) {
-
- var container = document.createElement('div');
- container.className = 'nvtooltip ' + (classes ? classes :
'xy-tooltip');
-
- gravity = gravity || 's';
- dist = dist || 20;
-
- 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.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);
- }
- } while( Elem = Elem.offsetParent );
- return offsetTop;
- }
-
- var tooltipLeft = function ( Elem ) {
- var offsetLeft = left;
- do {
- if( !isNaN( Elem.offsetLeft ) ) {
- offsetLeft += (Elem.offsetLeft);
- }
- } 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.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
-
- return container;
- };
-
- nvtooltip.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);
- };
-
-
-})();
-
-nv.utils.windowSize = function() {
- // Sane defaults
- var size = {width: 640, height: 480};
-
- // Earlier IE uses Doc.body
- if (document.body && document.body.offsetWidth) {
- size.width = document.body.offsetWidth;
- size.height = document.body.offsetHeight;
- }
-
- // IE can use depending on mode it is in
- if (document.compatMode=='CSS1Compat' &&
- document.documentElement &&
- document.documentElement.offsetWidth ) {
- size.width = document.documentElement.offsetWidth;
- size.height = document.documentElement.offsetHeight;
- }
-
- // Most recent browsers use
- if (window.innerWidth && window.innerHeight) {
- size.width = window.innerWidth;
- size.height = window.innerHeight;
- }
- return (size);
-};
-
-
-
-// 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){
- var oldresize = window.onresize;
-
- window.onresize = function(e) {
- if (typeof oldresize == 'function') oldresize(e);
- fun(e);
- }
-}
-
-// Backwards compatible way to implement more d3-like coloring of graphs.
-// If passed an array, wrap it in a function which implements the old default
-// behavior
-nv.utils.getColor = function(color) {
- if (!arguments.length) return nv.utils.defaultColor(); //if you pass in nothing, get
default colors back
-
- if( Object.prototype.toString.call( color ) === '[object Array]' )
- return function(d, i) { return d.color || color[i % color.length]; };
- else
- return color;
- //can't really help it if someone passes rubbish as color
-}
-
-// Default color chooser uses the index of an object as before.
-nv.utils.defaultColor = function() {
- var colors = d3.scale.category20().range();
- return function(d, i) { return d.color || colors[i % colors.length] };
-}
-
-
-// Returns a color function that takes the result of 'getKey' for each series
and
-// looks for a corresponding color from the dictionary,
-nv.utils.customTheme = function(dictionary, getKey, defaultColors) {
- getKey = getKey || function(series) { return series.key }; // use default series.key if
getKey is undefined
- defaultColors = defaultColors || d3.scale.category20().range(); //default color
function
-
- var defIndex = defaultColors.length; //current default color (going in reverse)
-
- return function(series, index) {
- var key = getKey(series);
-
- if (!defIndex) defIndex = defaultColors.length; //used all the default colors, start
over
-
- if (typeof dictionary[key] !== "undefined")
- return (typeof dictionary[key] === "function") ? dictionary[key]() :
dictionary[key];
- else
- return defaultColors[--defIndex]; // no match in dictionary, use default color
- }
-}
-
-
-
-// From the PJAX example on
d3js.org, while this is not really directly needed
-// it's a very cool method for doing pjax, I may expand upon it a little bit,
-// open to suggestions on anything that may be useful
-nv.utils.pjax = function(links, content) {
- d3.selectAll(links).on("click", function() {
- history.pushState(this.href, this.textContent, this.href);
- load(this.href);
- d3.event.preventDefault();
- });
-
- function load(href) {
- d3.html(href, function(fragment) {
- var target = d3.select(content).node();
- target.parentNode.replaceChild(d3.select(fragment).select(content).node(),
target);
- nv.utils.pjax(links, content);
- });
- }
-
- d3.select(window).on("popstate", function() {
- if (d3.event.state) load(d3.event.state);
- });
-}
-
-/* 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.
-Forumla is : text.length * font-size * constant_factor
-*/
-nv.utils.calcApproxTextWidth = function (svgTextElem) {
- if (svgTextElem instanceof d3.selection) {
- var fontSize =
parseInt(svgTextElem.style("font-size").replace("px",""));
- var textLength = svgTextElem.text().length;
-
- return textLength * fontSize * 0.5;
- }
- return 0;
-};
-nv.models.axis = function() {
-
- //============================================================
- // Public Variables with Default Settings
- //------------------------------------------------------------
-
- var axis = d3.svg.axis()
- ;
-
- var margin = {top: 0, right: 0, bottom: 0, left: 0}
- , width = 75 //only used for tickLabel currently
- , height = 60 //only used for tickLabel currently
- , scale = d3.scale.linear()
- , axisLabelText = null
- , showMaxMin = true //TODO: showMaxMin should be disabled on all ordinal scaled axes
- , highlightZero = true
- , rotateLabels = 0
- , rotateYLabel = true
- , staggerLabels = false
- , isOrdinal = false
- , ticks = null
- ;
-
- axis
- .scale(scale)
- .orient('bottom')
- .tickFormat(function(d) { return d })
- ;
-
- //============================================================
-
-
- //============================================================
- // Private Variables
- //------------------------------------------------------------
-
- var scale0;
-
- //============================================================
-
-
- function chart(selection) {
- selection.each(function(data) {
- var container = d3.select(this);
-
-
- //------------------------------------------------------------
- // Setup containers and skeleton of chart
-
- var wrap = container.selectAll('g.nv-wrap.nv-axis').data([data]);
- var wrapEnter = wrap.enter().append('g').attr('class', 'nvd3
nv-wrap nv-axis');
- var gEnter = wrapEnter.append('g');
- var g = wrap.select('g')
-
- //------------------------------------------------------------
-
-
- if (ticks !== null)
- axis.ticks(ticks);
- else if (axis.orient() == 'top' || axis.orient() == 'bottom')
- axis.ticks(Math.abs(scale.range()[1] - scale.range()[0]) / 100);
-
-
- //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);
-
- scale0 = scale0 || axis.scale();
-
- var fmt = axis.tickFormat();
- if (fmt == null) {
- fmt = scale0.tickFormat();
- }
-
- var axisLabel = g.selectAll('text.nv-axislabel')
- .data([axisLabelText || null]);
- axisLabel.exit().remove();
- switch (axis.orient()) {
- case 'top':
- 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]));
- axisLabel
- .attr('text-anchor', 'middle')
- .attr('y', 0)
- .attr('x', w/2);
- if (showMaxMin) {
- var axisMaxMin = wrap.selectAll('g.nv-axisMaxMin')
- .data(scale.domain());
- axisMaxMin.enter().append('g').attr('class',
'nv-axisMaxMin').append('text');
- axisMaxMin.exit().remove();
- axisMaxMin
- .attr('transform', function(d,i) {
- return 'translate(' + scale(d) + ',0)'
- })
- .select('text')
- .attr('dy', '0em')
- .attr('y', -axis.tickPadding())
- .attr('text-anchor', 'middle')
- .text(function(d,i) {
- var v = fmt(d);
- return ('' + v).match('NaN') ? '' : v;
- });
- d3.transition(axisMaxMin)
- .attr('transform', function(d,i) {
- return 'translate(' + scale.range()[i] + ',0)'
- });
- }
- break;
- case 'bottom':
- var xLabelMargin = 36;
- var maxTextWidth = 30;
- var xTicks = g.selectAll('g').select("text");
- if (rotateLabels%360) {
- //Calculate the longest xTick width
- xTicks.each(function(d,i){
- var width = this.getBBox().width;
- if(width > maxTextWidth) maxTextWidth = width;
- });
- //Convert to radians before calculating sin. Add 30 to margin for healthy
padding.
- var sin = Math.abs(Math.sin(rotateLabels*Math.PI/180));
- var xLabelMargin = (sin ? sin*maxTextWidth : maxTextWidth)+30;
- //Rotate all xTicks
- xTicks
- .attr('transform', function(d,i,j) { return 'rotate(' +
rotateLabels + ' 0,0)' })
- .attr('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]));
- axisLabel
- .attr('text-anchor', 'middle')
- .attr('y', xLabelMargin)
- .attr('x', w/2);
- if (showMaxMin) {
- //if (showMaxMin && !isOrdinal) {
- var axisMaxMin = wrap.selectAll('g.nv-axisMaxMin')
- //.data(scale.domain())
- .data([scale.domain()[0], scale.domain()[scale.domain().length
- 1]]);
- axisMaxMin.enter().append('g').attr('class',
'nv-axisMaxMin').append('text');
- axisMaxMin.exit().remove();
- axisMaxMin
- .attr('transform', function(d,i) {
- return 'translate(' + (scale(d) + (isOrdinal ?
scale.rangeBand() / 2 : 0)) + ',0)'
- })
- .select('text')
- .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')
- .text(function(d,i) {
- var v = fmt(d);
- return ('' + v).match('NaN') ? '' : v;
- });
- d3.transition(axisMaxMin)
- .attr('transform', function(d,i) {
- //return 'translate(' + scale.range()[i] + ',0)'
- //return 'translate(' + scale(d) + ',0)'
- return 'translate(' + (scale(d) + (isOrdinal ?
scale.rangeBand() / 2 : 0)) + ',0)'
- });
- }
- if (staggerLabels)
- xTicks
- .attr('transform', function(d,i) { return 'translate(0,'
+ (i % 2 == 0 ? '0' : '12') + ')' });
-
- break;
- case 'right':
- axisLabel.enter().append('text').attr('class',
'nv-axislabel');
- axisLabel
- .attr('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());
- if (showMaxMin) {
- var axisMaxMin = wrap.selectAll('g.nv-axisMaxMin')
- .data(scale.domain());
- axisMaxMin.enter().append('g').attr('class',
'nv-axisMaxMin').append('text')
- .style('opacity', 0);
- axisMaxMin.exit().remove();
- axisMaxMin
- .attr('transform', function(d,i) {
- return 'translate(0,' + scale(d) + ')'
- })
- .select('text')
- .attr('dy', '.32em')
- .attr('y', 0)
- .attr('x', axis.tickPadding())
- .attr('text-anchor', 'start')
- .text(function(d,i) {
- var v = fmt(d);
- return ('' + v).match('NaN') ? '' : v;
- });
- d3.transition(axisMaxMin)
- .attr('transform', function(d,i) {
- return 'translate(0,' + scale.range()[i] + ')'
- })
- .select('text')
- .style('opacity', 1);
- }
- break;
- case 'left':
- /*
- //For dynamically placing the label. Can be used with dynamically-sized chart
axis margins
- var yTicks = g.selectAll('g').select("text");
- yTicks.each(function(d,i){
- var labelPadding = this.getBBox().width + axis.tickPadding() + 16;
- if(labelPadding > width) width = labelPadding;
- });
- */
- axisLabel.enter().append('text').attr('class',
'nv-axislabel');
- axisLabel
- .attr('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('x', rotateYLabel ? (-scale.range()[0] / 2) :
-axis.tickPadding());
- if (showMaxMin) {
- var axisMaxMin = wrap.selectAll('g.nv-axisMaxMin')
- .data(scale.domain());
- axisMaxMin.enter().append('g').attr('class',
'nv-axisMaxMin').append('text')
- .style('opacity', 0);
- axisMaxMin.exit().remove();
- axisMaxMin
- .attr('transform', function(d,i) {
- return 'translate(0,' + scale0(d) + ')'
- })
- .select('text')
- .attr('dy', '.32em')
- .attr('y', 0)
- .attr('x', -axis.tickPadding())
- .attr('text-anchor', 'end')
- .text(function(d,i) {
- var v = fmt(d);
- return ('' + v).match('NaN') ? '' : v;
- });
- d3.transition(axisMaxMin)
- .attr('transform', function(d,i) {
- return 'translate(0,' + scale.range()[i] + ')'
- })
- .select('text')
- .style('opacity', 1);
- }
- break;
- }
- axisLabel
- .text(function(d) { return d });
-
-
- if (showMaxMin && (axis.orient() === 'left' || axis.orient() ===
'right')) {
- //check if max and min overlap other values, if so, hide the values that overlap
- g.selectAll('g') // the g's wrapping each tick
- .each(function(d,i) {
- d3.select(this).select('text').attr('opacity', 1);
- 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!!
- }
- });
-
- //if Max and Min = 0 only show min, Issue #281
- if (scale.domain()[0] == scale.domain()[1] && scale.domain()[0] == 0)
- wrap.selectAll('g.nv-axisMaxMin')
- .style('opacity', function(d,i) { return !i ? 1 : 0 });
-
- }
-
- if (showMaxMin && (axis.orient() === 'top' || axis.orient() ===
'bottom')) {
- var maxMinRange = [];
- wrap.selectAll('g.nv-axisMaxMin')
- .each(function(d,i) {
- try {
- if (i) // i== 1, max position
- maxMinRange.push(scale(d) - this.getBBox().width - 4) //assuming
the max and min labels are as wide as the next tick (with an extra 4 pixels just in case)
- else // i==0, min position
- maxMinRange.push(scale(d) + this.getBBox().width + 4)
- }catch (err) {
- if (i) // i== 1, max position
- maxMinRange.push(scale(d) - 4) //assuming the max and min labels
are as wide as the next tick (with an extra 4 pixels just in case)
- else // i==0, min position
- maxMinRange.push(scale(d) + 4)
- }
- });
- g.selectAll('g') // the g's wrapping each tick
- .each(function(d,i) {
- if (scale(d) < maxMinRange[0] || scale(d) > maxMinRange[1]) {
- 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).remove();
- else
- d3.select(this).select('text').remove(); // Don't remove
the ZERO line!!
- }
- });
- }
-
-
- //highlight zero line ... Maybe should not be an option and should just be in CSS?
- if (highlightZero)
- g.selectAll('.tick')
- .filter(function(d) { return !parseFloat(Math.round(d.__data__*100000)/1000000)
&& (d.__data__ !== undefined) }) //this is because sometimes the 0 tick is a very
small fraction, TODO: think of cleaner technique
- .classed('zero', true);
-
- //store old scales for use in transitions on update
- scale0 = scale.copy();
-
- });
-
- return chart;
- }
-
-
- //============================================================
- // Expose Public Variables
- //------------------------------------------------------------
-
- // expose chart's sub-components
- chart.axis = axis;
-
- 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.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.ticks = function(_) {
- if (!arguments.length) return ticks;
- ticks = _;
- return chart;
- };
-
- chart.height = function(_) {
- if (!arguments.length) return height;
- height = _;
- return chart;
- };
-
- chart.axisLabel = function(_) {
- if (!arguments.length) return axisLabelText;
- axisLabelText = _;
- return chart;
- }
-
- chart.showMaxMin = function(_) {
- if (!arguments.length) return showMaxMin;
- showMaxMin = _;
- return chart;
- }
-
- chart.highlightZero = function(_) {
- if (!arguments.length) return highlightZero;
- highlightZero = _;
- return chart;
- }
-
- chart.scale = function(_) {
- if (!arguments.length) return scale;
- scale = _;
- axis.scale(scale);
- isOrdinal = typeof scale.rangeBands === 'function';
- d3.rebind(chart, scale, 'domain', 'range', 'rangeBand',
'rangeBands');
- return chart;
- }
-
- chart.rotateYLabel = function(_) {
- if(!arguments.length) return rotateYLabel;
- rotateYLabel = _;
- return chart;
- }
-
- chart.rotateLabels = function(_) {
- if(!arguments.length) return rotateLabels;
- rotateLabels = _;
- return chart;
- }
-
- chart.staggerLabels = function(_) {
- if (!arguments.length) return staggerLabels;
- staggerLabels = _;
- 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() {
-
- //============================================================
- // 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')
- ;
-
- //============================================================
-
-
- 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);
-
-
- //------------------------------------------------------------
- // 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)
- : x1(rangeMax) - x1(rangeAvg))
- .attr('x', rangeMax <= 0 ?
- x1(rangeMin)
- : x1(rangeAvg))
- */
-
- g.select('rect.nv-measure')
- .style('fill', color)
- .attr('height', availableHeight / 3)
- .attr('y', availableHeight / 3)
- .attr('width', measurez < 0 ?
- x1(0) - x1(measurez[0])
- : x1(measurez[0]) - x1(0))
- .attr('x', xp1(measurez))
- .on('mouseover', function() {
- dispatch.elementMouseover({
- value: measurez[0],
- label: 'Current',
- pos: [x1(measurez[0]), availableHeight/2]
- })
- })
- .on('mouseout', function() {
- dispatch.elementMouseout({
- value: measurez[0],
- label: 'Current'
- })
- })
-
- var h3 = availableHeight / 6;
- if (markerz[0]) {
- g.selectAll('path.nv-markerTriangle')
- .attr('transform', function(d) { return 'translate(' +
x1(markerz[0]) + ',' + (availableHeight / 2) + ')' })
- .attr('d', 'M0,' + h3 + 'L' + h3 + ',' +
(-h3) + ' ' + (-h3) + ',' + (-h3) + 'Z')
- .on('mouseover', function() {
- dispatch.elementMouseover({
- value: markerz[0],
- label: 'Previous',
- pos: [x1(markerz[0]), availableHeight/2]
- })
- })
- .on('mouseout', function() {
- dispatch.elementMouseout({
- value: markerz[0],
- label: 'Previous'
- })
- });
- } else {
- g.selectAll('path.nv-markerTriangle').remove();
- }
-
-
- wrap.selectAll('.nv-range')
- .on('mouseover', function(d,i) {
- var label = !i ? "Maximum" : i == 1 ? "Mean" :
"Minimum";
-
- dispatch.elementMouseover({
- value: d,
- label: label,
- pos: [x1(d), availableHeight/2]
- })
- })
- .on('mouseout', function(d,i) {
- var label = !i ? "Maximum" : i == 1 ? "Mean" :
"Minimum";
-
- dispatch.elementMouseout({
- value: d,
- label: label
- })
- })
-
-/* // THIS IS THE PREVIOUS BULLET IMPLEMENTATION, WILL REMOVE SHORTLY
- // Update the range rects.
- var range = g.selectAll('rect.nv-range')
- .data(rangez);
-
- range.enter().append('rect')
- .attr('class', function(d, i) { return 'nv-range nv-s' + i; })
- .attr('width', w0)
- .attr('height', availableHeight)
- .attr('x', reverse ? x0 : 0)
- .on('mouseover', function(d,i) {
- dispatch.elementMouseover({
- value: d,
- label: (i <= 0) ? 'Maximum' : (i > 1) ? 'Minimum' :
'Mean', //TODO: make these labels a variable
- pos: [x1(d), availableHeight/2]
- })
- })
- .on('mouseout', function(d,i) {
- dispatch.elementMouseout({
- value: d,
- label: (i <= 0) ? 'Minimum' : (i >=1) ? 'Maximum' :
'Mean' //TODO: make these labels a variable
- })
- })
-
- d3.transition(range)
- .attr('x', reverse ? x1 : 0)
- .attr('width', w1)
- .attr('height', availableHeight);
-
-
- // Update the measure rects.
- var measure = g.selectAll('rect.nv-measure')
- .data(measurez);
-
- measure.enter().append('rect')
- .attr('class', function(d, i) { return 'nv-measure nv-s' + i;
})
- .style('fill', function(d,i) { return color(d,i ) })
- .attr('width', w0)
- .attr('height', availableHeight / 3)
- .attr('x', reverse ? x0 : 0)
- .attr('y', availableHeight / 3)
- .on('mouseover', function(d) {
- dispatch.elementMouseover({
- value: d,
- label: 'Current', //TODO: make these labels a variable
- pos: [x1(d), availableHeight/2]
- })
- })
- .on('mouseout', function(d) {
- dispatch.elementMouseout({
- value: d,
- label: 'Current' //TODO: make these labels a variable
- })
- })
-
- d3.transition(measure)
- .attr('width', w1)
- .attr('height', availableHeight / 3)
- .attr('x', reverse ? x1 : 0)
- .attr('y', availableHeight / 3);
-
-
-
- // Update the marker lines.
- var marker = g.selectAll('path.nv-markerTriangle')
- .data(markerz);
-
- var h3 = availableHeight / 6;
- marker.enter().append('path')
- .attr('class', 'nv-markerTriangle')
- .attr('transform', function(d) { return 'translate(' + x0(d) +
',' + (availableHeight / 2) + ')' })
- .attr('d', 'M0,' + h3 + 'L' + h3 + ',' + (-h3)
+ ' ' + (-h3) + ',' + (-h3) + 'Z')
- .on('mouseover', function(d,i) {
- dispatch.elementMouseover({
- value: d,
- label: 'Previous',
- pos: [x1(d), availableHeight/2]
- })
- })
- .on('mouseout', function(d,i) {
- dispatch.elementMouseout({
- value: d,
- label: 'Previous'
- })
- });
-
- d3.transition(marker)
- .attr('transform', function(d) { return 'translate(' + (x1(d) -
x1(0)) + ',' + (availableHeight / 2) + ')' });
-
- marker.exit().remove();
-*/
-
- });
-
- // d3.timer.flush(); // Not needed?
-
- return chart;
- }
-
-
- //============================================================
- // Expose Public Variables
- //------------------------------------------------------------
-
- chart.dispatch = dispatch;
-
- // left, right, top, bottom
- chart.orient = function(_) {
- if (!arguments.length) return orient;
- orient = _;
- reverse = orient == 'right' || orient == 'bottom';
- return chart;
- };
-
- // ranges (bad, satisfactory, good)
- chart.ranges = function(_) {
- if (!arguments.length) return ranges;
- ranges = _;
- return chart;
- };
-
- // markers (previous, goal)
- chart.markers = function(_) {
- if (!arguments.length) return markers;
- markers = _;
- return chart;
- };
-
- // measures (actual, forecast)
- chart.measures = function(_) {
- if (!arguments.length) return measures;
- measures = _;
- return chart;
- };
-
- chart.forceX = function(_) {
- if (!arguments.length) return forceX;
- forceX = _;
- 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.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.tickFormat = function(_) {
- if (!arguments.length) return tickFormat;
- tickFormat = _;
- return chart;
- };
-
- chart.color = function(_) {
- if (!arguments.length) return color;
- color = nv.utils.getColor(_);
- 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.bulletChart = function() {
-
- //============================================================
- // Public Variables with Default Settings
- //------------------------------------------------------------
-
- var bullet = nv.models.bullet()
- ;
-
- var orient = 'left' // TODO top & bottom
- , reverse = false
- , margin = {top: 5, right: 40, bottom: 20, left: 120}
- , ranges = function(d) { return d.ranges }
- , markers = function(d) { return d.markers }
- , measures = function(d) { return d.measures }
- , width = null
- , height = 55
- , tickFormat = null
- , tooltips = true
- , tooltip = function(key, x, y, e, graph) {
- return '<h3>' + x + '</h3>' +
- '<p>' + y + '</p>'
- }
- , noData = 'No Data Available.'
- , dispatch = d3.dispatch('tooltipShow', 'tooltipHide')
- ;
-
- //============================================================
-
-
- //============================================================
- // Private Variables
- //------------------------------------------------------------
-
- var showTooltip = function(e, offsetElement) {
- var left = e.pos[0] + ( offsetElement.offsetLeft || 0 ) + margin.left,
- top = e.pos[1] + ( offsetElement.offsetTop || 0) + margin.top,
- content = tooltip(e.key, e.label, e.value, e, chart);
-
- nv.tooltip.show([left, top], content, e.value < 0 ? 'e' : 'w',
null, offsetElement);
- };
-
- //============================================================
-
-
- function chart(selection) {
- selection.each(function(d, i) {
- var container = d3.select(this);
-
- var availableWidth = (width || parseInt(container.style('width')) || 960)
- - margin.left - margin.right,
- availableHeight = height - margin.top - margin.bottom,
- that = this;
-
-
- chart.update = function() { chart(selection) };
- chart.container = this;
-
- //------------------------------------------------------------
- // Display No Data message if there's nothing to show.
-
- if (!d || !ranges.call(this, d, i)) {
- var noDataText = container.selectAll('.nv-noData').data([noData]);
-
- noDataText.enter().append('text')
- .attr('class', 'nvd3 nv-noData')
- .attr('dy', '-.7em')
- .style('text-anchor', 'middle');
-
- noDataText
- .attr('x', margin.left + availableWidth / 2)
- .attr('y', 18 + margin.top + availableHeight / 2)
- .text(function(d) { return d });
-
- return chart;
- } else {
- container.selectAll('.nv-noData').remove();
- }
-
- //------------------------------------------------------------
-
-
-
- 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 containers and skeleton of chart
-
- var wrap = container.selectAll('g.nv-wrap.nv-bulletChart').data([d]);
- var wrapEnter = wrap.enter().append('g').attr('class', 'nvd3
nv-wrap nv-bulletChart');
- var gEnter = wrapEnter.append('g');
- var g = wrap.select('g');
-
- gEnter.append('g').attr('class', 'nv-bulletWrap');
- gEnter.append('g').attr('class', 'nv-titles');
-
- wrap.attr('transform', 'translate(' + margin.left + ',' +
margin.top + ')');
-
- //------------------------------------------------------------
-
-
- // Compute the new x-scale.
- var x1 = d3.scale.linear()
- .domain([0, Math.max(rangez[0], markerz[0], measurez[0])]) // TODO: need to
allow forceX and forceY, and xDomain, yDomain
- .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;
-
- /*
- // Derive width-scales from the x-scales.
- var w0 = bulletWidth(x0),
- w1 = bulletWidth(x1);
-
- function bulletWidth(x) {
- var x0 = x(0);
- return function(d) {
- return Math.abs(x(d) - x(0));
- };
- }
-
- function bulletTranslate(x) {
- return function(d) {
- return 'translate(' + x(d) + ',0)';
- };
- }
- */
-
- 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 title = gEnter.select('.nv-titles').append('g')
- .attr('text-anchor', 'end')
- .attr('transform', 'translate(-6,' + (height - margin.top -
margin.bottom) / 2 + ')');
- title.append('text')
- .attr('class', 'nv-title')
- .text(function(d) { return d.title; });
-
- title.append('text')
- .attr('class', 'nv-subtitle')
- .attr('dy', '1em')
- .text(function(d) { return d.subtitle; });
-
-
-
- bullet
- .width(availableWidth)
- .height(availableHeight)
-
- var bulletWrap = g.select('.nv-bulletWrap');
-
- d3.transition(bulletWrap).call(bullet);
-
-
-
- // Compute the tick format.
- var format = tickFormat || x1.tickFormat( availableWidth / 100 );
-
- // Update the tick groups.
- var tick = g.selectAll('g.nv-tick')
- .data(x1.ticks( availableWidth / 50 ), function(d) {
- return this.textContent || format(d);
- });
-
- // Initialize the ticks with the old scale, x0.
- var tickEnter = tick.enter().append('g')
- .attr('class', 'nv-tick')
- .attr('transform', function(d) { return 'translate(' + x0(d) +
',0)' })
- .style('opacity', 1e-6);
-
- tickEnter.append('line')
- .attr('y1', availableHeight)
- .attr('y2', availableHeight * 7 / 6);
-
- tickEnter.append('text')
- .attr('text-anchor', 'middle')
- .attr('dy', '1em')
- .attr('y', availableHeight * 7 / 6)
- .text(format);
-
-
- // Transition the updating ticks to the new scale, x1.
- var tickUpdate = d3.transition(tick)
- .attr('transform', function(d) { return 'translate(' + x1(d) +
',0)' })
- .style('opacity', 1);
-
- tickUpdate.select('line')
- .attr('y1', availableHeight)
- .attr('y2', availableHeight * 7 / 6);
-
- tickUpdate.select('text')
- .attr('y', availableHeight * 7 / 6);
-
- // Transition the exiting ticks to the new scale, x1.
- d3.transition(tick.exit())
- .attr('transform', function(d) { return 'translate(' + x1(d) +
',0)' })
- .style('opacity', 1e-6)
- .remove();
-
-
- //============================================================
- // Event Handling/Dispatching (in chart's scope)
- //------------------------------------------------------------
-
- dispatch.on('tooltipShow', function(e) {
- e.key = d.title;
- if (tooltips) showTooltip(e, that.parentNode);
- });
-
- //============================================================
-
- });
-
- d3.timer.flush();
-
- return chart;
- }
-
-
- //============================================================
- // Event Handling/Dispatching (out of chart's scope)
- //------------------------------------------------------------
-
- bullet.dispatch.on('elementMouseover.tooltip', function(e) {
- dispatch.tooltipShow(e);
- });
-
- bullet.dispatch.on('elementMouseout.tooltip', function(e) {
- dispatch.tooltipHide(e);
- });
-
- dispatch.on('tooltipHide', function() {
- if (tooltips) nv.tooltip.cleanup();
- });
-
- //============================================================
-
-
- //============================================================
- // Expose Public Variables
- //------------------------------------------------------------
-
- chart.dispatch = dispatch;
- chart.bullet = bullet;
-
- d3.rebind(chart, bullet, 'color');
-
- // left, right, top, bottom
- chart.orient = function(x) {
- if (!arguments.length) return orient;
- orient = x;
- reverse = orient == 'right' || orient == 'bottom';
- return chart;
- };
-
- // ranges (bad, satisfactory, good)
- chart.ranges = function(x) {
- if (!arguments.length) return ranges;
- ranges = x;
- return chart;
- };
-
- // markers (previous, goal)
- chart.markers = function(x) {
- if (!arguments.length) return markers;
- markers = x;
- return chart;
- };
-
- // measures (actual, forecast)
- chart.measures = function(x) {
- if (!arguments.length) return measures;
- measures = x;
- return chart;
- };
-
- chart.width = function(x) {
- if (!arguments.length) return width;
- width = x;
- return chart;
- };
-
- chart.height = function(x) {
- if (!arguments.length) return height;
- height = x;
- 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.tickFormat = function(x) {
- if (!arguments.length) return tickFormat;
- tickFormat = x;
- return chart;
- };
-
- chart.tooltips = function(_) {
- if (!arguments.length) return tooltips;
- tooltips = _;
- return chart;
- };
-
- chart.tooltipContent = function(_) {
- if (!arguments.length) return tooltip;
- tooltip = _;
- return chart;
- };
-
- chart.noData = function(_) {
- if (!arguments.length) return noData;
- noData = _;
- return chart;
- };
-
- //============================================================
-
-
- return chart;
-};
-
-
-
-nv.models.cumulativeLineChart = function() {
-
- //============================================================
- // Public Variables with Default Settings
- //------------------------------------------------------------
-
- var lines = nv.models.line()
- , xAxis = nv.models.axis()
- , yAxis = nv.models.axis()
- , legend = nv.models.legend()
- , controls = nv.models.legend()
- ;
-
- var margin = {top: 30, right: 30, bottom: 50, left: 60}
- , color = nv.utils.defaultColor()
- , width = null
- , height = null
- , showLegend = true
- , tooltips = true
- , showControls = true
- , rescaleY = true
- , tooltip = function(key, x, y, e, graph) {
- return '<h3>' + key + '</h3>' +
- '<p>' + y + ' at ' + x + '</p>'
- }
- , x //can be accessed via chart.xScale()
- , y //can be accessed via chart.yScale()
- , id = lines.id()
- , state = { index: 0, rescaleY: rescaleY }
- , defaultState = null
- , noData = 'No Data Available.'
- , average = function(d) { return d.average }
- , dispatch = d3.dispatch('tooltipShow', 'tooltipHide',
'stateChange', 'changeState')
- ;
-
- xAxis
- .orient('bottom')
- .tickPadding(7)
- ;
- yAxis
- .orient('left')
- ;
-
- //============================================================
-
-
- //============================================================
- // Private Variables
- //------------------------------------------------------------
-
- var dx = d3.scale.linear()
- , index = {i: 0, x: 0}
- ;
-
- var showTooltip = function(e, offsetElement) {
- var left = e.pos[0] + ( offsetElement.offsetLeft || 0 ),
- top = e.pos[1] + ( offsetElement.offsetTop || 0),
- x = xAxis.tickFormat()(lines.x()(e.point, e.pointIndex)),
- y = yAxis.tickFormat()(lines.y()(e.point, e.pointIndex)),
- content = tooltip(e.series.key, x, y, e, chart);
-
- 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),
- that = this;
-
- var availableWidth = (width || parseInt(container.style('width')) || 960)
- - margin.left - margin.right,
- availableHeight = (height || parseInt(container.style('height')) ||
400)
- - margin.top - margin.bottom;
-
-
- chart.update = function() { container.transition().call(chart) };
- chart.container = this;
-
- //set state.disabled
- state.disabled = data.map(function(d) { return !!d.disabled });
-
- if (!defaultState) {
- var key;
- defaultState = {};
- for (key in state) {
- if (state[key] instanceof Array)
- defaultState[key] = state[key].slice(0);
- else
- defaultState[key] = state[key];
- }
- }
-
- 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) {
- index.x = d3.event.x;
- index.i = Math.round(dx.invert(index.x));
- updateZero();
- }
-
- function dragEnd(d,i) {
- d3.select(chart.container)
- .style('cursor', 'auto');
-
- // update state and send stateChange with new index
- state.index = index.i;
- dispatch.stateChange(state);
- }
-
-
-
-
- //------------------------------------------------------------
- // Display No Data message if there's nothing to show.
-
- if (!data || !data.length || !data.filter(function(d) { return d.values.length
}).length) {
- var noDataText = container.selectAll('.nv-noData').data([noData]);
-
- noDataText.enter().append('text')
- .attr('class', 'nvd3 nv-noData')
- .attr('dy', '-.7em')
- .style('text-anchor', 'middle');
-
- noDataText
- .attr('x', margin.left + availableWidth / 2)
- .attr('y', margin.top + availableHeight / 2)
- .text(function(d) { return d });
-
- return chart;
- } else {
- container.selectAll('.nv-noData').remove();
- }
-
- //------------------------------------------------------------
-
-
- //------------------------------------------------------------
- // Setup Scales
-
- x = lines.xScale();
- y = lines.yScale();
-
-
- if (!rescaleY) {
- var seriesDomains = data
- .filter(function(series) { return !series.disabled })
- .map(function(series,i) {
- var initialDomain = d3.extent(series.values, lines.y());
-
- //account for series being disabled when losing 95% or more
- if (initialDomain[0] < -.95) initialDomain[0] = -.95;
-
- return [
- (initialDomain[0] - initialDomain[1]) / (1 + initialDomain[1]),
- (initialDomain[1] - initialDomain[0]) / (1 + initialDomain[0])
- ];
- });
-
- var completeDomain = [
- d3.min(seriesDomains, function(d) { return d[0] }),
- d3.max(seriesDomains, function(d) { return d[1] })
- ]
-
- lines.yDomain(completeDomain);
- } else {
- lines.yDomain(null);
- }
-
-
- dx .domain([0, data[0].values.length - 1]) //Assumes all series have same length
- .range([0, availableWidth])
- .clamp(true);
-
- //------------------------------------------------------------
-
-
- var data = indexify(index.i, data);
-
-
- //------------------------------------------------------------
- // Setup containers and skeleton of chart
-
- 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-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-legendWrap');
- gEnter.append('g').attr('class', 'nv-controlsWrap');
-
- //------------------------------------------------------------
-
-
- //------------------------------------------------------------
- // Legend
-
- if (showLegend) {
- legend.width(availableWidth);
-
- g.select('.nv-legendWrap')
- .datum(data)
- .call(legend);
-
- if ( margin.top != legend.height()) {
- margin.top = legend.height();
- availableHeight = (height || parseInt(container.style('height')) ||
400)
- - margin.top - margin.bottom;
- }
-
- g.select('.nv-legendWrap')
- .attr('transform', 'translate(0,' + (-margin.top)
+')')
- }
-
- //------------------------------------------------------------
-
-
- //------------------------------------------------------------
- // Controls
-
- if (showControls) {
- var controlsData = [
- { key: 'Re-scale y-axis', disabled: !rescaleY }
- ];
-
- controls.width(140).color(['#444', '#444', '#444']);
- g.select('.nv-controlsWrap')
- .datum(controlsData)
- .attr('transform', 'translate(0,' + (-margin.top)
+')')
- .call(controls);
- }
-
- //------------------------------------------------------------
-
-
- wrap.attr('transform', 'translate(' + margin.left + ',' +
margin.top + ')');
-
-
- // Show error if series goes below 100%
- var tempDisabled = data.filter(function(d) { return d.tempDisabled });
-
- wrap.select('.tempDisabled').remove(); //clean-up and prevent duplicates
- if (tempDisabled.length) {
- wrap.append('text').attr('class', 'tempDisabled')
- .attr('x', availableWidth / 2)
- .attr('y', '-.71em')
- .style('text-anchor', 'end')
- .text(tempDisabled.map(function(d) { return d.key }).join(', ') +
' values cannot be calculated for this time period.');
- }
-
- //------------------------------------------------------------
- // Main Chart Component(s)
-
- gEnter.select('.nv-background')
- .append('rect');
-
- g.select('.nv-background rect')
- .attr('width', availableWidth)
- .attr('height', availableHeight);
-
- lines
- //.x(function(d) { return d.x })
- .y(function(d) { return d.display.y })
- .width(availableWidth)
- .height(availableHeight)
- .color(data.map(function(d,i) {
- return d.color || color(d, i);
- }).filter(function(d,i) { return !data[i].disabled &&
!data[i].tempDisabled; }));
-
-
-
- var linesWrap = g.select('.nv-linesWrap')
- .datum(data.filter(function(d) { return !d.disabled && !d.tempDisabled
}));
-
- //d3.transition(linesWrap).call(lines);
- linesWrap.call(lines);
-
- /*Handle average lines [AN-612] ----------------------------*/
-
- //Store a series index number in the data array.
- data.forEach(function(d,i) {
- d.seriesIndex = i;
- });
-
- var avgLineData = data.filter(function(d) {
- return !d.disabled && !!average(d);
- });
-
- var avgLines = g.select(".nv-avgLinesWrap").selectAll("line")
- .data(avgLineData, function(d) { return d.key; });
-
- avgLines.enter()
- .append('line')
- .style('stroke-width',2)
- .style('stroke-dasharray','10,10')
- .style('stroke',function (d,i) {
- return lines.color()(d,d.seriesIndex);
- })
- .attr('x1',0)
- .attr('x2',availableWidth)
- .attr('y1', function(d) { return y(average(d)); })
- .attr('y2', function(d) { return y(average(d)); });
-
- avgLines
- .attr('x1',0)
- .attr('x2',availableWidth)
- .attr('y1', function(d) { return y(average(d)); })
- .attr('y2', function(d) { return y(average(d)); });
-
- avgLines.exit().remove();
-
- //Create index line -----------------------------------------
-
- var indexLine = linesWrap.selectAll('.nv-indexLine')
- .data([index]);
- indexLine.enter().append('rect').attr('class',
'nv-indexLine')
- .attr('width', 3)
- .attr('x', -2)
- .attr('fill', 'red')
- .attr('fill-opacity', .5)
- .call(indexDrag)
-
- indexLine
- .attr('transform', function(d) { return 'translate(' + dx(d.i)
+ ',0)' })
- .attr('height', availableHeight)
-
- //------------------------------------------------------------
-
-
- //------------------------------------------------------------
- // 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);
-
-
- yAxis
- .scale(y)
- .ticks( availableHeight / 36 )
- .tickSize( -availableWidth, 0);
-
- d3.transition(g.select('.nv-y.nv-axis'))
- .call(yAxis);
-
- //------------------------------------------------------------
-
-
- //============================================================
- // Event Handling/Dispatching (in chart's scope)
- //------------------------------------------------------------
-
-
- function updateZero() {
- indexLine
- .data([index]);
-
- container.call(chart);
- }
-
- g.select('.nv-background rect')
- .on('click', function() {
- index.x = d3.mouse(this)[0];
- index.i = Math.round(dx.invert(index.x));
-
- // update state and send stateChange with new index
- state.index = index.i;
- dispatch.stateChange(state);
-
- updateZero();
- });
-
- lines.dispatch.on('elementClick', function(e) {
- index.i = e.pointIndex;
- index.x = dx(index.i);
-
- // update state and send stateChange with new index
- state.index = index.i;
- dispatch.stateChange(state);
-
- updateZero();
- });
-
- 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 });
- 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;
- });
- d.disabled = false;
-
- state.disabled = data.map(function(d) { return !!d.disabled });
- dispatch.stateChange(state);
- chart.update();
- });
-
-
-/*
- //
- 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)
- });
-*/
-
- dispatch.on('tooltipShow', function(e) {
- if (tooltips) showTooltip(e, that.parentNode);
- });
-
-
- // Update chart from a state object passed to event handler
- dispatch.on('changeState', function(e) {
-
- if (typeof e.disabled !== 'undefined') {
- data.forEach(function(series,i) {
- series.disabled = e.disabled[i];
- });
-
- state.disabled = e.disabled;
- }
-
-
- if (typeof e.index !== 'undefined') {
- index.i = e.index;
- index.x = dx(index.i);
-
- state.index = e.index;
-
- indexLine
- .data([index]);
- }
-
-
- if (typeof e.rescaleY !== 'undefined') {
- rescaleY = e.rescaleY;
- }
-
- chart.update();
- });
-
- //============================================================
-
- });
-
- return chart;
- }
-
-
- //============================================================
- // Event Handling/Dispatching (out of chart's scope)
- //------------------------------------------------------------
-
- lines.dispatch.on('elementMouseover.tooltip', function(e) {
- e.pos = [e.pos[0] + margin.left, e.pos[1] + margin.top];
- dispatch.tooltipShow(e);
- });
-
- lines.dispatch.on('elementMouseout.tooltip', function(e) {
- dispatch.tooltipHide(e);
- });
-
- dispatch.on('tooltipHide', function() {
- if (tooltips) nv.tooltip.cleanup();
- });
-
- //============================================================
-
-
- //============================================================
- // Expose Public Variables
- //------------------------------------------------------------
-
- // expose chart's sub-components
- chart.dispatch = dispatch;
- chart.lines = lines;
- chart.legend = legend;
- chart.xAxis = xAxis;
- chart.yAxis = yAxis;
-
- d3.rebind(chart, lines, 'defined', 'isArea', 'x', 'y',
'size', 'xDomain', 'yDomain', 'forceX', 'forceY',
'interactive', 'clipEdge', 'clipVoronoi', 'id');
-
- 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.color = function(_) {
- if (!arguments.length) return color;
- color = nv.utils.getColor(_);
- legend.color(color);
- return chart;
- };
-
- chart.rescaleY = function(_) {
- if (!arguments.length) return rescaleY;
- rescaleY = _
- return rescaleY;
- };
-
- chart.showControls = function(_) {
- if (!arguments.length) return showControls;
- showControls = _;
- return chart;
- };
-
- chart.showLegend = function(_) {
- if (!arguments.length) return showLegend;
- showLegend = _;
- return chart;
- };
-
- chart.tooltips = function(_) {
- if (!arguments.length) return tooltips;
- tooltips = _;
- return chart;
- };
-
- chart.tooltipContent = function(_) {
- if (!arguments.length) return tooltip;
- tooltip = _;
- return chart;
- };
-
- chart.state = function(_) {
- if (!arguments.length) return state;
- state = _;
- return chart;
- };
-
- chart.defaultState = function(_) {
- if (!arguments.length) return defaultState;
- defaultState = _;
- return chart;
- };
-
- chart.noData = function(_) {
- if (!arguments.length) return noData;
- noData = _;
- return chart;
- };
-
- chart.average = function(_) {
- if(!arguments.length) return average;
- average = _;
- return chart;
- };
-
- //============================================================
-
-
- //============================================================
- // Functions
- //------------------------------------------------------------
-
- /* Normalize the data according to an index point. */
- function indexify(idx, data) {
- return data.map(function(line, i) {
- if (!line.values) {
- return line;
- }
- var v = lines.y()(line.values[idx], idx);
-
- //TODO: implement check below, and disable series if series loses 100% or more
cause divide by 0 issue
- if (v < -.95) {
- //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;
- }
-
- line.tempDisabled = false;
-
- line.values = line.values.map(function(point, pointIndex) {
- point.display = {'y': (lines.y()(point, pointIndex) - v) / (1 + v) };
- return point;
- })
-
- return line;
- })
- }
-
- //============================================================
-
-
- return chart;
-}
-//TODO: consider deprecating by adding necessary features to multiBar model
-nv.models.discreteBar = function() {
-
- //============================================================
- // Public Variables with Default Settings
- //------------------------------------------------------------
-
- var margin = {top: 0, right: 0, bottom: 0, left: 0}
- , width = 960
- , height = 500
- , id = Math.floor(Math.random() * 10000) //Create semi-unique ID in case user
doesn't select one
- , x = d3.scale.ordinal()
- , y = d3.scale.linear()
- , getX = function(d) { return d.x }
- , getY = function(d) { return d.y }
- , forceY = [0] // 0 is forced by default.. this makes sense for the majority of bar
graphs... user can always do chart.forceY([]) to remove
- , color = nv.utils.defaultColor()
- , showValues = false
- , valueFormat = d3.format(',.2f')
- , xDomain
- , yDomain
- , dispatch = d3.dispatch('chartClick', 'elementClick',
'elementDblClick', 'elementMouseover', 'elementMouseout')
- , rectClass = 'discreteBar'
- ;
-
- //============================================================
-
-
- //============================================================
- // Private Variables
- //------------------------------------------------------------
-
- var x0, y0;
-
- //============================================================
-
-
- function chart(selection) {
- selection.each(function(data) {
- var availableWidth = width - margin.left - margin.right,
- availableHeight = height - margin.top - margin.bottom,
- container = d3.select(this);
-
-
- //add series index to each data point for reference
- data = data.map(function(series, i) {
- series.values = series.values.map(function(point) {
- point.series = i;
- return point;
- });
- return series;
- });
-
-
- //------------------------------------------------------------
- // Setup Scales
-
- // remap and flatten the data for use in calculating the scales' domains
- var seriesData = (xDomain && yDomain) ? [] : // if we know xDomain and
yDomain, no need to calculate
- data.map(function(d) {
- return d.values.map(function(d,i) {
- return { x: getX(d,i), y: getY(d,i), y0: d.y0 }
- })
- });
-
- x .domain(xDomain || d3.merge(seriesData).map(function(d) { return d.x }))
- .rangeBands([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]);
-
- //store old scales if they exist
- x0 = x0 || x;
- y0 = y0 || y.copy().range([y(0),y(0)]);
-
- //------------------------------------------------------------
-
-
- //------------------------------------------------------------
- // Setup containers and skeleton of chart
-
- var wrap = container.selectAll('g.nv-wrap.nv-discretebar').data([data]);
- var wrapEnter = wrap.enter().append('g').attr('class', 'nvd3
nv-wrap nv-discretebar');
- var gEnter = wrapEnter.append('g');
- var g = wrap.select('g');
-
- gEnter.append('g').attr('class', 'nv-groups');
-
- wrap.attr('transform', 'translate(' + margin.left + ',' +
margin.top + ')');
-
- //------------------------------------------------------------
-
-
-
- //TODO: by definition, the discrete bar should not have multiple groups, will
modify/remove later
- var groups = wrap.select('.nv-groups').selectAll('.nv-group')
- .data(function(d) { return d }, function(d) { return d.key });
- groups.enter().append('g')
- .style('stroke-opacity', 1e-6)
- .style('fill-opacity', 1e-6);
- d3.transition(groups.exit())
- .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)
- .style('stroke-opacity', 1)
- .style('fill-opacity', .75);
-
-
- var bars = groups.selectAll('g.nv-bar')
- .data(function(d) { return d.values });
-
- bars.exit().remove();
-
-
- var barsEnter = bars.enter().append('g')
- .attr('transform', function(d,i,j) {
- 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);
- dispatch.elementMouseover({
- value: getY(d,i),
- point: d,
- series: data[d.series],
- pos: [x(getX(d,i)) + (x.rangeBand() * (d.series + .5) / data.length),
y(getY(d,i))], // TODO: Figure out why the value appears to be shifted
- pointIndex: i,
- seriesIndex: d.series,
- e: d3.event
- });
- })
- .on('mouseout', function(d,i) {
- d3.select(this).classed('hover', false);
- dispatch.elementMouseout({
- value: getY(d,i),
- point: d,
- series: data[d.series],
- pointIndex: i,
- seriesIndex: d.series,
- e: d3.event
- });
- })
- .on('click', function(d,i) {
- dispatch.elementClick({
- value: getY(d,i),
- point: d,
- series: data[d.series],
- pos: [x(getX(d,i)) + (x.rangeBand() * (d.series + .5) / data.length),
y(getY(d,i))], // TODO: Figure out why the value appears to be shifted
- pointIndex: i,
- seriesIndex: d.series,
- e: d3.event
- });
- d3.event.stopPropagation();
- })
- .on('dblclick', function(d,i) {
- dispatch.elementDblClick({
- value: getY(d,i),
- point: d,
- series: data[d.series],
- pos: [x(getX(d,i)) + (x.rangeBand() * (d.series + .5) / data.length),
y(getY(d,i))], // TODO: Figure out why the value appears to be shifted
- pointIndex: i,
- seriesIndex: d.series,
- e: d3.event
- });
- d3.event.stopPropagation();
- });
-
- barsEnter.append('rect')
- .attr('height', 0)
- .attr('width', x.rangeBand() * .9 / data.length )
-
- if (showValues) {
- barsEnter.append('text')
- .attr('text-anchor', 'middle')
- bars.select('text')
- .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 valueFormat(getY(d,i)) });
- } else {
- bars.selectAll('text').remove();
- }
-
- bars
- .attr('class', function(d,i) { return getY(d,i) < 0 ? 'nv-bar
negative' : 'nv-bar positive' })
- .style('fill', function(d,i) { return d.color || color(d,i) })
- .style('stroke', function(d,i) { return d.color || color(d,i) })
- .select('rect')
- .attr('class', rectClass)
- .attr('width', x.rangeBand() * .9 / data.length);
- d3.transition(bars)
- //.delay(function(d,i) { return i * 1200 / data[0].values.length })
- .attr('transform', function(d,i) {
- var left = x(getX(d,i)) + x.rangeBand() * .05,
- top = getY(d,i) < 0 ?
- y(0) :
- y(0) - y(getY(d,i)) < 1 ?
- y(0) - 1 : //make 1 px positive bars show up above y=0
- y(getY(d,i));
-
- return 'translate(' + left + ', ' + top + ')'
- })
- .select('rect')
- .attr('height', function(d,i) {
- return Math.max(Math.abs(y(getY(d,i)) - y(0)) || 1)
- });
-
-
- //store old scales for use in transitions on update
- x0 = x.copy();
- y0 = y.copy();
-
- });
-
- return chart;
- }
-
-
- //============================================================
- // Expose Public Variables
- //------------------------------------------------------------
-
- chart.dispatch = dispatch;
-
- 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.forceY = function(_) {
- if (!arguments.length) return forceY;
- forceY = _;
- 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.showValues = function(_) {
- if (!arguments.length) return showValues;
- showValues = _;
- return chart;
- };
-
- chart.valueFormat= function(_) {
- if (!arguments.length) return valueFormat;
- valueFormat = _;
- return chart;
- };
-
- chart.rectClass= function(_) {
- if (!arguments.length) return rectClass;
- rectClass = _;
- return chart;
- }
- //============================================================
-
-
- return chart;
-}
-
-nv.models.discreteBarChart = function() {
-
- //============================================================
- // Public Variables with Default Settings
- //------------------------------------------------------------
-
- var discretebar = nv.models.discreteBar()
- , xAxis = nv.models.axis()
- , yAxis = nv.models.axis()
- ;
-
- var margin = {top: 15, right: 10, bottom: 50, left: 60}
- , width = null
- , height = null
- , color = nv.utils.getColor()
- , staggerLabels = false
- , tooltips = true
- , tooltip = function(key, x, y, e, graph) {
- return '<h3>' + x + '</h3>' +
- '<p>' + y + '</p>'
- }
- , x
- , y
- , noData = "No Data Available."
- , dispatch = d3.dispatch('tooltipShow', 'tooltipHide',
'beforeUpdate')
- ;
-
- xAxis
- .orient('bottom')
- .highlightZero(false)
- .showMaxMin(false)
- .tickFormat(function(d) { return d })
- ;
- yAxis
- .orient('left')
- .tickFormat(d3.format(',.1f'))
- ;
-
- //============================================================
-
-
- //============================================================
- // Private Variables
- //------------------------------------------------------------
-
- var showTooltip = function(e, offsetElement) {
- var left = e.pos[0] + ( offsetElement.offsetLeft || 0 ),
- top = e.pos[1] + ( offsetElement.offsetTop || 0),
- x = xAxis.tickFormat()(discretebar.x()(e.point, e.pointIndex)),
- y = yAxis.tickFormat()(discretebar.y()(e.point, e.pointIndex)),
- content = tooltip(e.series.key, x, y, e, chart);
-
- nv.tooltip.show([left, top], content, e.value < 0 ? 'n' : 's',
null, offsetElement);
- };
-
- //============================================================
-
-
- function chart(selection) {
- selection.each(function(data) {
- var container = d3.select(this),
- that = this;
-
- var availableWidth = (width || parseInt(container.style('width')) || 960)
- - margin.left - margin.right,
- availableHeight = (height || parseInt(container.style('height')) ||
400)
- - margin.top - margin.bottom;
-
-
- chart.update = function() { dispatch.beforeUpdate();
container.transition().call(chart); };
- chart.container = this;
-
-
- //------------------------------------------------------------
- // Display No Data message if there's nothing to show.
-
- if (!data || !data.length || !data.filter(function(d) { return d.values.length
}).length) {
- var noDataText = container.selectAll('.nv-noData').data([noData]);
-
- noDataText.enter().append('text')
- .attr('class', 'nvd3 nv-noData')
- .attr('dy', '-.7em')
- .style('text-anchor', 'middle');
-
- noDataText
- .attr('x', margin.left + availableWidth / 2)
- .attr('y', margin.top + availableHeight / 2)
- .text(function(d) { return d });
-
- return chart;
- } else {
- container.selectAll('.nv-noData').remove();
- }
-
- //------------------------------------------------------------
-
-
- //------------------------------------------------------------
- // Setup Scales
-
- x = discretebar.xScale();
- y = discretebar.yScale();
-
- //------------------------------------------------------------
-
-
- //------------------------------------------------------------
- // Setup containers and skeleton of chart
-
- var wrap =
container.selectAll('g.nv-wrap.nv-discreteBarWithAxes').data([data]);
- var gEnter = wrap.enter().append('g').attr('class', 'nvd3
nv-wrap nv-discreteBarWithAxes').append('g');
- var defsEnter = gEnter.append('defs');
- var g = wrap.select('g');
-
- gEnter.append('g').attr('class', 'nv-x nv-axis');
- gEnter.append('g').attr('class', 'nv-y nv-axis');
- gEnter.append('g').attr('class', 'nv-barsWrap');
-
- g.attr('transform', 'translate(' + margin.left + ',' +
margin.top + ')');
-
- //------------------------------------------------------------
-
-
- //------------------------------------------------------------
- // Main Chart Component(s)
-
- discretebar
- .width(availableWidth)
- .height(availableHeight);
-
-
- var barsWrap = g.select('.nv-barsWrap')
- .datum(data.filter(function(d) { return !d.disabled }))
-
- d3.transition(barsWrap).call(discretebar);
-
- //------------------------------------------------------------
-
-
-
- defsEnter.append('clipPath')
- .attr('id', 'nv-x-label-clip-' + discretebar.id())
- .append('rect');
-
- g.select('#nv-x-label-clip-' + discretebar.id() + ' rect')
- .attr('width', x.rangeBand() * (staggerLabels ? 2 : 1))
- .attr('height', 16)
- .attr('x', -x.rangeBand() / (staggerLabels ? 1 : 2 ));
-
-
- //------------------------------------------------------------
- // Setup Axes
-
- xAxis
- .scale(x)
- .ticks( availableWidth / 100 )
- .tickSize(-availableHeight, 0);
-
- g.select('.nv-x.nv-axis')
- .attr('transform', 'translate(0,' + (y.range()[0] +
((discretebar.showValues() && y.domain()[0] < 0) ? 16 : 0)) + ')');
- //d3.transition(g.select('.nv-x.nv-axis'))
- g.select('.nv-x.nv-axis').transition().duration(0)
- .call(xAxis);
-
-
- var xTicks = g.select('.nv-x.nv-axis').selectAll('g');
-
- if (staggerLabels) {
- xTicks
- .selectAll('text')
- .attr('transform', function(d,i,j) { return 'translate(0,' +
(j % 2 == 0 ? '5' : '17') + ')' })
- }
-
- yAxis
- .scale(y)
- .ticks( availableHeight / 36 )
- .tickSize( -availableWidth, 0);
-
- d3.transition(g.select('.nv-y.nv-axis'))
- .call(yAxis);
-
- //------------------------------------------------------------
-
-
- //============================================================
- // Event Handling/Dispatching (in chart's scope)
- //------------------------------------------------------------
-
- dispatch.on('tooltipShow', function(e) {
- if (tooltips) showTooltip(e, that.parentNode);
- });
-
- //============================================================
-
-
- });
-
- return chart;
- }
-
- //============================================================
- // Event Handling/Dispatching (out of chart's scope)
- //------------------------------------------------------------
-
- discretebar.dispatch.on('elementMouseover.tooltip', function(e) {
- e.pos = [e.pos[0] + margin.left, e.pos[1] + margin.top];
- dispatch.tooltipShow(e);
- });
-
- discretebar.dispatch.on('elementMouseout.tooltip', function(e) {
- dispatch.tooltipHide(e);
- });
-
- dispatch.on('tooltipHide', function() {
- if (tooltips) nv.tooltip.cleanup();
- });
-
- //============================================================
-
-
- //============================================================
- // Expose Public Variables
- //------------------------------------------------------------
-
- // expose chart's sub-components
- chart.dispatch = dispatch;
- chart.discretebar = discretebar;
- chart.xAxis = xAxis;
- chart.yAxis = yAxis;
-
- d3.rebind(chart, discretebar, 'x', 'y', 'xDomain',
'yDomain', 'forceX', 'forceY', 'id', 'showValues',
'valueFormat');
-
- 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.color = function(_) {
- if (!arguments.length) return color;
- color = nv.utils.getColor(_);
- discretebar.color(color);
- return chart;
- };
-
- chart.staggerLabels = function(_) {
- if (!arguments.length) return staggerLabels;
- staggerLabels = _;
- return chart;
- };
-
- chart.tooltips = function(_) {
- if (!arguments.length) return tooltips;
- tooltips = _;
- return chart;
- };
-
- chart.tooltipContent = function(_) {
- if (!arguments.length) return tooltip;
- tooltip = _;
- return chart;
- };
-
- chart.noData = function(_) {
- if (!arguments.length) return noData;
- noData = _;
- return chart;
- };
-
- //============================================================
-
-
- return chart;
-}
-
-nv.models.distribution = function() {
-
- //============================================================
- // Public Variables with Default Settings
- //------------------------------------------------------------
-
- var margin = {top: 0, right: 0, bottom: 0, left: 0}
- , width = 400 //technically width or height depending on x or y....
- , size = 8
- , axis = 'x' // 'x' or 'y'... horizontal or vertical
- , getData = function(d) { return d[axis] } // defaults d.x or d.y
- , color = nv.utils.defaultColor()
- , scale = d3.scale.linear()
- , domain
- ;
-
- //============================================================
-
-
- //============================================================
- // Private Variables
- //------------------------------------------------------------
-
- var scale0;
-
- //============================================================
-
-
- function chart(selection) {
- selection.each(function(data) {
- var availableLength = width - (axis === 'x' ? margin.left + margin.right :
margin.top + margin.bottom),
- naxis = axis == 'x' ? 'y' : 'x',
- container = d3.select(this);
-
-
- //------------------------------------------------------------
- // Setup Scales
-
- scale0 = scale0 || scale;
-
- //------------------------------------------------------------
-
-
- //------------------------------------------------------------
- // Setup containers and skeleton of chart
-
- var wrap = container.selectAll('g.nv-distribution').data([data]);
- var wrapEnter = wrap.enter().append('g').attr('class', 'nvd3
nv-distribution');
- var gEnter = wrapEnter.append('g');
- var g = wrap.select('g');
-
- wrap.attr('transform', 'translate(' + margin.left + ',' +
margin.top + ')')
-
- //------------------------------------------------------------
-
-
- var distWrap = g.selectAll('g.nv-dist')
- .data(function(d) { return d }, function(d) { return d.key });
-
- distWrap.enter().append('g');
- distWrap
- .attr('class', function(d,i) { return 'nv-dist nv-series-' + i
})
- .style('stroke', function(d,i) { return color(d, i) });
-
- var dist = distWrap.selectAll('line.nv-dist' + axis)
- .data(function(d) { return d.values })
- dist.enter().append('line')
- .attr(axis + '1', function(d,i) { return scale0(getData(d,i)) })
- .attr(axis + '2', function(d,i) { return scale0(getData(d,i)) })
- d3.transition(distWrap.exit().selectAll('line.nv-dist' + axis))
- .attr(axis + '1', function(d,i) { return scale(getData(d,i)) })
- .attr(axis + '2', function(d,i) { return scale(getData(d,i)) })
- .style('stroke-opacity', 0)
- .remove();
- dist
- .attr('class', function(d,i) { return 'nv-dist' + axis + '
nv-dist' + axis + '-' + i })
- .attr(naxis + '1', 0)
- .attr(naxis + '2', size);
- d3.transition(dist)
- .attr(axis + '1', function(d,i) { return scale(getData(d,i)) })
- .attr(axis + '2', function(d,i) { return scale(getData(d,i)) })
-
-
- scale0 = scale.copy();
-
- });
-
- return chart;
- }
-
-
- //============================================================
- // Expose Public Variables
- //------------------------------------------------------------
-
- 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.axis = function(_) {
- if (!arguments.length) return axis;
- axis = _;
- return chart;
- };
-
- chart.size = function(_) {
- if (!arguments.length) return size;
- size = _;
- return chart;
- };
-
- chart.getData = function(_) {
- if (!arguments.length) return getData;
- getData = d3.functor(_);
- return chart;
- };
-
- chart.scale = function(_) {
- if (!arguments.length) return scale;
- scale = _;
- return chart;
- };
-
- chart.color = function(_) {
- if (!arguments.length) return color;
- color = nv.utils.getColor(_);
- return chart;
- };
-
- //============================================================
-
-
- return chart;
-}
-//TODO: consider deprecating and using multibar with single series for this
-nv.models.historicalBar = function() {
-
- //============================================================
- // Public Variables with Default Settings
- //------------------------------------------------------------
-
- var margin = {top: 0, right: 0, bottom: 0, left: 0}
- , 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
- , dispatch = d3.dispatch('chartClick', 'elementClick',
'elementDblClick', 'elementMouseover', 'elementMouseout')
- ;
-
- //============================================================
-
-
- function chart(selection) {
- selection.each(function(data) {
- var availableWidth = width - margin.left - margin.right,
- availableHeight = height - margin.top - margin.bottom,
- container = d3.select(this);
-
-
- //------------------------------------------------------------
- // Setup Scales
-
- x .domain(xDomain || d3.extent(data[0].values.map(getX).concat(forceX) ))
-
- if (padData)
- x.range([availableWidth * .5 / data[0].values.length, availableWidth *
(data[0].values.length - .5) / data[0].values.length ]);
- else
- x.range([0, availableWidth]);
-
- y .domain(yDomain || d3.extent(data[0].values.map(getY).concat(forceY) ))
- .range([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
- if (x.domain()[0] === x.domain()[1] || y.domain()[0] === y.domain()[1]) singlePoint
= true;
- 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]);
-
- //------------------------------------------------------------
-
-
- //------------------------------------------------------------
- // Setup containers and skeleton of chart
-
- var wrap = container.selectAll('g.nv-wrap.nv-bar').data([data[0].values]);
- var wrapEnter = wrap.enter().append('g').attr('class', 'nvd3
nv-wrap nv-bar');
- var defsEnter = wrapEnter.append('defs');
- var gEnter = wrapEnter.append('g');
- var g = wrap.select('g');
-
- 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
- });
- });
-
-
- defsEnter.append('clipPath')
- .attr('id', 'nv-chart-clip-path-' + id)
- .append('rect');
-
- wrap.select('#nv-chart-clip-path-' + id + ' rect')
- .attr('width', availableWidth)
- .attr('height', availableHeight);
-
- g .attr('clip-path', clipEdge ? 'url(#nv-chart-clip-path-' + id +
')' : '');
-
-
-
- var bars = wrap.select('.nv-bars').selectAll('.nv-bar')
- .data(function(d) { return d });
-
- 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 y(Math.max(0, getY(d,i))) })
- .attr('height', function(d,i) { return Math.abs(y(getY(d,i)) - y(0))
})
- .on('mouseover', function(d,i) {
- 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) {
- 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) {
- 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) {
- 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 })
- .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 )
-
-
- d3.transition(bars)
- //.attr('y', function(d,i) { return y(Math.max(0, getY(d,i))) })
- .attr('y', function(d,i) {
- return getY(d,i) < 0 ?
- y(0) :
- y(0) - y(getY(d,i)) < 1 ?
- y(0) - 1 :
- y(getY(d,i))
- })
- .attr('height', function(d,i) { return Math.max(Math.abs(y(getY(d,i)) -
y(0)),1) });
- //.order(); // not sure if this makes any sense for this model
-
- });
-
- return chart;
- }
-
-
- //============================================================
- // Expose Public Variables
- //------------------------------------------------------------
-
- chart.dispatch = dispatch;
-
- 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.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;
- };
-
- //============================================================
-
-
- return chart;
-}
-
-nv.models.historicalBarChart = function() {
-
- //============================================================
- // Public Variables with Default Settings
- //------------------------------------------------------------
-
- var bars = nv.models.historicalBar()
- , xAxis = nv.models.axis()
- , yAxis = nv.models.axis()
- , legend = nv.models.legend()
- ;
-
-
- var margin = {top: 30, right: 90, bottom: 50, left: 90}
- , color = nv.utils.defaultColor()
- , width = null
- , height = null
- , showLegend = false
- , showXAxis = true
- , showYAxis = true
- , rightAlignYAxis = false
- , tooltips = true
- , tooltip = function(key, x, y, e, graph) {
- return '<h3>' + key + '</h3>' +
- '<p>' + y + ' at ' + x + '</p>'
- }
- , x
- , y
- , state = {}
- , defaultState = null
- , noData = 'No Data Available.'
- , dispatch = d3.dispatch('tooltipShow', 'tooltipHide',
'stateChange', 'changeState')
- ;
-
- xAxis
- .orient('bottom')
- .tickPadding(7)
- ;
- yAxis
- .orient( (rightAlignYAxis) ? 'right' : 'left')
- ;
-
- //============================================================
-
-
- //============================================================
- // Private Variables
- //------------------------------------------------------------
-
- var showTooltip = function(e, offsetElement) {
-
- // New addition to calculate position if SVG is scaled with viewBox, may move TODO:
consider implementing everywhere else
- if (offsetElement) {
- var svg = d3.select(offsetElement).select('svg');
- var viewBox = (svg.node()) ? svg.attr('viewBox') : null;
- if (viewBox) {
- viewBox = viewBox.split(' ');
- var ratio = parseInt(svg.style('width')) / viewBox[2];
- e.pos[0] = e.pos[0] * ratio;
- e.pos[1] = e.pos[1] * ratio;
- }
- }
-
- var left = e.pos[0] + ( offsetElement.offsetLeft || 0 ),
- top = e.pos[1] + ( offsetElement.offsetTop || 0),
- x = xAxis.tickFormat()(bars.x()(e.point, e.pointIndex)),
- y = yAxis.tickFormat()(bars.y()(e.point, e.pointIndex)),
- content = tooltip(e.series.key, x, y, e, chart);
-
- nv.tooltip.show([left, top], content, null, null, offsetElement);
- };
-
- //============================================================
-
-
- function chart(selection) {
- selection.each(function(data) {
- var container = d3.select(this),
- that = this;
-
- var availableWidth = (width || parseInt(container.style('width')) || 960)
- - margin.left - margin.right,
- availableHeight = (height || parseInt(container.style('height')) ||
400)
- - margin.top - margin.bottom;
-
-
- chart.update = function() { chart(selection) };
- chart.container = this;
-
- //set state.disabled
- state.disabled = data.map(function(d) { return !!d.disabled });
-
- if (!defaultState) {
- var key;
- defaultState = {};
- for (key in state) {
- if (state[key] instanceof Array)
- defaultState[key] = state[key].slice(0);
- else
- defaultState[key] = state[key];
- }
- }
-
- //------------------------------------------------------------
- // Display noData message if there's nothing to show.
-
- if (!data || !data.length || !data.filter(function(d) { return d.values.length
}).length) {
- var noDataText = container.selectAll('.nv-noData').data([noData]);
-
- noDataText.enter().append('text')
- .attr('class', 'nvd3 nv-noData')
- .attr('dy', '-.7em')
- .style('text-anchor', 'middle');
-
- noDataText
- .attr('x', margin.left + availableWidth / 2)
- .attr('y', margin.top + availableHeight / 2)
- .text(function(d) { return d });
-
- return chart;
- } else {
- container.selectAll('.nv-noData').remove();
- }
-
- //------------------------------------------------------------
-
-
- //------------------------------------------------------------
- // Setup Scales
-
- x = bars.xScale();
- y = bars.yScale();
-
- //------------------------------------------------------------
-
-
- //------------------------------------------------------------
- // Setup containers and skeleton of chart
-
- var wrap = container.selectAll('g.nv-wrap.nv-lineChart').data([data]);
- var gEnter = wrap.enter().append('g').attr('class', 'nvd3
nv-wrap nv-lineChart').append('g');
- var g = wrap.select('g');
-
- gEnter.append('g').attr('class', 'nv-x nv-axis');
- gEnter.append('g').attr('class', 'nv-y nv-axis');
- gEnter.append('g').attr('class', 'nv-barsWrap');
- gEnter.append('g').attr('class', 'nv-legendWrap');
-
- //------------------------------------------------------------
-
-
- //------------------------------------------------------------
- // Legend
-
- if (showLegend) {
- legend.width(availableWidth);
-
- g.select('.nv-legendWrap')
- .datum(data)
- .call(legend);
-
- if ( margin.top != legend.height()) {
- margin.top = legend.height();
- availableHeight = (height || parseInt(container.style('height')) ||
400)
- - margin.top - margin.bottom;
- }
-
- wrap.select('.nv-legendWrap')
- .attr('transform', 'translate(0,' + (-margin.top)
+')')
- }
-
- //------------------------------------------------------------
-
- wrap.attr('transform', 'translate(' + margin.left + ',' +
margin.top + ')');
-
- if (rightAlignYAxis) {
- g.select(".nv-y.nv-axis")
- .attr("transform", "translate(" + availableWidth +
",0)");
- }
-
-
- //------------------------------------------------------------
- // Main Chart Component(s)
-
- bars
- .width(availableWidth)
- .height(availableHeight)
- .color(data.map(function(d,i) {
- return d.color || color(d, i);
- }).filter(function(d,i) { return !data[i].disabled }));
-
-
- var barsWrap = g.select('.nv-barsWrap')
- .datum(data.filter(function(d) { return !d.disabled }))
-
- d3.transition(barsWrap).call(bars);
-
- //------------------------------------------------------------
-
-
- //------------------------------------------------------------
- // Setup Axes
-
- if (showXAxis) {
- xAxis
- .scale(x)
- .tickSize(-availableHeight, 0);
-
- g.select('.nv-x.nv-axis')
- .attr('transform', 'translate(0,' + y.range()[0] +
')');
- g.select('.nv-x.nv-axis')
- .transition()
- .call(xAxis);
- }
-
- if (showYAxis) {
- yAxis
- .scale(y)
- .ticks( availableHeight / 36 )
- .tickSize( -availableWidth, 0);
-
- g.select('.nv-y.nv-axis')
- .transition().duration(0)
- .call(yAxis);
- }
- //------------------------------------------------------------
-
-
- //============================================================
- // Event Handling/Dispatching (in chart's scope)
- //------------------------------------------------------------
-
- 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 });
- dispatch.stateChange(state);
-
- selection.transition().call(chart);
- });
-
- legend.dispatch.on('legendDblclick', function(d) {
- //Double clicking should always enable current series, and disabled all
others.
- data.forEach(function(d) {
- d.disabled = true;
- });
- d.disabled = false;
-
- state.disabled = data.map(function(d) { return !!d.disabled });
- dispatch.stateChange(state);
- chart.update();
- });
-
-/*
- 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)
- });
-*/
-
- dispatch.on('tooltipShow', function(e) {
- if (tooltips) showTooltip(e, that.parentNode);
- });
-
-
- dispatch.on('changeState', function(e) {
-
- if (typeof e.disabled !== 'undefined') {
- data.forEach(function(series,i) {
- series.disabled = e.disabled[i];
- });
-
- state.disabled = e.disabled;
- }
-
- selection.call(chart);
- });
-
- //============================================================
-
- });
-
- return chart;
- }
-
-
- //============================================================
- // Event Handling/Dispatching (out of chart's scope)
- //------------------------------------------------------------
-
- bars.dispatch.on('elementMouseover.tooltip', function(e) {
- e.pos = [e.pos[0] + margin.left, e.pos[1] + margin.top];
- dispatch.tooltipShow(e);
- });
-
- bars.dispatch.on('elementMouseout.tooltip', function(e) {
- dispatch.tooltipHide(e);
- });
-
- dispatch.on('tooltipHide', function() {
- if (tooltips) nv.tooltip.cleanup();
- });
-
- //============================================================
-
-
- //============================================================
- // Expose Public Variables
- //------------------------------------------------------------
-
- // expose chart's sub-components
- chart.dispatch = dispatch;
- chart.bars = bars;
- chart.legend = legend;
- chart.xAxis = xAxis;
- chart.yAxis = yAxis;
-
- d3.rebind(chart, bars, 'defined', 'isArea', 'x', 'y',
'size', 'xScale', 'yScale', 'xDomain', 'yDomain',
'forceX', 'forceY', 'interactive', 'clipEdge',
'clipVoronoi', 'id', 'interpolate');
-
- 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.color = function(_) {
- if (!arguments.length) return color;
- color = nv.utils.getColor(_);
- legend.color(color);
- 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 = _;
- return chart;
- };
-
- chart.tooltipContent = function(_) {
- if (!arguments.length) return tooltip;
- tooltip = _;
- return chart;
- };
-
- chart.state = function(_) {
- if (!arguments.length) return state;
- state = _;
- return chart;
- };
-
- chart.defaultState = function(_) {
- if (!arguments.length) return defaultState;
- defaultState = _;
- return chart;
- };
-
- chart.noData = function(_) {
- if (!arguments.length) return noData;
- noData = _;
- return chart;
- };
-
- //============================================================
-
-
- return chart;
-}
-nv.models.indentedTree = function() {
-
- //============================================================
- // Public Variables with Default Settings
- //------------------------------------------------------------
-
- var margin = {top: 0, right: 0, bottom: 0, left: 0} //TODO: implement, maybe as margin
on the containing div
- , width = 960
- , height = 500
- , color = nv.utils.defaultColor()
- , id = Math.floor(Math.random() * 10000)
- , header = true
- , filterZero = false
- , noData = "No Data Available."
- , childIndent = 20
- , columns = [{key:'key', label: 'Name', type:'text'}] //TODO:
consider functions like chart.addColumn, chart.removeColumn, instead of a block like this
- , tableClass = null
- , iconOpen = 'images/grey-plus.png' //TODO: consider removing this and
replacing with a '+' or '-' unless user defines images
- , iconClose = 'images/grey-minus.png'
- , dispatch = d3.dispatch('elementClick', 'elementDblclick',
'elementMouseover', 'elementMouseout')
- ;
-
- //============================================================
-
- var idx = 0;
-
- function chart(selection) {
- selection.each(function(data) {
- var depth = 1,
- container = d3.select(this);
-
- var tree = d3.layout.tree()
- .children(function(d) { return d.values })
- .size([height, childIndent]); //Not sure if this is needed now that the result
is HTML
-
- chart.update = function() { container.transition().duration(600).call(chart) };
-
-
- //------------------------------------------------------------
- // Display No Data message if there's nothing to show.
- if (!data[0]) data[0] = {key: noData};
-
- //------------------------------------------------------------
-
-
- var nodes = tree.nodes(data[0]);
-
- // nodes.map(function(d) {
- // d.id = i++;
- // })
-
- //------------------------------------------------------------
- // Setup containers and skeleton of chart
-
- var wrap = d3.select(this).selectAll('div').data([[nodes]]);
- var wrapEnter = wrap.enter().append('div').attr('class', 'nvd3
nv-wrap nv-indentedtree');
- var tableEnter = wrapEnter.append('table');
- var table = wrap.select('table').attr('width',
'100%').attr('class', tableClass);
-
- //------------------------------------------------------------
-
-
- if (header) {
- var thead = tableEnter.append('thead');
-
- var theadRow1 = thead.append('tr');
-
- columns.forEach(function(column) {
- theadRow1
- .append('th')
- .attr('width', column.width ? column.width : '10%')
- .style('text-align', column.type == 'numeric' ?
'right' : 'left')
- .append('span')
- .text(column.label);
- });
- }
-
-
- var tbody = table.selectAll('tbody')
- .data(function(d) { return d });
- tbody.enter().append('tbody');
-
-
-
- //compute max generations
- depth = d3.max(nodes, function(node) { return node.depth });
- tree.size([height, depth * childIndent]); //TODO: see if this is necessary at all
-
-
- // Update the nodes…
- var node = tbody.selectAll('tr')
- // .data(function(d) { return d; }, function(d) { return d.id || (d.id ==
++i)});
- .data(function(d) { return d.filter(function(d) { return (filterZero &&
!d.children) ? filterZero(d) : true; } )}, function(d,i) { return d.id || (d.id ||
++idx)});
- //.style('display', 'table-row'); //TODO: see if this does
anything
-
- node.exit().remove();
-
- node.select('img.nv-treeicon')
- .attr('src', icon)
- .classed('folded', folded);
-
- var nodeEnter = node.enter().append('tr');
-
-
- columns.forEach(function(column, index) {
-
- var nodeName = nodeEnter.append('td')
- .style('padding-left', function(d) { return (index ? 0 : d.depth *
childIndent + 12 + (icon(d) ? 0 : 16)) + 'px' }, 'important') //TODO:
check why I did the ternary here
- .style('text-align', column.type == 'numeric' ?
'right' : 'left');
-
-
- if (index == 0) {
- nodeName.append('img')
- .classed('nv-treeicon', true)
- .classed('nv-folded', folded)
- .attr('src', icon)
- .style('width', '14px')
- .style('height', '14px')
- .style('padding', '0 1px')
- .style('display', function(d) { return icon(d) ?
'inline-block' : 'none'; })
- .on('click', click);
- }
-
-
- nodeName.append('span')
- .attr('class', d3.functor(column.classes) )
- .text(function(d) { return column.format ? column.format(d) :
- (d[column.key] || '-') });
-
- if (column.showCount) {
- nodeName.append('span')
- .attr('class', 'nv-childrenCount');
-
- node.selectAll('span.nv-childrenCount').text(function(d) {
- return ((d.values && d.values.length) || (d._values &&
d._values.length)) ? //If this is a parent
- '(' + ((d.values && (d.values.filter(function(d) {
return filterZero ? filterZero(d) : true; }).length)) //If children are in values check
its children and filter
- || (d._values && d._values.filter(function(d) { return
filterZero ? filterZero(d) : true; }).length) //Otherwise, do the same, but with the
other name, _values...
- || 0) + ')'
//This is the catch-all in case there are no
children after a filter
- : ''
//If this is not a parent, just give an empty
string
- });
- }
-
- if (column.click)
- nodeName.select('span').on('click', column.click);
-
- });
-
- node
- .order()
- .on('click', function(d) {
- dispatch.elementClick({
- row: this, //TODO: decide whether or not this should be consistent with
scatter/line events or should be an html link (a href)
- data: d,
- pos: [d.x, d.y]
- });
- })
- .on('dblclick', function(d) {
- dispatch.elementDblclick({
- row: this,
- data: d,
- pos: [d.x, d.y]
- });
- })
- .on('mouseover', function(d) {
- dispatch.elementMouseover({
- row: this,
- data: d,
- pos: [d.x, d.y]
- });
- })
- .on('mouseout', function(d) {
- dispatch.elementMouseout({
- row: this,
- data: d,
- pos: [d.x, d.y]
- });
- });
-
-
-
-
- // Toggle children on click.
- function click(d, _, unshift) {
- d3.event.stopPropagation();
-
- if(d3.event.shiftKey && !unshift) {
- //If you shift-click, it'll toggle fold all the children, instead of
itself
- d3.event.shiftKey = false;
- d.values && d.values.forEach(function(node){
- if (node.values || node._values) {
- click(node, 0, true);
- }
- });
- return true;
- }
- if(!hasChildren(d)) {
- //download file
- //window.location.href = d.url;
- return true;
- }
- if (d.values) {
- d._values = d.values;
- d.values = null;
- } else {
- d.values = d._values;
- d._values = null;
- }
- chart.update();
- }
-
-
- function icon(d) {
- return (d._values && d._values.length) ? iconOpen : (d.values &&
d.values.length) ? iconClose : '';
- }
-
- function folded(d) {
- return (d._values && d._values.length);
- }
-
- function hasChildren(d) {
- var values = d.values || d._values;
-
- return (values && values.length);
- }
-
-
- });
-
- return chart;
- }
-
-
- //============================================================
- // Expose Public Variables
- //------------------------------------------------------------
-
- 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.color = function(_) {
- if (!arguments.length) return color;
- color = nv.utils.getColor(_);
- scatter.color(color);
- return chart;
- };
-
- chart.id = function(_) {
- if (!arguments.length) return id;
- id = _;
- return chart;
- };
-
- chart.header = function(_) {
- if (!arguments.length) return header;
- header = _;
- return chart;
- };
-
- chart.noData = function(_) {
- if (!arguments.length) return noData;
- noData = _;
- return chart;
- };
-
- chart.filterZero = function(_) {
- if (!arguments.length) return filterZero;
- filterZero = _;
- return chart;
- };
-
- chart.columns = function(_) {
- if (!arguments.length) return columns;
- columns = _;
- return chart;
- };
-
- chart.tableClass = function(_) {
- if (!arguments.length) return tableClass;
- tableClass = _;
- return chart;
- };
-
- chart.iconOpen = function(_){
- if (!arguments.length) return iconOpen;
- iconOpen = _;
- return chart;
- }
-
- chart.iconClose = function(_){
- if (!arguments.length) return iconClose;
- iconClose = _;
- return chart;
- }
-
- //============================================================
-
-
- return chart;
-};nv.models.legend = function() {
-
- //============================================================
- // Public Variables with Default Settings
- //------------------------------------------------------------
-
- var margin = {top: 5, right: 0, bottom: 5, left: 0}
- , width = 400
- , height = 20
- , getKey = function(d) { return d.key }
- , color = nv.utils.defaultColor()
- , align = true
- , dispatch = d3.dispatch('legendClick', 'legendDblclick',
'legendMouseover', 'legendMouseout')
- ;
-
- //============================================================
-
-
- function chart(selection) {
- selection.each(function(data) {
- var availableWidth = width - margin.left - margin.right,
- container = d3.select(this);
-
-
- //------------------------------------------------------------
- // Setup containers and skeleton of chart
-
- var wrap = container.selectAll('g.nv-legend').data([data]);
- var gEnter = wrap.enter().append('g').attr('class', 'nvd3
nv-legend').append('g');
- var g = wrap.select('g');
-
- wrap.attr('transform', 'translate(' + margin.left + ',' +
margin.top + ')');
-
- //------------------------------------------------------------
-
-
- var series = g.selectAll('.nv-series')
- .data(function(d) { return d });
- var seriesEnter = series.enter().append('g').attr('class',
'nv-series')
- .on('mouseover', function(d,i) {
- dispatch.legendMouseover(d,i); //TODO: Make consistent with other event
objects
- })
- .on('mouseout', function(d,i) {
- dispatch.legendMouseout(d,i);
- })
- .on('click', function(d,i) {
- dispatch.legendClick(d,i);
- })
- .on('dblclick', function(d,i) {
- dispatch.legendDblclick(d,i);
- });
- seriesEnter.append('circle')
- .style('stroke-width', 2)
- .attr('r', 5);
- seriesEnter.append('text')
- .attr('text-anchor', 'start')
- .attr('dy', '.32em')
- .attr('dx', '8');
- series.classed('disabled', function(d) { return d.disabled });
- series.exit().remove();
- series.select('circle')
- .style('fill', function(d,i) { return d.color || color(d,i)})
- .style('stroke', function(d,i) { return d.color || color(d, i) });
- series.select('text').text(getKey);
-
-
- //TODO: implement fixed-width and max-width options (max-width is especially useful
with the align option)
-
- // NEW ALIGNING CODE, TODO: clean up
- if (align) {
-
- var seriesWidths = [];
- series.each(function(d,i) {
- var legendText = d3.select(this).select('text');
- var svgComputedTextLength = legendText.node().getComputedTextLength()
- || nv.utils.calcApproxTextWidth(legendText);
- seriesWidths.push(svgComputedTextLength + 28); // 28 is ~ the width of the
circle plus some padding
- });
-
- //nv.log('Series Widths: ', JSON.stringify(seriesWidths));
-
- var seriesPerRow = 0;
- var legendWidth = 0;
- var columnWidths = [];
-
- while ( legendWidth < availableWidth && seriesPerRow <
seriesWidths.length) {
- columnWidths[seriesPerRow] = seriesWidths[seriesPerRow];
- legendWidth += seriesWidths[seriesPerRow++];
- }
-
-
- while ( legendWidth > availableWidth && seriesPerRow > 1 ) {
- columnWidths = [];
- seriesPerRow--;
-
- for (k = 0; k < seriesWidths.length; k++) {
- if (seriesWidths[k] > (columnWidths[k % seriesPerRow] || 0) )
- columnWidths[k % seriesPerRow] = seriesWidths[k];
- }
-
- legendWidth = columnWidths.reduce(function(prev, cur, index, array) {
- return prev + cur;
- });
- }
- //console.log(columnWidths, legendWidth, seriesPerRow);
-
- var xPositions = [];
- for (var i = 0, curX = 0; i < seriesPerRow; i++) {
- xPositions[i] = curX;
- curX += columnWidths[i];
- }
-
- series
- .attr('transform', function(d, i) {
- return 'translate(' + xPositions[i % seriesPerRow] + ',' +
(5 + Math.floor(i / seriesPerRow) * 20) + ')';
- });
-
- //position legend as far right as possible within the total width
- g.attr('transform', 'translate(' + (width - margin.right -
legendWidth) + ',' + margin.top + ')');
-
- height = margin.top + margin.bottom + (Math.ceil(seriesWidths.length /
seriesPerRow) * 20);
-
- } else {
-
- var ypos = 5,
- newxpos = 5,
- maxwidth = 0,
- xpos;
- series
- .attr('transform', function(d, i) {
- var length =
d3.select(this).select('text').node().getComputedTextLength() + 28;
- xpos = newxpos;
-
- if (width < margin.left + margin.right + xpos + length) {
- newxpos = xpos = 5;
- ypos += 20;
- }
-
- newxpos += length;
- if (newxpos > maxwidth) maxwidth = newxpos;
-
- return 'translate(' + xpos + ',' + ypos + ')';
- });
-
- //position legend as far right as possible within the total width
- g.attr('transform', 'translate(' + (width - margin.right -
maxwidth) + ',' + margin.top + ')');
-
- height = margin.top + margin.bottom + ypos + 15;
-
- }
-
- });
-
- return chart;
- }
-
-
- //============================================================
- // Expose Public Variables
- //------------------------------------------------------------
-
- chart.dispatch = dispatch;
-
- 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.key = function(_) {
- if (!arguments.length) return getKey;
- getKey = _;
- return chart;
- };
-
- chart.color = function(_) {
- if (!arguments.length) return color;
- color = nv.utils.getColor(_);
- return chart;
- };
-
- chart.align = function(_) {
- if (!arguments.length) return align;
- align = _;
- return chart;
- };
-
- //============================================================
-
-
- return chart;
-}
-
-nv.models.line = function() {
-
- //============================================================
- // Public Variables with Default Settings
- //------------------------------------------------------------
-
- var scatter = nv.models.scatter()
- ;
-
- var margin = {top: 0, right: 0, bottom: 0, left: 0}
- , width = 960
- , height = 500
- , color = nv.utils.defaultColor() // a function that returns a color
- , getX = function(d) { return d.x } // accessor to get the x value from a data point
- , getY = function(d) { return d.y } // accessor to get the y value from a data point
- , defined = function(d,i) { return !isNaN(getY(d,i)) && getY(d,i) !== null }
// allows a line to be not continuous when it is not defined
- , isArea = function(d) { return d.area } // decides if a line is an area or just a
line
- , clipEdge = false // if true, masks lines within x and y scale
- , x //can be accessed via chart.xScale()
- , y //can be accessed via chart.yScale()
- , interpolate = "linear" // controls the line interpolation
- ;
-
- scatter
- .size(16) // default size
- .sizeDomain([16,256]) //set to speed up calculation, needs to be unset if there is a
custom size accessor
- ;
-
- //============================================================
-
-
- //============================================================
- // Private Variables
- //------------------------------------------------------------
-
- var x0, y0 //used to store previous scales
- ;
-
- //============================================================
-
-
- function chart(selection) {
- selection.each(function(data) {
- var availableWidth = width - margin.left - margin.right,
- availableHeight = height - margin.top - margin.bottom,
- container = d3.select(this);
-
- //------------------------------------------------------------
- // Setup Scales
-
- x = scatter.xScale();
- y = scatter.yScale();
-
- x0 = x0 || x;
- y0 = y0 || y;
-
- //------------------------------------------------------------
-
-
- //------------------------------------------------------------
- // Setup containers and skeleton of chart
-
- var wrap = container.selectAll('g.nv-wrap.nv-line').data([data]);
- var wrapEnter = wrap.enter().append('g').attr('class', 'nvd3
nv-wrap nv-line');
- var defsEnter = wrapEnter.append('defs');
- var gEnter = wrapEnter.append('g');
- var g = wrap.select('g')
-
- gEnter.append('g').attr('class', 'nv-groups');
- gEnter.append('g').attr('class', 'nv-scatterWrap');
-
- wrap.attr('transform', 'translate(' + margin.left + ',' +
margin.top + ')');
-
- //------------------------------------------------------------
-
-
-
-
- scatter
- .width(availableWidth)
- .height(availableHeight)
-
- var scatterWrap = wrap.select('.nv-scatterWrap');
- //.datum(data); // Data automatically trickles down from the wrap
-
- d3.transition(scatterWrap).call(scatter);
-
-
-
- defsEnter.append('clipPath')
- .attr('id', 'nv-edge-clip-' + scatter.id())
- .append('rect');
-
- wrap.select('#nv-edge-clip-' + scatter.id() + ' rect')
- .attr('width', availableWidth)
- .attr('height', availableHeight);
-
- g .attr('clip-path', clipEdge ? 'url(#nv-edge-clip-' +
scatter.id() + ')' : '');
- scatterWrap
- .attr('clip-path', clipEdge ? 'url(#nv-edge-clip-' +
scatter.id() + ')' : '');
-
-
-
-
- var groups = wrap.select('.nv-groups').selectAll('.nv-group')
- .data(function(d) { return d }, function(d) { return d.key });
- groups.enter().append('g')
- .style('stroke-opacity', 1e-6)
- .style('fill-opacity', 1e-6);
- d3.transition(groups.exit())
- .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 })
- .style('fill', function(d,i){ return color(d, i) })
- .style('stroke', function(d,i){ return color(d, i)});
- d3.transition(groups)
- .style('stroke-opacity', 1)
- .style('fill-opacity', .5);
-
-
-
- var areaPaths = groups.selectAll('path.nv-area')
- .data(function(d) { return isArea(d) ? [d] : [] }); // this is done differently
than lines because I need to check if series is an area
- areaPaths.enter().append('path')
- .attr('class', 'nv-area')
- .attr('d', function(d) {
- return d3.svg.area()
- .interpolate(interpolate)
- .defined(defined)
- .x(function(d,i) { return x0(getX(d,i)) })
- .y0(function(d,i) { return y0(getY(d,i)) })
- .y1(function(d,i) { return y0( y.domain()[0] <= 0 ? y.domain()[1]
>= 0 ? 0 : y.domain()[1] : y.domain()[0] ) })
- //.y1(function(d,i) { return y0(0) }) //assuming 0 is within y domain..
may need to tweak this
- .apply(this, [d.values])
- });
- d3.transition(groups.exit().selectAll('path.nv-area'))
- .attr('d', function(d) {
- return d3.svg.area()
- .interpolate(interpolate)
- .defined(defined)
- .x(function(d,i) { return x(getX(d,i)) })
- .y0(function(d,i) { return y(getY(d,i)) })
- .y1(function(d,i) { return y( y.domain()[0] <= 0 ? y.domain()[1] >=
0 ? 0 : y.domain()[1] : y.domain()[0] ) })
- //.y1(function(d,i) { return y0(0) }) //assuming 0 is within y domain..
may need to tweak this
- .apply(this, [d.values])
- });
- d3.transition(areaPaths)
- .attr('d', function(d) {
- return d3.svg.area()
- .interpolate(interpolate)
- .defined(defined)
- .x(function(d,i) { return x(getX(d,i)) })
- .y0(function(d,i) { return y(getY(d,i)) })
- .y1(function(d,i) { return y( y.domain()[0] <= 0 ? y.domain()[1] >=
0 ? 0 : y.domain()[1] : y.domain()[0] ) })
- //.y1(function(d,i) { return y0(0) }) //assuming 0 is within y domain..
may need to tweak this
- .apply(this, [d.values])
- });
-
-
-
- var linePaths = groups.selectAll('path.nv-line')
- .data(function(d) { return [d.values] });
- linePaths.enter().append('path')
- .attr('class', 'nv-line')
- .attr('d',
- d3.svg.line()
- .interpolate(interpolate)
- .defined(defined)
- .x(function(d,i) { return x0(getX(d,i)) })
- .y(function(d,i) { return y0(getY(d,i)) })
- );
- d3.transition(groups.exit().selectAll('path.nv-line'))
- .attr('d',
- d3.svg.line()
- .interpolate(interpolate)
- .defined(defined)
- .x(function(d,i) { return x(getX(d,i)) })
- .y(function(d,i) { return y(getY(d,i)) })
- );
- d3.transition(linePaths)
- .attr('d',
- d3.svg.line()
- .interpolate(interpolate)
- .defined(defined)
- .x(function(d,i) { return x(getX(d,i)) })
- .y(function(d,i) { return y(getY(d,i)) })
- );
-
-
-
- //store old scales for use in transitions on update
- x0 = x.copy();
- y0 = y.copy();
-
- });
-
- return chart;
- }
-
-
- //============================================================
- // Expose Public Variables
- //------------------------------------------------------------
-
- chart.dispatch = scatter.dispatch;
- chart.scatter = scatter;
-
- d3.rebind(chart, scatter, 'id', 'interactive', 'size',
'xScale', 'yScale', 'zScale', 'xDomain',
'yDomain', 'sizeDomain', 'forceX', 'forceY',
'forceSize', 'clipVoronoi', 'clipRadius', 'padData');
-
- 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.x = function(_) {
- if (!arguments.length) return getX;
- getX = _;
- scatter.x(_);
- return chart;
- };
-
- chart.y = function(_) {
- if (!arguments.length) return getY;
- getY = _;
- scatter.y(_);
- 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(_);
- scatter.color(color);
- return chart;
- };
-
- chart.interpolate = function(_) {
- if (!arguments.length) return interpolate;
- interpolate = _;
- return chart;
- };
-
- chart.defined = function(_) {
- if (!arguments.length) return defined;
- defined = _;
- return chart;
- };
-
- chart.isArea = function(_) {
- if (!arguments.length) return isArea;
- isArea = d3.functor(_);
- return chart;
- };
-
- //============================================================
-
-
- return chart;
-}
-
-nv.models.lineChart = function() {
-
- //============================================================
- // Public Variables with Default Settings
- //------------------------------------------------------------
-
- var lines = nv.models.line()
- , xAxis = nv.models.axis()
- , yAxis = nv.models.axis()
- , legend = nv.models.legend()
- ;
-
-//set margin.right to 23 to fit dates on the x-axis within the chart
- var margin = {top: 30, right: 20, bottom: 50, left: 60}
- , color = nv.utils.defaultColor()
- , width = null
- , height = null
- , showLegend = true
- , showXAxis = true
- , showYAxis = true
- , rightAlignYAxis = false
- , tooltips = true
- , tooltip = function(key, x, y, e, graph) {
- return '<h3>' + key + '</h3>' +
- '<p>' + y + ' at ' + x + '</p>'
- }
- , x
- , y
- , state = {}
- , defaultState = null
- , noData = 'No Data Available.'
- , dispatch = d3.dispatch('tooltipShow', 'tooltipHide',
'stateChange', 'changeState')
- ;
-
- xAxis
- .orient('bottom')
- .tickPadding(7)
- ;
- yAxis
- .orient((rightAlignYAxis) ? 'right' : 'left')
- ;
-
- //============================================================
-
-
- //============================================================
- // Private Variables
- //------------------------------------------------------------
-
- var showTooltip = function(e, offsetElement) {
-
- // New addition to calculate position if SVG is scaled with viewBox, may move TODO:
consider implementing everywhere else
- if (offsetElement) {
- var svg = d3.select(offsetElement).select('svg');
- var viewBox = (svg.node()) ? svg.attr('viewBox') : null;
- if (viewBox) {
- viewBox = viewBox.split(' ');
- var ratio = parseInt(svg.style('width')) / viewBox[2];
- e.pos[0] = e.pos[0] * ratio;
- e.pos[1] = e.pos[1] * ratio;
- }
- }
-
- var left = e.pos[0] + ( offsetElement.offsetLeft || 0 ),
- top = e.pos[1] + ( offsetElement.offsetTop || 0),
- x = xAxis.tickFormat()(lines.x()(e.point, e.pointIndex)),
- y = yAxis.tickFormat()(lines.y()(e.point, e.pointIndex)),
- content = tooltip(e.series.key, x, y, e, chart);
-
- nv.tooltip.show([left, top], content, null, null, offsetElement);
- };
-
- //============================================================
-
-
- function chart(selection) {
- selection.each(function(data) {
- var container = d3.select(this),
- that = this;
-
- var availableWidth = (width || parseInt(container.style('width')) || 960)
- - margin.left - margin.right,
- availableHeight = (height || parseInt(container.style('height')) ||
400)
- - margin.top - margin.bottom;
-
-
- chart.update = function() { container.transition().call(chart) };
- chart.container = this;
-
- //set state.disabled
- state.disabled = data.map(function(d) { return !!d.disabled });
-
- if (!defaultState) {
- var key;
- defaultState = {};
- for (key in state) {
- if (state[key] instanceof Array)
- defaultState[key] = state[key].slice(0);
- else
- defaultState[key] = state[key];
- }
- }
-
- //------------------------------------------------------------
- // Display noData message if there's nothing to show.
-
- if (!data || !data.length || !data.filter(function(d) { return d.values.length
}).length) {
- var noDataText = container.selectAll('.nv-noData').data([noData]);
-
- noDataText.enter().append('text')
- .attr('class', 'nvd3 nv-noData')
- .attr('dy', '-.7em')
- .style('text-anchor', 'middle');
-
- noDataText
- .attr('x', margin.left + availableWidth / 2)
- .attr('y', margin.top + availableHeight / 2)
- .text(function(d) { return d });
-
- return chart;
- } else {
- container.selectAll('.nv-noData').remove();
- }
-
- //------------------------------------------------------------
-
-
- //------------------------------------------------------------
- // Setup Scales
-
- x = lines.xScale();
- y = lines.yScale();
-
- //------------------------------------------------------------
-
-
- //------------------------------------------------------------
- // Setup containers and skeleton of chart
-
- var wrap = container.selectAll('g.nv-wrap.nv-lineChart').data([data]);
- var gEnter = wrap.enter().append('g').attr('class', 'nvd3
nv-wrap nv-lineChart').append('g');
- var g = wrap.select('g');
-
- gEnter.append('g').attr('class', 'nv-x nv-axis');
- gEnter.append('g').attr('class', 'nv-y nv-axis');
- gEnter.append('g').attr('class', 'nv-linesWrap');
- gEnter.append('g').attr('class', 'nv-legendWrap');
-
- //------------------------------------------------------------
-
-
- //------------------------------------------------------------
- // Legend
-
- if (showLegend) {
- legend.width(availableWidth);
-
- g.select('.nv-legendWrap')
- .datum(data)
- .call(legend);
-
- if ( margin.top != legend.height()) {
- margin.top = legend.height();
- availableHeight = (height || parseInt(container.style('height')) ||
400)
- - margin.top - margin.bottom;
- }
-
- wrap.select('.nv-legendWrap')
- .attr('transform', 'translate(0,' + (-margin.top)
+')')
- }
-
- //------------------------------------------------------------
-
- wrap.attr('transform', 'translate(' + margin.left + ',' +
margin.top + ')');
-
- if (rightAlignYAxis) {
- g.select(".nv-y.nv-axis")
- .attr("transform", "translate(" + availableWidth +
",0)");
- }
-
- //------------------------------------------------------------
- // Main Chart Component(s)
-
- lines
- .width(availableWidth)
- .height(availableHeight)
- .color(data.map(function(d,i) {
- return d.color || color(d, i);
- }).filter(function(d,i) { return !data[i].disabled }));
-
-
- var linesWrap = g.select('.nv-linesWrap')
- .datum(data.filter(function(d) { return !d.disabled }))
-
- d3.transition(linesWrap).call(lines);
-
- //------------------------------------------------------------
-
-
- //------------------------------------------------------------
- // Setup Axes
-
- if (showXAxis) {
- xAxis
- .scale(x)
- .ticks( availableWidth / 100 )
- .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 (showYAxis) {
- yAxis
- .scale(y)
- .ticks( availableHeight / 36 )
- .tickSize( -availableWidth, 0);
-
- d3.transition(g.select('.nv-y.nv-axis'))
- .call(yAxis);
- }
- //------------------------------------------------------------
-
-
- //============================================================
- // Event Handling/Dispatching (in chart's scope)
- //------------------------------------------------------------
-
- 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 });
- dispatch.stateChange(state);
-
- // container.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;
- });
- d.disabled = false;
-
- state.disabled = data.map(function(d) { return !!d.disabled });
- dispatch.stateChange(state);
- chart.update();
- });
-
-
-/*
- 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)
- });
-*/
-
- dispatch.on('tooltipShow', function(e) {
- if (tooltips) showTooltip(e, that.parentNode);
- });
-
-
- dispatch.on('changeState', function(e) {
-
- if (typeof e.disabled !== 'undefined') {
- data.forEach(function(series,i) {
- series.disabled = e.disabled[i];
- });
-
- state.disabled = e.disabled;
- }
-
- chart.update();
- });
-
- //============================================================
-
- });
-
- return chart;
- }
-
-
- //============================================================
- // Event Handling/Dispatching (out of chart's scope)
- //------------------------------------------------------------
-
- lines.dispatch.on('elementMouseover.tooltip', function(e) {
- e.pos = [e.pos[0] + margin.left, e.pos[1] + margin.top];
- dispatch.tooltipShow(e);
- });
-
- lines.dispatch.on('elementMouseout.tooltip', function(e) {
- dispatch.tooltipHide(e);
- });
-
- dispatch.on('tooltipHide', function() {
- if (tooltips) nv.tooltip.cleanup();
- });
-
- //============================================================
-
-
- //============================================================
- // Expose Public Variables
- //------------------------------------------------------------
-
- // expose chart's sub-components
- chart.dispatch = dispatch;
- chart.lines = lines;
- chart.legend = legend;
- chart.xAxis = xAxis;
- chart.yAxis = yAxis;
-
- d3.rebind(chart, lines, 'defined', 'isArea', 'x', 'y',
'size', 'xScale', 'yScale', 'xDomain', 'yDomain',
'forceX', 'forceY', 'interactive', 'clipEdge',
'clipVoronoi', 'id', 'interpolate');
-
- 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.color = function(_) {
- if (!arguments.length) return color;
- color = nv.utils.getColor(_);
- legend.color(color);
- 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 = _;
- return chart;
- };
-
- chart.tooltipContent = function(_) {
- if (!arguments.length) return tooltip;
- tooltip = _;
- return chart;
- };
-
- chart.state = function(_) {
- if (!arguments.length) return state;
- state = _;
- return chart;
- };
-
- chart.defaultState = function(_) {
- if (!arguments.length) return defaultState;
- defaultState = _;
- return chart;
- };
-
- chart.noData = function(_) {
- if (!arguments.length) return noData;
- noData = _;
- return chart;
- };
-
- //============================================================
-
-
- return chart;
-}
-
-nv.models.linePlusBarChart = function() {
-
- //============================================================
- // Public Variables with Default Settings
- //------------------------------------------------------------
-
- var lines = nv.models.line()
- , bars = nv.models.historicalBar()
- , xAxis = nv.models.axis()
- , y1Axis = nv.models.axis()
- , y2Axis = nv.models.axis()
- , legend = nv.models.legend()
- ;
-
- var margin = {top: 30, right: 60, bottom: 50, left: 60}
- , width = null
- , height = null
- , getX = function(d) { return d.x }
- , getY = function(d) { return d.y }
- , color = nv.utils.defaultColor()
- , showLegend = true
- , tooltips = true
- , tooltip = function(key, x, y, e, graph) {
- return '<h3>' + key + '</h3>' +
- '<p>' + y + ' at ' + x + '</p>';
- }
- , x
- , y1
- , y2
- , state = {}
- , defaultState = null
- , noData = "No Data Available."
- , dispatch = d3.dispatch('tooltipShow', 'tooltipHide',
'stateChange', 'changeState')
- ;
-
- bars
- .padData(true)
- ;
- lines
- .clipEdge(false)
- .padData(true)
- ;
- xAxis
- .orient('bottom')
- .tickPadding(7)
- .highlightZero(false)
- ;
- y1Axis
- .orient('left')
- ;
- y2Axis
- .orient('right')
- ;
-
- //============================================================
-
-
- //============================================================
- // Private Variables
- //------------------------------------------------------------
-
- var showTooltip = function(e, offsetElement) {
- var left = e.pos[0] + ( offsetElement.offsetLeft || 0 ),
- top = e.pos[1] + ( offsetElement.offsetTop || 0),
- x = xAxis.tickFormat()(lines.x()(e.point, e.pointIndex)),
- y = (e.series.bar ? y1Axis : y2Axis).tickFormat()(lines.y()(e.point,
e.pointIndex)),
- content = tooltip(e.series.key, x, y, e, chart);
-
- nv.tooltip.show([left, top], content, e.value < 0 ? 'n' : 's',
null, offsetElement);
- }
- ;
-
- //------------------------------------------------------------
-
-
-
- function chart(selection) {
- selection.each(function(data) {
- var container = d3.select(this),
- that = this;
-
- var availableWidth = (width || parseInt(container.style('width')) || 960)
- - margin.left - margin.right,
- availableHeight = (height || parseInt(container.style('height')) ||
400)
- - margin.top - margin.bottom;
-
- chart.update = function() { container.transition().call(chart); };
- // chart.container = this;
-
- //set state.disabled
- state.disabled = data.map(function(d) { return !!d.disabled });
-
- if (!defaultState) {
- var key;
- defaultState = {};
- for (key in state) {
- if (state[key] instanceof Array)
- defaultState[key] = state[key].slice(0);
- else
- defaultState[key] = state[key];
- }
- }
-
- //------------------------------------------------------------
- // Display No Data message if there's nothing to show.
-
- if (!data || !data.length || !data.filter(function(d) { return d.values.length
}).length) {
- var noDataText = container.selectAll('.nv-noData').data([noData]);
-
- noDataText.enter().append('text')
- .attr('class', 'nvd3 nv-noData')
- .attr('dy', '-.7em')
- .style('text-anchor', 'middle');
-
- noDataText
- .attr('x', margin.left + availableWidth / 2)
- .attr('y', margin.top + availableHeight / 2)
- .text(function(d) { return d });
-
- return chart;
- } else {
- container.selectAll('.nv-noData').remove();
- }
-
- //------------------------------------------------------------
-
-
- //------------------------------------------------------------
- // Setup Scales
-
- var dataBars = data.filter(function(d) { return !d.disabled && d.bar });
- var dataLines = data.filter(function(d) { return !d.bar }); // removed the
!d.disabled clause here to fix Issue #240
-
- //x = xAxis.scale();
- x = dataLines.filter(function(d) { return !d.disabled; }).length &&
dataLines.filter(function(d) { return !d.disabled; })[0].values.length ? lines.xScale() :
bars.xScale();
- //x = dataLines.filter(function(d) { return !d.disabled; }).length ? lines.xScale()
: bars.xScale(); //old code before change above
- y1 = bars.yScale();
- y2 = lines.yScale();
-
- //------------------------------------------------------------
-
- //------------------------------------------------------------
- // Setup containers and skeleton of chart
-
- var wrap =
d3.select(this).selectAll('g.nv-wrap.nv-linePlusBar').data([data]);
- var gEnter = wrap.enter().append('g').attr('class', 'nvd3
nv-wrap nv-linePlusBar').append('g');
- var g = wrap.select('g');
-
- gEnter.append('g').attr('class', 'nv-x nv-axis');
- gEnter.append('g').attr('class', 'nv-y1 nv-axis');
- gEnter.append('g').attr('class', 'nv-y2 nv-axis');
- gEnter.append('g').attr('class', 'nv-barsWrap');
- gEnter.append('g').attr('class', 'nv-linesWrap');
- gEnter.append('g').attr('class', 'nv-legendWrap');
-
- //------------------------------------------------------------
-
-
- //------------------------------------------------------------
- // Legend
-
- if (showLegend) {
- legend.width( availableWidth / 2 );
-
- g.select('.nv-legendWrap')
- .datum(data.map(function(series) {
- series.originalKey = series.originalKey === undefined ? series.key :
series.originalKey;
- series.key = series.originalKey + (series.bar ? ' (left axis)' :
' (right axis)');
- return series;
- }))
- .call(legend);
-
- if ( margin.top != legend.height()) {
- margin.top = legend.height();
- availableHeight = (height || parseInt(container.style('height')) ||
400)
- - margin.top - margin.bottom;
- }
-
- g.select('.nv-legendWrap')
- .attr('transform', 'translate(' + ( availableWidth / 2 ) +
',' + (-margin.top) +')');
- }
-
- //------------------------------------------------------------
-
-
- wrap.attr('transform', 'translate(' + margin.left + ',' +
margin.top + ')');
-
-
- //------------------------------------------------------------
- // Main Chart Component(s)
-
-
- lines
- .width(availableWidth)
- .height(availableHeight)
- .color(data.map(function(d,i) {
- return d.color || color(d, i);
- }).filter(function(d,i) { return !data[i].disabled && !data[i].bar }))
-
- bars
- .width(availableWidth)
- .height(availableHeight)
- .color(data.map(function(d,i) {
- return d.color || color(d, i);
- }).filter(function(d,i) { return !data[i].disabled && data[i].bar }))
-
-
-
- var barsWrap = g.select('.nv-barsWrap')
- .datum(dataBars.length ? dataBars : [{values:[]}])
-
- var linesWrap = g.select('.nv-linesWrap')
- .datum(dataLines[0] && !dataLines[0].disabled ? dataLines :
[{values:[]}] );
- //.datum(!dataLines[0].disabled ? dataLines :
[{values:dataLines[0].values.map(function(d) { return [d[0], null] }) }] );
-
- d3.transition(barsWrap).call(bars);
- d3.transition(linesWrap).call(lines);
-
- //------------------------------------------------------------
-
-
- //------------------------------------------------------------
- // Setup Axes
-
- xAxis
- .scale(x)
- .ticks( availableWidth / 100 )
- .tickSize(-availableHeight, 0);
-
- g.select('.nv-x.nv-axis')
- .attr('transform', 'translate(0,' + y1.range()[0] +
')');
- d3.transition(g.select('.nv-x.nv-axis'))
- .call(xAxis);
-
-
- y1Axis
- .scale(y1)
- .ticks( availableHeight / 36 )
- .tickSize(-availableWidth, 0);
-
- d3.transition(g.select('.nv-y1.nv-axis'))
- .style('opacity', dataBars.length ? 1 : 0)
- .call(y1Axis);
-
-
- y2Axis
- .scale(y2)
- .ticks( availableHeight / 36 )
- .tickSize(dataBars.length ? 0 : -availableWidth, 0); // Show the y2 rules only if
y1 has none
-
- g.select('.nv-y2.nv-axis')
- .style('opacity', dataLines.length ? 1 : 0)
- .attr('transform', 'translate(' + availableWidth +
',0)');
- //.attr('transform', 'translate(' + x.range()[1] +
',0)');
-
- d3.transition(g.select('.nv-y2.nv-axis'))
- .call(y2Axis);
-
- //------------------------------------------------------------
-
-
- //============================================================
- // Event Handling/Dispatching (in chart's scope)
- //------------------------------------------------------------
-
- 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 });
- dispatch.stateChange(state);
-
- 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;
- });
- d.disabled = false;
-
- state.disabled = data.map(function(d) { return !!d.disabled });
- dispatch.stateChange(state);
- chart.update();
- });
-
-
- dispatch.on('tooltipShow', function(e) {
- if (tooltips) showTooltip(e, that.parentNode);
- });
-
-
- // Update chart from a state object passed to event handler
- dispatch.on('changeState', function(e) {
-
- if (typeof e.disabled !== 'undefined') {
- data.forEach(function(series,i) {
- series.disabled = e.disabled[i];
- });
-
- state.disabled = e.disabled;
- }
-
- chart.update();
- });
-
- //============================================================
-
-
- });
-
- return chart;
- }
-
-
- //============================================================
- // Event Handling/Dispatching (out of chart's scope)
- //------------------------------------------------------------
-
- lines.dispatch.on('elementMouseover.tooltip', function(e) {
- e.pos = [e.pos[0] + margin.left, e.pos[1] + margin.top];
- dispatch.tooltipShow(e);
- });
-
- lines.dispatch.on('elementMouseout.tooltip', function(e) {
- dispatch.tooltipHide(e);
- });
-
- bars.dispatch.on('elementMouseover.tooltip', function(e) {
- e.pos = [e.pos[0] + margin.left, e.pos[1] + margin.top];
- dispatch.tooltipShow(e);
- });
-
- bars.dispatch.on('elementMouseout.tooltip', function(e) {
- dispatch.tooltipHide(e);
- });
-
- dispatch.on('tooltipHide', function() {
- if (tooltips) nv.tooltip.cleanup();
- });
-
- //============================================================
-
-
- //============================================================
- // Expose Public Variables
- //------------------------------------------------------------
-
- // expose chart's sub-components
- chart.dispatch = dispatch;
- chart.legend = legend;
- chart.lines = lines;
- chart.bars = bars;
- chart.xAxis = xAxis;
- chart.y1Axis = y1Axis;
- chart.y2Axis = y2Axis;
-
- d3.rebind(chart, lines, 'defined', 'size', 'clipVoronoi',
'interpolate');
- //TODO: consider rebinding x, y and some other stuff, and simply do soemthign lile
bars.x(lines.x()), etc.
- //d3.rebind(chart, lines, 'x', 'y', 'size', 'xDomain',
'yDomain', 'forceX', 'forceY', 'interactive',
'clipEdge', 'clipVoronoi', 'id');
-
- chart.x = function(_) {
- if (!arguments.length) return getX;
- getX = _;
- lines.x(_);
- bars.x(_);
- return chart;
- };
-
- chart.y = function(_) {
- if (!arguments.length) return getY;
- getY = _;
- lines.y(_);
- bars.y(_);
- 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.color = function(_) {
- if (!arguments.length) return color;
- color = nv.utils.getColor(_);
- legend.color(color);
- return chart;
- };
-
- chart.showLegend = function(_) {
- if (!arguments.length) return showLegend;
- showLegend = _;
- return chart;
- };
-
- chart.tooltips = function(_) {
- if (!arguments.length) return tooltips;
- tooltips = _;
- return chart;
- };
-
- chart.tooltipContent = function(_) {
- if (!arguments.length) return tooltip;
- tooltip = _;
- return chart;
- };
-
- chart.state = function(_) {
- if (!arguments.length) return state;
- state = _;
- return chart;
- };
-
- chart.defaultState = function(_) {
- if (!arguments.length) return defaultState;
- defaultState = _;
- return chart;
- };
-
- chart.noData = function(_) {
- if (!arguments.length) return noData;
- noData = _;
- return chart;
- };
-
- //============================================================
-
-
- return chart;
-}
-
-nv.models.lineWithFocusChart = function() {
-
- //============================================================
- // Public Variables with Default Settings
- //------------------------------------------------------------
-
- var lines = nv.models.line()
- , lines2 = nv.models.line()
- , xAxis = nv.models.axis()
- , yAxis = nv.models.axis()
- , x2Axis = nv.models.axis()
- , y2Axis = nv.models.axis()
- , legend = nv.models.legend()
- , brush = d3.svg.brush()
- ;
-
- var margin = {top: 30, right: 30, bottom: 30, left: 60}
- , margin2 = {top: 0, right: 30, bottom: 20, left: 60}
- , color = nv.utils.defaultColor()
- , width = null
- , height = null
- , height2 = 100
- , x
- , y
- , x2
- , y2
- , showLegend = true
- , brushExtent = null
- , tooltips = true
- , tooltip = function(key, x, y, e, graph) {
- return '<h3>' + key + '</h3>' +
- '<p>' + y + ' at ' + x + '</p>'
- }
- , noData = "No Data Available."
- , dispatch = d3.dispatch('tooltipShow', 'tooltipHide',
'brush')
- ;
-
- lines
- .clipEdge(true)
- ;
- lines2
- .interactive(false)
- ;
- xAxis
- .orient('bottom')
- .tickPadding(5)
- ;
- yAxis
- .orient('left')
- ;
- x2Axis
- .orient('bottom')
- .tickPadding(5)
- ;
- y2Axis
- .orient('left')
- ;
- //============================================================
-
-
- //============================================================
- // Private Variables
- //------------------------------------------------------------
-
- var showTooltip = function(e, offsetElement) {
- var left = e.pos[0] + ( offsetElement.offsetLeft || 0 ),
- top = e.pos[1] + ( offsetElement.offsetTop || 0),
- x = xAxis.tickFormat()(lines.x()(e.point, e.pointIndex)),
- y = yAxis.tickFormat()(lines.y()(e.point, e.pointIndex)),
- content = tooltip(e.series.key, x, y, e, chart);
-
- nv.tooltip.show([left, top], content, null, null, offsetElement);
- };
-
- //============================================================
-
-
- function chart(selection) {
- selection.each(function(data) {
- var container = d3.select(this),
- that = this;
-
- var availableWidth = (width || parseInt(container.style('width')) || 960)
- - margin.left - margin.right,
- availableHeight1 = (height || parseInt(container.style('height')) ||
400)
- - margin.top - margin.bottom - height2,
- availableHeight2 = height2 - margin2.top - margin2.bottom;
-
- chart.update = function() { container.transition().call(chart) };
- chart.container = this;
-
-
- //------------------------------------------------------------
- // Display No Data message if there's nothing to show.
-
- if (!data || !data.length || !data.filter(function(d) { return d.values.length
}).length) {
- var noDataText = container.selectAll('.nv-noData').data([noData]);
-
- noDataText.enter().append('text')
- .attr('class', 'nvd3 nv-noData')
- .attr('dy', '-.7em')
- .style('text-anchor', 'middle');
-
- noDataText
- .attr('x', margin.left + availableWidth / 2)
- .attr('y', margin.top + availableHeight1 / 2)
- .text(function(d) { return d });
-
- return chart;
- } else {
- container.selectAll('.nv-noData').remove();
- }
-
- //------------------------------------------------------------
-
-
- //------------------------------------------------------------
- // Setup Scales
-
- x = lines.xScale();
- y = lines.yScale();
- x2 = lines2.xScale();
- y2 = lines2.yScale();
-
- //------------------------------------------------------------
-
-
- //------------------------------------------------------------
- // Setup containers and skeleton of chart
-
- var wrap =
container.selectAll('g.nv-wrap.nv-lineWithFocusChart').data([data]);
- var gEnter = wrap.enter().append('g').attr('class', 'nvd3
nv-wrap nv-lineWithFocusChart').append('g');
- var g = wrap.select('g');
-
- gEnter.append('g').attr('class', 'nv-legendWrap');
-
- var focusEnter = gEnter.append('g').attr('class',
'nv-focus');
- focusEnter.append('g').attr('class', 'nv-x nv-axis');
- focusEnter.append('g').attr('class', 'nv-y nv-axis');
- focusEnter.append('g').attr('class', 'nv-linesWrap');
-
- var contextEnter = gEnter.append('g').attr('class',
'nv-context');
- contextEnter.append('g').attr('class', 'nv-x nv-axis');
- contextEnter.append('g').attr('class', 'nv-y nv-axis');
- contextEnter.append('g').attr('class', 'nv-linesWrap');
- contextEnter.append('g').attr('class',
'nv-brushBackground');
- contextEnter.append('g').attr('class', 'nv-x nv-brush');
-
- //------------------------------------------------------------
-
-
- //------------------------------------------------------------
- // Legend
-
- if (showLegend) {
- legend.width(availableWidth);
-
- g.select('.nv-legendWrap')
- .datum(data)
- .call(legend);
-
- if ( margin.top != legend.height()) {
- margin.top = legend.height();
- availableHeight1 = (height || parseInt(container.style('height')) ||
400)
- - margin.top - margin.bottom - height2;
- }
-
- g.select('.nv-legendWrap')
- .attr('transform', 'translate(0,' + (-margin.top)
+')')
- }
-
- //------------------------------------------------------------
-
-
- wrap.attr('transform', 'translate(' + margin.left + ',' +
margin.top + ')');
-
-
- //------------------------------------------------------------
- // Main Chart Component(s)
-
- lines
- .width(availableWidth)
- .height(availableHeight1)
- .color(
- data
- .map(function(d,i) {
- return d.color || color(d, i);
- })
- .filter(function(d,i) {
- return !data[i].disabled;
- })
- );
-
- lines2
- .defined(lines.defined())
- .width(availableWidth)
- .height(availableHeight2)
- .color(
- data
- .map(function(d,i) {
- return d.color || color(d, i);
- })
- .filter(function(d,i) {
- return !data[i].disabled;
- })
- );
-
- g.select('.nv-context')
- .attr('transform', 'translate(0,' + ( availableHeight1 +
margin.bottom + margin2.top) + ')')
-
- var contextLinesWrap = g.select('.nv-context .nv-linesWrap')
- .datum(data.filter(function(d) { return !d.disabled }))
-
- d3.transition(contextLinesWrap).call(lines2);
-
- //------------------------------------------------------------
-
-
- /*
- var focusLinesWrap = g.select('.nv-focus .nv-linesWrap')
- .datum(data.filter(function(d) { return !d.disabled }))
-
- d3.transition(focusLinesWrap).call(lines);
- */
-
-
- //------------------------------------------------------------
- // Setup Main (Focus) Axes
-
- xAxis
- .scale(x)
- .ticks( availableWidth / 100 )
- .tickSize(-availableHeight1, 0);
-
- yAxis
- .scale(y)
- .ticks( availableHeight1 / 36 )
- .tickSize( -availableWidth, 0);
-
- g.select('.nv-focus .nv-x.nv-axis')
- .attr('transform', 'translate(0,' + availableHeight1 +
')');
-
- //------------------------------------------------------------
-
-
- //------------------------------------------------------------
- // Setup Brush
-
- brush
- .x(x2)
- .on('brush', onBrush);
-
- if (brushExtent) brush.extent(brushExtent);
-
- var brushBG = g.select('.nv-brushBackground').selectAll('g')
- .data([brushExtent || brush.extent()])
-
- var brushBGenter = brushBG.enter()
- .append('g');
-
- brushBGenter.append('rect')
- .attr('class', 'left')
- .attr('x', 0)
- .attr('y', 0)
- .attr('height', availableHeight2);
-
- brushBGenter.append('rect')
- .attr('class', 'right')
- .attr('x', 0)
- .attr('y', 0)
- .attr('height', availableHeight2);
-
- gBrush = g.select('.nv-x.nv-brush')
- .call(brush);
- gBrush.selectAll('rect')
- //.attr('y', -5)
- .attr('height', availableHeight2);
- gBrush.selectAll('.resize').append('path').attr('d',
resizePath);
-
- onBrush();
-
- //------------------------------------------------------------
-
-
- //------------------------------------------------------------
- // Setup Secondary (Context) Axes
-
- x2Axis
- .scale(x2)
- .ticks( availableWidth / 100 )
- .tickSize(-availableHeight2, 0);
-
- g.select('.nv-context .nv-x.nv-axis')
- .attr('transform', 'translate(0,' + y2.range()[0] +
')');
- d3.transition(g.select('.nv-context .nv-x.nv-axis'))
- .call(x2Axis);
-
-
- y2Axis
- .scale(y2)
- .ticks( availableHeight2 / 36 )
- .tickSize( -availableWidth, 0);
-
- d3.transition(g.select('.nv-context .nv-y.nv-axis'))
- .call(y2Axis);
-
- g.select('.nv-context .nv-x.nv-axis')
- .attr('transform', 'translate(0,' + y2.range()[0] +
')');
-
- //------------------------------------------------------------
-
-
- //============================================================
- // Event Handling/Dispatching (in chart's scope)
- //------------------------------------------------------------
-
- 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;
- });
- }
-
- container.transition().call(chart);
- });
-
- dispatch.on('tooltipShow', function(e) {
- if (tooltips) showTooltip(e, that.parentNode);
- });
-
- //============================================================
-
-
- //============================================================
- // Functions
- //------------------------------------------------------------
-
- // Taken from crossfilter (
http://square.github.com/crossfilter/)
- function resizePath(d) {
- var e = +(d == 'e'),
- x = e ? 1 : -1,
- y = availableHeight2 / 3;
- return 'M' + (.5 * x) + ',' + y
- + 'A6,6 0 0 ' + e + ' ' + (6.5 * x) + ',' + (y + 6)
- + 'V' + (2 * y - 6)
- + 'A6,6 0 0 ' + e + ' ' + (.5 * x) + ',' + (2 * y)
- + 'Z'
- + 'M' + (2.5 * x) + ',' + (y + 8)
- + 'V' + (2 * y - 8)
- + 'M' + (4.5 * x) + ',' + (y + 8)
- + 'V' + (2 * y - 8);
- }
-
-
- function updateBrushBG() {
- if (!brush.empty()) brush.extent(brushExtent);
- brushBG
- .data([brush.empty() ? x2.domain() : brushExtent])
- .each(function(d,i) {
- var leftWidth = x2(d[0]) - x.range()[0],
- rightWidth = x.range()[1] - x2(d[1]);
- d3.select(this).select('.left')
- .attr('width', leftWidth < 0 ? 0 : leftWidth);
-
- d3.select(this).select('.right')
- .attr('x', x2(d[1]))
- .attr('width', rightWidth < 0 ? 0 : rightWidth);
- });
- }
-
-
- function onBrush() {
- brushExtent = brush.empty() ? null : brush.extent();
- extent = brush.empty() ? x2.domain() : brush.extent();
-
-
- dispatch.brush({extent: extent, brush: brush});
-
-
- updateBrushBG();
-
- // Update Main (Focus)
- var focusLinesWrap = g.select('.nv-focus .nv-linesWrap')
- .datum(
- data
- .filter(function(d) { return !d.disabled })
- .map(function(d,i) {
- return {
- key: d.key,
- values: d.values.filter(function(d,i) {
- return lines.x()(d,i) >= extent[0] && lines.x()(d,i)
<= extent[1];
- })
- }
- })
- );
- d3.transition(focusLinesWrap).call(lines);
-
-
- // Update Main (Focus) Axes
- d3.transition(g.select('.nv-focus .nv-x.nv-axis'))
- .call(xAxis);
- d3.transition(g.select('.nv-focus .nv-y.nv-axis'))
- .call(yAxis);
- }
-
- //============================================================
-
-
- });
-
- return chart;
- }
-
-
- //============================================================
- // Event Handling/Dispatching (out of chart's scope)
- //------------------------------------------------------------
-
- lines.dispatch.on('elementMouseover.tooltip', function(e) {
- e.pos = [e.pos[0] + margin.left, e.pos[1] + margin.top];
- dispatch.tooltipShow(e);
- });
-
- lines.dispatch.on('elementMouseout.tooltip', function(e) {
- dispatch.tooltipHide(e);
- });
-
- dispatch.on('tooltipHide', function() {
- if (tooltips) nv.tooltip.cleanup();
- });
-
- //============================================================
-
-
- //============================================================
- // Expose Public Variables
- //------------------------------------------------------------
-
- // expose chart's sub-components
- chart.dispatch = dispatch;
- chart.legend = legend;
- chart.lines = lines;
- chart.lines2 = lines2;
- chart.xAxis = xAxis;
- chart.yAxis = yAxis;
- chart.x2Axis = x2Axis;
- chart.y2Axis = y2Axis;
-
- d3.rebind(chart, lines, 'defined', 'isArea', 'size',
'xDomain', 'yDomain', 'forceX', 'forceY',
'interactive', 'clipEdge', 'clipVoronoi', 'id');
-
- chart.x = function(_) {
- if (!arguments.length) return lines.x;
- lines.x(_);
- lines2.x(_);
- return chart;
- };
-
- chart.y = function(_) {
- if (!arguments.length) return lines.y;
- lines.y(_);
- lines2.y(_);
- 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.margin2 = function(_) {
- if (!arguments.length) return margin2;
- margin2 = _;
- 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.height2 = function(_) {
- if (!arguments.length) return height2;
- height2 = _;
- return chart;
- };
-
- chart.color = function(_) {
- if (!arguments.length) return color;
- color =nv.utils.getColor(_);
- legend.color(color);
- return chart;
- };
-
- chart.showLegend = function(_) {
- if (!arguments.length) return showLegend;
- showLegend = _;
- return chart;
- };
-
- chart.tooltips = function(_) {
- if (!arguments.length) return tooltips;
- tooltips = _;
- return chart;
- };
-
- chart.tooltipContent = function(_) {
- if (!arguments.length) return tooltip;
- tooltip = _;
- return chart;
- };
-
- chart.interpolate = function(_) {
- if (!arguments.length) return lines.interpolate();
- lines.interpolate(_);
- lines2.interpolate(_);
- return chart;
- };
-
- chart.noData = function(_) {
- if (!arguments.length) return noData;
- noData = _;
- return chart;
- };
-
- // Chart has multiple similar Axes, to prevent code duplication, probably need to link
all axis functions manually like below
- chart.xTickFormat = function(_) {
- if (!arguments.length) return xAxis.tickFormat();
- xAxis.tickFormat(_);
- x2Axis.tickFormat(_);
- return chart;
- };
-
- chart.yTickFormat = function(_) {
- if (!arguments.length) return yAxis.tickFormat();
- yAxis.tickFormat(_);
- y2Axis.tickFormat(_);
- return chart;
- };
-
- //============================================================
-
-
- return chart;
-}
-
-nv.models.linePlusBarWithFocusChart = function() {
-
- //============================================================
- // Public Variables with Default Settings
- //------------------------------------------------------------
-
- var lines = nv.models.line()
- , lines2 = nv.models.line()
- , bars = nv.models.historicalBar()
- , bars2 = nv.models.historicalBar()
- , xAxis = nv.models.axis()
- , x2Axis = nv.models.axis()
- , y1Axis = nv.models.axis()
- , y2Axis = nv.models.axis()
- , y3Axis = nv.models.axis()
- , y4Axis = nv.models.axis()
- , legend = nv.models.legend()
- , brush = d3.svg.brush()
- ;
-
- var margin = {top: 30, right: 30, bottom: 30, left: 60}
- , margin2 = {top: 0, right: 30, bottom: 20, left: 60}
- , width = null
- , height = null
- , height2 = 100
- , getX = function(d) { return d.x }
- , getY = function(d) { return d.y }
- , color = nv.utils.defaultColor()
- , showLegend = true
- , extent
- , brushExtent = null
- , tooltips = true
- , tooltip = function(key, x, y, e, graph) {
- return '<h3>' + key + '</h3>' +
- '<p>' + y + ' at ' + x + '</p>';
- }
- , x
- , x2
- , y1
- , y2
- , y3
- , y4
- , noData = "No Data Available."
- , dispatch = d3.dispatch('tooltipShow', 'tooltipHide',
'brush')
- ;
-
- lines
- .clipEdge(true)
- ;
- lines2
- .interactive(false)
- ;
- xAxis
- .orient('bottom')
- .tickPadding(5)
- ;
- y1Axis
- .orient('left')
- ;
- y2Axis
- .orient('right')
- ;
- x2Axis
- .orient('bottom')
- .tickPadding(5)
- ;
- y3Axis
- .orient('left')
- ;
- y4Axis
- .orient('right')
- ;
-
- //============================================================
-
-
- //============================================================
- // Private Variables
- //------------------------------------------------------------
-
- var showTooltip = function(e, offsetElement) {
- if (extent) {
- e.pointIndex += Math.ceil(extent[0]);
- }
- var left = e.pos[0] + ( offsetElement.offsetLeft || 0 ),
- top = e.pos[1] + ( offsetElement.offsetTop || 0),
- x = xAxis.tickFormat()(lines.x()(e.point, e.pointIndex)),
- y = (e.series.bar ? y1Axis : y2Axis).tickFormat()(lines.y()(e.point,
e.pointIndex)),
- content = tooltip(e.series.key, x, y, e, chart);
-
- nv.tooltip.show([left, top], content, e.value < 0 ? 'n' : 's',
null, offsetElement);
- };
-
- //------------------------------------------------------------
-
-
-
- function chart(selection) {
- selection.each(function(data) {
- var container = d3.select(this),
- that = this;
-
- var availableWidth = (width || parseInt(container.style('width')) || 960)
- - margin.left - margin.right,
- availableHeight1 = (height || parseInt(container.style('height')) ||
400)
- - margin.top - margin.bottom - height2,
- availableHeight2 = height2 - margin2.top - margin2.bottom;
-
- chart.update = function() { container.transition().call(chart); };
- chart.container = this;
-
-
- //------------------------------------------------------------
- // Display No Data message if there's nothing to show.
-
- if (!data || !data.length || !data.filter(function(d) { return d.values.length
}).length) {
- var noDataText = container.selectAll('.nv-noData').data([noData]);
-
- noDataText.enter().append('text')
- .attr('class', 'nvd3 nv-noData')
- .attr('dy', '-.7em')
- .style('text-anchor', 'middle');
-
- noDataText
- .attr('x', margin.left + availableWidth / 2)
- .attr('y', margin.top + availableHeight1 / 2)
- .text(function(d) { return d });
-
- return chart;
- } else {
- container.selectAll('.nv-noData').remove();
- }
-
- //------------------------------------------------------------
-
-
- //------------------------------------------------------------
- // Setup Scales
-
- var dataBars = data.filter(function(d) { return !d.disabled && d.bar });
- var dataLines = data.filter(function(d) { return !d.bar }); // removed the
!d.disabled clause here to fix Issue #240
-
- x = bars.xScale();
- x2 = x2Axis.scale();
- y1 = bars.yScale();
- y2 = lines.yScale();
- y3 = bars2.yScale();
- y4 = lines2.yScale();
-
- var series1 = data
- .filter(function(d) { return !d.disabled && d.bar })
- .map(function(d) {
- return d.values.map(function(d,i) {
- return { x: getX(d,i), y: getY(d,i) }
- })
- });
-
- var series2 = data
- .filter(function(d) { return !d.disabled && !d.bar })
- .map(function(d) {
- return d.values.map(function(d,i) {
- return { x: getX(d,i), y: getY(d,i) }
- })
- });
-
- x .range([0, availableWidth]);
-
- x2 .domain(d3.extent(d3.merge(series1.concat(series2)), function(d) { return d.x }
))
- .range([0, availableWidth]);
-
-
- //------------------------------------------------------------
-
-
- //------------------------------------------------------------
- // Setup containers and skeleton of chart
-
- var wrap = container.selectAll('g.nv-wrap.nv-linePlusBar').data([data]);
- var gEnter = wrap.enter().append('g').attr('class', 'nvd3
nv-wrap nv-linePlusBar').append('g');
- var g = wrap.select('g');
-
- gEnter.append('g').attr('class', 'nv-legendWrap');
-
- var focusEnter = gEnter.append('g').attr('class',
'nv-focus');
- focusEnter.append('g').attr('class', 'nv-x nv-axis');
- focusEnter.append('g').attr('class', 'nv-y1 nv-axis');
- focusEnter.append('g').attr('class', 'nv-y2 nv-axis');
- focusEnter.append('g').attr('class', 'nv-barsWrap');
- focusEnter.append('g').attr('class', 'nv-linesWrap');
-
- var contextEnter = gEnter.append('g').attr('class',
'nv-context');
- contextEnter.append('g').attr('class', 'nv-x nv-axis');
- contextEnter.append('g').attr('class', 'nv-y1 nv-axis');
- contextEnter.append('g').attr('class', 'nv-y2 nv-axis');
- contextEnter.append('g').attr('class', 'nv-barsWrap');
- contextEnter.append('g').attr('class', 'nv-linesWrap');
- contextEnter.append('g').attr('class',
'nv-brushBackground');
- contextEnter.append('g').attr('class', 'nv-x nv-brush');
-
-
- //------------------------------------------------------------
-
-
- //------------------------------------------------------------
- // Legend
-
- if (showLegend) {
- legend.width( availableWidth / 2 );
-
- g.select('.nv-legendWrap')
- .datum(data.map(function(series) {
- series.originalKey = series.originalKey === undefined ? series.key :
series.originalKey;
- series.key = series.originalKey + (series.bar ? ' (left axis)' :
' (right axis)');
- return series;
- }))
- .call(legend);
-
- if ( margin.top != legend.height()) {
- margin.top = legend.height();
- availableHeight1 = (height || parseInt(container.style('height')) ||
400)
- - margin.top - margin.bottom - height2;
- }
-
- g.select('.nv-legendWrap')
- .attr('transform', 'translate(' + ( availableWidth / 2 ) +
',' + (-margin.top) +')');
- }
-
- //------------------------------------------------------------
-
-
- wrap.attr('transform', 'translate(' + margin.left + ',' +
margin.top + ')');
-
-
- //------------------------------------------------------------
- // Context Components
-
- bars2
- .width(availableWidth)
- .height(availableHeight2)
- .color(data.map(function(d,i) {
- return d.color || color(d, i);
- }).filter(function(d,i) { return !data[i].disabled && data[i].bar }));
-
- lines2
- .width(availableWidth)
- .height(availableHeight2)
- .color(data.map(function(d,i) {
- return d.color || color(d, i);
- }).filter(function(d,i) { return !data[i].disabled && !data[i].bar }));
-
- var bars2Wrap = g.select('.nv-context .nv-barsWrap')
- .datum(dataBars.length ? dataBars : [{values:[]}]);
-
- var lines2Wrap = g.select('.nv-context .nv-linesWrap')
- .datum(!dataLines[0].disabled ? dataLines : [{values:[]}]);
-
- g.select('.nv-context')
- .attr('transform', 'translate(0,' + ( availableHeight1 +
margin.bottom + margin2.top) + ')')
-
- d3.transition(bars2Wrap).call(bars2);
- d3.transition(lines2Wrap).call(lines2);
-
- //------------------------------------------------------------
-
-
-
- //------------------------------------------------------------
- // Setup Brush
-
- brush
- .x(x2)
- .on('brush', onBrush);
-
- if (brushExtent) brush.extent(brushExtent);
-
- var brushBG = g.select('.nv-brushBackground').selectAll('g')
- .data([brushExtent || brush.extent()])
-
- var brushBGenter = brushBG.enter()
- .append('g');
-
- brushBGenter.append('rect')
- .attr('class', 'left')
- .attr('x', 0)
- .attr('y', 0)
- .attr('height', availableHeight2);
-
- brushBGenter.append('rect')
- .attr('class', 'right')
- .attr('x', 0)
- .attr('y', 0)
- .attr('height', availableHeight2);
-
- var gBrush = g.select('.nv-x.nv-brush')
- .call(brush);
- gBrush.selectAll('rect')
- //.attr('y', -5)
- .attr('height', availableHeight2);
- gBrush.selectAll('.resize').append('path').attr('d',
resizePath);
-
- //------------------------------------------------------------
-
- //------------------------------------------------------------
- // Setup Secondary (Context) Axes
-
- x2Axis
- .ticks( availableWidth / 100 )
- .tickSize(-availableHeight2, 0);
-
- g.select('.nv-context .nv-x.nv-axis')
- .attr('transform', 'translate(0,' + y3.range()[0] +
')');
- d3.transition(g.select('.nv-context .nv-x.nv-axis'))
- .call(x2Axis);
-
-
- y3Axis
- .scale(y3)
- .ticks( availableHeight2 / 36 )
- .tickSize( -availableWidth, 0);
-
- g.select('.nv-context .nv-y1.nv-axis')
- .style('opacity', dataBars.length ? 1 : 0)
- .attr('transform', 'translate(0,' + x2.range()[0] +
')');
-
- d3.transition(g.select('.nv-context .nv-y1.nv-axis'))
- .call(y3Axis);
-
-
- y4Axis
- .scale(y4)
- .ticks( availableHeight2 / 36 )
- .tickSize(dataBars.length ? 0 : -availableWidth, 0); // Show the y2 rules only if
y1 has none
-
- g.select('.nv-context .nv-y2.nv-axis')
- .style('opacity', dataLines.length ? 1 : 0)
- .attr('transform', 'translate(' + x2.range()[1] +
',0)');
-
- d3.transition(g.select('.nv-context .nv-y2.nv-axis'))
- .call(y4Axis);
-
- //------------------------------------------------------------
-
- //============================================================
- // Event Handling/Dispatching (in chart's scope)
- //------------------------------------------------------------
-
- 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;
- });
- }
-
- chart.update();
- });
-
- dispatch.on('tooltipShow', function(e) {
- if (tooltips) showTooltip(e, that.parentNode);
- });
-
- //============================================================
-
-
- //============================================================
- // Functions
- //------------------------------------------------------------
-
- // Taken from crossfilter (
http://square.github.com/crossfilter/)
- function resizePath(d) {
- var e = +(d == 'e'),
- x = e ? 1 : -1,
- y = availableHeight2 / 3;
- return 'M' + (.5 * x) + ',' + y
- + 'A6,6 0 0 ' + e + ' ' + (6.5 * x) + ',' + (y + 6)
- + 'V' + (2 * y - 6)
- + 'A6,6 0 0 ' + e + ' ' + (.5 * x) + ',' + (2 * y)
- + 'Z'
- + 'M' + (2.5 * x) + ',' + (y + 8)
- + 'V' + (2 * y - 8)
- + 'M' + (4.5 * x) + ',' + (y + 8)
- + 'V' + (2 * y - 8);
- }
-
-
- function updateBrushBG() {
- if (!brush.empty()) brush.extent(brushExtent);
- brushBG
- .data([brush.empty() ? x2.domain() : brushExtent])
- .each(function(d,i) {
- var leftWidth = x2(d[0]) - x2.range()[0],
- rightWidth = x2.range()[1] - x2(d[1]);
- d3.select(this).select('.left')
- .attr('width', leftWidth < 0 ? 0 : leftWidth);
-
- d3.select(this).select('.right')
- .attr('x', x2(d[1]))
- .attr('width', rightWidth < 0 ? 0 : rightWidth);
- });
- }
-
-
- function onBrush() {
- brushExtent = brush.empty() ? null : brush.extent();
- extent = brush.empty() ? x2.domain() : brush.extent();
-
-
- dispatch.brush({extent: extent, brush: brush});
-
- updateBrushBG();
-
-
- //------------------------------------------------------------
- // Prepare Main (Focus) Bars and Lines
-
- bars
- .width(availableWidth)
- .height(availableHeight1)
- .color(data.map(function(d,i) {
- return d.color || color(d, i);
- }).filter(function(d,i) { return !data[i].disabled && data[i].bar }));
-
-
- lines
- .width(availableWidth)
- .height(availableHeight1)
- .color(data.map(function(d,i) {
- return d.color || color(d, i);
- }).filter(function(d,i) { return !data[i].disabled && !data[i].bar }));
-
- var focusBarsWrap = g.select('.nv-focus .nv-barsWrap')
- .datum(!dataBars.length ? [{values:[]}] :
- dataBars
- .map(function(d,i) {
- return {
- key: d.key,
- values: d.values.filter(function(d,i) {
- return bars.x()(d,i) >= extent[0] && bars.x()(d,i) <=
extent[1];
- })
- }
- })
- );
-
- var focusLinesWrap = g.select('.nv-focus .nv-linesWrap')
- .datum(dataLines[0].disabled ? [{values:[]}] :
- dataLines
- .map(function(d,i) {
- return {
- key: d.key,
- values: d.values.filter(function(d,i) {
- return lines.x()(d,i) >= extent[0] && lines.x()(d,i)
<= extent[1];
- })
- }
- })
- );
-
- //------------------------------------------------------------
-
-
- //------------------------------------------------------------
- // Update Main (Focus) X Axis
-
- if (dataBars.length) {
- x = bars.xScale();
- } else {
- x = lines.xScale();
- }
-
- xAxis
- .scale(x)
- .ticks( availableWidth / 100 )
- .tickSize(-availableHeight1, 0);
-
- xAxis.domain([Math.ceil(extent[0]), Math.floor(extent[1])]);
-
- d3.transition(g.select('.nv-x.nv-axis'))
- .call(xAxis);
- //------------------------------------------------------------
-
-
- //------------------------------------------------------------
- // Update Main (Focus) Bars and Lines
-
- d3.transition(focusBarsWrap).call(bars);
- d3.transition(focusLinesWrap).call(lines);
-
- //------------------------------------------------------------
-
-
- //------------------------------------------------------------
- // Setup and Update Main (Focus) Y Axes
-
- g.select('.nv-focus .nv-x.nv-axis')
- .attr('transform', 'translate(0,' + y1.range()[0] +
')');
-
-
- y1Axis
- .scale(y1)
- .ticks( availableHeight1 / 36 )
- .tickSize(-availableWidth, 0);
-
- g.select('.nv-focus .nv-y1.nv-axis')
- .style('opacity', dataBars.length ? 1 : 0);
-
-
- y2Axis
- .scale(y2)
- .ticks( availableHeight1 / 36 )
- .tickSize(dataBars.length ? 0 : -availableWidth, 0); // Show the y2 rules only if
y1 has none
-
- g.select('.nv-focus .nv-y2.nv-axis')
- .style('opacity', dataLines.length ? 1 : 0)
- .attr('transform', 'translate(' + x.range()[1] +
',0)');
-
- d3.transition(g.select('.nv-focus .nv-y1.nv-axis'))
- .call(y1Axis);
- d3.transition(g.select('.nv-focus .nv-y2.nv-axis'))
- .call(y2Axis);
- }
-
- //============================================================
-
- onBrush();
-
- });
-
- return chart;
- }
-
-
- //============================================================
- // Event Handling/Dispatching (out of chart's scope)
- //------------------------------------------------------------
-
- lines.dispatch.on('elementMouseover.tooltip', function(e) {
- e.pos = [e.pos[0] + margin.left, e.pos[1] + margin.top];
- dispatch.tooltipShow(e);
- });
-
- lines.dispatch.on('elementMouseout.tooltip', function(e) {
- dispatch.tooltipHide(e);
- });
-
- bars.dispatch.on('elementMouseover.tooltip', function(e) {
- e.pos = [e.pos[0] + margin.left, e.pos[1] + margin.top];
- dispatch.tooltipShow(e);
- });
-
- bars.dispatch.on('elementMouseout.tooltip', function(e) {
- dispatch.tooltipHide(e);
- });
-
- dispatch.on('tooltipHide', function() {
- if (tooltips) nv.tooltip.cleanup();
- });
-
- //============================================================
-
-
- //============================================================
- // Expose Public Variables
- //------------------------------------------------------------
-
- // expose chart's sub-components
- chart.dispatch = dispatch;
- chart.legend = legend;
- chart.lines = lines;
- chart.lines2 = lines2;
- chart.bars = bars;
- chart.bars2 = bars2;
- chart.xAxis = xAxis;
- chart.x2Axis = x2Axis;
- chart.y1Axis = y1Axis;
- chart.y2Axis = y2Axis;
- chart.y3Axis = y3Axis;
- chart.y4Axis = y4Axis;
-
- d3.rebind(chart, lines, 'defined', 'size', 'clipVoronoi',
'interpolate');
- //TODO: consider rebinding x, y and some other stuff, and simply do soemthign lile
bars.x(lines.x()), etc.
- //d3.rebind(chart, lines, 'x', 'y', 'size', 'xDomain',
'yDomain', 'forceX', 'forceY', 'interactive',
'clipEdge', 'clipVoronoi', 'id');
-
- chart.x = function(_) {
- if (!arguments.length) return getX;
- getX = _;
- lines.x(_);
- bars.x(_);
- return chart;
- };
-
- chart.y = function(_) {
- if (!arguments.length) return getY;
- getY = _;
- lines.y(_);
- bars.y(_);
- 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.color = function(_) {
- if (!arguments.length) return color;
- color = nv.utils.getColor(_);
- legend.color(color);
- return chart;
- };
-
- chart.showLegend = function(_) {
- if (!arguments.length) return showLegend;
- showLegend = _;
- return chart;
- };
-
- chart.tooltips = function(_) {
- if (!arguments.length) return tooltips;
- tooltips = _;
- return chart;
- };
-
- chart.tooltipContent = function(_) {
- if (!arguments.length) return tooltip;
- tooltip = _;
- return chart;
- };
-
- chart.noData = function(_) {
- if (!arguments.length) return noData;
- noData = _;
- return chart;
- };
-
- chart.brushExtent = function(_) {
- if (!arguments.length) return brushExtent;
- brushExtent = _;
- return chart;
- };
-
-
- //============================================================
-
-
- return chart;
-}
-
-nv.models.multiBar = function() {
-
- //============================================================
- // Public Variables with Default Settings
- //------------------------------------------------------------
-
- var margin = {top: 0, right: 0, bottom: 0, left: 0}
- , width = 960
- , height = 500
- , x = d3.scale.ordinal()
- , y = d3.scale.linear()
- , id = Math.floor(Math.random() * 10000) //Create semi-unique ID in case user
doesn't select one
- , getX = function(d) { return d.x }
- , getY = function(d) { return d.y }
- , forceY = [0] // 0 is forced by default.. this makes sense for the majority of bar
graphs... user can always do chart.forceY([]) to remove
- , clipEdge = true
- , stacked = false
- , color = nv.utils.defaultColor()
- , hideable = false
- , barColor = null // adding the ability to set the color for each rather than the
whole group
- , disabled // used in conjunction with barColor to communicate from
multiBarHorizontalChart what series are disabled
- , delay = 1200
- , drawTime = 500
- , xDomain
- , yDomain
- , dispatch = d3.dispatch('chartClick', 'elementClick',
'elementDblClick', 'elementMouseover', 'elementMouseout')
- ;
-
- //============================================================
-
-
- //============================================================
- // Private Variables
- //------------------------------------------------------------
-
- var x0, y0 //used to store previous scales
- ;
-
- //============================================================
-
-
- function chart(selection) {
- selection.each(function(data) {
- var availableWidth = width - margin.left - margin.right,
- availableHeight = height - margin.top - margin.bottom,
- container = d3.select(this);
-
- if(hideable && data.length) hideable = [{
- values: data[0].values.map(function(d) {
- return {
- x: d.x,
- y: 0,
- series: d.series,
- size: 0.01
- };}
- )}];
-
- if (stacked)
- data = d3.layout.stack()
- .offset('zero')
- .values(function(d){ return d.values })
- .y(getY)
- (!data.length && hideable ? hideable : data);
-
-
- //add series index to each data point for reference
- data = data.map(function(series, i) {
- series.values = series.values.map(function(point) {
- point.series = i;
- return point;
- });
- return series;
- });
-
-
- //------------------------------------------------------------
- // HACK for negative value stacking
- if (stacked)
- data[0].values.map(function(d,i) {
- var posBase = 0, negBase = 0;
- data.map(function(d) {
- var f = d.values[i]
- f.size = Math.abs(f.y);
- if (f.y<0) {
- f.y1 = negBase;
- negBase = negBase - f.size;
- } else
- {
- f.y1 = f.size + posBase;
- posBase = posBase + f.size;
- }
- });
- });
-
- //------------------------------------------------------------
- // Setup Scales
-
- // remap and flatten the data for use in calculating the scales' domains
- var seriesData = (xDomain && yDomain) ? [] : // if we know xDomain and
yDomain, no need to calculate
- data.map(function(d) {
- return d.values.map(function(d,i) {
- return { x: getX(d,i), y: getY(d,i), y0: d.y0, y1: d.y1 }
- })
- });
-
- x .domain(d3.merge(seriesData).map(function(d) { return d.x }))
- .rangeBands([0, availableWidth], .1);
-
- //y .domain(yDomain || d3.extent(d3.merge(seriesData).map(function(d) { return
d.y + (stacked ? d.y1 : 0) }).concat(forceY)))
- y .domain(yDomain || d3.extent(d3.merge(seriesData).map(function(d) { return
stacked ? (d.y > 0 ? d.y1 : d.y1 + d.y ) : d.y }).concat(forceY)))
- .range([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
- if (x.domain()[0] === x.domain()[1] || y.domain()[0] === y.domain()[1]) singlePoint
= true;
- 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]);
-
-
- x0 = x0 || x;
- y0 = y0 || y;
-
- //------------------------------------------------------------
-
-
- //------------------------------------------------------------
- // Setup containers and skeleton of chart
-
- var wrap = container.selectAll('g.nv-wrap.nv-multibar').data([data]);
- var wrapEnter = wrap.enter().append('g').attr('class', 'nvd3
nv-wrap nv-multibar');
- var defsEnter = wrapEnter.append('defs');
- var gEnter = wrapEnter.append('g');
- var g = wrap.select('g')
-
- gEnter.append('g').attr('class', 'nv-groups');
-
- wrap.attr('transform', 'translate(' + margin.left + ',' +
margin.top + ')');
-
- //------------------------------------------------------------
-
-
-
- defsEnter.append('clipPath')
- .attr('id', 'nv-edge-clip-' + id)
- .append('rect');
- wrap.select('#nv-edge-clip-' + id + ' rect')
- .attr('width', availableWidth)
- .attr('height', availableHeight);
-
- g .attr('clip-path', clipEdge ? 'url(#nv-edge-clip-' + id +
')' : '');
-
-
-
- var groups = wrap.select('.nv-groups').selectAll('.nv-group')
- .data(function(d) { return d }, function(d) { return d.key });
- groups.enter().append('g')
- .style('stroke-opacity', 1e-6)
- .style('fill-opacity', 1e-6);
-
-
- groups.exit()
- .selectAll('rect.nv-bar')
- .transition()
- .delay(function(d,i) { return i * delay/ data[0].values.length })
- .attr('y', function(d) { return stacked ? y0(d.y0) : y0(0) })
- .attr('height', 0)
- .remove();
- groups
- .attr('class', function(d,i) { return 'nv-group nv-series-' + i
})
- .classed('hover', function(d) { return d.hover })
- .style('fill', function(d,i){ return color(d, i) })
- .style('stroke', function(d,i){ return color(d, i) });
- d3.transition(groups)
- .style('stroke-opacity', 1)
- .style('fill-opacity', .75);
-
-
- var bars = groups.selectAll('rect.nv-bar')
- .data(function(d) { return (hideable && !data.length) ? hideable.values
: d.values });
-
- bars.exit().remove();
-
-
- var barsEnter = bars.enter().append('rect')
- .attr('class', function(d,i) { return getY(d,i) < 0 ? 'nv-bar
negative' : 'nv-bar positive'})
- .attr('x', function(d,i,j) {
- return stacked ? 0 : (j * x.rangeBand() / data.length )
- })
- .attr('y', function(d) { return y0(stacked ? d.y0 : 0) })
- .attr('height', 0)
- .attr('width', x.rangeBand() / (stacked ? 1 : data.length) );
- bars
- .style('fill', function(d,i,j){ return color(d, j, i); })
- .style('stroke', function(d,i,j){ return color(d, j, i); })
- .on('mouseover', function(d,i) { //TODO: figure out why j works above,
but not here
- d3.select(this).classed('hover', true);
- dispatch.elementMouseover({
- value: getY(d,i),
- point: d,
- series: data[d.series],
- pos: [x(getX(d,i)) + (x.rangeBand() * (stacked ? data.length / 2 : d.series
+ .5) / data.length), y(getY(d,i) + (stacked ? d.y0 : 0))], // TODO: Figure out why the
value appears to be shifted
- pointIndex: i,
- seriesIndex: d.series,
- e: d3.event
- });
- })
- .on('mouseout', function(d,i) {
- d3.select(this).classed('hover', false);
- dispatch.elementMouseout({
- value: getY(d,i),
- point: d,
- series: data[d.series],
- pointIndex: i,
- seriesIndex: d.series,
- e: d3.event
- });
- })
- .on('click', function(d,i) {
- dispatch.elementClick({
- value: getY(d,i),
- point: d,
- series: data[d.series],
- pos: [x(getX(d,i)) + (x.rangeBand() * (stacked ? data.length / 2 : d.series
+ .5) / data.length), y(getY(d,i) + (stacked ? d.y0 : 0))], // TODO: Figure out why the
value appears to be shifted
- pointIndex: i,
- seriesIndex: d.series,
- e: d3.event
- });
- d3.event.stopPropagation();
- })
- .on('dblclick', function(d,i) {
- dispatch.elementDblClick({
- value: getY(d,i),
- point: d,
- series: data[d.series],
- pos: [x(getX(d,i)) + (x.rangeBand() * (stacked ? data.length / 2 : d.series
+ .5) / data.length), y(getY(d,i) + (stacked ? d.y0 : 0))], // TODO: Figure out why the
value appears to be shifted
- pointIndex: i,
- seriesIndex: d.series,
- e: d3.event
- });
- d3.event.stopPropagation();
- });
- bars
- .attr('class', function(d,i) { return getY(d,i) < 0 ? 'nv-bar
negative' : 'nv-bar positive'})
- .attr('transform', function(d,i) { return 'translate(' +
x(getX(d,i)) + ',0)'; })
-
- if (barColor) {
- if (!disabled) disabled = data.map(function() { return true });
- bars
- //.style('fill', barColor)
- //.style('stroke', barColor)
- //.style('fill', function(d,i,j) { return
d3.rgb(barColor(d,i)).darker(j).toString(); })
- //.style('stroke', function(d,i,j) { return
d3.rgb(barColor(d,i)).darker(j).toString(); })
- .style('fill', function(d,i,j) { return d3.rgb(barColor(d,i)).darker(
disabled.map(function(d,i) { return i }).filter(function(d,i){ return !disabled[i] })[j]
).toString(); })
- .style('stroke', function(d,i,j) { return d3.rgb(barColor(d,i)).darker(
disabled.map(function(d,i) { return i }).filter(function(d,i){ return !disabled[i] })[j]
).toString(); });
- }
-
-
- if (stacked)
- bars.transition()
-
- .delay(function(d,i) { return i * delay / data[0].values.length })
- .attr('y', function(d,i) {
-
- return y((stacked ? d.y1 : 0));
- })
- .attr('height', function(d,i) {
- return Math.max(Math.abs(y(d.y + (stacked ? d.y0 : 0)) - y((stacked ? d.y0
: 0))),1);
- })
- .each('end', function() {
- d3.select(this).transition().duration(drawTime)
- .attr('x', function(d,i) {
- return stacked ? 0 : (d.series * x.rangeBand() / data.length )
- })
- .attr('width', x.rangeBand() / (stacked ? 1 : data.length) );
- })
- else
- d3.transition(bars).duration(drawTime)
- .delay(function(d,i) { return i * delay/ data[0].values.length })
- .attr('x', function(d,i) {
- return d.series * x.rangeBand() / data.length
- })
- .attr('width', x.rangeBand() / data.length)
- .each('end', function() {
- d3.select(this).transition().duration(drawTime)
- .attr('y', function(d,i) {
- return getY(d,i) < 0 ?
- y(0) :
- y(0) - y(getY(d,i)) < 1 ?
- y(0) - 1 :
- y(getY(d,i)) || 0;
- })
- .attr('height', function(d,i) {
- return Math.max(Math.abs(y(getY(d,i)) - y(0)),1) || 0;
- });
- })
-
-
- //store old scales for use in transitions on update
- x0 = x.copy();
- y0 = y.copy();
-
- });
-
- return chart;
- }
-
-
- //============================================================
- // Expose Public Variables
- //------------------------------------------------------------
-
- chart.dispatch = dispatch;
-
- 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.forceY = function(_) {
- if (!arguments.length) return forceY;
- forceY = _;
- return chart;
- };
-
- chart.stacked = function(_) {
- if (!arguments.length) return stacked;
- stacked = _;
- 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.barColor = function(_) {
- if (!arguments.length) return barColor;
- barColor = nv.utils.getColor(_);
- return chart;
- };
-
- chart.disabled = function(_) {
- if (!arguments.length) return disabled;
- disabled = _;
- return chart;
- };
-
- chart.id = function(_) {
- if (!arguments.length) return id;
- id = _;
- return chart;
- };
-
- chart.hideable = function(_) {
- if (!arguments.length) return hideable;
- hideable = _;
- return chart;
- };
-
- chart.delay = function(_) {
- if (!arguments.length) return delay;
- delay = _;
- return chart;
- };
-
- chart.drawTime = function(_) {
- if (!arguments.length) return drawTime;
- drawTime = _;
- return chart;
- };
-
- //============================================================
-
-
- return chart;
-}
-
-nv.models.multiBarChart = function() {
-
- //============================================================
- // Public Variables with Default Settings
- //------------------------------------------------------------
-
- var multibar = nv.models.multiBar()
- , xAxis = nv.models.axis()
- , yAxis = nv.models.axis()
- , legend = nv.models.legend()
- , controls = nv.models.legend()
- ;
-
- var margin = {top: 30, right: 20, bottom: 50, left: 60}
- , width = null
- , height = null
- , color = nv.utils.defaultColor()
- , showControls = true
- , showLegend = true
- , reduceXTicks = true // if false a tick will show for every data point
- , staggerLabels = false
- , rotateLabels = 0
- , tooltips = true
- , tooltip = function(key, x, y, e, graph) {
- return '<h3>' + key + '</h3>' +
- '<p>' + y + ' on ' + x + '</p>'
- }
- , x //can be accessed via chart.xScale()
- , y //can be accessed via chart.yScale()
- , state = { stacked: false }
- , defaultState = null
- , noData = "No Data Available."
- , dispatch = d3.dispatch('tooltipShow', 'tooltipHide',
'stateChange', 'changeState')
- , controlWidth = function() { return showControls ? 180 : 0 }
- ;
-
- multibar
- .stacked(false)
- ;
- xAxis
- .orient('bottom')
- .tickPadding(7)
- .highlightZero(true)
- .showMaxMin(false)
- .tickFormat(function(d) { return d })
- ;
- yAxis
- .orient('left')
- .tickFormat(d3.format(',.1f'))
- ;
-
- //============================================================
-
-
- //============================================================
- // Private Variables
- //------------------------------------------------------------
-
- var showTooltip = function(e, offsetElement) {
- var left = e.pos[0] + ( offsetElement.offsetLeft || 0 ),
- top = e.pos[1] + ( offsetElement.offsetTop || 0),
- x = xAxis.tickFormat()(multibar.x()(e.point, e.pointIndex)),
- y = yAxis.tickFormat()(multibar.y()(e.point, e.pointIndex)),
- content = tooltip(e.series.key, x, y, e, chart);
-
- nv.tooltip.show([left, top], content, e.value < 0 ? 'n' : 's',
null, offsetElement);
- };
-
- //============================================================
-
-
- function chart(selection) {
- selection.each(function(data) {
- var container = d3.select(this),
- that = this;
-
- var availableWidth = (width || parseInt(container.style('width')) || 960)
- - margin.left - margin.right,
- availableHeight = (height || parseInt(container.style('height')) ||
400)
- - margin.top - margin.bottom;
-
- chart.update = function() { container.transition().call(chart) };
- chart.container = this;
-
- //set state.disabled
- state.disabled = data.map(function(d) { return !!d.disabled });
-
- if (!defaultState) {
- var key;
- defaultState = {};
- for (key in state) {
- if (state[key] instanceof Array)
- defaultState[key] = state[key].slice(0);
- else
- defaultState[key] = state[key];
- }
- }
- //------------------------------------------------------------
- // Display noData message if there's nothing to show.
-
- if (!data || !data.length || !data.filter(function(d) { return d.values.length
}).length) {
- var noDataText = container.selectAll('.nv-noData').data([noData]);
-
- noDataText.enter().append('text')
- .attr('class', 'nvd3 nv-noData')
- .attr('dy', '-.7em')
- .style('text-anchor', 'middle');
-
- noDataText
- .attr('x', margin.left + availableWidth / 2)
- .attr('y', margin.top + availableHeight / 2)
- .text(function(d) { return d });
-
- return chart;
- } else {
- container.selectAll('.nv-noData').remove();
- }
-
- //------------------------------------------------------------
-
-
- //------------------------------------------------------------
- // Setup Scales
-
- x = multibar.xScale();
- y = multibar.yScale();
-
- //------------------------------------------------------------
-
-
- //------------------------------------------------------------
- // Setup containers and skeleton of chart
-
- var wrap =
container.selectAll('g.nv-wrap.nv-multiBarWithLegend').data([data]);
- var gEnter = wrap.enter().append('g').attr('class', 'nvd3
nv-wrap nv-multiBarWithLegend').append('g');
- var g = wrap.select('g');
-
- gEnter.append('g').attr('class', 'nv-x nv-axis');
- gEnter.append('g').attr('class', 'nv-y nv-axis');
- gEnter.append('g').attr('class', 'nv-barsWrap');
- gEnter.append('g').attr('class', 'nv-legendWrap');
- gEnter.append('g').attr('class', 'nv-controlsWrap');
-
- //------------------------------------------------------------
-
-
- //------------------------------------------------------------
- // Legend
-
- if (showLegend) {
- legend.width(availableWidth - controlWidth());
-
- if (multibar.barColor())
- data.forEach(function(series,i) {
- series.color = d3.rgb('#ccc').darker(i * 1.5).toString();
- })
-
- g.select('.nv-legendWrap')
- .datum(data)
- .call(legend);
-
- if ( margin.top != legend.height()) {
- margin.top = legend.height();
- availableHeight = (height || parseInt(container.style('height')) ||
400)
- - margin.top - margin.bottom;
- }
-
- g.select('.nv-legendWrap')
- .attr('transform', 'translate(' + controlWidth() +
',' + (-margin.top) +')');
- }
-
- //------------------------------------------------------------
-
-
- //------------------------------------------------------------
- // Controls
-
- if (showControls) {
- var controlsData = [
- { key: 'Grouped', disabled: multibar.stacked() },
- { key: 'Stacked', disabled: !multibar.stacked() }
- ];
-
- controls.width(controlWidth()).color(['#444', '#444',
'#444']);
- g.select('.nv-controlsWrap')
- .datum(controlsData)
- .attr('transform', 'translate(0,' + (-margin.top)
+')')
- .call(controls);
- }
-
- //------------------------------------------------------------
-
-
- wrap.attr('transform', 'translate(' + margin.left + ',' +
margin.top + ')');
-
-
- //------------------------------------------------------------
- // Main Chart Component(s)
-
- multibar
- .disabled(data.map(function(series) { return series.disabled }))
- .width(availableWidth)
- .height(availableHeight)
- .color(data.map(function(d,i) {
- return d.color || color(d, i);
- }).filter(function(d,i) { return !data[i].disabled }))
-
-
- var barsWrap = g.select('.nv-barsWrap')
- .datum(data.filter(function(d) { return !d.disabled }))
-
- d3.transition(barsWrap).call(multibar);
-
- //------------------------------------------------------------
-
-
- //------------------------------------------------------------
- // Setup Axes
-
- xAxis
- .scale(x)
- .ticks( availableWidth / 100 )
- .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);
-
- var xTicks = g.select('.nv-x.nv-axis > g').selectAll('g');
-
- xTicks
- .selectAll('line, text')
- .style('opacity', 1)
-
- if (staggerLabels) {
- var getTranslate = function(x,y) {
- return "translate(" + x + "," + y + ")";
- };
-
- var staggerUp = 5, staggerDown = 17; //pixels to stagger by
- // Issue #140
- xTicks
- .selectAll("text")
- .attr('transform', function(d,i,j) {
- return getTranslate(0, (j % 2 == 0 ? staggerUp : staggerDown));
- });
-
- var totalInBetweenTicks = d3.selectAll(".nv-x.nv-axis .nv-wrap g g
text")[0].length;
- g.selectAll(".nv-x.nv-axis .nv-axisMaxMin text")
- .attr("transform", function(d,i) {
- return getTranslate(0, (i === 0 || totalInBetweenTicks % 2 !== 0) ?
staggerDown : staggerUp);
- });
- }
-
-
- if (reduceXTicks)
- xTicks
- .filter(function(d,i) {
- return i % Math.ceil(data[0].values.length / (availableWidth / 100)) !==
0;
- })
- .selectAll('text, line')
- .style('opacity', 0);
-
- if(rotateLabels)
- xTicks
- .selectAll('text')
- .attr('transform', 'rotate(' + rotateLabels + ' 0,0)')
- .attr('text-anchor', rotateLabels > 0 ? 'start' :
'end');
-
- g.select('.nv-x.nv-axis').selectAll('g.nv-axisMaxMin text')
- .style('opacity', 1);
-
- yAxis
- .scale(y)
- .ticks( availableHeight / 36 )
- .tickSize( -availableWidth, 0);
-
- d3.transition(g.select('.nv-y.nv-axis'))
- .call(yAxis);
-
- //------------------------------------------------------------
-
-
-
- //============================================================
- // Event Handling/Dispatching (in chart's scope)
- //------------------------------------------------------------
-
- 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 });
- dispatch.stateChange(state);
-
- 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;
- });
- d.disabled = false;
-
- state.disabled = data.map(function(d) { return !!d.disabled });
- dispatch.stateChange(state);
- chart.update();
- });
-
-
- controls.dispatch.on('legendClick', function(d,i) {
- if (!d.disabled) return;
- controlsData = controlsData.map(function(s) {
- s.disabled = true;
- return s;
- });
- d.disabled = false;
-
- switch (d.key) {
- case 'Grouped':
- multibar.stacked(false);
- break;
- case 'Stacked':
- multibar.stacked(true);
- break;
- }
-
- state.stacked = multibar.stacked();
- dispatch.stateChange(state);
-
- chart.update();
- });
-
- dispatch.on('tooltipShow', function(e) {
- if (tooltips) showTooltip(e, that.parentNode)
- });
-
- // Update chart from a state object passed to event handler
- dispatch.on('changeState', function(e) {
-
- if (typeof e.disabled !== 'undefined') {
- data.forEach(function(series,i) {
- series.disabled = e.disabled[i];
- });
-
- state.disabled = e.disabled;
- }
-
- if (typeof e.stacked !== 'undefined') {
- multibar.stacked(e.stacked);
- state.stacked = e.stacked;
- }
-
- chart.update();
- });
-
- //============================================================
-
-
- });
-
- return chart;
- }
-
-
- //============================================================
- // Event Handling/Dispatching (out of chart's scope)
- //------------------------------------------------------------
-
- multibar.dispatch.on('elementMouseover.tooltip', function(e) {
- e.pos = [e.pos[0] + margin.left, e.pos[1] + margin.top];
- dispatch.tooltipShow(e);
- });
-
- multibar.dispatch.on('elementMouseout.tooltip', function(e) {
- dispatch.tooltipHide(e);
- });
- dispatch.on('tooltipHide', function() {
- if (tooltips) nv.tooltip.cleanup();
- });
-
- //============================================================
-
-
- //============================================================
- // Expose Public Variables
- //------------------------------------------------------------
-
- // expose chart's sub-components
- chart.dispatch = dispatch;
- chart.multibar = multibar;
- chart.legend = legend;
- chart.xAxis = xAxis;
- chart.yAxis = yAxis;
-
- d3.rebind(chart, multibar, 'x', 'y', 'xDomain',
'yDomain', 'forceX', 'forceY', 'clipEdge', 'id',
'stacked', 'delay', 'barColor');
-
- 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.color = function(_) {
- if (!arguments.length) return color;
- color = nv.utils.getColor(_);
- legend.color(color);
- return chart;
- };
-
- chart.showControls = function(_) {
- if (!arguments.length) return showControls;
- showControls = _;
- return chart;
- };
-
- chart.showLegend = function(_) {
- if (!arguments.length) return showLegend;
- showLegend = _;
- return chart;
- };
-
- chart.reduceXTicks= function(_) {
- if (!arguments.length) return reduceXTicks;
- reduceXTicks = _;
- return chart;
- };
-
- chart.rotateLabels = function(_) {
- if (!arguments.length) return rotateLabels;
- rotateLabels = _;
- return chart;
- }
-
- chart.staggerLabels = function(_) {
- if (!arguments.length) return staggerLabels;
- staggerLabels = _;
- return chart;
- };
-
- chart.tooltip = function(_) {
- if (!arguments.length) return tooltip;
- tooltip = _;
- return chart;
- };
-
- chart.tooltips = function(_) {
- if (!arguments.length) return tooltips;
- tooltips = _;
- return chart;
- };
-
- chart.tooltipContent = function(_) {
- if (!arguments.length) return tooltip;
- tooltip = _;
- return chart;
- };
-
- chart.state = function(_) {
- if (!arguments.length) return state;
- state = _;
- return chart;
- };
-
- chart.defaultState = function(_) {
- if (!arguments.length) return defaultState;
- defaultState = _;
- return chart;
- };
-
- chart.noData = function(_) {
- if (!arguments.length) return noData;
- noData = _;
- return chart;
- };
-
- //============================================================
-
-
- return chart;
-}
-
-nv.models.multiBarHorizontal = function() {
-
- //============================================================
- // Public Variables with Default Settings
- //------------------------------------------------------------
-
- var margin = {top: 0, right: 0, bottom: 0, left: 0}
- , width = 960
- , height = 500
- , id = Math.floor(Math.random() * 10000) //Create semi-unique ID in case user
doesn't select one
- , x = d3.scale.ordinal()
- , y = d3.scale.linear()
- , getX = function(d) { return d.x }
- , getY = function(d) { return d.y }
- , forceY = [0] // 0 is forced by default.. this makes sense for the majority of bar
graphs... user can always do chart.forceY([]) to remove
- , color = nv.utils.defaultColor()
- , barColor = null // adding the ability to set the color for each rather than the
whole group
- , disabled // used in conjunction with barColor to communicate from
multiBarHorizontalChart what series are disabled
- , stacked = false
- , showValues = false
- , valuePadding = 60
- , valueFormat = d3.format(',.2f')
- , delay = 1200
- , xDomain
- , yDomain
- , dispatch = d3.dispatch('chartClick', 'elementClick',
'elementDblClick', 'elementMouseover', 'elementMouseout')
- ;
-
- //============================================================
-
-
- //============================================================
- // Private Variables
- //------------------------------------------------------------
-
- var x0, y0 //used to store previous scales
- ;
-
- //============================================================
-
-
- function chart(selection) {
- selection.each(function(data) {
- var availableWidth = width - margin.left - margin.right,
- availableHeight = height - margin.top - margin.bottom,
- container = d3.select(this);
-
-
- if (stacked)
- data = d3.layout.stack()
- .offset('zero')
- .values(function(d){ return d.values })
- .y(getY)
- (data);
-
-
- //add series index to each data point for reference
- data = data.map(function(series, i) {
- series.values = series.values.map(function(point) {
- point.series = i;
- return point;
- });
- return series;
- });
-
-
-
- //------------------------------------------------------------
- // HACK for negative value stacking
- if (stacked)
- data[0].values.map(function(d,i) {
- var posBase = 0, negBase = 0;
- data.map(function(d) {
- var f = d.values[i]
- f.size = Math.abs(f.y);
- if (f.y<0) {
- f.y1 = negBase - f.size;
- negBase = negBase - f.size;
- } else
- {
- f.y1 = posBase;
- posBase = posBase + f.size;
- }
- });
- });
-
-
-
- //------------------------------------------------------------
- // Setup Scales
-
- // remap and flatten the data for use in calculating the scales' domains
- var seriesData = (xDomain && yDomain) ? [] : // if we know xDomain and
yDomain, no need to calculate
- data.map(function(d) {
- return d.values.map(function(d,i) {
- return { x: getX(d,i), y: getY(d,i), y0: d.y0, y1: d.y1 }
- })
- });
-
- x .domain(xDomain || d3.merge(seriesData).map(function(d) { return d.x }))
- .rangeBands([0, availableHeight], .1);
-
- //y .domain(yDomain || d3.extent(d3.merge(seriesData).map(function(d) { return
d.y + (stacked ? d.y0 : 0) }).concat(forceY)))
- y .domain(yDomain || d3.extent(d3.merge(seriesData).map(function(d) { return
stacked ? (d.y > 0 ? d.y1 + d.y : d.y1 ) : d.y }).concat(forceY)))
-
- if (showValues && !stacked)
- y.range([(y.domain()[0] < 0 ? valuePadding : 0), availableWidth -
(y.domain()[1] > 0 ? valuePadding : 0) ]);
- else
- y.range([0, availableWidth]);
-
- x0 = x0 || x;
- y0 = y0 || d3.scale.linear().domain(y.domain()).range([y(0),y(0)]);
-
- //------------------------------------------------------------
-
-
- //------------------------------------------------------------
- // Setup containers and skeleton of chart
-
- var wrap =
d3.select(this).selectAll('g.nv-wrap.nv-multibarHorizontal').data([data]);
- var wrapEnter = wrap.enter().append('g').attr('class', 'nvd3
nv-wrap nv-multibarHorizontal');
- var defsEnter = wrapEnter.append('defs');
- var gEnter = wrapEnter.append('g');
- var g = wrap.select('g');
-
- gEnter.append('g').attr('class', 'nv-groups');
-
- wrap.attr('transform', 'translate(' + margin.left + ',' +
margin.top + ')');
-
- //------------------------------------------------------------
-
-
-
- var groups = wrap.select('.nv-groups').selectAll('.nv-group')
- .data(function(d) { return d }, function(d) { return d.key });
- groups.enter().append('g')
- .style('stroke-opacity', 1e-6)
- .style('fill-opacity', 1e-6);
- d3.transition(groups.exit())
- .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 })
- .style('fill', function(d,i){ return color(d, i) })
- .style('stroke', function(d,i){ return color(d, i) });
- d3.transition(groups)
- .style('stroke-opacity', 1)
- .style('fill-opacity', .75);
-
-
- var bars = groups.selectAll('g.nv-bar')
- .data(function(d) { return d.values });
-
- bars.exit().remove();
-
-
- var barsEnter = bars.enter().append('g')
- .attr('transform', function(d,i,j) {
- return 'translate(' + y0(stacked ? d.y0 : 0) + ',' +
(stacked ? 0 : (j * x.rangeBand() / data.length ) + x(getX(d,i))) + ')'
- });
-
- barsEnter.append('rect')
- .attr('width', 0)
- .attr('height', x.rangeBand() / (stacked ? 1 : data.length) )
-
- bars
- .on('mouseover', function(d,i) { //TODO: figure out why j works above,
but not here
- d3.select(this).classed('hover', true);
- dispatch.elementMouseover({
- value: getY(d,i),
- point: d,
- series: data[d.series],
- pos: [ y(getY(d,i) + (stacked ? d.y0 : 0)), x(getX(d,i)) + (x.rangeBand() *
(stacked ? data.length / 2 : d.series + .5) / data.length) ],
- pointIndex: i,
- seriesIndex: d.series,
- e: d3.event
- });
- })
- .on('mouseout', function(d,i) {
- d3.select(this).classed('hover', false);
- dispatch.elementMouseout({
- value: getY(d,i),
- point: d,
- series: data[d.series],
- pointIndex: i,
- seriesIndex: d.series,
- e: d3.event
- });
- })
- .on('click', function(d,i) {
- dispatch.elementClick({
- value: getY(d,i),
- point: d,
- series: data[d.series],
- pos: [x(getX(d,i)) + (x.rangeBand() * (stacked ? data.length / 2 : d.series
+ .5) / data.length), y(getY(d,i) + (stacked ? d.y0 : 0))], // TODO: Figure out why the
value appears to be shifted
- pointIndex: i,
- seriesIndex: d.series,
- e: d3.event
- });
- d3.event.stopPropagation();
- })
- .on('dblclick', function(d,i) {
- dispatch.elementDblClick({
- value: getY(d,i),
- point: d,
- series: data[d.series],
- pos: [x(getX(d,i)) + (x.rangeBand() * (stacked ? data.length / 2 : d.series
+ .5) / data.length), y(getY(d,i) + (stacked ? d.y0 : 0))], // TODO: Figure out why the
value appears to be shifted
- pointIndex: i,
- seriesIndex: d.series,
- e: d3.event
- });
- d3.event.stopPropagation();
- });
-
-
- barsEnter.append('text');
-
- if (showValues && !stacked) {
- bars.select('text')
- .attr('text-anchor', function(d,i) { return getY(d,i) < 0 ?
'end' : 'start' })
- .attr('y', x.rangeBand() / (data.length * 2))
- .attr('dy', '.32em')
- .text(function(d,i) { return valueFormat(getY(d,i)) })
- d3.transition(bars)
- //.delay(function(d,i) { return i * delay / data[0].values.length })
- .select('text')
- .attr('x', function(d,i) { return getY(d,i) < 0 ? -4 :
y(getY(d,i)) - y(0) + 4 })
- } else {
- //bars.selectAll('text').remove();
- bars.selectAll('text').text('');
- }
-
- bars
- .attr('class', function(d,i) { return getY(d,i) < 0 ? 'nv-bar
negative' : 'nv-bar positive'})
-
- if (barColor) {
- if (!disabled) disabled = data.map(function() { return true });
- bars
- //.style('fill', barColor)
- //.style('stroke', barColor)
- //.style('fill', function(d,i,j) { return
d3.rgb(barColor(d,i)).darker(j).toString(); })
- //.style('stroke', function(d,i,j) { return
d3.rgb(barColor(d,i)).darker(j).toString(); })
- .style('fill', function(d,i,j) { return d3.rgb(barColor(d,i)).darker(
disabled.map(function(d,i) { return i }).filter(function(d,i){ return !disabled[i] })[j]
).toString(); })
- .style('stroke', function(d,i,j) { return d3.rgb(barColor(d,i)).darker(
disabled.map(function(d,i) { return i }).filter(function(d,i){ return !disabled[i] })[j]
).toString(); });
- }
-
- if (stacked)
- d3.transition(bars)
- //.delay(function(d,i) { return i * delay / data[0].values.length })
- .attr('transform', function(d,i) {
- //return 'translate(' + y(d.y0) + ',0)'
- //return 'translate(' + y(d.y0) + ',' + x(getX(d,i)) +
')'
- return 'translate(' + y(d.y1) + ',' + x(getX(d,i)) +
')'
- })
- .select('rect')
- .attr('width', function(d,i) {
- return Math.abs(y(getY(d,i) + d.y0) - y(d.y0))
- })
- .attr('height', x.rangeBand() );
- else
- d3.transition(bars)
- //.delay(function(d,i) { return i * delay / data[0].values.length })
- .attr('transform', function(d,i) {
- //TODO: stacked must be all positive or all negative, not both?
- return 'translate(' +
- (getY(d,i) < 0 ? y(getY(d,i)) : y(0))
- + ',' +
- (d.series * x.rangeBand() / data.length
- +
- x(getX(d,i)) )
- + ')'
- })
- .select('rect')
- .attr('height', x.rangeBand() / data.length )
- .attr('width', function(d,i) {
- return Math.max(Math.abs(y(getY(d,i)) - y(0)),1)
- });
-
-
- //store old scales for use in transitions on update
- x0 = x.copy();
- y0 = y.copy();
-
- });
-
- return chart;
- }
-
-
- //============================================================
- // Expose Public Variables
- //------------------------------------------------------------
-
- chart.dispatch = dispatch;
-
- 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.forceY = function(_) {
- if (!arguments.length) return forceY;
- forceY = _;
- return chart;
- };
-
- chart.stacked = function(_) {
- if (!arguments.length) return stacked;
- stacked = _;
- return chart;
- };
-
- chart.color = function(_) {
- if (!arguments.length) return color;
- color = nv.utils.getColor(_);
- return chart;
- };
-
- chart.barColor = function(_) {
- if (!arguments.length) return barColor;
- barColor = nv.utils.getColor(_);
- return chart;
- };
-
- chart.disabled = function(_) {
- if (!arguments.length) return disabled;
- disabled = _;
- return chart;
- };
-
- chart.id = function(_) {
- if (!arguments.length) return id;
- id = _;
- return chart;
- };
-
- chart.delay = function(_) {
- if (!arguments.length) return delay;
- delay = _;
- return chart;
- };
-
- chart.showValues = function(_) {
- if (!arguments.length) return showValues;
- showValues = _;
- return chart;
- };
-
- chart.valueFormat= function(_) {
- if (!arguments.length) return valueFormat;
- valueFormat = _;
- return chart;
- };
-
- chart.valuePadding = function(_) {
- if (!arguments.length) return valuePadding;
- valuePadding = _;
- return chart;
- };
-
- //============================================================
-
-
- return chart;
-}
-
-nv.models.multiBarHorizontalChart = function() {
-
- //============================================================
- // Public Variables with Default Settings
- //------------------------------------------------------------
-
- var multibar = nv.models.multiBarHorizontal()
- , xAxis = nv.models.axis()
- , yAxis = nv.models.axis()
- , legend = nv.models.legend().height(30)
- , controls = nv.models.legend().height(30)
- ;
-
- var margin = {top: 30, right: 20, bottom: 50, left: 60}
- , width = null
- , height = null
- , color = nv.utils.defaultColor()
- , showControls = true
- , showLegend = true
- , stacked = false
- , tooltips = true
- , tooltip = function(key, x, y, e, graph) {
- return '<h3>' + key + ' - ' + x + '</h3>' +
- '<p>' + y + '</p>'
- }
- , x //can be accessed via chart.xScale()
- , y //can be accessed via chart.yScale()
- , state = { stacked: stacked }
- , defaultState = null
- , noData = 'No Data Available.'
- , dispatch = d3.dispatch('tooltipShow', 'tooltipHide',
'stateChange', 'changeState')
- , controlWidth = function() { return showControls ? 180 : 0 }
- ;
-
- multibar
- .stacked(stacked)
- ;
- xAxis
- .orient('left')
- .tickPadding(5)
- .highlightZero(false)
- .showMaxMin(false)
- .tickFormat(function(d) { return d })
- ;
- yAxis
- .orient('bottom')
- .tickFormat(d3.format(',.1f'))
- ;
-
- //============================================================
-
-
- //============================================================
- // Private Variables
- //------------------------------------------------------------
-
- var showTooltip = function(e, offsetElement) {
- var left = e.pos[0] + ( offsetElement.offsetLeft || 0 ),
- top = e.pos[1] + ( offsetElement.offsetTop || 0),
- x = xAxis.tickFormat()(multibar.x()(e.point, e.pointIndex)),
- y = yAxis.tickFormat()(multibar.y()(e.point, e.pointIndex)),
- content = tooltip(e.series.key, x, y, e, chart);
-
- nv.tooltip.show([left, top], content, e.value < 0 ? 'e' : 'w',
null, offsetElement);
- };
-
- //============================================================
-
-
- function chart(selection) {
- selection.each(function(data) {
- var container = d3.select(this),
- that = this;
-
- var availableWidth = (width || parseInt(container.style('width')) || 960)
- - margin.left - margin.right,
- availableHeight = (height || parseInt(container.style('height')) ||
400)
- - margin.top - margin.bottom;
-
- chart.update = function() { container.transition().call(chart) };
- chart.container = this;
-
- //set state.disabled
- state.disabled = data.map(function(d) { return !!d.disabled });
-
- if (!defaultState) {
- var key;
- defaultState = {};
- for (key in state) {
- if (state[key] instanceof Array)
- defaultState[key] = state[key].slice(0);
- else
- defaultState[key] = state[key];
- }
- }
-
- //------------------------------------------------------------
- // Display No Data message if there's nothing to show.
-
- if (!data || !data.length || !data.filter(function(d) { return d.values.length
}).length) {
- var noDataText = container.selectAll('.nv-noData').data([noData]);
-
- noDataText.enter().append('text')
- .attr('class', 'nvd3 nv-noData')
- .attr('dy', '-.7em')
- .style('text-anchor', 'middle');
-
- noDataText
- .attr('x', margin.left + availableWidth / 2)
- .attr('y', margin.top + availableHeight / 2)
- .text(function(d) { return d });
-
- return chart;
- } else {
- container.selectAll('.nv-noData').remove();
- }
-
- //------------------------------------------------------------
-
-
- //------------------------------------------------------------
- // Setup Scales
-
- x = multibar.xScale();
- y = multibar.yScale();
-
- //------------------------------------------------------------
-
-
- //------------------------------------------------------------
- // Setup containers and skeleton of chart
-
- var wrap =
container.selectAll('g.nv-wrap.nv-multiBarHorizontalChart').data([data]);
- var gEnter = wrap.enter().append('g').attr('class', 'nvd3
nv-wrap nv-multiBarHorizontalChart').append('g');
- var g = wrap.select('g');
-
- gEnter.append('g').attr('class', 'nv-x nv-axis');
- gEnter.append('g').attr('class', 'nv-y nv-axis');
- gEnter.append('g').attr('class', 'nv-barsWrap');
- gEnter.append('g').attr('class', 'nv-legendWrap');
- gEnter.append('g').attr('class', 'nv-controlsWrap');
-
- //------------------------------------------------------------
-
-
- //------------------------------------------------------------
- // Legend
-
- if (showLegend) {
- legend.width(availableWidth - controlWidth());
-
- if (multibar.barColor())
- data.forEach(function(series,i) {
- series.color = d3.rgb('#ccc').darker(i * 1.5).toString();
- })
-
- g.select('.nv-legendWrap')
- .datum(data)
- .call(legend);
-
- if ( margin.top != legend.height()) {
- margin.top = legend.height();
- availableHeight = (height || parseInt(container.style('height')) ||
400)
- - margin.top - margin.bottom;
- }
-
- g.select('.nv-legendWrap')
- .attr('transform', 'translate(' + controlWidth() +
',' + (-margin.top) +')');
- }
-
- //------------------------------------------------------------
-
-
- //------------------------------------------------------------
- // Controls
-
- if (showControls) {
- var controlsData = [
- { key: 'Grouped', disabled: multibar.stacked() },
- { key: 'Stacked', disabled: !multibar.stacked() }
- ];
-
- controls.width(controlWidth()).color(['#444', '#444',
'#444']);
- g.select('.nv-controlsWrap')
- .datum(controlsData)
- .attr('transform', 'translate(0,' + (-margin.top)
+')')
- .call(controls);
- }
-
- //------------------------------------------------------------
-
-
- wrap.attr('transform', 'translate(' + margin.left + ',' +
margin.top + ')');
-
-
- //------------------------------------------------------------
- // Main Chart Component(s)
-
- multibar
- .disabled(data.map(function(series) { return series.disabled }))
- .width(availableWidth)
- .height(availableHeight)
- .color(data.map(function(d,i) {
- return d.color || color(d, i);
- }).filter(function(d,i) { return !data[i].disabled }))
-
-
- var barsWrap = g.select('.nv-barsWrap')
- .datum(data.filter(function(d) { return !d.disabled }))
-
- d3.transition(barsWrap).call(multibar);
-
- //------------------------------------------------------------
-
-
- //------------------------------------------------------------
- // Setup Axes
-
- xAxis
- .scale(x)
- .ticks( availableHeight / 24 )
- .tickSize(-availableWidth, 0);
-
- d3.transition(g.select('.nv-x.nv-axis'))
- .call(xAxis);
-
- var xTicks = g.select('.nv-x.nv-axis').selectAll('g');
-
- xTicks
- .selectAll('line, text')
- .style('opacity', 1)
-
-
- yAxis
- .scale(y)
- .ticks( availableWidth / 100 )
- .tickSize( -availableHeight, 0);
-
- g.select('.nv-y.nv-axis')
- .attr('transform', 'translate(0,' + availableHeight +
')');
- d3.transition(g.select('.nv-y.nv-axis'))
- .call(yAxis);
-
- //------------------------------------------------------------
-
-
-
- //============================================================
- // Event Handling/Dispatching (in chart's scope)
- //------------------------------------------------------------
-
- 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 });
- dispatch.stateChange(state);
-
- 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;
- });
- d.disabled = false;
-
- state.disabled = data.map(function(d) { return !!d.disabled });
- dispatch.stateChange(state);
- chart.update();
- });
-
- controls.dispatch.on('legendClick', function(d,i) {
- if (!d.disabled) return;
- controlsData = controlsData.map(function(s) {
- s.disabled = true;
- return s;
- });
- d.disabled = false;
-
- switch (d.key) {
- case 'Grouped':
- multibar.stacked(false);
- break;
- case 'Stacked':
- multibar.stacked(true);
- break;
- }
-
- state.stacked = multibar.stacked();
- dispatch.stateChange(state);
-
- chart.update();
- });
-
- dispatch.on('tooltipShow', function(e) {
- if (tooltips) showTooltip(e, that.parentNode);
- });
-
- // Update chart from a state object passed to event handler
- dispatch.on('changeState', function(e) {
-
- if (typeof e.disabled !== 'undefined') {
- data.forEach(function(series,i) {
- series.disabled = e.disabled[i];
- });
-
- state.disabled = e.disabled;
- }
-
- if (typeof e.stacked !== 'undefined') {
- multibar.stacked(e.stacked);
- state.stacked = e.stacked;
- }
-
- selection.call(chart);
- });
- //============================================================
-
-
- });
-
- return chart;
- }
-
-
- //============================================================
- // Event Handling/Dispatching (out of chart's scope)
- //------------------------------------------------------------
-
- multibar.dispatch.on('elementMouseover.tooltip', function(e) {
- e.pos = [e.pos[0] + margin.left, e.pos[1] + margin.top];
- dispatch.tooltipShow(e);
- });
-
- multibar.dispatch.on('elementMouseout.tooltip', function(e) {
- dispatch.tooltipHide(e);
- });
- dispatch.on('tooltipHide', function() {
- if (tooltips) nv.tooltip.cleanup();
- });
-
- //============================================================
-
-
- //============================================================
- // Expose Public Variables
- //------------------------------------------------------------
-
- // expose chart's sub-components
- chart.dispatch = dispatch;
- chart.multibar = multibar;
- chart.legend = legend;
- chart.xAxis = xAxis;
- chart.yAxis = yAxis;
-
- d3.rebind(chart, multibar, 'x', 'y', 'xDomain',
'yDomain', 'forceX', 'forceY', 'clipEdge', 'id',
'delay', 'showValues', 'valueFormat', 'stacked',
'barColor');
-
- 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.color = function(_) {
- if (!arguments.length) return color;
- color = nv.utils.getColor(_);
- legend.color(color);
- return chart;
- };
-
- chart.showControls = function(_) {
- if (!arguments.length) return showControls;
- showControls = _;
- return chart;
- };
-
- chart.showLegend = function(_) {
- if (!arguments.length) return showLegend;
- showLegend = _;
- return chart;
- };
-
- chart.tooltip = function(_) {
- if (!arguments.length) return tooltip;
- tooltip = _;
- return chart;
- };
-
- chart.tooltips = function(_) {
- if (!arguments.length) return tooltips;
- tooltips = _;
- return chart;
- };
-
- chart.tooltipContent = function(_) {
- if (!arguments.length) return tooltip;
- tooltip = _;
- return chart;
- };
-
- chart.state = function(_) {
- if (!arguments.length) return state;
- state = _;
- return chart;
- };
-
- chart.defaultState = function(_) {
- if (!arguments.length) return defaultState;
- defaultState = _;
- return chart;
- };
-
- chart.noData = function(_) {
- if (!arguments.length) return noData;
- noData = _;
- return chart;
- };
-
- //============================================================
-
-
- return chart;
-}
-nv.models.multiChart = function() {
-
- //============================================================
- // Public Variables with Default Settings
- //------------------------------------------------------------
-
- var margin = {top: 30, right: 20, bottom: 50, left: 60},
- color = d3.scale.category20().range(),
- width = null,
- height = null,
- showLegend = true,
- tooltips = true,
- tooltip = function(key, x, y, e, graph) {
- return '<h3>' + key + '</h3>' +
- '<p>' + y + ' at ' + x + '</p>'
- },
- x, y; //can be accessed via chart.lines.[x/y]Scale()
-
- //============================================================
- // Private Variables
- //------------------------------------------------------------
-
- var x = d3.scale.linear(),
- yScale1 = d3.scale.linear(),
- yScale2 = d3.scale.linear(),
-
- lines1 = nv.models.line().yScale(yScale1),
- lines2 = nv.models.line().yScale(yScale2),
-
- bars1 = nv.models.multiBar().stacked(false).yScale(yScale1),
- bars2 = nv.models.multiBar().stacked(false).yScale(yScale2),
-
- stack1 = nv.models.stackedArea().yScale(yScale1),
- stack2 = nv.models.stackedArea().yScale(yScale2),
-
- xAxis = nv.models.axis().scale(x).orient('bottom').tickPadding(5),
- yAxis1 = nv.models.axis().scale(yScale1).orient('left'),
- yAxis2 = nv.models.axis().scale(yScale2).orient('right'),
-
- legend = nv.models.legend().height(30),
- dispatch = d3.dispatch('tooltipShow', 'tooltipHide');
-
- var showTooltip = function(e, offsetElement) {
- var left = e.pos[0] + ( offsetElement.offsetLeft || 0 ),
- top = e.pos[1] + ( offsetElement.offsetTop || 0),
- x = xAxis.tickFormat()(lines1.x()(e.point, e.pointIndex)),
- y = ((e.series.yAxis == 2) ? yAxis2 : yAxis1).tickFormat()(lines1.y()(e.point,
e.pointIndex)),
- content = tooltip(e.series.key, x, y, e, chart);
-
- nv.tooltip.show([left, top], content, undefined, undefined,
offsetElement.offsetParent);
- };
-
- function chart(selection) {
- selection.each(function(data) {
- var container = d3.select(this),
- that = this;
-
- chart.update = function() { container.transition().call(chart); };
- chart.container = this;
-
- var availableWidth = (width || parseInt(container.style('width')) || 960)
- - margin.left - margin.right,
- availableHeight = (height || parseInt(container.style('height')) ||
400)
- - margin.top - margin.bottom;
-
- var dataLines1 = data.filter(function(d) {return !d.disabled && d.type ==
'line' && d.yAxis == 1})
- var dataLines2 = data.filter(function(d) {return !d.disabled && d.type ==
'line' && d.yAxis == 2})
- var dataBars1 = data.filter(function(d) {return !d.disabled && d.type ==
'bar' && d.yAxis == 1})
- var dataBars2 = data.filter(function(d) {return !d.disabled && d.type ==
'bar' && d.yAxis == 2})
- var dataStack1 = data.filter(function(d) {return !d.disabled && d.type ==
'area' && d.yAxis == 1})
- var dataStack2 = data.filter(function(d) {return !d.disabled && d.type ==
'area' && d.yAxis == 2})
-
- var series1 = data.filter(function(d) {return !d.disabled && d.yAxis ==
1})
- .map(function(d) {
- return d.values.map(function(d,i) {
- return { x: d.x, y: d.y }
- })
- })
-
- var series2 = data.filter(function(d) {return !d.disabled && d.yAxis ==
2})
- .map(function(d) {
- return d.values.map(function(d,i) {
- return { x: d.x, y: d.y }
- })
- })
-
- x .domain(d3.extent(d3.merge(series1.concat(series2)), function(d) { return d.x }
))
- .range([0, availableWidth]);
-
- var wrap = container.selectAll('g.wrap.multiChart').data([data]);
- var gEnter = wrap.enter().append('g').attr('class', 'wrap nvd3
multiChart').append('g');
-
- gEnter.append('g').attr('class', 'x axis');
- gEnter.append('g').attr('class', 'y1 axis');
- gEnter.append('g').attr('class', 'y2 axis');
- gEnter.append('g').attr('class', 'lines1Wrap');
- gEnter.append('g').attr('class', 'lines2Wrap');
- gEnter.append('g').attr('class', 'bars1Wrap');
- gEnter.append('g').attr('class', 'bars2Wrap');
- gEnter.append('g').attr('class', 'stack1Wrap');
- gEnter.append('g').attr('class', 'stack2Wrap');
- gEnter.append('g').attr('class', 'legendWrap');
-
- var g = wrap.select('g');
-
- if (showLegend) {
- legend.width( availableWidth / 2 );
-
- g.select('.legendWrap')
- .datum(data.map(function(series) {
- series.originalKey = series.originalKey === undefined ? series.key :
series.originalKey;
- series.key = series.originalKey + (series.yAxis == 1 ? '' : '
(right axis)');
- return series;
- }))
- .call(legend);
-
- if ( margin.top != legend.height()) {
- margin.top = legend.height();
- availableHeight = (height || parseInt(container.style('height')) ||
400)
- - margin.top - margin.bottom;
- }
-
- g.select('.legendWrap')
- .attr('transform', 'translate(' + ( availableWidth / 2 ) +
',' + (-margin.top) +')');
- }
-
-
- lines1
- .width(availableWidth)
- .height(availableHeight)
- .interpolate("monotone")
- .color(data.map(function(d,i) {
- return d.color || color[i % color.length];
- }).filter(function(d,i) { return !data[i].disabled && data[i].yAxis == 1
&& data[i].type == 'line'}));
-
- lines2
- .width(availableWidth)
- .height(availableHeight)
- .interpolate("monotone")
- .color(data.map(function(d,i) {
- return d.color || color[i % color.length];
- }).filter(function(d,i) { return !data[i].disabled && data[i].yAxis == 2
&& data[i].type == 'line'}));
-
- bars1
- .width(availableWidth)
- .height(availableHeight)
- .color(data.map(function(d,i) {
- return d.color || color[i % color.length];
- }).filter(function(d,i) { return !data[i].disabled && data[i].yAxis == 1
&& data[i].type == 'bar'}));
-
- bars2
- .width(availableWidth)
- .height(availableHeight)
- .color(data.map(function(d,i) {
- return d.color || color[i % color.length];
- }).filter(function(d,i) { return !data[i].disabled && data[i].yAxis == 2
&& data[i].type == 'bar'}));
-
- stack1
- .width(availableWidth)
- .height(availableHeight)
- .color(data.map(function(d,i) {
- return d.color || color[i % color.length];
- }).filter(function(d,i) { return !data[i].disabled && data[i].yAxis == 1
&& data[i].type == 'area'}));
-
- stack2
- .width(availableWidth)
- .height(availableHeight)
- .color(data.map(function(d,i) {
- return d.color || color[i % color.length];
- }).filter(function(d,i) { return !data[i].disabled && data[i].yAxis == 2
&& data[i].type == 'area'}));
-
- g.attr('transform', 'translate(' + margin.left + ',' +
margin.top + ')');
-
-
- var lines1Wrap = g.select('.lines1Wrap')
- .datum(dataLines1)
- var bars1Wrap = g.select('.bars1Wrap')
- .datum(dataBars1)
- var stack1Wrap = g.select('.stack1Wrap')
- .datum(dataStack1)
-
- var lines2Wrap = g.select('.lines2Wrap')
- .datum(dataLines2)
- var bars2Wrap = g.select('.bars2Wrap')
- .datum(dataBars2)
- var stack2Wrap = g.select('.stack2Wrap')
- .datum(dataStack2)
-
- var extraValue1 = dataStack1.length ? dataStack1.map(function(a){return
a.values}).reduce(function(a,b){
- return a.map(function(aVal,i){return {x: aVal.x, y: aVal.y + b[i].y}})
- }).concat([{x:0, y:0}]) : []
- var extraValue2 = dataStack2.length ? dataStack2.map(function(a){return
a.values}).reduce(function(a,b){
- return a.map(function(aVal,i){return {x: aVal.x, y: aVal.y + b[i].y}})
- }).concat([{x:0, y:0}]) : []
-
- yScale1 .domain(d3.extent(d3.merge(series1).concat(extraValue1), function(d) {
return d.y } ))
- .range([0, availableHeight])
-
- yScale2 .domain(d3.extent(d3.merge(series2).concat(extraValue2), function(d) {
return d.y } ))
- .range([0, availableHeight])
-
- lines1.yDomain(yScale1.domain())
- bars1.yDomain(yScale1.domain())
- stack1.yDomain(yScale1.domain())
-
- lines2.yDomain(yScale2.domain())
- bars2.yDomain(yScale2.domain())
- stack2.yDomain(yScale2.domain())
-
- if(dataStack1.length){d3.transition(stack1Wrap).call(stack1);}
- if(dataStack2.length){d3.transition(stack2Wrap).call(stack2);}
-
- if(dataBars1.length){d3.transition(bars1Wrap).call(bars1);}
- if(dataBars2.length){d3.transition(bars2Wrap).call(bars2);}
-
- if(dataLines1.length){d3.transition(lines1Wrap).call(lines1);}
- if(dataLines2.length){d3.transition(lines2Wrap).call(lines2);}
-
-
-
- xAxis
- .ticks( availableWidth / 100 )
- .tickSize(-availableHeight, 0);
-
- g.select('.x.axis')
- .attr('transform', 'translate(0,' + availableHeight +
')');
- d3.transition(g.select('.x.axis'))
- .call(xAxis);
-
- yAxis1
- .ticks( availableHeight / 36 )
- .tickSize( -availableWidth, 0);
-
-
- d3.transition(g.select('.y1.axis'))
- .call(yAxis1);
-
- yAxis2
- .ticks( availableHeight / 36 )
- .tickSize( -availableWidth, 0);
-
- d3.transition(g.select('.y2.axis'))
- .call(yAxis2);
-
- g.select('.y2.axis')
- .style('opacity', series2.length ? 1 : 0)
- .attr('transform', 'translate(' + x.range()[1] +
',0)');
-
- 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('.series').classed('disabled', false);
- return d;
- });
- }
- chart.update();
- });
-
- dispatch.on('tooltipShow', function(e) {
- if (tooltips) showTooltip(e, that.parentNode);
- });
-
- });
-
- return chart;
- }
-
-
- //============================================================
- // Event Handling/Dispatching (out of chart's scope)
- //------------------------------------------------------------
-
- lines1.dispatch.on('elementMouseover.tooltip', function(e) {
- e.pos = [e.pos[0] + margin.left, e.pos[1] + margin.top];
- dispatch.tooltipShow(e);
- });
-
- lines1.dispatch.on('elementMouseout.tooltip', function(e) {
- dispatch.tooltipHide(e);
- });
-
- lines2.dispatch.on('elementMouseover.tooltip', function(e) {
- e.pos = [e.pos[0] + margin.left, e.pos[1] + margin.top];
- dispatch.tooltipShow(e);
- });
-
- lines2.dispatch.on('elementMouseout.tooltip', function(e) {
- dispatch.tooltipHide(e);
- });
-
- bars1.dispatch.on('elementMouseover.tooltip', function(e) {
- e.pos = [e.pos[0] + margin.left, e.pos[1] + margin.top];
- dispatch.tooltipShow(e);
- });
-
- bars1.dispatch.on('elementMouseout.tooltip', function(e) {
- dispatch.tooltipHide(e);
- });
-
- bars2.dispatch.on('elementMouseover.tooltip', function(e) {
- e.pos = [e.pos[0] + margin.left, e.pos[1] + margin.top];
- dispatch.tooltipShow(e);
- });
-
- bars2.dispatch.on('elementMouseout.tooltip', function(e) {
- dispatch.tooltipHide(e);
- });
-
- stack1.dispatch.on('tooltipShow', function(e) {
- //disable tooltips when value ~= 0
- //// TODO: consider removing points from voronoi that have 0 value instead of this
hack
- if (!Math.round(stack1.y()(e.point) * 100)) { // 100 will not be good for very small
numbers... will have to think about making this valu dynamic, based on data range
- setTimeout(function() {
d3.selectAll('.point.hover').classed('hover', false) }, 0);
- return false;
- }
-
- e.pos = [e.pos[0] + margin.left, e.pos[1] + margin.top],
- dispatch.tooltipShow(e);
- });
-
- stack1.dispatch.on('tooltipHide', function(e) {
- dispatch.tooltipHide(e);
- });
-
- stack2.dispatch.on('tooltipShow', function(e) {
- //disable tooltips when value ~= 0
- //// TODO: consider removing points from voronoi that have 0 value instead of this
hack
- if (!Math.round(stack2.y()(e.point) * 100)) { // 100 will not be good for very small
numbers... will have to think about making this valu dynamic, based on data range
- setTimeout(function() {
d3.selectAll('.point.hover').classed('hover', false) }, 0);
- return false;
- }
-
- e.pos = [e.pos[0] + margin.left, e.pos[1] + margin.top],
- dispatch.tooltipShow(e);
- });
-
- stack2.dispatch.on('tooltipHide', function(e) {
- dispatch.tooltipHide(e);
- });
-
- lines1.dispatch.on('elementMouseover.tooltip', function(e) {
- e.pos = [e.pos[0] + margin.left, e.pos[1] + margin.top];
- dispatch.tooltipShow(e);
- });
-
- lines1.dispatch.on('elementMouseout.tooltip', function(e) {
- dispatch.tooltipHide(e);
- });
-
- lines2.dispatch.on('elementMouseover.tooltip', function(e) {
- e.pos = [e.pos[0] + margin.left, e.pos[1] + margin.top];
- dispatch.tooltipShow(e);
- });
-
- lines2.dispatch.on('elementMouseout.tooltip', function(e) {
- dispatch.tooltipHide(e);
- });
-
- dispatch.on('tooltipHide', function() {
- if (tooltips) nv.tooltip.cleanup();
- });
-
-
-
- //============================================================
- // Global getters and setters
- //------------------------------------------------------------
-
- chart.dispatch = dispatch;
- chart.lines1 = lines1;
- chart.lines2 = lines2;
- chart.bars1 = bars1;
- chart.bars2 = bars2;
- chart.stack1 = stack1;
- chart.stack2 = stack2;
- chart.xAxis = xAxis;
- chart.yAxis1 = yAxis1;
- chart.yAxis2 = yAxis2;
-
- chart.x = function(_) {
- if (!arguments.length) return getX;
- getX = _;
- lines1.x(_);
- bars1.x(_);
- return chart;
- };
-
- chart.y = function(_) {
- if (!arguments.length) return getY;
- getY = _;
- lines1.y(_);
- bars1.y(_);
- return chart;
- };
-
- chart.margin = function(_) {
- if (!arguments.length) return margin;
- margin = _;
- 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.color = function(_) {
- if (!arguments.length) return color;
- color = _;
- legend.color(_);
- return chart;
- };
-
- chart.showLegend = function(_) {
- if (!arguments.length) return showLegend;
- showLegend = _;
- return chart;
- };
-
- chart.tooltips = function(_) {
- if (!arguments.length) return tooltips;
- tooltips = _;
- return chart;
- };
-
- chart.tooltipContent = function(_) {
- if (!arguments.length) return tooltip;
- tooltip = _;
- return chart;
- };
-
- return chart;
-}
-
-
-nv.models.ohlcBar = function() {
-
- //============================================================
- // Public Variables with Default Settings
- //------------------------------------------------------------
-
- var margin = {top: 0, right: 0, bottom: 0, left: 0}
- , 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 }
- , getOpen = function(d) { return d.open }
- , getClose = function(d) { return d.close }
- , getHigh = function(d) { return d.high }
- , getLow = function(d) { return d.low }
- , forceX = []
- , forceY = []
- , padData = false // If true, adds half a data points width to front and back,
for lining up a line chart with a bar chart
- , clipEdge = true
- , color = nv.utils.defaultColor()
- , xDomain
- , yDomain
- , dispatch = d3.dispatch('chartClick', 'elementClick',
'elementDblClick', 'elementMouseover', 'elementMouseout')
- ;
-
- //============================================================
-
- //============================================================
- // Private Variables
- //------------------------------------------------------------
-
- //TODO: store old scales for transitions
-
- //============================================================
-
-
- function chart(selection) {
- selection.each(function(data) {
- var availableWidth = width - margin.left - margin.right,
- availableHeight = height - margin.top - margin.bottom,
- container = d3.select(this);
-
-
- //------------------------------------------------------------
- // Setup Scales
-
- x .domain(xDomain || d3.extent(data[0].values.map(getX).concat(forceX) ));
-
- if (padData)
- x.range([availableWidth * .5 / data[0].values.length, availableWidth *
(data[0].values.length - .5) / data[0].values.length ]);
- else
- x.range([0, availableWidth]);
-
- y .domain(yDomain || [
- d3.min(data[0].values.map(getLow).concat(forceY)),
- d3.max(data[0].values.map(getHigh).concat(forceY))
- ])
- .range([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
- if (x.domain()[0] === x.domain()[1] || y.domain()[0] === y.domain()[1]) singlePoint
= true;
- 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]);
-
- //------------------------------------------------------------
-
-
- //------------------------------------------------------------
- // Setup containers and skeleton of chart
-
- var wrap =
d3.select(this).selectAll('g.nv-wrap.nv-ohlcBar').data([data[0].values]);
- var wrapEnter = wrap.enter().append('g').attr('class', 'nvd3
nv-wrap nv-ohlcBar');
- var defsEnter = wrapEnter.append('defs');
- var gEnter = wrapEnter.append('g');
- var g = wrap.select('g');
-
- gEnter.append('g').attr('class', 'nv-ticks');
-
- 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
- });
- });
-
-
- defsEnter.append('clipPath')
- .attr('id', 'nv-chart-clip-path-' + id)
- .append('rect');
-
- wrap.select('#nv-chart-clip-path-' + id + ' rect')
- .attr('width', availableWidth)
- .attr('height', availableHeight);
-
- g .attr('clip-path', clipEdge ? 'url(#nv-chart-clip-path-' + id +
')' : '');
-
-
-
- var ticks = wrap.select('.nv-ticks').selectAll('.nv-tick')
- .data(function(d) { return d });
-
- ticks.exit().remove();
-
-
- var ticksEnter = ticks.enter().append('path')
- .attr('class', function(d,i,j) { return (getOpen(d,i) >
getClose(d,i) ? 'nv-tick negative' : 'nv-tick positive') + '
nv-tick-' + j + '-' + i })
- .attr('d', function(d,i) {
- var w = (availableWidth / data[0].values.length) * .9;
- return 'm0,0l0,'
- + (y(getOpen(d,i))
- - y(getHigh(d,i)))
- + 'l'
- + (-w/2)
- + ',0l'
- + (w/2)
- + ',0l0,'
- + (y(getLow(d,i)) - y(getOpen(d,i)))
- + 'l0,'
- + (y(getClose(d,i))
- - y(getLow(d,i)))
- + 'l'
- + (w/2)
- + ',0l'
- + (-w/2)
- + ',0z';
- })
- .attr('transform', function(d,i) { return 'translate(' +
x(getX(d,i)) + ',' + y(getHigh(d,i)) + ')'; })
- //.attr('fill', function(d,i) { return color[0]; })
- //.attr('stroke', function(d,i) { return color[0]; })
- //.attr('x', 0 )
- //.attr('y', function(d,i) { return y(Math.max(0, getY(d,i))) })
- //.attr('height', function(d,i) { return Math.abs(y(getY(d,i)) - y(0))
})
- .on('mouseover', function(d,i) {
- 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) {
- 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) {
- 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) {
- 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();
- });
-
- ticks
- .attr('class', function(d,i,j) { return (getOpen(d,i) >
getClose(d,i) ? 'nv-tick negative' : 'nv-tick positive') + '
nv-tick-' + j + '-' + i })
- d3.transition(ticks)
- .attr('transform', function(d,i) { return 'translate(' +
x(getX(d,i)) + ',' + y(getHigh(d,i)) + ')'; })
- .attr('d', function(d,i) {
- var w = (availableWidth / data[0].values.length) * .9;
- return 'm0,0l0,'
- + (y(getOpen(d,i))
- - y(getHigh(d,i)))
- + 'l'
- + (-w/2)
- + ',0l'
- + (w/2)
- + ',0l0,'
- + (y(getLow(d,i))
- - y(getOpen(d,i)))
- + 'l0,'
- + (y(getClose(d,i))
- - y(getLow(d,i)))
- + 'l'
- + (w/2)
- + ',0l'
- + (-w/2)
- + ',0z';
- })
- //.attr('width', (availableWidth / data[0].values.length) * .9 )
-
-
- //d3.transition(ticks)
- //.attr('y', function(d,i) { return y(Math.max(0, getY(d,i))) })
- //.attr('height', function(d,i) { return Math.abs(y(getY(d,i)) - y(0))
});
- //.order(); // not sure if this makes any sense for this model
-
- });
-
- return chart;
- }
-
-
- //============================================================
- // Expose Public Variables
- //------------------------------------------------------------
-
- chart.dispatch = dispatch;
-
- chart.x = function(_) {
- if (!arguments.length) return getX;
- getX = _;
- return chart;
- };
-
- chart.y = function(_) {
- if (!arguments.length) return getY;
- getY = _;
- return chart;
- };
-
- chart.open = function(_) {
- if (!arguments.length) return getOpen;
- getOpen = _;
- return chart;
- };
-
- chart.close = function(_) {
- if (!arguments.length) return getClose;
- getClose = _;
- return chart;
- };
-
- chart.high = function(_) {
- if (!arguments.length) return getHigh;
- getHigh = _;
- return chart;
- };
-
- chart.low = function(_) {
- if (!arguments.length) return getLow;
- getLow = _;
- 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.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;
- };
-
- //============================================================
-
-
- return chart;
-}
-nv.models.pie = function() {
-
- //============================================================
- // Public Variables with Default Settings
- //------------------------------------------------------------
-
- var margin = {top: 0, right: 0, bottom: 0, left: 0}
- , width = 500
- , height = 500
- , getValues = function(d) { return d.values }
- , getX = function(d) { return d.x }
- , getY = function(d) { return d.y }
- , getDescription = function(d) { return d.description }
- , id = Math.floor(Math.random() * 10000) //Create semi-unique ID in case user
doesn't select one
- , color = nv.utils.defaultColor()
- , valueFormat = d3.format(',.2f')
- , showLabels = true
- , pieLabelsOutside = true
- , donutLabelsOutside = false
- , labelThreshold = .02 //if slice percentage is under this, don't show label
- , donut = false
- , labelSunbeamLayout = false
- , startAngle = false
- , endAngle = false
- , donutRatio = 0.5
- , dispatch = d3.dispatch('chartClick', 'elementClick',
'elementDblClick', 'elementMouseover', 'elementMouseout')
- ;
-
- //============================================================
-
-
- function chart(selection) {
- selection.each(function(data) {
- var availableWidth = width - margin.left - margin.right,
- availableHeight = height - margin.top - margin.bottom,
- radius = Math.min(availableWidth, availableHeight) / 2,
- arcRadius = radius-(radius / 5),
- container = d3.select(this);
-
-
- //------------------------------------------------------------
- // Setup containers and skeleton of chart
-
- //var wrap = container.selectAll('.nv-wrap.nv-pie').data([data]);
- var wrap =
container.selectAll('.nv-wrap.nv-pie').data([getValues(data[0])]);
- var wrapEnter = wrap.enter().append('g').attr('class','nvd3
nv-wrap nv-pie nv-chart-' + id);
- var gEnter = wrapEnter.append('g');
- var g = wrap.select('g');
-
- gEnter.append('g').attr('class', 'nv-pie');
-
- wrap.attr('transform', 'translate(' + margin.left + ',' +
margin.top + ')');
- g.select('.nv-pie').attr('transform', 'translate(' +
availableWidth / 2 + ',' + availableHeight / 2 + ')');
-
- //------------------------------------------------------------
-
-
- container
- .on('click', function(d,i) {
- dispatch.chartClick({
- data: d,
- index: i,
- pos: d3.event,
- id: id
- });
- });
-
-
- var arc = d3.svg.arc()
- .outerRadius(arcRadius);
-
- if (startAngle) arc.startAngle(startAngle)
- if (endAngle) arc.endAngle(endAngle);
- if (donut) arc.innerRadius(radius * donutRatio);
-
- // Setup the Pie chart and choose the data element
- var pie = d3.layout.pie()
- .sort(null)
- .value(function(d) { return d.disabled ? 0 : getY(d) });
-
- var slices = wrap.select('.nv-pie').selectAll('.nv-slice')
- .data(pie);
-
- slices.exit().remove();
-
- var ae = slices.enter().append('g')
- .attr('class', 'nv-slice')
- .on('mouseover', function(d,i){
- d3.select(this).classed('hover', true);
- dispatch.elementMouseover({
- label: getX(d.data),
- value: getY(d.data),
- point: d.data,
- pointIndex: i,
- pos: [d3.event.pageX, d3.event.pageY],
- id: id
- });
- })
- .on('mouseout', function(d,i){
- d3.select(this).classed('hover', false);
- dispatch.elementMouseout({
- label: getX(d.data),
- value: getY(d.data),
- point: d.data,
- index: i,
- id: id
- });
- })
- .on('click', function(d,i) {
- dispatch.elementClick({
- label: getX(d.data),
- value: getY(d.data),
- point: d.data,
- index: i,
- pos: d3.event,
- id: id
- });
- d3.event.stopPropagation();
- })
- .on('dblclick', function(d,i) {
- dispatch.elementDblClick({
- label: getX(d.data),
- value: getY(d.data),
- point: d.data,
- index: i,
- pos: d3.event,
- id: id
- });
- d3.event.stopPropagation();
- });
-
- slices
- .attr('fill', function(d,i) { return color(d, i); })
- .attr('stroke', function(d,i) { return color(d, i); });
-
- var paths = ae.append('path')
- .each(function(d) { this._current = d; });
- //.attr('d', arc);
-
- d3.transition(slices.select('path'))
- .attr('d', arc)
- .attrTween('d', arcTween);
-
- if (showLabels) {
- // This does the normal label
- var labelsArc = d3.svg.arc().innerRadius(0);
-
- if (pieLabelsOutside){ labelsArc = arc; }
-
- if (donutLabelsOutside) { labelsArc =
d3.svg.arc().outerRadius(arc.outerRadius()); }
-
- ae.append("g").classed("nv-label", true)
- .each(function(d, i) {
- var group = d3.select(this);
-
- group
- .attr('transform', function(d) {
- if (labelSunbeamLayout) {
- d.outerRadius = arcRadius + 10; // Set Outer Coordinate
- d.innerRadius = arcRadius + 15; // Set Inner Coordinate
- var rotateAngle = (d.startAngle + d.endAngle) / 2 * (180 /
Math.PI);
- if ((d.startAngle+d.endAngle)/2 < Math.PI) {
- rotateAngle -= 90;
- } else {
- rotateAngle += 90;
- }
- return 'translate(' + labelsArc.centroid(d) + ')
rotate(' + rotateAngle + ')';
- } else {
- d.outerRadius = radius + 10; // Set Outer Coordinate
- d.innerRadius = radius + 15; // Set Inner Coordinate
- return 'translate(' + labelsArc.centroid(d) + ')'
- }
- });
-
- group.append('rect')
- .style('stroke', '#fff')
- .style('fill', '#fff')
- .attr("rx", 3)
- .attr("ry", 3);
-
- group.append('text')
- .style('text-anchor', labelSunbeamLayout ? ((d.startAngle +
d.endAngle) / 2 < Math.PI ? 'start' : 'end') : 'middle')
//center the text on it's origin or begin/end if orthogonal aligned
- .style('fill', '#000')
-
-
- });
-
- slices.select(".nv-label").transition()
- .attr('transform', function(d) {
- if (labelSunbeamLayout) {
- d.outerRadius = arcRadius + 10; // Set Outer Coordinate
- d.innerRadius = arcRadius + 15; // Set Inner Coordinate
- var rotateAngle = (d.startAngle + d.endAngle) / 2 * (180 / Math.PI);
- if ((d.startAngle+d.endAngle)/2 < Math.PI) {
- rotateAngle -= 90;
- } else {
- rotateAngle += 90;
- }
- return 'translate(' + labelsArc.centroid(d) + ')
rotate(' + rotateAngle + ')';
- } else {
- d.outerRadius = radius + 10; // Set Outer Coordinate
- d.innerRadius = radius + 15; // Set Inner Coordinate
- return 'translate(' + labelsArc.centroid(d) + ')'
- }
- });
-
- slices.each(function(d, i) {
- var slice = d3.select(this);
-
- slice
- .select(".nv-label text")
- .style('text-anchor', labelSunbeamLayout ? ((d.startAngle +
d.endAngle) / 2 < Math.PI ? 'start' : 'end') : 'middle')
//center the text on it's origin or begin/end if orthogonal aligned
- .text(function(d, i) {
- var percent = (d.endAngle - d.startAngle) / (2 * Math.PI);
- return (d.value && percent > labelThreshold) ? getX(d.data)
: '';
- });
-
- var textBox = slice.select('text').node().getBBox();
- slice.select(".nv-label rect")
- .attr("width", textBox.width + 10)
- .attr("height", textBox.height + 10)
- .attr("transform", function() {
- return "translate(" + [textBox.x - 5, textBox.y - 5] +
")";
- });
- });
- }
-
-
- // Computes the angle of an arc, converting from radians to degrees.
- function angle(d) {
- var a = (d.startAngle + d.endAngle) * 90 / Math.PI - 90;
- return a > 90 ? a - 180 : a;
- }
-
- function arcTween(a) {
- a.endAngle = isNaN(a.endAngle) ? 0 : a.endAngle;
- a.startAngle = isNaN(a.startAngle) ? 0 : a.startAngle;
- if (!donut) a.innerRadius = 0;
- var i = d3.interpolate(this._current, a);
- this._current = i(0);
- return function(t) {
- return arc(i(t));
- };
- }
-
- function tweenPie(b) {
- b.innerRadius = 0;
- var i = d3.interpolate({startAngle: 0, endAngle: 0}, b);
- return function(t) {
- return arc(i(t));
- };
- }
-
- });
-
- return chart;
- }
-
-
- //============================================================
- // Expose Public Variables
- //------------------------------------------------------------
-
- chart.dispatch = dispatch;
-
- 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.values = function(_) {
- if (!arguments.length) return getValues;
- getValues = _;
- return chart;
- };
-
- chart.x = function(_) {
- if (!arguments.length) return getX;
- getX = _;
- return chart;
- };
-
- chart.y = function(_) {
- if (!arguments.length) return getY;
- getY = d3.functor(_);
- return chart;
- };
-
- chart.description = function(_) {
- if (!arguments.length) return getDescription;
- getDescription = _;
- return chart;
- };
-
- chart.showLabels = function(_) {
- if (!arguments.length) return showLabels;
- showLabels = _;
- return chart;
- };
-
- chart.labelSunbeamLayout = function(_) {
- if (!arguments.length) return labelSunbeamLayout;
- labelSunbeamLayout = _;
- return chart;
- };
-
- chart.donutLabelsOutside = function(_) {
- if (!arguments.length) return donutLabelsOutside;
- donutLabelsOutside = _;
- return chart;
- };
-
- chart.pieLabelsOutside = function(_) {
- if (!arguments.length) return pieLabelsOutside;
- pieLabelsOutside = _;
- return chart;
- };
-
- chart.donut = function(_) {
- if (!arguments.length) return donut;
- donut = _;
- return chart;
- };
-
- chart.donutRatio = function(_) {
- if (!arguments.length) return donutRatio;
- donutRatio = _;
- return chart;
- };
-
- chart.startAngle = function(_) {
- if (!arguments.length) return startAngle;
- startAngle = _;
- return chart;
- };
-
- chart.endAngle = function(_) {
- if (!arguments.length) return endAngle;
- endAngle = _;
- return chart;
- };
-
- chart.id = function(_) {
- if (!arguments.length) return id;
- id = _;
- return chart;
- };
-
- chart.color = function(_) {
- if (!arguments.length) return color;
- color = nv.utils.getColor(_);
- return chart;
- };
-
- chart.valueFormat = function(_) {
- if (!arguments.length) return valueFormat;
- valueFormat = _;
- return chart;
- };
-
- chart.labelThreshold = function(_) {
- if (!arguments.length) return labelThreshold;
- labelThreshold = _;
- return chart;
- };
- //============================================================
-
-
- return chart;
-}
-nv.models.pieChart = function() {
-
- //============================================================
- // Public Variables with Default Settings
- //------------------------------------------------------------
-
- var pie = nv.models.pie()
- , legend = nv.models.legend()
- ;
-
- var margin = {top: 30, right: 20, bottom: 20, left: 20}
- , width = null
- , height = null
- , showLegend = true
- , color = nv.utils.defaultColor()
- , tooltips = true
- , tooltip = function(key, y, e, graph) {
- return '<h3>' + key + '</h3>' +
- '<p>' + y + '</p>'
- }
- , state = {}
- , defaultState = null
- , noData = "No Data Available."
- , dispatch = d3.dispatch('tooltipShow', 'tooltipHide',
'stateChange', 'changeState')
- ;
-
- //============================================================
-
-
- //============================================================
- // Private Variables
- //------------------------------------------------------------
-
- var showTooltip = function(e, offsetElement) {
- var tooltipLabel = pie.description()(e.point) || pie.x()(e.point)
- var left = e.pos[0] + ( (offsetElement && offsetElement.offsetLeft) || 0 ),
- top = e.pos[1] + ( (offsetElement && offsetElement.offsetTop) || 0),
- y = pie.valueFormat()(pie.y()(e.point)),
- content = tooltip(tooltipLabel, y, e, chart);
-
- nv.tooltip.show([left, top], content, e.value < 0 ? 'n' : 's',
null, offsetElement);
- };
-
- //============================================================
-
-
- function chart(selection) {
- selection.each(function(data) {
- var container = d3.select(this),
- that = this;
-
- var availableWidth = (width || parseInt(container.style('width')) || 960)
- - margin.left - margin.right,
- availableHeight = (height || parseInt(container.style('height')) ||
400)
- - margin.top - margin.bottom;
-
- chart.update = function() { container.transition().call(chart); };
- chart.container = this;
-
- //set state.disabled
- state.disabled = data[0].map(function(d) { return !!d.disabled });
-
- if (!defaultState) {
- var key;
- defaultState = {};
- for (key in state) {
- if (state[key] instanceof Array)
- defaultState[key] = state[key].slice(0);
- else
- defaultState[key] = state[key];
- }
- }
-
- //------------------------------------------------------------
- // Display No Data message if there's nothing to show.
-
- if (!data[0] || !data[0].length) {
- var noDataText = container.selectAll('.nv-noData').data([noData]);
-
- noDataText.enter().append('text')
- .attr('class', 'nvd3 nv-noData')
- .attr('dy', '-.7em')
- .style('text-anchor', 'middle');
-
- noDataText
- .attr('x', margin.left + availableWidth / 2)
- .attr('y', margin.top + availableHeight / 2)
- .text(function(d) { return d });
-
- return chart;
- } else {
- container.selectAll('.nv-noData').remove();
- }
-
- //------------------------------------------------------------
-
-
- //------------------------------------------------------------
- // Setup containers and skeleton of chart
-
- var wrap = container.selectAll('g.nv-wrap.nv-pieChart').data([data]);
- var gEnter = wrap.enter().append('g').attr('class', 'nvd3
nv-wrap nv-pieChart').append('g');
- var g = wrap.select('g');
-
- gEnter.append('g').attr('class', 'nv-pieWrap');
- gEnter.append('g').attr('class', 'nv-legendWrap');
-
- //------------------------------------------------------------
-
-
- //------------------------------------------------------------
- // Legend
-
- if (showLegend) {
- legend
- .width( availableWidth )
- .key(pie.x());
-
- wrap.select('.nv-legendWrap')
- .datum(pie.values()(data[0]))
- .call(legend);
-
- if ( margin.top != legend.height()) {
- margin.top = legend.height();
- availableHeight = (height || parseInt(container.style('height')) ||
400)
- - margin.top - margin.bottom;
- }
-
- wrap.select('.nv-legendWrap')
- .attr('transform', 'translate(0,' + (-margin.top)
+')');
- }
-
- //------------------------------------------------------------
-
-
- wrap.attr('transform', 'translate(' + margin.left + ',' +
margin.top + ')');
-
-
- //------------------------------------------------------------
- // Main Chart Component(s)
-
- pie
- .width(availableWidth)
- .height(availableHeight);
-
-
- var pieWrap = g.select('.nv-pieWrap')
- .datum(data);
-
- d3.transition(pieWrap).call(pie);
-
- //------------------------------------------------------------
-
-
- //============================================================
- // Event Handling/Dispatching (in chart's scope)
- //------------------------------------------------------------
-
- legend.dispatch.on('legendClick', function(d,i, that) {
- d.disabled = !d.disabled;
-
- if (!pie.values()(data[0]).filter(function(d) { return !d.disabled }).length) {
- pie.values()(data[0]).map(function(d) {
- d.disabled = false;
- wrap.selectAll('.nv-series').classed('disabled', false);
- return d;
- });
- }
-
- state.disabled = data[0].map(function(d) { return !!d.disabled });
- dispatch.stateChange(state);
-
- chart.update();
- });
-
- pie.dispatch.on('elementMouseout.tooltip', function(e) {
- dispatch.tooltipHide(e);
- });
-
- // Update chart from a state object passed to event handler
- dispatch.on('changeState', function(e) {
-
- if (typeof e.disabled !== 'undefined') {
- data[0].forEach(function(series,i) {
- series.disabled = e.disabled[i];
- });
-
- state.disabled = e.disabled;
- }
-
- chart.update();
- });
-
- //============================================================
-
-
- });
-
- return chart;
- }
-
- //============================================================
- // Event Handling/Dispatching (out of chart's scope)
- //------------------------------------------------------------
-
- pie.dispatch.on('elementMouseover.tooltip', function(e) {
- e.pos = [e.pos[0] + margin.left, e.pos[1] + margin.top];
- dispatch.tooltipShow(e);
- });
-
- dispatch.on('tooltipShow', function(e) {
- if (tooltips) showTooltip(e);
- });
-
- dispatch.on('tooltipHide', function() {
- if (tooltips) nv.tooltip.cleanup();
- });
-
- //============================================================
-
-
- //============================================================
- // Expose Public Variables
- //------------------------------------------------------------
-
- // expose chart's sub-components
- chart.legend = legend;
- chart.dispatch = dispatch;
- chart.pie = pie;
-
- d3.rebind(chart, pie, 'valueFormat', 'values', 'x',
'y', 'description', 'id', 'showLabels',
'donutLabelsOutside', 'pieLabelsOutside', 'donut',
'donutRatio', 'labelThreshold');
-
- 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.color = function(_) {
- if (!arguments.length) return color;
- color = nv.utils.getColor(_);
- legend.color(color);
- pie.color(color);
- return chart;
- };
-
- chart.showLegend = function(_) {
- if (!arguments.length) return showLegend;
- showLegend = _;
- return chart;
- };
-
- chart.tooltips = function(_) {
- if (!arguments.length) return tooltips;
- tooltips = _;
- return chart;
- };
-
- chart.tooltipContent = function(_) {
- if (!arguments.length) return tooltip;
- tooltip = _;
- return chart;
- };
-
- chart.state = function(_) {
- if (!arguments.length) return state;
- state = _;
- return chart;
- };
-
- chart.defaultState = function(_) {
- if (!arguments.length) return defaultState;
- defaultState = _;
- return chart;
- };
-
- chart.noData = function(_) {
- if (!arguments.length) return noData;
- noData = _;
- return chart;
- };
-
- //============================================================
-
-
- return chart;
-}
-
-nv.models.scatter = function() {
-
- //============================================================
- // Public Variables with Default Settings
- //------------------------------------------------------------
-
- var margin = {top: 0, right: 0, bottom: 0, left: 0}
- , width = 960
- , height = 500
- , color = nv.utils.defaultColor() // chooses color
- , id = Math.floor(Math.random() * 100000) //Create semi-unique ID incase
user doesn't select one
- , x = d3.scale.linear()
- , y = d3.scale.linear()
- , z = d3.scale.linear() //linear because d3.svg.shape.size is treated as
area
- , getX = function(d) { return d.x } // accessor to get the x value
- , getY = function(d) { return d.y } // accessor to get the y value
- , getSize = function(d) { return d.size || 1} // accessor to get the point size
- , getShape = function(d) { return d.shape || 'circle' } // accessor to
get point shape
- , onlyCircles = true // Set to false to use shapes
- , forceX = [] // List of numbers to Force into the X scale (ie. 0, or a max /
min, etc.)
- , forceY = [] // List of numbers to Force into the Y scale
- , forceSize = [] // List of numbers to Force into the Size scale
- , interactive = true // If true, plots a voronoi overlay for advanced point
intersection
- , pointKey = null
- , pointActive = function(d) { return !d.notActive } // any points that return false
will be filtered out
- , padData = false // If true, adds half a data points width to front and back,
for lining up a line chart with a bar chart
- , padDataOuter = .1 //outerPadding to imitate ordinal scale outer padding
- , clipEdge = false // if true, masks points within x and y scale
- , clipVoronoi = true // if true, masks each point with a circle... can turn off to
slightly increase performance
- , clipRadius = function() { return 25 } // function to get the radius for voronoi
point clips
- , xDomain = null // Override x domain (skips the calculation from data)
- , yDomain = null // Override y domain
- , sizeDomain = null // Override point size domain
- , sizeRange = null
- , singlePoint = false
- , dispatch = d3.dispatch('elementClick', 'elementMouseover',
'elementMouseout')
- , useVoronoi = true
- ;
-
- //============================================================
-
-
- //============================================================
- // Private Variables
- //------------------------------------------------------------
-
- var x0, y0, z0 // used to store previous scales
- , timeoutID
- , needsUpdate = false // Flag for when the points are visually updating, but the
interactive layer is behind, to disable tooltips
- ;
-
- //============================================================
-
-
- function chart(selection) {
- selection.each(function(data) {
- var availableWidth = width - margin.left - margin.right,
- availableHeight = height - margin.top - margin.bottom,
- container = d3.select(this);
-
- //add series index to each data point for reference
- data = data.map(function(series, i) {
- series.values = series.values.map(function(point) {
- point.series = i;
- return point;
- });
- return series;
- });
-
- //------------------------------------------------------------
- // Setup Scales
-
- // remap and flatten the data for use in calculating the scales' domains
- var seriesData = (xDomain && yDomain && sizeDomain) ? [] : // if we
know xDomain and yDomain and sizeDomain, no need to calculate.... if Size is constant
remember to set sizeDomain to speed up performance
- d3.merge(
- data.map(function(d) {
- return d.values.map(function(d,i) {
- return { x: getX(d,i), y: getY(d,i), size: getSize(d,i) }
- })
- })
- );
-
- x .domain(xDomain || d3.extent(seriesData.map(function(d) { return d.x;
}).concat(forceX)))
-
- if (padData && data[0])
- x.range([(availableWidth * padDataOuter + availableWidth) / (2
*data[0].values.length), availableWidth - availableWidth * (1 + padDataOuter) / (2 *
data[0].values.length) ]);
- //x.range([availableWidth * .5 / data[0].values.length, availableWidth *
(data[0].values.length - .5) / data[0].values.length ]);
- else
- x.range([0, availableWidth]);
-
- y .domain(yDomain || d3.extent(seriesData.map(function(d) { return d.y
}).concat(forceY)))
- .range([availableHeight, 0]);
-
- z .domain(sizeDomain || d3.extent(seriesData.map(function(d) { return d.size
}).concat(forceSize)))
- .range(sizeRange || [16, 256]);
-
- // If scale's domain don't have a range, slightly adjust to make one... so
a chart can show a single data point
- if (x.domain()[0] === x.domain()[1] || y.domain()[0] === y.domain()[1]) singlePoint
= true;
- 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]);
-
- if ( isNaN(x.domain()[0])) {
- x.domain([-1,1]);
- }
-
- if ( isNaN(y.domain()[0])) {
- y.domain([-1,1]);
- }
-
-
- x0 = x0 || x;
- y0 = y0 || y;
- z0 = z0 || z;
-
- //------------------------------------------------------------
-
-
- //------------------------------------------------------------
- // Setup containers and skeleton of chart
-
- var wrap = container.selectAll('g.nv-wrap.nv-scatter').data([data]);
- var wrapEnter = wrap.enter().append('g').attr('class', 'nvd3
nv-wrap nv-scatter nv-chart-' + id + (singlePoint ? ' nv-single-point' :
''));
- var defsEnter = wrapEnter.append('defs');
- var gEnter = wrapEnter.append('g');
- var g = wrap.select('g');
-
- gEnter.append('g').attr('class', 'nv-groups');
- gEnter.append('g').attr('class', 'nv-point-paths');
-
- wrap.attr('transform', 'translate(' + margin.left + ',' +
margin.top + ')');
-
- //------------------------------------------------------------
-
-
- defsEnter.append('clipPath')
- .attr('id', 'nv-edge-clip-' + id)
- .append('rect');
-
- wrap.select('#nv-edge-clip-' + id + ' rect')
- .attr('width', availableWidth)
- .attr('height', availableHeight);
-
- g .attr('clip-path', clipEdge ? 'url(#nv-edge-clip-' + id +
')' : '');
-
-
- function updateInteractiveLayer() {
-
- if (!interactive) return false;
-
- var eventElements;
-
- var vertices = d3.merge(data.map(function(group, groupIndex) {
- return group.values
- .map(function(point, pointIndex) {
- // *Adding noise to make duplicates very unlikely
- // *Injecting series and point index for reference
- /* *Adding a 'jitter' to the points, because there's an issue
in d3.geom.voronoi.
- */
- var pX = getX(point,pointIndex) + Math.random() * 1e-7;
- var pY = getY(point,pointIndex) + Math.random() * 1e-7;
-
- return [x(pX),
- y(pY),
- groupIndex,
- pointIndex, point]; //temp hack to add noise untill I think of a
better way so there are no duplicates
- })
- .filter(function(pointArray, pointIndex) {
- return pointActive(pointArray[4], pointIndex); // Issue #237.. move
filter to after map, so pointIndex is correct!
- })
- })
- );
-
-
-
- //inject series and point index for reference into voronoi
- if (useVoronoi === true) {
-
- if (clipVoronoi) {
- var pointClipsEnter =
wrap.select('defs').selectAll('.nv-point-clips')
- .data([id])
- .enter();
-
- pointClipsEnter.append('clipPath')
- .attr('class', 'nv-point-clips')
- .attr('id', 'nv-points-clip-' + id);
-
- var pointClips = wrap.select('#nv-points-clip-' +
id).selectAll('circle')
- .data(vertices);
- pointClips.enter().append('circle')
- .attr('r', clipRadius);
- pointClips.exit().remove();
- pointClips
- .attr('cx', function(d) { return d[0] })
- .attr('cy', function(d) { return d[1] });
-
- wrap.select('.nv-point-paths')
- .attr('clip-path', 'url(#nv-points-clip-' + id +
')');
- }
-
-
- if(vertices.length) {
- // Issue #283 - Adding 2 dummy points to the voronoi b/c voronoi requires min
3 points to work
- vertices.push([x.range()[0] - 20, y.range()[0] - 20, null, null]);
- vertices.push([x.range()[1] + 20, y.range()[1] + 20, null, null]);
- vertices.push([x.range()[0] - 20, y.range()[0] + 20, null, null]);
- vertices.push([x.range()[1] + 20, y.range()[1] - 20, null, null]);
- }
-
- var bounds = d3.geom.polygon([
- [-10,-10],
- [-10,height + 10],
- [width + 10,height + 10],
- [width + 10,-10]
- ]);
-
- var voronoi = d3.geom.voronoi(vertices).map(function(d, i) {
- return {
- 'data': bounds.clip(d),
- 'series': vertices[i][2],
- 'point': vertices[i][3]
- }
- });
-
-
- var pointPaths =
wrap.select('.nv-point-paths').selectAll('path')
- .data(voronoi);
- pointPaths.enter().append('path')
- .attr('class', function(d,i) { return 'nv-path-'+i; });
- pointPaths.exit().remove();
- pointPaths
- .attr('d', function(d) {
- if (d.data.length === 0)
- return 'M 0 0'
- else
- return 'M' + d.data.join('L') + 'Z';
- });
-
- pointPaths
- .on('click', function(d) {
- if (needsUpdate) return 0;
- var series = data[d.series],
- point = series.values[d.point];
-
- dispatch.elementClick({
- point: point,
- series: series,
- pos: [x(getX(point, d.point)) + margin.left, y(getY(point, d.point)) +
margin.top],
- seriesIndex: d.series,
- pointIndex: d.point
- });
- })
- .on('mouseover', function(d) {
- if (needsUpdate) return 0;
- var series = data[d.series],
- point = series.values[d.point];
-
- dispatch.elementMouseover({
- point: point,
- series: series,
- pos: [x(getX(point, d.point)) + margin.left, y(getY(point, d.point)) +
margin.top],
- seriesIndex: d.series,
- pointIndex: d.point
- });
- })
- .on('mouseout', function(d, i) {
- if (needsUpdate) return 0;
- var series = data[d.series],
- point = series.values[d.point];
-
- dispatch.elementMouseout({
- point: point,
- series: series,
- seriesIndex: d.series,
- pointIndex: d.point
- });
- });
-
-
- } else {
- /*
- // bring data in form needed for click handlers
- var dataWithPoints = vertices.map(function(d, i) {
- return {
- 'data': d,
- 'series': vertices[i][2],
- 'point': vertices[i][3]
- }
- });
- */
-
- // add event handlers to points instead voronoi paths
- wrap.select('.nv-groups').selectAll('.nv-group')
- .selectAll('.nv-point')
- //.data(dataWithPoints)
- //.style('pointer-events', 'auto') // recativate events,
disabled by css
- .on('click', function(d,i) {
- //nv.log('test', d, i);
- if (needsUpdate || !data[d.series]) return 0; //check if this is a dummy
point
- var series = data[d.series],
- point = series.values[i];
-
- dispatch.elementClick({
- point: point,
- series: series,
- pos: [x(getX(point, i)) + margin.left, y(getY(point, i)) +
margin.top],
- seriesIndex: d.series,
- pointIndex: i
- });
- })
- .on('mouseover', function(d,i) {
- if (needsUpdate || !data[d.series]) return 0; //check if this is a dummy
point
- var series = data[d.series],
- point = series.values[i];
-
- dispatch.elementMouseover({
- point: point,
- series: series,
- pos: [x(getX(point, i)) + margin.left, y(getY(point, i)) +
margin.top],
- seriesIndex: d.series,
- pointIndex: i
- });
- })
- .on('mouseout', function(d,i) {
- if (needsUpdate || !data[d.series]) return 0; //check if this is a dummy
point
- var series = data[d.series],
- point = series.values[i];
-
- dispatch.elementMouseout({
- point: point,
- series: series,
- seriesIndex: d.series,
- pointIndex: i
- });
- });
- }
-
- needsUpdate = false;
- }
-
- needsUpdate = true;
-
- var groups = wrap.select('.nv-groups').selectAll('.nv-group')
- .data(function(d) { return d }, function(d) { return d.key });
- groups.enter().append('g')
- .style('stroke-opacity', 1e-6)
- .style('fill-opacity', 1e-6);
- d3.transition(groups.exit())
- .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)
- .style('fill', function(d,i) { return color(d, i) })
- .style('stroke', function(d,i) { return color(d, i) })
- .style('stroke-opacity', 1)
- .style('fill-opacity', .5);
-
-
- if (onlyCircles) {
-
- var points = groups.selectAll('circle.nv-point')
- .data(function(d) { return d.values }, pointKey);
- points.enter().append('circle')
- .attr('cx', function(d,i) { return x0(getX(d,i)) })
- .attr('cy', function(d,i) { return y0(getY(d,i)) })
- .attr('r', function(d,i) { return Math.sqrt(z(getSize(d,i))/Math.PI)
});
- points.exit().remove();
- groups.exit().selectAll('path.nv-point').transition()
- .attr('cx', function(d,i) { return x(getX(d,i)) })
- .attr('cy', function(d,i) { return y(getY(d,i)) })
- .remove();
- points.each(function(d,i) {
- d3.select(this)
- .classed('nv-point', true)
- .classed('nv-point-' + i, true);
- });
- points.transition()
- .attr('cx', function(d,i) { return x(getX(d,i)) })
- .attr('cy', function(d,i) { return y(getY(d,i)) })
- .attr('r', function(d,i) { return Math.sqrt(z(getSize(d,i))/Math.PI)
});
-
- } else {
-
- var points = groups.selectAll('path.nv-point')
- .data(function(d) { return d.values });
- points.enter().append('path')
- .attr('transform', function(d,i) {
- return 'translate(' + x0(getX(d,i)) + ',' + y0(getY(d,i)) +
')'
- })
- .attr('d',
- d3.svg.symbol()
- .type(getShape)
- .size(function(d,i) { return z(getSize(d,i)) })
- );
- points.exit().remove();
- d3.transition(groups.exit().selectAll('path.nv-point'))
- .attr('transform', function(d,i) {
- return 'translate(' + x(getX(d,i)) + ',' + y(getY(d,i)) +
')'
- })
- .remove();
- points.each(function(d,i) {
- d3.select(this)
- .classed('nv-point', true)
- .classed('nv-point-' + i, true);
- });
- points.transition()
- .attr('transform', function(d,i) {
- //nv.log(d,i,getX(d,i), x(getX(d,i)));
- return 'translate(' + x(getX(d,i)) + ',' + y(getY(d,i)) +
')'
- })
- .attr('d',
- d3.svg.symbol()
- .type(getShape)
- .size(function(d,i) { return z(getSize(d,i)) })
- );
- }
-
-
- // Delay updating the invisible interactive layer for smoother animation
- clearTimeout(timeoutID); // stop repeat calls to updateInteractiveLayer
- timeoutID = setTimeout(updateInteractiveLayer, 300);
- //updateInteractiveLayer();
-
- //store old scales for use in transitions on update
- x0 = x.copy();
- y0 = y.copy();
- z0 = z.copy();
-
- });
-
- return chart;
- }
-
-
- //============================================================
- // Event Handling/Dispatching (out of chart's scope)
- //------------------------------------------------------------
-
- dispatch.on('elementMouseover.point', function(d) {
- if (interactive)
- d3.select('.nv-chart-' + id + ' .nv-series-' + d.seriesIndex +
' .nv-point-' + d.pointIndex)
- .classed('hover', true);
- });
-
- dispatch.on('elementMouseout.point', function(d) {
- if (interactive)
- d3.select('.nv-chart-' + id + ' .nv-series-' + d.seriesIndex +
' .nv-point-' + d.pointIndex)
- .classed('hover', false);
- });
-
- //============================================================
-
-
- //============================================================
- // Expose Public Variables
- //------------------------------------------------------------
-
- chart.dispatch = dispatch;
-
- chart.x = function(_) {
- if (!arguments.length) return getX;
- getX = d3.functor(_);
- return chart;
- };
-
- chart.y = function(_) {
- if (!arguments.length) return getY;
- getY = d3.functor(_);
- return chart;
- };
-
- chart.size = function(_) {
- if (!arguments.length) return getSize;
- getSize = d3.functor(_);
- 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.zScale = function(_) {
- if (!arguments.length) return z;
- z = _;
- 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.sizeDomain = function(_) {
- if (!arguments.length) return sizeDomain;
- sizeDomain = _;
- return chart;
- };
-
- chart.sizeRange = function(_) {
- if (!arguments.length) return sizeRange;
- sizeRange = _;
- 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.forceSize = function(_) {
- if (!arguments.length) return forceSize;
- forceSize = _;
- return chart;
- };
-
- chart.interactive = function(_) {
- if (!arguments.length) return interactive;
- interactive = _;
- return chart;
- };
-
- chart.pointKey = function(_) {
- if (!arguments.length) return pointKey;
- pointKey = _;
- return chart;
- };
-
- chart.pointActive = function(_) {
- if (!arguments.length) return pointActive;
- pointActive = _;
- return chart;
- };
-
- chart.padData = function(_) {
- if (!arguments.length) return padData;
- padData = _;
- return chart;
- };
-
- chart.padDataOuter = function(_) {
- if (!arguments.length) return padDataOuter;
- padDataOuter = _;
- return chart;
- };
-
- chart.clipEdge = function(_) {
- if (!arguments.length) return clipEdge;
- clipEdge = _;
- return chart;
- };
-
- chart.clipVoronoi= function(_) {
- if (!arguments.length) return clipVoronoi;
- clipVoronoi = _;
- return chart;
- };
-
- chart.useVoronoi= function(_) {
- if (!arguments.length) return useVoronoi;
- useVoronoi = _;
- if (useVoronoi === false) {
- clipVoronoi = false;
- }
- return chart;
- };
-
- chart.clipRadius = function(_) {
- if (!arguments.length) return clipRadius;
- clipRadius = _;
- return chart;
- };
-
- chart.color = function(_) {
- if (!arguments.length) return color;
- color = nv.utils.getColor(_);
- return chart;
- };
-
- chart.shape = function(_) {
- if (!arguments.length) return getShape;
- getShape = _;
- return chart;
- };
-
- chart.onlyCircles = function(_) {
- if (!arguments.length) return onlyCircles;
- onlyCircles = _;
- return chart;
- };
-
- chart.id = function(_) {
- if (!arguments.length) return id;
- id = _;
- return chart;
- };
-
- chart.singlePoint = function(_) {
- if (!arguments.length) return singlePoint;
- singlePoint = _;
- return chart;
- };
-
- //============================================================
-
-
- return chart;
-}
-
-nv.models.scatterChart = function() {
-
- //============================================================
- // Public Variables with Default Settings
- //------------------------------------------------------------
-
- var scatter = nv.models.scatter()
- , xAxis = nv.models.axis()
- , yAxis = nv.models.axis()
- , legend = nv.models.legend()
- , controls = nv.models.legend()
- , distX = nv.models.distribution()
- , distY = nv.models.distribution()
- ;
-
- var margin = {top: 30, right: 20, bottom: 50, left: 75}
- , width = null
- , height = null
- , color = nv.utils.defaultColor()
- , x = d3.fisheye ? d3.fisheye.scale(d3.scale.linear).distortion(0) :
scatter.xScale()
- , y = d3.fisheye ? d3.fisheye.scale(d3.scale.linear).distortion(0) :
scatter.yScale()
- , xPadding = 0
- , yPadding = 0
- , showDistX = false
- , showDistY = false
- , showLegend = true
- , showControls = !!d3.fisheye
- , fisheye = 0
- , pauseFisheye = false
- , tooltips = true
- , tooltipX = function(key, x, y) { return '<strong>' + x +
'</strong>' }
- , tooltipY = function(key, x, y) { return '<strong>' + y +
'</strong>' }
- //, tooltip = function(key, x, y) { return '<h3>' + key +
'</h3>' }
- , tooltip = null
- , state = {}
- , defaultState = null
- , dispatch = d3.dispatch('tooltipShow', 'tooltipHide',
'stateChange', 'changeState')
- , noData = "No Data Available."
- ;
-
- scatter
- .xScale(x)
- .yScale(y)
- ;
- xAxis
- .orient('bottom')
- .tickPadding(10)
- ;
- yAxis
- .orient('left')
- .tickPadding(10)
- ;
- distX
- .axis('x')
- ;
- distY
- .axis('y')
- ;
-
- //============================================================
-
-
- //============================================================
- // Private Variables
- //------------------------------------------------------------
-
- var x0, y0;
-
- var showTooltip = function(e, offsetElement) {
- //TODO: make tooltip style an option between single or dual on axes (maybe on all
charts with axes?)
-
- var left = e.pos[0] + ( offsetElement.offsetLeft || 0 ),
- top = e.pos[1] + ( offsetElement.offsetTop || 0),
- leftX = e.pos[0] + ( offsetElement.offsetLeft || 0 ),
- topX = y.range()[0] + margin.top + ( offsetElement.offsetTop || 0),
- leftY = x.range()[0] + margin.left + ( offsetElement.offsetLeft || 0 ),
- topY = e.pos[1] + ( offsetElement.offsetTop || 0),
- xVal = xAxis.tickFormat()(scatter.x()(e.point, e.pointIndex)),
- yVal = yAxis.tickFormat()(scatter.y()(e.point, e.pointIndex));
-
- if( tooltipX != null )
- nv.tooltip.show([leftX, topX], tooltipX(e.series.key, xVal, yVal, e, chart),
'n', 1, offsetElement, 'x-nvtooltip');
- if( tooltipY != null )
- nv.tooltip.show([leftY, topY], tooltipY(e.series.key, xVal, yVal, e, chart),
'e', 1, offsetElement, 'y-nvtooltip');
- if( tooltip != null )
- nv.tooltip.show([left, top], tooltip(e.series.key, xVal, yVal, e, chart),
e.value < 0 ? 'n' : 's', null, offsetElement);
- };
-
- var controlsData = [
- { key: 'Magnify', disabled: true }
- ];
-
- //============================================================
-
-
- function chart(selection) {
- selection.each(function(data) {
- var container = d3.select(this),
- that = this;
-
- var availableWidth = (width || parseInt(container.style('width')) || 960)
- - margin.left - margin.right,
- availableHeight = (height || parseInt(container.style('height')) ||
400)
- - margin.top - margin.bottom;
-
- chart.update = function() { container.transition().call(chart); };
- // chart.container = this;
-
- //set state.disabled
- state.disabled = data.map(function(d) { return !!d.disabled });
-
- if (!defaultState) {
- var key;
- defaultState = {};
- for (key in state) {
- if (state[key] instanceof Array)
- defaultState[key] = state[key].slice(0);
- else
- defaultState[key] = state[key];
- }
- }
-
- //------------------------------------------------------------
- // Display noData message if there's nothing to show.
-
- if (!data || !data.length || !data.filter(function(d) { return d.values.length
}).length) {
- var noDataText = container.selectAll('.nv-noData').data([noData]);
-
- noDataText.enter().append('text')
- .attr('class', 'nvd3 nv-noData')
- .attr('dy', '-.7em')
- .style('text-anchor', 'middle');
-
- noDataText
- .attr('x', margin.left + availableWidth / 2)
- .attr('y', margin.top + availableHeight / 2)
- .text(function(d) { return d });
-
- return chart;
- } else {
- container.selectAll('.nv-noData').remove();
- }
-
- //------------------------------------------------------------
-
-
- //------------------------------------------------------------
- // Setup Scales
-
- x0 = x0 || x;
- y0 = y0 || y;
-
- //------------------------------------------------------------
-
-
- //------------------------------------------------------------
- // Setup containers and skeleton of chart
-
- var wrap = container.selectAll('g.nv-wrap.nv-scatterChart').data([data]);
- var wrapEnter = wrap.enter().append('g').attr('class', 'nvd3
nv-wrap nv-scatterChart nv-chart-' + scatter.id());
- var gEnter = wrapEnter.append('g');
- var g = wrap.select('g');
-
- // background for pointer events
- gEnter.append('rect').attr('class', 'nvd3 nv-background');
-
- gEnter.append('g').attr('class', 'nv-x nv-axis');
- gEnter.append('g').attr('class', 'nv-y nv-axis');
- gEnter.append('g').attr('class', 'nv-scatterWrap');
- gEnter.append('g').attr('class', 'nv-distWrap');
- gEnter.append('g').attr('class', 'nv-legendWrap');
- gEnter.append('g').attr('class', 'nv-controlsWrap');
-
- //------------------------------------------------------------
-
-
- //------------------------------------------------------------
- // Legend
-
- if (showLegend) {
- legend.width( availableWidth / 2 );
-
- wrap.select('.nv-legendWrap')
- .datum(data)
- .call(legend);
-
- if ( margin.top != legend.height()) {
- margin.top = legend.height();
- availableHeight = (height || parseInt(container.style('height')) ||
400)
- - margin.top - margin.bottom;
- }
-
- wrap.select('.nv-legendWrap')
- .attr('transform', 'translate(' + (availableWidth / 2) +
',' + (-margin.top) +')');
- }
-
- //------------------------------------------------------------
-
-
- //------------------------------------------------------------
- // Controls
-
- if (showControls) {
- controls.width(180).color(['#444']);
- g.select('.nv-controlsWrap')
- .datum(controlsData)
- .attr('transform', 'translate(0,' + (-margin.top)
+')')
- .call(controls);
- }
-
- //------------------------------------------------------------
-
-
- wrap.attr('transform', 'translate(' + margin.left + ',' +
margin.top + ')');
-
-
- //------------------------------------------------------------
- // Main Chart Component(s)
-
- scatter
- .width(availableWidth)
- .height(availableHeight)
- .color(data.map(function(d,i) {
- return d.color || color(d, i);
- }).filter(function(d,i) { return !data[i].disabled }))
- .xDomain(null)
- .yDomain(null)
-
- wrap.select('.nv-scatterWrap')
- .datum(data.filter(function(d) { return !d.disabled }))
- .call(scatter);
-
-
- //Adjust for x and y padding
- if (xPadding) {
- var xRange = x.domain()[1] - x.domain()[0];
- scatter.xDomain([x.domain()[0] - (xPadding * xRange), x.domain()[1] + (xPadding *
xRange)]);
- }
-
- if (yPadding) {
- var yRange = y.domain()[1] - y.domain()[0];
- scatter.yDomain([y.domain()[0] - (yPadding * yRange), y.domain()[1] + (yPadding *
yRange)]);
- }
-
- wrap.select('.nv-scatterWrap')
- .datum(data.filter(function(d) { return !d.disabled }))
- .call(scatter);
-
- //------------------------------------------------------------
-
-
- //------------------------------------------------------------
- // Setup Axes
-
- xAxis
- .scale(x)
- .ticks( xAxis.ticks() && xAxis.ticks().length ? xAxis.ticks() :
availableWidth / 100 )
- .tickSize( -availableHeight , 0);
-
- g.select('.nv-x.nv-axis')
- .attr('transform', 'translate(0,' + y.range()[0] +
')')
- .call(xAxis);
-
-
- yAxis
- .scale(y)
- .ticks( yAxis.ticks() && yAxis.ticks().length ? yAxis.ticks() :
availableHeight / 36 )
- .tickSize( -availableWidth, 0);
-
- g.select('.nv-y.nv-axis')
- .call(yAxis);
-
-
- if (showDistX) {
- distX
- .getData(scatter.x())
- .scale(x)
- .width(availableWidth)
- .color(data.map(function(d,i) {
- return d.color || color(d, i);
- }).filter(function(d,i) { return !data[i].disabled }));
- gEnter.select('.nv-distWrap').append('g')
- .attr('class', 'nv-distributionX');
- g.select('.nv-distributionX')
- .attr('transform', 'translate(0,' + y.range()[0] +
')')
- .datum(data.filter(function(d) { return !d.disabled }))
- .call(distX);
- }
-
- if (showDistY) {
- distY
- .getData(scatter.y())
- .scale(y)
- .width(availableHeight)
- .color(data.map(function(d,i) {
- return d.color || color(d, i);
- }).filter(function(d,i) { return !data[i].disabled }));
- gEnter.select('.nv-distWrap').append('g')
- .attr('class', 'nv-distributionY');
- g.select('.nv-distributionY')
- .attr('transform', 'translate(-' + distY.size() +
',0)')
- .datum(data.filter(function(d) { return !d.disabled }))
- .call(distY);
- }
-
- //------------------------------------------------------------
-
-
-
-
- if (d3.fisheye) {
- g.select('.nv-background')
- .attr('width', availableWidth)
- .attr('height', availableHeight);
-
- g.select('.nv-background').on('mousemove', updateFisheye);
- g.select('.nv-background').on('click', function() { pauseFisheye
= !pauseFisheye;});
- scatter.dispatch.on('elementClick.freezeFisheye', function() {
- pauseFisheye = !pauseFisheye;
- });
- }
-
-
- function updateFisheye() {
- if (pauseFisheye) {
- g.select('.nv-point-paths').style('pointer-events',
'all');
- return false;
- }
-
- g.select('.nv-point-paths').style('pointer-events',
'none' );
-
- var mouse = d3.mouse(this);
- x.distortion(fisheye).focus(mouse[0]);
- y.distortion(fisheye).focus(mouse[1]);
-
- g.select('.nv-scatterWrap')
- .call(scatter);
-
- g.select('.nv-x.nv-axis').call(xAxis);
- g.select('.nv-y.nv-axis').call(yAxis);
- g.select('.nv-distributionX')
- .datum(data.filter(function(d) { return !d.disabled }))
- .call(distX);
- g.select('.nv-distributionY')
- .datum(data.filter(function(d) { return !d.disabled }))
- .call(distY);
- }
-
-
-
- //============================================================
- // Event Handling/Dispatching (in chart's scope)
- //------------------------------------------------------------
-
- controls.dispatch.on('legendClick', function(d,i) {
- d.disabled = !d.disabled;
-
- fisheye = d.disabled ? 0 : 2.5;
- g.select('.nv-background') .style('pointer-events', d.disabled ?
'none' : 'all');
- g.select('.nv-point-paths').style('pointer-events', d.disabled ?
'all' : 'none' );
-
- if (d.disabled) {
- x.distortion(fisheye).focus(0);
- y.distortion(fisheye).focus(0);
-
- g.select('.nv-scatterWrap').call(scatter);
- g.select('.nv-x.nv-axis').call(xAxis);
- g.select('.nv-y.nv-axis').call(yAxis);
- } else {
- pauseFisheye = false;
- }
-
- chart.update();
- });
-
- legend.dispatch.on('legendClick', function(d,i, that) {
- 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 });
- dispatch.stateChange(state);
-
- 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;
- });
- d.disabled = false;
-
- state.disabled = data.map(function(d) { return !!d.disabled });
- dispatch.stateChange(state);
- chart.update();
- });
-
-
- /*
- legend.dispatch.on('legendMouseover', function(d, i) {
- d.hover = true;
- chart(selection);
- });
-
- legend.dispatch.on('legendMouseout', function(d, i) {
- d.hover = false;
- chart(selection);
- });
- */
-
- scatter.dispatch.on('elementMouseover.tooltip', function(e) {
- d3.select('.nv-chart-' + scatter.id() + ' .nv-series-' +
e.seriesIndex + ' .nv-distx-' + e.pointIndex)
- .attr('y1', function(d,i) { return e.pos[1] - availableHeight;});
- d3.select('.nv-chart-' + scatter.id() + ' .nv-series-' +
e.seriesIndex + ' .nv-disty-' + e.pointIndex)
- .attr('x2', e.pos[0] + distX.size());
-
- e.pos = [e.pos[0] + margin.left, e.pos[1] + margin.top];
- dispatch.tooltipShow(e);
- });
-
- dispatch.on('tooltipShow', function(e) {
- if (tooltips) showTooltip(e, that.parentNode);
- });
-
- // Update chart from a state object passed to event handler
- dispatch.on('changeState', function(e) {
-
- if (typeof e.disabled !== 'undefined') {
- data.forEach(function(series,i) {
- series.disabled = e.disabled[i];
- });
-
- state.disabled = e.disabled;
- }
-
- chart.update();
- });
-
- //============================================================
-
-
- //store old scales for use in transitions on update
- x0 = x.copy();
- y0 = y.copy();
-
-
- });
-
- return chart;
- }
-
-
- //============================================================
- // Event Handling/Dispatching (out of chart's scope)
- //------------------------------------------------------------
-
- scatter.dispatch.on('elementMouseout.tooltip', function(e) {
- dispatch.tooltipHide(e);
-
- d3.select('.nv-chart-' + scatter.id() + ' .nv-series-' +
e.seriesIndex + ' .nv-distx-' + e.pointIndex)
- .attr('y1', 0);
- d3.select('.nv-chart-' + scatter.id() + ' .nv-series-' +
e.seriesIndex + ' .nv-disty-' + e.pointIndex)
- .attr('x2', distY.size());
- });
- dispatch.on('tooltipHide', function() {
- if (tooltips) nv.tooltip.cleanup();
- });
-
- //============================================================
-
-
- //============================================================
- // Expose Public Variables
- //------------------------------------------------------------
-
- // expose chart's sub-components
- chart.dispatch = dispatch;
- chart.scatter = scatter;
- chart.legend = legend;
- chart.controls = controls;
- chart.xAxis = xAxis;
- chart.yAxis = yAxis;
- chart.distX = distX;
- chart.distY = distY;
-
- d3.rebind(chart, scatter, 'id', 'interactive', 'pointActive',
'x', 'y', 'shape', 'size', 'xScale',
'yScale', 'zScale', 'xDomain', 'yDomain',
'sizeDomain', 'sizeRange', 'forceX', 'forceY',
'forceSize', 'clipVoronoi', 'clipRadius', 'useVoronoi');
-
- 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.color = function(_) {
- if (!arguments.length) return color;
- color = nv.utils.getColor(_);
- legend.color(color);
- distX.color(color);
- distY.color(color);
- return chart;
- };
-
- chart.showDistX = function(_) {
- if (!arguments.length) return showDistX;
- showDistX = _;
- return chart;
- };
-
- chart.showDistY = function(_) {
- if (!arguments.length) return showDistY;
- showDistY = _;
- return chart;
- };
-
- chart.showControls = function(_) {
- if (!arguments.length) return showControls;
- showControls = _;
- return chart;
- };
-
- chart.showLegend = function(_) {
- if (!arguments.length) return showLegend;
- showLegend = _;
- return chart;
- };
-
- chart.fisheye = function(_) {
- if (!arguments.length) return fisheye;
- fisheye = _;
- return chart;
- };
-
- chart.xPadding = function(_) {
- if (!arguments.length) return xPadding;
- xPadding = _;
- return chart;
- };
-
- chart.yPadding = function(_) {
- if (!arguments.length) return yPadding;
- yPadding = _;
- return chart;
- };
-
- chart.tooltips = function(_) {
- if (!arguments.length) return tooltips;
- tooltips = _;
- return chart;
- };
-
- chart.tooltipContent = function(_) {
- if (!arguments.length) return tooltip;
- tooltip = _;
- return chart;
- };
-
- chart.tooltipXContent = function(_) {
- if (!arguments.length) return tooltipX;
- tooltipX = _;
- return chart;
- };
-
- chart.tooltipYContent = function(_) {
- if (!arguments.length) return tooltipY;
- tooltipY = _;
- return chart;
- };
-
- chart.state = function(_) {
- if (!arguments.length) return state;
- state = _;
- return chart;
- };
-
- chart.defaultState = function(_) {
- if (!arguments.length) return defaultState;
- defaultState = _;
- return chart;
- };
-
- chart.noData = function(_) {
- if (!arguments.length) return noData;
- noData = _;
- return chart;
- };
-
- //============================================================
-
-
- return chart;
-}
-
-nv.models.scatterPlusLineChart = function() {
-
- //============================================================
- // Public Variables with Default Settings
- //------------------------------------------------------------
-
- var scatter = nv.models.scatter()
- , xAxis = nv.models.axis()
- , yAxis = nv.models.axis()
- , legend = nv.models.legend()
- , controls = nv.models.legend()
- , distX = nv.models.distribution()
- , distY = nv.models.distribution()
- ;
-
- var margin = {top: 30, right: 20, bottom: 50, left: 75}
- , width = null
- , height = null
- , color = nv.utils.defaultColor()
- , x = d3.fisheye ? d3.fisheye.scale(d3.scale.linear).distortion(0) :
scatter.xScale()
- , y = d3.fisheye ? d3.fisheye.scale(d3.scale.linear).distortion(0) :
scatter.yScale()
- , showDistX = false
- , showDistY = false
- , showLegend = true
- , showControls = !!d3.fisheye
- , fisheye = 0
- , pauseFisheye = false
- , tooltips = true
- , tooltipX = function(key, x, y) { return '<strong>' + x +
'</strong>' }
- , tooltipY = function(key, x, y) { return '<strong>' + y +
'</strong>' }
- , tooltip = function(key, x, y, date) { return '<h3>' + key +
'</h3>'
- + '<p>' + date +
'</p>' }
- //, tooltip = null
- , state = {}
- , defaultState = null
- , dispatch = d3.dispatch('tooltipShow', 'tooltipHide',
'stateChange', 'changeState')
- , noData = "No Data Available."
- ;
-
- scatter
- .xScale(x)
- .yScale(y)
- ;
- xAxis
- .orient('bottom')
- .tickPadding(10)
- ;
- yAxis
- .orient('left')
- .tickPadding(10)
- ;
- distX
- .axis('x')
- ;
- distY
- .axis('y')
- ;
-
- //============================================================
-
-
- //============================================================
- // Private Variables
- //------------------------------------------------------------
-
- var x0, y0;
-
- var showTooltip = function(e, offsetElement) {
- //TODO: make tooltip style an option between single or dual on axes (maybe on all
charts with axes?)
-
- var left = e.pos[0] + ( offsetElement.offsetLeft || 0 ),
- top = e.pos[1] + ( offsetElement.offsetTop || 0),
- leftX = e.pos[0] + ( offsetElement.offsetLeft || 0 ),
- topX = y.range()[0] + margin.top + ( offsetElement.offsetTop || 0),
- leftY = x.range()[0] + margin.left + ( offsetElement.offsetLeft || 0 ),
- topY = e.pos[1] + ( offsetElement.offsetTop || 0),
- xVal = xAxis.tickFormat()(scatter.x()(e.point, e.pointIndex)),
- yVal = yAxis.tickFormat()(scatter.y()(e.point, e.pointIndex));
-
- if( tooltipX != null )
- nv.tooltip.show([leftX, topX], tooltipX(e.series.key, xVal, yVal, e, chart),
'n', 1, offsetElement, 'x-nvtooltip');
- if( tooltipY != null )
- nv.tooltip.show([leftY, topY], tooltipY(e.series.key, xVal, yVal, e, chart),
'e', 1, offsetElement, 'y-nvtooltip');
- if( tooltip != null )
- nv.tooltip.show([left, top], tooltip(e.series.key, xVal, yVal, e.point.tooltip,
e, chart), e.value < 0 ? 'n' : 's', null, offsetElement);
- };
-
- var controlsData = [
- { key: 'Magnify', disabled: true }
- ];
-
- //============================================================
-
-
- function chart(selection) {
- selection.each(function(data) {
- var container = d3.select(this),
- that = this;
-
- var availableWidth = (width || parseInt(container.style('width')) || 960)
- - margin.left - margin.right,
- availableHeight = (height || parseInt(container.style('height')) ||
400)
- - margin.top - margin.bottom;
-
- chart.update = function() { container.transition().call(chart); };
- chart.container = this;
-
- //set state.disabled
- state.disabled = data.map(function(d) { return !!d.disabled });
-
- if (!defaultState) {
- var key;
- defaultState = {};
- for (key in state) {
- if (state[key] instanceof Array)
- defaultState[key] = state[key].slice(0);
- else
- defaultState[key] = state[key];
- }
- }
-
- //------------------------------------------------------------
- // Display noData message if there's nothing to show.
-
- if (!data || !data.length || !data.filter(function(d) { return d.values.length
}).length) {
- var noDataText = container.selectAll('.nv-noData').data([noData]);
-
- noDataText.enter().append('text')
- .attr('class', 'nvd3 nv-noData')
- .attr('dy', '-.7em')
- .style('text-anchor', 'middle');
-
- noDataText
- .attr('x', margin.left + availableWidth / 2)
- .attr('y', margin.top + availableHeight / 2)
- .text(function(d) { return d });
-
- return chart;
- } else {
- container.selectAll('.nv-noData').remove();
- }
-
- //------------------------------------------------------------
-
-
- //------------------------------------------------------------
- // Setup Scales
-
- x = scatter.xScale();
- y = scatter.yScale();
-
- x0 = x0 || x;
- y0 = y0 || y;
-
- //------------------------------------------------------------
-
-
- //------------------------------------------------------------
- // Setup containers and skeleton of chart
-
- var wrap = container.selectAll('g.nv-wrap.nv-scatterChart').data([data]);
- var wrapEnter = wrap.enter().append('g').attr('class', 'nvd3
nv-wrap nv-scatterChart nv-chart-' + scatter.id());
- var gEnter = wrapEnter.append('g');
- var g = wrap.select('g')
-
- // background for pointer events
- gEnter.append('rect').attr('class', 'nvd3 nv-background')
-
- gEnter.append('g').attr('class', 'nv-x nv-axis');
- gEnter.append('g').attr('class', 'nv-y nv-axis');
- gEnter.append('g').attr('class', 'nv-scatterWrap');
- gEnter.append('g').attr('class',
'nv-regressionLinesWrap');
- gEnter.append('g').attr('class', 'nv-distWrap');
- gEnter.append('g').attr('class', 'nv-legendWrap');
- gEnter.append('g').attr('class', 'nv-controlsWrap');
-
- wrap.attr('transform', 'translate(' + margin.left + ',' +
margin.top + ')');
-
- //------------------------------------------------------------
-
-
- //------------------------------------------------------------
- // Legend
-
- if (showLegend) {
- legend.width( availableWidth / 2 );
-
- wrap.select('.nv-legendWrap')
- .datum(data)
- .call(legend);
-
- if ( margin.top != legend.height()) {
- margin.top = legend.height();
- availableHeight = (height || parseInt(container.style('height')) ||
400)
- - margin.top - margin.bottom;
- }
-
- wrap.select('.nv-legendWrap')
- .attr('transform', 'translate(' + (availableWidth / 2) +
',' + (-margin.top) +')');
- }
-
- //------------------------------------------------------------
-
-
- //------------------------------------------------------------
- // Controls
-
- if (showControls) {
- controls.width(180).color(['#444']);
- g.select('.nv-controlsWrap')
- .datum(controlsData)
- .attr('transform', 'translate(0,' + (-margin.top)
+')')
- .call(controls);
- }
-
- //------------------------------------------------------------
-
-
- //------------------------------------------------------------
- // Main Chart Component(s)
-
- scatter
- .width(availableWidth)
- .height(availableHeight)
- .color(data.map(function(d,i) {
- return d.color || color(d, i);
- }).filter(function(d,i) { return !data[i].disabled }))
-
- wrap.select('.nv-scatterWrap')
- .datum(data.filter(function(d) { return !d.disabled }))
- .call(scatter);
-
-
- wrap.select('.nv-regressionLinesWrap')
- .attr('clip-path', 'url(#nv-edge-clip-' + scatter.id() +
')');
-
- var regWrap =
wrap.select('.nv-regressionLinesWrap').selectAll('.nv-regLines')
- .data(function(d) { return d });
-
- var reglines = regWrap.enter()
- .append('g').attr('class', 'nv-regLines')
- .append('line').attr('class',
'nv-regLine')
- .style('stroke-opacity', 0);
-
- //d3.transition(regWrap.selectAll('.nv-regLines line'))
- regWrap.selectAll('.nv-regLines line')
- .attr('x1', x.range()[0])
- .attr('x2', x.range()[1])
- .attr('y1', function(d,i) { return y(x.domain()[0] * d.slope +
d.intercept) })
- .attr('y2', function(d,i) { return y(x.domain()[1] * d.slope +
d.intercept) })
- .style('stroke', function(d,i,j) { return color(d,j) })
- .style('stroke-opacity', function(d,i) {
- return (d.disabled || typeof d.slope === 'undefined' || typeof
d.intercept === 'undefined') ? 0 : 1
- });
-
-
- //------------------------------------------------------------
-
-
- //------------------------------------------------------------
- // Setup Axes
-
- xAxis
- .scale(x)
- .ticks( xAxis.ticks() ? xAxis.ticks() : availableWidth / 100 )
- .tickSize( -availableHeight , 0);
-
- g.select('.nv-x.nv-axis')
- .attr('transform', 'translate(0,' + y.range()[0] +
')')
- .call(xAxis);
-
-
- yAxis
- .scale(y)
- .ticks( yAxis.ticks() ? yAxis.ticks() : availableHeight / 36 )
- .tickSize( -availableWidth, 0);
-
- g.select('.nv-y.nv-axis')
- .call(yAxis);
-
-
- if (showDistX) {
- distX
- .getData(scatter.x())
- .scale(x)
- .width(availableWidth)
- .color(data.map(function(d,i) {
- return d.color || color(d, i);
- }).filter(function(d,i) { return !data[i].disabled }));
- gEnter.select('.nv-distWrap').append('g')
- .attr('class', 'nv-distributionX');
- g.select('.nv-distributionX')
- .attr('transform', 'translate(0,' + y.range()[0] +
')')
- .datum(data.filter(function(d) { return !d.disabled }))
- .call(distX);
- }
-
- if (showDistY) {
- distY
- .getData(scatter.y())
- .scale(y)
- .width(availableHeight)
- .color(data.map(function(d,i) {
- return d.color || color(d, i);
- }).filter(function(d,i) { return !data[i].disabled }));
- gEnter.select('.nv-distWrap').append('g')
- .attr('class', 'nv-distributionY');
- g.select('.nv-distributionY')
- .attr('transform', 'translate(-' + distY.size() +
',0)')
- .datum(data.filter(function(d) { return !d.disabled }))
- .call(distY);
- }
-
- //------------------------------------------------------------
-
-
-
-
- if (d3.fisheye) {
- g.select('.nv-background')
- .attr('width', availableWidth)
- .attr('height', availableHeight);
-
- g.select('.nv-background').on('mousemove', updateFisheye);
- g.select('.nv-background').on('click', function() { pauseFisheye
= !pauseFisheye;});
- scatter.dispatch.on('elementClick.freezeFisheye', function() {
- pauseFisheye = !pauseFisheye;
- });
- }
-
-
- function updateFisheye() {
- if (pauseFisheye) {
- g.select('.nv-point-paths').style('pointer-events',
'all');
- return false;
- }
-
- g.select('.nv-point-paths').style('pointer-events',
'none' );
-
- var mouse = d3.mouse(this);
- x.distortion(fisheye).focus(mouse[0]);
- y.distortion(fisheye).focus(mouse[1]);
-
- g.select('.nv-scatterWrap')
- .datum(data.filter(function(d) { return !d.disabled }))
- .call(scatter);
- g.select('.nv-x.nv-axis').call(xAxis);
- g.select('.nv-y.nv-axis').call(yAxis);
- g.select('.nv-distributionX')
- .datum(data.filter(function(d) { return !d.disabled }))
- .call(distX);
- g.select('.nv-distributionY')
- .datum(data.filter(function(d) { return !d.disabled }))
- .call(distY);
- }
-
-
-
- //============================================================
- // Event Handling/Dispatching (in chart's scope)
- //------------------------------------------------------------
-
- controls.dispatch.on('legendClick', function(d,i) {
- d.disabled = !d.disabled;
-
- fisheye = d.disabled ? 0 : 2.5;
- g.select('.nv-background') .style('pointer-events', d.disabled ?
'none' : 'all');
- g.select('.nv-point-paths').style('pointer-events', d.disabled ?
'all' : 'none' );
-
- if (d.disabled) {
- x.distortion(fisheye).focus(0);
- y.distortion(fisheye).focus(0);
-
- g.select('.nv-scatterWrap').call(scatter);
- g.select('.nv-x.nv-axis').call(xAxis);
- g.select('.nv-y.nv-axis').call(yAxis);
- } else {
- pauseFisheye = false;
- }
-
- chart.update();
- });
-
- legend.dispatch.on('legendClick', function(d,i, that) {
- 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 });
- dispatch.stateChange(state);
-
- 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;
- });
- d.disabled = false;
-
- state.disabled = data.map(function(d) { return !!d.disabled });
- dispatch.stateChange(state);
- chart.update();
- });
-
-
- /*
- legend.dispatch.on('legendMouseover', function(d, i) {
- d.hover = true;
- chart(selection);
- });
-
- legend.dispatch.on('legendMouseout', function(d, i) {
- d.hover = false;
- chart(selection);
- });
- */
-
- scatter.dispatch.on('elementMouseover.tooltip', function(e) {
- d3.select('.nv-chart-' + scatter.id() + ' .nv-series-' +
e.seriesIndex + ' .nv-distx-' + e.pointIndex)
- .attr('y1', e.pos[1] - availableHeight);
- d3.select('.nv-chart-' + scatter.id() + ' .nv-series-' +
e.seriesIndex + ' .nv-disty-' + e.pointIndex)
- .attr('x2', e.pos[0] + distX.size());
-
- e.pos = [e.pos[0] + margin.left, e.pos[1] + margin.top];
- dispatch.tooltipShow(e);
- });
-
- dispatch.on('tooltipShow', function(e) {
- if (tooltips) showTooltip(e, that.parentNode);
- });
-
- // Update chart from a state object passed to event handler
- dispatch.on('changeState', function(e) {
-
- if (typeof e.disabled !== 'undefined') {
- data.forEach(function(series,i) {
- series.disabled = e.disabled[i];
- });
-
- state.disabled = e.disabled;
- }
-
- chart.update();
- });
-
- //============================================================
-
-
- //store old scales for use in transitions on update
- x0 = x.copy();
- y0 = y.copy();
-
-
- });
-
- return chart;
- }
-
-
- //============================================================
- // Event Handling/Dispatching (out of chart's scope)
- //------------------------------------------------------------
-
- scatter.dispatch.on('elementMouseout.tooltip', function(e) {
- dispatch.tooltipHide(e);
-
- d3.select('.nv-chart-' + scatter.id() + ' .nv-series-' +
e.seriesIndex + ' .nv-distx-' + e.pointIndex)
- .attr('y1', 0);
- d3.select('.nv-chart-' + scatter.id() + ' .nv-series-' +
e.seriesIndex + ' .nv-disty-' + e.pointIndex)
- .attr('x2', distY.size());
- });
- dispatch.on('tooltipHide', function() {
- if (tooltips) nv.tooltip.cleanup();
- });
-
- //============================================================
-
-
- //============================================================
- // Expose Public Variables
- //------------------------------------------------------------
-
- // expose chart's sub-components
- chart.dispatch = dispatch;
- chart.scatter = scatter;
- chart.legend = legend;
- chart.controls = controls;
- chart.xAxis = xAxis;
- chart.yAxis = yAxis;
- chart.distX = distX;
- chart.distY = distY;
-
- d3.rebind(chart, scatter, 'id', 'interactive', 'pointActive',
'x', 'y', 'shape', 'size', 'xScale',
'yScale', 'zScale', 'xDomain', 'yDomain',
'sizeDomain', 'sizeRange', 'forceX', 'forceY',
'forceSize', 'clipVoronoi', 'clipRadius', 'useVoronoi');
-
- 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.color = function(_) {
- if (!arguments.length) return color;
- color = nv.utils.getColor(_);
- legend.color(color);
- distX.color(color);
- distY.color(color);
- return chart;
- };
-
- chart.showDistX = function(_) {
- if (!arguments.length) return showDistX;
- showDistX = _;
- return chart;
- };
-
- chart.showDistY = function(_) {
- if (!arguments.length) return showDistY;
- showDistY = _;
- return chart;
- };
-
- chart.showControls = function(_) {
- if (!arguments.length) return showControls;
- showControls = _;
- return chart;
- };
-
- chart.showLegend = function(_) {
- if (!arguments.length) return showLegend;
- showLegend = _;
- return chart;
- };
-
- chart.fisheye = function(_) {
- if (!arguments.length) return fisheye;
- fisheye = _;
- return chart;
- };
-
- chart.tooltips = function(_) {
- if (!arguments.length) return tooltips;
- tooltips = _;
- return chart;
- };
-
- chart.tooltipContent = function(_) {
- if (!arguments.length) return tooltip;
- tooltip = _;
- return chart;
- };
-
- chart.tooltipXContent = function(_) {
- if (!arguments.length) return tooltipX;
- tooltipX = _;
- return chart;
- };
-
- chart.tooltipYContent = function(_) {
- if (!arguments.length) return tooltipY;
- tooltipY = _;
- return chart;
- };
-
- chart.state = function(_) {
- if (!arguments.length) return state;
- state = _;
- return chart;
- };
-
- chart.defaultState = function(_) {
- if (!arguments.length) return defaultState;
- defaultState = _;
- return chart;
- };
-
- chart.noData = function(_) {
- if (!arguments.length) return noData;
- noData = _;
- return chart;
- };
-
- //============================================================
-
-
- return chart;
-}
-
-nv.models.sparkline = function() {
-
- //============================================================
- // Public Variables with Default Settings
- //------------------------------------------------------------
-
- var margin = {top: 2, right: 0, bottom: 2, left: 0}
- , width = 400
- , height = 32
- , animate = true
- , x = d3.scale.linear()
- , y = d3.scale.linear()
- , getX = function(d) { return d.x }
- , getY = function(d) { return d.y }
- , color = nv.utils.getColor(['#000'])
- , xDomain
- , yDomain
- ;
-
- //============================================================
-
-
- function chart(selection) {
- selection.each(function(data) {
- var availableWidth = width - margin.left - margin.right,
- availableHeight = height - margin.top - margin.bottom,
- container = d3.select(this);
-
-
- //------------------------------------------------------------
- // Setup Scales
-
- x .domain(xDomain || d3.extent(data, getX ))
- .range([0, availableWidth]);
-
- y .domain(yDomain || d3.extent(data, getY ))
- .range([availableHeight, 0]);
-
- //------------------------------------------------------------
-
-
- //------------------------------------------------------------
- // Setup containers and skeleton of chart
-
- var wrap = container.selectAll('g.nv-wrap.nv-sparkline').data([data]);
- var wrapEnter = wrap.enter().append('g').attr('class', 'nvd3
nv-wrap nv-sparkline');
- var gEnter = wrapEnter.append('g');
- var g = wrap.select('g');
-
- wrap.attr('transform', 'translate(' + margin.left + ',' +
margin.top + ')')
-
- //------------------------------------------------------------
-
-
- var paths = wrap.selectAll('path')
- .data(function(d) { return [d] });
- paths.enter().append('path');
- paths.exit().remove();
- paths
- .style('stroke', function(d,i) { return d.color || color(d, i) })
- .attr('d', d3.svg.line()
- .x(function(d,i) { return x(getX(d,i)) })
- .y(function(d,i) { return y(getY(d,i)) })
- );
-
-
- // TODO: Add CURRENT data point (Need Min, Mac, Current / Most recent)
- var points = wrap.selectAll('circle.nv-point')
- .data(function(data) {
- var yValues = data.map(function(d, i) { return getY(d,i); });
- function pointIndex(index) {
- if (index != -1) {
- var result = data[index];
- result.pointIndex = index;
- return result;
- } else {
- return null;
- }
- }
- var maxPoint = pointIndex(yValues.lastIndexOf(y.domain()[1])),
- minPoint = pointIndex(yValues.indexOf(y.domain()[0])),
- currentPoint = pointIndex(yValues.length - 1);
- return [minPoint, maxPoint, currentPoint].filter(function (d) {return d !=
null;});
- });
- points.enter().append('circle');
- points.exit().remove();
- points
- .attr('cx', function(d,i) { return x(getX(d,d.pointIndex)) })
- .attr('cy', function(d,i) { return y(getY(d,d.pointIndex)) })
- .attr('r', 2)
- .attr('class', function(d,i) {
- return getX(d, d.pointIndex) == x.domain()[1] ? 'nv-point
nv-currentValue' :
- getY(d, d.pointIndex) == y.domain()[0] ? 'nv-point
nv-minValue' : 'nv-point nv-maxValue'
- });
- });
-
- return chart;
- }
-
-
- //============================================================
- // Expose Public Variables
- //------------------------------------------------------------
-
- 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.x = function(_) {
- if (!arguments.length) return getX;
- getX = d3.functor(_);
- return chart;
- };
-
- chart.y = function(_) {
- if (!arguments.length) return getY;
- getY = d3.functor(_);
- 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.animate = function(_) {
- if (!arguments.length) return animate;
- animate = _;
- return chart;
- };
-
- chart.color = function(_) {
- if (!arguments.length) return color;
- color = nv.utils.getColor(_);
- return chart;
- };
-
- //============================================================
-
-
- return chart;
-}
-
-nv.models.sparklinePlus = function() {
-
- //============================================================
- // Public Variables with Default Settings
- //------------------------------------------------------------
-
- var sparkline = nv.models.sparkline();
-
- var margin = {top: 15, right: 100, bottom: 10, left: 50}
- , width = null
- , height = null
- , x
- , y
- , index = []
- , paused = false
- , xTickFormat = d3.format(',r')
- , yTickFormat = d3.format(',.2f')
- , showValue = true
- , alignValue = true
- , rightAlignValue = false
- , noData = "No Data Available."
- ;
-
- //============================================================
-
-
- function chart(selection) {
- selection.each(function(data) {
- var container = d3.select(this);
-
- var availableWidth = (width || parseInt(container.style('width')) || 960)
- - margin.left - margin.right,
- availableHeight = (height || parseInt(container.style('height')) ||
400)
- - margin.top - margin.bottom;
-
-
-
- chart.update = function() { chart(selection) };
- chart.container = this;
-
-
- //------------------------------------------------------------
- // Display No Data message if there's nothing to show.
-
- if (!data || !data.length) {
- var noDataText = container.selectAll('.nv-noData').data([noData]);
-
- noDataText.enter().append('text')
- .attr('class', 'nvd3 nv-noData')
- .attr('dy', '-.7em')
- .style('text-anchor', 'middle');
-
- noDataText
- .attr('x', margin.left + availableWidth / 2)
- .attr('y', margin.top + availableHeight / 2)
- .text(function(d) { return d });
-
- return chart;
- } else {
- container.selectAll('.nv-noData').remove();
- }
-
- var currentValue = sparkline.y()(data[data.length-1], data.length-1);
-
- //------------------------------------------------------------
-
-
-
- //------------------------------------------------------------
- // Setup Scales
-
- x = sparkline.xScale();
- y = sparkline.yScale();
-
- //------------------------------------------------------------
-
-
- //------------------------------------------------------------
- // Setup containers and skeleton of chart
-
- var wrap = container.selectAll('g.nv-wrap.nv-sparklineplus').data([data]);
- var wrapEnter = wrap.enter().append('g').attr('class', 'nvd3
nv-wrap nv-sparklineplus');
- var gEnter = wrapEnter.append('g');
- var g = wrap.select('g');
-
- gEnter.append('g').attr('class', 'nv-sparklineWrap');
- gEnter.append('g').attr('class', 'nv-valueWrap');
- gEnter.append('g').attr('class', 'nv-hoverArea');
-
- wrap.attr('transform', 'translate(' + margin.left + ',' +
margin.top + ')');
-
- //------------------------------------------------------------
-
-
- //------------------------------------------------------------
- // Main Chart Component(s)
-
- var sparklineWrap = g.select('.nv-sparklineWrap');
-
- sparkline
- .width(availableWidth)
- .height(availableHeight);
-
- sparklineWrap
- .call(sparkline);
-
- //------------------------------------------------------------
-
-
- var valueWrap = g.select('.nv-valueWrap');
-
- var value = valueWrap.selectAll('.nv-currentValue')
- .data([currentValue]);
-
- value.enter().append('text').attr('class',
'nv-currentValue')
- .attr('dx', rightAlignValue ? -8 : 8)
- .attr('dy', '.9em')
- .style('text-anchor', rightAlignValue ? 'end' :
'start');
-
- value
- .attr('x', availableWidth + (rightAlignValue ? margin.right : 0))
- .attr('y', alignValue ? function(d) { return y(d) } : 0)
- .style('fill', sparkline.color()(data[data.length-1], data.length-1))
- .text(yTickFormat(currentValue));
-
-
-
- gEnter.select('.nv-hoverArea').append('rect')
- .on('mousemove', sparklineHover)
- .on('click', function() { paused = !paused })
- .on('mouseout', function() { index = []; updateValueLine(); });
- //.on('mouseout', function() { index = null; updateValueLine(); });
-
- g.select('.nv-hoverArea rect')
- .attr('transform', function(d) { return 'translate(' +
-margin.left + ',' + -margin.top + ')' })
- .attr('width', availableWidth + margin.left + margin.right)
- .attr('height', availableHeight + margin.top);
-
-
-
- function updateValueLine() { //index is currently global (within the chart), may or
may not keep it that way
- if (paused) return;
-
- var hoverValue = g.selectAll('.nv-hoverValue').data(index)
-
- var hoverEnter = hoverValue.enter()
- .append('g').attr('class', 'nv-hoverValue')
- .style('stroke-opacity', 0)
- .style('fill-opacity', 0);
-
- hoverValue.exit()
- .transition().duration(250)
- .style('stroke-opacity', 0)
- .style('fill-opacity', 0)
- .remove();
-
- hoverValue
- .attr('transform', function(d) { return 'translate(' +
x(sparkline.x()(data[d],d)) + ',0)' })
- .transition().duration(250)
- .style('stroke-opacity', 1)
- .style('fill-opacity', 1);
-
- if (!index.length) return;
-
- hoverEnter.append('line')
- .attr('x1', 0)
- .attr('y1', -margin.top)
- .attr('x2', 0)
- .attr('y2', availableHeight);
-
-
- hoverEnter.append('text').attr('class', 'nv-xValue')
- .attr('x', -6)
- .attr('y', -margin.top)
- .attr('text-anchor', 'end')
- .attr('dy', '.9em')
-
-
- g.select('.nv-hoverValue .nv-xValue')
- .text(xTickFormat(sparkline.x()(data[index[0]], index[0])));
-
- hoverEnter.append('text').attr('class', 'nv-yValue')
- .attr('x', 6)
- .attr('y', -margin.top)
- .attr('text-anchor', 'start')
- .attr('dy', '.9em')
-
- g.select('.nv-hoverValue .nv-yValue')
- .text(yTickFormat(sparkline.y()(data[index[0]], index[0])));
-
- }
-
-
- function sparklineHover() {
- if (paused) return;
-
- var pos = d3.mouse(this)[0] - margin.left;
-
- function getClosestIndex(data, x) {
- var distance = Math.abs(sparkline.x()(data[0], 0) - x);
- var closestIndex = 0;
- for (var i = 0; i < data.length; i++){
- if (Math.abs(sparkline.x()(data[i], i) - x) < distance) {
- distance = Math.abs(sparkline.x()(data[i], i) - x);
- closestIndex = i;
- }
- }
- return closestIndex;
- }
-
- index = [getClosestIndex(data, Math.round(x.invert(pos)))];
-
- updateValueLine();
- }
-
- });
-
- return chart;
- }
-
-
- //============================================================
- // Expose Public Variables
- //------------------------------------------------------------
-
- // expose chart's sub-components
- chart.sparkline = sparkline;
-
- d3.rebind(chart, sparkline, 'x', 'y', 'xScale',
'yScale', 'color');
-
- 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.xTickFormat = function(_) {
- if (!arguments.length) return xTickFormat;
- xTickFormat = _;
- return chart;
- };
-
- chart.yTickFormat = function(_) {
- if (!arguments.length) return yTickFormat;
- yTickFormat = _;
- return chart;
- };
-
- chart.showValue = function(_) {
- if (!arguments.length) return showValue;
- showValue = _;
- return chart;
- };
-
- chart.alignValue = function(_) {
- if (!arguments.length) return alignValue;
- alignValue = _;
- return chart;
- };
-
- chart.rightAlignValue = function(_) {
- if (!arguments.length) return rightAlignValue;
- rightAlignValue = _;
- return chart;
- };
-
- chart.noData = function(_) {
- if (!arguments.length) return noData;
- noData = _;
- return chart;
- };
-
- //============================================================
-
-
- return chart;
-}
-
-nv.models.stackedArea = function() {
-
- //============================================================
- // Public Variables with Default Settings
- //------------------------------------------------------------
-
- var margin = {top: 0, right: 0, bottom: 0, left: 0}
- , width = 960
- , height = 500
- , color = nv.utils.defaultColor() // a function that computes the color
- , id = Math.floor(Math.random() * 100000) //Create semi-unique ID incase user
doesn't selet one
- , getX = function(d) { return d.x } // accessor to get the x value from a data point
- , getY = function(d) { return d.y } // accessor to get the y value from a data point
- , style = 'stack'
- , offset = 'zero'
- , order = 'default'
- , interpolate = 'linear' // controls the line interpolation
- , clipEdge = false // if true, masks lines within x and y scale
- , x //can be accessed via chart.xScale()
- , y //can be accessed via chart.yScale()
- , scatter = nv.models.scatter()
- , dispatch = d3.dispatch('tooltipShow', 'tooltipHide',
'areaClick', 'areaMouseover', 'areaMouseout')
- ;
-
- scatter
- .size(2.2) // default size
- .sizeDomain([2.2,2.2]) // all the same size by default
- ;
-
- /************************************
- * offset:
- * 'wiggle' (stream)
- * 'zero' (stacked)
- * 'expand' (normalize to 100%)
- * 'silhouette' (simple centered)
- *
- * order:
- * 'inside-out' (stream)
- * 'default' (input order)
- ************************************/
-
- //============================================================
-
-
- function chart(selection) {
- selection.each(function(data) {
- var availableWidth = width - margin.left - margin.right,
- availableHeight = height - margin.top - margin.bottom,
- container = d3.select(this);
-
- //------------------------------------------------------------
- // Setup Scales
-
- x = scatter.xScale();
- y = scatter.yScale();
-
- //------------------------------------------------------------
-
-
- // Injecting point index into each point because d3.layout.stack().out does not
give index
- // ***Also storing getY(d,i) as stackedY so that it can be set to 0 if series is
disabled
- data = data.map(function(aseries, i) {
- aseries.values = aseries.values.map(function(d, j) {
- d.index = j;
- d.stackedY = aseries.disabled ? 0 : getY(d,j);
- return d;
- })
- return aseries;
- });
-
-
- data = d3.layout.stack()
- .order(order)
- .offset(offset)
- .values(function(d) { return d.values }) //TODO: make values
customizeable in EVERY model in this fashion
- .x(getX)
- .y(function(d) { return d.stackedY })
- .out(function(d, y0, y) {
- d.display = {
- y: y,
- y0: y0
- };
- })
- (data);
-
-
- //------------------------------------------------------------
- // Setup containers and skeleton of chart
-
- var wrap = container.selectAll('g.nv-wrap.nv-stackedarea').data([data]);
- var wrapEnter = wrap.enter().append('g').attr('class', 'nvd3
nv-wrap nv-stackedarea');
- var defsEnter = wrapEnter.append('defs');
- var gEnter = wrapEnter.append('g');
- var g = wrap.select('g');
-
- gEnter.append('g').attr('class', 'nv-areaWrap');
- gEnter.append('g').attr('class', 'nv-scatterWrap');
-
- wrap.attr('transform', 'translate(' + margin.left + ',' +
margin.top + ')');
-
- //------------------------------------------------------------
-
-
- scatter
- .width(availableWidth)
- .height(availableHeight)
- .x(getX)
- .y(function(d) { return d.display.y + d.display.y0 })
- .forceY([0])
- .color(data.map(function(d,i) {
- return d.color || color(d, i);
- }).filter(function(d,i) { return !data[i].disabled }));
-
-
- var scatterWrap = g.select('.nv-scatterWrap')
- .datum(data.filter(function(d) { return !d.disabled }))
-
- //d3.transition(scatterWrap).call(scatter);
- scatterWrap.call(scatter);
-
-
-
-
-
- defsEnter.append('clipPath')
- .attr('id', 'nv-edge-clip-' + id)
- .append('rect');
-
- wrap.select('#nv-edge-clip-' + id + ' rect')
- .attr('width', availableWidth)
- .attr('height', availableHeight);
-
- g .attr('clip-path', clipEdge ? 'url(#nv-edge-clip-' + id +
')' : '');
-
-
-
-
- var area = d3.svg.area()
- .x(function(d,i) { return x(getX(d,i)) })
- .y0(function(d) { return y(d.display.y0) })
- .y1(function(d) { return y(d.display.y + d.display.y0) })
- .interpolate(interpolate);
-
- var zeroArea = d3.svg.area()
- .x(function(d,i) { return x(getX(d,i)) })
- .y0(function(d) { return y(d.display.y0) })
- .y1(function(d) { return y(d.display.y0) });
-
-
- var path = g.select('.nv-areaWrap').selectAll('path.nv-area')
- .data(function(d) { return d });
- //.data(function(d) { return d }, function(d) { return d.key });
- path.enter().append('path').attr('class', function(d,i) { return
'nv-area nv-area-' + i })
- .on('mouseover', function(d,i) {
- d3.select(this).classed('hover', true);
- dispatch.areaMouseover({
- point: d,
- series: d.key,
- pos: [d3.event.pageX, d3.event.pageY],
- seriesIndex: i
- });
- })
- .on('mouseout', function(d,i) {
- d3.select(this).classed('hover', false);
- dispatch.areaMouseout({
- point: d,
- series: d.key,
- pos: [d3.event.pageX, d3.event.pageY],
- seriesIndex: i
- });
- })
- .on('click', function(d,i) {
- d3.select(this).classed('hover', false);
- dispatch.areaClick({
- point: d,
- series: d.key,
- pos: [d3.event.pageX, d3.event.pageY],
- seriesIndex: i
- });
- })
- //d3.transition(path.exit())
- path.exit()
- .attr('d', function(d,i) { return zeroArea(d.values,i) })
- .remove();
- path
- .style('fill', function(d,i){ return d.color || color(d, i) })
- .style('stroke', function(d,i){ return d.color || color(d, i) });
- //d3.transition(path)
- path
- .attr('d', function(d,i) { return area(d.values,i) })
-
-
- //============================================================
- // Event Handling/Dispatching (in chart's scope)
- //------------------------------------------------------------
-
- scatter.dispatch.on('elementMouseover.area', function(e) {
- g.select('.nv-chart-' + id + ' .nv-area-' +
e.seriesIndex).classed('hover', true);
- });
- scatter.dispatch.on('elementMouseout.area', function(e) {
- g.select('.nv-chart-' + id + ' .nv-area-' +
e.seriesIndex).classed('hover', false);
- });
-
- //============================================================
-
- });
-
-
- return chart;
- }
-
-
- //============================================================
- // Event Handling/Dispatching (out of chart's scope)
- //------------------------------------------------------------
-
- scatter.dispatch.on('elementClick.area', function(e) {
- dispatch.areaClick(e);
- })
- scatter.dispatch.on('elementMouseover.tooltip', function(e) {
- e.pos = [e.pos[0] + margin.left, e.pos[1] + margin.top],
- dispatch.tooltipShow(e);
- });
- scatter.dispatch.on('elementMouseout.tooltip', function(e) {
- dispatch.tooltipHide(e);
- });
-
- //============================================================
-
-
- //============================================================
- // Global getters and setters
- //------------------------------------------------------------
-
- chart.dispatch = dispatch;
- chart.scatter = scatter;
-
- d3.rebind(chart, scatter, 'interactive', 'size', 'xScale',
'yScale', 'zScale', 'xDomain', 'yDomain',
'sizeDomain', 'forceX', 'forceY', 'forceSize',
'clipVoronoi', 'clipRadius');
-
- chart.x = function(_) {
- if (!arguments.length) return getX;
- getX = d3.functor(_);
- return chart;
- };
-
- chart.y = function(_) {
- if (!arguments.length) return getY;
- getY = d3.functor(_);
- 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.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.offset = function(_) {
- if (!arguments.length) return offset;
- offset = _;
- return chart;
- };
-
- chart.order = function(_) {
- if (!arguments.length) return order;
- order = _;
- return chart;
- };
-
- //shortcut for offset + order
- chart.style = function(_) {
- if (!arguments.length) return style;
- style = _;
-
- switch (style) {
- case 'stack':
- chart.offset('zero');
- chart.order('default');
- break;
- case 'stream':
- chart.offset('wiggle');
- chart.order('inside-out');
- break;
- case 'stream-center':
- chart.offset('silhouette');
- chart.order('inside-out');
- break;
- case 'expand':
- chart.offset('expand');
- chart.order('default');
- break;
- }
-
- return chart;
- };
-
- chart.interpolate = function(_) {
- if (!arguments.length) return interpolate;
- interpolate = _;
- return interpolate;
-
- };
-
- //============================================================
-
-
- return chart;
-}
-
-nv.models.stackedAreaChart = function() {
-
- //============================================================
- // Public Variables with Default Settings
- //------------------------------------------------------------
-
- var stacked = nv.models.stackedArea()
- , xAxis = nv.models.axis()
- , yAxis = nv.models.axis()
- , legend = nv.models.legend()
- , controls = nv.models.legend()
- ;
-
- var margin = {top: 30, right: 25, bottom: 50, left: 60}
- , width = null
- , height = null
- , color = nv.utils.defaultColor() // a function that takes in d, i and returns color
- , showControls = true
- , showLegend = true
- , tooltips = true
- , tooltip = function(key, x, y, e, graph) {
- return '<h3>' + key + '</h3>' +
- '<p>' + y + ' on ' + x + '</p>'
- }
- , x //can be accessed via chart.xScale()
- , y //can be accessed via chart.yScale()
- , yAxisTickFormat = d3.format(',.2f')
- , state = { style: stacked.style() }
- , defaultState = null
- , noData = 'No Data Available.'
- , dispatch = d3.dispatch('tooltipShow', 'tooltipHide',
'stateChange', 'changeState')
- , controlWidth = 250
- ;
-
- xAxis
- .orient('bottom')
- .tickPadding(7)
- ;
- yAxis
- .orient('left')
- ;
- stacked.scatter
- .pointActive(function(d) {
- //console.log(stacked.y()(d), !!Math.round(stacked.y()(d) * 100));
- return !!Math.round(stacked.y()(d) * 100);
- })
- ;
-
- //============================================================
-
-
- //============================================================
- // Private Variables
- //------------------------------------------------------------
-
- var showTooltip = function(e, offsetElement) {
- var left = e.pos[0] + ( offsetElement.offsetLeft || 0 ),
- top = e.pos[1] + ( offsetElement.offsetTop || 0),
- x = xAxis.tickFormat()(stacked.x()(e.point, e.pointIndex)),
- y = yAxis.tickFormat()(stacked.y()(e.point, e.pointIndex)),
- content = tooltip(e.series.key, x, y, e, chart);
-
- nv.tooltip.show([left, top], content, e.value < 0 ? 'n' : 's',
null, offsetElement);
- };
-
- //============================================================
-
-
- function chart(selection) {
- selection.each(function(data) {
- var container = d3.select(this),
- that = this;
-
- var availableWidth = (width || parseInt(container.style('width')) || 960)
- - margin.left - margin.right,
- availableHeight = (height || parseInt(container.style('height')) ||
400)
- - margin.top - margin.bottom;
-
- chart.update = function() { container.transition().call(chart); };
- chart.container = this;
-
- //set state.disabled
- state.disabled = data.map(function(d) { return !!d.disabled });
-
- if (!defaultState) {
- var key;
- defaultState = {};
- for (key in state) {
- if (state[key] instanceof Array)
- defaultState[key] = state[key].slice(0);
- else
- defaultState[key] = state[key];
- }
- }
-
- //------------------------------------------------------------
- // Display No Data message if there's nothing to show.
-
- if (!data || !data.length || !data.filter(function(d) { return d.values.length
}).length) {
- var noDataText = container.selectAll('.nv-noData').data([noData]);
-
- noDataText.enter().append('text')
- .attr('class', 'nvd3 nv-noData')
- .attr('dy', '-.7em')
- .style('text-anchor', 'middle');
-
- noDataText
- .attr('x', margin.left + availableWidth / 2)
- .attr('y', margin.top + availableHeight / 2)
- .text(function(d) { return d });
-
- return chart;
- } else {
- container.selectAll('.nv-noData').remove();
- }
-
- //------------------------------------------------------------
-
-
- //------------------------------------------------------------
- // Setup Scales
-
- x = stacked.xScale();
- y = stacked.yScale();
-
- //------------------------------------------------------------
-
-
- //------------------------------------------------------------
- // Setup containers and skeleton of chart
-
- var wrap =
container.selectAll('g.nv-wrap.nv-stackedAreaChart').data([data]);
- var gEnter = wrap.enter().append('g').attr('class', 'nvd3
nv-wrap nv-stackedAreaChart').append('g');
- var g = wrap.select('g');
-
- gEnter.append('g').attr('class', 'nv-x nv-axis');
- gEnter.append('g').attr('class', 'nv-y nv-axis');
- gEnter.append('g').attr('class', 'nv-stackedWrap');
- gEnter.append('g').attr('class', 'nv-legendWrap');
- gEnter.append('g').attr('class', 'nv-controlsWrap');
-
- //------------------------------------------------------------
-
-
- //------------------------------------------------------------
- // Legend
-
- if (showLegend) {
- legend
- .width( availableWidth - controlWidth );
-
- g.select('.nv-legendWrap')
- .datum(data)
- .call(legend);
-
- if ( margin.top != legend.height()) {
- margin.top = legend.height();
- availableHeight = (height || parseInt(container.style('height')) ||
400)
- - margin.top - margin.bottom;
- }
-
- g.select('.nv-legendWrap')
- .attr('transform', 'translate(' + controlWidth + ','
+ (-margin.top) +')');
- }
-
- //------------------------------------------------------------
-
-
- //------------------------------------------------------------
- // Controls
-
- if (showControls) {
- var controlsData = [
- { key: 'Stacked', disabled: stacked.offset() != 'zero' },
- { key: 'Stream', disabled: stacked.offset() != 'wiggle' },
- { key: 'Expanded', disabled: stacked.offset() != 'expand' }
- ];
-
- controls
- .width( controlWidth )
- .color(['#444', '#444', '#444']);
-
- g.select('.nv-controlsWrap')
- .datum(controlsData)
- .call(controls);
-
-
- if ( margin.top != Math.max(controls.height(), legend.height()) ) {
- margin.top = Math.max(controls.height(), legend.height());
- availableHeight = (height || parseInt(container.style('height')) ||
400)
- - margin.top - margin.bottom;
- }
-
-
- g.select('.nv-controlsWrap')
- .attr('transform', 'translate(0,' + (-margin.top)
+')');
- }
-
- //------------------------------------------------------------
-
-
- wrap.attr('transform', 'translate(' + margin.left + ',' +
margin.top + ')');
-
-
- //------------------------------------------------------------
- // Main Chart Component(s)
-
- stacked
- .width(availableWidth)
- .height(availableHeight)
-
- var stackedWrap = g.select('.nv-stackedWrap')
- .datum(data);
- //d3.transition(stackedWrap).call(stacked);
- stackedWrap.call(stacked);
-
- //------------------------------------------------------------
-
-
- //------------------------------------------------------------
- // Setup Axes
-
- xAxis
- .scale(x)
- .ticks( availableWidth / 100 )
- .tickSize( -availableHeight, 0);
-
- g.select('.nv-x.nv-axis')
- .attr('transform', 'translate(0,' + availableHeight +
')');
- //d3.transition(g.select('.nv-x.nv-axis'))
- g.select('.nv-x.nv-axis')
- .transition().duration(0)
- .call(xAxis);
-
- yAxis
- .scale(y)
- .ticks(stacked.offset() == 'wiggle' ? 0 : availableHeight / 36)
- .tickSize(-availableWidth, 0)
- .setTickFormat(stacked.offset() == 'expand' ? d3.format('%') :
yAxisTickFormat);
-
- //d3.transition(g.select('.nv-y.nv-axis'))
- g.select('.nv-y.nv-axis')
- .transition().duration(0)
- .call(yAxis);
-
- //------------------------------------------------------------
-
-
- //============================================================
- // Event Handling/Dispatching (in chart's scope)
- //------------------------------------------------------------
-
- stacked.dispatch.on('areaClick.toggle', function(e) {
- if (data.filter(function(d) { return !d.disabled }).length === 1)
- data = data.map(function(d) {
- d.disabled = false;
- return d
- });
- else
- data = data.map(function(d,i) {
- d.disabled = (i != e.seriesIndex);
- return d
- });
-
- state.disabled = data.map(function(d) { return !!d.disabled });
- 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;
- return d;
- });
- }
-
- state.disabled = data.map(function(d) { return !!d.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;
- });
- d.disabled = false;
-
- state.disabled = data.map(function(d) { return !!d.disabled });
- dispatch.stateChange(state);
- chart.update();
- });
-
- controls.dispatch.on('legendClick', function(d,i) {
- if (!d.disabled) return;
-
- controlsData = controlsData.map(function(s) {
- s.disabled = true;
- return s;
- });
- d.disabled = false;
-
- switch (d.key) {
- case 'Stacked':
- stacked.style('stack');
- break;
- case 'Stream':
- stacked.style('stream');
- break;
- case 'Expanded':
- stacked.style('expand');
- break;
- }
-
- state.style = stacked.style();
- dispatch.stateChange(state);
-
- //selection.transition().call(chart);
- chart.update();
- });
-
- dispatch.on('tooltipShow', function(e) {
- if (tooltips) showTooltip(e, that.parentNode);
- });
-
- // Update chart from a state object passed to event handler
- dispatch.on('changeState', function(e) {
-
- if (typeof e.disabled !== 'undefined') {
- data.forEach(function(series,i) {
- series.disabled = e.disabled[i];
- });
-
- state.disabled = e.disabled;
- }
-
- if (typeof e.style !== 'undefined') {
- stacked.style(e.style);
- }
-
- chart.update();
- });
-
- });
-
-
- return chart;
- }
-
-
- //============================================================
- // Event Handling/Dispatching (out of chart's scope)
- //------------------------------------------------------------
-
- stacked.dispatch.on('tooltipShow', function(e) {
- //disable tooltips when value ~= 0
- //// TODO: consider removing points from voronoi that have 0 value instead of this
hack
- /*
- if (!Math.round(stacked.y()(e.point) * 100)) { // 100 will not be good for very
small numbers... will have to think about making this valu dynamic, based on data range
- setTimeout(function() {
d3.selectAll('.point.hover').classed('hover', false) }, 0);
- return false;
- }
- */
-
- e.pos = [e.pos[0] + margin.left, e.pos[1] + margin.top],
- dispatch.tooltipShow(e);
- });
-
- stacked.dispatch.on('tooltipHide', function(e) {
- dispatch.tooltipHide(e);
- });
-
- dispatch.on('tooltipHide', function() {
- if (tooltips) nv.tooltip.cleanup();
- });
-
- //============================================================
-
-
- //============================================================
- // Expose Public Variables
- //------------------------------------------------------------
-
- // expose chart's sub-components
- chart.dispatch = dispatch;
- chart.stacked = stacked;
- chart.legend = legend;
- chart.controls = controls;
- chart.xAxis = xAxis;
- chart.yAxis = yAxis;
-
- d3.rebind(chart, stacked, 'x', 'y', 'size', 'xScale',
'yScale', 'xDomain', 'yDomain', 'sizeDomain',
'interactive', 'offset', 'order', 'style',
'clipEdge', 'forceX', 'forceY', 'forceSize',
'interpolate');
-
- 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 getWidth;
- width = _;
- return chart;
- };
-
- chart.height = function(_) {
- if (!arguments.length) return getHeight;
- height = _;
- return chart;
- };
-
- chart.color = function(_) {
- if (!arguments.length) return color;
- color = nv.utils.getColor(_);
- legend.color(color);
- stacked.color(color);
- return chart;
- };
-
- chart.showControls = function(_) {
- if (!arguments.length) return showControls;
- showControls = _;
- return chart;
- };
-
- chart.showLegend = function(_) {
- if (!arguments.length) return showLegend;
- showLegend = _;
- return chart;
- };
-
- chart.tooltip = function(_) {
- if (!arguments.length) return tooltip;
- tooltip = _;
- return chart;
- };
-
- chart.tooltips = function(_) {
- if (!arguments.length) return tooltips;
- tooltips = _;
- return chart;
- };
-
- chart.tooltipContent = function(_) {
- if (!arguments.length) return tooltip;
- tooltip = _;
- return chart;
- };
-
- chart.state = function(_) {
- if (!arguments.length) return state;
- state = _;
- return chart;
- };
-
- chart.defaultState = function(_) {
- if (!arguments.length) return defaultState;
- defaultState = _;
- return chart;
- };
-
- chart.noData = function(_) {
- if (!arguments.length) return noData;
- noData = _;
- return chart;
- };
-
- yAxis.setTickFormat = yAxis.tickFormat;
-
- yAxis.tickFormat = function(_) {
- if (!arguments.length) return yAxisTickFormat;
- yAxisTickFormat = _;
- return yAxis;
- };
-
- //============================================================
-
- return chart;
-}
-})();
\ No newline at end of file
diff --git a/modules/enterprise/gui/coregui/src/main/webapp/js/nv.d3.min.js
b/modules/enterprise/gui/coregui/src/main/webapp/js/nv.d3.min.js
deleted file mode 100755
index 309108b..0000000
--- a/modules/enterprise/gui/coregui/src/main/webapp/js/nv.d3.min.js
+++ /dev/null
@@ -1,6 +0,0 @@
-(function(){function t(e,t){return(new Date(t,e+1,0)).getDate()}function n(e,t,n){return
function(r,i,s){var o=e(r),u=[];o<r&&t(o);if(s>1)while(o<i){var a=new
Date(+o);n(a)%s===0&&u.push(a),t(o)}else while(o<i)u.push(new
Date(+o)),t(o);return u}}var
e=window.nv||{};e.version="0.0.1a",e.dev=!0,window.nv=e,e.tooltip={},e.utils={},e.models={},e.charts={},e.graphs=[],e.logs={},e.dispatch=d3.dispatch("render_start","render_end"),e.dev&&(e.dispatch.on("render_start",function(t){e.logs.startTime=+(new
Date)}),e.dispatch.on("render_end",function(t){e.logs.endTime=+(new
Date),e.logs.totalTime=e.logs.endTime-e.logs.startTime,e.log("total",e.logs.totalTime)})),e.log=function(){if(e.dev&&console.log&&console.log.apply)console.log.apply(console,arguments);else
if(e.dev&&console.log&&Function.prototype.bind){var
t=Function.prototype.bind.call(console.log,console);t.apply(console,arguments)}return
arguments[arguments.length-1]},e.render=function(n){n=n||1,e.render.active=!0,e.dispatch.rend
er_start(),setTimeout(function(){var t,r;for(var
i=0;i<n&&(r=e.render.queue[i]);i++)t=r.generate(),typeof r.callback==typeof
Function&&r.callback(t),e.graphs.push(t);e.render.queue.splice(0,i),e.render.queue.length?setTimeout(arguments.callee,0):(e.render.active=!1,e.dispatch.render_end())},0)},e.render.active=!1,e.render.queue=[],e.addGraph=function(t){typeof
arguments[0]==typeof
Function&&(t={generate:arguments[0],callback:arguments[1]}),e.render.queue.push(t),e.render.active||e.render()},e.identity=function(e){return
e},e.strip=function(e){return
e.replace(/(\s|&)/g,"")},d3.time.monthEnd=function(e){return new
Date(e.getFullYear(),e.getMonth(),0)},d3.time.monthEnds=n(d3.time.monthEnd,function(e){e.setUTCDate(e.getUTCDate()+1),e.setDate(t(e.getMonth()+1,e.getFullYear()))},function(e){return
e.getMonth()}),function(){var t=window.nv.tooltip={};t.show=function(t,n,r,i,s,o){var
u=document.createElement("div");u.className="nvtooltip
"+(o?o:"xy-tooltip"),r=r||"s",i=i||20;var a=
s;if(!s||s.tagName.match(/g|svg/i))a=document.getElementsByTagName("body")[0];u.innerHTML=n,u.style.left=0,u.style.top=0,u.style.opacity=0,a.appendChild(u);var
f=parseInt(u.offsetHeight),l=parseInt(u.offsetWidth),c=e.utils.windowSize().width,h=e.utils.windowSize().height,p=window.scrollY,d=window.scrollX,v,m;h=window.innerWidth>=document.body.scrollWidth?h:h-16,c=window.innerHeight>=document.body.scrollHeight?c:c-16;var
g=function(e){var t=m;do
isNaN(e.offsetTop)||(t+=e.offsetTop);while(e=e.offsetParent);return t},y=function(e){var
t=v;do isNaN(e.offsetLeft)||(t+=e.offsetLeft);while(e=e.offsetParent);return
t};switch(r){case"e":v=t[0]-l-i,m=t[1]-f/2;var
b=y(u),w=g(u);b<d&&(v=t[0]+i>d?t[0]+i:d-b+v),w<p&&(m=p-w+m),w+f>p+h&&(m=p+h-w+m-f);break;case"w":v=t[0]+i,m=t[1]-f/2,b+l>c&&(v=t[0]-l-i),w<p&&(m=p+5),w+f>p+h&&(m=p-f-5);break;case"n":v=t[0]-l/2-5,m=t[1]+i;var
b=y(u),w=g(u);b<d&&(v=d+5),b+l>c&&(v=v-l/2+5),w+f>p+h&&(m=p+h-w+m-f);break;case"s":v=t[0]-l/2,m=t[1]-f-i;var
b=y(u),w=
g(u);b<d&&(v=d+5),b+l>c&&(v=v-l/2+5),p>w&&(m=p)}return
u.style.left=v+"px",u.style.top=m+"px",u.style.opacity=1,u.style.position="absolute",u.style.pointerEvents="none",u},t.cleanup=function(){var
e=document.getElementsByClassName("nvtooltip"),t=[];while(e.length)t.push(e[0]),e[0].style.transitionDelay="0
!important",e[0].style.opacity=0,e[0].className="nvtooltip-pending-removal";setTimeout(function(){while(t.length){var
e=t.pop();e.parentNode.removeChild(e)}},500)}}(),e.utils.windowSize=function(){var
e={width:640,height:480};return
document.body&&document.body.offsetWidth&&(e.width=document.body.offsetWidth,e.height=document.body.offsetHeight),document.compatMode=="CSS1Compat"&&document.documentElement&&document.documentElement.offsetWidth&&(e.width=document.documentElement.offsetWidth,e.height=document.documentElement.offsetHeight),window.innerWidth&&window.innerHeight&&(e.width=window.innerWidth,e.height=window.innerHeight),e},e.utils.windowResize=function(e){var
t=windo
w.onresize;window.onresize=function(n){typeof
t=="function"&&t(n),e(n)}},e.utils.getColor=function(t){return
arguments.length?Object.prototype.toString.call(t)==="[object
Array]"?function(e,n){return
e.color||t[n%t.length]}:t:e.utils.defaultColor()},e.utils.defaultColor=function(){var
e=d3.scale.category20().range();return function(t,n){return
t.color||e[n%e.length]}},e.utils.customTheme=function(e,t,n){t=t||function(e){return
e.key},n=n||d3.scale.category20().range();var r=n.length;return function(i,s){var
o=t(i);return r||(r=n.length),typeof e[o]!="undefined"?typeof
e[o]=="function"?e[o]():e[o]:n[--r]}},e.utils.pjax=function(t,n){function
r(r){d3.html(r,function(r){var
i=d3.select(n).node();i.parentNode.replaceChild(d3.select(r).select(n).node(),i),e.utils.pjax(t,n)})}d3.selectAll(t).on("click",function(){history.pushState(this.href,this.textContent,this.href),r(this.href),d3.event.preventDefault()}),d3.select(window).on("popstate",function(){d3.event.state&&r(d3.event.sta
te)})},e.utils.calcApproxTextWidth=function(e){if(e instanceof d3.selection){var
t=parseInt(e.style("font-size").replace("px","")),n=e.text().length;return
n*t*.5}return 0},e.models.axis=function(){function d(r){return r.each(function(r){var
d=d3.select(this),v=d.selectAll("g.nv-wrap.nv-axis").data([r]),m=v.enter().append("g").attr("class","nvd3
nv-wrap
nv-axis"),g=m.append("g"),y=v.select("g");h!==null?e.ticks(h):(e.orient()=="top"||e.orient()=="bottom")&&e.ticks(Math.abs(i.range()[1]-i.range()[0])/100),d3.transition(y).call(e),p=p||e.scale();var
b=e.tickFormat();b==null&&(b=p.tickFormat());var
w=y.selectAll("text.nv-axislabel").data([s||null]);w.exit().remove();switch(e.orient()){case"top":w.enter().append("text").attr("class","nv-axislabel");var
E=i.range().length==2?i.range()[1]:i.range()[i.range().length-1]+(i.range()[1]-i.range()[0]);w.attr("text-anchor","middle").attr("y",0).attr("x",E/2);if(o){var
S=v.selectAll("g.nv-axisMaxMin").data(i.domain());S.enter().append("g"
).attr("class","nv-axisMaxMin").append("text"),S.exit().remove(),S.attr("transform",function(e,t){return"translate("+i(e)+",0)"}).select("text").attr("dy","0em").attr("y",-e.tickPadding()).attr("text-anchor","middle").text(function(e,t){var
n=b(e);return(""+n).match("NaN")?"":n}),d3.transition(S).attr("transform",function(e,t){return"translate("+i.range()[t]+",0)"})}break;case"bottom":var
x=36,T=30,N=y.selectAll("g").select("text");if(a%360){N.each(function(e,t){var
n=this.getBBox().width;n>T&&(T=n)});var
C=Math.abs(Math.sin(a*Math.PI/180)),x=(C?C*T:T)+30;N.attr("transform",function(e,t,n){return"rotate("+a+"
0,0)"}).attr("text-anchor",a%360>0?"start":"end")}w.enter().append("text").attr("class","nv-axislabel");var
E=i.range().length==2?i.range()[1]:i.range()[i.range().length-1]+(i.range()[1]-i.range()[0]);w.attr("text-anchor","middle").attr("y",x).attr("x",E/2);if(o){var
S=v.selectAll("g.nv-axisMaxMin").data([i.domain()[0],i.domain()[i.domain().length-1]]);S.enter().append(
"g").attr("class","nv-axisMaxMin").append("text"),S.exit().remove(),S.attr("transform",function(e,t){return"translate("+(i(e)+(c?i.rangeBand()/2:0))+",0)"}).select("text").attr("dy",".71em").attr("y",e.tickPadding()).attr("transform",function(e,t,n){return"rotate("+a+"
0,0)"}).attr("text-anchor",a?a%360>0?"start":"end":"middle").text(function(e,t){var
n=b(e);return(""+n).match("NaN")?"":n}),d3.transition(S).attr("transform",function(e,t){return"translate("+(i(e)+(c?i.rangeBand()/2:0))+",0)"})}l&&N.attr("transform",function(e,t){return"translate(0,"+(t%2==0?"0":"12")+")"});break;case"right":w.enter().append("text").attr("class","nv-axislabel"),w.attr("text-anchor",f?"middle":"begin").attr("transform",f?"rotate(90)":"").attr("y",f?-Math.max(t.right,n)+12:-10).attr("x",f?i.range()[0]/2:e.tickPadding());if(o){var
S=v.selectAll("g.nv-axisMaxMin").data(i.domain());S.enter().append("g").attr("class","nv-axisMaxMin").append("text").style("opacity",0),S.exit().remove(),S.attr("transf
orm",function(e,t){return"translate(0,"+i(e)+")"}).select("text").attr("dy",".32em").attr("y",0).attr("x",e.tickPadding()).attr("text-anchor","start").text(function(e,t){var
n=b(e);return(""+n).match("NaN")?"":n}),d3.transition(S).attr("transform",function(e,t){return"translate(0,"+i.range()[t]+")"}).select("text").style("opacity",1)}break;case"left":w.enter().append("text").attr("class","nv-axislabel"),w.attr("text-anchor",f?"middle":"end").attr("transform",f?"rotate(-90)":"").attr("y",f?-Math.max(t.left,n)+12:-10).attr("x",f?-i.range()[0]/2:-e.tickPadding());if(o){var
S=v.selectAll("g.nv-axisMaxMin").data(i.domain());S.enter().append("g").attr("class","nv-axisMaxMin").append("text").style("opacity",0),S.exit().remove(),S.attr("transform",function(e,t){return"translate(0,"+p(e)+")"}).select("text").attr("dy",".32em").attr("y",0).attr("x",-e.tickPadding()).attr("text-anchor","end").text(function(e,t){var
n=b(e);return(""+n).match("NaN")?"":n}),d3.transition(S).attr("transfor
m",function(e,t){return"translate(0,"+i.range()[t]+")"}).select("text").style("opacity",1)}}w.text(function(e){return
e}),o&&(e.orient()==="left"||e.orient()==="right")&&(y.selectAll("g").each(function(e,t){d3.select(this).select("text").attr("opacity",1);if(i(e)<i.range()[1]+10||i(e)>i.range()[0]-10)(e>1e-10||e<-1e-10)&&d3.select(this).attr("opacity",0),d3.select(this).select("text").attr("opacity",0)}),i.domain()[0]==i.domain()[1]&&i.domain()[0]==0&&v.selectAll("g.nv-axisMaxMin").style("opacity",function(e,t){return
t?0:1}));if(o&&(e.orient()==="top"||e.orient()==="bottom")){var
k=[];v.selectAll("g.nv-axisMaxMin").each(function(e,t){try{t?k.push(i(e)-this.getBBox().width-4):k.push(i(e)+this.getBBox().width+4)}catch(n){t?k.push(i(e)-4):k.push(i(e)+4)}}),y.selectAll("g").each(function(e,t){if(i(e)<k[0]||i(e)>k[1])e>1e-10||e<-1e-10?d3.select(this).remove():d3.select(this).select("text").remove()})}u&&y.selectAll(".tick").filter(function(e){return!parseFloat(Math.round(e.__dat
a__*1e5)/1e6)&&e.__data__!==undefined}).classed("zero",!0),p=i.copy()}),d}var
e=d3.svg.axis(),t={top:0,right:0,bottom:0,left:0},n=75,r=60,i=d3.scale.linear(),s=null,o=!0,u=!0,a=0,f=!0,l=!1,c=!1,h=null;e.scale(i).orient("bottom").tickFormat(function(e){return
e});var p;return
d.axis=e,d3.rebind(d,e,"orient","tickValues","tickSubdivide","tickSize","tickPadding","tickFormat"),d3.rebind(d,i,"domain","range","rangeBand","rangeBands"),d.margin=function(e){return
arguments.length?(t.top=typeof e.top!="undefined"?e.top:t.top,t.right=typeof
e.right!="undefined"?e.right:t.right,t.bottom=typeof
e.bottom!="undefined"?e.bottom:t.bottom,t.left=typeof
e.left!="undefined"?e.left:t.left,d):t},d.width=function(e){return
arguments.length?(n=e,d):n},d.ticks=function(e){return
arguments.length?(h=e,d):h},d.height=function(e){return
arguments.length?(r=e,d):r},d.axisLabel=function(e){return
arguments.length?(s=e,d):s},d.showMaxMin=function(e){return
arguments.length?(o=e,d):o},d.highlightZero=fun
ction(e){return arguments.length?(u=e,d):u},d.scale=function(t){return
arguments.length?(i=t,e.scale(i),c=typeof
i.rangeBands=="function",d3.rebind(d,i,"domain","range","rangeBand","rangeBands"),d):i},d.rotateYLabel=function(e){return
arguments.length?(f=e,d):f},d.rotateLabels=function(e){return
arguments.length?(a=e,d):a},d.staggerLabels=function(e){return
arguments.length?(l=e,d):l},d},e.models.bullet=function(){function p(e){return
e.each(function(e,n){var
l=a-t.left-t.right,p=f-t.top-t.bottom,d=d3.select(this),v=i.call(this,e,n).slice().sort(d3.descending),m=s.call(this,e,n).slice().sort(d3.descending),g=o.call(this,e,n).slice().sort(d3.descending),y=d3.scale.linear().domain(d3.extent(d3.merge([u,v]))).range(r?[l,0]:[0,l]),b=this.__chart__||d3.scale.linear().domain([0,Infinity]).range(y.range());this.__chart__=y;var
w=d3.min(v),E=d3.max(v),S=v[1],x=d.selectAll("g.nv-wrap.nv-bullet").data([e]),T=x.enter().append("g").attr("class","nvd3
nv-wrap nv-bullet"),N=T.append("g"),
C=x.select("g");N.append("rect").attr("class","nv-range
nv-rangeMax"),N.append("rect").attr("class","nv-range
nv-rangeAvg"),N.append("rect").attr("class","nv-range
nv-rangeMin"),N.append("rect").attr("class","nv-measure"),N.append("path").attr("class","nv-markerTriangle"),x.attr("transform","translate("+t.left+","+t.top+")");var
k=function(e){return Math.abs(b(e)-b(0))},L=function(e){return
Math.abs(y(e)-y(0))},A=function(e){return e<0?b(e):b(0)},O=function(e){return
e<0?y(e):y(0)};C.select("rect.nv-rangeMax").attr("height",p).attr("width",L(E>0?E:w)).attr("x",O(E>0?E:w)).datum(E>0?E:w),C.select("rect.nv-rangeAvg").attr("height",p).attr("width",L(S)).attr("x",O(S)).datum(S),C.select("rect.nv-rangeMin").attr("height",p).attr("width",L(E)).attr("x",O(E)).attr("width",L(E>0?w:E)).attr("x",O(E>0?w:E)).datum(E>0?w:E),C.select("rect.nv-measure").style("fill",c).attr("height",p/3).attr("y",p/3).attr("width",g<0?y(0)-y(g[0]):y(g[0])-y(0)).attr("x",O(g)).on("mouseover",function(){h.e
lementMouseover({value:g[0],label:"Current",pos:[y(g[0]),p/2]})}).on("mouseout",function(){h.elementMouseout({value:g[0],label:"Current"})});var
M=p/6;m[0]?C.selectAll("path.nv-markerTriangle").attr("transform",function(e){return"translate("+y(m[0])+","+p/2+")"}).attr("d","M0,"+M+"L"+M+","+
-M+" "+ -M+","+
-M+"Z").on("mouseover",function(){h.elementMouseover({value:m[0],label:"Previous",pos:[y(m[0]),p/2]})}).on("mouseout",function(){h.elementMouseout({value:m[0],label:"Previous"})}):C.selectAll("path.nv-markerTriangle").remove(),x.selectAll(".nv-range").on("mouseover",function(e,t){var
n=t?t==1?"Mean":"Minimum":"Maximum";h.elementMouseover({value:e,label:n,pos:[y(e),p/2]})}).on("mouseout",function(e,t){var
n=t?t==1?"Mean":"Minimum":"Maximum";h.elementMouseout({value:e,label:n})})}),p}var
t={top:0,right:0,bottom:0,left:0},n="left",r=!1,i=function(e){return
e.ranges},s=function(e){return e.markers},o=function(e){return
e.measures},u=[0],a=380,f=30,l=null,c=e.utils.getColor(["#
1f77b4"]),h=d3.dispatch("elementMouseover","elementMouseout");return
p.dispatch=h,p.orient=function(e){return
arguments.length?(n=e,r=n=="right"||n=="bottom",p):n},p.ranges=function(e){return
arguments.length?(i=e,p):i},p.markers=function(e){return
arguments.length?(s=e,p):s},p.measures=function(e){return
arguments.length?(o=e,p):o},p.forceX=function(e){return
arguments.length?(u=e,p):u},p.width=function(e){return
arguments.length?(a=e,p):a},p.height=function(e){return
arguments.length?(f=e,p):f},p.margin=function(e){return arguments.length?(t.top=typeof
e.top!="undefined"?e.top:t.top,t.right=typeof
e.right!="undefined"?e.right:t.right,t.bottom=typeof
e.bottom!="undefined"?e.bottom:t.bottom,t.left=typeof
e.left!="undefined"?e.left:t.left,p):t},p.tickFormat=function(e){return
arguments.length?(l=e,p):l},p.color=function(t){return
arguments.length?(c=e.utils.getColor(t),p):c},p},e.models.bulletChart=function(){function
m(e){return e.each(function(n,h){var g=d3.select(this),y=(
a||parseInt(g.style("width"))||960)-i.left-i.right,b=f-i.top-i.bottom,w=this;m.update=function(){m(e)},m.container=this;if(!n||!s.call(this,n,h)){var
E=g.selectAll(".nv-noData").data([p]);return
E.enter().append("text").attr("class","nvd3
nv-noData").attr("dy","-.7em").style("text-anchor","middle"),E.attr("x",i.left+y/2).attr("y",18+i.top+b/2).text(function(e){return
e}),m}g.selectAll(".nv-noData").remove();var
S=s.call(this,n,h).slice().sort(d3.descending),x=o.call(this,n,h).slice().sort(d3.descending),T=u.call(this,n,h).slice().sort(d3.descending),N=g.selectAll("g.nv-wrap.nv-bulletChart").data([n]),C=N.enter().append("g").attr("class","nvd3
nv-wrap
nv-bulletChart"),k=C.append("g"),L=N.select("g");k.append("g").attr("class","nv-bulletWrap"),k.append("g").attr("class","nv-titles"),N.attr("transform","translate("+i.left+","+i.top+")");var
A=d3.scale.linear().domain([0,Math.max(S[0],x[0],T[0])]).range(r?[y,0]:[0,y]),O=this.__chart__||d3.scale.linear().domain([0,Infinity]).rang
e(A.range());this.__chart__=A;var M=function(e){return
Math.abs(O(e)-O(0))},_=function(e){return
Math.abs(A(e)-A(0))},D=k.select(".nv-titles").append("g").attr("text-anchor","end").attr("transform","translate(-6,"+(f-i.top-i.bottom)/2+")");D.append("text").attr("class","nv-title").text(function(e){return
e.title}),D.append("text").attr("class","nv-subtitle").attr("dy","1em").text(function(e){return
e.subtitle}),t.width(y).height(b);var
P=L.select(".nv-bulletWrap");d3.transition(P).call(t);var
H=l||A.tickFormat(y/100),B=L.selectAll("g.nv-tick").data(A.ticks(y/50),function(e){return
this.textContent||H(e)}),j=B.enter().append("g").attr("class","nv-tick").attr("transform",function(e){return"translate("+O(e)+",0)"}).style("opacity",1e-6);j.append("line").attr("y1",b).attr("y2",b*7/6),j.append("text").attr("text-anchor","middle").attr("dy","1em").attr("y",b*7/6).text(H);var
F=d3.transition(B).attr("transform",function(e){return"translate("+A(e)+",0)"}).style("opacity",1);F.select
("line").attr("y1",b).attr("y2",b*7/6),F.select("text").attr("y",b*7/6),d3.transition(B.exit()).attr("transform",function(e){return"translate("+A(e)+",0)"}).style("opacity",1e-6).remove(),d.on("tooltipShow",function(e){e.key=n.title,c&&v(e,w.parentNode)})}),d3.timer.flush(),m}var
t=e.models.bullet(),n="left",r=!1,i={top:5,right:40,bottom:20,left:120},s=function(e){return
e.ranges},o=function(e){return e.markers},u=function(e){return
e.measures},a=null,f=55,l=null,c=!0,h=function(e,t,n,r,i){return"<h3>"+t+"</h3>"+"<p>"+n+"</p>"},p="No
Data
Available.",d=d3.dispatch("tooltipShow","tooltipHide"),v=function(t,n){var
r=t.pos[0]+(n.offsetLeft||0)+i.left,s=t.pos[1]+(n.offsetTop||0)+i.top,o=h(t.key,t.label,t.value,t,m);e.tooltip.show([r,s],o,t.value<0?"e":"w",null,n)};return
t.dispatch.on("elementMouseover.tooltip",function(e){d.tooltipShow(e)}),t.dispatch.on("elementMouseout.tooltip",function(e){d.tooltipHide(e)}),d.on("tooltipHide",function(){c&&e.tooltip.cleanup()}),m.dispatch=d,
m.bullet=t,d3.rebind(m,t,"color"),m.orient=function(e){return
arguments.length?(n=e,r=n=="right"||n=="bottom",m):n},m.ranges=function(e){return
arguments.length?(s=e,m):s},m.markers=function(e){return
arguments.length?(o=e,m):o},m.measures=function(e){return
arguments.length?(u=e,m):u},m.width=function(e){return
arguments.length?(a=e,m):a},m.height=function(e){return
arguments.length?(f=e,m):f},m.margin=function(e){return arguments.length?(i.top=typeof
e.top!="undefined"?e.top:i.top,i.right=typeof
e.right!="undefined"?e.right:i.right,i.bottom=typeof
e.bottom!="undefined"?e.bottom:i.bottom,i.left=typeof
e.left!="undefined"?e.left:i.left,m):i},m.tickFormat=function(e){return
arguments.length?(l=e,m):l},m.tooltips=function(e){return
arguments.length?(c=e,m):c},m.tooltipContent=function(e){return
arguments.length?(h=e,m):h},m.noData=function(e){return
arguments.length?(p=e,m):p},m},e.models.cumulativeLineChart=function(){function
C(e){return e.each(function(e){function D(e,t){d3
.select(C.container).style("cursor","ew-resize")}function
P(e,t){T.x=d3.event.x,T.i=Math.round(x.invert(T.x)),J()}function
H(e,t){d3.select(C.container).style("cursor","auto"),y.index=T.i,S.stateChange(y)}function
J(){$.data([T]),d.call(C)}var
d=d3.select(this).classed("nv-chart-"+g,!0),L=this,A=(a||parseInt(d.style("width"))||960)-o.left-o.right,O=(f||parseInt(d.style("height"))||400)-o.top-o.bottom;C.update=function(){d.transition().call(C)},C.container=this,y.disabled=e.map(function(e){return!!e.disabled});if(!b){var
M;b={};for(M in y)y[M]instanceof Array?b[M]=y[M].slice(0):b[M]=y[M]}var
_=d3.behavior.drag().on("dragstart",D).on("drag",P).on("dragend",H);if(!e||!e.length||!e.filter(function(e){return
e.values.length}).length){var B=d.selectAll(".nv-noData").data([w]);return
B.enter().append("text").attr("class","nvd3
nv-noData").attr("dy","-.7em").style("text-anchor","middle"),B.attr("x",o.left+A/2).attr("y",o.top+O/2).text(function(e){return
e}),C}d.selectAll(".nv-noData
").remove(),v=t.xScale(),m=t.yScale();if(!p){var
j=e.filter(function(e){return!e.disabled}).map(function(e,n){var
r=d3.extent(e.values,t.y());return
r[0]<-0.95&&(r[0]=-0.95),[(r[0]-r[1])/(1+r[1]),(r[1]-r[0])/(1+r[0])]}),F=[d3.min(j,function(e){return
e[0]}),d3.max(j,function(e){return e[1]})];t.yDomain(F)}else
t.yDomain(null);x.domain([0,e[0].values.length-1]).range([0,A]).clamp(!0);var
e=k(T.i,e),I=d.selectAll("g.nv-wrap.nv-cumulativeLine").data([e]),q=I.enter().append("g").attr("class","nvd3
nv-wrap
nv-cumulativeLine").append("g"),R=I.select("g");q.append("g").attr("class","nv-x
nv-axis"),q.append("g").attr("class","nv-y
nv-axis"),q.append("g").attr("class","nv-background"),q.append("g").attr("class","nv-linesWrap"),q.append("g").attr("class","nv-avgLinesWrap"),q.append("g").attr("class","nv-legendWrap"),q.append("g").attr("class","nv-controlsWrap"),l&&(i.width(A),R.select(".nv-legendWrap").datum(e).call(i),o.top!=i.height()&&(o.top=i.height(),O=(f||parseInt(d.style("heigh
t"))||400)-o.top-o.bottom),R.select(".nv-legendWrap").attr("transform","translate(0,"+
-o.top+")"));if(h){var U=[{key:"Re-scale
y-axis",disabled:!p}];s.width(140).color(["#444","#444","#444"]),R.select(".nv-controlsWrap").datum(U).attr("transform","translate(0,"+
-o.top+")").call(s)}I.attr("transform","translate("+o.left+","+o.top+")");var
z=e.filter(function(e){return
e.tempDisabled});I.select(".tempDisabled").remove(),z.length&&I.append("text").attr("class","tempDisabled").attr("x",A/2).attr("y","-.71em").style("text-anchor","end").text(z.map(function(e){return
e.key}).join(", ")+" values cannot be calculated for this time
period."),q.select(".nv-background").append("rect"),R.select(".nv-background
rect").attr("width",A).attr("height",O),t.y(function(e){return
e.display.y}).width(A).height(O).color(e.map(function(e,t){return
e.color||u(e,t)}).filter(function(t,n){return!e[n].disabled&&!e[n].tempDisabled}));var
W=R.select(".nv-linesWrap").datum(e.filter(function(e){return!e
.disabled&&!e.tempDisabled}));W.call(t),e.forEach(function(e,t){e.seriesIndex=t});var
X=e.filter(function(e){return!e.disabled&&!!E(e)}),V=R.select(".nv-avgLinesWrap").selectAll("line").data(X,function(e){return
e.key});V.enter().append("line").style("stroke-width",2).style("stroke-dasharray","10,10").style("stroke",function(e,n){return
t.color()(e,e.seriesIndex)}).attr("x1",0).attr("x2",A).attr("y1",function(e){return
m(E(e))}).attr("y2",function(e){return
m(E(e))}),V.attr("x1",0).attr("x2",A).attr("y1",function(e){return
m(E(e))}).attr("y2",function(e){return m(E(e))}),V.exit().remove();var
$=W.selectAll(".nv-indexLine").data([T]);$.enter().append("rect").attr("class","nv-indexLine").attr("width",3).attr("x",-2).attr("fill","red").attr("fill-opacity",.5).call(_),$.attr("transform",function(e){return"translate("+x(e.i)+",0)"}).attr("height",O),n.scale(v).ticks(Math.min(e[0].values.length,A/70)).tickSize(-O,0),R.select(".nv-x.nv-axis").attr("transform","translate(0,"+m.range
()[0]+")"),d3.transition(R.select(".nv-x.nv-axis")).call(n),r.scale(m).ticks(O/36).tickSize(-A,0),d3.transition(R.select(".nv-y.nv-axis")).call(r),R.select(".nv-background
rect").on("click",function(){T.x=d3.mouse(this)[0],T.i=Math.round(x.invert(T.x)),y.index=T.i,S.stateChange(y),J()}),t.dispatch.on("elementClick",function(e){T.i=e.pointIndex,T.x=x(T.i),y.index=T.i,S.stateChange(y),J()}),s.dispatch.on("legendClick",function(e,t){e.disabled=!e.disabled,p=!e.disabled,y.rescaleY=p,S.stateChange(y),C.update()}),i.dispatch.on("legendClick",function(t,n){t.disabled=!t.disabled,e.filter(function(e){return!e.disabled}).length||e.map(function(e){return
e.disabled=!1,I.selectAll(".nv-series").classed("disabled",!1),e}),y.disabled=e.map(function(e){return!!e.disabled}),S.stateChange(y),C.update()}),i.dispatch.on("legendDblclick",function(t){e.forEach(function(e){e.disabled=!0}),t.disabled=!1,y.disabled=e.map(function(e){return!!e.disabled}),S.stateChange(y),C.update()}),S.on("tooltipS
how",function(e){c&&N(e,L.parentNode)}),S.on("changeState",function(t){typeof
t.disabled!="undefined"&&(e.forEach(function(e,n){e.disabled=t.disabled[n]}),y.disabled=t.disabled),typeof
t.index!="undefined"&&(T.i=t.index,T.x=x(T.i),y.index=t.index,$.data([T])),typeof
t.rescaleY!="undefined"&&(p=t.rescaleY),C.update()})}),C}function
k(e,n){return n.map(function(n,r){if(!n.values)return n;var i=t.y()(n.values[e],e);return
i<-0.95?(n.tempDisabled=!0,n):(n.tempDisabled=!1,n.values=n.values.map(function(e,n){return
e.display={y:(t.y()(e,n)-i)/(1+i)},e}),n)})}var
t=e.models.line(),n=e.models.axis(),r=e.models.axis(),i=e.models.legend(),s=e.models.legend(),o={top:30,right:30,bottom:50,left:60},u=e.utils.defaultColor(),a=null,f=null,l=!0,c=!0,h=!0,p=!0,d=function(e,t,n,r,i){return"<h3>"+e+"</h3>"+"<p>"+n+"
at "+t+"</p>"},v,m,g=t.id(),y={index:0,rescaleY:p},b=null,w="No
Data Available.",E=function(e){return
e.average},S=d3.dispatch("tooltipShow","tooltipHide","stateChange","changeStat
e");n.orient("bottom").tickPadding(7),r.orient("left");var
x=d3.scale.linear(),T={i:0,x:0},N=function(i,s){var
o=i.pos[0]+(s.offsetLeft||0),u=i.pos[1]+(s.offsetTop||0),a=n.tickFormat()(t.x()(i.point,i.pointIndex)),f=r.tickFormat()(t.y()(i.point,i.pointIndex)),l=d(i.series.key,a,f,i,C);e.tooltip.show([o,u],l,null,null,s)};return
t.dispatch.on("elementMouseover.tooltip",function(e){e.pos=[e.pos[0]+o.left,e.pos[1]+o.top],S.tooltipShow(e)}),t.dispatch.on("elementMouseout.tooltip",function(e){S.tooltipHide(e)}),S.on("tooltipHide",function(){c&&e.tooltip.cleanup()}),C.dispatch=S,C.lines=t,C.legend=i,C.xAxis=n,C.yAxis=r,d3.rebind(C,t,"defined","isArea","x","y","size","xDomain","yDomain","forceX","forceY","interactive","clipEdge","clipVoronoi","id"),C.margin=function(e){return
arguments.length?(o.top=typeof e.top!="undefined"?e.top:o.top,o.right=typeof
e.right!="undefined"?e.right:o.right,o.bottom=typeof
e.bottom!="undefined"?e.bottom:o.bottom,o.left=typeof
e.left!="undefined"?e.lef
t:o.left,C):o},C.width=function(e){return
arguments.length?(a=e,C):a},C.height=function(e){return
arguments.length?(f=e,C):f},C.color=function(t){return
arguments.length?(u=e.utils.getColor(t),i.color(u),C):u},C.rescaleY=function(e){return
arguments.length?(p=e,p):p},C.showControls=function(e){return
arguments.length?(h=e,C):h},C.showLegend=function(e){return
arguments.length?(l=e,C):l},C.tooltips=function(e){return
arguments.length?(c=e,C):c},C.tooltipContent=function(e){return
arguments.length?(d=e,C):d},C.state=function(e){return
arguments.length?(y=e,C):y},C.defaultState=function(e){return
arguments.length?(b=e,C):b},C.noData=function(e){return
arguments.length?(w=e,C):w},C.average=function(e){return
arguments.length?(E=e,C):E},C},e.models.discreteBar=function(){function b(e){return
e.each(function(e){var
i=n-t.left-t.right,b=r-t.top-t.bottom,w=d3.select(this);e=e.map(function(e,t){return
e.values=e.values.map(function(e){return e.series=t,e}),e});var
E=p&&d?[]:e.map(fun
ction(e){return
e.values.map(function(e,t){return{x:u(e,t),y:a(e,t),y0:e.y0}})});s.domain(p||d3.merge(E).map(function(e){return
e.x})).rangeBands([0,i],.1),o.domain(d||d3.extent(d3.merge(E).map(function(e){return
e.y}).concat(f))),c?o.range([b-(o.domain()[0]<0?12:0),o.domain()[1]>0?12:0]):o.range([b,0]),g=g||s,y=y||o.copy().range([o(0),o(0)]);var
S=w.selectAll("g.nv-wrap.nv-discretebar").data([e]),T=S.enter().append("g").attr("class","nvd3
nv-wrap
nv-discretebar"),N=T.append("g"),C=S.select("g");N.append("g").attr("class","nv-groups"),S.attr("transform","translate("+t.left+","+t.top+")");var
k=S.select(".nv-groups").selectAll(".nv-group").data(function(e){return
e},function(e){return
e.key});k.enter().append("g").style("stroke-opacity",1e-6).style("fill-opacity",1e-6),d3.transition(k.exit()).style("stroke-opacity",1e-6).style("fill-opacity",1e-6).remove(),k.attr("class",function(e,t){return"nv-group
nv-series-"+t}).classed("hover",function(e){return
e.hover}),d3.transition(k
).style("stroke-opacity",1).style("fill-opacity",.75);var
L=k.selectAll("g.nv-bar").data(function(e){return
e.values});L.exit().remove();var
A=L.enter().append("g").attr("transform",function(e,t,n){return"translate("+(s(u(e,t))+s.rangeBand()*.05)+",
"+o(0)+")"}).on("mouseover",function(t,n){d3.select(this).classed("hover",!0),v.elementMouseover({value:a(t,n),point:t,series:e[t.series],pos:[s(u(t,n))+s.rangeBand()*(t.series+.5)/e.length,o(a(t,n))],pointIndex:n,seriesIndex:t.series,e:d3.event})}).on("mouseout",function(t,n){d3.select(this).classed("hover",!1),v.elementMouseout({value:a(t,n),point:t,series:e[t.series],pointIndex:n,seriesIndex:t.series,e:d3.event})}).on("click",function(t,n){v.elementClick({value:a(t,n),point:t,series:e[t.series],pos:[s(u(t,n))+s.rangeBand()*(t.series+.5)/e.length,o(a(t,n))],pointIndex:n,seriesIndex:t.series,e:d3.event}),d3.event.stopPropagation()}).on("dblclick",function(t,n){v.elementDblClick({value:a(t,n),point:t,series:e[t.series],pos:[s(u(t
,n))+s.rangeBand()*(t.series+.5)/e.length,o(a(t,n))],pointIndex:n,seriesIndex:t.series,e:d3.event}),d3.event.stopPropagation()});A.append("rect").attr("height",0).attr("width",s.rangeBand()*.9/e.length),c?(A.append("text").attr("text-anchor","middle"),L.select("text").attr("x",s.rangeBand()*.9/2).attr("y",function(e,t){return
a(e,t)<0?o(a(e,t))-o(0)+12:-4}).text(function(e,t){return
h(a(e,t))})):L.selectAll("text").remove(),L.attr("class",function(e,t){return
a(e,t)<0?"nv-bar negative":"nv-bar
positive"}).style("fill",function(e,t){return
e.color||l(e,t)}).style("stroke",function(e,t){return
e.color||l(e,t)}).select("rect").attr("class",m).attr("width",s.rangeBand()*.9/e.length),d3.transition(L).attr("transform",function(e,t){var
n=s(u(e,t))+s.rangeBand()*.05,r=a(e,t)<0?o(0):o(0)-o(a(e,t))<1?o(0)-1:o(a(e,t));return"translate("+n+",
"+r+")"}).select("rect").attr("height",function(e,t){return
Math.max(Math.abs(o(a(e,t))-o(0))||1)}),g=s.copy(),y=o.copy()}),b}var t={top:0,right:
0,bottom:0,left:0},n=960,r=500,i=Math.floor(Math.random()*1e4),s=d3.scale.ordinal(),o=d3.scale.linear(),u=function(e){return
e.x},a=function(e){return
e.y},f=[0],l=e.utils.defaultColor(),c=!1,h=d3.format(",.2f"),p,d,v=d3.dispatch("chartClick","elementClick","elementDblClick","elementMouseover","elementMouseout"),m="discreteBar",g,y;return
b.dispatch=v,b.x=function(e){return arguments.length?(u=e,b):u},b.y=function(e){return
arguments.length?(a=e,b):a},b.margin=function(e){return arguments.length?(t.top=typeof
e.top!="undefined"?e.top:t.top,t.right=typeof
e.right!="undefined"?e.right:t.right,t.bottom=typeof
e.bottom!="undefined"?e.bottom:t.bottom,t.left=typeof
e.left!="undefined"?e.left:t.left,b):t},b.width=function(e){return
arguments.length?(n=e,b):n},b.height=function(e){return
arguments.length?(r=e,b):r},b.xScale=function(e){return
arguments.length?(s=e,b):s},b.yScale=function(e){return
arguments.length?(o=e,b):o},b.xDomain=function(e){return arguments.length?(p=e,b):p},b
.yDomain=function(e){return arguments.length?(d=e,b):d},b.forceY=function(e){return
arguments.length?(f=e,b):f},b.color=function(t){return
arguments.length?(l=e.utils.getColor(t),b):l},b.id=function(e){return
arguments.length?(i=e,b):i},b.showValues=function(e){return
arguments.length?(c=e,b):c},b.valueFormat=function(e){return
arguments.length?(h=e,b):h},b.rectClass=function(e){return
arguments.length?(m=e,b):m},b},e.models.discreteBarChart=function(){function m(e){return
e.each(function(e){var
u=d3.select(this),l=this,g=(s||parseInt(u.style("width"))||960)-i.left-i.right,b=(o||parseInt(u.style("height"))||400)-i.top-i.bottom;m.update=function(){d.beforeUpdate(),u.transition().call(m)},m.container=this;if(!e||!e.length||!e.filter(function(e){return
e.values.length}).length){var w=u.selectAll(".nv-noData").data([p]);return
w.enter().append("text").attr("class","nvd3
nv-noData").attr("dy","-.7em").style("text-anchor","middle"),w.attr("x",i.left+g/2).attr("y",i.top+b/2).text(f
unction(e){return
e}),m}u.selectAll(".nv-noData").remove(),c=t.xScale(),h=t.yScale();var
E=u.selectAll("g.nv-wrap.nv-discreteBarWithAxes").data([e]),S=E.enter().append("g").attr("class","nvd3
nv-wrap
nv-discreteBarWithAxes").append("g"),T=S.append("defs"),N=E.select("g");S.append("g").attr("class","nv-x
nv-axis"),S.append("g").attr("class","nv-y
nv-axis"),S.append("g").attr("class","nv-barsWrap"),N.attr("transform","translate("+i.left+","+i.top+")"),t.width(g).height(b);var
C=N.select(".nv-barsWrap").datum(e.filter(function(e){return!e.disabled}));d3.transition(C).call(t),T.append("clipPath").attr("id","nv-x-label-clip-"+t.id()).append("rect"),N.select("#nv-x-label-clip-"+t.id()+"
rect").attr("width",c.rangeBand()*(a?2:1)).attr("height",16).attr("x",-c.rangeBand()/(a?1:2)),n.scale(c).ticks(g/100).tickSize(-b,0),N.select(".nv-x.nv-axis").attr("transform","translate(0,"+(h.range()[0]+(t.showValues()&&h.domain()[0]<0?16:0))+")"),N.select(".nv-x.nv-axis").transition().duration(0
).call(n);var
k=N.select(".nv-x.nv-axis").selectAll("g");a&&k.selectAll("text").attr("transform",function(e,t,n){return"translate(0,"+
-(n%2==0?"5":"17")+")"}),r.scale(h).ticks(b/36).tickSize(-g,0),d3.transition(N.select(".nv-y.nv-axis")).call(r),d.on("tooltipShow",function(e){f&&v(e,l.parentNode)})}),m}var
t=e.models.discreteBar(),n=e.models.axis(),r=e.models.axis(),i={top:15,right:10,bottom:50,left:60},s=null,o=null,u=e.utils.getColor(),a=!1,f=!0,l=function(e,t,n,r,i){return"<h3>"+t+"</h3>"+"<p>"+n+"</p>"},c,h,p="No
Data
Available.",d=d3.dispatch("tooltipShow","tooltipHide","beforeUpdate");n.orient("bottom").highlightZero(!1).showMaxMin(!1).tickFormat(function(e){return
e}),r.orient("left").tickFormat(d3.format(",.1f"));var
v=function(i,s){var
o=i.pos[0]+(s.offsetLeft||0),u=i.pos[1]+(s.offsetTop||0),a=n.tickFormat()(t.x()(i.point,i.pointIndex)),f=r.tickFormat()(t.y()(i.point,i.pointIndex)),c=l(i.series.key,a,f,i,m);e.tooltip.show([o,u],c,i.value<0?"n":"s",null,s)};return
t.dispatch.on("elementMouseover.tooltip",function(e){e.pos=[e.pos[0]+i.left,e.pos[1]+i.top],d.tooltipShow(e)}),t.dispatch.on("elementMous
eout.tooltip",function(e){d.tooltipHide(e)}),d.on("tooltipHide",function(){f&&e.tooltip.cleanup()}),m.dispatch=d,m.discretebar=t,m.xAxis=n,m.yAxis=r,d3.rebind(m,t,"x","y","xDomain","yDomain","forceX","forceY","id","showValues","valueFormat"),m.margin=function(e){return
arguments.length?(i.top=typeof e.top!="undefined"?e.top:i.top,i.right=typeof
e.right!="undefined"?e.right:i.right,i.bottom=typeof
e.bottom!="undefined"?e.bottom:i.bottom,i.left=typeof
e.left!="undefined"?e.left:i.left,m):i},m.width=function(e){return
arguments.length?(s=e,m):s},m.height=function(e){return
arguments.length?(o=e,m):o},m.color=function(n){return
arguments.length?(u=e.utils.getColor(n),t.color(u),m):u},m.staggerLabels=function(e){return
arguments.length?(a=e,m):a},m.tooltips=function(e){return
arguments.length?(f=e,m):f},m.tooltipContent=function(e){return
arguments.length?(l=e,m):l},m.noData=function(e){return
arguments.length?(p=e,m):p},m},e.models.distribution=function(){function l(e){return e.
each(function(e){var
a=n-(i==="x"?t.left+t.right:t.top+t.bottom),l=i=="x"?"y":"x",c=d3.select(this);f=f||u;var
h=c.selectAll("g.nv-distribution").data([e]),p=h.enter().append("g").attr("class","nvd3
nv-distribution"),d=p.append("g"),v=h.select("g");h.attr("transform","translate("+t.left+","+t.top+")");var
m=v.selectAll("g.nv-dist").data(function(e){return e},function(e){return
e.key});m.enter().append("g"),m.attr("class",function(e,t){return"nv-dist
nv-series-"+t}).style("stroke",function(e,t){return o(e,t)});var
g=m.selectAll("line.nv-dist"+i).data(function(e){return
e.values});g.enter().append("line").attr(i+"1",function(e,t){return
f(s(e,t))}).attr(i+"2",function(e,t){return
f(s(e,t))}),d3.transition(m.exit().selectAll("line.nv-dist"+i)).attr(i+"1",function(e,t){return
u(s(e,t))}).attr(i+"2",function(e,t){return
u(s(e,t))}).style("stroke-opacity",0).remove(),g.attr("class",function(e,t){return"nv-dist"+i+"
nv-dist"+i+"-"+t}).attr(l+"1",0).attr(l+"2",r),d3.transition(g).at
tr(i+"1",function(e,t){return
u(s(e,t))}).attr(i+"2",function(e,t){return u(s(e,t))}),f=u.copy()}),l}var
t={top:0,right:0,bottom:0,left:0},n=400,r=8,i="x",s=function(e){return
e[i]},o=e.utils.defaultColor(),u=d3.scale.linear(),a,f;return l.margin=function(e){return
arguments.length?(t.top=typeof e.top!="undefined"?e.top:t.top,t.right=typeof
e.right!="undefined"?e.right:t.right,t.bottom=typeof
e.bottom!="undefined"?e.bottom:t.bottom,t.left=typeof
e.left!="undefined"?e.left:t.left,l):t},l.width=function(e){return
arguments.length?(n=e,l):n},l.axis=function(e){return
arguments.length?(i=e,l):i},l.size=function(e){return
arguments.length?(r=e,l):r},l.getData=function(e){return
arguments.length?(s=d3.functor(e),l):s},l.scale=function(e){return
arguments.length?(u=e,l):u},l.color=function(t){return
arguments.length?(o=e.utils.getColor(t),l):o},l},e.models.historicalBar=function(){function
g(e){return e.each(function(e){var
g=n-t.left-t.right,b=r-t.top-t.bottom,w=d3.select(this);s.
domain(d||d3.extent(e[0].values.map(u).concat(f))),c?s.range([g*.5/e[0].values.length,g*(e[0].values.length-.5)/e[0].values.length]):s.range([0,g]),o.domain(v||d3.extent(e[0].values.map(a).concat(l))).range([b,0]);if(s.domain()[0]===s.domain()[1]||o.domain()[0]===o.domain()[1])singlePoint=!0;s.domain()[0]===s.domain()[1]&&(s.domain()[0]?s.domain([s.domain()[0]-s.domain()[0]*.01,s.domain()[1]+s.domain()[1]*.01]):s.domain([-1,1])),o.domain()[0]===o.domain()[1]&&(o.domain()[0]?o.domain([o.domain()[0]+o.domain()[0]*.01,o.domain()[1]-o.domain()[1]*.01]):o.domain([-1,1]));var
E=w.selectAll("g.nv-wrap.nv-bar").data([e[0].values]),S=E.enter().append("g").attr("class","nvd3
nv-wrap
nv-bar"),T=S.append("defs"),N=S.append("g"),C=E.select("g");N.append("g").attr("class","nv-bars"),E.attr("transform","translate("+t.left+","+t.top+")"),w.on("click",function(e,t){m.chartClick({data:e,index:t,pos:d3.event,id:i})}),T.append("clipPath").attr("id","nv-chart-clip-path-"+i).append("rect"),E.sele
ct("#nv-chart-clip-path-"+i+"
rect").attr("width",g).attr("height",b),C.attr("clip-path",h?"url(#nv-chart-clip-path-"+i+")":"");var
k=E.select(".nv-bars").selectAll(".nv-bar").data(function(e){return
e});k.exit().remove();var
L=k.enter().append("rect").attr("x",0).attr("y",function(e,t){return
o(Math.max(0,a(e,t)))}).attr("height",function(e,t){return
Math.abs(o(a(e,t))-o(0))}).on("mouseover",function(t,n){d3.select(this).classed("hover",!0),m.elementMouseover({point:t,series:e[0],pos:[s(u(t,n)),o(a(t,n))],pointIndex:n,seriesIndex:0,e:d3.event})}).on("mouseout",function(t,n){d3.select(this).classed("hover",!1),m.elementMouseout({point:t,series:e[0],pointIndex:n,seriesIndex:0,e:d3.event})}).on("click",function(e,t){m.elementClick({value:a(e,t),data:e,index:t,pos:[s(u(e,t)),o(a(e,t))],e:d3.event,id:i}),d3.event.stopPropagation()}).on("dblclick",function(e,t){m.elementDblClick({value:a(e,t),data:e,index:t,pos:[s(u(e,t)),o(a(e,t))],e:d3.event,id:i}),d3.event.stopPropagation()});
k.attr("fill",function(e,t){return
p(e,t)}).attr("class",function(e,t,n){return(a(e,t)<0?"nv-bar
negative":"nv-bar positive")+"
nv-bar-"+n+"-"+t}).attr("transform",function(t,n){return"translate("+(s(u(t,n))-g/e[0].values.length*.45)+",0)"}).attr("width",g/e[0].values.length*.9),d3.transition(k).attr("y",function(e,t){return
a(e,t)<0?o(0):o(0)-o(a(e,t))<1?o(0)-1:o(a(e,t))}).attr("height",function(e,t){return
Math.max(Math.abs(o(a(e,t))-o(0)),1)})}),g}var
t={top:0,right:0,bottom:0,left:0},n=960,r=500,i=Math.floor(Math.random()*1e4),s=d3.scale.linear(),o=d3.scale.linear(),u=function(e){return
e.x},a=function(e){return
e.y},f=[],l=[0],c=!1,h=!0,p=e.utils.defaultColor(),d,v,m=d3.dispatch("chartClick","elementClick","elementDblClick","elementMouseover","elementMouseout");return
g.dispatch=m,g.x=function(e){return arguments.length?(u=e,g):u},g.y=function(e){return
arguments.length?(a=e,g):a},g.margin=function(e){return arguments.length?(t.top=typeof
e.top!="undefined"?e.top:t.top,
t.right=typeof e.right!="undefined"?e.right:t.right,t.bottom=typeof
e.bottom!="undefined"?e.bottom:t.bottom,t.left=typeof
e.left!="undefined"?e.left:t.left,g):t},g.width=function(e){return
arguments.length?(n=e,g):n},g.height=function(e){return
arguments.length?(r=e,g):r},g.xScale=function(e){return
arguments.length?(s=e,g):s},g.yScale=function(e){return
arguments.length?(o=e,g):o},g.xDomain=function(e){return
arguments.length?(d=e,g):d},g.yDomain=function(e){return
arguments.length?(v=e,g):v},g.forceX=function(e){return
arguments.length?(f=e,g):f},g.forceY=function(e){return
arguments.length?(l=e,g):l},g.padData=function(e){return
arguments.length?(c=e,g):c},g.clipEdge=function(e){return
arguments.length?(h=e,g):h},g.color=function(t){return
arguments.length?(p=e.utils.getColor(t),g):p},g.id=function(e){return
arguments.length?(i=e,g):i},g},e.models.historicalBarChart=function(){function S(e){return
e.each(function(d){var T=d3.select(this),N=this,C=(u||parseInt(T.style("wid
th"))||960)-s.left-s.right,k=(a||parseInt(T.style("height"))||400)-s.top-s.bottom;S.update=function(){S(e)},S.container=this,g.disabled=d.map(function(e){return!!e.disabled});if(!y){var
L;y={};for(L in g)g[L]instanceof
Array?y[L]=g[L].slice(0):y[L]=g[L]}if(!d||!d.length||!d.filter(function(e){return
e.values.length}).length){var A=T.selectAll(".nv-noData").data([b]);return
A.enter().append("text").attr("class","nvd3
nv-noData").attr("dy","-.7em").style("text-anchor","middle"),A.attr("x",s.left+C/2).attr("y",s.top+k/2).text(function(e){return
e}),S}T.selectAll(".nv-noData").remove(),v=t.xScale(),m=t.yScale();var
O=T.selectAll("g.nv-wrap.nv-lineChart").data([d]),M=O.enter().append("g").attr("class","nvd3
nv-wrap
nv-lineChart").append("g"),_=O.select("g");M.append("g").attr("class","nv-x
nv-axis"),M.append("g").attr("class","nv-y
nv-axis"),M.append("g").attr("class","nv-barsWrap"),M.append("g").attr("class","nv-legendWrap"),f&&(i.width(C),_.select(".nv-legendWrap").datum(d).cal
l(i),s.top!=i.height()&&(s.top=i.height(),k=(a||parseInt(T.style("height"))||400)-s.top-s.bottom),O.select(".nv-legendWrap").attr("transform","translate(0,"+
-s.top+")")),O.attr("transform","translate("+s.left+","+s.top+")"),h&&_.select(".nv-y.nv-axis").attr("transform","translate("+C+",0)"),t.width(C).height(k).color(d.map(function(e,t){return
e.color||o(e,t)}).filter(function(e,t){return!d[t].disabled}));var
D=_.select(".nv-barsWrap").datum(d.filter(function(e){return!e.disabled}));d3.transition(D).call(t),l&&(n.scale(v).tickSize(-k,0),_.select(".nv-x.nv-axis").attr("transform","translate(0,"+m.range()[0]+")"),_.select(".nv-x.nv-axis").transition().call(n)),c&&(r.scale(m).ticks(k/36).tickSize(-C,0),_.select(".nv-y.nv-axis").transition().duration(0).call(r)),i.dispatch.on("legendClick",function(t,n){t.disabled=!t.disabled,d.filter(function(e){return!e.disabled}).length||d.map(function(e){return
e.disabled=!1,O.selectAll(".nv-series").classed("disabled",!1),e}),g.disabled=d.
map(function(e){return!!e.disabled}),w.stateChange(g),e.transition().call(S)}),i.dispatch.on("legendDblclick",function(e){d.forEach(function(e){e.disabled=!0}),e.disabled=!1,g.disabled=d.map(function(e){return!!e.disabled}),w.stateChange(g),S.update()}),w.on("tooltipShow",function(e){p&&E(e,N.parentNode)}),w.on("changeState",function(t){typeof
t.disabled!="undefined"&&(d.forEach(function(e,n){e.disabled=t.disabled[n]}),g.disabled=t.disabled),e.call(S)})}),S}var
t=e.models.historicalBar(),n=e.models.axis(),r=e.models.axis(),i=e.models.legend(),s={top:30,right:90,bottom:50,left:90},o=e.utils.defaultColor(),u=null,a=null,f=!1,l=!0,c=!0,h=!1,p=!0,d=function(e,t,n,r,i){return"<h3>"+e+"</h3>"+"<p>"+n+"
at "+t+"</p>"},v,m,g={},y=null,b="No Data
Available.",w=d3.dispatch("tooltipShow","tooltipHide","stateChange","changeState");n.orient("bottom").tickPadding(7),r.orient(h?"right":"left");var
E=function(i,s){if(s){var
o=d3.select(s).select("svg"),u=o.node()?o.attr("viewBox"):null;if(u
){u=u.split(" ");var
a=parseInt(o.style("width"))/u[2];i.pos[0]=i.pos[0]*a,i.pos[1]=i.pos[1]*a}}var
f=i.pos[0]+(s.offsetLeft||0),l=i.pos[1]+(s.offsetTop||0),c=n.tickFormat()(t.x()(i.point,i.pointIndex)),h=r.tickFormat()(t.y()(i.point,i.pointIndex)),p=d(i.series.key,c,h,i,S);e.tooltip.show([f,l],p,null,null,s)};return
t.dispatch.on("elementMouseover.tooltip",function(e){e.pos=[e.pos[0]+s.left,e.pos[1]+s.top],w.tooltipShow(e)}),t.dispatch.on("elementMouseout.tooltip",function(e){w.tooltipHide(e)}),w.on("tooltipHide",function(){p&&e.tooltip.cleanup()}),S.dispatch=w,S.bars=t,S.legend=i,S.xAxis=n,S.yAxis=r,d3.rebind(S,t,"defined","isArea","x","y","size","xScale","yScale","xDomain","yDomain","forceX","forceY","interactive","clipEdge","clipVoronoi","id","interpolate"),S.margin=function(e){return
arguments.length?(s.top=typeof e.top!="undefined"?e.top:s.top,s.right=typeof
e.right!="undefined"?e.right:s.right,s.bottom=typeof
e.bottom!="undefined"?e.bottom:s.bottom,s.left=typeof e.lef
t!="undefined"?e.left:s.left,S):s},S.width=function(e){return
arguments.length?(u=e,S):u},S.height=function(e){return
arguments.length?(a=e,S):a},S.color=function(t){return
arguments.length?(o=e.utils.getColor(t),i.color(o),S):o},S.showLegend=function(e){return
arguments.length?(f=e,S):f},S.showXAxis=function(e){return
arguments.length?(l=e,S):l},S.showYAxis=function(e){return
arguments.length?(c=e,S):c},S.rightAlignYAxis=function(e){return
arguments.length?(h=e,r.orient(e?"right":"left"),S):h},S.tooltips=function(e){return
arguments.length?(p=e,S):p},S.tooltipContent=function(e){return
arguments.length?(d=e,S):d},S.state=function(e){return
arguments.length?(g=e,S):g},S.defaultState=function(e){return
arguments.length?(y=e,S):y},S.noData=function(e){return
arguments.length?(b=e,S):b},S},e.models.indentedTree=function(){function m(e){return
e.each(function(e){function
C(e,t,n){d3.event.stopPropagation();if(d3.event.shiftKey&&!n)return
d3.event.shiftKey=!1,e.values&&e.values.f
orEach(function(e){(e.values||e._values)&&C(e,0,!0)}),!0;if(!A(e))return!0;e.values?(e._values=e.values,e.values=null):(e.values=e._values,e._values=null),m.update()}function
k(e){return
e._values&&e._values.length?h:e.values&&e.values.length?p:""}function
L(e){return e._values&&e._values.length}function A(e){var
t=e.values||e._values;return t&&t.length}var
t=1,n=d3.select(this),i=d3.layout.tree().children(function(e){return
e.values}).size([r,f]);m.update=function(){n.transition().duration(600).call(m)},e[0]||(e[0]={key:a});var
s=i.nodes(e[0]),g=d3.select(this).selectAll("div").data([[s]]),y=g.enter().append("div").attr("class","nvd3
nv-wrap
nv-indentedtree"),b=y.append("table"),w=g.select("table").attr("width","100%").attr("class",c);if(o){var
E=b.append("thead"),S=E.append("tr");l.forEach(function(e){S.append("th").attr("width",e.width?e.width:"10%").style("text-align",e.type=="numeric"?"right":"left").append("span").text(e.label)})}var
x=w.selectAll("tbody").data(functio
n(e){return e});x.enter().append("tbody"),t=d3.max(s,function(e){return
e.depth}),i.size([r,t*f]);var T=x.selectAll("tr").data(function(e){return
e.filter(function(e){return u&&!e.children?u(e):!0})},function(e,t){return
e.id||e.id||++v});T.exit().remove(),T.select("img.nv-treeicon").attr("src",k).classed("folded",L);var
N=T.enter().append("tr");l.forEach(function(e,t){var
n=N.append("td").style("padding-left",function(e){return(t?0:e.depth*f+12+(k(e)?0:16))+"px"},"important").style("text-align",e.type=="numeric"?"right":"left");t==0&&n.append("img").classed("nv-treeicon",!0).classed("nv-folded",L).attr("src",k).style("width","14px").style("height","14px").style("padding","0
1px").style("display",function(e){return
k(e)?"inline-block":"none"}).on("click",C),n.append("span").attr("class",d3.functor(e.classes)).text(function(t){return
e.format?e.format(t):t[e.key]||"-"}),e.showCount&&(n.append("span").attr("class","nv-childrenCount"),T.selectAll("span.nv-childrenCount").text(f
unction(e){return
e.values&&e.values.length||e._values&&e._values.length?"("+(e.values&&e.values.filter(function(e){return
u?u(e):!0}).length||e._values&&e._values.filter(function(e){return
u?u(e):!0}).length||0)+")":""})),e.click&&n.select("span").on("click",e.click)}),T.order().on("click",function(e){d.elementClick({row:this,data:e,pos:[e.x,e.y]})}).on("dblclick",function(e){d.elementDblclick({row:this,data:e,pos:[e.x,e.y]})}).on("mouseover",function(e){d.elementMouseover({row:this,data:e,pos:[e.x,e.y]})}).on("mouseout",function(e){d.elementMouseout({row:this,data:e,pos:[e.x,e.y]})})}),m}var
t={top:0,right:0,bottom:0,left:0},n=960,r=500,i=e.utils.defaultColor(),s=Math.floor(Math.random()*1e4),o=!0,u=!1,a="No
Data
Available.",f=20,l=[{key:"key",label:"Name",type:"text"}],c=null,h="images/grey-plus.png",p="images/grey-minus.png",d=d3.dispatch("elementClick","elementDblclick","elementMouseover","elementMouseout"),v=0;return
m.margin=function(e){return arguments.length?(t.top=
typeof e.top!="undefined"?e.top:t.top,t.right=typeof
e.right!="undefined"?e.right:t.right,t.bottom=typeof
e.bottom!="undefined"?e.bottom:t.bottom,t.left=typeof
e.left!="undefined"?e.left:t.left,m):t},m.width=function(e){return
arguments.length?(n=e,m):n},m.height=function(e){return
arguments.length?(r=e,m):r},m.color=function(t){return
arguments.length?(i=e.utils.getColor(t),scatter.color(i),m):i},m.id=function(e){return
arguments.length?(s=e,m):s},m.header=function(e){return
arguments.length?(o=e,m):o},m.noData=function(e){return
arguments.length?(a=e,m):a},m.filterZero=function(e){return
arguments.length?(u=e,m):u},m.columns=function(e){return
arguments.length?(l=e,m):l},m.tableClass=function(e){return
arguments.length?(c=e,m):c},m.iconOpen=function(e){return
arguments.length?(h=e,m):h},m.iconClose=function(e){return
arguments.length?(p=e,m):p},m},e.models.legend=function(){function a(f){return
f.each(function(a){var f=n-t.left-t.right,l=d3.select(this),c=l.selectAll("g.nv
-legend").data([a]),h=c.enter().append("g").attr("class","nvd3
nv-legend").append("g"),p=c.select("g");c.attr("transform","translate("+t.left+","+t.top+")");var
d=p.selectAll(".nv-series").data(function(e){return
e}),v=d.enter().append("g").attr("class","nv-series").on("mouseover",function(e,t){u.legendMouseover(e,t)}).on("mouseout",function(e,t){u.legendMouseout(e,t)}).on("click",function(e,t){u.legendClick(e,t)}).on("dblclick",function(e,t){u.legendDblclick(e,t)});v.append("circle").style("stroke-width",2).attr("r",5),v.append("text").attr("text-anchor","start").attr("dy",".32em").attr("dx","8"),d.classed("disabled",function(e){return
e.disabled}),d.exit().remove(),d.select("circle").style("fill",function(e,t){return
e.color||s(e,t)}).style("stroke",function(e,t){return
e.color||s(e,t)}),d.select("text").text(i);if(o){var
m=[];d.each(function(t,n){var
r=d3.select(this).select("text"),i=r.node().getComputedTextLength()||e.utils.calcApproxTextWidth(r);m.push(i+28)});var
g=0,
y=0,b=[];while(y<f&&g<m.length)b[g]=m[g],y+=m[g++];while(y>f&&g>1){b=[],g--;for(k=0;k<m.length;k++)m[k]>(b[k%g]||0)&&(b[k%g]=m[k]);y=b.reduce(function(e,t,n,r){return
e+t})}var w=[];for(var
E=0,S=0;E<g;E++)w[E]=S,S+=b[E];d.attr("transform",function(e,t){return"translate("+w[t%g]+","+(5+Math.floor(t/g)*20)+")"}),p.attr("transform","translate("+(n-t.right-y)+","+t.top+")"),r=t.top+t.bottom+Math.ceil(m.length/g)*20}else{var
x=5,T=5,N=0,C;d.attr("transform",function(e,r){var
i=d3.select(this).select("text").node().getComputedTextLength()+28;return
C=T,n<t.left+t.right+C+i&&(T=C=5,x+=20),T+=i,T>N&&(N=T),"translate("+C+","+x+")"}),p.attr("transform","translate("+(n-t.right-N)+","+t.top+")"),r=t.top+t.bottom+x+15}}),a}var
t={top:5,right:0,bottom:5,left:0},n=400,r=20,i=function(e){return
e.key},s=e.utils.defaultColor(),o=!0,u=d3.dispatch("legendClick","legendDblclick","legendMouseover","legendMouseout");return
a.dispatch=u,a.margin=function(e){return arguments.length?(t.top=typeof e
.top!="undefined"?e.top:t.top,t.right=typeof
e.right!="undefined"?e.right:t.right,t.bottom=typeof
e.bottom!="undefined"?e.bottom:t.bottom,t.left=typeof
e.left!="undefined"?e.left:t.left,a):t},a.width=function(e){return
arguments.length?(n=e,a):n},a.height=function(e){return
arguments.length?(r=e,a):r},a.key=function(e){return
arguments.length?(i=e,a):i},a.color=function(t){return
arguments.length?(s=e.utils.getColor(t),a):s},a.align=function(e){return
arguments.length?(o=e,a):o},a},e.models.line=function(){function m(e){return
e.each(function(e){var
m=r-n.left-n.right,g=i-n.top-n.bottom,b=d3.select(this);c=t.xScale(),h=t.yScale(),d=d||c,v=v||h;var
w=b.selectAll("g.nv-wrap.nv-line").data([e]),E=w.enter().append("g").attr("class","nvd3
nv-wrap
nv-line"),S=E.append("defs"),T=E.append("g"),N=w.select("g");T.append("g").attr("class","nv-groups"),T.append("g").attr("class","nv-scatterWrap"),w.attr("transform","translate("+n.left+","+n.top+")"),t.width(m).height(g);var
C=w.select("
.nv-scatterWrap");d3.transition(C).call(t),S.append("clipPath").attr("id","nv-edge-clip-"+t.id()).append("rect"),w.select("#nv-edge-clip-"+t.id()+"
rect").attr("width",m).attr("height",g),N.attr("clip-path",l?"url(#nv-edge-clip-"+t.id()+")":""),C.attr("clip-path",l?"url(#nv-edge-clip-"+t.id()+")":"");var
k=w.select(".nv-groups").selectAll(".nv-group").data(function(e){return
e},function(e){return
e.key});k.enter().append("g").style("stroke-opacity",1e-6).style("fill-opacity",1e-6),d3.transition(k.exit()).style("stroke-opacity",1e-6).style("fill-opacity",1e-6).remove(),k.attr("class",function(e,t){return"nv-group
nv-series-"+t}).classed("hover",function(e){return
e.hover}).style("fill",function(e,t){return
s(e,t)}).style("stroke",function(e,t){return
s(e,t)}),d3.transition(k).style("stroke-opacity",1).style("fill-opacity",.5);var
L=k.selectAll("path.nv-area").data(function(e){return
f(e)?[e]:[]});L.enter().append("path").attr("class","nv-area").attr("d",function(e){return
d3.
svg.area().interpolate(p).defined(a).x(function(e,t){return
d(o(e,t))}).y0(function(e,t){return v(u(e,t))}).y1(function(e,t){return
v(h.domain()[0]<=0?h.domain()[1]>=0?0:h.domain()[1]:h.domain()[0])}).apply(this,[e.values])}),d3.transition(k.exit().selectAll("path.nv-area")).attr("d",function(e){return
d3.svg.area().interpolate(p).defined(a).x(function(e,t){return
c(o(e,t))}).y0(function(e,t){return h(u(e,t))}).y1(function(e,t){return
h(h.domain()[0]<=0?h.domain()[1]>=0?0:h.domain()[1]:h.domain()[0])}).apply(this,[e.values])}),d3.transition(L).attr("d",function(e){return
d3.svg.area().interpolate(p).defined(a).x(function(e,t){return
c(o(e,t))}).y0(function(e,t){return h(u(e,t))}).y1(function(e,t){return
h(h.domain()[0]<=0?h.domain()[1]>=0?0:h.domain()[1]:h.domain()[0])}).apply(this,[e.values])});var
A=k.selectAll("path.nv-line").data(function(e){return[e.values]});A.enter().append("path").attr("class","nv-line").attr("d",d3.svg.line().interpolate(p).defined(a).x(function(e,t
){return d(o(e,t))}).y(function(e,t){return
v(u(e,t))})),d3.transition(k.exit().selectAll("path.nv-line")).attr("d",d3.svg.line().interpolate(p).defined(a).x(function(e,t){return
c(o(e,t))}).y(function(e,t){return
h(u(e,t))})),d3.transition(A).attr("d",d3.svg.line().interpolate(p).defined(a).x(function(e,t){return
c(o(e,t))}).y(function(e,t){return h(u(e,t))})),d=c.copy(),v=h.copy()}),m}var
t=e.models.scatter(),n={top:0,right:0,bottom:0,left:0},r=960,i=500,s=e.utils.defaultColor(),o=function(e){return
e.x},u=function(e){return
e.y},a=function(e,t){return!isNaN(u(e,t))&&u(e,t)!==null},f=function(e){return
e.area},l=!1,c,h,p="linear";t.size(16).sizeDomain([16,256]);var d,v;return
m.dispatch=t.dispatch,m.scatter=t,d3.rebind(m,t,"id","interactive","size","xScale","yScale","zScale","xDomain","yDomain","sizeDomain","forceX","forceY","forceSize","clipVoronoi","clipRadius","padData"),m.margin=function(e){return
arguments.length?(n.top=typeof e.top!="undefined"?e.top:n.top,n.right=ty
peof e.right!="undefined"?e.right:n.right,n.bottom=typeof
e.bottom!="undefined"?e.bottom:n.bottom,n.left=typeof
e.left!="undefined"?e.left:n.left,m):n},m.width=function(e){return
arguments.length?(r=e,m):r},m.height=function(e){return
arguments.length?(i=e,m):i},m.x=function(e){return
arguments.length?(o=e,t.x(e),m):o},m.y=function(e){return
arguments.length?(u=e,t.y(e),m):u},m.clipEdge=function(e){return
arguments.length?(l=e,m):l},m.color=function(n){return
arguments.length?(s=e.utils.getColor(n),t.color(s),m):s},m.interpolate=function(e){return
arguments.length?(p=e,m):p},m.defined=function(e){return
arguments.length?(a=e,m):a},m.isArea=function(e){return
arguments.length?(f=d3.functor(e),m):f},m},e.models.lineChart=function(){function
S(e){return e.each(function(e){var
d=d3.select(this),T=this,N=(u||parseInt(d.style("width"))||960)-s.left-s.right,C=(a||parseInt(d.style("height"))||400)-s.top-s.bottom;S.update=function(){d.transition().call(S)},S.container=this,g.disabled
=e.map(function(e){return!!e.disabled});if(!y){var k;y={};for(k in g)g[k]instanceof
Array?y[k]=g[k].slice(0):y[k]=g[k]}if(!e||!e.length||!e.filter(function(e){return
e.values.length}).length){var L=d.selectAll(".nv-noData").data([b]);return
L.enter().append("text").attr("class","nvd3
nv-noData").attr("dy","-.7em").style("text-anchor","middle"),L.attr("x",s.left+N/2).attr("y",s.top+C/2).text(function(e){return
e}),S}d.selectAll(".nv-noData").remove(),v=t.xScale(),m=t.yScale();var
A=d.selectAll("g.nv-wrap.nv-lineChart").data([e]),O=A.enter().append("g").attr("class","nvd3
nv-wrap
nv-lineChart").append("g"),M=A.select("g");O.append("g").attr("class","nv-x
nv-axis"),O.append("g").attr("class","nv-y
nv-axis"),O.append("g").attr("class","nv-linesWrap"),O.append("g").attr("class","nv-legendWrap"),f&&(i.width(N),M.select(".nv-legendWrap").datum(e).call(i),s.top!=i.height()&&(s.top=i.height(),C=(a||parseInt(d.style("height"))||400)-s.top-s.bottom),A.select(".nv-legendWrap").attr("tra
nsform","translate(0,"+
-s.top+")")),A.attr("transform","translate("+s.left+","+s.top+")"),h&&M.select(".nv-y.nv-axis").attr("transform","translate("+N+",0)"),t.width(N).height(C).color(e.map(function(e,t){return
e.color||o(e,t)}).filter(function(t,n){return!e[n].disabled}));var
_=M.select(".nv-linesWrap").datum(e.filter(function(e){return!e.disabled}));d3.transition(_).call(t),l&&(n.scale(v).ticks(N/100).tickSize(-C,0),M.select(".nv-x.nv-axis").attr("transform","translate(0,"+m.range()[0]+")"),d3.transition(M.select(".nv-x.nv-axis")).call(n)),c&&(r.scale(m).ticks(C/36).tickSize(-N,0),d3.transition(M.select(".nv-y.nv-axis")).call(r)),i.dispatch.on("legendClick",function(t,n){t.disabled=!t.disabled,e.filter(function(e){return!e.disabled}).length||e.map(function(e){return
e.disabled=!1,A.selectAll(".nv-series").classed("disabled",!1),e}),g.disabled=e.map(function(e){return!!e.disabled}),w.stateChange(g),S.update()}),i.dispatch.on("legendDblclick",function(t){e.forEach(function
(e){e.disabled=!0}),t.disabled=!1,g.disabled=e.map(function(e){return!!e.disabled}),w.stateChange(g),S.update()}),w.on("tooltipShow",function(e){p&&E(e,T.parentNode)}),w.on("changeState",function(t){typeof
t.disabled!="undefined"&&(e.forEach(function(e,n){e.disabled=t.disabled[n]}),g.disabled=t.disabled),S.update()})}),S}var
t=e.models.line(),n=e.models.axis(),r=e.models.axis(),i=e.models.legend(),s={top:30,right:20,bottom:50,left:60},o=e.utils.defaultColor(),u=null,a=null,f=!0,l=!0,c=!0,h=!1,p=!0,d=function(e,t,n,r,i){return"<h3>"+e+"</h3>"+"<p>"+n+"
at "+t+"</p>"},v,m,g={},y=null,b="No Data
Available.",w=d3.dispatch("tooltipShow","tooltipHide","stateChange","changeState");n.orient("bottom").tickPadding(7),r.orient(h?"right":"left");var
E=function(i,s){if(s){var
o=d3.select(s).select("svg"),u=o.node()?o.attr("viewBox"):null;if(u){u=u.split("
");var
a=parseInt(o.style("width"))/u[2];i.pos[0]=i.pos[0]*a,i.pos[1]=i.pos[1]*a}}var
f=i.pos[0]+(s.offsetLeft||0),l=i.pos[1]+(s.offse
tTop||0),c=n.tickFormat()(t.x()(i.point,i.pointIndex)),h=r.tickFormat()(t.y()(i.point,i.pointIndex)),p=d(i.series.key,c,h,i,S);e.tooltip.show([f,l],p,null,null,s)};return
t.dispatch.on("elementMouseover.tooltip",function(e){e.pos=[e.pos[0]+s.left,e.pos[1]+s.top],w.tooltipShow(e)}),t.dispatch.on("elementMouseout.tooltip",function(e){w.tooltipHide(e)}),w.on("tooltipHide",function(){p&&e.tooltip.cleanup()}),S.dispatch=w,S.lines=t,S.legend=i,S.xAxis=n,S.yAxis=r,d3.rebind(S,t,"defined","isArea","x","y","size","xScale","yScale","xDomain","yDomain","forceX","forceY","interactive","clipEdge","clipVoronoi","id","interpolate"),S.margin=function(e){return
arguments.length?(s.top=typeof e.top!="undefined"?e.top:s.top,s.right=typeof
e.right!="undefined"?e.right:s.right,s.bottom=typeof
e.bottom!="undefined"?e.bottom:s.bottom,s.left=typeof
e.left!="undefined"?e.left:s.left,S):s},S.width=function(e){return
arguments.length?(u=e,S):u},S.height=function(e){return arguments.length?(a=e,S):a},S
.color=function(t){return
arguments.length?(o=e.utils.getColor(t),i.color(o),S):o},S.showLegend=function(e){return
arguments.length?(f=e,S):f},S.showXAxis=function(e){return
arguments.length?(l=e,S):l},S.showYAxis=function(e){return
arguments.length?(c=e,S):c},S.rightAlignYAxis=function(e){return
arguments.length?(h=e,r.orient(e?"right":"left"),S):h},S.tooltips=function(e){return
arguments.length?(p=e,S):p},S.tooltipContent=function(e){return
arguments.length?(d=e,S):d},S.state=function(e){return
arguments.length?(g=e,S):g},S.defaultState=function(e){return
arguments.length?(y=e,S):y},S.noData=function(e){return
arguments.length?(b=e,S):b},S},e.models.linePlusBarChart=function(){function T(e){return
e.each(function(e){var
l=d3.select(this),c=this,v=(a||parseInt(l.style("width"))||960)-u.left-u.right,N=(f||parseInt(l.style("height"))||400)-u.top-u.bottom;T.update=function(){l.transition().call(T)},b.disabled=e.map(function(e){return!!e.disabled});if(!w){var
C;w={};for(C in b)
b[C]instanceof
Array?w[C]=b[C].slice(0):w[C]=b[C]}if(!e||!e.length||!e.filter(function(e){return
e.values.length}).length){var k=l.selectAll(".nv-noData").data([E]);return
k.enter().append("text").attr("class","nvd3
nv-noData").attr("dy","-.7em").style("text-anchor","middle"),k.attr("x",u.left+v/2).attr("y",u.top+N/2).text(function(e){return
e}),T}l.selectAll(".nv-noData").remove();var
L=e.filter(function(e){return!e.disabled&&e.bar}),A=e.filter(function(e){return!e.bar});m=A.filter(function(e){return!e.disabled}).length&&A.filter(function(e){return!e.disabled})[0].values.length?t.xScale():n.xScale(),g=n.yScale(),y=t.yScale();var
O=d3.select(this).selectAll("g.nv-wrap.nv-linePlusBar").data([e]),M=O.enter().append("g").attr("class","nvd3
nv-wrap
nv-linePlusBar").append("g"),_=O.select("g");M.append("g").attr("class","nv-x
nv-axis"),M.append("g").attr("class","nv-y1
nv-axis"),M.append("g").attr("class","nv-y2
nv-axis"),M.append("g").attr("class","nv-barsWrap"),M.append("g").at
tr("class","nv-linesWrap"),M.append("g").attr("class","nv-legendWrap"),p&&(o.width(v/2),_.select(".nv-legendWrap").datum(e.map(function(e){return
e.originalKey=e.originalKey===undefined?e.key:e.originalKey,e.key=e.originalKey+(e.bar?"
(left axis)":" (right
axis)"),e})).call(o),u.top!=o.height()&&(u.top=o.height(),N=(f||parseInt(l.style("height"))||400)-u.top-u.bottom),_.select(".nv-legendWrap").attr("transform","translate("+v/2+","+
-u.top+")")),O.attr("transform","translate("+u.left+","+u.top+")"),t.width(v).height(N).color(e.map(function(e,t){return
e.color||h(e,t)}).filter(function(t,n){return!e[n].disabled&&!e[n].bar})),n.width(v).height(N).color(e.map(function(e,t){return
e.color||h(e,t)}).filter(function(t,n){return!e[n].disabled&&e[n].bar}));var
D=_.select(".nv-barsWrap").datum(L.length?L:[{values:[]}]),P=_.select(".nv-linesWrap").datum(A[0]&&!A[0].disabled?A:[{values:[]}]);d3.transition(D).call(n),d3.transition(P).call(t),r.scale(m).ticks(v/100).tickSize(-N,0),_.sele
ct(".nv-x.nv-axis").attr("transform","translate(0,"+g.range()[0]+")"),d3.transition(_.select(".nv-x.nv-axis")).call(r),i.scale(g).ticks(N/36).tickSize(-v,0),d3.transition(_.select(".nv-y1.nv-axis")).style("opacity",L.length?1:0).call(i),s.scale(y).ticks(N/36).tickSize(L.length?0:-v,0),_.select(".nv-y2.nv-axis").style("opacity",A.length?1:0).attr("transform","translate("+v+",0)"),d3.transition(_.select(".nv-y2.nv-axis")).call(s),o.dispatch.on("legendClick",function(t,n){t.disabled=!t.disabled,e.filter(function(e){return!e.disabled}).length||e.map(function(e){return
e.disabled=!1,O.selectAll(".nv-series").classed("disabled",!1),e}),b.disabled=e.map(function(e){return!!e.disabled}),S.stateChange(b),T.update()}),o.dispatch.on("legendDblclick",function(t){e.forEach(function(e){e.disabled=!0}),t.disabled=!1,b.disabled=e.map(function(e){return!!e.disabled}),S.stateChange(b),T.update()}),S.on("tooltipShow",function(e){d&&x(e,c.parentNode)}),S.on("changeState",function(t){typeof
t.di
sabled!="undefined"&&(e.forEach(function(e,n){e.disabled=t.disabled[n]}),b.disabled=t.disabled),T.update()})}),T}var
t=e.models.line(),n=e.models.historicalBar(),r=e.models.axis(),i=e.models.axis(),s=e.models.axis(),o=e.models.legend(),u={top:30,right:60,bottom:50,left:60},a=null,f=null,l=function(e){return
e.x},c=function(e){return
e.y},h=e.utils.defaultColor(),p=!0,d=!0,v=function(e,t,n,r,i){return"<h3>"+e+"</h3>"+"<p>"+n+"
at "+t+"</p>"},m,g,y,b={},w=null,E="No Data
Available.",S=d3.dispatch("tooltipShow","tooltipHide","stateChange","changeState");n.padData(!0),t.clipEdge(!1).padData(!0),r.orient("bottom").tickPadding(7).highlightZero(!1),i.orient("left"),s.orient("right");var
x=function(n,o){var
u=n.pos[0]+(o.offsetLeft||0),a=n.pos[1]+(o.offsetTop||0),f=r.tickFormat()(t.x()(n.point,n.pointIndex)),l=(n.series.bar?i:s).tickFormat()(t.y()(n.point,n.pointIndex)),c=v(n.series.key,f,l,n,T);e.tooltip.show([u,a],c,n.value<0?"n":"s",null,o)};return
t.dispatch.on("elementMouseover
.tooltip",function(e){e.pos=[e.pos[0]+u.left,e.pos[1]+u.top],S.tooltipShow(e)}),t.dispatch.on("elementMouseout.tooltip",function(e){
-S.tooltipHide(e)}),n.dispatch.on("elementMouseover.tooltip",function(e){e.pos=[e.pos[0]+u.left,e.pos[1]+u.top],S.tooltipShow(e)}),n.dispatch.on("elementMouseout.tooltip",function(e){S.tooltipHide(e)}),S.on("tooltipHide",function(){d&&e.tooltip.cleanup()}),T.dispatch=S,T.legend=o,T.lines=t,T.bars=n,T.xAxis=r,T.y1Axis=i,T.y2Axis=s,d3.rebind(T,t,"defined","size","clipVoronoi","interpolate"),T.x=function(e){return
arguments.length?(l=e,t.x(e),n.x(e),T):l},T.y=function(e){return
arguments.length?(c=e,t.y(e),n.y(e),T):c},T.margin=function(e){return
arguments.length?(u.top=typeof e.top!="undefined"?e.top:u.top,u.right=typeof
e.right!="undefined"?e.right:u.right,u.bottom=typeof
e.bottom!="undefined"?e.bottom:u.bottom,u.left=typeof
e.left!="undefined"?e.left:u.left,T):u},T.width=function(e){return
arguments.length?(a=e,T):a},T.height=function(e){return
arguments.length?(f=e,T):f},T.color=function(t){return
arguments.length?(h=e.utils.getColor(t),o.color(h),T):h},T.showLegend=function
(e){return arguments.length?(p=e,T):p},T.tooltips=function(e){return
arguments.length?(d=e,T):d},T.tooltipContent=function(e){return
arguments.length?(v=e,T):v},T.state=function(e){return
arguments.length?(b=e,T):b},T.defaultState=function(e){return
arguments.length?(w=e,T):w},T.noData=function(e){return
arguments.length?(E=e,T):E},T},e.models.lineWithFocusChart=function(){function C(e){return
e.each(function(e){function q(e){var
t=+(e=="e"),n=t?1:-1,r=O/3;return"M"+.5*n+","+r+"A6,6 0
0 "+t+" "+6.5*n+","+(r+6)+"V"+(2*r-6)+"A6,6 0 0
"+t+"
"+.5*n+","+2*r+"Z"+"M"+2.5*n+","+(r+8)+"V"+(2*r-8)+"M"+4.5*n+","+(r+8)+"V"+(2*r-8)}function
R(){a.empty()||a.extent(w),F.data([a.empty()?g.domain():w]).each(function(e,t){var
n=g(e[0])-v.range()[0],r=v.range()[1]-g(e[1]);d3.select(this).select(".left").attr("width",n<0?0:n),d3.select(this).select(".right").attr("x",g(e[1])).attr("width",r<0?0:r)})}function
U(){w=a.empty()?null:a.extent(),extent=a.empty()?g.domain():a.extent(),T.brush({extent
:extent,brush:a}),R();var n=P.select(".nv-focus
.nv-linesWrap").datum(e.filter(function(e){return!e.disabled}).map(function(e,n){return{key:e.key,values:e.values.filter(function(e,n){return
t.x()(e,n)>=extent[0]&&t.x()(e,n)<=extent[1]})}}));d3.transition(n).call(t),d3.transition(P.select(".nv-focus
.nv-x.nv-axis")).call(r),d3.transition(P.select(".nv-focus
.nv-y.nv-axis")).call(i)}var
S=d3.select(this),k=this,L=(h||parseInt(S.style("width"))||960)-f.left-f.right,A=(p||parseInt(S.style("height"))||400)-f.top-f.bottom-d,O=d-l.top-l.bottom;C.update=function(){S.transition().call(C)},C.container=this;if(!e||!e.length||!e.filter(function(e){return
e.values.length}).length){var M=S.selectAll(".nv-noData").data([x]);return
M.enter().append("text").attr("class","nvd3
nv-noData").attr("dy","-.7em").style("text-anchor","middle"),M.attr("x",f.left+L/2).attr("y",f.top+A/2).text(function(e){return
e}),C}S.selectAll(".nv-noData").remove(),v=t.xScale(),m=t.yScale(),g=n.xScale(),y=n.yScale(
);var
_=S.selectAll("g.nv-wrap.nv-lineWithFocusChart").data([e]),D=_.enter().append("g").attr("class","nvd3
nv-wrap
nv-lineWithFocusChart").append("g"),P=_.select("g");D.append("g").attr("class","nv-legendWrap");var
H=D.append("g").attr("class","nv-focus");H.append("g").attr("class","nv-x
nv-axis"),H.append("g").attr("class","nv-y
nv-axis"),H.append("g").attr("class","nv-linesWrap");var
B=D.append("g").attr("class","nv-context");B.append("g").attr("class","nv-x
nv-axis"),B.append("g").attr("class","nv-y
nv-axis"),B.append("g").attr("class","nv-linesWrap"),B.append("g").attr("class","nv-brushBackground"),B.append("g").attr("class","nv-x
nv-brush"),b&&(u.width(L),P.select(".nv-legendWrap").datum(e).call(u),f.top!=u.height()&&(f.top=u.height(),A=(p||parseInt(S.style("height"))||400)-f.top-f.bottom-d),P.select(".nv-legendWrap").attr("transform","translate(0,"+
-f.top+")")),_.attr("transform","translate("+f.left+","+f.top+")"),t.width(L).height(A).color(e.map(function(e,t){return
e.color||c(e,t)}).filter(function(t,n){return!e[n].disabled})),n.defined(t.defined()).width(L).height(O).color(e.map(function(e,t){return
e.color||c(e,t)}).filter(function(t,n){return!e[n].disabled})),P.select(".nv-context").attr("transform","translate(0,"+(A+f.bottom+l.top)+")");var
j=P.select(".nv-context
.nv-linesWrap").datum(e.filter(function(e){return!e.disabled}));d3.transition(j).call(n),r.scale(v).ticks(L/100).tickSize(-A,0),i.scale(m).ticks(A/36).tickSize(-L,0),P.select(".nv-focus
.nv-x.nv-axis").attr("transform","translate(0,"+A+")"),a.x(g).on("brush",U),w&&a.extent(w);var
F=P.select(".nv-brushBackground").selectAll("g").data([w||a.extent()]),I=F.enter().append("g");I.append("rect").attr("class","left").attr("x",0).attr("y",0).attr("height",O),I.append("rect").attr("class","right").attr("x",0).attr("y",0).attr("height",O),gBrush=P.select(".nv-x.nv-brush").call(a),gBrush.selectAll("rect").attr("height",O),gBrush.selectAll(".resize").append("path").attr("d",q),U(),s
.scale(g).ticks(L/100).tickSize(-O,0),P.select(".nv-context
.nv-x.nv-axis").attr("transform","translate(0,"+y.range()[0]+")"),d3.transition(P.select(".nv-context
.nv-x.nv-axis")).call(s),o.scale(y).ticks(O/36).tickSize(-L,0),d3.transition(P.select(".nv-context
.nv-y.nv-axis")).call(o),P.select(".nv-context
.nv-x.nv-axis").attr("transform","translate(0,"+y.range()[0]+")"),u.dispatch.on("legendClick",function(t,n){t.disabled=!t.disabled,e.filter(function(e){return!e.disabled}).length||e.map(function(e){return
e.disabled=!1,_.selectAll(".nv-series").classed("disabled",!1),e}),S.transition().call(C)}),T.on("tooltipShow",function(e){E&&N(e,k.parentNode)})}),C}var
t=e.models.line(),n=e.models.line(),r=e.models.axis(),i=e.models.axis(),s=e.models.axis(),o=e.models.axis(),u=e.models.legend(),a=d3.svg.brush(),f={top:30,right:30,bottom:30,left:60},l={top:0,right:30,bottom:20,left:60},c=e.utils.defaultColor(),h=null,p=null,d=100,v,m,g,y,b=!0,w=null,E=!0,S=function(e,t,n,r,i){return"<h3
"+e+"</h3>"+"<p>"+n+" at
"+t+"</p>"},x="No Data
Available.",T=d3.dispatch("tooltipShow","tooltipHide","brush");t.clipEdge(!0),n.interactive(!1),r.orient("bottom").tickPadding(5),i.orient("left"),s.orient("bottom").tickPadding(5),o.orient("left");var
N=function(n,s){var
o=n.pos[0]+(s.offsetLeft||0),u=n.pos[1]+(s.offsetTop||0),a=r.tickFormat()(t.x()(n.point,n.pointIndex)),f=i.tickFormat()(t.y()(n.point,n.pointIndex)),l=S(n.series.key,a,f,n,C);e.tooltip.show([o,u],l,null,null,s)};return
t.dispatch.on("elementMouseover.tooltip",function(e){e.pos=[e.pos[0]+f.left,e.pos[1]+f.top],T.tooltipShow(e)}),t.dispatch.on("elementMouseout.tooltip",function(e){T.tooltipHide(e)}),T.on("tooltipHide",function(){E&&e.tooltip.cleanup()}),C.dispatch=T,C.legend=u,C.lines=t,C.lines2=n,C.xAxis=r,C.yAxis=i,C.x2Axis=s,C.y2Axis=o,d3.rebind(C,t,"defined","isArea","size","xDomain","yDomain","forceX","forceY","interactive","clipEdge","clipVoronoi","id"),C.x=function(e){return
arguments.length?(t.x(e),n.x(
e),C):t.x},C.y=function(e){return
arguments.length?(t.y(e),n.y(e),C):t.y},C.margin=function(e){return
arguments.length?(f.top=typeof e.top!="undefined"?e.top:f.top,f.right=typeof
e.right!="undefined"?e.right:f.right,f.bottom=typeof
e.bottom!="undefined"?e.bottom:f.bottom,f.left=typeof
e.left!="undefined"?e.left:f.left,C):f},C.margin2=function(e){return
arguments.length?(l=e,C):l},C.width=function(e){return
arguments.length?(h=e,C):h},C.height=function(e){return
arguments.length?(p=e,C):p},C.height2=function(e){return
arguments.length?(d=e,C):d},C.color=function(t){return
arguments.length?(c=e.utils.getColor(t),u.color(c),C):c},C.showLegend=function(e){return
arguments.length?(b=e,C):b},C.tooltips=function(e){return
arguments.length?(E=e,C):E},C.tooltipContent=function(e){return
arguments.length?(S=e,C):S},C.interpolate=function(e){return
arguments.length?(t.interpolate(e),n.interpolate(e),C):t.interpolate()},C.noData=function(e){return
arguments.length?(x=e,C):x},C.xTickForm
at=function(e){return
arguments.length?(r.tickFormat(e),s.tickFormat(e),C):r.tickFormat()},C.yTickFormat=function(e){return
arguments.length?(i.tickFormat(e),o.tickFormat(e),C):i.tickFormat()},C},e.models.linePlusBarWithFocusChart=function(){function
H(e){return e.each(function(e){function tt(e){var
t=+(e=="e"),n=t?1:-1,r=I/3;return"M"+.5*n+","+r+"A6,6 0
0 "+t+" "+6.5*n+","+(r+6)+"V"+(2*r-6)+"A6,6 0 0
"+t+"
"+.5*n+","+2*r+"Z"+"M"+2.5*n+","+(r+8)+"V"+(2*r-8)+"M"+4.5*n+","+(r+8)+"V"+(2*r-8)}function
nt(){h.empty()||h.extent(x),Y.data([h.empty()?k.domain():x]).each(function(e,t){var
n=k(e[0])-k.range()[0],r=k.range()[1]-k(e[1]);d3.select(this).select(".left").attr("width",n<0?0:n),d3.select(this).select(".right").attr("x",k(e[1])).attr("width",r<0?0:r)})}function
rt(){x=h.empty()?null:h.extent(),S=h.empty()?k.domain():h.extent(),D.brush({extent:S,brush:h}),nt(),r.width(j).height(F).color(e.map(function(e,t){return
e.color||w(e,t)}).filter(function(t,n){return!e[n].disabled&&e[n
].bar})),t.width(j).height(F).color(e.map(function(e,t){return
e.color||w(e,t)}).filter(function(t,n){return!e[n].disabled&&!e[n].bar}));var
n=$.select(".nv-focus
.nv-barsWrap").datum(R.length?R.map(function(e,t){return{key:e.key,values:e.values.filter(function(e,t){return
r.x()(e,t)>=S[0]&&r.x()(e,t)<=S[1]})}}):[{values:[]}]),i=$.select(".nv-focus
.nv-linesWrap").datum(U[0].disabled?[{values:[]}]:U.map(function(e,n){return{key:e.key,values:e.values.filter(function(e,n){return
t.x()(e,n)>=S[0]&&t.x()(e,n)<=S[1]})}}));R.length?C=r.xScale():C=t.xScale(),s.scale(C).ticks(j/100).tickSize(-F,0),s.domain([Math.ceil(S[0]),Math.floor(S[1])]),d3.transition($.select(".nv-x.nv-axis")).call(s),d3.transition(n).call(r),d3.transition(i).call(t),$.select(".nv-focus
.nv-x.nv-axis").attr("transform","translate(0,"+L.range()[0]+")"),u.scale(L).ticks(F/36).tickSize(-j,0),$.select(".nv-focus
.nv-y1.nv-axis").style("opacity",R.length?1:0),a.scale(A).ticks(F/36).tickSize(R.length?0:-j,0),$.select
(".nv-focus
.nv-y2.nv-axis").style("opacity",U.length?1:0).attr("transform","translate("+C.range()[1]+",0)"),d3.transition($.select(".nv-focus
.nv-y1.nv-axis")).call(u),d3.transition($.select(".nv-focus
.nv-y2.nv-axis")).call(a)}var
N=d3.select(this),B=this,j=(v||parseInt(N.style("width"))||960)-p.left-p.right,F=(m||parseInt(N.style("height"))||400)-p.top-p.bottom-g,I=g-d.top-d.bottom;H.update=function(){N.transition().call(H)},H.container=this;if(!e||!e.length||!e.filter(function(e){return
e.values.length}).length){var q=N.selectAll(".nv-noData").data([_]);return
q.enter().append("text").attr("class","nvd3
nv-noData").attr("dy","-.7em").style("text-anchor","middle"),q.attr("x",p.left+j/2).attr("y",p.top+F/2).text(function(e){return
e}),H}N.selectAll(".nv-noData").remove();var
R=e.filter(function(e){return!e.disabled&&e.bar}),U=e.filter(function(e){return!e.bar});C=r.xScale(),k=o.scale(),L=r.yScale(),A=t.yScale(),O=i.yScale(),M=n.yScale();var
z=e.filter(function(e){return!e.
disabled&&e.bar}).map(function(e){return
e.values.map(function(e,t){return{x:y(e,t),y:b(e,t)}})}),W=e.filter(function(e){return!e.disabled&&!e.bar}).map(function(e){return
e.values.map(function(e,t){return{x:y(e,t),y:b(e,t)}})});C.range([0,j]),k.domain(d3.extent(d3.merge(z.concat(W)),function(e){return
e.x})).range([0,j]);var
X=N.selectAll("g.nv-wrap.nv-linePlusBar").data([e]),V=X.enter().append("g").attr("class","nvd3
nv-wrap
nv-linePlusBar").append("g"),$=X.select("g");V.append("g").attr("class","nv-legendWrap");var
J=V.append("g").attr("class","nv-focus");J.append("g").attr("class","nv-x
nv-axis"),J.append("g").attr("class","nv-y1
nv-axis"),J.append("g").attr("class","nv-y2
nv-axis"),J.append("g").attr("class","nv-barsWrap"),J.append("g").attr("class","nv-linesWrap");var
K=V.append("g").attr("class","nv-context");K.append("g").attr("class","nv-x
nv-axis"),K.append("g").attr("class","nv-y1
nv-axis"),K.append("g").attr("class","nv-y2
nv-axis"),K.append("g").attr("class","nv
-barsWrap"),K.append("g").attr("class","nv-linesWrap"),K.append("g").attr("class","nv-brushBackground"),K.append("g").attr("class","nv-x
nv-brush"),E&&(c.width(j/2),$.select(".nv-legendWrap").datum(e.map(function(e){return
e.originalKey=e.originalKey===undefined?e.key:e.originalKey,e.key=e.originalKey+(e.bar?"
(left axis)":" (right
axis)"),e})).call(c),p.top!=c.height()&&(p.top=c.height(),F=(m||parseInt(N.style("height"))||400)-p.top-p.bottom-g),$.select(".nv-legendWrap").attr("transform","translate("+j/2+","+
-p.top+")")),X.attr("transform","translate("+p.left+","+p.top+")"),i.width(j).height(I).color(e.map(function(e,t){return
e.color||w(e,t)}).filter(function(t,n){return!e[n].disabled&&e[n].bar})),n.width(j).height(I).color(e.map(function(e,t){return
e.color||w(e,t)}).filter(function(t,n){return!e[n].disabled&&!e[n].bar}));var
Q=$.select(".nv-context
.nv-barsWrap").datum(R.length?R:[{values:[]}]),G=$.select(".nv-context
.nv-linesWrap").datum(U[0].disabled?[{values:[]}]:U)
;$.select(".nv-context").attr("transform","translate(0,"+(F+p.bottom+d.top)+")"),d3.transition(Q).call(i),d3.transition(G).call(n),h.x(k).on("brush",rt),x&&h.extent(x);var
Y=$.select(".nv-brushBackground").selectAll("g").data([x||h.extent()]),Z=Y.enter().append("g");Z.append("rect").attr("class","left").attr("x",0).attr("y",0).attr("height",I),Z.append("rect").attr("class","right").attr("x",0).attr("y",0).attr("height",I);var
et=$.select(".nv-x.nv-brush").call(h);et.selectAll("rect").attr("height",I),et.selectAll(".resize").append("path").attr("d",tt),o.ticks(j/100).tickSize(-I,0),$.select(".nv-context
.nv-x.nv-axis").attr("transform","translate(0,"+O.range()[0]+")"),d3.transition($.select(".nv-context
.nv-x.nv-axis")).call(o),f.scale(O).ticks(I/36).tickSize(-j,0),$.select(".nv-context
.nv-y1.nv-axis").style("opacity",R.length?1:0).attr("transform","translate(0,"+k.range()[0]+")"),d3.transition($.select(".nv-context
.nv-y1.nv-axis")).call(f),l.scale(M).ticks(I/36).tickSize(R
.length?0:-j,0),$.select(".nv-context
.nv-y2.nv-axis").style("opacity",U.length?1:0).attr("transform","translate("+k.range()[1]+",0)"),d3.transition($.select(".nv-context
.nv-y2.nv-axis")).call(l),c.dispatch.on("legendClick",function(t,n){t.disabled=!t.disabled,e.filter(function(e){return!e.disabled}).length||e.map(function(e){return
e.disabled=!1,X.selectAll(".nv-series").classed("disabled",!1),e}),H.update()}),D.on("tooltipShow",function(e){T&&P(e,B.parentNode)}),rt()}),H}var
t=e.models.line(),n=e.models.line(),r=e.models.historicalBar(),i=e.models.historicalBar(),s=e.models.axis(),o=e.models.axis(),u=e.models.axis(),a=e.models.axis(),f=e.models.axis(),l=e.models.axis(),c=e.models.legend(),h=d3.svg.brush(),p={top:30,right:30,bottom:30,left:60},d={top:0,right:30,bottom:20,left:60},v=null,m=null,g=100,y=function(e){return
e.x},b=function(e){return
e.y},w=e.utils.defaultColor(),E=!0,S,x=null,T=!0,N=function(e,t,n,r,i){return"<h3>"+e+"</h3>"+"<p>"+n+"
at "+t+"</p>"},C,k,L,A,O,
M,_="No Data
Available.",D=d3.dispatch("tooltipShow","tooltipHide","brush");t.clipEdge(!0),n.interactive(!1),s.orient("bottom").tickPadding(5),u.orient("left"),a.orient("right"),o.orient("bottom").tickPadding(5),f.orient("left"),l.orient("right");var
P=function(n,r){S&&(n.pointIndex+=Math.ceil(S[0]));var
i=n.pos[0]+(r.offsetLeft||0),o=n.pos[1]+(r.offsetTop||0),f=s.tickFormat()(t.x()(n.point,n.pointIndex)),l=(n.series.bar?u:a).tickFormat()(t.y()(n.point,n.pointIndex)),c=N(n.series.key,f,l,n,H);e.tooltip.show([i,o],c,n.value<0?"n":"s",null,r)};return
t.dispatch.on("elementMouseover.tooltip",function(e){e.pos=[e.pos[0]+p.left,e.pos[1]+p.top],D.tooltipShow(e)}),t.dispatch.on("elementMouseout.tooltip",function(e){D.tooltipHide(e)}),r.dispatch.on("elementMouseover.tooltip",function(e){e.pos=[e.pos[0]+p.left,e.pos[1]+p.top],D.tooltipShow(e)}),r.dispatch.on("elementMouseout.tooltip",function(e){D.tooltipHide(e)}),D.on("tooltipHide",function(){T&&e.tooltip.cleanup()}),H.dispatch=D,H.
legend=c,H.lines=t,H.lines2=n,H.bars=r,H.bars2=i,H.xAxis=s,H.x2Axis=o,H.y1Axis=u,H.y2Axis=a,H.y3Axis=f,H.y4Axis=l,d3.rebind(H,t,"defined","size","clipVoronoi","interpolate"),H.x=function(e){return
arguments.length?(y=e,t.x(e),r.x(e),H):y},H.y=function(e){return
arguments.length?(b=e,t.y(e),r.y(e),H):b},H.margin=function(e){return
arguments.length?(p.top=typeof e.top!="undefined"?e.top:p.top,p.right=typeof
e.right!="undefined"?e.right:p.right,p.bottom=typeof
e.bottom!="undefined"?e.bottom:p.bottom,p.left=typeof
e.left!="undefined"?e.left:p.left,H):p},H.width=function(e){return
arguments.length?(v=e,H):v},H.height=function(e){return
arguments.length?(m=e,H):m},H.color=function(t){return
arguments.length?(w=e.utils.getColor(t),c.color(w),H):w},H.showLegend=function(e){return
arguments.length?(E=e,H):E},H.tooltips=function(e){return
arguments.length?(T=e,H):T},H.tooltipContent=function(e){return
arguments.length?(N=e,H):N},H.noData=function(e){return arguments.length?(_=e,H):_},
H.brushExtent=function(e){return
arguments.length?(x=e,H):x},H},e.models.multiBar=function(){function x(e){return
e.each(function(e){var
x=n-t.left-t.right,T=r-t.top-t.bottom,N=d3.select(this);p&&e.length&&(p=[{values:e[0].values.map(function(e){return{x:e.x,y:0,series:e.series,size:.01}})}]),c&&(e=d3.layout.stack().offset("zero").values(function(e){return
e.values}).y(a)(!e.length&&p?p:e)),e=e.map(function(e,t){return
e.values=e.values.map(function(e){return
e.series=t,e}),e}),c&&e[0].values.map(function(t,n){var
r=0,i=0;e.map(function(e){var
t=e.values[n];t.size=Math.abs(t.y),t.y<0?(t.y1=i,i-=t.size):(t.y1=t.size+r,r+=t.size)})});var
C=y&&b?[]:e.map(function(e){return
e.values.map(function(e,t){return{x:u(e,t),y:a(e,t),y0:e.y0,y1:e.y1}})});i.domain(d3.merge(C).map(function(e){return
e.x})).rangeBands([0,x],.1),s.domain(b||d3.extent(d3.merge(C).map(function(e){return
c?e.y>0?e.y1:e.y1+e.y:e.y}).concat(f))).range([T,0]);if(i.domain()[0]===i.domain()[1]||s.domain()[0]===s.dom
ain()[1])singlePoint=!0;i.domain()[0]===i.domain()[1]&&(i.domain()[0]?i.domain([i.domain()[0]-i.domain()[0]*.01,i.domain()[1]+i.domain()[1]*.01]):i.domain([-1,1])),s.domain()[0]===s.domain()[1]&&(s.domain()[0]?s.domain([s.domain()[0]+s.domain()[0]*.01,s.domain()[1]-s.domain()[1]*.01]):s.domain([-1,1])),E=E||i,S=S||s;var
k=N.selectAll("g.nv-wrap.nv-multibar").data([e]),L=k.enter().append("g").attr("class","nvd3
nv-wrap
nv-multibar"),A=L.append("defs"),O=L.append("g"),M=k.select("g");O.append("g").attr("class","nv-groups"),k.attr("transform","translate("+t.left+","+t.top+")"),A.append("clipPath").attr("id","nv-edge-clip-"+o).append("rect"),k.select("#nv-edge-clip-"+o+"
rect").attr("width",x).attr("height",T),M.attr("clip-path",l?"url(#nv-edge-clip-"+o+")":"");var
_=k.select(".nv-groups").selectAll(".nv-group").data(function(e){return
e},function(e){return
e.key});_.enter().append("g").style("stroke-opacity",1e-6).style("fill-opacity",1e-6),_.exit().selectAll("rect.nv-bar").tra
nsition().delay(function(t,n){return
n*m/e[0].values.length}).attr("y",function(e){return
c?S(e.y0):S(0)}).attr("height",0).remove(),_.attr("class",function(e,t){return"nv-group
nv-series-"+t}).classed("hover",function(e){return
e.hover}).style("fill",function(e,t){return
h(e,t)}).style("stroke",function(e,t){return
h(e,t)}),d3.transition(_).style("stroke-opacity",1).style("fill-opacity",.75);var
D=_.selectAll("rect.nv-bar").data(function(t){return
p&&!e.length?p.values:t.values});D.exit().remove();var
P=D.enter().append("rect").attr("class",function(e,t){return
a(e,t)<0?"nv-bar negative":"nv-bar
positive"}).attr("x",function(t,n,r){return
c?0:r*i.rangeBand()/e.length}).attr("y",function(e){return
S(c?e.y0:0)}).attr("height",0).attr("width",i.rangeBand()/(c?1:e.length));D.style("fill",function(e,t,n){return
h(e,n,t)}).style("stroke",function(e,t,n){return
h(e,n,t)}).on("mouseover",function(t,n){d3.select(this).classed("hover",!0),w.elementMouseover({value:a(t,n),point:t,seri
es:e[t.series],pos:[i(u(t,n))+i.rangeBand()*(c?e.length/2:t.series+.5)/e.length,s(a(t,n)+(c?t.y0:0))],pointIndex:n,seriesIndex:t.series,e:d3.event})}).on("mouseout",function(t,n){d3.select(this).classed("hover",!1),w.elementMouseout({value:a(t,n),point:t,series:e[t.series],pointIndex:n,seriesIndex:t.series,e:d3.event})}).on("click",function(t,n){w.elementClick({value:a(t,n),point:t,series:e[t.series],pos:[i(u(t,n))+i.rangeBand()*(c?e.length/2:t.series+.5)/e.length,s(a(t,n)+(c?t.y0:0))],pointIndex:n,seriesIndex:t.series,e:d3.event}),d3.event.stopPropagation()}).on("dblclick",function(t,n){w.elementDblClick({value:a(t,n),point:t,series:e[t.series],pos:[i(u(t,n))+i.rangeBand()*(c?e.length/2:t.series+.5)/e.length,s(a(t,n)+(c?t.y0:0))],pointIndex:n,seriesIndex:t.series,e:d3.event}),d3.event.stopPropagation()}),D.attr("class",function(e,t){return
a(e,t)<0?"nv-bar negative":"nv-bar
positive"}).attr("transform",function(e,t){return"translate("+i(u(e,t))+",0)"}),d&&(v||(v=e.map(funct
ion(){return!0})),D.style("fill",function(e,t,n){return
d3.rgb(d(e,t)).darker(v.map(function(e,t){return
t}).filter(function(e,t){return!v[t]})[n]).toString()}).style("stroke",function(e,t,n){return
d3.rgb(d(e,t)).darker(v.map(function(e,t){return
t}).filter(function(e,t){return!v[t]})[n]).toString()})),c?D.transition().delay(function(t,n){return
n*m/e[0].values.length}).attr("y",function(e,t){return
s(c?e.y1:0)}).attr("height",function(e,t){return
Math.max(Math.abs(s(e.y+(c?e.y0:0))-s(c?e.y0:0)),1)}).each("end",function(){d3.select(this).transition().duration(g).attr("x",function(t,n){return
c?0:t.series*i.rangeBand()/e.length}).attr("width",i.rangeBand()/(c?1:e.length))}):d3.transition(D).duration(g).delay(function(t,n){return
n*m/e[0].values.length}).attr("x",function(t,n){return
t.series*i.rangeBand()/e.length}).attr("width",i.rangeBand()/e.length).each("end",function(){d3.select(this).transition().duration(g).attr("y",function(e,t){return
a(e,t)<0?s(0):s(0)-s(a(e,t))<1?
s(0)-1:s(a(e,t))||0}).attr("height",function(e,t){return
Math.max(Math.abs(s(a(e,t))-s(0)),1)||0})}),E=i.copy(),S=s.copy()}),x}var
t={top:0,right:0,bottom:0,left:0},n=960,r=500,i=d3.scale.ordinal(),s=d3.scale.linear(),o=Math.floor(Math.random()*1e4),u=function(e){return
e.x},a=function(e){return
e.y},f=[0],l=!0,c=!1,h=e.utils.defaultColor(),p=!1,d=null,v,m=1200,g=500,y,b,w=d3.dispatch("chartClick","elementClick","elementDblClick","elementMouseover","elementMouseout"),E,S;return
x.dispatch=w,x.x=function(e){return arguments.length?(u=e,x):u},x.y=function(e){return
arguments.length?(a=e,x):a},x.margin=function(e){return arguments.length?(t.top=typeof
e.top!="undefined"?e.top:t.top,t.right=typeof
e.right!="undefined"?e.right:t.right,t.bottom=typeof
e.bottom!="undefined"?e.bottom:t.bottom,t.left=typeof
e.left!="undefined"?e.left:t.left,x):t},x.width=function(e){return
arguments.length?(n=e,x):n},x.height=function(e){return
arguments.length?(r=e,x):r},x.xScale=function(e){return
arguments.length?(i=e,x):i},x.yScale=function(e){return
arguments.length?(s=e,x):s},x.xDomain=function(e){return
arguments.length?(y=e,x):y},x.yDomain=function(e){return
arguments.length?(b=e,x):b},x.forceY=function(e){return
arguments.length?(f=e,x):f},x.stacked=function(e){return
arguments.length?(c=e,x):c},x.clipEdge=function(e){return
arguments.length?(l=e,x):l},x.color=function(t){return
arguments.length?(h=e.utils.getColor(t),x):h},x.barColor=function(t){return
arguments.length?(d=e.utils.getColor(t),x):d},x.disabled=function(e){return
arguments.length?(v=e,x):v},x.id=function(e){return
arguments.length?(o=e,x):o},x.hideable=function(e){return
arguments.length?(p=e,x):p},x.delay=function(e){return
arguments.length?(m=e,x):m},x.drawTime=function(e){return
arguments.length?(g=e,x):g},x},e.models.multiBarChart=function(){function N(e){return
e.each(function(e){var
m=d3.select(this),C=this,k=(u||parseInt(m.style("width"))||960)-o.left-o.right,L=(a||parseInt(m.style("height
"))||400)-o.top-o.bottom;N.update=function(){m.transition().call(N)},N.container=this,b.disabled=e.map(function(e){return!!e.disabled});if(!w){var
A;w={};for(A in b)b[A]instanceof
Array?w[A]=b[A].slice(0):w[A]=b[A]}if(!e||!e.length||!e.filter(function(e){return
e.values.length}).length){var O=m.selectAll(".nv-noData").data([E]);return
O.enter().append("text").attr("class","nvd3
nv-noData").attr("dy","-.7em").style("text-anchor","middle"),O.attr("x",o.left+k/2).attr("y",o.top+L/2).text(function(e){return
e}),N}m.selectAll(".nv-noData").remove(),g=t.xScale(),y=t.yScale();var
M=m.selectAll("g.nv-wrap.nv-multiBarWithLegend").data([e]),_=M.enter().append("g").attr("class","nvd3
nv-wrap
nv-multiBarWithLegend").append("g"),D=M.select("g");_.append("g").attr("class","nv-x
nv-axis"),_.append("g").attr("class","nv-y
nv-axis"),_.append("g").attr("class","nv-barsWrap"),_.append("g").attr("class","nv-legendWrap"),_.append("g").attr("class","nv-controlsWrap"),c&&(i.width(k-x()),t.barColor
()&&e.forEach(function(e,t){e.color=d3.rgb("#ccc").darker(t*1.5).toString()}),D.select(".nv-legendWrap").datum(e).call(i),o.top!=i.height()&&(o.top=i.height(),L=(a||parseInt(m.style("height"))||400)-o.top-o.bottom),D.select(".nv-legendWrap").attr("transform","translate("+x()+","+
-o.top+")"));if(l){var
P=[{key:"Grouped",disabled:t.stacked()},{key:"Stacked",disabled:!t.stacked()}];s.width(x()).color(["#444","#444","#444"]),D.select(".nv-controlsWrap").datum(P).attr("transform","translate(0,"+
-o.top+")").call(s)}M.attr("transform","translate("+o.left+","+o.top+")"),t.disabled(e.map(function(e){return
e.disabled})).width(k).height(L).color(e.map(function(e,t){return
e.color||f(e,t)}).filter(function(t,n){return!e[n].disabled}));var
H=D.select(".nv-barsWrap").datum(e.filter(function(e){return!e.disabled}));d3.transition(H).call(t),n.scale(g).ticks(k/100).tickSize(-L,0),D.select(".nv-x.nv-axis").attr("transform","translate(0,"+y.range()[0]+")"),d3.transition(D.select(".nv-x.nv-a
xis")).call(n);var B=D.select(".nv-x.nv-axis >
g").selectAll("g");B.selectAll("line,
text").style("opacity",1);if(p){var
j=function(e,t){return"translate("+e+","+t+")"},F=5,I=17;B.selectAll("text").attr("transform",function(e,t,n){return
j(0,n%2==0?F:I)});var q=d3.selectAll(".nv-x.nv-axis .nv-wrap g g
text")[0].length;D.selectAll(".nv-x.nv-axis .nv-axisMaxMin
text").attr("transform",function(e,t){return
j(0,t===0||q%2!==0?I:F)})}h&&B.filter(function(t,n){return
n%Math.ceil(e[0].values.length/(k/100))!==0}).selectAll("text,
line").style("opacity",0),d&&B.selectAll("text").attr("transform","rotate("+d+"
0,0)").attr("text-anchor",d>0?"start":"end"),D.select(".nv-x.nv-axis").selectAll("g.nv-axisMaxMin
text").style("opacity",1),r.scale(y).ticks(L/36).tickSize(-k,0),d3.transition(D.select(".nv-y.nv-axis")).call(r),i.dispatch.on("legendClick",function(t,n){t.disabled=!t.disabled,e.filter(function(e){return!e.disabled}).length||e.map(function(e){return
e.disabled=!1,M.selectAll(".nv
-series").classed("disabled",!1),e}),b.disabled=e.map(function(e){return!!e.disabled}),S.stateChange(b),N.update()}),i.dispatch.on("legendDblclick",function(t){e.forEach(function(e){e.disabled=!0}),t.disabled=!1,b.disabled=e.map(function(e){return!!e.disabled}),S.stateChange(b),N.update()}),s.dispatch.on("legendClick",function(e,n){if(!e.disabled)return;P=P.map(function(e){return
e.disabled=!0,e}),e.disabled=!1;switch(e.key){case"Grouped":t.stacked(!1);break;case"Stacked":t.stacked(!0)}b.stacked=t.stacked(),S.stateChange(b),N.update()}),S.on("tooltipShow",function(e){v&&T(e,C.parentNode)}),S.on("changeState",function(n){typeof
n.disabled!="undefined"&&(e.forEach(function(e,t){e.disabled=n.disabled[t]}),b.disabled=n.disabled),typeof
n.stacked!="undefined"&&(t.stacked(n.stacked),b.stacked=n.stacked),N.update()})}),N}var
t=e.models.multiBar(),n=e.models.axis(),r=e.models.axis(),i=e.models.legend(),s=e.models.legend(),o={top:30,right:20,bottom:50,left:60},u=null,a=null,f=e.utils
.defaultColor(),l=!0,c=!0,h=!0,p=!1,d=0,v=!0,m=function(e,t,n,r,i){return"<h3>"+e+"</h3>"+"<p>"+n+"
on "+t+"</p>"},g,y,b={stacked:!1},w=null,E="No Data
Available.",S=d3.dispatch("tooltipShow","tooltipHide","stateChange","changeState"),x=function(){return
l?180:0};t.stacked(!1),n.orient("bottom").tickPadding(7).highlightZero(!0).showMaxMin(!1).tickFormat(function(e){return
e}),r.orient("left").tickFormat(d3.format(",.1f"));var
T=function(i,s){var
o=i.pos[0]+(s.offsetLeft||0),u=i.pos[1]+(s.offsetTop||0),a=n.tickFormat()(t.x()(i.point,i.pointIndex)),f=r.tickFormat()(t.y()(i.point,i.pointIndex)),l=m(i.series.key,a,f,i,N);e.tooltip.show([o,u],l,i.value<0?"n":"s",null,s)};return
t.dispatch.on("elementMouseover.tooltip",function(e){e.pos=[e.pos[0]+o.left,e.pos[1]+o.top],S.tooltipShow(e)}),t.dispatch.on("elementMouseout.tooltip",function(e){S.tooltipHide(e)}),S.on("tooltipHide",function(){v&&e.tooltip.cleanup()}),N.dispatch=S,N.multibar=t,N.legend=i,N.xAxis=n,N.yAxis=r,d3.rebind(N,t
,"x","y","xDomain","yDomain","forceX","forceY","clipEdge","id","stacked","delay","barColor"),N.margin=function(e){return
arguments.length?(o.top=typeof e.top!="undefined"?e.top:o.top,o.right=typeof
e.right!="undefined"?e.right:o.right,o.bottom=typeof
e.bottom!="undefined"?e.bottom:o.bottom,o.left=typeof
e.left!="undefined"?e.left:o.left,N):o},N.width=function(e){return
arguments.length?(u=e,N):u},N.height=function(e){return
arguments.length?(a=e,N):a},N.color=function(t){return
arguments.length?(f=e.utils.getColor(t),i.color(f),N):f},N.showControls=function(e){return
arguments.length?(l=e,N):l},N.showLegend=function(e){return
arguments.length?(c=e,N):c},N.reduceXTicks=function(e){return
arguments.length?(h=e,N):h},N.rotateLabels=function(e){return
arguments.length?(d=e,N):d},N.staggerLabels=function(e){return
arguments.length?(p=e,N):p},N.tooltip=function(e){return
arguments.length?(m=e,N):m},N.tooltips=function(e){return
arguments.length?(v=e,N):v},N.tooltipContent=function
(e){return arguments.length?(m=e,N):m},N.state=function(e){return
arguments.length?(b=e,N):b},N.defaultState=function(e){return
arguments.length?(w=e,N):w},N.noData=function(e){return
arguments.length?(E=e,N):E},N},e.models.multiBarHorizontal=function(){function x(e){return
e.each(function(e){var
i=n-t.left-t.right,g=r-t.top-t.bottom,x=d3.select(this);p&&(e=d3.layout.stack().offset("zero").values(function(e){return
e.values}).y(a)(e)),e=e.map(function(e,t){return e.values=e.values.map(function(e){return
e.series=t,e}),e}),p&&e[0].values.map(function(t,n){var
r=0,i=0;e.map(function(e){var
t=e.values[n];t.size=Math.abs(t.y),t.y<0?(t.y1=i-t.size,i-=t.size):(t.y1=r,r+=t.size)})});var
T=y&&b?[]:e.map(function(e){return
e.values.map(function(e,t){return{x:u(e,t),y:a(e,t),y0:e.y0,y1:e.y1}})});s.domain(y||d3.merge(T).map(function(e){return
e.x})).rangeBands([0,g],.1),o.domain(b||d3.extent(d3.merge(T).map(function(e){return
p?e.y>0?e.y1+e.y:e.y1:e.y}).concat(f))),d&&!p?o.range([o.dom
ain()[0]<0?v:0,i-(o.domain()[1]>0?v:0)]):o.range([0,i]),E=E||s,S=S||d3.scale.linear().domain(o.domain()).range([o(0),o(0)]);var
N=d3.select(this).selectAll("g.nv-wrap.nv-multibarHorizontal").data([e]),C=N.enter().append("g").attr("class","nvd3
nv-wrap
nv-multibarHorizontal"),k=C.append("defs"),L=C.append("g"),A=N.select("g");L.append("g").attr("class","nv-groups"),N.attr("transform","translate("+t.left+","+t.top+")");var
O=N.select(".nv-groups").selectAll(".nv-group").data(function(e){return
e},function(e){return
e.key});O.enter().append("g").style("stroke-opacity",1e-6).style("fill-opacity",1e-6),d3.transition(O.exit()).style("stroke-opacity",1e-6).style("fill-opacity",1e-6).remove(),O.attr("class",function(e,t){return"nv-group
nv-series-"+t}).classed("hover",function(e){return
e.hover}).style("fill",function(e,t){return
l(e,t)}).style("stroke",function(e,t){return
l(e,t)}),d3.transition(O).style("stroke-opacity",1).style("fill-opacity",.75);var
M=O.selectAll("g.nv-bar").da
ta(function(e){return e.values});M.exit().remove();var
_=M.enter().append("g").attr("transform",function(t,n,r){return"translate("+S(p?t.y0:0)+","+(p?0:r*s.rangeBand()/e.length+s(u(t,n)))+")"});_.append("rect").attr("width",0).attr("height",s.rangeBand()/(p?1:e.length)),M.on("mouseover",function(t,n){d3.select(this).classed("hover",!0),w.elementMouseover({value:a(t,n),point:t,series:e[t.series],pos:[o(a(t,n)+(p?t.y0:0)),s(u(t,n))+s.rangeBand()*(p?e.length/2:t.series+.5)/e.length],pointIndex:n,seriesIndex:t.series,e:d3.event})}).on("mouseout",function(t,n){d3.select(this).classed("hover",!1),w.elementMouseout({value:a(t,n),point:t,series:e[t.series],pointIndex:n,seriesIndex:t.series,e:d3.event})}).on("click",function(t,n){w.elementClick({value:a(t,n),point:t,series:e[t.series],pos:[s(u(t,n))+s.rangeBand()*(p?e.length/2:t.series+.5)/e.length,o(a(t,n)+(p?t.y0:0))],pointIndex:n,seriesIndex:t.series,e:d3.event}),d3.event.stopPropagation()}).on("dblclick",function(t,n){w.elementDb
lClick({value:a(t,n),point:t,series:e[t.series],pos:[s(u(t,n))+s.rangeBand()*(p?e.length/2:t.series+.5)/e.length,o(a(t,n)+(p?t.y0:0)
-)],pointIndex:n,seriesIndex:t.series,e:d3.event}),d3.event.stopPropagation()}),_.append("text"),d&&!p?(M.select("text").attr("text-anchor",function(e,t){return
a(e,t)<0?"end":"start"}).attr("y",s.rangeBand()/(e.length*2)).attr("dy",".32em").text(function(e,t){return
m(a(e,t))}),d3.transition(M).select("text").attr("x",function(e,t){return
a(e,t)<0?-4:o(a(e,t))-o(0)+4})):M.selectAll("text").text(""),M.attr("class",function(e,t){return
a(e,t)<0?"nv-bar negative":"nv-bar
positive"}),c&&(h||(h=e.map(function(){return!0})),M.style("fill",function(e,t,n){return
d3.rgb(c(e,t)).darker(h.map(function(e,t){return
t}).filter(function(e,t){return!h[t]})[n]).toString()}).style("stroke",function(e,t,n){return
d3.rgb(c(e,t)).darker(h.map(function(e,t){return
t}).filter(function(e,t){return!h[t]})[n]).toString()})),p?d3.transition(M).attr("transform",function(e,t){return"translate("+o(e.y1)+","+s(u(e,t))+")"}).select("rect").attr("width",function(e,t){return
Math.abs(o(a(e,t)+e.y0)-o(e.y0))
}).attr("height",s.rangeBand()):d3.transition(M).attr("transform",function(t,n){return"translate("+(a(t,n)<0?o(a(t,n)):o(0))+","+(t.series*s.rangeBand()/e.length+s(u(t,n)))+")"}).select("rect").attr("height",s.rangeBand()/e.length).attr("width",function(e,t){return
Math.max(Math.abs(o(a(e,t))-o(0)),1)}),E=s.copy(),S=o.copy()}),x}var
t={top:0,right:0,bottom:0,left:0},n=960,r=500,i=Math.floor(Math.random()*1e4),s=d3.scale.ordinal(),o=d3.scale.linear(),u=function(e){return
e.x},a=function(e){return
e.y},f=[0],l=e.utils.defaultColor(),c=null,h,p=!1,d=!1,v=60,m=d3.format(",.2f"),g=1200,y,b,w=d3.dispatch("chartClick","elementClick","elementDblClick","elementMouseover","elementMouseout"),E,S;return
x.dispatch=w,x.x=function(e){return arguments.length?(u=e,x):u},x.y=function(e){return
arguments.length?(a=e,x):a},x.margin=function(e){return arguments.length?(t.top=typeof
e.top!="undefined"?e.top:t.top,t.right=typeof
e.right!="undefined"?e.right:t.right,t.bottom=typeof e.bottom!="unde
fined"?e.bottom:t.bottom,t.left=typeof
e.left!="undefined"?e.left:t.left,x):t},x.width=function(e){return
arguments.length?(n=e,x):n},x.height=function(e){return
arguments.length?(r=e,x):r},x.xScale=function(e){return
arguments.length?(s=e,x):s},x.yScale=function(e){return
arguments.length?(o=e,x):o},x.xDomain=function(e){return
arguments.length?(y=e,x):y},x.yDomain=function(e){return
arguments.length?(b=e,x):b},x.forceY=function(e){return
arguments.length?(f=e,x):f},x.stacked=function(e){return
arguments.length?(p=e,x):p},x.color=function(t){return
arguments.length?(l=e.utils.getColor(t),x):l},x.barColor=function(t){return
arguments.length?(c=e.utils.getColor(t),x):c},x.disabled=function(e){return
arguments.length?(h=e,x):h},x.id=function(e){return
arguments.length?(i=e,x):i},x.delay=function(e){return
arguments.length?(g=e,x):g},x.showValues=function(e){return
arguments.length?(d=e,x):d},x.valueFormat=function(e){return
arguments.length?(m=e,x):m},x.valuePadding=function(e
){return
arguments.length?(v=e,x):v},x},e.models.multiBarHorizontalChart=function(){function
x(e){return e.each(function(h){var
d=d3.select(this),T=this,N=(u||parseInt(d.style("width"))||960)-o.left-o.right,C=(a||parseInt(d.style("height"))||400)-o.top-o.bottom;x.update=function(){d.transition().call(x)},x.container=this,g.disabled=h.map(function(e){return!!e.disabled});if(!y){var
k;y={};for(k in g)g[k]instanceof
Array?y[k]=g[k].slice(0):y[k]=g[k]}if(!h||!h.length||!h.filter(function(e){return
e.values.length}).length){var L=d.selectAll(".nv-noData").data([b]);return
L.enter().append("text").attr("class","nvd3
nv-noData").attr("dy","-.7em").style("text-anchor","middle"),L.attr("x",o.left+N/2).attr("y",o.top+C/2).text(function(e){return
e}),x}d.selectAll(".nv-noData").remove(),v=t.xScale(),m=t.yScale();var
A=d.selectAll("g.nv-wrap.nv-multiBarHorizontalChart").data([h]),O=A.enter().append("g").attr("class","nvd3
nv-wrap
nv-multiBarHorizontalChart").append("g"),M=A.select("g");
O.append("g").attr("class","nv-x
nv-axis"),O.append("g").attr("class","nv-y
nv-axis"),O.append("g").attr("class","nv-barsWrap"),O.append("g").attr("class","nv-legendWrap"),O.append("g").attr("class","nv-controlsWrap"),c&&(i.width(N-E()),t.barColor()&&h.forEach(function(e,t){e.color=d3.rgb("#ccc").darker(t*1.5).toString()}),M.select(".nv-legendWrap").datum(h).call(i),o.top!=i.height()&&(o.top=i.height(),C=(a||parseInt(d.style("height"))||400)-o.top-o.bottom),M.select(".nv-legendWrap").attr("transform","translate("+E()+","+
-o.top+")"));if(l){var
_=[{key:"Grouped",disabled:t.stacked()},{key:"Stacked",disabled:!t.stacked()}];s.width(E()).color(["#444","#444","#444"]),M.select(".nv-controlsWrap").datum(_).attr("transform","translate(0,"+
-o.top+")").call(s)}A.attr("transform","translate("+o.left+","+o.top+")"),t.disabled(h.map(function(e){return
e.disabled})).width(N).height(C).color(h.map(function(e,t){return
e.color||f(e,t)}).filter(function(e,t){return!h[t].disabled}));var D=
M.select(".nv-barsWrap").datum(h.filter(function(e){return!e.disabled}));d3.transition(D).call(t),n.scale(v).ticks(C/24).tickSize(-N,0),d3.transition(M.select(".nv-x.nv-axis")).call(n);var
P=M.select(".nv-x.nv-axis").selectAll("g");P.selectAll("line,
text").style("opacity",1),r.scale(m).ticks(N/100).tickSize(-C,0),M.select(".nv-y.nv-axis").attr("transform","translate(0,"+C+")"),d3.transition(M.select(".nv-y.nv-axis")).call(r),i.dispatch.on("legendClick",function(e,t){e.disabled=!e.disabled,h.filter(function(e){return!e.disabled}).length||h.map(function(e){return
e.disabled=!1,A.selectAll(".nv-series").classed("disabled",!1),e}),g.disabled=h.map(function(e){return!!e.disabled}),w.stateChange(g),x.update()}),i.dispatch.on("legendDblclick",function(e){h.forEach(function(e){e.disabled=!0}),e.disabled=!1,g.disabled=h.map(function(e){return!!e.disabled}),w.stateChange(g),x.update()}),s.dispatch.on("legendClick",function(e,n){if(!e.disabled)return;_=_.map(function(e){return
e.disab
led=!0,e}),e.disabled=!1;switch(e.key){case"Grouped":t.stacked(!1);break;case"Stacked":t.stacked(!0)}g.stacked=t.stacked(),w.stateChange(g),x.update()}),w.on("tooltipShow",function(e){p&&S(e,T.parentNode)}),w.on("changeState",function(n){typeof
n.disabled!="undefined"&&(h.forEach(function(e,t){e.disabled=n.disabled[t]}),g.disabled=n.disabled),typeof
n.stacked!="undefined"&&(t.stacked(n.stacked),g.stacked=n.stacked),e.call(x)})}),x}var
t=e.models.multiBarHorizontal(),n=e.models.axis(),r=e.models.axis(),i=e.models.legend().height(30),s=e.models.legend().height(30),o={top:30,right:20,bottom:50,left:60},u=null,a=null,f=e.utils.defaultColor(),l=!0,c=!0,h=!1,p=!0,d=function(e,t,n,r,i){return"<h3>"+e+"
-
"+t+"</h3>"+"<p>"+n+"</p>"},v,m,g={stacked:h},y=null,b="No
Data
Available.",w=d3.dispatch("tooltipShow","tooltipHide","stateChange","changeState"),E=function(){return
l?180:0};t.stacked(h),n.orient("left").tickPadding(5).highlightZero(!1).showMaxMin(!1).tickFormat(function(e){retur
n e}),r.orient("bottom").tickFormat(d3.format(",.1f"));var
S=function(i,s){var
o=i.pos[0]+(s.offsetLeft||0),u=i.pos[1]+(s.offsetTop||0),a=n.tickFormat()(t.x()(i.point,i.pointIndex)),f=r.tickFormat()(t.y()(i.point,i.pointIndex)),l=d(i.series.key,a,f,i,x);e.tooltip.show([o,u],l,i.value<0?"e":"w",null,s)};return
t.dispatch.on("elementMouseover.tooltip",function(e){e.pos=[e.pos[0]+o.left,e.pos[1]+o.top],w.tooltipShow(e)}),t.dispatch.on("elementMouseout.tooltip",function(e){w.tooltipHide(e)}),w.on("tooltipHide",function(){p&&e.tooltip.cleanup()}),x.dispatch=w,x.multibar=t,x.legend=i,x.xAxis=n,x.yAxis=r,d3.rebind(x,t,"x","y","xDomain","yDomain","forceX","forceY","clipEdge","id","delay","showValues","valueFormat","stacked","barColor"),x.margin=function(e){return
arguments.length?(o.top=typeof e.top!="undefined"?e.top:o.top,o.right=typeof
e.right!="undefined"?e.right:o.right,o.bottom=typeof
e.bottom!="undefined"?e.bottom:o.bottom,o.left=typeof
e.left!="undefined"?e.left:o.left,x):o}
,x.width=function(e){return arguments.length?(u=e,x):u},x.height=function(e){return
arguments.length?(a=e,x):a},x.color=function(t){return
arguments.length?(f=e.utils.getColor(t),i.color(f),x):f},x.showControls=function(e){return
arguments.length?(l=e,x):l},x.showLegend=function(e){return
arguments.length?(c=e,x):c},x.tooltip=function(e){return
arguments.length?(d=e,x):d},x.tooltips=function(e){return
arguments.length?(p=e,x):p},x.tooltipContent=function(e){return
arguments.length?(d=e,x):d},x.state=function(e){return
arguments.length?(g=e,x):g},x.defaultState=function(e){return
arguments.length?(y=e,x):y},x.noData=function(e){return
arguments.length?(b=e,x):b},x},e.models.multiChart=function(){function T(e){return
e.each(function(e){var
u=d3.select(this),f=this;T.update=function(){u.transition().call(T)},T.container=this;var
N=(r||parseInt(u.style("width"))||960)-t.left-t.right,C=(i||parseInt(u.style("height"))||400)-t.top-t.bottom,k=e.filter(function(e){return!e.disabled&&
e.type=="line"&&e.yAxis==1}),L=e.filter(function(e){return!e.disabled&&e.type=="line"&&e.yAxis==2}),A=e.filter(function(e){return!e.disabled&&e.type=="bar"&&e.yAxis==1}),O=e.filter(function(e){return!e.disabled&&e.type=="bar"&&e.yAxis==2}),M=e.filter(function(e){return!e.disabled&&e.type=="area"&&e.yAxis==1}),_=e.filter(function(e){return!e.disabled&&e.type=="area"&&e.yAxis==2}),D=e.filter(function(e){return!e.disabled&&e.yAxis==1}).map(function(e){return
e.values.map(function(e,t){return{x:e.x,y:e.y}})}),P=e.filter(function(e){return!e.disabled&&e.yAxis==2}).map(function(e){return
e.values.map(function(e,t){return{x:e.x,y:e.y}})});a.domain(d3.extent(d3.merge(D.concat(P)),function(e){return
e.x})).range([0,N]);var
H=u.selectAll("g.wrap.multiChart").data([e]),B=H.enter().append("g").attr("class","wrap
nvd3
multiChart").append("g");B.append("g").attr("class","x
axis"),B.append("g").attr("class","y1
axis"),B.append("g").attr("class","y2
axis"),B.append("g").attr("class","lines1
Wrap"),B.append("g").attr("class","lines2Wrap"),B.append("g").attr("class","bars1Wrap"),B.append("g").attr("class","bars2Wrap"),B.append("g").attr("class","stack1Wrap"),B.append("g").attr("class","stack2Wrap"),B.append("g").attr("class","legendWrap");var
j=H.select("g");s&&(E.width(N/2),j.select(".legendWrap").datum(e.map(function(e){return
e.originalKey=e.originalKey===undefined?e.key:e.originalKey,e.key=e.originalKey+(e.yAxis==1?"":"
(right
axis)"),e})).call(E),t.top!=E.height()&&(t.top=E.height(),C=(i||parseInt(u.style("height"))||400)-t.top-t.bottom),j.select(".legendWrap").attr("transform","translate("+N/2+","+
-t.top+")")),h.width(N).height(C).interpolate("monotone").color(e.map(function(e,t){return
e.color||n[t%n.length]}).filter(function(t,n){return!e[n].disabled&&e[n].yAxis==1&&e[n].type=="line"})),p.width(N).height(C).interpolate("monotone").color(e.map(function(e,t){return
e.color||n[t%n.length]}).filter(function(t,n){return!e[n].disabled&&e[n].yAxis==2&&e[n].type
=="line"})),d.width(N).height(C).color(e.map(function(e,t){return
e.color||n[t%n.length]}).filter(function(t,n){return!e[n].disabled&&e[n].yAxis==1&&e[n].type=="bar"})),v.width(N).height(C).color(e.map(function(e,t){return
e.color||n[t%n.length]}).filter(function(t,n){return!e[n].disabled&&e[n].yAxis==2&&e[n].type=="bar"})),m.width(N).height(C).color(e.map(function(e,t){return
e.color||n[t%n.length]}).filter(function(t,n){return!e[n].disabled&&e[n].yAxis==1&&e[n].type=="area"})),g.width(N).height(C).color(e.map(function(e,t){return
e.color||n[t%n.length]}).filter(function(t,n){return!e[n].disabled&&e[n].yAxis==2&&e[n].type=="area"})),j.attr("transform","translate("+t.left+","+t.top+")");var
F=j.select(".lines1Wrap").datum(k),I=j.select(".bars1Wrap").datum(A),q=j.select(".stack1Wrap").datum(M),R=j.select(".lines2Wrap").datum(L),U=j.select(".bars2Wrap").datum(O),z=j.select(".stack2Wrap").datum(_),W=M.length?M.map(function(e){return
e.values}).reduce(function(e,t){return e.map(
function(e,n){return{x:e.x,y:e.y+t[n].y}})}).concat([{x:0,y:0}]):[],X=_.length?_.map(function(e){return
e.values}).reduce(function(e,t){return
e.map(function(e,n){return{x:e.x,y:e.y+t[n].y}})}).concat([{x:0,y:0}]):[];l.domain(d3.extent(d3.merge(D).concat(W),function(e){return
e.y})).range([0,C]),c.domain(d3.extent(d3.merge(P).concat(X),function(e){return
e.y})).range([0,C]),h.yDomain(l.domain()),d.yDomain(l.domain()),m.yDomain(l.domain()),p.yDomain(c.domain()),v.yDomain(c.domain()),g.yDomain(c.domain()),M.length&&d3.transition(q).call(m),_.length&&d3.transition(z).call(g),A.length&&d3.transition(I).call(d),O.length&&d3.transition(U).call(v),k.length&&d3.transition(F).call(h),L.length&&d3.transition(R).call(p),y.ticks(N/100).tickSize(-C,0),j.select(".x.axis").attr("transform","translate(0,"+C+")"),d3.transition(j.select(".x.axis")).call(y),b.ticks(C/36).tickSize(-N,0),d3.transition(j.select(".y1.axis")).call(b),w.ticks(C/36).tickSize(-N,0),d3.transition(j.select(".y2.axis")).
call(w),j.select(".y2.axis").style("opacity",P.length?1:0).attr("transform","translate("+a.range()[1]+",0)"),E.dispatch.on("legendClick",function(t,n){t.disabled=!t.disabled,e.filter(function(e){return!e.disabled}).length||e.map(function(e){return
e.disabled=!1,H.selectAll(".series").classed("disabled",!1),e}),T.update()}),S.on("tooltipShow",function(e){o&&x(e,f.parentNode)})}),T}var
t={top:30,right:20,bottom:50,left:60},n=d3.scale.category20().range(),r=null,i=null,s=!0,o=!0,u=function(e,t,n,r,i){return"<h3>"+e+"</h3>"+"<p>"+n+"
at
"+t+"</p>"},a,f,a=d3.scale.linear(),l=d3.scale.linear(),c=d3.scale.linear(),h=e.models.line().yScale(l),p=e.models.line().yScale(c),d=e.models.multiBar().stacked(!1).yScale(l),v=e.models.multiBar().stacked(!1).yScale(c),m=e.models.stackedArea().yScale(l),g=e.models.stackedArea().yScale(c),y=e.models.axis().scale(a).orient("bottom").tickPadding(5),b=e.models.axis().scale(l).orient("left"),w=e.models.axis().scale(c).orient("right"),E=e.models.legen
d().height(30),S=d3.dispatch("tooltipShow","tooltipHide"),x=function(t,n){var
r=t.pos[0]+(n.offsetLeft||0),i=t.pos[1]+(n.offsetTop||0),s=y.tickFormat()(h.x()(t.point,t.pointIndex)),o=(t.series.yAxis==2?w:b).tickFormat()(h.y()(t.point,t.pointIndex)),a=u(t.series.key,s,o,t,T);e.tooltip.show([r,i],a,undefined,undefined,n.offsetParent)};return
h.dispatch.on("elementMouseover.tooltip",function(e){e.pos=[e.pos[0]+t.left,e.pos[1]+t.top],S.tooltipShow(e)}),h.dispatch.on("elementMouseout.tooltip",function(e){S.tooltipHide(e)}),p.dispatch.on("elementMouseover.tooltip",function(e){e.pos=[e.pos[0]+t.left,e.pos[1]+t.top],S.tooltipShow(e)}),p.dispatch.on("elementMouseout.tooltip",function(e){S.tooltipHide(e)}),d.dispatch.on("elementMouseover.tooltip",function(e){e.pos=[e.pos[0]+t.left,e.pos[1]+t.top],S.tooltipShow(e)}),d.dispatch.on("elementMouseout.tooltip",function(e){S.tooltipHide(e)}),v.dispatch.on("elementMouseover.tooltip",function(e){e.pos=[e.pos[0]+t.left,e.pos[1]+t.top],S.tooltip
Show(e)}),v.dispatch.on("elementMouseout.tooltip",function(e){S.tooltipHide(e)}),m.dispatch.on("tooltipShow",function(e){if(!Math.round(m.y()(e.point)*100))return
setTimeout(function(){d3.selectAll(".point.hover").classed("hover",!1)},0),!1;e.pos=[e.pos[0]+t.left,e.pos[1]+t.top],S.tooltipShow(e)}),m.dispatch.on("tooltipHide",function(e){S.tooltipHide(e)}),g.dispatch.on("tooltipShow",function(e){if(!Math.round(g.y()(e.point)*100))return
setTimeout(function(){d3.selectAll(".point.hover").classed("hover",!1)},0),!1;e.pos=[e.pos[0]+t.left,e.pos[1]+t.top],S.tooltipShow(e)}),g.dispatch.on("tooltipHide",function(e){S.tooltipHide(e)}),h.dispatch.on("elementMouseover.tooltip",function(e){e.pos=[e.pos[0]+t.left,e.pos[1]+t.top],S.tooltipShow(e)}),h.dispatch.on("elementMouseout.tooltip",function(e){S.tooltipHide(e)}),p.dispatch.on("elementMouseover.tooltip",function(e){e.pos=[e.pos[0]+t.left,e.pos[1]+t.top],S.tooltipShow(e)}),p.dispatch.on("elementMouseout.tooltip",function(e){S.tooltip
Hide(e)}),S.on("tooltipHide",function(){o&&e.tooltip.cleanup()}),T.dispatch=S,T.lines1=h,T.lines2=p,T.bars1=d,T.bars2=v,T.stack1=m,T.stack2=g,T.xAxis=y,T.yAxis1=b,T.yAxis2=w,T.x=function(e){return
arguments.length?(getX=e,h.x(e),d.x(e),T):getX},T.y=function(e){return
arguments.length?(getY=e,h.y(e),d.y(e),T):getY},T.margin=function(e){return
arguments.length?(t=e,T):t},T.width=function(e){return
arguments.length?(r=e,T):r},T.height=function(e){return
arguments.length?(i=e,T):i},T.color=function(e){return
arguments.length?(n=e,E.color(e),T):n},T.showLegend=function(e){return
arguments.length?(s=e,T):s},T.tooltips=function(e){return
arguments.length?(o=e,T):o},T.tooltipContent=function(e){return
arguments.length?(u=e,T):u},T},e.models.ohlcBar=function(){function E(e){return
e.each(function(e){var
g=n-t.left-t.right,E=r-t.top-t.bottom,S=d3.select(this);s.domain(y||d3.extent(e[0].values.map(u).concat(p))),v?s.range([g*.5/e[0].values.length,g*(e[0].values.length-.5)/e[0].values.l
ength]):s.range([0,g]),o.domain(b||[d3.min(e[0].values.map(h).concat(d)),d3.max(e[0].values.map(c).concat(d))]).range([E,0]);if(s.domain()[0]===s.domain()[1]||o.domain()[0]===o.domain()[1])singlePoint=!0;s.domain()[0]===s.domain()[1]&&(s.domain()[0]?s.domain([s.domain()[0]-s.domain()[0]*.01,s.domain()[1]+s.domain()[1]*.01]):s.domain([-1,1])),o.domain()[0]===o.domain()[1]&&(o.domain()[0]?o.domain([o.domain()[0]+o.domain()[0]*.01,o.domain()[1]-o.domain()[1]*.01]):o.domain([-1,1]));var
T=d3.select(this).selectAll("g.nv-wrap.nv-ohlcBar").data([e[0].values]),N=T.enter().append("g").attr("class","nvd3
nv-wrap
nv-ohlcBar"),C=N.append("defs"),k=N.append("g"),L=T.select("g");k.append("g").attr("class","nv-ticks"),T.attr("transform","translate("+t.left+","+t.top+")"),S.on("click",function(e,t){w.chartClick({data:e,index:t,pos:d3.event,id:i})}),C.append("clipPath").attr("id","nv-chart-clip-path-"+i).append("rect"),T.select("#nv-chart-clip-path-"+i+"
rect").attr("width",g).attr("height"
,E),L.attr("clip-path",m?"url(#nv-chart-clip-path-"+i+")":"");var
A=T.select(".nv-ticks").selectAll(".nv-tick").data(function(e){return
e});A.exit().remove();var
O=A.enter().append("path").attr("class",function(e,t,n){return(f(e,t)>l(e,t)?"nv-tick
negative":"nv-tick positive")+"
nv-tick-"+n+"-"+t}).attr("d",function(t,n){var
r=g/e[0].values.length*.9;return"m0,0l0,"+(o(f(t,n))-o(c(t,n)))+"l"+
-r/2+",0l"+r/2+",0l0,"+(o(h(t,n))-o(f(t,n)))+"l0,"+(o(l(t,n))-o(h(t,n)))+"l"+r/2+",0l"+
-r/2+",0z"}).attr("transform",function(e,t){return"translate("+s(u(e,t))+","+o(c(e,t))+")"}).on("mouseover",function(t,n){d3.select(this).classed("hover",!0),w.elementMouseover({point:t,series:e[0],pos:[s(u(t,n)),o(a(t,n))],pointIndex:n,seriesIndex:0,e:d3.event})}).on("mouseout",function(t,n){d3.select(this).classed("hover",!1),w.elementMouseout({point:t,series:e[0],pointIndex:n,seriesIndex:0,e:d3.event})}).on("click",function(e,t){w.elementClick({value:a(e,t),data:e,index:t,pos:[s(u(e,t)),o(a(e,t))]
,e:d3.event,id:i}),d3.event.stopPropagation()}).on("dblclick",function(e,t){w.elementDblClick({value:a(e,t),data:e,index:t,pos:[s(u(e,t)),o(a(e,t))],e:d3.event,id:i}),d3.event.stopPropagation()});A.attr("class",function(e,t,n){return(f(e,t)>l(e,t)?"nv-tick
negative":"nv-tick positive")+"
nv-tick-"+n+"-"+t}),d3.transition(A).attr("transform",function(e,t){return"translate("+s(u(e,t))+","+o(c(e,t))+")"}).attr("d",function(t,n){var
r=g/e[0].values.length*.9;return"m0,0l0,"+(o(f(t,n))-o(c(t,n)))+"l"+
-r/2+",0l"+r/2+",0l0,"+(o(h(t,n))-o(f(t,n)))+"l0,"+(o(l(t,n))-o(h(t,n)))+"l"+r/2+",0l"+
-r/2+",0z"})}),E}var
t={top:0,right:0,bottom:0,left:0},n=960,r=500,i=Math.floor(Math.random()*1e4),s=d3.scale.linear(),o=d3.scale.linear(),u=function(e){return
e.x},a=function(e){return e.y},f=function(e){return e.open},l=function(e){return
e.close},c=function(e){return e.high},h=function(e){return
e.low},p=[],d=[],v=!1,m=!0,g=e.utils.defaultColor(),y,b,w=d3.dispatch("chartClick","elementClick","
elementDblClick","elementMouseover","elementMouseout");return
E.dispatch=w,E.x=function(e){return arguments.length?(u=e,E):u},E.y=function(e){return
arguments.length?(a=e,E):a},E.open=function(e){return
arguments.length?(f=e,E):f},E.close=function(e){return
arguments.length?(l=e,E):l},E.high=function(e){return
arguments.length?(c=e,E):c},E.low=function(e){return
arguments.length?(h=e,E):h},E.margin=function(e){return arguments.length?(t.top=typeof
e.top!="undefined"?e.top:t.top,t.right=typeof
e.right!="undefined"?e.right:t.right,t.bottom=typeof
e.bottom!="undefined"?e.bottom:t.bottom,t.left=typeof
e.left!="undefined"?e.left:t.left,E):t},E.width=function(e){return
arguments.length?(n=e,E):n},E.height=function(e){return
arguments.length?(r=e,E):r},E.xScale=function(e){return
arguments.length?(s=e,E):s},E.yScale=function(e){return
arguments.length?(o=e,E):o},E.xDomain=function(e){return
arguments.length?(y=e,E):y},E.yDomain=function(e){return
arguments.length?(b=e,E):b},E.force
X=function(e){return arguments.length?(p=e,E):p},E.forceY=function(e){return
arguments.length?(d=e,E):d},E.padData=function(e){return
arguments.length?(v=e,E):v},E.clipEdge=function(e){return
arguments.length?(m=e,E):m},E.color=function(t){return
arguments.length?(g=e.utils.getColor(t),E):g},E.id=function(e){return
arguments.length?(i=e,E):i},E},e.models.pie=function(){function E(e){return
e.each(function(e){function P(e){var t=(e.startAngle+e.endAngle)*90/Math.PI-90;return
t>90?t-180:t}function
H(e){e.endAngle=isNaN(e.endAngle)?0:e.endAngle,e.startAngle=isNaN(e.startAngle)?0:e.startAngle,v||(e.innerRadius=0);var
t=d3.interpolate(this._current,e);return this._current=t(0),function(e){return
L(t(e))}}function B(e){e.innerRadius=0;var
t=d3.interpolate({startAngle:0,endAngle:0},e);return function(e){return L(t(e))}}var
u=n-t.left-t.right,l=r-t.top-t.bottom,E=Math.min(u,l)/2,S=E-E/5,x=d3.select(this),T=x.selectAll(".nv-wrap.nv-pie").data([i(e[0])]),N=T.enter().append("g").attr("
class","nvd3 nv-wrap nv-pie
nv-chart-"+a),C=N.append("g"),k=T.select("g");C.append("g").attr("class","nv-pie"),T.attr("transform","translate("+t.left+","+t.top+")"),k.select(".nv-pie").attr("transform","translate("+u/2+","+l/2+")"),x.on("click",function(e,t){w.chartClick({data:e,index:t,pos:d3.event,id:a})});var
L=d3.svg.arc().outerRadius(S);g&&L.startAngle(g),y&&L.endAngle(y),v&&L.innerRadius(E*b);var
A=d3.layout.pie().sort(null).value(function(e){return
e.disabled?0:o(e)}),O=T.select(".nv-pie").selectAll(".nv-slice").data(A);O.exit().remove();var
M=O.enter().append("g").attr("class","nv-slice").on("mouseover",function(e,t){d3.select(this).classed("hover",!0),w.elementMouseover({label:s(e.data),value:o(e.data),point:e.data,pointIndex:t,pos:[d3.event.pageX,d3.event.pageY],id:a})}).on("mouseout",function(e,t){d3.select(this).classed("hover",!1),w.elementMouseout({label:s(e.data),value:o(e.data),point:e.data,index:t,id:a})}).on("click",function(e,t){w.elementClick({label:s(e.d
ata),value:o(e.data),point:e.data,index:t,pos:d3.event,id:a}),d3.event.stopPropagation()}).on("dblclick",function(e,t){w.elementDblClick({label:s(e.data),value:o(e.data),point:e.data,index:t,pos:d3.event,id:a}),d3.event.stopPropagation()});O.attr("fill",function(e,t){return
f(e,t)}).attr("stroke",function(e,t){return f(e,t)});var
_=M.append("path").each(function(e){this._current=e});d3.transition(O.select("path")).attr("d",L).attrTween("d",H);if(c){var
D=d3.svg.arc().innerRadius(0);h&&(D=L),p&&(D=d3.svg.arc().outerRadius(L.outerRadius())),M.append("g").classed("nv-label",!0).each(function(e,t){var
n=d3.select(this);n.attr("transform",function(e){if(m){e.outerRadius=S+10,e.innerRadius=S+15;var
t=(e.startAngle+e.endAngle)/2*(180/Math.PI);return(e.startAngle+e.endAngle)/2<Math.PI?t-=90:t+=90,"translate("+D.centroid(e)+")
rotate("+t+")"}return
e.outerRadius=E+10,e.innerRadius=E+15,"translate("+D.centroid(e)+")"}),n.append("rect").style("stroke","#fff").style("fill","#fff").attr(
"rx",3).attr("ry",3),n.append("text").style("text-anchor",m?(e.startAngle+e.endAngle)/2<Math.PI?"start":"end":"middle").style("fill","#000")}),O.select(".nv-label").transition().attr("transform",function(e){if(m){e.outerRadius=S+10,e.innerRadius=S+15;var
t=(e.startAngle+e.endAngle)/2*(180/Math.PI);return(e.startAngle+e.endAngle)/2<Math.PI?t-=90:t+=90,"translate("+D.centroid(e)+")
rotate("+t+")"}return
e.outerRadius=E+10,e.innerRadius=E+15,"translate("+D.centroid(e)+")"}),O.each(function(e,t){var
n=d3.select(this);n.select(".nv-label
text").style("text-anchor",m?(e.startAngle+e.endAngle)/2<Math.PI?"start":"end":"middle").text(function(e,t){var
n=(e.endAngle-e.startAngle)/(2*Math.PI);return
e.value&&n>d?s(e.data):""});var
r=n.select("text").node().getBBox();n.select(".nv-label
rect").attr("width",r.width+10).attr("height",r.height+10).attr("transform",function(){return"translate("+[r.x-5,r.y-5]+")"})})}}),E}var
t={top:0,right:0,bottom:0,left:0},n=500,r=500,i=function(e){return
e.values},s=function(e){return e.x},o=function(e){return e.y},u=function(e){return
e.description},a=Math.floor(Math.random()*1e4),f=e.utils.defaultColor(),l=d3.format(",.2f"),c=!0,h=!0,p=!1,d=.02,v=!1,m=!1,g=!1,y=!1,b=.5,w=d3.dispatch("chartClick","elementClick","elementDblClick","elementMouseover","elementMouseout");return
E.dispatch=w,E.margin=function(e){return arguments.length?(t.top=typeof
e.top!="undefined"?e.top:t.top,t.right=typeof
e.right!="undefined"?e.right:t.right,t.bottom=typeof
e.bottom!="undefined"?e.bottom:t.bottom,t.left=typeof
e.left!="undefined"?e.left:t.left,E):t},E.width=function(e){return
arguments.length?(n=e,E):n},E.height=function(e){return
arguments.length?(r=e,E):r},E.values=function(e){return
arguments.length?(i=e,E):i},E.x=function(e){return
arguments.length?(s=e,E):s},E.y=function(e){return
arguments.length?(o=d3.functor(e),E):o},E.description=function(e){return
arguments.length?(u=e,E):u},E.showLabels=function(e){return arguments.length?(c=e,E
):c},E.labelSunbeamLayout=function(e){return
arguments.length?(m=e,E):m},E.donutLabelsOutside=function(e){return
arguments.length?(p=e,E):p},E.pieLabelsOutside=function(e){return
arguments.length?(h=e,E):h},E.donut=function(e){return
arguments.length?(v=e,E):v},E.donutRatio=function(e){return
arguments.length?(b=e,E):b},E.startAngle=function(e){return
arguments.length?(g=e,E):g},E.endAngle=function(e){return
arguments.length?(y=e,E):y},E.id=function(e){return
arguments.length?(a=e,E):a},E.color=function(t){return
arguments.length?(f=e.utils.getColor(t),E):f},E.valueFormat=function(e){return
arguments.length?(l=e,E):l},E.labelThreshold=function(e){return
arguments.length?(d=e,E):d},E},e.models.pieChart=function(){function v(e){return
e.each(function(e){var
u=d3.select(this),a=this,f=(i||parseInt(u.style("width"))||960)-r.left-r.right,d=(s||parseInt(u.style("height"))||400)-r.top-r.bottom;v.update=function(){u.transition().call(v)},v.container=this,l.disabled=e[0].map(function
(e){return!!e.disabled});if(!c){var m;c={};for(m in l)l[m]instanceof
Array?c[m]=l[m].slice(0):c[m]=l[m]}if(!e[0]||!e[0].length){var
g=u.selectAll(".nv-noData").data([h]);return
g.enter().append("text").attr("class","nvd3
nv-noData").attr("dy","-.7em").style("text-anchor","middle"),g.attr("x",r.left+f/2).attr("y",r.top+d/2).text(function(e){return
e}),v}u.selectAll(".nv-noData").remove();var
y=u.selectAll("g.nv-wrap.nv-pieChart").data([e]),b=y.enter().append("g").attr("class","nvd3
nv-wrap
nv-pieChart").append("g"),w=y.select("g");b.append("g").attr("class","nv-pieWrap"),b.append("g").attr("class","nv-legendWrap"),o&&(n.width(f).key(t.x()),y.select(".nv-legendWrap").datum(t.values()(e[0])).call(n),r.top!=n.height()&&(r.top=n.height(),d=(s||parseInt(u.style("height"))||400)-r.top-r.bottom),y.select(".nv-legendWrap").attr("transform","translate(0,"+
-r.top+")")),y.attr("transform","translate("+r.left+","+r.top+")"),t.width(f).height(d);var
E=w.select(".nv-pieWrap").datum(e);d3.
transition(E).call(t),n.dispatch.on("legendClick",function(n,r,i){n.disabled=!n.disabled,t.values()(e[0]).filter(function(e){return!e.disabled}).length||t.values()(e[0]).map(function(e){return
e.disabled=!1,y.selectAll(".nv-series").classed("disabled",!1),e}),l.disabled=e[0].map(function(e){return!!e.disabled}),p.stateChange(l),v.update()}),t.dispatch.on("elementMouseout.tooltip",function(e){p.tooltipHide(e)}),p.on("changeState",function(t){typeof
t.disabled!="undefined"&&(e[0].forEach(function(e,n){e.disabled=t.disabled[n]}),l.disabled=t.disabled),v.update()})}),v}var
t=e.models.pie(),n=e.models.legend(),r={top:30,right:20,bottom:20,left:20},i=null,s=null,o=!0,u=e.utils.defaultColor(),a=!0,f=function(e,t,n,r){return"<h3>"+e+"</h3>"+"<p>"+t+"</p>"},l={},c=null,h="No
Data
Available.",p=d3.dispatch("tooltipShow","tooltipHide","stateChange","changeState"),d=function(n,r){var
i=t.description()(n.point)||t.x()(n.point),s=n.pos[0]+(r&&r.offsetLeft||0),o=n.pos[1]+(r&&r.offsetTop||0
),u=t.valueFormat()(t.y()(n.point)),a=f(i,u,n,v);e.tooltip.show([s,o],a,n.value<0?"n":"s",null,r)};return
t.dispatch.on("elementMouseover.tooltip",function(e){e.pos=[e.pos[0]+r.left,e.pos[1]+r.top],p.tooltipShow(e)}),p.on("tooltipShow",function(e){a&&d(e)}),p.on("tooltipHide",function(){a&&e.tooltip.cleanup()}),v.legend=n,v.dispatch=p,v.pie=t,d3.rebind(v,t,"valueFormat","values","x","y","description","id","showLabels","donutLabelsOutside","pieLabelsOutside","donut","donutRatio","labelThreshold"),v.margin=function(e){return
arguments.length?(r.top=typeof e.top!="undefined"?e.top:r.top,r.right=typeof
e.right!="undefined"?e.right:r.right,r.bottom=typeof
e.bottom!="undefined"?e.bottom:r.bottom,r.left=typeof
e.left!="undefined"?e.left:r.left,v):r},v.width=function(e){return
arguments.length?(i=e,v):i},v.height=function(e){return
arguments.length?(s=e,v):s},v.color=function(r){return
arguments.length?(u=e.utils.getColor(r),n.color(u),t.color(u),v):u},v.showLegend=function(e){retur
n arguments.length?(o=e,v):o},v.tooltips=function(e){return
arguments.length?(a=e,v):a},v.tooltipContent=function(e){return
arguments.length?(f=e,v):f},v.state=function(e){return
arguments.length?(l=e,v):l},v.defaultState=function(e){return
arguments.length?(c=e,v):c},v.noData=function(e){return
arguments.length?(h=e,v):h},v},e.models.scatter=function(){function j(e){return
e.each(function(e){function $(){if(!g)return!1;var i,a=d3.merge(e.map(function(e,t){return
e.values.map(function(e,n){var
r=f(e,n)+Math.random()*1e-7,i=l(e,n)+Math.random()*1e-7;return[o(r),u(i),t,n,e]}).filter(function(e,t){return
b(e[4],t)})}));if(M===!0){if(x){var
c=R.select("defs").selectAll(".nv-point-clips").data([s]).enter();c.append("clipPath").attr("class","nv-point-clips").attr("id","nv-points-clip-"+s);var
h=R.select("#nv-points-clip-"+s).selectAll("circle").data(a);h.enter().append("circle").attr("r",T),h.exit().remove(),h.attr("cx",function(e){return
e[0]}).attr("cy",function(e){return e[1]})
,R.select(".nv-point-paths").attr("clip-path","url(#nv-points-clip-"+s+")")}a.length&&(a.push([o.range()[0]-20,u.range()[0]-20,null,null]),a.push([o.range()[1]+20,u.range()[1]+20,null,null]),a.push([o.range()[0]-20,u.range()[0]+20,null,null]),a.push([o.range()[1]+20,u.range()[1]-20,null,null]));var
p=d3.geom.polygon([[-10,-10],[-10,r+10],[n+10,r+10],[n+10,-10]]),d=d3.geom.voronoi(a).map(function(e,t){return{data:p.clip(e),series:a[t][2],point:a[t][3]}}),v=R.select(".nv-point-paths").selectAll("path").data(d);v.enter().append("path").attr("class",function(e,t){return"nv-path-"+t}),v.exit().remove(),v.attr("d",function(e){return
e.data.length===0?"M 0
0":"M"+e.data.join("L")+"Z"}),v.on("click",function(n){if(B)return
0;var
r=e[n.series],i=r.values[n.point];O.elementClick({point:i,series:r,pos:[o(f(i,n.point))+t.left,u(l(i,n.point))+t.top],seriesIndex:n.series,pointIndex:n.point})}).on("mouseover",function(n){if(B)return
0;var r=e[n.series],i=r.values[n.point];O.elementMouseove
r({point:i,series:r,pos:[o(f(i,n.point))+t.left,u(l(i,n.point))+t.top],seriesIndex:n.series,pointIndex:n.point})}).on("mouseout",function(t,n){if(B)return
0;var
r=e[t.series],i=r.values[t.point];O.elementMouseout({point:i,series:r,seriesIndex:t.series,pointIndex:t.point})})}else
R.select(".nv-groups").selectAll(".nv-group").selectAll(".nv-point").on("click",function(n,r){if(B||!e[n.series])return
0;var
i=e[n.series],s=i.values[r];O.elementClick({point:s,series:i,pos:[o(f(s,r))+t.left,u(l(s,r))+t.top],seriesIndex:n.series,pointIndex:r})}).on("mouseover",function(n,r){if(B||!e[n.series])return
0;var
i=e[n.series],s=i.values[r];O.elementMouseover({point:s,series:i,pos:[o(f(s,r))+t.left,u(l(s,r))+t.top],seriesIndex:n.series,pointIndex:r})}).on("mouseout",function(t,n){if(B||!e[t.series])return
0;var
r=e[t.series],i=r.values[n];O.elementMouseout({point:i,series:r,seriesIndex:t.series,pointIndex:n})});B=!1}var
j=n-t.left-t.right,F=r-t.top-t.bottom,I=d3.select(this);e=e.map(functio
n(e,t){return e.values=e.values.map(function(e){return e.series=t,e}),e});var
q=N&&C&&k?[]:d3.merge(e.map(function(e){return e.values
-.map(function(e,t){return{x:f(e,t),y:l(e,t),size:c(e,t)}})}));o.domain(N||d3.extent(q.map(function(e){return
e.x}).concat(d))),w&&e[0]?o.range([(j*E+j)/(2*e[0].values.length),j-j*(1+E)/(2*e[0].values.length)]):o.range([0,j]),u.domain(C||d3.extent(q.map(function(e){return
e.y}).concat(v))).range([F,0]),a.domain(k||d3.extent(q.map(function(e){return
e.size}).concat(m))).range(L||[16,256]);if(o.domain()[0]===o.domain()[1]||u.domain()[0]===u.domain()[1])A=!0;o.domain()[0]===o.domain()[1]&&(o.domain()[0]?o.domain([o.domain()[0]-o.domain()[0]*.01,o.domain()[1]+o.domain()[1]*.01]):o.domain([-1,1])),u.domain()[0]===u.domain()[1]&&(u.domain()[0]?u.domain([u.domain()[0]+u.domain()[0]*.01,u.domain()[1]-u.domain()[1]*.01]):u.domain([-1,1])),isNaN(o.domain()[0])&&o.domain([-1,1]),isNaN(u.domain()[0])&&u.domain([-1,1]),_=_||o,D=D||u,P=P||a;var
R=I.selectAll("g.nv-wrap.nv-scatter").data([e]),U=R.enter().append("g").attr("class","nvd3
nv-wrap nv-scatter nv-chart-"+s+(A?" nv-single-point":""
)),W=U.append("defs"),X=U.append("g"),V=R.select("g");X.append("g").attr("class","nv-groups"),X.append("g").attr("class","nv-point-paths"),R.attr("transform","translate("+t.left+","+t.top+")"),W.append("clipPath").attr("id","nv-edge-clip-"+s).append("rect"),R.select("#nv-edge-clip-"+s+"
rect").attr("width",j).attr("height",F),V.attr("clip-path",S?"url(#nv-edge-clip-"+s+")":""),B=!0;var
J=R.select(".nv-groups").selectAll(".nv-group").data(function(e){return
e},function(e){return
e.key});J.enter().append("g").style("stroke-opacity",1e-6).style("fill-opacity",1e-6),d3.transition(J.exit()).style("stroke-opacity",1e-6).style("fill-opacity",1e-6).remove(),J.attr("class",function(e,t){return"nv-group
nv-series-"+t}).classed("hover",function(e){return
e.hover}),d3.transition(J).style("fill",function(e,t){return
i(e,t)}).style("stroke",function(e,t){return
i(e,t)}).style("stroke-opacity",1).style("fill-opacity",.5);if(p){var
K=J.selectAll("circle.nv-point").data(function(e){return e.
values},y);K.enter().append("circle").attr("cx",function(e,t){return
_(f(e,t))}).attr("cy",function(e,t){return
D(l(e,t))}).attr("r",function(e,t){return
Math.sqrt(a(c(e,t))/Math.PI)}),K.exit().remove(),J.exit().selectAll("path.nv-point").transition().attr("cx",function(e,t){return
o(f(e,t))}).attr("cy",function(e,t){return
u(l(e,t))}).remove(),K.each(function(e,t){d3.select(this).classed("nv-point",!0).classed("nv-point-"+t,!0)}),K.transition().attr("cx",function(e,t){return
o(f(e,t))}).attr("cy",function(e,t){return
u(l(e,t))}).attr("r",function(e,t){return
Math.sqrt(a(c(e,t))/Math.PI)})}else{var
K=J.selectAll("path.nv-point").data(function(e){return
e.values});K.enter().append("path").attr("transform",function(e,t){return"translate("+_(f(e,t))+","+D(l(e,t))+")"}).attr("d",d3.svg.symbol().type(h).size(function(e,t){return
a(c(e,t))})),K.exit().remove(),d3.transition(J.exit().selectAll("path.nv-point")).attr("transform",function(e,t){return"translate("+o(f(e,t))+","+u(l(e,t
))+")"}).remove(),K.each(function(e,t){d3.select(this).classed("nv-point",!0).classed("nv-point-"+t,!0)}),K.transition().attr("transform",function(e,t){return"translate("+o(f(e,t))+","+u(l(e,t))+")"}).attr("d",d3.svg.symbol().type(h).size(function(e,t){return
a(c(e,t))}))}clearTimeout(H),H=setTimeout($,300),_=o.copy(),D=u.copy(),P=a.copy()}),j}var
t={top:0,right:0,bottom:0,left:0},n=960,r=500,i=e.utils.defaultColor(),s=Math.floor(Math.random()*1e5),o=d3.scale.linear(),u=d3.scale.linear(),a=d3.scale.linear(),f=function(e){return
e.x},l=function(e){return e.y},c=function(e){return e.size||1},h=function(e){return
e.shape||"circle"},p=!0,d=[],v=[],m=[],g=!0,y=null,b=function(e){return!e.notActive},w=!1,E=.1,S=!1,x=!0,T=function(){return
25},N=null,C=null,k=null,L=null,A=!1,O=d3.dispatch("elementClick","elementMouseover","elementMouseout"),M=!0,_,D,P,H,B=!1;return
O.on("elementMouseover.point",function(e){g&&d3.select(".nv-chart-"+s+"
.nv-series-"+e.seriesIndex+" .nv-point-"+e.po
intIndex).classed("hover",!0)}),O.on("elementMouseout.point",function(e){g&&d3.select(".nv-chart-"+s+"
.nv-series-"+e.seriesIndex+"
.nv-point-"+e.pointIndex).classed("hover",!1)}),j.dispatch=O,j.x=function(e){return
arguments.length?(f=d3.functor(e),j):f},j.y=function(e){return
arguments.length?(l=d3.functor(e),j):l},j.size=function(e){return
arguments.length?(c=d3.functor(e),j):c},j.margin=function(e){return
arguments.length?(t.top=typeof e.top!="undefined"?e.top:t.top,t.right=typeof
e.right!="undefined"?e.right:t.right,t.bottom=typeof
e.bottom!="undefined"?e.bottom:t.bottom,t.left=typeof
e.left!="undefined"?e.left:t.left,j):t},j.width=function(e){return
arguments.length?(n=e,j):n},j.height=function(e){return
arguments.length?(r=e,j):r},j.xScale=function(e){return
arguments.length?(o=e,j):o},j.yScale=function(e){return
arguments.length?(u=e,j):u},j.zScale=function(e){return
arguments.length?(a=e,j):a},j.xDomain=function(e){return
arguments.length?(N=e,j):N},j.yDomain=functi
on(e){return arguments.length?(C=e,j):C},j.sizeDomain=function(e){return
arguments.length?(k=e,j):k},j.sizeRange=function(e){return
arguments.length?(L=e,j):L},j.forceX=function(e){return
arguments.length?(d=e,j):d},j.forceY=function(e){return
arguments.length?(v=e,j):v},j.forceSize=function(e){return
arguments.length?(m=e,j):m},j.interactive=function(e){return
arguments.length?(g=e,j):g},j.pointKey=function(e){return
arguments.length?(y=e,j):y},j.pointActive=function(e){return
arguments.length?(b=e,j):b},j.padData=function(e){return
arguments.length?(w=e,j):w},j.padDataOuter=function(e){return
arguments.length?(E=e,j):E},j.clipEdge=function(e){return
arguments.length?(S=e,j):S},j.clipVoronoi=function(e){return
arguments.length?(x=e,j):x},j.useVoronoi=function(e){return
arguments.length?(M=e,M===!1&&(x=!1),j):M},j.clipRadius=function(e){return
arguments.length?(T=e,j):T},j.color=function(t){return
arguments.length?(i=e.utils.getColor(t),j):i},j.shape=function(e){return argum
ents.length?(h=e,j):h},j.onlyCircles=function(e){return
arguments.length?(p=e,j):p},j.id=function(e){return
arguments.length?(s=e,j):s},j.singlePoint=function(e){return
arguments.length?(A=e,j):A},j},e.models.scatterChart=function(){function P(e){return
e.each(function(e){function W(){if(E)return
R.select(".nv-point-paths").style("pointer-events","all"),!1;R.select(".nv-point-paths").style("pointer-events","none");var
i=d3.mouse(this);h.distortion(w).focus(i[0]),p.distortion(w).focus(i[1]),R.select(".nv-scatterWrap").call(t),R.select(".nv-x.nv-axis").call(n),R.select(".nv-y.nv-axis").call(r),R.select(".nv-distributionX").datum(e.filter(function(e){return!e.disabled})).call(o),R.select(".nv-distributionY").datum(e.filter(function(e){return!e.disabled})).call(u)}var
x=d3.select(this),T=this,N=(f||parseInt(x.style("width"))||960)-a.left-a.right,H=(l||parseInt(x.style("height"))||400)-a.top-a.bottom;P.update=function(){x.transition().call(P)},C.disabled=e.map(function(e){return!
!e.disabled});if(!k){var B;k={};for(B in C)C[B]instanceof
Array?k[B]=C[B].slice(0):k[B]=C[B]}if(!e||!e.length||!e.filter(function(e){return
e.values.length}).length){var j=x.selectAll(".nv-noData").data([A]);return
j.enter().append("text").attr("class","nvd3
nv-noData").attr("dy","-.7em").style("text-anchor","middle"),j.attr("x",a.left+N/2).attr("y",a.top+H/2).text(function(e){return
e}),P}x.selectAll(".nv-noData").remove(),O=O||h,M=M||p;var
F=x.selectAll("g.nv-wrap.nv-scatterChart").data([e]),I=F.enter().append("g").attr("class","nvd3
nv-wrap nv-scatterChart
nv-chart-"+t.id()),q=I.append("g"),R=F.select("g");q.append("rect").attr("class","nvd3
nv-background"),q.append("g").attr("class","nv-x
nv-axis"),q.append("g").attr("class","nv-y
nv-axis"),q.append("g").attr("class","nv-scatterWrap"),q.append("g").attr("class","nv-distWrap"),q.append("g").attr("class","nv-legendWrap"),q.append("g").attr("class","nv-controlsWrap"),y&&(i.width(N/2),F.select(".nv-legendWrap").datum(e).call
(i),a.top!=i.height()&&(a.top=i.height(),H=(l||parseInt(x.style("height"))||400)-a.top-a.bottom),F.select(".nv-legendWrap").attr("transform","translate("+N/2+","+
-a.top+")")),b&&(s.width(180).color(["#444"]),R.select(".nv-controlsWrap").datum(D).attr("transform","translate(0,"+
-a.top+")").call(s)),F.attr("transform","translate("+a.left+","+a.top+")"),t.width(N).height(H).color(e.map(function(e,t){return
e.color||c(e,t)}).filter(function(t,n){return!e[n].disabled})).xDomain(null).yDomain(null),F.select(".nv-scatterWrap").datum(e.filter(function(e){return!e.disabled})).call(t);if(d){var
U=h.domain()[1]-h.domain()[0];t.xDomain([h.domain()[0]-d*U,h.domain()[1]+d*U])}if(v){var
z=p.domain()[1]-p.domain()[0];t.yDomain([p.domain()[0]-v*z,p.domain()[1]+v*z])}F.select(".nv-scatterWrap").datum(e.filter(function(e){return!e.disabled})).call(t),n.scale(h).ticks(n.ticks()&&n.ticks().length?n.ticks():N/100).tickSize(-H,0),R.select(".nv-x.nv-axis").attr("transform","translate(0,"+p.range(
)[0]+")").call(n),r.scale(p).ticks(r.ticks()&&r.ticks().length?r.ticks():H/36).tickSize(-N,0),R.select(".nv-y.nv-axis").call(r),m&&(o.getData(t.x()).scale(h).width(N).color(e.map(function(e,t){return
e.color||c(e,t)}).filter(function(t,n){return!e[n].disabled})),q.select(".nv-distWrap").append("g").attr("class","nv-distributionX"),R.select(".nv-distributionX").attr("transform","translate(0,"+p.range()[0]+")").datum(e.filter(function(e){return!e.disabled})).call(o)),g&&(u.getData(t.y()).scale(p).width(H).color(e.map(function(e,t){return
e.color||c(e,t)}).filter(function(t,n){return!e[n].disabled})),q.select(".nv-distWrap").append("g").attr("class","nv-distributionY"),R.select(".nv-distributionY").attr("transform","translate(-"+u.size()+",0)").datum(e.filter(function(e){return!e.disabled})).call(u)),d3.fisheye&&(R.select(".nv-background").attr("width",N).attr("height",H),R.select(".nv-background").on("mousemove",W),R.select(".nv-background").on("click",function(){E=!E}),t.disp
atch.on("elementClick.freezeFisheye",function(){E=!E})),s.dispatch.on("legendClick",function(e,i){e.disabled=!e.disabled,w=e.disabled?0:2.5,R.select(".nv-background").style("pointer-events",e.disabled?"none":"all"),R.select(".nv-point-paths").style("pointer-events",e.disabled?"all":"none"),e.disabled?(h.distortion(w).focus(0),p.distortion(w).focus(0),R.select(".nv-scatterWrap").call(t),R.select(".nv-x.nv-axis").call(n),R.select(".nv-y.nv-axis").call(r)):E=!1,P.update()}),i.dispatch.on("legendClick",function(t,n,r){t.disabled=!t.disabled,e.filter(function(e){return!e.disabled}).length||e.map(function(e){return
e.disabled=!1,F.selectAll(".nv-series").classed("disabled",!1),e}),C.disabled=e.map(function(e){return!!e.disabled}),L.stateChange(C),P.update()}),i.dispatch.on("legendDblclick",function(t){e.forEach(function(e){e.disabled=!0}),t.disabled=!1,C.disabled=e.map(function(e){return!!e.disabled}),L.stateChange(C),P.update()}),t.dispatch.on("elementMouseover.tooltip",function(
e){d3.select(".nv-chart-"+t.id()+" .nv-series-"+e.seriesIndex+"
.nv-distx-"+e.pointIndex).attr("y1",function(t,n){return
e.pos[1]-H}),d3.select(".nv-chart-"+t.id()+"
.nv-series-"+e.seriesIndex+"
.nv-disty-"+e.pointIndex).attr("x2",e.pos[0]+o.size()),e.pos=[e.pos[0]+a.left,e.pos[1]+a.top],L.tooltipShow(e)}),L.on("tooltipShow",function(e){S&&_(e,T.parentNode)}),L.on("changeState",function(t){typeof
t.disabled!="undefined"&&(e.forEach(function(e,n){e.disabled=t.disabled[n]}),C.disabled=t.disabled),P.update()}),O=h.copy(),M=p.copy()}),P}var
t=e.models.scatter(),n=e.models.axis(),r=e.models.axis(),i=e.models.legend(),s=e.models.legend(),o=e.models.distribution(),u=e.models.distribution(),a={top:30,right:20,bottom:50,left:75},f=null,l=null,c=e.utils.defaultColor(),h=d3.fisheye?d3.fisheye.scale(d3.scale.linear).distortion(0):t.xScale(),p=d3.fisheye?d3.fisheye.scale(d3.scale.linear).distortion(0):t.yScale(),d=0,v=0,m=!1,g=!1,y=!0,b=!!d3.fisheye,w=0,E=!1,S=!0,x=function(e,t,n){return
"<strong>"+t+"</strong>"},T=function(e,t,n){return"<strong>"+n+"</strong>"},N=null,C={},k=null,L=d3.dispatch("tooltipShow","tooltipHide","stateChange","changeState"),A="No
Data
Available.";t.xScale(h).yScale(p),n.orient("bottom").tickPadding(10),r.orient("left").tickPadding(10),o.axis("x"),u.axis("y");var
O,M,_=function(i,s){var
o=i.pos[0]+(s.offsetLeft||0),u=i.pos[1]+(s.offsetTop||0),f=i.pos[0]+(s.offsetLeft||0),l=p.range()[0]+a.top+(s.offsetTop||0),c=h.range()[0]+a.left+(s.offsetLeft||0),d=i.pos[1]+(s.offsetTop||0),v=n.tickFormat()(t.x()(i.point,i.pointIndex)),m=r.tickFormat()(t.y()(i.point,i.pointIndex));x!=null&&e.tooltip.show([f,l],x(i.series.key,v,m,i,P),"n",1,s,"x-nvtooltip"),T!=null&&e.tooltip.show([c,d],T(i.series.key,v,m,i,P),"e",1,s,"y-nvtooltip"),N!=null&&e.tooltip.show([o,u],N(i.series.key,v,m,i,P),i.value<0?"n":"s",null,s)},D=[{key:"Magnify",disabled:!0}];return
t.dispatch.on("elementMouseout.tooltip",function(e){L.tooltipHide(e),d3.select(".nv-chart-"+t.id()+"
.nv-series-"+e.seriesIndex+"
.nv-distx-"+e.pointIndex).attr("y1",0),d3.select(".nv-chart-"+t.id()+"
.nv-series-"+e.seriesIndex+"
.nv-disty-"+e.pointIndex).attr("x2",u.size())}),L.on("tooltipHide",function(){S&&e.tooltip.cleanup()}),P.dispatch=L,P.scatter=t,P.legend=i,P.controls=s,P.xAxis=n,P.yAxis=r,P.distX=o,P.distY=u,d3.rebind(P,t,"id","interactive","pointActive","x","y","shape","size","xScale","yScale","zScale","xDomain","yDomain","sizeDomain","sizeRange","forceX","forceY","forceSize","clipVoronoi","clipRadius","useVoronoi"),P.margin=function(e){return
arguments.length?(a.top=typeof e.top!="undefined"?e.top:a.top,a.right=typeof
e.right!="undefined"?e.right:a.right,a.bottom=typeof
e.bottom!="undefined"?e.bottom:a.bottom,a.left=typeof
e.left!="undefined"?e.left:a.left,P):a},P.width=function(e){return
arguments.length?(f=e,P):f},P.height=function(e){return
arguments.length?(l=e,P):l},P.color=function(t){return
arguments.length?(c=e.utils.getColor(t),i.color(c),o.color(c),u.
color(c),P):c},P.showDistX=function(e){return
arguments.length?(m=e,P):m},P.showDistY=function(e){return
arguments.length?(g=e,P):g},P.showControls=function(e){return
arguments.length?(b=e,P):b},P.showLegend=function(e){return
arguments.length?(y=e,P):y},P.fisheye=function(e){return
arguments.length?(w=e,P):w},P.xPadding=function(e){return
arguments.length?(d=e,P):d},P.yPadding=function(e){return
arguments.length?(v=e,P):v},P.tooltips=function(e){return
arguments.length?(S=e,P):S},P.tooltipContent=function(e){return
arguments.length?(N=e,P):N},P.tooltipXContent=function(e){return
arguments.length?(x=e,P):x},P.tooltipYContent=function(e){return
arguments.length?(T=e,P):T},P.state=function(e){return
arguments.length?(C=e,P):C},P.defaultState=function(e){return
arguments.length?(k=e,P):k},P.noData=function(e){return
arguments.length?(A=e,P):A},P},e.models.scatterPlusLineChart=function(){function
_(e){return e.each(function(e){function U(){if(b)return
I.select(".nv-point-paths")
.style("pointer-events","all"),!1;I.select(".nv-point-paths").style("pointer-events","none");var
i=d3.mouse(this);h.distortion(y).focus(i[0]),p.distortion(y).focus(i[1]),I.select(".nv-scatterWrap").datum(e.filter(function(e){return!e.disabled})).call(t),I.select(".nv-x.nv-axis").call(n),I.select(".nv-y.nv-axis").call(r),I.select(".nv-distributionX").datum(e.filter(function(e){return!e.disabled})).call(o),I.select(".nv-distributionY").datum(e.filter(function(e){return!e.disabled})).call(u)}var
E=d3.select(this),S=this,x=(f||parseInt(E.style("width"))||960)-a.left-a.right,D=(l||parseInt(E.style("height"))||400)-a.top-a.bottom;_.update=function(){E.transition().call(_)},_.container=this,T.disabled=e.map(function(e){return!!e.disabled});if(!N){var
P;N={};for(P in T)T[P]instanceof
Array?N[P]=T[P].slice(0):N[P]=T[P]}if(!e||!e.length||!e.filter(function(e){return
e.values.length}).length){var H=E.selectAll(".nv-noData").data([k]);return
H.enter().append("text").attr("class","nvd3 n
v-noData").attr("dy","-.7em").style("text-anchor","middle"),H.attr("x",a.left+x/2).attr("y",a.top+D/2).text(function(e){return
e}),_}E.selectAll(".nv-noData").remove(),h=t.xScale(),p=t.yScale(),L=L||h,A=A||p;var
B=E.selectAll("g.nv-wrap.nv-scatterChart").data([e]),j=B.enter().append("g").attr("class","nvd3
nv-wrap nv-scatterChart
nv-chart-"+t.id()),F=j.append("g"),I=B.select("g");F.append("rect").attr("class","nvd3
nv-background"),F.append("g").attr("class","nv-x
nv-axis"),F.append("g").attr("class","nv-y
nv-axis"),F.append("g").attr("class","nv-scatterWrap"),F.append("g").attr("class","nv-regressionLinesWrap"),F.append("g").attr("class","nv-distWrap"),F.append("g").attr("class","nv-legendWrap"),F.append("g").attr("class","nv-controlsWrap"),B.attr("transform","translate("+a.left+","+a.top+")"),m&&(i.width(x/2),B.select(".nv-legendWrap").datum(e).call(i),a.top!=i.height()&&(a.top=i.height(),D=(l||parseInt(E.style("height"))||400)-a.top-a.bottom),B.select(".nv-legendWrap").att
r("transform","translate("+x/2+","+
-a.top+")")),g&&(s.width(180).color(["#444"]),I.select(".nv-controlsWrap").datum(M).attr("transform","translate(0,"+
-a.top+")").call(s)),t.width(x).height(D).color(e.map(function(e,t){return
e.color||c(e,t)}).filter(function(t,n){return!e[n].disabled})),B.select(".nv-scatterWrap").datum(e.filter(function(e){return!e.disabled})).call(t),B.select(".nv-regressionLinesWrap").attr("clip-path","url(#nv-edge-clip-"+t.id()+")");var
q=B.select(".nv-regressionLinesWrap").selectAll(".nv-regLines").data(function(e){return
e}),R=q.enter().append("g").attr("class","nv-regLines").append("line").attr("class","nv-regLine").style("stroke-opacity",0);q.selectAll(".nv-regLines
line").attr("x1",h.range()[0]).attr("x2",h.range()[1]).attr("y1",function(e,t){return
p(h.domain()[0]*e.slope+e.intercept)}).attr("y2",function(e,t){return
p(h.domain()[1]*e.slope+e.intercept)}).style("stroke",function(e,t,n){return
c(e,n)}).style("stroke-opacity",function(e,t){return
e.disabled||typeof e.slope=="undefined"||typeof
e.intercept=="undefined"?0:1}),n.scale(h).ticks(n.ticks()?n.ticks():x/100).tickSize(-D,0),I.select(".nv-x.nv-axis").attr("transform","translate(0,"+p.range()[0]+")").call(n),r.scale(p).ticks(r.ticks()?r.ticks():D/36).tickSize(-x,0),I.select(".nv-y.nv-axis").call(r),d&&(o.getData(t.x()).scale(h).width(x).color(e.map(function(e,t){return
e.color||c(e,t)}).filter(function(t,n){return!e[n].disabled})),F.select(".nv-distWrap").append("g").attr("class","nv-distributionX"),I.select(".nv-distributionX").attr("transform","translate(0,"+p.range()[0]+")").datum(e.filter(function(e){return!e.disabled})).call(o)),v&&(u.getData(t.y()).scale(p).width(D).color(e.map(function(e,t){return
e.color||c(e,t)}).filter(function(t,n){return!e[n].disabled})),F.select(".nv-distWrap").append("g").attr("class","nv-distributionY"),I.select(".nv-distributionY").attr("transform","translate(-"+u.size()+",0)").datum(e.filter(function(e){return!e.disabled})).cal
l(u)),d3.fisheye&&(I.select(".nv-background").attr("width",x).attr("height",D),I.select(".nv-background").on("mousemove",U),I.select(".nv-background").on("click",function(){b=!b}),t.dispatch.on("elementClick.freezeFisheye",function(){b=!b})),s.dispatch.on("legendClick",function(e,i){e.disabled=!e.disabled,y=e.disabled?0:2.5,I.select(".nv-background").style("pointer-events",e.disabled?"none":"all"),I.select(".nv-point-paths").style("pointer-events",e.disabled?"all":"none"),e.disabled?(h.distortion(y).focus(0),p.distortion(y).focus(0),I.select(".nv-scatterWrap").call(t),I.select(".nv-x.nv-axis").call(n),I.select(".nv-y.nv-axis").call(r)):b=!1,_.update()}),i.dispatch.on("legendClick",function(t,n,r){t.disabled=!t.disabled,e.filter(function(e){return!e.disabled}).length||e.map(function(e){return
e.disabled=!1,B.selectAll(".nv-series").classed("disabled",!1),e}),T.disabled=e.map(function(e){return!!e.disabled}),C.stateChange(T),_.update()}),i.dispatch.on("legendDblclick",function
(t){e.forEach(function(e){e.disabled=!0}),t.disabled=!1,T.disabled=e.map(function(e){return!!e.disabled}),C.stateChange(T),_.update()}),t.dispatch.on("elementMouseover.tooltip",function(e){d3.select(".nv-chart-"+t.id()+"
.nv-series-"+e.seriesIndex+"
.nv-distx-"+e.pointIndex).attr("y1",e.pos[1]-D),d3.select(".nv-chart-"+t.id()+"
.nv-series-"+e.seriesIndex+"
.nv-disty-"+e.pointIndex).attr("x2",e.pos[0]+o.size()),e.pos=[e.pos[0]+a.left,e.pos[1]+a.top],C.tooltipShow(e)}),C.on("tooltipShow",function(e){w&&O(e,S.parentNode)}),C.on("changeState",function(t){typeof
t.disabled!="undefined"&&(e.forEach(function(e,n){e.disabled=t.disabled[n]}),T.disabled=t.disabled),_.update()}),L=h.copy(),A=p.copy()}),_}var
t=e.models.scatter(),n=e.models.axis(),r=e.models.axis(),i=e.models.legend(),s=e.models.legend(),o=e.models.distribution(),u=e.models.distribution(),a={top:30,right:20,bottom:50,left:75},f=null,l=null,c=e.utils.defaultColor(),h=d3.fisheye?d3.fisheye.scale(d3.scale.linear).distortio
n(0):t.xScale(),p=d3.fisheye?d3.fisheye.scale(d3.scale.linear).distortion(0):t.yScale(),d=!1,v=!1,m=!0,g=!!d3.fisheye,y=0,b=!1,w=!0,E=function(e,t,n){return"<strong>"+t+"</strong>"},S=function(e,t,n){return"<strong>"+n+"</strong>"},x=function(e,t,n,r){return"<h3>"+e+"</h3>"+"<p>"+r+"</p>"},T={},N=null,C=d3.dispatch("tooltipShow","tooltipHide","stateChange","changeState"),k="No
Data
Available.";t.xScale(h).yScale(p),n.orient("bottom").tickPadding(10),r.orient("left").tickPadding(10),o.axis("x"),u.axis("y");var
L,A,O=function(i,s){var
o=i.pos[0]+(s.offsetLeft||0),u=i.pos[1]+(s.offsetTop||0),f=i.pos[0]+(s.offsetLeft||0),l=p.range()[0]+a.top+(s.offsetTop||0),c=h.range()[0]+a.left+(s.offsetLeft||0),d=i.pos[1]+(s.offsetTop||0),v=n.tickFormat()(t.x()(i.point,i.pointIndex)),m=r.tickFormat()(t.y()(i.point,i.pointIndex));E!=null&&e.tooltip.show([f,l],E(i.series.key,v,m,i,_),"n",1,s,"x-nvtooltip"),S!=null&&e.tooltip.show([c,d],S(i.series.key,v,m,i,_),"e",1,s,"y-nvtooltip"),x!=null&&e.t
ooltip.show([o,u],x(i.series.key,v,m,i.point.tooltip,i,_),i.value<0?"n":"s",null,s)},M=[{key:"Magnify",disabled:!0}];return
t.dispatch.on("elementMouseout.tooltip",function(e){C.tooltipHide(e),d3.select(".nv-chart-"+t.id()+"
.nv-series-"+e.seriesIndex+"
.nv-distx-"+e.pointIndex).attr("y1",0),d3.select(".nv-chart-"+t.id()+"
.nv-series-"+e.seriesIndex+"
.nv-disty-"+e.pointIndex).attr("x2",u.size())}),C.on("tooltipHide",function(){w&&e.tooltip.cleanup()}),_.dispatch=C,_.scatter=t,_.legend=i,_.controls=s,_.xAxis=n,_.yAxis=r,_.distX=o,_.distY=u,d3.rebind(_,t,"id","interactive","pointActive","x","y","shape","size","xScale","yScale","zScale","xDomain","yDomain","sizeDomain","sizeRange","forceX","forceY","forceSize","clipVoronoi","clipRadius","useVoronoi"),_.margin=function(e){return
arguments.length?(a.top=typeof e.top!="undefined"?e.top:a.top,a.right=typeof
e.right!="undefined"?e.right:a.right,a.bottom=typeof
e.bottom!="undefined"?e.bottom:a.bottom,a.left=typeof e.left!="undefined
"?e.left:a.left,_):a},_.width=function(e){return
arguments.length?(f=e,_):f},_.height=function(e){return
arguments.length?(l=e,_):l},_.color=function(t){return
arguments.length?(c=e.utils.getColor(t),i.color(c),o.color(c),u.color(c),_):c},_.showDistX=function(e){return
arguments.length?(d=e,_):d},_.showDistY=function(e){return
arguments.length?(v=e,_):v},_.showControls=function(e){return
arguments.length?(g=e,_):g},_.showLegend=function(e){return
arguments.length?(m=e,_):m},_.fisheye=function(e){return
arguments.length?(y=e,_):y},_.tooltips=function(e){return
arguments.length?(w=e,_):w},_.tooltipContent=function(e){return
arguments.length?(x=e,_):x},_.tooltipXContent=function(e){return
arguments.length?(E=e,_):E},_.tooltipYContent=function(e){return
arguments.length?(S=e,_):S},_.state=function(e){return
arguments.length?(T=e,_):T},_.defaultState=function(e){return
arguments.length?(N=e,_):N},_.noData=function(e){return
arguments.length?(k=e,_):k},_},e.models.sparkline=functi
on(){function h(e){return e.each(function(e){var
i=n-t.left-t.right,h=r-t.top-t.bottom,p=d3.select(this);s.domain(l||d3.extent(e,u)).range([0,i]),o.domain(c||d3.extent(e,a)).range([h,0]);var
d=p.selectAll("g.nv-wrap.nv-sparkline").data([e]),v=d.enter().append("g").attr("class","nvd3
nv-wrap
nv-sparkline"),m=v.append("g"),g=d.select("g");d.attr("transform","translate("+t.left+","+t.top+")");var
b=d.selectAll("path").data(function(e){return[e]});b.enter().append("path"),b.exit().remove(),b.style("stroke",function(e,t){return
e.color||f(e,t)}).attr("d",d3.svg.line().x(function(e,t){return
s(u(e,t))}).y(function(e,t){return o(a(e,t))}));var
w=d.selectAll("circle.nv-point").data(function(e){function n(t){if(t!=-1){var
n=e[t];return n.pointIndex=t,n}return null}var t=e.map(function(e,t){return
a(e,t)}),r=n(t.lastIndexOf(o.domain()[1])),i=n(t.indexOf(o.domain()[0])),s=n(t.length-1);return[i,r,s].filter(function(e){return
e!=null})});w.enter().append("circle"),w.exit().remove(),w.at
tr("cx",function(e,t){return
s(u(e,e.pointIndex))}).attr("cy",function(e,t){return
o(a(e,e.pointIndex))}).attr("r",2).attr("class",function(e,t){return
u(e,e.pointIndex)==s.domain()[1]?"nv-point
nv-currentValue":a(e,e.pointIndex)==o.domain()[0]?"nv-point
nv-minValue":"nv-point nv-maxValue"})}),h}var
t={top:2,right:0,bottom:2,left:0},n=400,r=32,i=!0,s=d3.scale.linear(),o=d3.scale.linear(),u=function(e){return
e.x},a=function(e){return e.y},f=e.utils.getColor(["#000"]),l,c;return
h.margin=function(e){return arguments.length?(t.top=typeof
e.top!="undefined"?e.top:t.top,t.right=typeof
e.right!="undefined"?e.right:t.right,t.bottom=typeof
e.bottom!="undefined"?e.bottom:t.bottom,t.left=typeof
e.left!="undefined"?e.left:t.left,h):t},h.width=function(e){return
arguments.length?(n=e,h):n},h.height=function(e){return
arguments.length?(r=e,h):r},h.x=function(e){return
arguments.length?(u=d3.functor(e),h):u},h.y=function(e){return
arguments.length?(a=d3.functor(e),h):a},h.xScale=function
(e){return arguments.length?(s=e,h):s},h.yScale=function(e){return
arguments.length?(o=e,h):o},h.xDomain=function(e){return
arguments.length?(l=e,h):l},h.yDomain=function(e){return
arguments.length?(c=e,h):c},h.animate=function(e){return
arguments.length?(i=e,h):i},h.color=function(t){return
arguments.length?(f=e.utils.getColor(t),h):f},h},e.models.sparklinePlus=function(){function
v(e){return e.each(function(c){function O(){if(a)return;var
e=C.selectAll(".nv-hoverValue").data(u),r=e.enter().append("g").attr("class","nv-hoverValue").style("stroke-opacity",0).style("fill-opacity",0);e.exit().transition().duration(250).style("stroke-opacity",0).style("fill-opacity",0).remove(),e.attr("transform",function(e){return"translate("+s(t.x()(c[e],e))+",0)"}).transition().duration(250).style("stroke-opacity",1).style("fill-opacity",1);if(!u.length)return;r.append("line").attr("x1",0).attr("y1",-n.top).attr("x2",0).attr("y2",b),r.append("text").attr("class","nv-xValue").attr("x",-6).att
r("y",-n.top).attr("text-anchor","end").attr("dy",".9em"),C.select(".nv-hoverValue
.nv-xValue").text(f(t.x()(c[u[0]],u[0]))),r.append("text").attr("class","nv-yValue").attr("x",6).attr("y",-n.top).attr("text-anchor","start").attr("dy",".9em"),C.select(".nv-hoverValue
.nv-yValue").text(l(t.y()(c[u[0]],u[0])))}function M(){function r(e,n){var
r=Math.abs(t.x()(e[0],0)-n),i=0;for(var
s=0;s<e.length;s++)Math.abs(t.x()(e[s],s)-n)<r&&(r=Math.abs(t.x()(e[s],s)-n),i=s);return
i}if(a)return;var e=d3.mouse(this)[0]-n.left;u=[r(c,Math.round(s.invert(e)))],O()}var
m=d3.select(this),g=(r||parseInt(m.style("width"))||960)-n.left-n.right,b=(i||parseInt(m.style("height"))||400)-n.top-n.bottom;v.update=function(){v(e)},v.container=this;if(!c||!c.length){var
w=m.selectAll(".nv-noData").data([d]);return
w.enter().append("text").attr("class","nvd3
nv-noData").attr("dy","-.7em").style("text-anchor","middle"),w.attr("x",n.left+g/2).attr("y",n.top+b/2).text(function(e){return
e}),v}m.selectAll(".nv
-noData").remove();var
E=t.y()(c[c.length-1],c.length-1);s=t.xScale(),o=t.yScale();var
S=m.selectAll("g.nv-wrap.nv-sparklineplus").data([c]),T=S.enter().append("g").attr("class","nvd3
nv-wrap
nv-sparklineplus"),N=T.append("g"),C=S.select("g");N.append("g").attr("class","nv-sparklineWrap"),N.append("g").attr("class","nv-valueWrap"),N.append("g").attr("class","nv-hoverArea"),S.attr("transform","translate("+n.left+","+n.top+")");var
k=C.select(".nv-sparklineWrap");t.width(g).height(b),k.call(t);var
L=C.select(".nv-valueWrap"),A=L.selectAll(".nv-currentValue").data([E]);A.enter().append("text").attr("class","nv-currentValue").attr("dx",p?-8:8).attr("dy",".9em").style("text-anchor",p?"end":"start"),A.attr("x",g+(p?n.right:0)).attr("y",h?function(e){return
o(e)}:0).style("fill",t.color()(c[c.length-1],c.length-1)).text(l(E)),N.select(".nv-hoverArea").append("rect").on("mousemove",M).on("click",function(){a=!a}).on("mouseout",function(){u=[],O()}),C.select(".nv-hoverArea
rect").att
r("transform",function(e){return"translate("+ -n.left+","+
-n.top+")"}).attr("width",g+n.left+n.right).attr("height",b+n.top)}),v}var
t=e.models.sparkline(),n={top:15,right:100,bottom:10,left:50},r=null,i=null,s,o,u=[],a=!1,f=d3.format(",r"),l=d3.format(",.2f"),c=!0,h=!0,p=!1,d="No
Data Available.";return
v.sparkline=t,d3.rebind(v,t,"x","y","xScale","yScale","color"),v.margin=function(e){return
arguments.length?(n.top=typeof e.top!="undefined"?e.top:n.top,n.right=typeof
e.right!="undefined"?e.right:n.right,n.bottom=typeof
e.bottom!="undefined"?e.bottom:n.bottom,n.left=typeof
e.left!="undefined"?e.left:n.left,v):n},v.width=function(e){return
arguments.length?(r=e,v):r},v.height=function(e){return
arguments.length?(i=e,v):i},v.xTickFormat=function(e){return
arguments.length?(f=e,v):f},v.yTickFormat=function(e){return
arguments.length?(l=e,v):l},v.showValue=function(e){return
arguments.length?(c=e,v):c},v.alignValue=function(e){return
arguments.length?(h=e,v):h},v.rightAlignVal
ue=function(e){return arguments.length?(p=e,v):p},v.noData=function(e){return
arguments.length?(d=e,v):d},v},e.models.stackedArea=function(){function g(e){return
e.each(function(e){var
a=n-t.left-t.right,g=r-t.top-t.bottom,b=d3.select(this);p=v.xScale(),d=v.yScale(),e=e.map(function(e,t){return
e.values=e.values.map(function(t,n){return
t.index=n,t.stackedY=e.disabled?0:u(t,n),t}),e}),e=d3.layout.stack().order(l).offset(f).values(function(e){return
e.values}).x(o).y(function(e){return
e.stackedY}).out(function(e,t,n){e.display={y:n,y0:t}})(e);var
w=b.selectAll("g.nv-wrap.nv-stackedarea").data([e]),E=w.enter().append("g").attr("class","nvd3
nv-wrap
nv-stackedarea"),S=E.append("defs"),T=E.append("g"),N=w.select("g");T.append("g").attr("class","nv-areaWrap"),T.append("g").attr("class","nv-scatterWrap"),w.attr("transform","translate("+t.left+","+t.top+")"),v.width(a).height(g).x(o).y(function(e){return
e.display.y+e.display.y0}).forceY([0]).color(e.map(function(e,t){return e.col
or||i(e,t)}).filter(function(t,n){return!e[n].disabled}));var
C=N.select(".nv-scatterWrap").datum(e.filter(function(e){return!e.disabled}));C.call(v),S.append("clipPath").attr("id","nv-edge-clip-"+s).append("rect"),w.select("#nv-edge-clip-"+s+"
rect").attr("width",a).attr("height",g),N.attr("clip-path",h?"url(#nv-edge-clip-"+s+")":"");var
k=d3.svg.area().x(function(e,t){return p(o(e,t))}).y0(function(e){return
d(e.display.y0)}).y1(function(e){return
d(e.display.y+e.display.y0)}).interpolate(c),L=d3.svg.area().x(function(e,t){return
p(o(e,t))}).y0(function(e){return d(e.display.y0)}).y1(function(e){return
d(e.display.y0)}),A=N.select(".nv-areaWrap").selectAll("path.nv-area").data(function(e){return
e});A.enter().append("path").attr("class",function(e,t){return"nv-area
nv-area-"+t}).on("mouseover",function(e,t){d3.select(this).classed("hover",!0),m.areaMouseover({point:e,series:e.key,pos:[d3.event.pageX,d3.event.pageY],seriesIndex:t})}).on("mouseout",function(e,t){d3.select(th
is).classed("hover",!1),m.areaMouseout({point:e,series:e.key,pos:[d3.event.pageX,d3.event.pageY],seriesIndex:t})}).on("click",function(e,t){d3.select(this).classed("hover",!1),m.areaClick({point:e,series:e.key,pos:[d3.event.pageX,d3.event.pageY],seriesIndex:t})}),A.exit().attr("d",function(e,t){return
L(e.values,t)}).remove(),A.style("fill",function(e,t){return
e.color||i(e,t)}).style("stroke",function(e,t){return
e.color||i(e,t)}),A.attr("d",function(e,t){return
k(e.values,t)}),v.dispatch.on("elementMouseover.area",function(e){N.select(".nv-chart-"+s+"
.nv-area-"+e.seriesIndex).classed("hover",!0)}),v.dispatch.on("elementMouseout.area",function(e){N.select(".nv-chart-"+s+"
.nv-area-"+e.seriesIndex).classed("hover",!1)})}),g}var
t={top:0,right:0,bottom:0,left:0},n=960,r=500,i=e.utils.defaultColor(),s=Math.floor(Math.random()*1e5),o=function(e){return
e.x},u=function(e){return
e.y},a="stack",f="zero",l="default",c="linear",h=!1,p,d,v=e.models.scatter(),m=d3.dispatch("tooltipS
how","tooltipHide","areaClick","areaMouseover","areaMouseout");return
v.size(2.2).sizeDomain([2.2,2.2]),v.dispatch.on("elementClick.area"
-,function(e){m.areaClick(e)}),v.dispatch.on("elementMouseover.tooltip",function(e){e.pos=[e.pos[0]+t.left,e.pos[1]+t.top],m.tooltipShow(e)}),v.dispatch.on("elementMouseout.tooltip",function(e){m.tooltipHide(e)}),g.dispatch=m,g.scatter=v,d3.rebind(g,v,"interactive","size","xScale","yScale","zScale","xDomain","yDomain","sizeDomain","forceX","forceY","forceSize","clipVoronoi","clipRadius"),g.x=function(e){return
arguments.length?(o=d3.functor(e),g):o},g.y=function(e){return
arguments.length?(u=d3.functor(e),g):u},g.margin=function(e){return
arguments.length?(t.top=typeof e.top!="undefined"?e.top:t.top,t.right=typeof
e.right!="undefined"?e.right:t.right,t.bottom=typeof
e.bottom!="undefined"?e.bottom:t.bottom,t.left=typeof
e.left!="undefined"?e.left:t.left,g):t},g.width=function(e){return
arguments.length?(n=e,g):n},g.height=function(e){return
arguments.length?(r=e,g):r},g.clipEdge=function(e){return
arguments.length?(h=e,g):h},g.color=function(t){return arguments.length?(i=e.uti
ls.getColor(t),g):i},g.offset=function(e){return
arguments.length?(f=e,g):f},g.order=function(e){return
arguments.length?(l=e,g):l},g.style=function(e){if(!arguments.length)return
a;a=e;switch(a){case"stack":g.offset("zero"),g.order("default");break;case"stream":g.offset("wiggle"),g.order("inside-out");break;case"stream-center":g.offset("silhouette"),g.order("inside-out");break;case"expand":g.offset("expand"),g.order("default")}return
g},g.interpolate=function(e){return
arguments.length?(c=e,c):c},g},e.models.stackedAreaChart=function(){function x(e){return
e.each(function(e){var
f=d3.select(this),p=this,T=(u||parseInt(f.style("width"))||960)-o.left-o.right,N=(a||parseInt(f.style("height"))||400)-o.top-o.bottom;x.update=function(){f.transition().call(x)},x.container=this,g.disabled=e.map(function(e){return!!e.disabled});if(!y){var
C;y={};for(C in g)g[C]instanceof
Array?y[C]=g[C].slice(0):y[C]=g[C]}if(!e||!e.length||!e.filter(function(e){return
e.values.length}).length){var k
=f.selectAll(".nv-noData").data([b]);return
k.enter().append("text").attr("class","nvd3
nv-noData").attr("dy","-.7em").style("text-anchor","middle"),k.attr("x",o.left+T/2).attr("y",o.top+N/2).text(function(e){return
e}),x}f.selectAll(".nv-noData").remove(),d=t.xScale(),v=t.yScale();var
L=f.selectAll("g.nv-wrap.nv-stackedAreaChart").data([e]),A=L.enter().append("g").attr("class","nvd3
nv-wrap
nv-stackedAreaChart").append("g"),O=L.select("g");A.append("g").attr("class","nv-x
nv-axis"),A.append("g").attr("class","nv-y
nv-axis"),A.append("g").attr("class","nv-stackedWrap"),A.append("g").attr("class","nv-legendWrap"),A.append("g").attr("class","nv-controlsWrap"),c&&(i.width(T-E),O.select(".nv-legendWrap").datum(e).call(i),o.top!=i.height()&&(o.top=i.height(),N=(a||parseInt(f.style("height"))||400)-o.top-o.bottom),O.select(".nv-legendWrap").attr("transform","translate("+E+","+
-o.top+")"));if(l){var
M=[{key:"Stacked",disabled:t.offset()!="zero"},{key:"Stream",disabled:t.offset()!=
"wiggle"},{key:"Expanded",disabled:t.offset()!="expand"}];s.width(E).color(["#444","#444","#444"]),O.select(".nv-controlsWrap").datum(M).call(s),o.top!=Math.max(s.height(),i.height())&&(o.top=Math.max(s.height(),i.height()),N=(a||parseInt(f.style("height"))||400)-o.top-o.bottom),O.select(".nv-controlsWrap").attr("transform","translate(0,"+
-o.top+")")}L.attr("transform","translate("+o.left+","+o.top+")"),t.width(T).height(N);var
_=O.select(".nv-stackedWrap").datum(e);_.call(t),n.scale(d).ticks(T/100).tickSize(-N,0),O.select(".nv-x.nv-axis").attr("transform","translate(0,"+N+")"),O.select(".nv-x.nv-axis").transition().duration(0).call(n),r.scale(v).ticks(t.offset()=="wiggle"?0:N/36).tickSize(-T,0).setTickFormat(t.offset()=="expand"?d3.format("%"):m),O.select(".nv-y.nv-axis").transition().duration(0).call(r),t.dispatch.on("areaClick.toggle",function(t){e.filter(function(e){return!e.disabled}).length===1?e=e.map(function(e){return
e.disabled=!1,e}):e=e.map(function(e,n){return
e.disabled=n!=t.seriesIndex,e}),g.disabled=e.map(function(e){return!!e.disabled}),w.stateChange(g),x.update()}),i.dispatch.on("legendClick",function(t,n){t.disabled=!t.disabled,e.filter(function(e){return!e.disabled}).length||e.map(function(e){return
e.disabled=!1,e}),g.disabled=e.map(function(e){return!!e.disabled}),w.stateChange(g),x.update()}),i.dispatch.on("legendDblclick",function(t){e.forEach(function(e){e.disabled=!0}),t.disabled=!1,g.disabled=e.map(function(e){return!!e.disabled}),w.stateChange(g),x.update()}),s.dispatch.on("legendClick",function(e,n){if(!e.disabled)return;M=M.map(function(e){return
e.disabled=!0,e}),e.disabled=!1;switch(e.key){case"Stacked":t.style("stack");break;case"Stream":t.style("stream");break;case"Expanded":t.style("expand")}g.style=t.style(),w.stateChange(g),x.update()}),w.on("tooltipShow",function(e){h&&S(e,p.parentNode)}),w.on("changeState",function(n){typeof
n.disabled!="undefined"&&(e.forEach(function(e,t){e.disabled=n.disabled[t]}),g.di
sabled=n.disabled),typeof
n.style!="undefined"&&t.style(n.style),x.update()})}),x}var
t=e.models.stackedArea(),n=e.models.axis(),r=e.models.axis(),i=e.models.legend(),s=e.models.legend(),o={top:30,right:25,bottom:50,left:60},u=null,a=null,f=e.utils.defaultColor(),l=!0,c=!0,h=!0,p=function(e,t,n,r,i){return"<h3>"+e+"</h3>"+"<p>"+n+"
on
"+t+"</p>"},d,v,m=d3.format(",.2f"),g={style:t.style()},y=null,b="No
Data
Available.",w=d3.dispatch("tooltipShow","tooltipHide","stateChange","changeState"),E=250;n.orient("bottom").tickPadding(7),r.orient("left"),t.scatter.pointActive(function(e){return!!Math.round(t.y()(e)*100)});var
S=function(i,s){var
o=i.pos[0]+(s.offsetLeft||0),u=i.pos[1]+(s.offsetTop||0),a=n.tickFormat()(t.x()(i.point,i.pointIndex)),f=r.tickFormat()(t.y()(i.point,i.pointIndex)),l=p(i.series.key,a,f,i,x);e.tooltip.show([o,u],l,i.value<0?"n":"s",null,s)};return
t.dispatch.on("tooltipShow",function(e){e.pos=[e.pos[0]+o.left,e.pos[1]+o.top],w.tooltipShow(e)}),t.dispatch.on("
tooltipHide",function(e){w.tooltipHide(e)}),w.on("tooltipHide",function(){h&&e.tooltip.cleanup()}),x.dispatch=w,x.stacked=t,x.legend=i,x.controls=s,x.xAxis=n,x.yAxis=r,d3.rebind(x,t,"x","y","size","xScale","yScale","xDomain","yDomain","sizeDomain","interactive","offset","order","style","clipEdge","forceX","forceY","forceSize","interpolate"),x.margin=function(e){return
arguments.length?(o.top=typeof e.top!="undefined"?e.top:o.top,o.right=typeof
e.right!="undefined"?e.right:o.right,o.bottom=typeof
e.bottom!="undefined"?e.bottom:o.bottom,o.left=typeof
e.left!="undefined"?e.left:o.left,x):o},x.width=function(e){return
arguments.length?(u=e,x):getWidth},x.height=function(e){return
arguments.length?(a=e,x):getHeight},x.color=function(n){return
arguments.length?(f=e.utils.getColor(n),i.color(f),t.color(f),x):f},x.showControls=function(e){return
arguments.length?(l=e,x):l},x.showLegend=function(e){return
arguments.length?(c=e,x):c},x.tooltip=function(e){return arguments.length?(p=e,
x):p},x.tooltips=function(e){return
arguments.length?(h=e,x):h},x.tooltipContent=function(e){return
arguments.length?(p=e,x):p},x.state=function(e){return
arguments.length?(g=e,x):g},x.defaultState=function(e){return
arguments.length?(y=e,x):y},x.noData=function(e){return
arguments.length?(b=e,x):b},r.setTickFormat=r.tickFormat,r.tickFormat=function(e){return
arguments.length?(m=e,r):m},x}})();
\ No newline at end of file
commit 2232cce0891d9181de672532aae3f0456c0fc0a4
Author: Mike Thompson <mithomps(a)redhat.com>
Date: Tue Jul 9 12:36:39 2013 -0700
On multi-resource chart add sort to legend to show alphabetically.
diff --git
a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/detail/monitoring/table/CompositeGroupD3MultiLineGraph.java
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/detail/monitoring/table/CompositeGroupD3MultiLineGraph.java
index a62cb5c..b89cc71 100644
---
a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/detail/monitoring/table/CompositeGroupD3MultiLineGraph.java
+++
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/detail/monitoring/table/CompositeGroupD3MultiLineGraph.java
@@ -40,7 +40,9 @@ public class CompositeGroupD3MultiLineGraph extends
CompositeGroupD3GraphListVie
}
this.chartId = chartId;
this.chartHeight = chartHeight;
- this.data = $wnd.jQuery.parseJSON(metricsData); // make into json
+ if(typeof metricsData !== 'undefined' && metricsData.length
> 0){
+ this.data = $wnd.jQuery.parseJSON(metricsData);
+ }
this.xAxisLabel = xAxisLabel;
this.chartTitle = chartTitle;
this.yAxisUnits = yAxisUnits;
@@ -57,14 +59,13 @@ public class CompositeGroupD3MultiLineGraph extends
CompositeGroupD3GraphListVie
this.chartXaxisTimeFormatHours = chartXaxisTimeFormatHours;
this.chartXaxisTimeFormatHoursMinutes = chartXaxisTimeFormatHoursMinutes;
- };
-
- var global = this,
+ },
+ global = this;
// create a chartContext object (from rhq.js) with the data required to render to
a chart
// this same data could be passed to different chart types
// This way, we are decoupled from the dependency on globals and JSNI and kept
all the java interaction right here.
- chartContext = new
MultiLineChartContext(global.@org.rhq.enterprise.gui.coregui.client.inventory.groups.detail.monitoring.table.CompositeGroupD3GraphListView::getChartId()(),
+ chartContext = new
MultiLineChartContext(global.@org.rhq.enterprise.gui.coregui.client.inventory.groups.detail.monitoring.table.CompositeGroupD3GraphListView::getChartId()(),
global.@org.rhq.enterprise.gui.coregui.client.inventory.groups.detail.monitoring.table.CompositeGroupD3GraphListView::getChartHeight()(),
global.@org.rhq.enterprise.gui.coregui.client.inventory.groups.detail.monitoring.table.CompositeGroupD3GraphListView::getJsonMetrics()(),
global.@org.rhq.enterprise.gui.coregui.client.inventory.groups.detail.monitoring.table.CompositeGroupD3GraphListView::getXAxisTitle()(),
@@ -102,14 +103,13 @@ public class CompositeGroupD3MultiLineGraph extends
CompositeGroupD3GraphListVie
function determineScale() {
- var xTicks, xTickSubDivide, minY, maxY;
+ var xTicks, xTickSubDivide;
console.log("DetermineScale for # resources: "+
chartContext.data.length);
if (chartContext.data.length > 0) {
xTicks = 8;
xTickSubDivide = 5;
var myExtent = getExtentFromNestedValues(chartContext.data);
- console.info("minY, maxY: "+myExtent[0] + ",
"+myExtent[1] );
yScale = $wnd.d3.scale.linear()
.clamp(true)
@@ -210,13 +210,14 @@ public class CompositeGroupD3MultiLineGraph extends
CompositeGroupD3GraphListVie
// add legend
var legend = svg.append("g")
.attr("class", "legend")
- .attr("x", width + 30)
+ .attr("x", width + 100)
.attr("y", 70)
.attr("height", 240)
.attr("width", 150);
legend.selectAll('g').data(chartContext.data)
.enter()
+
.append('g')
.each(function (d, i) {
var g = $wnd.d3.select(this);
@@ -277,6 +278,8 @@ public class CompositeGroupD3MultiLineGraph extends
CompositeGroupD3GraphListVie
return yScale(d.y);
});
+ chartContext.data.sort(function(a,b){return ((a.key < b.key) ? -1 :
((a.key > b.key) ? 1 : 0));});
+
svg.selectAll(".multiLine")
.data(chartContext.data)
.enter()
commit 90e16ae8d70c3c44d3e2b34cfd98c74bf832f692
Author: Mike Thompson <mithomps(a)redhat.com>
Date: Tue Jul 9 12:36:25 2013 -0700
Keep Global exception from occuring in multi resource graph when metrics return empty
data.
diff --git
a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/detail/monitoring/table/CompositeGroupD3GraphListView.java
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/detail/monitoring/table/CompositeGroupD3GraphListView.java
index 3ac3758..a5a0c9d 100644
---
a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/detail/monitoring/table/CompositeGroupD3GraphListView.java
+++
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/detail/monitoring/table/CompositeGroupD3GraphListView.java
@@ -363,17 +363,20 @@ public abstract class CompositeGroupD3GraphListView extends
EnhancedVLayout impl
@Override
public String getJsonMetrics() {
- StringBuilder sb = new StringBuilder("[");
- for (MultiLineGraphData multiLineGraphData : measurementForEachResource) {
- sb.append("{ \"key\": \"");
- sb.append(multiLineGraphData.getResourceName());
- sb.append("\",\"value\" : ");
- sb.append(produceInnerValuesArray(multiLineGraphData.getMeasurementData()));
- sb.append("},");
+ StringBuilder sb = new StringBuilder();
+ if (null != measurementForEachResource &&
!measurementForEachResource.isEmpty()) {
+ sb = new StringBuilder("[");
+ for (MultiLineGraphData multiLineGraphData : measurementForEachResource) {
+ sb.append("{ \"key\": \"");
+ sb.append(multiLineGraphData.getResourceName());
+ sb.append("\",\"value\" : ");
+
sb.append(produceInnerValuesArray(multiLineGraphData.getMeasurementData()));
+ sb.append("},");
+ }
+ sb.setLength(sb.length() - 1); // delete the last ','
+ sb.append("]");
}
- sb.setLength(sb.length() - 1); // delete the last ','
- sb.append("]");
- Log.debug("Multi-resource Graph json: "+ sb.toString());
+ Log.debug("Multi-resource Graph json: " + sb.toString());
return sb.toString();
}
commit 5942579d55637862952fbb09cc748717d1f73ae2
Author: Mike Thompson <mithomps(a)redhat.com>
Date: Tue Jul 9 08:16:49 2013 -0700
Add legend to new multi-line graph.
diff --git
a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/detail/monitoring/table/CompositeGroupD3MultiLineGraph.java
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/detail/monitoring/table/CompositeGroupD3MultiLineGraph.java
index 31f5b8b..a62cb5c 100644
---
a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/detail/monitoring/table/CompositeGroupD3MultiLineGraph.java
+++
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/detail/monitoring/table/CompositeGroupD3MultiLineGraph.java
@@ -205,6 +205,44 @@ public class CompositeGroupD3MultiLineGraph extends
CompositeGroupD3GraphListVie
}
+ function createLegend() {
+
+ // add legend
+ var legend = svg.append("g")
+ .attr("class", "legend")
+ .attr("x", width + 30)
+ .attr("y", 70)
+ .attr("height", 240)
+ .attr("width", 150);
+
+ legend.selectAll('g').data(chartContext.data)
+ .enter()
+ .append('g')
+ .each(function (d, i) {
+ var g = $wnd.d3.select(this);
+ g.append("rect")
+ .attr("x", width + 10)
+ .attr("y", (i * 15) - 8)
+ .attr("width", 10)
+ .attr("height", 10)
+ .style("fill", function(){return
colorScale(i);});
+
+ g.append("text")
+ .attr("x", width + 30)
+ .attr("y", i * 15)
+ .attr("height", 10)
+ .attr("width", 135)
+ .style("font-size", "10px")
+ .style("font-family", "Arial,
Helvetica, sans-serif")
+ .style("fill", "#50505A")
+ .text(function (d) {
+ return d.key;
+ });
+
+
+ });
+ }
+
function createHeader(titleName) {
var title = chart.append("g").append("rect")
@@ -266,6 +304,7 @@ public class CompositeGroupD3MultiLineGraph extends
CompositeGroupD3GraphListVie
createYAxisGridLines();
createMultiLines(chartContext);
createXandYAxes();
+ createLegend();
console.log("finished drawing multi-line graph");
}
}