novus-nvd3-rails 1.8.2 → 1.8.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +4 -0
- data/lib/novus/nvd3/rails/version.rb +1 -1
- data/novus-nvd3-rails.gemspec +1 -1
- data/vendor/assets/javascripts/nv.d3.js +1117 -554
- data/vendor/assets/stylesheets/nv.d3.css +23 -1
- metadata +20 -20
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fd609fdf8f388b5244547d270b2f5cb244e7ad2b
|
4
|
+
data.tar.gz: 5a954a6949b7fefe57819aa489330d36e34d693f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fe70dd05dce10fca74e1996cc6188f9b968755455a8a2472b0f0af81b8a11be7f361b95f18ec8eb03012b0d01c4fba21d3f4e2e65ae7c6afa50ad68c20a9d893
|
7
|
+
data.tar.gz: 6c2ecaa4a7eef83d6a32cb422125c449d589af58a079907d415905811be280d549be4e531c0dc10db51c43596ad4c30764e6777c3d4bdd328f4415d963f0d69d
|
data/README.md
CHANGED
data/novus-nvd3-rails.gemspec
CHANGED
@@ -20,7 +20,7 @@ Gem::Specification.new do |spec|
|
|
20
20
|
|
21
21
|
spec.add_development_dependency "bundler", "~> 1.7"
|
22
22
|
spec.add_development_dependency "rake", "~> 10.0"
|
23
|
-
spec.add_development_dependency 'rails', '4.2.
|
23
|
+
spec.add_development_dependency 'rails', '4.2.6'
|
24
24
|
spec.add_development_dependency 'rspec-rails', '~> 3.0'
|
25
25
|
spec.add_development_dependency 'capybara', '~> 2.6'
|
26
26
|
spec.add_development_dependency 'sqlite3', '~> 1.3'
|
@@ -1,4 +1,4 @@
|
|
1
|
-
/* nvd3 version 1.8.
|
1
|
+
/* nvd3 version 1.8.3 (https://github.com/novus/nvd3) 2016-04-26 */
|
2
2
|
(function(){
|
3
3
|
|
4
4
|
// set up main nv object
|
@@ -13,6 +13,11 @@ nv.charts = {}; //stores all the ready to use charts
|
|
13
13
|
nv.logs = {}; //stores some statistics and potential error messages
|
14
14
|
nv.dom = {}; //DOM manipulation functions
|
15
15
|
|
16
|
+
// Node/CommonJS - require D3
|
17
|
+
if (typeof(module) !== 'undefined' && typeof(exports) !== 'undefined' && typeof(d3) == 'undefined') {
|
18
|
+
d3 = require('d3');
|
19
|
+
}
|
20
|
+
|
16
21
|
nv.dispatch = d3.dispatch('render_start', 'render_end');
|
17
22
|
|
18
23
|
// Function bind polyfill
|
@@ -157,7 +162,7 @@ if (typeof(window) !== 'undefined') {
|
|
157
162
|
*/
|
158
163
|
nv.dom.write = function(callback) {
|
159
164
|
if (window.fastdom !== undefined) {
|
160
|
-
return fastdom.
|
165
|
+
return fastdom.mutate(callback);
|
161
166
|
}
|
162
167
|
return callback();
|
163
168
|
};
|
@@ -170,10 +175,11 @@ nv.dom.write = function(callback) {
|
|
170
175
|
*/
|
171
176
|
nv.dom.read = function(callback) {
|
172
177
|
if (window.fastdom !== undefined) {
|
173
|
-
return fastdom.
|
178
|
+
return fastdom.measure(callback);
|
174
179
|
}
|
175
180
|
return callback();
|
176
|
-
}
|
181
|
+
};
|
182
|
+
/* Utility class to handle creation of an interactive layer.
|
177
183
|
This places a rectangle on top of the chart. When you mouse move over it, it sends a dispatch
|
178
184
|
containing the X-coordinate. It can also render a vertical line where the mouse is located.
|
179
185
|
|
@@ -258,7 +264,8 @@ nv.interactiveGuideline = function() {
|
|
258
264
|
/* If mouseX/Y is outside of the chart's bounds,
|
259
265
|
trigger a mouseOut event.
|
260
266
|
*/
|
261
|
-
if (
|
267
|
+
if (d3.event.type === 'mouseout'
|
268
|
+
|| mouseX < 0 || mouseY < 0
|
262
269
|
|| mouseX > availableWidth || mouseY > availableHeight
|
263
270
|
|| (d3.event.relatedTarget && d3.event.relatedTarget.ownerSVGElement === undefined)
|
264
271
|
|| mouseOutAnyReason
|
@@ -642,11 +649,11 @@ nv.models.tooltip = function() {
|
|
642
649
|
|
643
650
|
var dataSeriesExists = function(d) {
|
644
651
|
if (d && d.series) {
|
645
|
-
if (d.series
|
646
|
-
return
|
652
|
+
if (nv.utils.isArray(d.series)) {
|
653
|
+
return true;
|
647
654
|
}
|
648
655
|
// if object, it's okay just convert to array of the object
|
649
|
-
if (d.series
|
656
|
+
if (nv.utils.isObject(d.series)) {
|
650
657
|
d.series = [d.series];
|
651
658
|
return true;
|
652
659
|
}
|
@@ -754,18 +761,23 @@ nv.models.tooltip = function() {
|
|
754
761
|
|
755
762
|
// Creates new tooltip container, or uses existing one on DOM.
|
756
763
|
function initTooltip() {
|
757
|
-
if (!tooltip) {
|
764
|
+
if (!tooltip || !tooltip.node()) {
|
758
765
|
var container = chartContainer ? chartContainer : document.body;
|
759
|
-
|
760
766
|
// Create new tooltip div if it doesn't exist on DOM.
|
761
|
-
|
762
|
-
|
763
|
-
|
764
|
-
|
765
|
-
tooltip.
|
766
|
-
|
767
|
-
|
768
|
-
|
767
|
+
|
768
|
+
var data = [1];
|
769
|
+
tooltip = d3.select(container).selectAll('.nvtooltip').data(data);
|
770
|
+
|
771
|
+
tooltip.enter().append('div')
|
772
|
+
.attr("class", "nvtooltip " + (classes ? classes : "xy-tooltip"))
|
773
|
+
.attr("id", id)
|
774
|
+
.style("top", 0).style("left", 0)
|
775
|
+
.style('opacity', 0)
|
776
|
+
.style('position', 'fixed')
|
777
|
+
.selectAll("div, table, td, tr").classed(nvPointerEventsClass, true)
|
778
|
+
.classed(nvPointerEventsClass, true);
|
779
|
+
|
780
|
+
tooltip.exit().remove()
|
769
781
|
}
|
770
782
|
}
|
771
783
|
|
@@ -884,6 +896,25 @@ nv.utils.windowSize = function() {
|
|
884
896
|
return (size);
|
885
897
|
};
|
886
898
|
|
899
|
+
|
900
|
+
/* handle dumb browser quirks... isinstance breaks if you use frames
|
901
|
+
typeof returns 'object' for null, NaN is a number, etc.
|
902
|
+
*/
|
903
|
+
nv.utils.isArray = Array.isArray;
|
904
|
+
nv.utils.isObject = function(a) {
|
905
|
+
return a !== null && typeof a === 'object';
|
906
|
+
};
|
907
|
+
nv.utils.isFunction = function(a) {
|
908
|
+
return typeof a === 'function';
|
909
|
+
};
|
910
|
+
nv.utils.isDate = function(a) {
|
911
|
+
return toString.call(a) === '[object Date]';
|
912
|
+
};
|
913
|
+
nv.utils.isNumber = function(a) {
|
914
|
+
return !isNaN(a) && typeof a === 'number';
|
915
|
+
};
|
916
|
+
|
917
|
+
|
887
918
|
/*
|
888
919
|
Binds callback function to run when window is resized
|
889
920
|
*/
|
@@ -915,8 +946,7 @@ nv.utils.getColor = function(color) {
|
|
915
946
|
return nv.utils.defaultColor();
|
916
947
|
|
917
948
|
//if passed an array, turn it into a color scale
|
918
|
-
|
919
|
-
} else if(Array.isArray(color)) {
|
949
|
+
} else if(nv.utils.isArray(color)) {
|
920
950
|
var color_scale = d3.scale.ordinal().range(color);
|
921
951
|
return function(d, i) {
|
922
952
|
var key = i === undefined ? d : i;
|
@@ -956,7 +986,7 @@ nv.utils.customTheme = function(dictionary, getKey, defaultColors) {
|
|
956
986
|
|
957
987
|
return function(series, index) {
|
958
988
|
var key = getKey(series);
|
959
|
-
if (
|
989
|
+
if (nv.utils.isFunction(dictionary[key])) {
|
960
990
|
return dictionary[key]();
|
961
991
|
} else if (dictionary[key] !== undefined) {
|
962
992
|
return dictionary[key];
|
@@ -1010,12 +1040,10 @@ Most common instance is when the element is in a display:none; container.
|
|
1010
1040
|
Forumla is : text.length * font-size * constant_factor
|
1011
1041
|
*/
|
1012
1042
|
nv.utils.calcApproxTextWidth = function (svgTextElem) {
|
1013
|
-
if (
|
1014
|
-
&& typeof svgTextElem.text === 'function') {
|
1015
|
-
|
1043
|
+
if (nv.utils.isFunction(svgTextElem.style) && nv.utils.isFunction(svgTextElem.text)) {
|
1016
1044
|
var fontSize = parseInt(svgTextElem.style("font-size").replace("px",""), 10);
|
1017
1045
|
var textLength = svgTextElem.text().length;
|
1018
|
-
return textLength * fontSize * 0.5;
|
1046
|
+
return nv.utils.NaNtoZero(textLength * fontSize * 0.5);
|
1019
1047
|
}
|
1020
1048
|
return 0;
|
1021
1049
|
};
|
@@ -1025,7 +1053,7 @@ nv.utils.calcApproxTextWidth = function (svgTextElem) {
|
|
1025
1053
|
Numbers that are undefined, null or NaN, convert them to zeros.
|
1026
1054
|
*/
|
1027
1055
|
nv.utils.NaNtoZero = function(n) {
|
1028
|
-
if (
|
1056
|
+
if (!nv.utils.isNumber(n)
|
1029
1057
|
|| isNaN(n)
|
1030
1058
|
|| n === null
|
1031
1059
|
|| n === Infinity
|
@@ -1143,9 +1171,9 @@ nv.utils.deepExtend = function(dst){
|
|
1143
1171
|
var sources = arguments.length > 1 ? [].slice.call(arguments, 1) : [];
|
1144
1172
|
sources.forEach(function(source) {
|
1145
1173
|
for (var key in source) {
|
1146
|
-
var isArray = dst[key]
|
1147
|
-
var isObject =
|
1148
|
-
var srcObj =
|
1174
|
+
var isArray = nv.utils.isArray(dst[key]);
|
1175
|
+
var isObject = nv.utils.isObject(dst[key]);
|
1176
|
+
var srcObj = nv.utils.isObject(source[key]);
|
1149
1177
|
|
1150
1178
|
if (isObject && !isArray && srcObj) {
|
1151
1179
|
nv.utils.deepExtend(dst[key], source[key]);
|
@@ -1244,7 +1272,7 @@ chart.options = nv.utils.optionsFunc.bind(chart);
|
|
1244
1272
|
nv.utils.optionsFunc = function(args) {
|
1245
1273
|
if (args) {
|
1246
1274
|
d3.map(args).forEach((function(key,value) {
|
1247
|
-
if (
|
1275
|
+
if (nv.utils.isFunction(this[key])) {
|
1248
1276
|
this[key](value);
|
1249
1277
|
}
|
1250
1278
|
}).bind(this));
|
@@ -1560,6 +1588,7 @@ nv.utils.arrayEquals = function (array1, array2) {
|
|
1560
1588
|
, isOrdinal = false
|
1561
1589
|
, ticks = null
|
1562
1590
|
, axisLabelDistance = 0
|
1591
|
+
, fontSize = undefined
|
1563
1592
|
, duration = 250
|
1564
1593
|
, dispatch = d3.dispatch('renderEnd')
|
1565
1594
|
;
|
@@ -1607,6 +1636,11 @@ nv.utils.arrayEquals = function (array1, array2) {
|
|
1607
1636
|
.data([axisLabelText || null]);
|
1608
1637
|
axisLabel.exit().remove();
|
1609
1638
|
|
1639
|
+
//only skip when fontSize is undefined so it can be cleared with a null or blank string
|
1640
|
+
if (fontSize !== undefined) {
|
1641
|
+
g.selectAll('g').select("text").style('font-size', fontSize);
|
1642
|
+
}
|
1643
|
+
|
1610
1644
|
var xLabelMargin;
|
1611
1645
|
var axisMaxMin;
|
1612
1646
|
var w;
|
@@ -1657,6 +1691,8 @@ nv.utils.arrayEquals = function (array1, array2) {
|
|
1657
1691
|
var xTicks = g.selectAll('g').select("text");
|
1658
1692
|
var rotateLabelsRule = '';
|
1659
1693
|
if (rotateLabels%360) {
|
1694
|
+
//Reset transform on ticks so textHeight can be calculated correctly
|
1695
|
+
xTicks.attr('transform', '');
|
1660
1696
|
//Calculate the longest xTick width
|
1661
1697
|
xTicks.each(function(d,i){
|
1662
1698
|
var box = this.getBoundingClientRect();
|
@@ -1896,6 +1932,7 @@ nv.utils.arrayEquals = function (array1, array2) {
|
|
1896
1932
|
height: {get: function(){return height;}, set: function(_){height=_;}},
|
1897
1933
|
ticks: {get: function(){return ticks;}, set: function(_){ticks=_;}},
|
1898
1934
|
width: {get: function(){return width;}, set: function(_){width=_;}},
|
1935
|
+
fontSize: {get: function(){return fontSize;}, set: function(_){fontSize=_;}},
|
1899
1936
|
|
1900
1937
|
// options that require extra logic in the setter
|
1901
1938
|
margin: {get: function(){return margin;}, set: function(_){
|
@@ -1929,30 +1966,36 @@ nv.models.boxPlot = function() {
|
|
1929
1966
|
// Public Variables with Default Settings
|
1930
1967
|
//------------------------------------------------------------
|
1931
1968
|
|
1932
|
-
var margin = {top: 0, right: 0, bottom: 0, left: 0}
|
1933
|
-
|
1934
|
-
|
1935
|
-
|
1936
|
-
|
1937
|
-
|
1938
|
-
|
1939
|
-
|
1940
|
-
|
1941
|
-
|
1942
|
-
,
|
1943
|
-
,
|
1944
|
-
,
|
1945
|
-
,
|
1946
|
-
|
1947
|
-
,
|
1948
|
-
,
|
1949
|
-
|
1969
|
+
var margin = {top: 0, right: 0, bottom: 0, left: 0},
|
1970
|
+
width = 960,
|
1971
|
+
height = 500,
|
1972
|
+
id = Math.floor(Math.random() * 10000), // Create semi-unique ID in case user doesn't select one
|
1973
|
+
xScale = d3.scale.ordinal(),
|
1974
|
+
yScale = d3.scale.linear(),
|
1975
|
+
getX = function(d) { return d.label }, // Default data model selectors.
|
1976
|
+
getQ1 = function(d) { return d.values.Q1 },
|
1977
|
+
getQ2 = function(d) { return d.values.Q2 },
|
1978
|
+
getQ3 = function(d) { return d.values.Q3 },
|
1979
|
+
getWl = function(d) { return d.values.whisker_low },
|
1980
|
+
getWh = function(d) { return d.values.whisker_high },
|
1981
|
+
getColor = function(d) { return d.color },
|
1982
|
+
getOlItems = function(d) { return d.values.outliers },
|
1983
|
+
getOlValue = function(d, i, j) { return d },
|
1984
|
+
getOlLabel = function(d, i, j) { return d },
|
1985
|
+
getOlColor = function(d, i, j) { return undefined },
|
1986
|
+
color = nv.utils.defaultColor(),
|
1987
|
+
container = null,
|
1988
|
+
xDomain, xRange,
|
1989
|
+
yDomain, yRange,
|
1990
|
+
dispatch = d3.dispatch('elementMouseover', 'elementMouseout', 'elementMousemove', 'renderEnd'),
|
1991
|
+
duration = 250,
|
1992
|
+
maxBoxWidth = null;
|
1950
1993
|
|
1951
1994
|
//============================================================
|
1952
1995
|
// Private Variables
|
1953
1996
|
//------------------------------------------------------------
|
1954
1997
|
|
1955
|
-
var
|
1998
|
+
var xScale0, yScale0;
|
1956
1999
|
var renderWatch = nv.utils.renderWatch(dispatch, duration);
|
1957
2000
|
|
1958
2001
|
function chart(selection) {
|
@@ -1965,45 +2008,38 @@ nv.models.boxPlot = function() {
|
|
1965
2008
|
nv.utils.initSVG(container);
|
1966
2009
|
|
1967
2010
|
// Setup Scales
|
1968
|
-
|
1969
|
-
.rangeBands(xRange || [0, availableWidth], .1);
|
2011
|
+
xScale.domain(xDomain || data.map(function(d,i) { return getX(d,i); }))
|
2012
|
+
.rangeBands(xRange || [0, availableWidth], 0.1);
|
1970
2013
|
|
1971
2014
|
// if we know yDomain, no need to calculate
|
1972
2015
|
var yData = []
|
1973
2016
|
if (!yDomain) {
|
1974
2017
|
// (y-range is based on quartiles, whiskers and outliers)
|
1975
|
-
|
1976
|
-
|
1977
|
-
|
1978
|
-
var
|
1979
|
-
|
1980
|
-
|
1981
|
-
|
1982
|
-
|
1983
|
-
|
1984
|
-
|
1985
|
-
|
1986
|
-
|
1987
|
-
|
1988
|
-
|
1989
|
-
|
1990
|
-
|
1991
|
-
max_arr.push(d.values.Q3);
|
1992
|
-
if (d.values.hasOwnProperty('whisker_high') && d.values.whisker_high !== null) { max_arr.push(d.values.whisker_high); }
|
1993
|
-
if (d.values.hasOwnProperty('outliers') && d.values.outliers !== null) { max_arr = max_arr.concat(d.values.outliers); }
|
1994
|
-
|
1995
|
-
return d3.max(max_arr);
|
1996
|
-
}));
|
1997
|
-
|
2018
|
+
var values = [], yMin, yMax;
|
2019
|
+
data.forEach(function (d, i) {
|
2020
|
+
var q1 = getQ1(d), q3 = getQ3(d), wl = getWl(d), wh = getWh(d);
|
2021
|
+
var olItems = getOlItems(d);
|
2022
|
+
if (olItems) {
|
2023
|
+
olItems.forEach(function (e, i) {
|
2024
|
+
values.push(getOlValue(e, i, undefined));
|
2025
|
+
});
|
2026
|
+
}
|
2027
|
+
if (wl) { values.push(wl) }
|
2028
|
+
if (q1) { values.push(q1) }
|
2029
|
+
if (q3) { values.push(q3) }
|
2030
|
+
if (wh) { values.push(wh) }
|
2031
|
+
});
|
2032
|
+
yMin = d3.min(values);
|
2033
|
+
yMax = d3.max(values);
|
1998
2034
|
yData = [ yMin, yMax ] ;
|
1999
2035
|
}
|
2000
2036
|
|
2001
|
-
|
2002
|
-
|
2037
|
+
yScale.domain(yDomain || yData);
|
2038
|
+
yScale.range(yRange || [availableHeight, 0]);
|
2003
2039
|
|
2004
2040
|
//store old scales if they exist
|
2005
|
-
|
2006
|
-
|
2041
|
+
xScale0 = xScale0 || xScale;
|
2042
|
+
yScale0 = yScale0 || yScale.copy().range([yScale(0),yScale(0)]);
|
2007
2043
|
|
2008
2044
|
// Setup containers and skeleton of chart
|
2009
2045
|
var wrap = container.selectAll('g.nv-wrap').data([data]);
|
@@ -2014,15 +2050,15 @@ nv.models.boxPlot = function() {
|
|
2014
2050
|
var boxEnter = boxplots.enter().append('g').style('stroke-opacity', 1e-6).style('fill-opacity', 1e-6);
|
2015
2051
|
boxplots
|
2016
2052
|
.attr('class', 'nv-boxplot')
|
2017
|
-
.attr('transform', function(d,i,j) { return 'translate(' + (
|
2053
|
+
.attr('transform', function(d,i,j) { return 'translate(' + (xScale(getX(d,i)) + xScale.rangeBand() * 0.05) + ', 0)'; })
|
2018
2054
|
.classed('hover', function(d) { return d.hover });
|
2019
2055
|
boxplots
|
2020
2056
|
.watchTransition(renderWatch, 'nv-boxplot: boxplots')
|
2021
2057
|
.style('stroke-opacity', 1)
|
2022
|
-
.style('fill-opacity', .75)
|
2058
|
+
.style('fill-opacity', 0.75)
|
2023
2059
|
.delay(function(d,i) { return i * duration / data.length })
|
2024
2060
|
.attr('transform', function(d,i) {
|
2025
|
-
return 'translate(' + (
|
2061
|
+
return 'translate(' + (xScale(getX(d,i)) + xScale.rangeBand() * 0.05) + ', 0)';
|
2026
2062
|
});
|
2027
2063
|
boxplots.exit().remove();
|
2028
2064
|
|
@@ -2030,97 +2066,62 @@ nv.models.boxPlot = function() {
|
|
2030
2066
|
|
2031
2067
|
// conditionally append whisker lines
|
2032
2068
|
boxEnter.each(function(d,i) {
|
2033
|
-
|
2034
|
-
|
2035
|
-
|
2036
|
-
|
2037
|
-
|
2038
|
-
|
2039
|
-
|
2040
|
-
|
2041
|
-
|
2042
|
-
|
2043
|
-
|
2044
|
-
}
|
2045
|
-
});
|
2046
|
-
});
|
2047
|
-
|
2048
|
-
// outliers
|
2049
|
-
// TODO: support custom colors here
|
2050
|
-
var outliers = boxplots.selectAll('.nv-boxplot-outlier').data(function(d) {
|
2051
|
-
if (d.values.hasOwnProperty('outliers') && d.values.outliers !== null) { return d.values.outliers; }
|
2052
|
-
else { return []; }
|
2053
|
-
});
|
2054
|
-
outliers.enter().append('circle')
|
2055
|
-
.style('fill', function(d,i,j) { return color(d,j) }).style('stroke', function(d,i,j) { return color(d,j) })
|
2056
|
-
.on('mouseover', function(d,i,j) {
|
2057
|
-
d3.select(this).classed('hover', true);
|
2058
|
-
dispatch.elementMouseover({
|
2059
|
-
series: { key: d, color: color(d,j) },
|
2060
|
-
e: d3.event
|
2061
|
-
});
|
2062
|
-
})
|
2063
|
-
.on('mouseout', function(d,i,j) {
|
2064
|
-
d3.select(this).classed('hover', false);
|
2065
|
-
dispatch.elementMouseout({
|
2066
|
-
series: { key: d, color: color(d,j) },
|
2067
|
-
e: d3.event
|
2068
|
-
});
|
2069
|
-
})
|
2070
|
-
.on('mousemove', function(d,i) {
|
2071
|
-
dispatch.elementMousemove({e: d3.event});
|
2069
|
+
var box = d3.select(this);
|
2070
|
+
[getWl, getWh].forEach(function (f) {
|
2071
|
+
if (f(d)) {
|
2072
|
+
var key = (f === getWl) ? 'low' : 'high';
|
2073
|
+
box.append('line')
|
2074
|
+
.style('stroke', getColor(d) || color(d,i))
|
2075
|
+
.attr('class', 'nv-boxplot-whisker nv-boxplot-' + key);
|
2076
|
+
box.append('line')
|
2077
|
+
.style('stroke', getColor(d) || color(d,i))
|
2078
|
+
.attr('class', 'nv-boxplot-tick nv-boxplot-' + key);
|
2079
|
+
}
|
2072
2080
|
});
|
2081
|
+
});
|
2073
2082
|
|
2074
|
-
|
2075
|
-
|
2076
|
-
|
2077
|
-
.attr('cx', x.rangeBand() * .45)
|
2078
|
-
.attr('cy', function(d,i,j) { return y(d); })
|
2079
|
-
.attr('r', '3');
|
2080
|
-
outliers.exit().remove();
|
2081
|
-
|
2082
|
-
var box_width = function() { return (maxBoxWidth === null ? x.rangeBand() * .9 : Math.min(75, x.rangeBand() * .9)); };
|
2083
|
-
var box_left = function() { return x.rangeBand() * .45 - box_width()/2; };
|
2084
|
-
var box_right = function() { return x.rangeBand() * .45 + box_width()/2; };
|
2083
|
+
var box_width = function() { return (maxBoxWidth === null ? xScale.rangeBand() * 0.9 : Math.min(75, xScale.rangeBand() * 0.9)); };
|
2084
|
+
var box_left = function() { return xScale.rangeBand() * 0.45 - box_width()/2; };
|
2085
|
+
var box_right = function() { return xScale.rangeBand() * 0.45 + box_width()/2; };
|
2085
2086
|
|
2086
2087
|
// update whisker lines and ticks
|
2087
|
-
[
|
2088
|
-
|
2089
|
-
|
2090
|
-
|
2091
|
-
|
2092
|
-
|
2093
|
-
|
2094
|
-
|
2095
|
-
|
2096
|
-
|
2097
|
-
|
2098
|
-
|
2099
|
-
|
2100
|
-
|
2101
|
-
|
2102
|
-
.attr('y2', function(d,i) { return y(d.values['whisker_' + key]); });
|
2088
|
+
[getWl, getWh].forEach(function (f) {
|
2089
|
+
var key = (f === getWl) ? 'low' : 'high';
|
2090
|
+
var endpoint = (f === getWl) ? getQ1 : getQ3;
|
2091
|
+
boxplots.select('line.nv-boxplot-whisker.nv-boxplot-' + key)
|
2092
|
+
.watchTransition(renderWatch, 'nv-boxplot: boxplots')
|
2093
|
+
.attr('x1', xScale.rangeBand() * 0.45 )
|
2094
|
+
.attr('y1', function(d,i) { return yScale(f(d)); })
|
2095
|
+
.attr('x2', xScale.rangeBand() * 0.45 )
|
2096
|
+
.attr('y2', function(d,i) { return yScale(endpoint(d)); });
|
2097
|
+
boxplots.select('line.nv-boxplot-tick.nv-boxplot-' + key)
|
2098
|
+
.watchTransition(renderWatch, 'nv-boxplot: boxplots')
|
2099
|
+
.attr('x1', box_left )
|
2100
|
+
.attr('y1', function(d,i) { return yScale(f(d)); })
|
2101
|
+
.attr('x2', box_right )
|
2102
|
+
.attr('y2', function(d,i) { return yScale(f(d)); });
|
2103
2103
|
});
|
2104
2104
|
|
2105
|
-
[
|
2106
|
-
|
2107
|
-
.
|
2108
|
-
|
2109
|
-
|
2110
|
-
|
2111
|
-
|
2112
|
-
|
2113
|
-
|
2114
|
-
|
2115
|
-
|
2116
|
-
|
2117
|
-
|
2118
|
-
|
2119
|
-
|
2120
|
-
|
2121
|
-
|
2122
|
-
|
2123
|
-
|
2105
|
+
[getWl, getWh].forEach(function (f) {
|
2106
|
+
var key = (f === getWl) ? 'low' : 'high';
|
2107
|
+
boxEnter.selectAll('.nv-boxplot-' + key)
|
2108
|
+
.on('mouseover', function(d,i,j) {
|
2109
|
+
d3.select(this).classed('hover', true);
|
2110
|
+
dispatch.elementMouseover({
|
2111
|
+
series: { key: f(d), color: getColor(d) || color(d,j) },
|
2112
|
+
e: d3.event
|
2113
|
+
});
|
2114
|
+
})
|
2115
|
+
.on('mouseout', function(d,i,j) {
|
2116
|
+
d3.select(this).classed('hover', false);
|
2117
|
+
dispatch.elementMouseout({
|
2118
|
+
series: { key: f(d), color: getColor(d) || color(d,j) },
|
2119
|
+
e: d3.event
|
2120
|
+
});
|
2121
|
+
})
|
2122
|
+
.on('mousemove', function(d,i) {
|
2123
|
+
dispatch.elementMousemove({e: d3.event});
|
2124
|
+
});
|
2124
2125
|
});
|
2125
2126
|
|
2126
2127
|
// boxes
|
@@ -2130,12 +2131,12 @@ nv.models.boxPlot = function() {
|
|
2130
2131
|
.on('mouseover', function(d,i) {
|
2131
2132
|
d3.select(this).classed('hover', true);
|
2132
2133
|
dispatch.elementMouseover({
|
2133
|
-
key: d
|
2134
|
-
value: d
|
2134
|
+
key: getX(d),
|
2135
|
+
value: getX(d),
|
2135
2136
|
series: [
|
2136
|
-
{ key: 'Q3', value: d
|
2137
|
-
{ key: 'Q2', value: d
|
2138
|
-
{ key: 'Q1', value: d
|
2137
|
+
{ key: 'Q3', value: getQ3(d), color: getColor(d) || color(d,i) },
|
2138
|
+
{ key: 'Q2', value: getQ2(d), color: getColor(d) || color(d,i) },
|
2139
|
+
{ key: 'Q1', value: getQ1(d), color: getColor(d) || color(d,i) }
|
2139
2140
|
],
|
2140
2141
|
data: d,
|
2141
2142
|
index: i,
|
@@ -2145,12 +2146,12 @@ nv.models.boxPlot = function() {
|
|
2145
2146
|
.on('mouseout', function(d,i) {
|
2146
2147
|
d3.select(this).classed('hover', false);
|
2147
2148
|
dispatch.elementMouseout({
|
2148
|
-
key: d
|
2149
|
-
value: d
|
2149
|
+
key: getX(d),
|
2150
|
+
value: getX(d),
|
2150
2151
|
series: [
|
2151
|
-
{ key: 'Q3', value: d
|
2152
|
-
{ key: 'Q2', value: d
|
2153
|
-
{ key: 'Q1', value: d
|
2152
|
+
{ key: 'Q3', value: getQ3(d), color: getColor(d) || color(d,i) },
|
2153
|
+
{ key: 'Q2', value: getQ2(d), color: getColor(d) || color(d,i) },
|
2154
|
+
{ key: 'Q1', value: getQ1(d), color: getColor(d) || color(d,i) }
|
2154
2155
|
],
|
2155
2156
|
data: d,
|
2156
2157
|
index: i,
|
@@ -2164,13 +2165,12 @@ nv.models.boxPlot = function() {
|
|
2164
2165
|
// box transitions
|
2165
2166
|
boxplots.select('rect.nv-boxplot-box')
|
2166
2167
|
.watchTransition(renderWatch, 'nv-boxplot: boxes')
|
2167
|
-
.attr('y', function(d,i) { return
|
2168
|
+
.attr('y', function(d,i) { return yScale(getQ3(d)); })
|
2168
2169
|
.attr('width', box_width)
|
2169
2170
|
.attr('x', box_left )
|
2170
|
-
|
2171
|
-
.
|
2172
|
-
.style('
|
2173
|
-
.style('stroke', function(d,i) { return d.color || color(d,i) });
|
2171
|
+
.attr('height', function(d,i) { return Math.abs(yScale(getQ3(d)) - yScale(getQ1(d))) || 1 })
|
2172
|
+
.style('fill', function(d,i) { return getColor(d) || color(d,i) })
|
2173
|
+
.style('stroke', function(d,i) { return getColor(d) || color(d,i) });
|
2174
2174
|
|
2175
2175
|
// median line
|
2176
2176
|
boxEnter.append('line').attr('class', 'nv-boxplot-median');
|
@@ -2178,13 +2178,46 @@ nv.models.boxPlot = function() {
|
|
2178
2178
|
boxplots.select('line.nv-boxplot-median')
|
2179
2179
|
.watchTransition(renderWatch, 'nv-boxplot: boxplots line')
|
2180
2180
|
.attr('x1', box_left)
|
2181
|
-
.attr('y1', function(d,i) { return
|
2181
|
+
.attr('y1', function(d,i) { return yScale(getQ2(d)); })
|
2182
2182
|
.attr('x2', box_right)
|
2183
|
-
.attr('y2', function(d,i) { return
|
2183
|
+
.attr('y2', function(d,i) { return yScale(getQ2(d)); });
|
2184
|
+
|
2185
|
+
// outliers
|
2186
|
+
var outliers = boxplots.selectAll('.nv-boxplot-outlier').data(function(d) {
|
2187
|
+
return getOlItems(d) || [];
|
2188
|
+
});
|
2189
|
+
outliers.enter().append('circle')
|
2190
|
+
.style('fill', function(d,i,j) { return getOlColor(d,i,j) || color(d,j) })
|
2191
|
+
.style('stroke', function(d,i,j) { return getOlColor(d,i,j) || color(d,j) })
|
2192
|
+
.style('z-index', 9000)
|
2193
|
+
.on('mouseover', function(d,i,j) {
|
2194
|
+
d3.select(this).classed('hover', true);
|
2195
|
+
dispatch.elementMouseover({
|
2196
|
+
series: { key: getOlLabel(d,i,j), color: getOlColor(d,i,j) || color(d,j) },
|
2197
|
+
e: d3.event
|
2198
|
+
});
|
2199
|
+
})
|
2200
|
+
.on('mouseout', function(d,i,j) {
|
2201
|
+
d3.select(this).classed('hover', false);
|
2202
|
+
dispatch.elementMouseout({
|
2203
|
+
series: { key: getOlLabel(d,i,j), color: getOlColor(d,i,j) || color(d,j) },
|
2204
|
+
e: d3.event
|
2205
|
+
});
|
2206
|
+
})
|
2207
|
+
.on('mousemove', function(d,i) {
|
2208
|
+
dispatch.elementMousemove({e: d3.event});
|
2209
|
+
});
|
2210
|
+
outliers.attr('class', 'nv-boxplot-outlier');
|
2211
|
+
outliers
|
2212
|
+
.watchTransition(renderWatch, 'nv-boxplot: nv-boxplot-outlier')
|
2213
|
+
.attr('cx', xScale.rangeBand() * 0.45)
|
2214
|
+
.attr('cy', function(d,i,j) { return yScale(getOlValue(d,i,j)); })
|
2215
|
+
.attr('r', '3');
|
2216
|
+
outliers.exit().remove();
|
2184
2217
|
|
2185
2218
|
//store old scales for use in transitions on update
|
2186
|
-
|
2187
|
-
|
2219
|
+
xScale0 = xScale.copy();
|
2220
|
+
yScale0 = yScale.copy();
|
2188
2221
|
});
|
2189
2222
|
|
2190
2223
|
renderWatch.renderEnd('nv-boxplot immediate');
|
@@ -2200,20 +2233,37 @@ nv.models.boxPlot = function() {
|
|
2200
2233
|
|
2201
2234
|
chart._options = Object.create({}, {
|
2202
2235
|
// simple options, just get/set the necessary values
|
2203
|
-
width:
|
2204
|
-
height:
|
2236
|
+
width: {get: function(){return width;}, set: function(_){width=_;}},
|
2237
|
+
height: {get: function(){return height;}, set: function(_){height=_;}},
|
2205
2238
|
maxBoxWidth: {get: function(){return maxBoxWidth;}, set: function(_){maxBoxWidth=_;}},
|
2206
|
-
x:
|
2207
|
-
|
2208
|
-
|
2209
|
-
|
2239
|
+
x: {get: function(){return getX;}, set: function(_){getX=_;}},
|
2240
|
+
q1: {get: function(){return getQ1;}, set: function(_){getQ1=_;}},
|
2241
|
+
q2: {get: function(){return getQ2;}, set: function(_){getQ2=_;}},
|
2242
|
+
q3: {get: function(){return getQ3;}, set: function(_){getQ3=_;}},
|
2243
|
+
wl: {get: function(){return getWl;}, set: function(_){getWl=_;}},
|
2244
|
+
wh: {get: function(){return getWh;}, set: function(_){getWh=_;}},
|
2245
|
+
itemColor: {get: function(){return getColor;}, set: function(_){getColor=_;}},
|
2246
|
+
outliers: {get: function(){return getOlItems;}, set: function(_){getOlItems=_;}},
|
2247
|
+
outlierValue: {get: function(){return getOlValue;}, set: function(_){getOlValue=_;}},
|
2248
|
+
outlierLabel: {get: function(){return getOlLabel;}, set: function(_){getOlLabel=_;}},
|
2249
|
+
outlierColor: {get: function(){return getOlColor;}, set: function(_){getOlColor=_;}},
|
2250
|
+
xScale: {get: function(){return xScale;}, set: function(_){xScale=_;}},
|
2251
|
+
yScale: {get: function(){return yScale;}, set: function(_){yScale=_;}},
|
2210
2252
|
xDomain: {get: function(){return xDomain;}, set: function(_){xDomain=_;}},
|
2211
2253
|
yDomain: {get: function(){return yDomain;}, set: function(_){yDomain=_;}},
|
2212
2254
|
xRange: {get: function(){return xRange;}, set: function(_){xRange=_;}},
|
2213
2255
|
yRange: {get: function(){return yRange;}, set: function(_){yRange=_;}},
|
2214
2256
|
id: {get: function(){return id;}, set: function(_){id=_;}},
|
2215
2257
|
// rectClass: {get: function(){return rectClass;}, set: function(_){rectClass=_;}},
|
2216
|
-
|
2258
|
+
y: {
|
2259
|
+
get: function() {
|
2260
|
+
console.warn('BoxPlot \'y\' chart option is deprecated. Please use model overrides instead.');
|
2261
|
+
return {};
|
2262
|
+
},
|
2263
|
+
set: function(_) {
|
2264
|
+
console.warn('BoxPlot \'y\' chart option is deprecated. Please use model overrides instead.');
|
2265
|
+
}
|
2266
|
+
},
|
2217
2267
|
// options that require extra logic in the setter
|
2218
2268
|
margin: {get: function(){return margin;}, set: function(_){
|
2219
2269
|
margin.top = _.top !== undefined ? _.top : margin.top;
|
@@ -2241,26 +2291,23 @@ nv.models.boxPlotChart = function() {
|
|
2241
2291
|
// Public Variables with Default Settings
|
2242
2292
|
//------------------------------------------------------------
|
2243
2293
|
|
2244
|
-
var boxplot = nv.models.boxPlot()
|
2245
|
-
|
2246
|
-
|
2247
|
-
;
|
2294
|
+
var boxplot = nv.models.boxPlot(),
|
2295
|
+
xAxis = nv.models.axis(),
|
2296
|
+
yAxis = nv.models.axis();
|
2248
2297
|
|
2249
|
-
var margin = {top: 15, right: 10, bottom: 50, left: 60}
|
2250
|
-
|
2251
|
-
|
2252
|
-
|
2253
|
-
|
2254
|
-
|
2255
|
-
|
2256
|
-
|
2257
|
-
|
2258
|
-
,
|
2259
|
-
,
|
2260
|
-
|
2261
|
-
|
2262
|
-
, duration = 250
|
2263
|
-
;
|
2298
|
+
var margin = {top: 15, right: 10, bottom: 50, left: 60},
|
2299
|
+
width = null,
|
2300
|
+
height = null,
|
2301
|
+
color = nv.utils.getColor(),
|
2302
|
+
showXAxis = true,
|
2303
|
+
showYAxis = true,
|
2304
|
+
rightAlignYAxis = false,
|
2305
|
+
staggerLabels = false,
|
2306
|
+
tooltip = nv.models.tooltip(),
|
2307
|
+
x, y,
|
2308
|
+
noData = 'No Data Available.',
|
2309
|
+
dispatch = d3.dispatch('beforeUpdate', 'renderEnd'),
|
2310
|
+
duration = 250;
|
2264
2311
|
|
2265
2312
|
xAxis
|
2266
2313
|
.orient('bottom')
|
@@ -2287,13 +2334,10 @@ nv.models.boxPlotChart = function() {
|
|
2287
2334
|
if (showYAxis) renderWatch.models(yAxis);
|
2288
2335
|
|
2289
2336
|
selection.each(function(data) {
|
2290
|
-
var container = d3.select(this),
|
2291
|
-
that = this;
|
2337
|
+
var container = d3.select(this), that = this;
|
2292
2338
|
nv.utils.initSVG(container);
|
2293
|
-
var availableWidth = (width || parseInt(container.style('width')) || 960)
|
2294
|
-
|
2295
|
-
availableHeight = (height || parseInt(container.style('height')) || 400)
|
2296
|
-
- margin.top - margin.bottom;
|
2339
|
+
var availableWidth = (width || parseInt(container.style('width')) || 960) - margin.left - margin.right;
|
2340
|
+
var availableHeight = (height || parseInt(container.style('height')) || 400) - margin.top - margin.bottom;
|
2297
2341
|
|
2298
2342
|
chart.update = function() {
|
2299
2343
|
dispatch.beforeUpdate();
|
@@ -2301,9 +2345,9 @@ nv.models.boxPlotChart = function() {
|
|
2301
2345
|
};
|
2302
2346
|
chart.container = this;
|
2303
2347
|
|
2304
|
-
//
|
2305
|
-
if (
|
2306
|
-
|
2348
|
+
// TODO still need to find a way to validate quartile data presence using boxPlot callbacks.
|
2349
|
+
// Display No Data message if there's nothing to show. (quartiles required at minimum).
|
2350
|
+
if (!data || !data.length) {
|
2307
2351
|
var noDataText = container.selectAll('.nv-noData').data([noData]);
|
2308
2352
|
|
2309
2353
|
noDataText.enter().append('text')
|
@@ -2337,25 +2381,21 @@ nv.models.boxPlotChart = function() {
|
|
2337
2381
|
.append('line');
|
2338
2382
|
|
2339
2383
|
gEnter.append('g').attr('class', 'nv-barsWrap');
|
2340
|
-
|
2341
2384
|
g.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');
|
2342
2385
|
|
2343
2386
|
if (rightAlignYAxis) {
|
2344
|
-
g.select(
|
2345
|
-
.attr(
|
2387
|
+
g.select('.nv-y.nv-axis')
|
2388
|
+
.attr('transform', 'translate(' + availableWidth + ',0)');
|
2346
2389
|
}
|
2347
2390
|
|
2348
2391
|
// Main Chart Component(s)
|
2349
|
-
boxplot
|
2350
|
-
.width(availableWidth)
|
2351
|
-
.height(availableHeight);
|
2392
|
+
boxplot.width(availableWidth).height(availableHeight);
|
2352
2393
|
|
2353
2394
|
var barsWrap = g.select('.nv-barsWrap')
|
2354
2395
|
.datum(data.filter(function(d) { return !d.disabled }))
|
2355
2396
|
|
2356
2397
|
barsWrap.transition().call(boxplot);
|
2357
2398
|
|
2358
|
-
|
2359
2399
|
defsEnter.append('clipPath')
|
2360
2400
|
.attr('id', 'nv-x-label-clip-' + boxplot.id())
|
2361
2401
|
.append('rect');
|
@@ -2379,7 +2419,7 @@ nv.models.boxPlotChart = function() {
|
|
2379
2419
|
if (staggerLabels) {
|
2380
2420
|
xTicks
|
2381
2421
|
.selectAll('text')
|
2382
|
-
.attr('transform', function(d,i,j) { return 'translate(0,' + (j % 2
|
2422
|
+
.attr('transform', function(d,i,j) { return 'translate(0,' + (j % 2 === 0 ? '5' : '17') + ')' })
|
2383
2423
|
}
|
2384
2424
|
}
|
2385
2425
|
|
@@ -2393,11 +2433,11 @@ nv.models.boxPlotChart = function() {
|
|
2393
2433
|
}
|
2394
2434
|
|
2395
2435
|
// Zero line
|
2396
|
-
g.select(
|
2397
|
-
.attr(
|
2398
|
-
.attr(
|
2399
|
-
.attr(
|
2400
|
-
.attr(
|
2436
|
+
g.select('.nv-zeroLine line')
|
2437
|
+
.attr('x1',0)
|
2438
|
+
.attr('x2',availableWidth)
|
2439
|
+
.attr('y1', y(0))
|
2440
|
+
.attr('y2', y(0))
|
2401
2441
|
;
|
2402
2442
|
|
2403
2443
|
//============================================================
|
@@ -2504,8 +2544,19 @@ nv.models.bullet = function() {
|
|
2504
2544
|
, tickFormat = null
|
2505
2545
|
, color = nv.utils.getColor(['#1f77b4'])
|
2506
2546
|
, dispatch = d3.dispatch('elementMouseover', 'elementMouseout', 'elementMousemove')
|
2547
|
+
, defaultRangeLabels = ["Maximum", "Mean", "Minimum"]
|
2548
|
+
, legacyRangeClassNames = ["Max", "Avg", "Min"]
|
2507
2549
|
;
|
2508
2550
|
|
2551
|
+
function sortLabels(labels, values){
|
2552
|
+
var lz = labels.slice();
|
2553
|
+
labels.sort(function(a, b){
|
2554
|
+
var iA = lz.indexOf(a);
|
2555
|
+
var iB = lz.indexOf(b);
|
2556
|
+
return d3.descending(values[iA], values[iB]);
|
2557
|
+
});
|
2558
|
+
};
|
2559
|
+
|
2509
2560
|
function chart(selection) {
|
2510
2561
|
selection.each(function(d, i) {
|
2511
2562
|
var availableWidth = width - margin.left - margin.right,
|
@@ -2514,13 +2565,23 @@ nv.models.bullet = function() {
|
|
2514
2565
|
container = d3.select(this);
|
2515
2566
|
nv.utils.initSVG(container);
|
2516
2567
|
|
2517
|
-
var rangez = ranges.call(this, d, i).slice()
|
2518
|
-
markerz = markers.call(this, d, i).slice()
|
2519
|
-
measurez = measures.call(this, d, i).slice()
|
2568
|
+
var rangez = ranges.call(this, d, i).slice(),
|
2569
|
+
markerz = markers.call(this, d, i).slice(),
|
2570
|
+
measurez = measures.call(this, d, i).slice(),
|
2520
2571
|
rangeLabelz = rangeLabels.call(this, d, i).slice(),
|
2521
2572
|
markerLabelz = markerLabels.call(this, d, i).slice(),
|
2522
2573
|
measureLabelz = measureLabels.call(this, d, i).slice();
|
2523
2574
|
|
2575
|
+
// Sort labels according to their sorted values
|
2576
|
+
sortLabels(rangeLabelz, rangez);
|
2577
|
+
sortLabels(markerLabelz, markerz);
|
2578
|
+
sortLabels(measureLabelz, measurez);
|
2579
|
+
|
2580
|
+
// sort values descending
|
2581
|
+
rangez.sort(d3.descending);
|
2582
|
+
markerz.sort(d3.descending);
|
2583
|
+
measurez.sort(d3.descending);
|
2584
|
+
|
2524
2585
|
// Setup Scales
|
2525
2586
|
// Compute the new x-scale.
|
2526
2587
|
var x1 = d3.scale.linear()
|
@@ -2545,9 +2606,14 @@ nv.models.bullet = function() {
|
|
2545
2606
|
var gEnter = wrapEnter.append('g');
|
2546
2607
|
var g = wrap.select('g');
|
2547
2608
|
|
2548
|
-
|
2549
|
-
|
2550
|
-
|
2609
|
+
for(var i=0,il=rangez.length; i<il; i++){
|
2610
|
+
var rangeClassNames = 'nv-range nv-range'+i;
|
2611
|
+
if(i <= 2){
|
2612
|
+
rangeClassNames = rangeClassNames + ' nv-range'+legacyRangeClassNames[i];
|
2613
|
+
}
|
2614
|
+
gEnter.append('rect').attr('class', rangeClassNames);
|
2615
|
+
}
|
2616
|
+
|
2551
2617
|
gEnter.append('rect').attr('class', 'nv-measure');
|
2552
2618
|
|
2553
2619
|
wrap.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');
|
@@ -2557,25 +2623,14 @@ nv.models.bullet = function() {
|
|
2557
2623
|
var xp0 = function(d) { return d < 0 ? x0(d) : x0(0) },
|
2558
2624
|
xp1 = function(d) { return d < 0 ? x1(d) : x1(0) };
|
2559
2625
|
|
2560
|
-
|
2561
|
-
|
2562
|
-
.
|
2563
|
-
|
2564
|
-
|
2565
|
-
|
2566
|
-
|
2567
|
-
|
2568
|
-
.attr('width', w1(rangeAvg))
|
2569
|
-
.attr('x', xp1(rangeAvg))
|
2570
|
-
.datum(rangeAvg)
|
2571
|
-
|
2572
|
-
g.select('rect.nv-rangeMin')
|
2573
|
-
.attr('height', availableHeight)
|
2574
|
-
.attr('width', w1(rangeMax))
|
2575
|
-
.attr('x', xp1(rangeMax))
|
2576
|
-
.attr('width', w1(rangeMax > 0 ? rangeMin : rangeMax))
|
2577
|
-
.attr('x', xp1(rangeMax > 0 ? rangeMin : rangeMax))
|
2578
|
-
.datum(rangeMax > 0 ? rangeMin : rangeMax)
|
2626
|
+
for(var i=0,il=rangez.length; i<il; i++){
|
2627
|
+
var range = rangez[i];
|
2628
|
+
g.select('rect.nv-range'+i)
|
2629
|
+
.attr('height', availableHeight)
|
2630
|
+
.attr('width', w1(range))
|
2631
|
+
.attr('x', xp1(range))
|
2632
|
+
.datum(range)
|
2633
|
+
}
|
2579
2634
|
|
2580
2635
|
g.select('rect.nv-measure')
|
2581
2636
|
.style('fill', color)
|
@@ -2649,7 +2704,7 @@ nv.models.bullet = function() {
|
|
2649
2704
|
|
2650
2705
|
wrap.selectAll('.nv-range')
|
2651
2706
|
.on('mouseover', function(d,i) {
|
2652
|
-
var label = rangeLabelz[i] ||
|
2707
|
+
var label = rangeLabelz[i] || defaultRangeLabels[i];
|
2653
2708
|
dispatch.elementMouseover({
|
2654
2709
|
value: d,
|
2655
2710
|
label: label,
|
@@ -2664,7 +2719,7 @@ nv.models.bullet = function() {
|
|
2664
2719
|
})
|
2665
2720
|
})
|
2666
2721
|
.on('mouseout', function(d,i) {
|
2667
|
-
var label = rangeLabelz[i] ||
|
2722
|
+
var label = rangeLabelz[i] || defaultRangeLabels[i];
|
2668
2723
|
dispatch.elementMouseout({
|
2669
2724
|
value: d,
|
2670
2725
|
label: label,
|
@@ -3365,7 +3420,9 @@ nv.models.cumulativeLineChart = function() {
|
|
3365
3420
|
gEnter.append('g').attr('class', 'nv-controlsWrap');
|
3366
3421
|
|
3367
3422
|
// Legend
|
3368
|
-
if (showLegend) {
|
3423
|
+
if (!showLegend) {
|
3424
|
+
g.select('.nv-legendWrap').selectAll('*').remove();
|
3425
|
+
} else {
|
3369
3426
|
legend.width(availableWidth);
|
3370
3427
|
|
3371
3428
|
g.select('.nv-legendWrap')
|
@@ -3382,7 +3439,9 @@ nv.models.cumulativeLineChart = function() {
|
|
3382
3439
|
}
|
3383
3440
|
|
3384
3441
|
// Controls
|
3385
|
-
if (showControls) {
|
3442
|
+
if (!showControls) {
|
3443
|
+
g.select('.nv-controlsWrap').selectAll('*').remove();
|
3444
|
+
} else {
|
3386
3445
|
var controlsData = [
|
3387
3446
|
{ key: 'Re-scale y-axis', disabled: !rescaleY }
|
3388
3447
|
];
|
@@ -4158,8 +4217,11 @@ nv.models.discreteBarChart = function() {
|
|
4158
4217
|
gEnter.append('g').attr('class', 'nv-legendWrap');
|
4159
4218
|
|
4160
4219
|
g.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');
|
4161
|
-
|
4162
|
-
|
4220
|
+
|
4221
|
+
// Legend
|
4222
|
+
if (!showLegend) {
|
4223
|
+
g.select('.nv-legendWrap').selectAll('*').remove();
|
4224
|
+
} else {
|
4163
4225
|
legend.width(availableWidth);
|
4164
4226
|
|
4165
4227
|
g.select('.nv-legendWrap')
|
@@ -4180,11 +4242,6 @@ nv.models.discreteBarChart = function() {
|
|
4180
4242
|
.attr("transform", "translate(" + availableWidth + ",0)");
|
4181
4243
|
}
|
4182
4244
|
|
4183
|
-
if (rightAlignYAxis) {
|
4184
|
-
g.select(".nv-y.nv-axis")
|
4185
|
-
.attr("transform", "translate(" + availableWidth + ",0)");
|
4186
|
-
}
|
4187
|
-
|
4188
4245
|
// Main Chart Component(s)
|
4189
4246
|
discretebar
|
4190
4247
|
.width(availableWidth)
|
@@ -4494,6 +4551,195 @@ nv.models.distribution = function() {
|
|
4494
4551
|
|
4495
4552
|
return chart;
|
4496
4553
|
}
|
4554
|
+
nv.models.forceDirectedGraph = function() {
|
4555
|
+
"use strict";
|
4556
|
+
|
4557
|
+
//============================================================
|
4558
|
+
// Public Variables with Default Settings
|
4559
|
+
//------------------------------------------------------------
|
4560
|
+
var margin = {top: 2, right: 0, bottom: 2, left: 0}
|
4561
|
+
, width = 400
|
4562
|
+
, height = 32
|
4563
|
+
, container = null
|
4564
|
+
, dispatch = d3.dispatch('renderEnd')
|
4565
|
+
, color = nv.utils.getColor(['#000'])
|
4566
|
+
, tooltip = nv.models.tooltip()
|
4567
|
+
, noData = null
|
4568
|
+
// Force directed graph specific parameters [default values]
|
4569
|
+
, linkStrength = 0.1
|
4570
|
+
, friction = 0.9
|
4571
|
+
, linkDist = 30
|
4572
|
+
, charge = -120
|
4573
|
+
, gravity = 0.1
|
4574
|
+
, theta = 0.8
|
4575
|
+
, alpha = 0.1
|
4576
|
+
, radius = 5
|
4577
|
+
// These functions allow to add extra attributes to ndes and links
|
4578
|
+
,nodeExtras = function(nodes) { /* Do nothing */ }
|
4579
|
+
,linkExtras = function(links) { /* Do nothing */ }
|
4580
|
+
;
|
4581
|
+
|
4582
|
+
|
4583
|
+
//============================================================
|
4584
|
+
// Private Variables
|
4585
|
+
//------------------------------------------------------------
|
4586
|
+
|
4587
|
+
var renderWatch = nv.utils.renderWatch(dispatch);
|
4588
|
+
|
4589
|
+
function chart(selection) {
|
4590
|
+
renderWatch.reset();
|
4591
|
+
|
4592
|
+
selection.each(function(data) {
|
4593
|
+
container = d3.select(this);
|
4594
|
+
nv.utils.initSVG(container);
|
4595
|
+
|
4596
|
+
var availableWidth = nv.utils.availableWidth(width, container, margin),
|
4597
|
+
availableHeight = nv.utils.availableHeight(height, container, margin);
|
4598
|
+
|
4599
|
+
container
|
4600
|
+
.attr("width", availableWidth)
|
4601
|
+
.attr("height", availableHeight);
|
4602
|
+
|
4603
|
+
// Display No Data message if there's nothing to show.
|
4604
|
+
if (!data || !data.links || !data.nodes) {
|
4605
|
+
nv.utils.noData(chart, container)
|
4606
|
+
return chart;
|
4607
|
+
} else {
|
4608
|
+
container.selectAll('.nv-noData').remove();
|
4609
|
+
}
|
4610
|
+
container.selectAll('*').remove();
|
4611
|
+
|
4612
|
+
// Collect names of all fields in the nodes
|
4613
|
+
var nodeFieldSet = new Set();
|
4614
|
+
data.nodes.forEach(function(node) {
|
4615
|
+
var keys = Object.keys(node);
|
4616
|
+
keys.forEach(function(key) {
|
4617
|
+
nodeFieldSet.add(key);
|
4618
|
+
});
|
4619
|
+
});
|
4620
|
+
|
4621
|
+
var force = d3.layout.force()
|
4622
|
+
.nodes(data.nodes)
|
4623
|
+
.links(data.links)
|
4624
|
+
.size([availableWidth, availableHeight])
|
4625
|
+
.linkStrength(linkStrength)
|
4626
|
+
.friction(friction)
|
4627
|
+
.linkDistance(linkDist)
|
4628
|
+
.charge(charge)
|
4629
|
+
.gravity(gravity)
|
4630
|
+
.theta(theta)
|
4631
|
+
.alpha(alpha)
|
4632
|
+
.start();
|
4633
|
+
|
4634
|
+
var link = container.selectAll(".link")
|
4635
|
+
.data(data.links)
|
4636
|
+
.enter().append("line")
|
4637
|
+
.attr("class", "nv-force-link")
|
4638
|
+
.style("stroke-width", function(d) { return Math.sqrt(d.value); });
|
4639
|
+
|
4640
|
+
var node = container.selectAll(".node")
|
4641
|
+
.data(data.nodes)
|
4642
|
+
.enter()
|
4643
|
+
.append("g")
|
4644
|
+
.attr("class", "nv-force-node")
|
4645
|
+
.call(force.drag);
|
4646
|
+
|
4647
|
+
node
|
4648
|
+
.append("circle")
|
4649
|
+
.attr("r", radius)
|
4650
|
+
.style("fill", function(d) { return color(d) } )
|
4651
|
+
.on("mouseover", function(evt) {
|
4652
|
+
container.select('.nv-series-' + evt.seriesIndex + ' .nv-distx-' + evt.pointIndex)
|
4653
|
+
.attr('y1', evt.py);
|
4654
|
+
container.select('.nv-series-' + evt.seriesIndex + ' .nv-disty-' + evt.pointIndex)
|
4655
|
+
.attr('x2', evt.px);
|
4656
|
+
|
4657
|
+
// Add 'series' object to
|
4658
|
+
var nodeColor = color(evt);
|
4659
|
+
evt.series = [];
|
4660
|
+
nodeFieldSet.forEach(function(field) {
|
4661
|
+
evt.series.push({
|
4662
|
+
color: nodeColor,
|
4663
|
+
key: field,
|
4664
|
+
value: evt[field]
|
4665
|
+
});
|
4666
|
+
});
|
4667
|
+
tooltip.data(evt).hidden(false);
|
4668
|
+
})
|
4669
|
+
.on("mouseout", function(d) {
|
4670
|
+
tooltip.hidden(true);
|
4671
|
+
});
|
4672
|
+
|
4673
|
+
tooltip.headerFormatter(function(d) {return "Node";});
|
4674
|
+
|
4675
|
+
// Apply extra attributes to nodes and links (if any)
|
4676
|
+
linkExtras(link);
|
4677
|
+
nodeExtras(node);
|
4678
|
+
|
4679
|
+
force.on("tick", function() {
|
4680
|
+
link.attr("x1", function(d) { return d.source.x; })
|
4681
|
+
.attr("y1", function(d) { return d.source.y; })
|
4682
|
+
.attr("x2", function(d) { return d.target.x; })
|
4683
|
+
.attr("y2", function(d) { return d.target.y; });
|
4684
|
+
|
4685
|
+
node.attr("transform", function(d) {
|
4686
|
+
return "translate(" + d.x + ", " + d.y + ")";
|
4687
|
+
});
|
4688
|
+
});
|
4689
|
+
});
|
4690
|
+
|
4691
|
+
return chart;
|
4692
|
+
}
|
4693
|
+
|
4694
|
+
//============================================================
|
4695
|
+
// Expose Public Variables
|
4696
|
+
//------------------------------------------------------------
|
4697
|
+
|
4698
|
+
chart.options = nv.utils.optionsFunc.bind(chart);
|
4699
|
+
|
4700
|
+
chart._options = Object.create({}, {
|
4701
|
+
// simple options, just get/set the necessary values
|
4702
|
+
width: {get: function(){return width;}, set: function(_){width=_;}},
|
4703
|
+
height: {get: function(){return height;}, set: function(_){height=_;}},
|
4704
|
+
|
4705
|
+
// Force directed graph specific parameters
|
4706
|
+
linkStrength:{get: function(){return linkStrength;}, set: function(_){linkStrength=_;}},
|
4707
|
+
friction: {get: function(){return friction;}, set: function(_){friction=_;}},
|
4708
|
+
linkDist: {get: function(){return linkDist;}, set: function(_){linkDist=_;}},
|
4709
|
+
charge: {get: function(){return charge;}, set: function(_){charge=_;}},
|
4710
|
+
gravity: {get: function(){return gravity;}, set: function(_){gravity=_;}},
|
4711
|
+
theta: {get: function(){return theta;}, set: function(_){theta=_;}},
|
4712
|
+
alpha: {get: function(){return alpha;}, set: function(_){alpha=_;}},
|
4713
|
+
radius: {get: function(){return radius;}, set: function(_){radius=_;}},
|
4714
|
+
|
4715
|
+
//functor options
|
4716
|
+
x: {get: function(){return getX;}, set: function(_){getX=d3.functor(_);}},
|
4717
|
+
y: {get: function(){return getY;}, set: function(_){getY=d3.functor(_);}},
|
4718
|
+
|
4719
|
+
// options that require extra logic in the setter
|
4720
|
+
margin: {get: function(){return margin;}, set: function(_){
|
4721
|
+
margin.top = _.top !== undefined ? _.top : margin.top;
|
4722
|
+
margin.right = _.right !== undefined ? _.right : margin.right;
|
4723
|
+
margin.bottom = _.bottom !== undefined ? _.bottom : margin.bottom;
|
4724
|
+
margin.left = _.left !== undefined ? _.left : margin.left;
|
4725
|
+
}},
|
4726
|
+
color: {get: function(){return color;}, set: function(_){
|
4727
|
+
color = nv.utils.getColor(_);
|
4728
|
+
}},
|
4729
|
+
noData: {get: function(){return noData;}, set: function(_){noData=_;}},
|
4730
|
+
nodeExtras: {get: function(){return nodeExtras;}, set: function(_){
|
4731
|
+
nodeExtras = _;
|
4732
|
+
}},
|
4733
|
+
linkExtras: {get: function(){return linkExtras;}, set: function(_){
|
4734
|
+
linkExtras = _;
|
4735
|
+
}}
|
4736
|
+
});
|
4737
|
+
|
4738
|
+
chart.dispatch = dispatch;
|
4739
|
+
chart.tooltip = tooltip;
|
4740
|
+
nv.utils.initOptions(chart);
|
4741
|
+
return chart;
|
4742
|
+
};
|
4497
4743
|
nv.models.furiousLegend = function() {
|
4498
4744
|
"use strict";
|
4499
4745
|
|
@@ -4675,13 +4921,13 @@ nv.models.furiousLegend = function() {
|
|
4675
4921
|
var seriesWidths = [];
|
4676
4922
|
series.each(function(d,i) {
|
4677
4923
|
var legendText;
|
4678
|
-
if (getKey(d).length > maxKeyLength) {
|
4924
|
+
if (getKey(d) && (getKey(d).length > maxKeyLength)) {
|
4679
4925
|
var trimmedKey = getKey(d).substring(0, maxKeyLength);
|
4680
4926
|
legendText = d3.select(this).select('text').text(trimmedKey + "...");
|
4681
4927
|
d3.select(this).append("svg:title").text(getKey(d));
|
4682
4928
|
} else {
|
4683
4929
|
legendText = d3.select(this).select('text');
|
4684
|
-
}
|
4930
|
+
}
|
4685
4931
|
var nodeTextLength;
|
4686
4932
|
try {
|
4687
4933
|
nodeTextLength = legendText.node().getComputedTextLength();
|
@@ -5180,7 +5426,9 @@ nv.models.historicalBarChart = function(bar_model) {
|
|
5180
5426
|
gEnter.append('g').attr('class', 'nv-interactive');
|
5181
5427
|
|
5182
5428
|
// Legend
|
5183
|
-
if (showLegend) {
|
5429
|
+
if (!showLegend) {
|
5430
|
+
g.select('.nv-legendWrap').selectAll('*').remove();
|
5431
|
+
} else {
|
5184
5432
|
legend.width(availableWidth);
|
5185
5433
|
|
5186
5434
|
g.select('.nv-legendWrap')
|
@@ -5534,7 +5782,7 @@ nv.models.legend = function() {
|
|
5534
5782
|
.attr('class','nv-legend-symbol')
|
5535
5783
|
.attr('r', 5);
|
5536
5784
|
|
5537
|
-
seriesShape = series.select('
|
5785
|
+
seriesShape = series.select('.nv-legend-symbol');
|
5538
5786
|
} else if (vers == 'furious') {
|
5539
5787
|
seriesEnter.append('rect')
|
5540
5788
|
.style('stroke-width', 2)
|
@@ -5651,13 +5899,13 @@ nv.models.legend = function() {
|
|
5651
5899
|
var seriesWidths = [];
|
5652
5900
|
series.each(function(d,i) {
|
5653
5901
|
var legendText;
|
5654
|
-
if (getKey(d).length > maxKeyLength) {
|
5902
|
+
if (getKey(d) && (getKey(d).length > maxKeyLength)) {
|
5655
5903
|
var trimmedKey = getKey(d).substring(0, maxKeyLength);
|
5656
5904
|
legendText = d3.select(this).select('text').text(trimmedKey + "...");
|
5657
5905
|
d3.select(this).append("svg:title").text(getKey(d));
|
5658
5906
|
} else {
|
5659
5907
|
legendText = d3.select(this).select('text');
|
5660
|
-
}
|
5908
|
+
}
|
5661
5909
|
var nodeTextLength;
|
5662
5910
|
try {
|
5663
5911
|
nodeTextLength = legendText.node().getComputedTextLength();
|
@@ -6104,6 +6352,7 @@ nv.models.lineChart = function() {
|
|
6104
6352
|
, width = null
|
6105
6353
|
, height = null
|
6106
6354
|
, showLegend = true
|
6355
|
+
, legendPosition = 'top'
|
6107
6356
|
, showXAxis = true
|
6108
6357
|
, showYAxis = true
|
6109
6358
|
, rightAlignYAxis = false
|
@@ -6254,20 +6503,27 @@ nv.models.lineChart = function() {
|
|
6254
6503
|
contextEnter.append('g').attr('class', 'nv-x nv-brush');
|
6255
6504
|
|
6256
6505
|
// Legend
|
6257
|
-
if (showLegend) {
|
6506
|
+
if (!showLegend) {
|
6507
|
+
g.select('.nv-legendWrap').selectAll('*').remove();
|
6508
|
+
} else {
|
6258
6509
|
legend.width(availableWidth);
|
6259
6510
|
|
6260
6511
|
g.select('.nv-legendWrap')
|
6261
6512
|
.datum(data)
|
6262
6513
|
.call(legend);
|
6263
6514
|
|
6264
|
-
if (
|
6265
|
-
|
6266
|
-
|
6267
|
-
}
|
6515
|
+
if (legendPosition === 'bottom') {
|
6516
|
+
wrap.select('.nv-legendWrap')
|
6517
|
+
.attr('transform', 'translate(0,' + (availableHeight1) +')');
|
6518
|
+
} else if (legendPosition === 'top') {
|
6519
|
+
if ( margin.top != legend.height()) {
|
6520
|
+
margin.top = legend.height();
|
6521
|
+
availableHeight1 = nv.utils.availableHeight(height, container, margin) - (focusEnable ? focusHeight : 0);
|
6522
|
+
}
|
6268
6523
|
|
6269
|
-
|
6270
|
-
|
6524
|
+
wrap.select('.nv-legendWrap')
|
6525
|
+
.attr('transform', 'translate(0,' + (-margin.top) +')');
|
6526
|
+
}
|
6271
6527
|
}
|
6272
6528
|
|
6273
6529
|
wrap.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');
|
@@ -6491,11 +6747,13 @@ nv.models.lineChart = function() {
|
|
6491
6747
|
allData[indexToHighlight].highlight = true;
|
6492
6748
|
}
|
6493
6749
|
|
6750
|
+
var defaultValueFormatter = function(d,i) {
|
6751
|
+
return d == null ? "N/A" : yAxis.tickFormat()(d);
|
6752
|
+
};
|
6753
|
+
|
6494
6754
|
interactiveLayer.tooltip
|
6495
6755
|
.chartContainer(chart.container.parentNode)
|
6496
|
-
.valueFormatter(
|
6497
|
-
return d === null ? "N/A" : yAxis.tickFormat()(d);
|
6498
|
-
})
|
6756
|
+
.valueFormatter(interactiveLayer.tooltip.valueFormatter() || defaultValueFormatter)
|
6499
6757
|
.data({
|
6500
6758
|
value: chart.x()( singlePoint,pointIndex ),
|
6501
6759
|
index: pointIndex,
|
@@ -6669,6 +6927,7 @@ nv.models.lineChart = function() {
|
|
6669
6927
|
width: {get: function(){return width;}, set: function(_){width=_;}},
|
6670
6928
|
height: {get: function(){return height;}, set: function(_){height=_;}},
|
6671
6929
|
showLegend: {get: function(){return showLegend;}, set: function(_){showLegend=_;}},
|
6930
|
+
legendPosition: {get: function(){return legendPosition;}, set: function(_){legendPosition=_;}},
|
6672
6931
|
showXAxis: {get: function(){return showXAxis;}, set: function(_){showXAxis=_;}},
|
6673
6932
|
showYAxis: {get: function(){return showYAxis;}, set: function(_){showYAxis=_;}},
|
6674
6933
|
focusEnable: {get: function(){return focusEnable;}, set: function(_){focusEnable=_;}},
|
@@ -6749,8 +7008,7 @@ nv.models.lineWithFocusChart = function() {
|
|
6749
7008
|
return nv.models.lineChart()
|
6750
7009
|
.margin({ bottom: 30 })
|
6751
7010
|
.focusEnable( true );
|
6752
|
-
};
|
6753
|
-
nv.models.linePlusBarChart = function() {
|
7011
|
+
};nv.models.linePlusBarChart = function() {
|
6754
7012
|
"use strict";
|
6755
7013
|
|
6756
7014
|
//============================================================
|
@@ -6822,15 +7080,15 @@ nv.models.linePlusBarChart = function() {
|
|
6822
7080
|
//------------------------------------------------------------
|
6823
7081
|
|
6824
7082
|
var getBarsAxis = function() {
|
6825
|
-
return switchYAxisOrder
|
6826
|
-
? { main:
|
6827
|
-
: { main:
|
7083
|
+
return !switchYAxisOrder
|
7084
|
+
? { main: y2Axis, focus: y4Axis }
|
7085
|
+
: { main: y1Axis, focus: y3Axis }
|
6828
7086
|
}
|
6829
7087
|
|
6830
7088
|
var getLinesAxis = function() {
|
6831
|
-
return switchYAxisOrder
|
6832
|
-
? { main:
|
6833
|
-
: { main:
|
7089
|
+
return !switchYAxisOrder
|
7090
|
+
? { main: y1Axis, focus: y3Axis }
|
7091
|
+
: { main: y2Axis, focus: y4Axis }
|
6834
7092
|
}
|
6835
7093
|
|
6836
7094
|
var stateGetter = function(data) {
|
@@ -6900,7 +7158,12 @@ nv.models.linePlusBarChart = function() {
|
|
6900
7158
|
var dataBars = data.filter(function(d) { return !d.disabled && d.bar });
|
6901
7159
|
var dataLines = data.filter(function(d) { return !d.bar }); // removed the !d.disabled clause here to fix Issue #240
|
6902
7160
|
|
6903
|
-
|
7161
|
+
if (dataBars.length && !switchYAxisOrder) {
|
7162
|
+
x = bars.xScale();
|
7163
|
+
} else {
|
7164
|
+
x = lines.xScale();
|
7165
|
+
}
|
7166
|
+
|
6904
7167
|
x2 = x2Axis.scale();
|
6905
7168
|
|
6906
7169
|
// select the scales and series based on the position of the yAxis
|
@@ -6959,7 +7222,9 @@ nv.models.linePlusBarChart = function() {
|
|
6959
7222
|
// Legend
|
6960
7223
|
//------------------------------------------------------------
|
6961
7224
|
|
6962
|
-
if (showLegend) {
|
7225
|
+
if (!showLegend) {
|
7226
|
+
g.select('.nv-legendWrap').selectAll('*').remove();
|
7227
|
+
} else {
|
6963
7228
|
var legendWidth = legend.align() ? availableWidth / 2 : availableWidth;
|
6964
7229
|
var legendXPosition = legend.align() ? legendWidth : 0;
|
6965
7230
|
|
@@ -7234,8 +7499,14 @@ nv.models.linePlusBarChart = function() {
|
|
7234
7499
|
.tickSize(-availableWidth, 0);
|
7235
7500
|
y2Axis
|
7236
7501
|
.scale(y2)
|
7237
|
-
._ticks( nv.utils.calcTicksY(availableHeight1/36, data) )
|
7238
|
-
|
7502
|
+
._ticks( nv.utils.calcTicksY(availableHeight1/36, data) );
|
7503
|
+
|
7504
|
+
// Show the y2 rules only if y1 has none
|
7505
|
+
if(!switchYAxisOrder) {
|
7506
|
+
y2Axis.tickSize(dataBars.length ? 0 : -availableWidth, 0);
|
7507
|
+
} else {
|
7508
|
+
y2Axis.tickSize(dataLines.length ? 0 : -availableWidth, 0);
|
7509
|
+
}
|
7239
7510
|
|
7240
7511
|
// Calculate opacity of the axis
|
7241
7512
|
var barsOpacity = dataBars.length ? 1 : 0;
|
@@ -7379,11 +7650,20 @@ nv.models.linePlusBarChart = function() {
|
|
7379
7650
|
switchYAxisOrder: {get: function(){return switchYAxisOrder;}, set: function(_){
|
7380
7651
|
// Switch the tick format for the yAxis
|
7381
7652
|
if(switchYAxisOrder !== _) {
|
7382
|
-
var
|
7383
|
-
y1Axis
|
7384
|
-
y2Axis
|
7653
|
+
var y1 = y1Axis;
|
7654
|
+
y1Axis = y2Axis;
|
7655
|
+
y2Axis = y1;
|
7656
|
+
|
7657
|
+
var y3 = y3Axis;
|
7658
|
+
y3Axis = y4Axis;
|
7659
|
+
y4Axis = y3;
|
7385
7660
|
}
|
7386
7661
|
switchYAxisOrder=_;
|
7662
|
+
|
7663
|
+
y1Axis.orient('left');
|
7664
|
+
y2Axis.orient('right');
|
7665
|
+
y3Axis.orient('left');
|
7666
|
+
y4Axis.orient('right');
|
7387
7667
|
}}
|
7388
7668
|
});
|
7389
7669
|
|
@@ -7495,7 +7775,7 @@ nv.models.multiBar = function() {
|
|
7495
7775
|
});
|
7496
7776
|
|
7497
7777
|
// HACK for negative value stacking
|
7498
|
-
if (stacked) {
|
7778
|
+
if (stacked && data.length > 0) {
|
7499
7779
|
data[0].values.map(function(d,i) {
|
7500
7780
|
var posBase = 0, negBase = 0;
|
7501
7781
|
data.map(function(d, idx) {
|
@@ -7819,7 +8099,8 @@ nv.models.multiBar = function() {
|
|
7819
8099
|
nv.utils.initOptions(chart);
|
7820
8100
|
|
7821
8101
|
return chart;
|
7822
|
-
};
|
8102
|
+
};
|
8103
|
+
nv.models.multiBarChart = function() {
|
7823
8104
|
"use strict";
|
7824
8105
|
|
7825
8106
|
//============================================================
|
@@ -7979,7 +8260,9 @@ nv.models.multiBar = function() {
|
|
7979
8260
|
gEnter.append('g').attr('class', 'nv-interactive');
|
7980
8261
|
|
7981
8262
|
// Legend
|
7982
|
-
if (showLegend) {
|
8263
|
+
if (!showLegend) {
|
8264
|
+
g.select('.nv-legendWrap').selectAll('*').remove();
|
8265
|
+
} else {
|
7983
8266
|
legend.width(availableWidth - controlWidth());
|
7984
8267
|
|
7985
8268
|
g.select('.nv-legendWrap')
|
@@ -7996,7 +8279,9 @@ nv.models.multiBar = function() {
|
|
7996
8279
|
}
|
7997
8280
|
|
7998
8281
|
// Controls
|
7999
|
-
if (showControls) {
|
8282
|
+
if (!showControls) {
|
8283
|
+
g.select('.nv-controlsWrap').selectAll('*').remove();
|
8284
|
+
} else {
|
8000
8285
|
var controlsData = [
|
8001
8286
|
{ key: controlLabels.grouped || 'Grouped', disabled: multibar.stacked() },
|
8002
8287
|
{ key: controlLabels.stacked || 'Stacked', disabled: !multibar.stacked() }
|
@@ -8480,10 +8765,13 @@ nv.models.multiBarHorizontal = function() {
|
|
8480
8765
|
});
|
8481
8766
|
})
|
8482
8767
|
.on('click', function(d,i) {
|
8768
|
+
var element = this;
|
8483
8769
|
dispatch.elementClick({
|
8484
8770
|
data: d,
|
8485
8771
|
index: i,
|
8486
|
-
color: d3.select(this).style("fill")
|
8772
|
+
color: d3.select(this).style("fill"),
|
8773
|
+
event: d3.event,
|
8774
|
+
element: element
|
8487
8775
|
});
|
8488
8776
|
d3.event.stopPropagation();
|
8489
8777
|
})
|
@@ -8807,7 +9095,9 @@ nv.models.multiBarHorizontalChart = function() {
|
|
8807
9095
|
gEnter.append('g').attr('class', 'nv-controlsWrap');
|
8808
9096
|
|
8809
9097
|
// Legend
|
8810
|
-
if (showLegend) {
|
9098
|
+
if (!showLegend) {
|
9099
|
+
g.select('.nv-legendWrap').selectAll('*').remove();
|
9100
|
+
} else {
|
8811
9101
|
legend.width(availableWidth - controlWidth());
|
8812
9102
|
|
8813
9103
|
g.select('.nv-legendWrap')
|
@@ -8824,7 +9114,9 @@ nv.models.multiBarHorizontalChart = function() {
|
|
8824
9114
|
}
|
8825
9115
|
|
8826
9116
|
// Controls
|
8827
|
-
if (showControls) {
|
9117
|
+
if (!showControls) {
|
9118
|
+
g.select('.nv-controlsWrap').selectAll('*').remove();
|
9119
|
+
} else {
|
8828
9120
|
var controlsData = [
|
8829
9121
|
{ key: controlLabels.grouped || 'Grouped', disabled: multibar.stacked() },
|
8830
9122
|
{ key: controlLabels.stacked || 'Stacked', disabled: !multibar.stacked() }
|
@@ -9044,7 +9336,7 @@ nv.models.multiChart = function() {
|
|
9044
9336
|
yDomain2,
|
9045
9337
|
getX = function(d) { return d.x },
|
9046
9338
|
getY = function(d) { return d.y},
|
9047
|
-
interpolate = '
|
9339
|
+
interpolate = 'linear',
|
9048
9340
|
useVoronoi = true,
|
9049
9341
|
interactiveLayer = nv.interactiveGuideline(),
|
9050
9342
|
useInteractiveGuideline = false,
|
@@ -9124,7 +9416,7 @@ nv.models.multiChart = function() {
|
|
9124
9416
|
})
|
9125
9417
|
});
|
9126
9418
|
|
9127
|
-
x .domain(d3.extent(d3.merge(series1.concat(series2)), function(d) { return
|
9419
|
+
x .domain(d3.extent(d3.merge(series1.concat(series2)), function(d) { return d.x }))
|
9128
9420
|
.range([0, availableWidth]);
|
9129
9421
|
|
9130
9422
|
var wrap = container.selectAll('g.wrap.multiChart').data([data]);
|
@@ -9150,7 +9442,10 @@ nv.models.multiChart = function() {
|
|
9150
9442
|
return data[i].color || color(d, i);
|
9151
9443
|
});
|
9152
9444
|
|
9153
|
-
|
9445
|
+
// Legend
|
9446
|
+
if (!showLegend) {
|
9447
|
+
g.select('.legendWrap').selectAll('*').remove();
|
9448
|
+
} else {
|
9154
9449
|
var legendWidth = legend.align() ? availableWidth / 2 : availableWidth;
|
9155
9450
|
var legendXPosition = legend.align() ? legendWidth : 0;
|
9156
9451
|
|
@@ -9203,10 +9498,12 @@ nv.models.multiChart = function() {
|
|
9203
9498
|
stack1
|
9204
9499
|
.width(availableWidth)
|
9205
9500
|
.height(availableHeight)
|
9501
|
+
.interpolate(interpolate)
|
9206
9502
|
.color(color_array.filter(function(d,i) { return !data[i].disabled && data[i].yAxis == 1 && data[i].type == 'area'}));
|
9207
9503
|
stack2
|
9208
9504
|
.width(availableWidth)
|
9209
9505
|
.height(availableHeight)
|
9506
|
+
.interpolate(interpolate)
|
9210
9507
|
.color(color_array.filter(function(d,i) { return !data[i].disabled && data[i].yAxis == 2 && data[i].type == 'area'}));
|
9211
9508
|
|
9212
9509
|
g.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');
|
@@ -9323,6 +9620,9 @@ nv.models.multiChart = function() {
|
|
9323
9620
|
};
|
9324
9621
|
tooltip
|
9325
9622
|
.duration(0)
|
9623
|
+
.headerFormatter(function(d, i) {
|
9624
|
+
return xAxis.tickFormat()(d, i);
|
9625
|
+
})
|
9326
9626
|
.valueFormatter(function(d, i) {
|
9327
9627
|
return yaxis.tickFormat()(d, i);
|
9328
9628
|
})
|
@@ -9340,6 +9640,9 @@ nv.models.multiChart = function() {
|
|
9340
9640
|
};
|
9341
9641
|
tooltip
|
9342
9642
|
.duration(100)
|
9643
|
+
.headerFormatter(function(d, i) {
|
9644
|
+
return xAxis.tickFormat()(d, i);
|
9645
|
+
})
|
9343
9646
|
.valueFormatter(function(d, i) {
|
9344
9647
|
return yaxis.tickFormat()(d, i);
|
9345
9648
|
})
|
@@ -9353,6 +9656,9 @@ nv.models.multiChart = function() {
|
|
9353
9656
|
evt.point['y'] = stack1.y()(evt.point);
|
9354
9657
|
tooltip
|
9355
9658
|
.duration(0)
|
9659
|
+
.headerFormatter(function(d, i) {
|
9660
|
+
return xAxis.tickFormat()(d, i);
|
9661
|
+
})
|
9356
9662
|
.valueFormatter(function(d, i) {
|
9357
9663
|
return yaxis.tickFormat()(d, i);
|
9358
9664
|
})
|
@@ -9371,6 +9677,9 @@ nv.models.multiChart = function() {
|
|
9371
9677
|
};
|
9372
9678
|
tooltip
|
9373
9679
|
.duration(0)
|
9680
|
+
.headerFormatter(function(d, i) {
|
9681
|
+
return xAxis.tickFormat()(d, i);
|
9682
|
+
})
|
9374
9683
|
.valueFormatter(function(d, i) {
|
9375
9684
|
return yaxis.tickFormat()(d, i);
|
9376
9685
|
})
|
@@ -9433,6 +9742,9 @@ nv.models.multiChart = function() {
|
|
9433
9742
|
|
9434
9743
|
interactiveLayer.tooltip
|
9435
9744
|
.chartContainer(chart.container.parentNode)
|
9745
|
+
.headerFormatter(function(d, i) {
|
9746
|
+
return xAxis.tickFormat()(d, i);
|
9747
|
+
})
|
9436
9748
|
.valueFormatter(function(d,i) {
|
9437
9749
|
var yAxis = allData[i].yAxis;
|
9438
9750
|
return d === null ? "N/A" : yAxis.tickFormat()(d);
|
@@ -9835,8 +10147,11 @@ nv.models.parallelCoordinates = function() {
|
|
9835
10147
|
var margin = {top: 30, right: 0, bottom: 10, left: 0}
|
9836
10148
|
, width = null
|
9837
10149
|
, height = null
|
10150
|
+
, availableWidth = null
|
10151
|
+
, availableHeight = null
|
9838
10152
|
, x = d3.scale.ordinal()
|
9839
10153
|
, y = {}
|
10154
|
+
, undefinedValuesLabel = "undefined values"
|
9840
10155
|
, dimensionData = []
|
9841
10156
|
, enabledDimensions = []
|
9842
10157
|
, dimensionNames = []
|
@@ -9859,19 +10174,17 @@ nv.models.parallelCoordinates = function() {
|
|
9859
10174
|
// Private Variables
|
9860
10175
|
//------------------------------------------------------------
|
9861
10176
|
|
9862
|
-
|
9863
10177
|
var renderWatch = nv.utils.renderWatch(dispatch);
|
9864
10178
|
|
9865
10179
|
function chart(selection) {
|
9866
10180
|
renderWatch.reset();
|
9867
10181
|
selection.each(function(data) {
|
9868
10182
|
var container = d3.select(this);
|
9869
|
-
|
9870
|
-
|
10183
|
+
availableWidth = nv.utils.availableWidth(width, container, margin);
|
10184
|
+
availableHeight = nv.utils.availableHeight(height, container, margin);
|
9871
10185
|
|
9872
10186
|
nv.utils.initSVG(container);
|
9873
10187
|
|
9874
|
-
|
9875
10188
|
//Convert old data to new format (name, values)
|
9876
10189
|
if (data[0].values === undefined) {
|
9877
10190
|
var newData = [];
|
@@ -9892,7 +10205,6 @@ nv.models.parallelCoordinates = function() {
|
|
9892
10205
|
dimensionNames = dimensionData.sort(function (a, b) { return a.currentPosition - b.currentPosition; }).map(function (d) { return d.key });
|
9893
10206
|
enabledDimensions = dimensionData.filter(function (d) { return !d.disabled; });
|
9894
10207
|
|
9895
|
-
|
9896
10208
|
// Setup Scales
|
9897
10209
|
x.rangePoints([0, availableWidth], 1).domain(enabledDimensions.map(function (d) { return d.key; }));
|
9898
10210
|
|
@@ -9900,7 +10212,8 @@ nv.models.parallelCoordinates = function() {
|
|
9900
10212
|
// Extract the list of dimensions and create a scale for each.
|
9901
10213
|
var oldDomainMaxValue = {};
|
9902
10214
|
var displayMissingValuesline = false;
|
9903
|
-
|
10215
|
+
var currentTicks = [];
|
10216
|
+
|
9904
10217
|
dimensionNames.forEach(function(d) {
|
9905
10218
|
var extent = d3.extent(dataValues, function (p) { return +p[d]; });
|
9906
10219
|
var min = extent[0];
|
@@ -9943,7 +10256,6 @@ nv.models.parallelCoordinates = function() {
|
|
9943
10256
|
.range([(availableHeight - 12) * 0.9, 0]);
|
9944
10257
|
|
9945
10258
|
axisWithUndefinedValues = [];
|
9946
|
-
|
9947
10259
|
y[d].brush = d3.svg.brush().y(y[d]).on('brushstart', brushstart).on('brush', brush).on('brushend', brushend);
|
9948
10260
|
});
|
9949
10261
|
|
@@ -9980,8 +10292,8 @@ nv.models.parallelCoordinates = function() {
|
|
9980
10292
|
.attr("y2", function(d) { return d[3]; });
|
9981
10293
|
|
9982
10294
|
//Add the text "undefined values" under the missing value line
|
9983
|
-
missingValueslineText = wrap.select('.missingValuesline').selectAll('text').data([
|
9984
|
-
missingValueslineText.append('text').data([
|
10295
|
+
missingValueslineText = wrap.select('.missingValuesline').selectAll('text').data([undefinedValuesLabel]);
|
10296
|
+
missingValueslineText.append('text').data([undefinedValuesLabel]);
|
9985
10297
|
missingValueslineText.enter().append('text');
|
9986
10298
|
missingValueslineText.exit().remove();
|
9987
10299
|
missingValueslineText.attr("y", availableHeight)
|
@@ -10007,7 +10319,9 @@ nv.models.parallelCoordinates = function() {
|
|
10007
10319
|
d3.select(this).classed('hover', true).style("stroke-width", d.strokeWidth + 2 + "px").style("stroke-opacity", 1);
|
10008
10320
|
dispatch.elementMouseover({
|
10009
10321
|
label: d.name,
|
10010
|
-
color: d.color || color(d, i)
|
10322
|
+
color: d.color || color(d, i),
|
10323
|
+
values: d.values,
|
10324
|
+
dimensions: enabledDimensions
|
10011
10325
|
});
|
10012
10326
|
|
10013
10327
|
});
|
@@ -10035,13 +10349,14 @@ nv.models.parallelCoordinates = function() {
|
|
10035
10349
|
|
10036
10350
|
// Add an axis and title.
|
10037
10351
|
dimensionsEnter.append('text')
|
10038
|
-
|
10352
|
+
.attr('class', 'nv-label')
|
10039
10353
|
.style("cursor", "move")
|
10040
10354
|
.attr('dy', '-1em')
|
10041
10355
|
.attr('text-anchor', 'middle')
|
10042
10356
|
.on("mouseover", function(d, i) {
|
10043
10357
|
dispatch.elementMouseover({
|
10044
|
-
label: d.tooltip || d.key
|
10358
|
+
label: d.tooltip || d.key,
|
10359
|
+
color: d.color
|
10045
10360
|
});
|
10046
10361
|
})
|
10047
10362
|
.on("mouseout", function(d, i) {
|
@@ -10057,10 +10372,6 @@ nv.models.parallelCoordinates = function() {
|
|
10057
10372
|
dimensionsEnter.append('g').attr('class', 'nv-brushBackground');
|
10058
10373
|
dimensions.exit().remove();
|
10059
10374
|
dimensions.select('.nv-label').text(function (d) { return d.key });
|
10060
|
-
dimensions.select('.nv-axis')
|
10061
|
-
.each(function (d, i) {
|
10062
|
-
d3.select(this).call(axis.scale(y[d.key]).tickFormat(d3.format(d.format)));
|
10063
|
-
});
|
10064
10375
|
|
10065
10376
|
// Add and store a brush for each axis.
|
10066
10377
|
restoreBrush(displayBrush);
|
@@ -10138,27 +10449,30 @@ nv.models.parallelCoordinates = function() {
|
|
10138
10449
|
});
|
10139
10450
|
|
10140
10451
|
dimensions.select('.nv-brushBackground')
|
10141
|
-
|
10142
|
-
|
10452
|
+
.each(function (d) {
|
10453
|
+
d3.select(this).call(y[d.key].brush);
|
10143
10454
|
|
10144
|
-
|
10145
|
-
|
10146
|
-
|
10147
|
-
|
10455
|
+
})
|
10456
|
+
.selectAll('rect')
|
10457
|
+
.attr('x', -8)
|
10458
|
+
.attr('width', 16);
|
10459
|
+
|
10460
|
+
updateTicks();
|
10148
10461
|
}
|
10149
10462
|
|
10150
10463
|
// Handles a brush event, toggling the display of foreground lines.
|
10151
10464
|
function brushstart() {
|
10152
10465
|
//If brush aren't visible, show it before brushing again.
|
10153
10466
|
if (displayBrush === false) {
|
10467
|
+
displayBrush = true;
|
10154
10468
|
restoreBrush(true);
|
10155
10469
|
}
|
10156
10470
|
}
|
10157
10471
|
|
10158
10472
|
// Handles a brush event, toggling the display of foreground lines.
|
10159
10473
|
function brush() {
|
10160
|
-
actives = dimensionNames.filter(function (p) { return !y[p].brush.empty(); })
|
10161
|
-
|
10474
|
+
actives = dimensionNames.filter(function (p) { return !y[p].brush.empty(); });
|
10475
|
+
extents = actives.map(function(p) { return y[p].brush.extent(); });
|
10162
10476
|
|
10163
10477
|
filters = []; //erase current filters
|
10164
10478
|
actives.forEach(function(d,i) {
|
@@ -10179,7 +10493,9 @@ nv.models.parallelCoordinates = function() {
|
|
10179
10493
|
if (isActive) active.push(d);
|
10180
10494
|
return isActive ? null : 'none';
|
10181
10495
|
});
|
10182
|
-
|
10496
|
+
|
10497
|
+
updateTicks();
|
10498
|
+
|
10183
10499
|
dispatch.brush({
|
10184
10500
|
filters: filters,
|
10185
10501
|
active: active
|
@@ -10194,13 +10510,30 @@ nv.models.parallelCoordinates = function() {
|
|
10194
10510
|
f.hasOnlyNaN = true;
|
10195
10511
|
});
|
10196
10512
|
dispatch.brushEnd(active, hasActiveBrush);
|
10513
|
+
}
|
10514
|
+
function updateTicks() {
|
10515
|
+
dimensions.select('.nv-axis')
|
10516
|
+
.each(function (d, i) {
|
10517
|
+
var f = filters.filter(function (k) { return k.dimension == d.key; });
|
10518
|
+
currentTicks[d.key] = y[d.key].domain();
|
10519
|
+
|
10520
|
+
//If brush are available, display brush extent
|
10521
|
+
if (f.length != 0 && displayBrush)
|
10522
|
+
{
|
10523
|
+
currentTicks[d.key] = [];
|
10524
|
+
if (f[0].extent[1] > y[d.key].domain()[0])
|
10525
|
+
currentTicks[d.key] = [f[0].extent[1]];
|
10526
|
+
if (f[0].extent[0] >= y[d.key].domain()[0])
|
10527
|
+
currentTicks[d.key].push(f[0].extent[0]);
|
10528
|
+
}
|
10529
|
+
|
10530
|
+
d3.select(this).call(axis.scale(y[d.key]).tickFormat(d.format).tickValues(currentTicks[d.key]));
|
10531
|
+
});
|
10197
10532
|
}
|
10198
10533
|
function dragStart(d) {
|
10199
10534
|
dragging[d.key] = this.parentNode.__origin__ = x(d.key);
|
10200
10535
|
background.attr("visibility", "hidden");
|
10201
|
-
|
10202
10536
|
}
|
10203
|
-
|
10204
10537
|
function dragMove(d) {
|
10205
10538
|
dragging[d.key] = Math.min(availableWidth, Math.max(0, this.parentNode.__origin__ += d3.event.x));
|
10206
10539
|
foreground.attr("d", path);
|
@@ -10209,7 +10542,6 @@ nv.models.parallelCoordinates = function() {
|
|
10209
10542
|
x.domain(enabledDimensions.map(function (d) { return d.key; }));
|
10210
10543
|
dimensions.attr("transform", function(d) { return "translate(" + dimensionPosition(d.key) + ")"; });
|
10211
10544
|
}
|
10212
|
-
|
10213
10545
|
function dragEnd(d, i) {
|
10214
10546
|
delete this.parentNode.__origin__;
|
10215
10547
|
delete dragging[d.key];
|
@@ -10222,22 +10554,11 @@ nv.models.parallelCoordinates = function() {
|
|
10222
10554
|
|
10223
10555
|
dispatch.dimensionsOrder(enabledDimensions);
|
10224
10556
|
}
|
10225
|
-
function resetBrush() {
|
10226
|
-
filters = [];
|
10227
|
-
active = [];
|
10228
|
-
dispatch.stateChange();
|
10229
|
-
}
|
10230
|
-
function resetDrag() {
|
10231
|
-
dimensionName.map(function (d, i) { return d.currentPosition = d.originalPosition; });
|
10232
|
-
dispatch.stateChange();
|
10233
|
-
}
|
10234
|
-
|
10235
10557
|
function dimensionPosition(d) {
|
10236
10558
|
var v = dragging[d];
|
10237
10559
|
return v == null ? x(d) : v;
|
10238
10560
|
}
|
10239
10561
|
});
|
10240
|
-
|
10241
10562
|
return chart;
|
10242
10563
|
}
|
10243
10564
|
|
@@ -10257,7 +10578,8 @@ nv.models.parallelCoordinates = function() {
|
|
10257
10578
|
filters: { get: function () { return filters; }, set: function (_) { filters = _; } },
|
10258
10579
|
active: { get: function () { return active; }, set: function (_) { active = _; } },
|
10259
10580
|
lineTension: {get: function(){return lineTension;}, set: function(_){lineTension = _;}},
|
10260
|
-
|
10581
|
+
undefinedValuesLabel : {get: function(){return undefinedValuesLabel;}, set: function(_){undefinedValuesLabel=_;}},
|
10582
|
+
|
10261
10583
|
// deprecated options
|
10262
10584
|
dimensions: {get: function () { return dimensionData.map(function (d){return d.key}); }, set: function (_) {
|
10263
10585
|
// deprecated after 1.8.1
|
@@ -10267,8 +10589,7 @@ nv.models.parallelCoordinates = function() {
|
|
10267
10589
|
} else {
|
10268
10590
|
_.forEach(function (k, i) { dimensionData[i].key= k })
|
10269
10591
|
}
|
10270
|
-
}
|
10271
|
-
},
|
10592
|
+
}},
|
10272
10593
|
dimensionNames: {get: function () { return dimensionData.map(function (d){return d.key}); }, set: function (_) {
|
10273
10594
|
// deprecated after 1.8.1
|
10274
10595
|
nv.deprecated('dimensionNames', 'use dimensionData instead');
|
@@ -10290,7 +10611,6 @@ nv.models.parallelCoordinates = function() {
|
|
10290
10611
|
}
|
10291
10612
|
|
10292
10613
|
}},
|
10293
|
-
|
10294
10614
|
// options that require extra logic in the setter
|
10295
10615
|
margin: {get: function(){return margin;}, set: function(_){
|
10296
10616
|
margin.top = _.top !== undefined ? _.top : margin.top;
|
@@ -10302,7 +10622,6 @@ nv.models.parallelCoordinates = function() {
|
|
10302
10622
|
color = nv.utils.getColor(_);
|
10303
10623
|
}}
|
10304
10624
|
});
|
10305
|
-
|
10306
10625
|
nv.utils.initOptions(chart);
|
10307
10626
|
return chart;
|
10308
10627
|
};
|
@@ -10324,10 +10643,10 @@ nv.models.parallelCoordinatesChart = function () {
|
|
10324
10643
|
, color = nv.utils.defaultColor()
|
10325
10644
|
, state = nv.utils.state()
|
10326
10645
|
, dimensionData = []
|
10327
|
-
, dimensionNames = []
|
10328
10646
|
, displayBrush = true
|
10329
10647
|
, defaultState = null
|
10330
10648
|
, noData = null
|
10649
|
+
, nanValue = "undefined"
|
10331
10650
|
, dispatch = d3.dispatch('dimensionsOrder', 'brushEnd', 'stateChange', 'changeState', 'renderEnd')
|
10332
10651
|
, controlWidth = function () { return showControls ? 180 : 0 }
|
10333
10652
|
;
|
@@ -10358,6 +10677,20 @@ nv.models.parallelCoordinatesChart = function () {
|
|
10358
10677
|
}
|
10359
10678
|
};
|
10360
10679
|
|
10680
|
+
tooltip.contentGenerator(function(data) {
|
10681
|
+
var str = '<table><thead><tr><td class="legend-color-guide"><div style="background-color:' + data.color + '"></div></td><td><strong>' + data.key + '</strong></td></tr></thead>';
|
10682
|
+
if(data.series.length !== 0)
|
10683
|
+
{
|
10684
|
+
str = str + '<tbody><tr><td height ="10px"></td></tr>';
|
10685
|
+
data.series.forEach(function(d){
|
10686
|
+
str = str + '<tr><td class="legend-color-guide"><div style="background-color:' + d.color + '"></div></td><td class="key">' + d.key + '</td><td class="value">' + d.value + '</td></tr>';
|
10687
|
+
});
|
10688
|
+
str = str + '</tbody>';
|
10689
|
+
}
|
10690
|
+
str = str + '</table>';
|
10691
|
+
return str;
|
10692
|
+
});
|
10693
|
+
|
10361
10694
|
//============================================================
|
10362
10695
|
// Chart function
|
10363
10696
|
//------------------------------------------------------------
|
@@ -10392,21 +10725,6 @@ nv.models.parallelCoordinatesChart = function () {
|
|
10392
10725
|
d.currentPosition = isNaN(d.currentPosition) ? i : d.currentPosition;
|
10393
10726
|
});
|
10394
10727
|
|
10395
|
-
var currentDimensions = dimensionNames.map(function (d) { return d.key; });
|
10396
|
-
var newDimensions = dimensionData.map(function (d) { return d.key; });
|
10397
|
-
dimensionData.forEach(function (k, i) {
|
10398
|
-
var idx = currentDimensions.indexOf(k.key);
|
10399
|
-
if (idx < 0) {
|
10400
|
-
dimensionNames.splice(i, 0, k);
|
10401
|
-
} else {
|
10402
|
-
var gap = dimensionNames[idx].currentPosition - dimensionNames[idx].originalPosition;
|
10403
|
-
dimensionNames[idx].originalPosition = k.originalPosition;
|
10404
|
-
dimensionNames[idx].currentPosition = k.originalPosition + gap;
|
10405
|
-
}
|
10406
|
-
});
|
10407
|
-
//Remove old dimensions
|
10408
|
-
dimensionNames = dimensionNames.filter(function (d) { return newDimensions.indexOf(d.key) >= 0; });
|
10409
|
-
|
10410
10728
|
if (!defaultState) {
|
10411
10729
|
var key;
|
10412
10730
|
defaultState = {};
|
@@ -10442,12 +10760,14 @@ nv.models.parallelCoordinatesChart = function () {
|
|
10442
10760
|
.attr("height", (availableHeight > 0) ? availableHeight : 0);
|
10443
10761
|
|
10444
10762
|
// Legend
|
10445
|
-
if (showLegend) {
|
10763
|
+
if (!showLegend) {
|
10764
|
+
g.select('.nv-legendWrap').selectAll('*').remove();
|
10765
|
+
} else {
|
10446
10766
|
legend.width(availableWidth)
|
10447
10767
|
.color(function (d) { return "rgb(188,190,192)"; });
|
10448
10768
|
|
10449
10769
|
g.select('.nv-legendWrap')
|
10450
|
-
.datum(
|
10770
|
+
.datum(dimensionData.sort(function (a, b) { return a.originalPosition - b.originalPosition; }))
|
10451
10771
|
.call(legend);
|
10452
10772
|
|
10453
10773
|
if (margin.top != legend.height()) {
|
@@ -10459,14 +10779,11 @@ nv.models.parallelCoordinatesChart = function () {
|
|
10459
10779
|
}
|
10460
10780
|
wrap.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');
|
10461
10781
|
|
10462
|
-
|
10463
|
-
|
10464
|
-
|
10465
10782
|
// Main Chart Component(s)
|
10466
10783
|
parallelCoordinates
|
10467
10784
|
.width(availableWidth)
|
10468
10785
|
.height(availableHeight)
|
10469
|
-
.dimensionData(
|
10786
|
+
.dimensionData(dimensionData)
|
10470
10787
|
.displayBrush(displayBrush);
|
10471
10788
|
|
10472
10789
|
var parallelCoordinatesWrap = g.select('.nv-parallelCoordinatesWrap ')
|
@@ -10498,21 +10815,21 @@ nv.models.parallelCoordinatesChart = function () {
|
|
10498
10815
|
|
10499
10816
|
//Update dimensions order and display reset sorting button
|
10500
10817
|
parallelCoordinates.dispatch.on('dimensionsOrder', function (e) {
|
10501
|
-
|
10818
|
+
dimensionData.sort(function (a, b) { return a.currentPosition - b.currentPosition; });
|
10502
10819
|
var isSorted = false;
|
10503
|
-
|
10820
|
+
dimensionData.forEach(function (d, i) {
|
10504
10821
|
d.currentPosition = i;
|
10505
10822
|
if (d.currentPosition !== d.originalPosition)
|
10506
10823
|
isSorted = true;
|
10507
10824
|
});
|
10508
|
-
dispatch.dimensionsOrder(
|
10825
|
+
dispatch.dimensionsOrder(dimensionData, isSorted);
|
10509
10826
|
});
|
10510
10827
|
|
10511
10828
|
// Update chart from a state object passed to event handler
|
10512
10829
|
dispatch.on('changeState', function (e) {
|
10513
10830
|
|
10514
10831
|
if (typeof e.disabled !== 'undefined') {
|
10515
|
-
|
10832
|
+
dimensionData.forEach(function (series, i) {
|
10516
10833
|
series.disabled = e.disabled[i];
|
10517
10834
|
});
|
10518
10835
|
state.disabled = e.disabled;
|
@@ -10530,11 +10847,27 @@ nv.models.parallelCoordinatesChart = function () {
|
|
10530
10847
|
//------------------------------------------------------------
|
10531
10848
|
|
10532
10849
|
parallelCoordinates.dispatch.on('elementMouseover.tooltip', function (evt) {
|
10533
|
-
|
10850
|
+
var tp = {
|
10534
10851
|
key: evt.label,
|
10535
|
-
color: evt.color
|
10536
|
-
|
10537
|
-
|
10852
|
+
color: evt.color,
|
10853
|
+
series: []
|
10854
|
+
}
|
10855
|
+
if(evt.values){
|
10856
|
+
Object.keys(evt.values).forEach(function (d) {
|
10857
|
+
var dim = evt.dimensions.filter(function (dd) {return dd.key === d;})[0];
|
10858
|
+
if(dim){
|
10859
|
+
var v;
|
10860
|
+
if (isNaN(evt.values[d]) || isNaN(parseFloat(evt.values[d]))) {
|
10861
|
+
v = nanValue;
|
10862
|
+
} else {
|
10863
|
+
v = dim.format(evt.values[d]);
|
10864
|
+
}
|
10865
|
+
tp.series.push({ idx: dim.currentPosition, key: d, value: v, color: dim.color });
|
10866
|
+
}
|
10867
|
+
});
|
10868
|
+
tp.series.sort(function(a,b) {return a.idx - b.idx});
|
10869
|
+
}
|
10870
|
+
tooltip.data(tp).hidden(false);
|
10538
10871
|
});
|
10539
10872
|
|
10540
10873
|
parallelCoordinates.dispatch.on('elementMouseout.tooltip', function(evt) {
|
@@ -10553,7 +10886,6 @@ nv.models.parallelCoordinatesChart = function () {
|
|
10553
10886
|
chart.parallelCoordinates = parallelCoordinates;
|
10554
10887
|
chart.legend = legend;
|
10555
10888
|
chart.tooltip = tooltip;
|
10556
|
-
|
10557
10889
|
chart.options = nv.utils.optionsFunc.bind(chart);
|
10558
10890
|
|
10559
10891
|
chart._options = Object.create({}, {
|
@@ -10565,7 +10897,8 @@ nv.models.parallelCoordinatesChart = function () {
|
|
10565
10897
|
dimensionData: { get: function () { return dimensionData; }, set: function (_) { dimensionData = _; } },
|
10566
10898
|
displayBrush: { get: function () { return displayBrush; }, set: function (_) { displayBrush = _; } },
|
10567
10899
|
noData: { get: function () { return noData; }, set: function (_) { noData = _; } },
|
10568
|
-
|
10900
|
+
nanValue: { get: function () { return nanValue; }, set: function (_) { nanValue = _; } },
|
10901
|
+
|
10569
10902
|
// options that require extra logic in the setter
|
10570
10903
|
margin: {
|
10571
10904
|
get: function () { return margin; },
|
@@ -10587,7 +10920,8 @@ nv.models.parallelCoordinatesChart = function () {
|
|
10587
10920
|
nv.utils.initOptions(chart);
|
10588
10921
|
|
10589
10922
|
return chart;
|
10590
|
-
};
|
10923
|
+
};
|
10924
|
+
nv.models.pie = function() {
|
10591
10925
|
"use strict";
|
10592
10926
|
|
10593
10927
|
//============================================================
|
@@ -10649,9 +10983,15 @@ nv.models.parallelCoordinatesChart = function () {
|
|
10649
10983
|
arcsRadiusInner.push(inner);
|
10650
10984
|
}
|
10651
10985
|
} else {
|
10652
|
-
|
10653
|
-
|
10654
|
-
|
10986
|
+
if(growOnHover){
|
10987
|
+
arcsRadiusOuter = arcsRadius.map(function (d) { return (d.outer - d.outer / 5) * radius; });
|
10988
|
+
arcsRadiusInner = arcsRadius.map(function (d) { return (d.inner - d.inner / 5) * radius; });
|
10989
|
+
donutRatio = d3.min(arcsRadius.map(function (d) { return (d.inner - d.inner / 5); }));
|
10990
|
+
} else {
|
10991
|
+
arcsRadiusOuter = arcsRadius.map(function (d) { return d.outer * radius; });
|
10992
|
+
arcsRadiusInner = arcsRadius.map(function (d) { return d.inner * radius; });
|
10993
|
+
donutRatio = d3.min(arcsRadius.map(function (d) { return d.inner; }));
|
10994
|
+
}
|
10655
10995
|
}
|
10656
10996
|
nv.utils.initSVG(container);
|
10657
10997
|
|
@@ -11119,7 +11459,9 @@ nv.models.pieChart = function() {
|
|
11119
11459
|
gEnter.append('g').attr('class', 'nv-legendWrap');
|
11120
11460
|
|
11121
11461
|
// Legend
|
11122
|
-
if (showLegend) {
|
11462
|
+
if (!showLegend) {
|
11463
|
+
g.select('.nv-legendWrap').selectAll('*').remove();
|
11464
|
+
} else {
|
11123
11465
|
if (legendPosition === "top") {
|
11124
11466
|
legend.width( availableWidth ).key(pie.x());
|
11125
11467
|
|
@@ -11219,6 +11561,8 @@ nv.models.pieChart = function() {
|
|
11219
11561
|
// use Object get/set functionality to map between vars and chart functions
|
11220
11562
|
chart._options = Object.create({}, {
|
11221
11563
|
// simple options, just get/set the necessary values
|
11564
|
+
width: {get: function(){return width;}, set: function(_){width=_;}},
|
11565
|
+
height: {get: function(){return height;}, set: function(_){height=_;}},
|
11222
11566
|
noData: {get: function(){return noData;}, set: function(_){noData=_;}},
|
11223
11567
|
showLegend: {get: function(){return showLegend;}, set: function(_){showLegend=_;}},
|
11224
11568
|
legendPosition: {get: function(){return legendPosition;}, set: function(_){legendPosition=_;}},
|
@@ -11288,6 +11632,7 @@ nv.models.scatter = function() {
|
|
11288
11632
|
, useVoronoi = true
|
11289
11633
|
, duration = 250
|
11290
11634
|
, interactiveUpdateDelay = 300
|
11635
|
+
, showLabels = false
|
11291
11636
|
;
|
11292
11637
|
|
11293
11638
|
|
@@ -11300,8 +11645,34 @@ nv.models.scatter = function() {
|
|
11300
11645
|
, needsUpdate = false // Flag for when the points are visually updating, but the interactive layer is behind, to disable tooltips
|
11301
11646
|
, renderWatch = nv.utils.renderWatch(dispatch, duration)
|
11302
11647
|
, _sizeRange_def = [16, 256]
|
11648
|
+
, _caches
|
11303
11649
|
;
|
11304
11650
|
|
11651
|
+
function getCache(d) {
|
11652
|
+
var cache, i;
|
11653
|
+
cache = _caches = _caches || {};
|
11654
|
+
i = d[0].series;
|
11655
|
+
cache = cache[i] = cache[i] || {};
|
11656
|
+
i = d[1];
|
11657
|
+
cache = cache[i] = cache[i] || {};
|
11658
|
+
return cache;
|
11659
|
+
}
|
11660
|
+
|
11661
|
+
function getDiffs(d) {
|
11662
|
+
var i, key,
|
11663
|
+
point = d[0],
|
11664
|
+
cache = getCache(d),
|
11665
|
+
diffs = false;
|
11666
|
+
for (i = 1; i < arguments.length; i ++) {
|
11667
|
+
key = arguments[i];
|
11668
|
+
if (cache[key] !== point[key] || !cache.hasOwnProperty(key)) {
|
11669
|
+
cache[key] = point[key];
|
11670
|
+
diffs = true;
|
11671
|
+
}
|
11672
|
+
}
|
11673
|
+
return diffs;
|
11674
|
+
}
|
11675
|
+
|
11305
11676
|
function chart(selection) {
|
11306
11677
|
renderWatch.reset();
|
11307
11678
|
selection.each(function(data) {
|
@@ -11319,6 +11690,7 @@ nv.models.scatter = function() {
|
|
11319
11690
|
});
|
11320
11691
|
|
11321
11692
|
// Setup Scales
|
11693
|
+
var logScale = chart.yScale().name === d3.scale.log().name ? true : false;
|
11322
11694
|
// remap and flatten the data for use in calculating the scales' domains
|
11323
11695
|
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
|
11324
11696
|
d3.merge(
|
@@ -11337,7 +11709,7 @@ nv.models.scatter = function() {
|
|
11337
11709
|
else
|
11338
11710
|
x.range(xRange || [0, availableWidth]);
|
11339
11711
|
|
11340
|
-
if (
|
11712
|
+
if (logScale) {
|
11341
11713
|
var min = d3.min(seriesData.map(function(d) { if (d.y !== 0) return d.y; }));
|
11342
11714
|
y.clamp(true)
|
11343
11715
|
.domain(yDomain || d3.extent(seriesData.map(function(d) {
|
@@ -11378,6 +11750,8 @@ nv.models.scatter = function() {
|
|
11378
11750
|
y0 = y0 || y;
|
11379
11751
|
z0 = z0 || z;
|
11380
11752
|
|
11753
|
+
var scaleDiff = x(1) !== x0(1) || y(1) !== y0(1) || z(1) !== z0(1);
|
11754
|
+
|
11381
11755
|
// Setup containers and skeleton of chart
|
11382
11756
|
var wrap = container.selectAll('g.nv-wrap.nv-scatter').data([data]);
|
11383
11757
|
var wrapEnter = wrap.enter().append('g').attr('class', 'nvd3 nv-wrap nv-scatter nv-chart-' + id);
|
@@ -11421,8 +11795,8 @@ nv.models.scatter = function() {
|
|
11421
11795
|
var pX = getX(point,pointIndex);
|
11422
11796
|
var pY = getY(point,pointIndex);
|
11423
11797
|
|
11424
|
-
return [x(pX)+ Math.random() * 1e-4,
|
11425
|
-
y(pY)+ Math.random() * 1e-4,
|
11798
|
+
return [nv.utils.NaNtoZero(x(pX))+ Math.random() * 1e-4,
|
11799
|
+
nv.utils.NaNtoZero(y(pY))+ Math.random() * 1e-4,
|
11426
11800
|
groupIndex,
|
11427
11801
|
pointIndex, point]; //temp hack to add noise until I think of a better way so there are no duplicates
|
11428
11802
|
})
|
@@ -11621,6 +11995,7 @@ nv.models.scatter = function() {
|
|
11621
11995
|
.attr('class', function(d,i) {
|
11622
11996
|
return (d.classed || '') + ' nv-group nv-series-' + i;
|
11623
11997
|
})
|
11998
|
+
.classed('nv-noninteractive', !interactive)
|
11624
11999
|
.classed('hover', function(d) { return d.hover });
|
11625
12000
|
groups.watchTransition(renderWatch, 'scatter: groups')
|
11626
12001
|
.style('fill', function(d,i) { return color(d, i) })
|
@@ -11640,6 +12015,9 @@ nv.models.scatter = function() {
|
|
11640
12015
|
})
|
11641
12016
|
});
|
11642
12017
|
points.enter().append('path')
|
12018
|
+
.attr('class', function (d) {
|
12019
|
+
return 'nv-point nv-point-' + d[1];
|
12020
|
+
})
|
11643
12021
|
.style('fill', function (d) { return d.color })
|
11644
12022
|
.style('stroke', function (d) { return d.color })
|
11645
12023
|
.attr('transform', function(d) {
|
@@ -11657,25 +12035,66 @@ nv.models.scatter = function() {
|
|
11657
12035
|
return 'translate(' + nv.utils.NaNtoZero(x(getX(d[0],d[1]))) + ',' + nv.utils.NaNtoZero(y(getY(d[0],d[1]))) + ')'
|
11658
12036
|
})
|
11659
12037
|
.remove();
|
11660
|
-
points.
|
11661
|
-
d3.select(this)
|
11662
|
-
.classed('nv-point', true)
|
11663
|
-
.classed('nv-point-' + d[1], true)
|
11664
|
-
.classed('nv-noninteractive', !interactive)
|
11665
|
-
.classed('hover',false)
|
11666
|
-
;
|
11667
|
-
});
|
11668
|
-
points
|
12038
|
+
points.filter(function (d) { return scaleDiff || getDiffs(d, 'x', 'y'); })
|
11669
12039
|
.watchTransition(renderWatch, 'scatter points')
|
11670
12040
|
.attr('transform', function(d) {
|
11671
12041
|
//nv.log(d, getX(d[0],d[1]), x(getX(d[0],d[1])));
|
11672
12042
|
return 'translate(' + nv.utils.NaNtoZero(x(getX(d[0],d[1]))) + ',' + nv.utils.NaNtoZero(y(getY(d[0],d[1]))) + ')'
|
11673
|
-
})
|
12043
|
+
});
|
12044
|
+
points.filter(function (d) { return scaleDiff || getDiffs(d, 'shape', 'size'); })
|
12045
|
+
.watchTransition(renderWatch, 'scatter points')
|
11674
12046
|
.attr('d',
|
11675
12047
|
nv.utils.symbol()
|
11676
12048
|
.type(function(d) { return getShape(d[0]); })
|
11677
12049
|
.size(function(d) { return z(getSize(d[0],d[1])) })
|
11678
12050
|
);
|
12051
|
+
|
12052
|
+
// add label a label to scatter chart
|
12053
|
+
if(showLabels)
|
12054
|
+
{
|
12055
|
+
var titles = groups.selectAll('.nv-label')
|
12056
|
+
.data(function(d) {
|
12057
|
+
return d.values.map(
|
12058
|
+
function (point, pointIndex) {
|
12059
|
+
return [point, pointIndex]
|
12060
|
+
}).filter(
|
12061
|
+
function(pointArray, pointIndex) {
|
12062
|
+
return pointActive(pointArray[0], pointIndex)
|
12063
|
+
})
|
12064
|
+
});
|
12065
|
+
|
12066
|
+
titles.enter().append('text')
|
12067
|
+
.style('fill', function (d,i) {
|
12068
|
+
return d.color })
|
12069
|
+
.style('stroke-opacity', 0)
|
12070
|
+
.style('fill-opacity', 1)
|
12071
|
+
.attr('transform', function(d) {
|
12072
|
+
var dx = nv.utils.NaNtoZero(x0(getX(d[0],d[1]))) + Math.sqrt(z(getSize(d[0],d[1]))/Math.PI) + 2;
|
12073
|
+
return 'translate(' + dx + ',' + nv.utils.NaNtoZero(y0(getY(d[0],d[1]))) + ')';
|
12074
|
+
})
|
12075
|
+
.text(function(d,i){
|
12076
|
+
return d[0].label;});
|
12077
|
+
|
12078
|
+
titles.exit().remove();
|
12079
|
+
groups.exit().selectAll('path.nv-label')
|
12080
|
+
.watchTransition(renderWatch, 'scatter exit')
|
12081
|
+
.attr('transform', function(d) {
|
12082
|
+
var dx = nv.utils.NaNtoZero(x(getX(d[0],d[1])))+ Math.sqrt(z(getSize(d[0],d[1]))/Math.PI)+2;
|
12083
|
+
return 'translate(' + dx + ',' + nv.utils.NaNtoZero(y(getY(d[0],d[1]))) + ')';
|
12084
|
+
})
|
12085
|
+
.remove();
|
12086
|
+
titles.each(function(d) {
|
12087
|
+
d3.select(this)
|
12088
|
+
.classed('nv-label', true)
|
12089
|
+
.classed('nv-label-' + d[1], false)
|
12090
|
+
.classed('hover',false);
|
12091
|
+
});
|
12092
|
+
titles.watchTransition(renderWatch, 'scatter labels')
|
12093
|
+
.attr('transform', function(d) {
|
12094
|
+
var dx = nv.utils.NaNtoZero(x(getX(d[0],d[1])))+ Math.sqrt(z(getSize(d[0],d[1]))/Math.PI)+2;
|
12095
|
+
return 'translate(' + dx + ',' + nv.utils.NaNtoZero(y(getY(d[0],d[1]))) + ')'
|
12096
|
+
});
|
12097
|
+
}
|
11679
12098
|
|
11680
12099
|
// Delay updating the invisible interactive layer for smoother animation
|
11681
12100
|
if( interactiveUpdateDelay )
|
@@ -11758,7 +12177,7 @@ nv.models.scatter = function() {
|
|
11758
12177
|
showVoronoi: {get: function(){return showVoronoi;}, set: function(_){showVoronoi=_;}},
|
11759
12178
|
id: {get: function(){return id;}, set: function(_){id=_;}},
|
11760
12179
|
interactiveUpdateDelay: {get:function(){return interactiveUpdateDelay;}, set: function(_){interactiveUpdateDelay=_;}},
|
11761
|
-
|
12180
|
+
showLabels: {get: function(){return showLabels;}, set: function(_){ showLabels = _;}},
|
11762
12181
|
|
11763
12182
|
// simple functor options
|
11764
12183
|
x: {get: function(){return getX;}, set: function(_){getX = d3.functor(_);}},
|
@@ -11826,6 +12245,7 @@ nv.models.scatterChart = function() {
|
|
11826
12245
|
, dispatch = d3.dispatch('stateChange', 'changeState', 'renderEnd')
|
11827
12246
|
, noData = null
|
11828
12247
|
, duration = 250
|
12248
|
+
, showLabels = false
|
11829
12249
|
;
|
11830
12250
|
|
11831
12251
|
scatter.xScale(x).yScale(y);
|
@@ -11947,7 +12367,9 @@ nv.models.scatterChart = function() {
|
|
11947
12367
|
}
|
11948
12368
|
|
11949
12369
|
// Legend
|
11950
|
-
if (showLegend) {
|
12370
|
+
if (!showLegend) {
|
12371
|
+
g.select('.nv-legendWrap').selectAll('*').remove();
|
12372
|
+
} else {
|
11951
12373
|
var legendWidth = availableWidth;
|
11952
12374
|
legend.width(legendWidth);
|
11953
12375
|
|
@@ -11973,7 +12395,8 @@ nv.models.scatterChart = function() {
|
|
11973
12395
|
.color(data.map(function(d,i) {
|
11974
12396
|
d.color = d.color || color(d, i);
|
11975
12397
|
return d.color;
|
11976
|
-
}).filter(function(d,i) { return !data[i].disabled }))
|
12398
|
+
}).filter(function(d,i) { return !data[i].disabled }))
|
12399
|
+
.showLabels(showLabels);
|
11977
12400
|
|
11978
12401
|
wrap.select('.nv-scatterWrap')
|
11979
12402
|
.datum(data.filter(function(d) { return !d.disabled }))
|
@@ -12151,6 +12574,7 @@ nv.models.scatterChart = function() {
|
|
12151
12574
|
defaultState: {get: function(){return defaultState;}, set: function(_){defaultState=_;}},
|
12152
12575
|
noData: {get: function(){return noData;}, set: function(_){noData=_;}},
|
12153
12576
|
duration: {get: function(){return duration;}, set: function(_){duration=_;}},
|
12577
|
+
showLabels: {get: function(){return showLabels;}, set: function(_){showLabels=_;}},
|
12154
12578
|
|
12155
12579
|
// options that require extra logic in the setter
|
12156
12580
|
margin: {get: function(){return margin;}, set: function(_){
|
@@ -12197,6 +12621,8 @@ nv.models.sparkline = function() {
|
|
12197
12621
|
, yDomain
|
12198
12622
|
, xRange
|
12199
12623
|
, yRange
|
12624
|
+
, showMinMaxPoints = true
|
12625
|
+
, showCurrentPoint = true
|
12200
12626
|
, dispatch = d3.dispatch('renderEnd')
|
12201
12627
|
;
|
12202
12628
|
|
@@ -12257,7 +12683,7 @@ nv.models.sparkline = function() {
|
|
12257
12683
|
var maxPoint = pointIndex(yValues.lastIndexOf(y.domain()[1])),
|
12258
12684
|
minPoint = pointIndex(yValues.indexOf(y.domain()[0])),
|
12259
12685
|
currentPoint = pointIndex(yValues.length - 1);
|
12260
|
-
return [minPoint, maxPoint, currentPoint].filter(function (d) {return d != null;});
|
12686
|
+
return [(showMinMaxPoints ? minPoint : null), (showMinMaxPoints ? maxPoint : null), (showCurrentPoint ? currentPoint : null)].filter(function (d) {return d != null;});
|
12261
12687
|
});
|
12262
12688
|
points.enter().append('circle');
|
12263
12689
|
points.exit().remove();
|
@@ -12283,15 +12709,17 @@ nv.models.sparkline = function() {
|
|
12283
12709
|
|
12284
12710
|
chart._options = Object.create({}, {
|
12285
12711
|
// simple options, just get/set the necessary values
|
12286
|
-
width:
|
12287
|
-
height:
|
12288
|
-
xDomain:
|
12289
|
-
yDomain:
|
12290
|
-
xRange:
|
12291
|
-
yRange:
|
12292
|
-
xScale:
|
12293
|
-
yScale:
|
12294
|
-
animate:
|
12712
|
+
width: {get: function(){return width;}, set: function(_){width=_;}},
|
12713
|
+
height: {get: function(){return height;}, set: function(_){height=_;}},
|
12714
|
+
xDomain: {get: function(){return xDomain;}, set: function(_){xDomain=_;}},
|
12715
|
+
yDomain: {get: function(){return yDomain;}, set: function(_){yDomain=_;}},
|
12716
|
+
xRange: {get: function(){return xRange;}, set: function(_){xRange=_;}},
|
12717
|
+
yRange: {get: function(){return yRange;}, set: function(_){yRange=_;}},
|
12718
|
+
xScale: {get: function(){return x;}, set: function(_){x=_;}},
|
12719
|
+
yScale: {get: function(){return y;}, set: function(_){y=_;}},
|
12720
|
+
animate: {get: function(){return animate;}, set: function(_){animate=_;}},
|
12721
|
+
showMinMaxPoints: {get: function(){return showMinMaxPoints;}, set: function(_){showMinMaxPoints=_;}},
|
12722
|
+
showCurrentPoint: {get: function(){return showCurrentPoint;}, set: function(_){showCurrentPoint=_;}},
|
12295
12723
|
|
12296
12724
|
//functor options
|
12297
12725
|
x: {get: function(){return getX;}, set: function(_){getX=d3.functor(_);}},
|
@@ -12646,7 +13074,6 @@ nv.models.stackedArea = function() {
|
|
12646
13074
|
.y(function(d) {
|
12647
13075
|
if (d.display !== undefined) { return d.display.y + d.display.y0; }
|
12648
13076
|
})
|
12649
|
-
.forceY([0])
|
12650
13077
|
.color(data.map(function(d,i) {
|
12651
13078
|
d.color = d.color || color(d, d.seriesIndex);
|
12652
13079
|
return d.color;
|
@@ -13021,7 +13448,9 @@ nv.models.stackedAreaChart = function() {
|
|
13021
13448
|
g.select("rect").attr("width",availableWidth).attr("height",availableHeight);
|
13022
13449
|
|
13023
13450
|
// Legend
|
13024
|
-
if (showLegend) {
|
13451
|
+
if (!showLegend) {
|
13452
|
+
g.select('.nv-legendWrap').selectAll('*').remove();
|
13453
|
+
} else {
|
13025
13454
|
var legendWidth = (showControls) ? availableWidth - controlWidth : availableWidth;
|
13026
13455
|
|
13027
13456
|
legend.width(legendWidth);
|
@@ -13037,7 +13466,9 @@ nv.models.stackedAreaChart = function() {
|
|
13037
13466
|
}
|
13038
13467
|
|
13039
13468
|
// Controls
|
13040
|
-
if (showControls) {
|
13469
|
+
if (!showControls) {
|
13470
|
+
g.select('.nv-controlsWrap').selectAll('*').remove();
|
13471
|
+
} else {
|
13041
13472
|
var controlsData = [
|
13042
13473
|
{
|
13043
13474
|
key: controlLabels.stacked || 'Stacked',
|
@@ -13231,7 +13662,7 @@ nv.models.stackedAreaChart = function() {
|
|
13231
13662
|
key: series.key,
|
13232
13663
|
value: tooltipValue,
|
13233
13664
|
color: color(series,series.seriesIndex),
|
13234
|
-
|
13665
|
+
point: point
|
13235
13666
|
});
|
13236
13667
|
|
13237
13668
|
if (showTotalInTooltip && stacked.style() != 'expand') {
|
@@ -13250,8 +13681,8 @@ nv.models.stackedAreaChart = function() {
|
|
13250
13681
|
//To handle situation where the stacked area chart is negative, we need to use absolute values
|
13251
13682
|
//when checking if the mouse Y value is within the stack area.
|
13252
13683
|
yValue = Math.abs(yValue);
|
13253
|
-
var stackedY0 = Math.abs(series.
|
13254
|
-
var stackedY = Math.abs(series.
|
13684
|
+
var stackedY0 = Math.abs(series.point.display.y0);
|
13685
|
+
var stackedY = Math.abs(series.point.display.y);
|
13255
13686
|
if ( yValue >= stackedY0 && yValue <= (stackedY + stackedY0))
|
13256
13687
|
{
|
13257
13688
|
indexToHighlight = i;
|
@@ -13423,70 +13854,208 @@ nv.models.sunburst = function() {
|
|
13423
13854
|
//------------------------------------------------------------
|
13424
13855
|
|
13425
13856
|
var margin = {top: 0, right: 0, bottom: 0, left: 0}
|
13426
|
-
, width =
|
13427
|
-
, height =
|
13857
|
+
, width = 600
|
13858
|
+
, height = 600
|
13428
13859
|
, mode = "count"
|
13429
|
-
, modes = {count: function(d) { return 1; }, size: function(d) { return d.size }}
|
13860
|
+
, modes = {count: function(d) { return 1; }, value: function(d) { return d.value || d.size }, size: function(d) { return d.value || d.size }}
|
13430
13861
|
, id = Math.floor(Math.random() * 10000) //Create semi-unique ID in case user doesn't select one
|
13431
13862
|
, container = null
|
13432
13863
|
, color = nv.utils.defaultColor()
|
13864
|
+
, showLabels = false
|
13865
|
+
, labelFormat = function(d){if(mode === 'count'){return d.name + ' #' + d.value}else{return d.name + ' ' + (d.value || d.size)}}
|
13866
|
+
, labelThreshold = 0.02
|
13867
|
+
, sort = function(d1, d2){return d1.name > d2.name;}
|
13868
|
+
, key = function(d,i){return d.name;}
|
13433
13869
|
, groupColorByParent = true
|
13434
13870
|
, duration = 500
|
13435
|
-
, dispatch = d3.dispatch('chartClick', 'elementClick', 'elementDblClick', 'elementMousemove', 'elementMouseover', 'elementMouseout', 'renderEnd')
|
13436
|
-
|
13871
|
+
, dispatch = d3.dispatch('chartClick', 'elementClick', 'elementDblClick', 'elementMousemove', 'elementMouseover', 'elementMouseout', 'renderEnd');
|
13872
|
+
|
13873
|
+
//============================================================
|
13874
|
+
// aux functions and setup
|
13875
|
+
//------------------------------------------------------------
|
13437
13876
|
|
13438
13877
|
var x = d3.scale.linear().range([0, 2 * Math.PI]);
|
13439
13878
|
var y = d3.scale.sqrt();
|
13440
13879
|
|
13441
|
-
var partition = d3.layout.partition()
|
13442
|
-
|
13443
|
-
|
13880
|
+
var partition = d3.layout.partition().sort(sort);
|
13881
|
+
|
13882
|
+
var node, availableWidth, availableHeight, radius;
|
13883
|
+
var prevPositions = {};
|
13444
13884
|
|
13445
13885
|
var arc = d3.svg.arc()
|
13446
|
-
.startAngle(function(d) {
|
13447
|
-
.endAngle(function(d) {
|
13448
|
-
.innerRadius(function(d) {
|
13449
|
-
.outerRadius(function(d) {
|
13886
|
+
.startAngle(function(d) {return Math.max(0, Math.min(2 * Math.PI, x(d.x))) })
|
13887
|
+
.endAngle(function(d) {return Math.max(0, Math.min(2 * Math.PI, x(d.x + d.dx))) })
|
13888
|
+
.innerRadius(function(d) {return Math.max(0, y(d.y)) })
|
13889
|
+
.outerRadius(function(d) {return Math.max(0, y(d.y + d.dy)) });
|
13890
|
+
|
13891
|
+
function rotationToAvoidUpsideDown(d) {
|
13892
|
+
var centerAngle = computeCenterAngle(d);
|
13893
|
+
if(centerAngle > 90){
|
13894
|
+
return 180;
|
13895
|
+
}
|
13896
|
+
else {
|
13897
|
+
return 0;
|
13898
|
+
}
|
13899
|
+
}
|
13900
|
+
|
13901
|
+
function computeCenterAngle(d) {
|
13902
|
+
var startAngle = Math.max(0, Math.min(2 * Math.PI, x(d.x)));
|
13903
|
+
var endAngle = Math.max(0, Math.min(2 * Math.PI, x(d.x + d.dx)));
|
13904
|
+
var centerAngle = (((startAngle + endAngle) / 2) * (180 / Math.PI)) - 90;
|
13905
|
+
return centerAngle;
|
13906
|
+
}
|
13907
|
+
|
13908
|
+
function labelThresholdMatched(d) {
|
13909
|
+
var startAngle = Math.max(0, Math.min(2 * Math.PI, x(d.x)));
|
13910
|
+
var endAngle = Math.max(0, Math.min(2 * Math.PI, x(d.x + d.dx)));
|
13911
|
+
|
13912
|
+
var size = endAngle - startAngle;
|
13913
|
+
return size > labelThreshold;
|
13914
|
+
}
|
13915
|
+
|
13916
|
+
// When zooming: interpolate the scales.
|
13917
|
+
function arcTweenZoom(e,i) {
|
13918
|
+
var xd = d3.interpolate(x.domain(), [node.x, node.x + node.dx]),
|
13919
|
+
yd = d3.interpolate(y.domain(), [node.y, 1]),
|
13920
|
+
yr = d3.interpolate(y.range(), [node.y ? 20 : 0, radius]);
|
13921
|
+
|
13922
|
+
if (i === 0) {
|
13923
|
+
return function() {return arc(e);}
|
13924
|
+
}
|
13925
|
+
else {
|
13926
|
+
return function (t) {
|
13927
|
+
x.domain(xd(t));
|
13928
|
+
y.domain(yd(t)).range(yr(t));
|
13929
|
+
return arc(e);
|
13930
|
+
}
|
13931
|
+
};
|
13932
|
+
}
|
13933
|
+
|
13934
|
+
function arcTweenUpdate(d) {
|
13935
|
+
var ipo = d3.interpolate({x: d.x0, dx: d.dx0, y: d.y0, dy: d.dy0}, d);
|
13936
|
+
|
13937
|
+
return function (t) {
|
13938
|
+
var b = ipo(t);
|
13939
|
+
|
13940
|
+
d.x0 = b.x;
|
13941
|
+
d.dx0 = b.dx;
|
13942
|
+
d.y0 = b.y;
|
13943
|
+
d.dy0 = b.dy;
|
13944
|
+
|
13945
|
+
return arc(b);
|
13946
|
+
};
|
13947
|
+
}
|
13948
|
+
|
13949
|
+
function updatePrevPosition(node) {
|
13950
|
+
var k = key(node);
|
13951
|
+
if(! prevPositions[k]) prevPositions[k] = {};
|
13952
|
+
var pP = prevPositions[k];
|
13953
|
+
pP.dx = node.dx;
|
13954
|
+
pP.x = node.x;
|
13955
|
+
pP.dy = node.dy;
|
13956
|
+
pP.y = node.y;
|
13957
|
+
}
|
13958
|
+
|
13959
|
+
function storeRetrievePrevPositions(nodes) {
|
13960
|
+
nodes.forEach(function(n){
|
13961
|
+
var k = key(n);
|
13962
|
+
var pP = prevPositions[k];
|
13963
|
+
//console.log(k,n,pP);
|
13964
|
+
if( pP ){
|
13965
|
+
n.dx0 = pP.dx;
|
13966
|
+
n.x0 = pP.x;
|
13967
|
+
n.dy0 = pP.dy;
|
13968
|
+
n.y0 = pP.y;
|
13969
|
+
}
|
13970
|
+
else {
|
13971
|
+
n.dx0 = n.dx;
|
13972
|
+
n.x0 = n.x;
|
13973
|
+
n.dy0 = n.dy;
|
13974
|
+
n.y0 = n.y;
|
13975
|
+
}
|
13976
|
+
updatePrevPosition(n);
|
13977
|
+
});
|
13978
|
+
}
|
13450
13979
|
|
13451
|
-
|
13452
|
-
|
13453
|
-
|
13454
|
-
|
13980
|
+
function zoomClick(d) {
|
13981
|
+
var labels = container.selectAll('text')
|
13982
|
+
var path = container.selectAll('path')
|
13983
|
+
|
13984
|
+
// fade out all text elements
|
13985
|
+
labels.transition().attr("opacity",0);
|
13986
|
+
|
13987
|
+
// to allow reference to the new center node
|
13988
|
+
node = d;
|
13989
|
+
|
13990
|
+
path.transition()
|
13991
|
+
.duration(duration)
|
13992
|
+
.attrTween("d", arcTweenZoom)
|
13993
|
+
.each('end', function(e) {
|
13994
|
+
// partially taken from here: http://bl.ocks.org/metmajer/5480307
|
13995
|
+
// check if the animated element's data e lies within the visible angle span given in d
|
13996
|
+
if(e.x >= d.x && e.x < (d.x + d.dx) ){
|
13997
|
+
if(e.depth >= d.depth){
|
13998
|
+
// get a selection of the associated text element
|
13999
|
+
var parentNode = d3.select(this.parentNode);
|
14000
|
+
var arcText = parentNode.select('text');
|
14001
|
+
|
14002
|
+
// fade in the text element and recalculate positions
|
14003
|
+
arcText.transition().duration(duration)
|
14004
|
+
.text( function(e){return labelFormat(e) })
|
14005
|
+
.attr("opacity", function(d){
|
14006
|
+
if(labelThresholdMatched(d)) {
|
14007
|
+
return 1;
|
14008
|
+
}
|
14009
|
+
else {
|
14010
|
+
return 0;
|
14011
|
+
}
|
14012
|
+
})
|
14013
|
+
.attr("transform", function() {
|
14014
|
+
var width = this.getBBox().width;
|
14015
|
+
if(e.depth === 0)
|
14016
|
+
return "translate(" + (width / 2 * - 1) + ",0)";
|
14017
|
+
else if(e.depth === d.depth){
|
14018
|
+
return "translate(" + (y(e.y) + 5) + ",0)";
|
14019
|
+
}
|
14020
|
+
else {
|
14021
|
+
var centerAngle = computeCenterAngle(e);
|
14022
|
+
var rotation = rotationToAvoidUpsideDown(e);
|
14023
|
+
if (rotation === 0) {
|
14024
|
+
return 'rotate('+ centerAngle +')translate(' + (y(e.y) + 5) + ',0)';
|
14025
|
+
}
|
14026
|
+
else {
|
14027
|
+
return 'rotate('+ centerAngle +')translate(' + (y(e.y) + width + 5) + ',0)rotate(' + rotation + ')';
|
14028
|
+
}
|
14029
|
+
}
|
14030
|
+
});
|
14031
|
+
}
|
14032
|
+
}
|
14033
|
+
})
|
14034
|
+
}
|
13455
14035
|
|
13456
14036
|
//============================================================
|
13457
14037
|
// chart function
|
13458
14038
|
//------------------------------------------------------------
|
13459
|
-
|
13460
14039
|
var renderWatch = nv.utils.renderWatch(dispatch);
|
13461
14040
|
|
13462
14041
|
function chart(selection) {
|
13463
14042
|
renderWatch.reset();
|
14043
|
+
|
13464
14044
|
selection.each(function(data) {
|
13465
14045
|
container = d3.select(this);
|
13466
|
-
|
13467
|
-
|
13468
|
-
|
13469
|
-
var path;
|
14046
|
+
availableWidth = nv.utils.availableWidth(width, container, margin);
|
14047
|
+
availableHeight = nv.utils.availableHeight(height, container, margin);
|
14048
|
+
radius = Math.min(availableWidth, availableHeight) / 2;
|
13470
14049
|
|
13471
|
-
|
14050
|
+
y.range([0, radius]);
|
13472
14051
|
|
13473
14052
|
// Setup containers and skeleton of chart
|
13474
|
-
var wrap = container.
|
13475
|
-
|
13476
|
-
|
13477
|
-
|
13478
|
-
|
13479
|
-
|
13480
|
-
if ( duration === 0 ) {
|
13481
|
-
container.call(chart);
|
13482
|
-
} else {
|
13483
|
-
container.transition().duration(duration).call(chart);
|
13484
|
-
}
|
13485
|
-
};
|
13486
|
-
chart.container = this;
|
13487
|
-
|
13488
|
-
|
13489
|
-
wrap.attr('transform', 'translate(' + availableWidth / 2 + ',' + availableHeight / 2 + ')');
|
14053
|
+
var wrap = container.select('g.nvd3.nv-wrap.nv-sunburst');
|
14054
|
+
if( !wrap[0][0] ) {
|
14055
|
+
wrap = container.append('g')
|
14056
|
+
.attr('class', 'nvd3 nv-wrap nv-sunburst nv-chart-' + id)
|
14057
|
+
.attr('transform', 'translate(' + availableWidth / 2 + ',' + availableHeight / 2 + ')');
|
14058
|
+
}
|
13490
14059
|
|
13491
14060
|
container.on('click', function (d, i) {
|
13492
14061
|
dispatch.chartClick({
|
@@ -13497,13 +14066,21 @@ nv.models.sunburst = function() {
|
|
13497
14066
|
});
|
13498
14067
|
});
|
13499
14068
|
|
13500
|
-
y.range([0, radius]);
|
13501
|
-
|
13502
|
-
node = node || data;
|
13503
|
-
rootNode = data[0];
|
13504
14069
|
partition.value(modes[mode] || modes["count"]);
|
13505
|
-
|
13506
|
-
|
14070
|
+
|
14071
|
+
//reverse the drawing order so that the labels of inner
|
14072
|
+
//arcs are drawn on top of the outer arcs.
|
14073
|
+
var nodes = partition.nodes(data[0]).reverse()
|
14074
|
+
|
14075
|
+
storeRetrievePrevPositions(nodes);
|
14076
|
+
var cG = wrap.selectAll('.arc-container').data(nodes, key)
|
14077
|
+
|
14078
|
+
//handle new datapoints
|
14079
|
+
var cGE = cG.enter()
|
14080
|
+
.append("g")
|
14081
|
+
.attr("class",'arc-container')
|
14082
|
+
|
14083
|
+
cGE.append("path")
|
13507
14084
|
.attr("d", arc)
|
13508
14085
|
.style("fill", function (d) {
|
13509
14086
|
if (d.color) {
|
@@ -13517,22 +14094,7 @@ nv.models.sunburst = function() {
|
|
13517
14094
|
}
|
13518
14095
|
})
|
13519
14096
|
.style("stroke", "#FFF")
|
13520
|
-
.on("click",
|
13521
|
-
if (prevNode !== node && node !== d) prevNode = node;
|
13522
|
-
node = d;
|
13523
|
-
path.transition()
|
13524
|
-
.duration(duration)
|
13525
|
-
.attrTween("d", arcTweenZoom(d));
|
13526
|
-
})
|
13527
|
-
.each(stash)
|
13528
|
-
.on("dblclick", function(d) {
|
13529
|
-
if (prevNode.parent == d) {
|
13530
|
-
path.transition()
|
13531
|
-
.duration(duration)
|
13532
|
-
.attrTween("d", arcTweenZoom(rootNode));
|
13533
|
-
}
|
13534
|
-
})
|
13535
|
-
.each(stash)
|
14097
|
+
.on("click", zoomClick)
|
13536
14098
|
.on('mouseover', function(d,i){
|
13537
14099
|
d3.select(this).classed('hover', true).style('opacity', 0.8);
|
13538
14100
|
dispatch.elementMouseover({
|
@@ -13552,58 +14114,68 @@ nv.models.sunburst = function() {
|
|
13552
14114
|
});
|
13553
14115
|
});
|
13554
14116
|
|
14117
|
+
///Iterating via each and selecting based on the this
|
14118
|
+
///makes it work ... a cG.selectAll('path') doesn't.
|
14119
|
+
///Without iteration the data (in the element) didn't update.
|
14120
|
+
cG.each(function(d){
|
14121
|
+
d3.select(this).select('path')
|
14122
|
+
.transition()
|
14123
|
+
.duration(duration)
|
14124
|
+
.attrTween('d', arcTweenUpdate);
|
14125
|
+
});
|
13555
14126
|
|
14127
|
+
if(showLabels){
|
14128
|
+
//remove labels first and add them back
|
14129
|
+
cG.selectAll('text').remove();
|
13556
14130
|
|
13557
|
-
|
13558
|
-
|
13559
|
-
|
13560
|
-
|
14131
|
+
//this way labels are on top of newly added arcs
|
14132
|
+
cG.append('text')
|
14133
|
+
.text( function(e){ return labelFormat(e)})
|
14134
|
+
.transition()
|
14135
|
+
.duration(duration)
|
14136
|
+
.attr("opacity", function(d){
|
14137
|
+
if(labelThresholdMatched(d)) {
|
14138
|
+
return 1;
|
14139
|
+
}
|
14140
|
+
else {
|
14141
|
+
return 0;
|
14142
|
+
}
|
14143
|
+
})
|
14144
|
+
.attr("transform", function(d) {
|
14145
|
+
var width = this.getBBox().width;
|
14146
|
+
if(d.depth === 0){
|
14147
|
+
return "rotate(0)translate(" + (width / 2 * -1) + ",0)";
|
14148
|
+
}
|
14149
|
+
else {
|
14150
|
+
var centerAngle = computeCenterAngle(d);
|
14151
|
+
var rotation = rotationToAvoidUpsideDown(d);
|
14152
|
+
if (rotation === 0) {
|
14153
|
+
return 'rotate('+ centerAngle +')translate(' + (y(d.y) + 5) + ',0)';
|
14154
|
+
}
|
14155
|
+
else {
|
14156
|
+
return 'rotate('+ centerAngle +')translate(' + (y(d.y) + width + 5) + ',0)rotate(' + rotation + ')';
|
14157
|
+
}
|
14158
|
+
}
|
14159
|
+
});
|
13561
14160
|
}
|
13562
14161
|
|
13563
|
-
//
|
13564
|
-
|
13565
|
-
var oi = d3.interpolate({x: a.x0, dx: a.dx0}, a);
|
13566
|
-
|
13567
|
-
function tween(t) {
|
13568
|
-
var b = oi(t);
|
13569
|
-
a.x0 = b.x;
|
13570
|
-
a.dx0 = b.dx;
|
13571
|
-
return arc(b);
|
13572
|
-
}
|
13573
|
-
|
13574
|
-
if (i == 0) {
|
13575
|
-
// If we are on the first arc, adjust the x domain to match the root node
|
13576
|
-
// at the current zoom level. (We only need to do this once.)
|
13577
|
-
var xd = d3.interpolate(x.domain(), [node.x, node.x + node.dx]);
|
13578
|
-
return function (t) {
|
13579
|
-
x.domain(xd(t));
|
13580
|
-
return tween(t);
|
13581
|
-
};
|
13582
|
-
} else {
|
13583
|
-
return tween;
|
13584
|
-
}
|
13585
|
-
}
|
14162
|
+
//zoom out to the center when the data is updated.
|
14163
|
+
zoomClick(nodes[nodes.length - 1])
|
13586
14164
|
|
13587
|
-
// When zooming: interpolate the scales.
|
13588
|
-
function arcTweenZoom(d) {
|
13589
|
-
var xd = d3.interpolate(x.domain(), [d.x, d.x + d.dx]),
|
13590
|
-
yd = d3.interpolate(y.domain(), [d.y, 1]),
|
13591
|
-
yr = d3.interpolate(y.range(), [d.y ? 20 : 0, radius]);
|
13592
|
-
return function (d, i) {
|
13593
|
-
return i
|
13594
|
-
? function (t) {
|
13595
|
-
return arc(d);
|
13596
|
-
}
|
13597
|
-
: function (t) {
|
13598
|
-
x.domain(xd(t));
|
13599
|
-
y.domain(yd(t)).range(yr(t));
|
13600
|
-
return arc(d);
|
13601
|
-
};
|
13602
|
-
};
|
13603
|
-
}
|
13604
14165
|
|
14166
|
+
//remove unmatched elements ...
|
14167
|
+
cG.exit()
|
14168
|
+
.transition()
|
14169
|
+
.duration(duration)
|
14170
|
+
.attr('opacity',0)
|
14171
|
+
.each('end',function(d){
|
14172
|
+
var k = key(d);
|
14173
|
+
prevPositions[k] = undefined;
|
14174
|
+
})
|
14175
|
+
.remove();
|
13605
14176
|
});
|
13606
14177
|
|
14178
|
+
|
13607
14179
|
renderWatch.renderEnd('sunburst immediate');
|
13608
14180
|
return chart;
|
13609
14181
|
}
|
@@ -13623,7 +14195,11 @@ nv.models.sunburst = function() {
|
|
13623
14195
|
id: {get: function(){return id;}, set: function(_){id=_;}},
|
13624
14196
|
duration: {get: function(){return duration;}, set: function(_){duration=_;}},
|
13625
14197
|
groupColorByParent: {get: function(){return groupColorByParent;}, set: function(_){groupColorByParent=!!_;}},
|
13626
|
-
|
14198
|
+
showLabels: {get: function(){return showLabels;}, set: function(_){showLabels=!!_}},
|
14199
|
+
labelFormat: {get: function(){return labelFormat;}, set: function(_){labelFormat=_}},
|
14200
|
+
labelThreshold: {get: function(){return labelThreshold;}, set: function(_){labelThreshold=_}},
|
14201
|
+
sort: {get: function(){return sort;}, set: function(_){sort=_}},
|
14202
|
+
key: {get: function(){return key;}, set: function(_){key=_}},
|
13627
14203
|
// options that require extra logic in the setter
|
13628
14204
|
margin: {get: function(){return margin;}, set: function(_){
|
13629
14205
|
margin.top = _.top != undefined ? _.top : margin.top;
|
@@ -13657,21 +14233,19 @@ nv.models.sunburstChart = function() {
|
|
13657
14233
|
, defaultState = null
|
13658
14234
|
, noData = null
|
13659
14235
|
, duration = 250
|
13660
|
-
, dispatch = d3.dispatch('stateChange', 'changeState','renderEnd')
|
13661
|
-
;
|
14236
|
+
, dispatch = d3.dispatch('stateChange', 'changeState','renderEnd');
|
13662
14237
|
|
13663
|
-
tooltip.duration(0);
|
13664
14238
|
|
13665
14239
|
//============================================================
|
13666
14240
|
// Private Variables
|
13667
14241
|
//------------------------------------------------------------
|
13668
14242
|
|
13669
14243
|
var renderWatch = nv.utils.renderWatch(dispatch);
|
14244
|
+
|
13670
14245
|
tooltip
|
14246
|
+
.duration(0)
|
13671
14247
|
.headerEnabled(false)
|
13672
|
-
.valueFormatter(function(d
|
13673
|
-
return d;
|
13674
|
-
});
|
14248
|
+
.valueFormatter(function(d){return d;});
|
13675
14249
|
|
13676
14250
|
//============================================================
|
13677
14251
|
// Chart function
|
@@ -13683,11 +14257,11 @@ nv.models.sunburstChart = function() {
|
|
13683
14257
|
|
13684
14258
|
selection.each(function(data) {
|
13685
14259
|
var container = d3.select(this);
|
14260
|
+
|
13686
14261
|
nv.utils.initSVG(container);
|
13687
14262
|
|
13688
|
-
var
|
13689
|
-
var
|
13690
|
-
availableHeight = nv.utils.availableHeight(height, container, margin);
|
14263
|
+
var availableWidth = nv.utils.availableWidth(width, container, margin);
|
14264
|
+
var availableHeight = nv.utils.availableHeight(height, container, margin);
|
13691
14265
|
|
13692
14266
|
chart.update = function() {
|
13693
14267
|
if (duration === 0) {
|
@@ -13696,7 +14270,7 @@ nv.models.sunburstChart = function() {
|
|
13696
14270
|
container.transition().duration(duration).call(chart);
|
13697
14271
|
}
|
13698
14272
|
};
|
13699
|
-
chart.container =
|
14273
|
+
chart.container = container;
|
13700
14274
|
|
13701
14275
|
// Display No Data message if there's nothing to show.
|
13702
14276
|
if (!data || !data.length) {
|
@@ -13706,20 +14280,8 @@ nv.models.sunburstChart = function() {
|
|
13706
14280
|
container.selectAll('.nv-noData').remove();
|
13707
14281
|
}
|
13708
14282
|
|
13709
|
-
// Setup containers and skeleton of chart
|
13710
|
-
var wrap = container.selectAll('g.nv-wrap.nv-sunburstChart').data(data);
|
13711
|
-
var gEnter = wrap.enter().append('g').attr('class', 'nvd3 nv-wrap nv-sunburstChart').append('g');
|
13712
|
-
var g = wrap.select('g');
|
13713
|
-
|
13714
|
-
gEnter.append('g').attr('class', 'nv-sunburstWrap');
|
13715
|
-
|
13716
|
-
wrap.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');
|
13717
|
-
|
13718
|
-
// Main Chart Component(s)
|
13719
14283
|
sunburst.width(availableWidth).height(availableHeight);
|
13720
|
-
|
13721
|
-
d3.transition(sunWrap).call(sunburst);
|
13722
|
-
|
14284
|
+
container.call(sunburst);
|
13723
14285
|
});
|
13724
14286
|
|
13725
14287
|
renderWatch.renderEnd('sunburstChart immediate');
|
@@ -13731,9 +14293,9 @@ nv.models.sunburstChart = function() {
|
|
13731
14293
|
//------------------------------------------------------------
|
13732
14294
|
|
13733
14295
|
sunburst.dispatch.on('elementMouseover.tooltip', function(evt) {
|
13734
|
-
evt
|
14296
|
+
evt.series = {
|
13735
14297
|
key: evt.data.name,
|
13736
|
-
value: evt.data.size,
|
14298
|
+
value: (evt.data.value || evt.data.size),
|
13737
14299
|
color: evt.color
|
13738
14300
|
};
|
13739
14301
|
tooltip.data(evt).hidden(false);
|
@@ -13783,7 +14345,8 @@ nv.models.sunburstChart = function() {
|
|
13783
14345
|
nv.utils.inheritOptions(chart, sunburst);
|
13784
14346
|
nv.utils.initOptions(chart);
|
13785
14347
|
return chart;
|
14348
|
+
|
13786
14349
|
};
|
13787
14350
|
|
13788
|
-
nv.version = "1.8.
|
14351
|
+
nv.version = "1.8.3";
|
13789
14352
|
})();
|