novus-nvd3-rails 1.8.5 → 1.8.6
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/lib/novus/nvd3/rails/version.rb +1 -1
- data/vendor/assets/javascripts/nv.d3.js +393 -146
- data/vendor/assets/stylesheets/nv.d3.css +1 -1
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f5a3b600d4ce921a4c4ef5efac45c6e33915acde
|
4
|
+
data.tar.gz: 19c327dad4f61916d35c02602a5ddec5604eb92d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: '07694780ab62c0a622da40d5b0ca3b41f76b6e4f577d87d841529733c871746cca41a7a0ce0a286761150870e93786baf94e950eb2d49b0c0772ae5fcd5a8aa3'
|
7
|
+
data.tar.gz: 8684fb0dba933fd725c3f3ec4512e8f54f883eef0c8dc59d4ecdf5b80cb8cce98408c30d195f71018722ec71ca7bcb3d69df21c74bc790cedffdf885b1ff5bce
|
@@ -1,4 +1,4 @@
|
|
1
|
-
/* nvd3 version 1.8.
|
1
|
+
/* nvd3 version 1.8.6 (https://github.com/novus/nvd3) 2017-08-23 */
|
2
2
|
(function(){
|
3
3
|
|
4
4
|
// set up main nv object
|
@@ -221,9 +221,9 @@ nv.interactiveGuideline = function() {
|
|
221
221
|
}
|
222
222
|
|
223
223
|
function mouseHandler() {
|
224
|
-
var
|
225
|
-
var
|
226
|
-
|
224
|
+
var mouseX = d3.event.clientX - this.getBoundingClientRect().left;
|
225
|
+
var mouseY = d3.event.clientY - this.getBoundingClientRect().top;
|
226
|
+
|
227
227
|
var subtractMargin = true;
|
228
228
|
var mouseOutAnyReason = false;
|
229
229
|
if (isMSIE) {
|
@@ -556,7 +556,10 @@ nv.models.tooltip = function() {
|
|
556
556
|
;
|
557
557
|
|
558
558
|
// Format function for the tooltip values column.
|
559
|
-
|
559
|
+
// d is value,
|
560
|
+
// i is series index
|
561
|
+
// p is point containing the value
|
562
|
+
var valueFormatter = function(d, i, p) {
|
560
563
|
return d;
|
561
564
|
};
|
562
565
|
|
@@ -569,9 +572,10 @@ nv.models.tooltip = function() {
|
|
569
572
|
return d;
|
570
573
|
};
|
571
574
|
|
572
|
-
// By default, the tooltip model renders a beautiful table inside a DIV
|
573
|
-
// You can override this function if a custom tooltip is desired.
|
574
|
-
|
575
|
+
// By default, the tooltip model renders a beautiful table inside a DIV, returned as HTML
|
576
|
+
// You can override this function if a custom tooltip is desired. For instance, you could directly manipulate
|
577
|
+
// the DOM by accessing elem and returning false.
|
578
|
+
var contentGenerator = function(d, elem) {
|
575
579
|
if (d === null) {
|
576
580
|
return '';
|
577
581
|
}
|
@@ -612,7 +616,7 @@ nv.models.tooltip = function() {
|
|
612
616
|
|
613
617
|
trowEnter.append("td")
|
614
618
|
.classed("value",true)
|
615
|
-
.html(function(p, i) { return valueFormatter(p.value, i) });
|
619
|
+
.html(function(p, i) { return valueFormatter(p.value, i, p) });
|
616
620
|
|
617
621
|
trowEnter.filter(function (p,i) { return p.percent !== undefined }).append("td")
|
618
622
|
.classed("percent", true)
|
@@ -802,9 +806,9 @@ nv.models.tooltip = function() {
|
|
802
806
|
nv.dom.write(function () {
|
803
807
|
initTooltip();
|
804
808
|
// Generate data and set it into tooltip.
|
805
|
-
// Bonus - If you override contentGenerator and return
|
806
|
-
// React or Knockout to bind the data for your tooltip.
|
807
|
-
var newContent = contentGenerator(data);
|
809
|
+
// Bonus - If you override contentGenerator and return false, you can use something like
|
810
|
+
// Angular, React or Knockout to bind the data for your tooltip directly to the DOM.
|
811
|
+
var newContent = contentGenerator(data, tooltip.node());
|
808
812
|
if (newContent) {
|
809
813
|
tooltip.node().innerHTML = newContent;
|
810
814
|
}
|
@@ -1387,6 +1391,8 @@ Also use _d3options so we can track what we inherit for documentation and chaine
|
|
1387
1391
|
*/
|
1388
1392
|
nv.utils.inheritOptionsD3 = function(target, d3_source, oplist) {
|
1389
1393
|
target._d3options = oplist.concat(target._d3options || []);
|
1394
|
+
// Find unique d3 options (string) and update d3options
|
1395
|
+
target._d3options = (target._d3options || []).filter(function(item, i, ar){ return ar.indexOf(item) === i; });
|
1390
1396
|
oplist.unshift(d3_source);
|
1391
1397
|
oplist.unshift(target);
|
1392
1398
|
d3.rebind.apply(this, oplist);
|
@@ -1584,6 +1590,27 @@ nv.utils.arrayEquals = function (array1, array2) {
|
|
1584
1590
|
}
|
1585
1591
|
return true;
|
1586
1592
|
};
|
1593
|
+
|
1594
|
+
/*
|
1595
|
+
Check if a point within an arc
|
1596
|
+
*/
|
1597
|
+
nv.utils.pointIsInArc = function(pt, ptData, d3Arc) {
|
1598
|
+
// Center of the arc is assumed to be 0,0
|
1599
|
+
// (pt.x, pt.y) are assumed to be relative to the center
|
1600
|
+
var r1 = d3Arc.innerRadius()(ptData), // Note: Using the innerRadius
|
1601
|
+
r2 = d3Arc.outerRadius()(ptData),
|
1602
|
+
theta1 = d3Arc.startAngle()(ptData),
|
1603
|
+
theta2 = d3Arc.endAngle()(ptData);
|
1604
|
+
|
1605
|
+
var dist = pt.x * pt.x + pt.y * pt.y,
|
1606
|
+
angle = Math.atan2(pt.x, -pt.y); // Note: different coordinate system.
|
1607
|
+
|
1608
|
+
angle = (angle < 0) ? (angle + Math.PI * 2) : angle;
|
1609
|
+
|
1610
|
+
return (r1 * r1 <= dist) && (dist <= r2 * r2) &&
|
1611
|
+
(theta1 <= angle) && (angle <= theta2);
|
1612
|
+
};
|
1613
|
+
|
1587
1614
|
nv.models.axis = function() {
|
1588
1615
|
"use strict";
|
1589
1616
|
|
@@ -1608,6 +1635,7 @@ nv.models.axis = function() {
|
|
1608
1635
|
, fontSize = undefined
|
1609
1636
|
, duration = 250
|
1610
1637
|
, dispatch = d3.dispatch('renderEnd')
|
1638
|
+
, tickFormatMaxMin
|
1611
1639
|
;
|
1612
1640
|
axis
|
1613
1641
|
.scale(scale)
|
@@ -1692,7 +1720,8 @@ nv.models.axis = function() {
|
|
1692
1720
|
.attr('y', -axis.tickPadding())
|
1693
1721
|
.attr('text-anchor', 'middle')
|
1694
1722
|
.text(function(d,i) {
|
1695
|
-
var
|
1723
|
+
var formatter = tickFormatMaxMin || fmt;
|
1724
|
+
var v = formatter(d);
|
1696
1725
|
return ('' + v).match('NaN') ? '' : v;
|
1697
1726
|
});
|
1698
1727
|
axisMaxMin.watchTransition(renderWatch, 'min-max top')
|
@@ -1709,7 +1738,7 @@ nv.models.axis = function() {
|
|
1709
1738
|
var rotateLabelsRule = '';
|
1710
1739
|
if (rotateLabels%360) {
|
1711
1740
|
//Reset transform on ticks so textHeight can be calculated correctly
|
1712
|
-
xTicks.attr('transform', '');
|
1741
|
+
xTicks.attr('transform', '');
|
1713
1742
|
//Calculate the longest xTick width
|
1714
1743
|
xTicks.each(function(d,i){
|
1715
1744
|
var box = this.getBoundingClientRect();
|
@@ -1767,7 +1796,8 @@ nv.models.axis = function() {
|
|
1767
1796
|
.attr('transform', rotateLabelsRule)
|
1768
1797
|
.style('text-anchor', rotateLabels ? (rotateLabels%360 > 0 ? 'start' : 'end') : 'middle')
|
1769
1798
|
.text(function(d,i) {
|
1770
|
-
var
|
1799
|
+
var formatter = tickFormatMaxMin || fmt;
|
1800
|
+
var v = formatter(d);
|
1771
1801
|
return ('' + v).match('NaN') ? '' : v;
|
1772
1802
|
});
|
1773
1803
|
axisMaxMin.watchTransition(renderWatch, 'min-max bottom')
|
@@ -1802,7 +1832,8 @@ nv.models.axis = function() {
|
|
1802
1832
|
.attr('x', axis.tickPadding())
|
1803
1833
|
.style('text-anchor', 'start')
|
1804
1834
|
.text(function(d, i) {
|
1805
|
-
var
|
1835
|
+
var formatter = tickFormatMaxMin || fmt;
|
1836
|
+
var v = formatter(d);
|
1806
1837
|
return ('' + v).match('NaN') ? '' : v;
|
1807
1838
|
});
|
1808
1839
|
axisMaxMin.watchTransition(renderWatch, 'min-max right')
|
@@ -1846,7 +1877,8 @@ nv.models.axis = function() {
|
|
1846
1877
|
.attr('x', -axis.tickPadding())
|
1847
1878
|
.attr('text-anchor', 'end')
|
1848
1879
|
.text(function(d,i) {
|
1849
|
-
var
|
1880
|
+
var formatter = tickFormatMaxMin || fmt;
|
1881
|
+
var v = formatter(d);
|
1850
1882
|
return ('' + v).match('NaN') ? '' : v;
|
1851
1883
|
});
|
1852
1884
|
axisMaxMin.watchTransition(renderWatch, 'min-max right')
|
@@ -1917,9 +1949,9 @@ nv.models.axis = function() {
|
|
1917
1949
|
and the arithmetic trick below solves that.
|
1918
1950
|
*/
|
1919
1951
|
return !parseFloat(Math.round(d * 100000) / 1000000) && (d !== undefined)
|
1920
|
-
})
|
1952
|
+
})
|
1921
1953
|
.classed('zero', true);
|
1922
|
-
|
1954
|
+
|
1923
1955
|
//store old scales for use in transitions on update
|
1924
1956
|
scale0 = scale.copy();
|
1925
1957
|
|
@@ -1950,6 +1982,7 @@ nv.models.axis = function() {
|
|
1950
1982
|
ticks: {get: function(){return ticks;}, set: function(_){ticks=_;}},
|
1951
1983
|
width: {get: function(){return width;}, set: function(_){width=_;}},
|
1952
1984
|
fontSize: {get: function(){return fontSize;}, set: function(_){fontSize=_;}},
|
1985
|
+
tickFormatMaxMin: {get: function(){return tickFormatMaxMin;}, set: function(_){tickFormatMaxMin=_;}},
|
1953
1986
|
|
1954
1987
|
// options that require extra logic in the setter
|
1955
1988
|
margin: {get: function(){return margin;}, set: function(_){
|
@@ -3350,6 +3383,7 @@ nv.models.cumulativeLineChart = function() {
|
|
3350
3383
|
var dx = d3.scale.linear()
|
3351
3384
|
, index = {i: 0, x: 0}
|
3352
3385
|
, renderWatch = nv.utils.renderWatch(dispatch, duration)
|
3386
|
+
, currentYDomain
|
3353
3387
|
;
|
3354
3388
|
|
3355
3389
|
var stateGetter = function(data) {
|
@@ -3454,30 +3488,6 @@ nv.models.cumulativeLineChart = function() {
|
|
3454
3488
|
x = lines.xScale();
|
3455
3489
|
y = lines.yScale();
|
3456
3490
|
|
3457
|
-
if (!rescaleY) {
|
3458
|
-
var seriesDomains = data
|
3459
|
-
.filter(function(series) { return !series.disabled })
|
3460
|
-
.map(function(series,i) {
|
3461
|
-
var initialDomain = d3.extent(series.values, lines.y());
|
3462
|
-
|
3463
|
-
//account for series being disabled when losing 95% or more
|
3464
|
-
if (initialDomain[0] < -.95) initialDomain[0] = -.95;
|
3465
|
-
|
3466
|
-
return [
|
3467
|
-
(initialDomain[0] - initialDomain[1]) / (1 + initialDomain[1]),
|
3468
|
-
(initialDomain[1] - initialDomain[0]) / (1 + initialDomain[0])
|
3469
|
-
];
|
3470
|
-
});
|
3471
|
-
|
3472
|
-
var completeDomain = [
|
3473
|
-
d3.min(seriesDomains, function(d) { return d[0] }),
|
3474
|
-
d3.max(seriesDomains, function(d) { return d[1] })
|
3475
|
-
];
|
3476
|
-
|
3477
|
-
lines.yDomain(completeDomain);
|
3478
|
-
} else {
|
3479
|
-
lines.yDomain(null);
|
3480
|
-
}
|
3481
3491
|
|
3482
3492
|
dx.domain([0, data[0].values.length - 1]) //Assumes all series have same length
|
3483
3493
|
.range([0, availableWidth])
|
@@ -3485,6 +3495,18 @@ nv.models.cumulativeLineChart = function() {
|
|
3485
3495
|
|
3486
3496
|
var data = indexify(index.i, data);
|
3487
3497
|
|
3498
|
+
// initialize the starting yDomain for the not-rescale case after indexify (to have calculated point.display)
|
3499
|
+
if (typeof(currentYDomain) === "undefined") {
|
3500
|
+
currentYDomain = getCurrentYDomain(data);
|
3501
|
+
}
|
3502
|
+
|
3503
|
+
if (!rescaleY) {
|
3504
|
+
lines.yDomain(currentYDomain);
|
3505
|
+
lines.clipEdge(true);
|
3506
|
+
} else {
|
3507
|
+
lines.yDomain(null);
|
3508
|
+
}
|
3509
|
+
|
3488
3510
|
// Setup containers and skeleton of chart
|
3489
3511
|
var interactivePointerEvents = (useInteractiveGuideline) ? "none" : "all";
|
3490
3512
|
var wrap = container.selectAll('g.nv-wrap.nv-cumulativeLine').data([data]);
|
@@ -3547,7 +3569,7 @@ nv.models.cumulativeLineChart = function() {
|
|
3547
3569
|
.attr("transform", "translate(" + availableWidth + ",0)");
|
3548
3570
|
}
|
3549
3571
|
|
3550
|
-
// Show error if
|
3572
|
+
// Show error if index point value is 0 (division by zero avoided)
|
3551
3573
|
var tempDisabled = data.filter(function(d) { return d.tempDisabled });
|
3552
3574
|
|
3553
3575
|
wrap.select('.tempDisabled').remove(); //clean-up and prevent duplicates
|
@@ -3717,8 +3739,10 @@ nv.models.cumulativeLineChart = function() {
|
|
3717
3739
|
controls.dispatch.on('legendClick', function(d,i) {
|
3718
3740
|
d.disabled = !d.disabled;
|
3719
3741
|
rescaleY = !d.disabled;
|
3720
|
-
|
3721
3742
|
state.rescaleY = rescaleY;
|
3743
|
+
if (!rescaleY) {
|
3744
|
+
currentYDomain = getCurrentYDomain(data); // rescale is turned off, so set the currentYDomain
|
3745
|
+
}
|
3722
3746
|
dispatch.stateChange(state);
|
3723
3747
|
chart.update();
|
3724
3748
|
});
|
@@ -3737,7 +3761,7 @@ nv.models.cumulativeLineChart = function() {
|
|
3737
3761
|
data
|
3738
3762
|
.filter(function(series, i) {
|
3739
3763
|
series.seriesIndex = i;
|
3740
|
-
return !series.disabled;
|
3764
|
+
return !(series.disabled || series.tempDisabled);
|
3741
3765
|
})
|
3742
3766
|
.forEach(function(series,i) {
|
3743
3767
|
pointIndex = nv.interactiveBisect(series.values, e.pointXValue, chart.x());
|
@@ -3852,10 +3876,8 @@ nv.models.cumulativeLineChart = function() {
|
|
3852
3876
|
}
|
3853
3877
|
var v = indexifyYGetter(indexValue, idx);
|
3854
3878
|
|
3855
|
-
//
|
3856
|
-
if (v <
|
3857
|
-
//if a series loses more than 100%, calculations fail.. anything close can cause major distortion (but is mathematically correct till it hits 100)
|
3858
|
-
|
3879
|
+
// avoid divide by zero
|
3880
|
+
if (Math.abs(v) < 0.00001 && !noErrorCheck) {
|
3859
3881
|
line.tempDisabled = true;
|
3860
3882
|
return line;
|
3861
3883
|
}
|
@@ -3863,7 +3885,7 @@ nv.models.cumulativeLineChart = function() {
|
|
3863
3885
|
line.tempDisabled = false;
|
3864
3886
|
|
3865
3887
|
line.values = line.values.map(function(point, pointIndex) {
|
3866
|
-
point.display = {'y': (indexifyYGetter(point, pointIndex) - v) /
|
3888
|
+
point.display = {'y': (indexifyYGetter(point, pointIndex) - v) / v };
|
3867
3889
|
return point;
|
3868
3890
|
});
|
3869
3891
|
|
@@ -3871,6 +3893,19 @@ nv.models.cumulativeLineChart = function() {
|
|
3871
3893
|
})
|
3872
3894
|
}
|
3873
3895
|
|
3896
|
+
function getCurrentYDomain(data) {
|
3897
|
+
var seriesDomains = data
|
3898
|
+
.filter(function(series) { return !(series.disabled || series.tempDisabled)})
|
3899
|
+
.map(function(series,i) {
|
3900
|
+
return d3.extent(series.values, function (d) { return d.display.y });
|
3901
|
+
});
|
3902
|
+
|
3903
|
+
return [
|
3904
|
+
d3.min(seriesDomains, function(d) { return d[0] }),
|
3905
|
+
d3.max(seriesDomains, function(d) { return d[1] })
|
3906
|
+
];
|
3907
|
+
}
|
3908
|
+
|
3874
3909
|
//============================================================
|
3875
3910
|
// Expose Public Variables
|
3876
3911
|
//------------------------------------------------------------
|
@@ -3892,7 +3927,6 @@ nv.models.cumulativeLineChart = function() {
|
|
3892
3927
|
// simple options, just get/set the necessary values
|
3893
3928
|
width: {get: function(){return width;}, set: function(_){width=_;}},
|
3894
3929
|
height: {get: function(){return height;}, set: function(_){height=_;}},
|
3895
|
-
rescaleY: {get: function(){return rescaleY;}, set: function(_){rescaleY=_;}},
|
3896
3930
|
showControls: {get: function(){return showControls;}, set: function(_){showControls=_;}},
|
3897
3931
|
showLegend: {get: function(){return showLegend;}, set: function(_){showLegend=_;}},
|
3898
3932
|
average: {get: function(){return average;}, set: function(_){average=_;}},
|
@@ -3903,6 +3937,10 @@ nv.models.cumulativeLineChart = function() {
|
|
3903
3937
|
noErrorCheck: {get: function(){return noErrorCheck;}, set: function(_){noErrorCheck=_;}},
|
3904
3938
|
|
3905
3939
|
// options that require extra logic in the setter
|
3940
|
+
rescaleY: {get: function(){return rescaleY;}, set: function(_){
|
3941
|
+
rescaleY = _;
|
3942
|
+
chart.state.rescaleY = _; // also update state
|
3943
|
+
}},
|
3906
3944
|
margin: {get: function(){return margin;}, set: function(_){
|
3907
3945
|
if (_.top !== undefined) {
|
3908
3946
|
margin.top = _.top;
|
@@ -4958,6 +4996,8 @@ nv.models.forceDirectedGraph = function() {
|
|
4958
4996
|
// These functions allow to add extra attributes to ndes and links
|
4959
4997
|
,nodeExtras = function(nodes) { /* Do nothing */ }
|
4960
4998
|
,linkExtras = function(links) { /* Do nothing */ }
|
4999
|
+
, getX=d3.functor(0.0)
|
5000
|
+
, getY=d3.functor(0.0)
|
4961
5001
|
;
|
4962
5002
|
|
4963
5003
|
|
@@ -6126,6 +6166,7 @@ nv.models.legend = function() {
|
|
6126
6166
|
, padding = 32 //define how much space between legend items. - recommend 32 for furious version
|
6127
6167
|
, rightAlign = true
|
6128
6168
|
, updateState = true //If true, legend will update data.disabled and trigger a 'stateChange' dispatch.
|
6169
|
+
, enableDoubleClick = true //If true, legend will enable double click handling
|
6129
6170
|
, radioButtonMode = false //If true, clicking legend items will cause it to behave like a radio button. (only one can be selected at a time)
|
6130
6171
|
, expanded = false
|
6131
6172
|
, dispatch = d3.dispatch('legendClick', 'legendDblclick', 'legendMouseover', 'legendMouseout', 'stateChange')
|
@@ -6258,22 +6299,26 @@ nv.models.legend = function() {
|
|
6258
6299
|
}
|
6259
6300
|
})
|
6260
6301
|
.on('dblclick', function(d,i) {
|
6261
|
-
if(
|
6262
|
-
|
6263
|
-
|
6264
|
-
|
6265
|
-
|
6266
|
-
|
6267
|
-
|
6268
|
-
|
6269
|
-
|
6270
|
-
|
6271
|
-
|
6272
|
-
|
6273
|
-
|
6274
|
-
|
6275
|
-
|
6276
|
-
|
6302
|
+
if (enableDoubleClick) {
|
6303
|
+
if (vers == 'furious' && expanded) return;
|
6304
|
+
dispatch.legendDblclick(d, i);
|
6305
|
+
if (updateState) {
|
6306
|
+
// make sure we re-get data in case it was modified
|
6307
|
+
var data = series.data();
|
6308
|
+
//the default behavior of NVD3 legends, when double clicking one,
|
6309
|
+
// is to set all other series' to false, and make the double clicked series enabled.
|
6310
|
+
data.forEach(function (series) {
|
6311
|
+
series.disabled = true;
|
6312
|
+
if (vers == 'furious') series.userDisabled = series.disabled;
|
6313
|
+
});
|
6314
|
+
d.disabled = false;
|
6315
|
+
if (vers == 'furious') d.userDisabled = d.disabled;
|
6316
|
+
dispatch.stateChange({
|
6317
|
+
disabled: data.map(function (d) {
|
6318
|
+
return !!d.disabled
|
6319
|
+
})
|
6320
|
+
});
|
6321
|
+
}
|
6277
6322
|
}
|
6278
6323
|
});
|
6279
6324
|
|
@@ -6472,6 +6517,7 @@ nv.models.legend = function() {
|
|
6472
6517
|
rightAlign: {get: function(){return rightAlign;}, set: function(_){rightAlign=_;}},
|
6473
6518
|
padding: {get: function(){return padding;}, set: function(_){padding=_;}},
|
6474
6519
|
updateState: {get: function(){return updateState;}, set: function(_){updateState=_;}},
|
6520
|
+
enableDoubleClick: {get: function(){return enableDoubleClick;}, set: function(_){enableDoubleClick=_;}},
|
6475
6521
|
radioButtonMode:{get: function(){return radioButtonMode;}, set: function(_){radioButtonMode=_;}},
|
6476
6522
|
expanded: {get: function(){return expanded;}, set: function(_){expanded=_;}},
|
6477
6523
|
vers: {get: function(){return vers;}, set: function(_){vers=_;}},
|
@@ -6754,7 +6800,7 @@ nv.models.lineChart = function() {
|
|
6754
6800
|
, state = nv.utils.state()
|
6755
6801
|
, defaultState = null
|
6756
6802
|
, noData = null
|
6757
|
-
, dispatch = d3.dispatch('
|
6803
|
+
, dispatch = d3.dispatch('stateChange', 'changeState', 'renderEnd')
|
6758
6804
|
, duration = 250
|
6759
6805
|
;
|
6760
6806
|
|
@@ -6883,8 +6929,10 @@ nv.models.lineChart = function() {
|
|
6883
6929
|
.call(legend);
|
6884
6930
|
|
6885
6931
|
if (legendPosition === 'bottom') {
|
6886
|
-
|
6887
|
-
|
6932
|
+
margin.bottom = xAxis.height() + legend.height();
|
6933
|
+
availableHeight = nv.utils.availableHeight(height, container, margin);
|
6934
|
+
g.select('.nv-legendWrap')
|
6935
|
+
.attr('transform', 'translate(0,' + (availableHeight + xAxis.height()) +')');
|
6888
6936
|
} else if (legendPosition === 'top') {
|
6889
6937
|
if (!marginTop && legend.height() !== margin.top) {
|
6890
6938
|
margin.top = legend.height();
|
@@ -6973,18 +7021,18 @@ nv.models.lineChart = function() {
|
|
6973
7021
|
//============================================================
|
6974
7022
|
// Update Focus
|
6975
7023
|
//============================================================
|
6976
|
-
if(!focusEnable) {
|
7024
|
+
if (!focusEnable && focus.brush.extent() === null) {
|
6977
7025
|
linesWrap.call(lines);
|
6978
7026
|
updateXAxis();
|
6979
7027
|
updateYAxis();
|
6980
7028
|
} else {
|
6981
7029
|
focus.width(availableWidth);
|
6982
7030
|
g.select('.nv-focusWrap')
|
7031
|
+
.style('display', focusEnable ? 'initial' : 'none')
|
6983
7032
|
.attr('transform', 'translate(0,' + ( availableHeight + margin.bottom + focus.margin().top) + ')')
|
6984
|
-
.datum(data.filter(function(d) { return !d.disabled; }))
|
6985
7033
|
.call(focus);
|
6986
7034
|
var extent = focus.brush.empty() ? focus.xDomain() : focus.brush.extent();
|
6987
|
-
if(extent !== null){
|
7035
|
+
if (extent !== null) {
|
6988
7036
|
onBrush(extent);
|
6989
7037
|
}
|
6990
7038
|
}
|
@@ -7008,7 +7056,7 @@ nv.models.lineChart = function() {
|
|
7008
7056
|
return !series.disabled && !series.disableTooltip;
|
7009
7057
|
})
|
7010
7058
|
.forEach(function(series,i) {
|
7011
|
-
var extent =
|
7059
|
+
var extent = focus.brush.extent() !== null ? (focus.brush.empty() ? focus.xScale().domain() : focus.brush.extent()) : x.domain();
|
7012
7060
|
var currentValues = series.values.filter(function(d,i) {
|
7013
7061
|
// Checks if the x point is between the extents, handling case where extent[0] is greater than extent[1]
|
7014
7062
|
// (e.g. x domain is manually set to reverse the x-axis)
|
@@ -8176,44 +8224,49 @@ nv.models.multiBar = function() {
|
|
8176
8224
|
bars
|
8177
8225
|
.style('fill', function(d,i,j){ return color(d, j, i); })
|
8178
8226
|
.style('stroke', function(d,i,j){ return color(d, j, i); })
|
8179
|
-
.on('mouseover', function(d,i) {
|
8227
|
+
.on('mouseover', function(d,i,j) {
|
8180
8228
|
d3.select(this).classed('hover', true);
|
8181
8229
|
dispatch.elementMouseover({
|
8182
8230
|
data: d,
|
8183
8231
|
index: i,
|
8232
|
+
series: data[j],
|
8184
8233
|
color: d3.select(this).style("fill")
|
8185
8234
|
});
|
8186
8235
|
})
|
8187
|
-
.on('mouseout', function(d,i) {
|
8236
|
+
.on('mouseout', function(d,i,j) {
|
8188
8237
|
d3.select(this).classed('hover', false);
|
8189
8238
|
dispatch.elementMouseout({
|
8190
8239
|
data: d,
|
8191
8240
|
index: i,
|
8241
|
+
series: data[j],
|
8192
8242
|
color: d3.select(this).style("fill")
|
8193
8243
|
});
|
8194
8244
|
})
|
8195
|
-
.on('mousemove', function(d,i) {
|
8245
|
+
.on('mousemove', function(d,i,j) {
|
8196
8246
|
dispatch.elementMousemove({
|
8197
8247
|
data: d,
|
8198
8248
|
index: i,
|
8249
|
+
series: data[j],
|
8199
8250
|
color: d3.select(this).style("fill")
|
8200
8251
|
});
|
8201
8252
|
})
|
8202
|
-
.on('click', function(d,i) {
|
8253
|
+
.on('click', function(d,i,j) {
|
8203
8254
|
var element = this;
|
8204
8255
|
dispatch.elementClick({
|
8205
8256
|
data: d,
|
8206
8257
|
index: i,
|
8258
|
+
series: data[j],
|
8207
8259
|
color: d3.select(this).style("fill"),
|
8208
8260
|
event: d3.event,
|
8209
8261
|
element: element
|
8210
8262
|
});
|
8211
8263
|
d3.event.stopPropagation();
|
8212
8264
|
})
|
8213
|
-
.on('dblclick', function(d,i) {
|
8265
|
+
.on('dblclick', function(d,i,j) {
|
8214
8266
|
dispatch.elementDblClick({
|
8215
8267
|
data: d,
|
8216
8268
|
index: i,
|
8269
|
+
series: data[j],
|
8217
8270
|
color: d3.select(this).style("fill")
|
8218
8271
|
});
|
8219
8272
|
d3.event.stopPropagation();
|
@@ -8397,6 +8450,7 @@ nv.models.multiBarChart = function() {
|
|
8397
8450
|
, showControls = true
|
8398
8451
|
, controlLabels = {}
|
8399
8452
|
, showLegend = true
|
8453
|
+
, legendPosition = null
|
8400
8454
|
, showXAxis = true
|
8401
8455
|
, showYAxis = true
|
8402
8456
|
, rightAlignYAxis = false
|
@@ -8562,19 +8616,32 @@ nv.models.multiBarChart = function() {
|
|
8562
8616
|
if (!showLegend) {
|
8563
8617
|
g.select('.nv-legendWrap').selectAll('*').remove();
|
8564
8618
|
} else {
|
8565
|
-
|
8619
|
+
if (legendPosition === 'bottom') {
|
8620
|
+
legend.width(availableWidth - margin.right);
|
8566
8621
|
|
8567
|
-
|
8568
|
-
|
8569
|
-
|
8622
|
+
g.select('.nv-legendWrap')
|
8623
|
+
.datum(data)
|
8624
|
+
.call(legend);
|
8570
8625
|
|
8571
|
-
|
8572
|
-
|
8573
|
-
|
8574
|
-
|
8626
|
+
margin.bottom = xAxis.height() + legend.height();
|
8627
|
+
availableHeight = nv.utils.availableHeight(height, container, margin);
|
8628
|
+
g.select('.nv-legendWrap')
|
8629
|
+
.attr('transform', 'translate(0,' + (availableHeight + xAxis.height()) +')');
|
8630
|
+
} else {
|
8631
|
+
legend.width(availableWidth - controlWidth());
|
8575
8632
|
|
8576
|
-
|
8577
|
-
|
8633
|
+
g.select('.nv-legendWrap')
|
8634
|
+
.datum(data)
|
8635
|
+
.call(legend);
|
8636
|
+
|
8637
|
+
if (!marginTop && legend.height() !== margin.top) {
|
8638
|
+
margin.top = legend.height();
|
8639
|
+
availableHeight = nv.utils.availableHeight(height, container, margin);
|
8640
|
+
}
|
8641
|
+
|
8642
|
+
g.select('.nv-legendWrap')
|
8643
|
+
.attr('transform', 'translate(' + controlWidth() + ',' + (-margin.top) +')');
|
8644
|
+
}
|
8578
8645
|
}
|
8579
8646
|
|
8580
8647
|
// Controls
|
@@ -8835,6 +8902,7 @@ nv.models.multiBarChart = function() {
|
|
8835
8902
|
width: {get: function(){return width;}, set: function(_){width=_;}},
|
8836
8903
|
height: {get: function(){return height;}, set: function(_){height=_;}},
|
8837
8904
|
showLegend: {get: function(){return showLegend;}, set: function(_){showLegend=_;}},
|
8905
|
+
legendPosition: {get: function(){return legendPosition;}, set: function(_){legendPosition=_;}},
|
8838
8906
|
showControls: {get: function(){return showControls;}, set: function(_){showControls=_;}},
|
8839
8907
|
controlLabels: {get: function(){return controlLabels;}, set: function(_){controlLabels=_;}},
|
8840
8908
|
showXAxis: {get: function(){return showXAxis;}, set: function(_){showXAxis=_;}},
|
@@ -9095,13 +9163,13 @@ nv.models.multiBarHorizontal = function() {
|
|
9095
9163
|
var xerr = getYerr(d,i)
|
9096
9164
|
, mid = 0.8 * x.rangeBand() / ((stacked ? 1 : data.length) * 2);
|
9097
9165
|
xerr = xerr.length ? xerr : [-Math.abs(xerr), Math.abs(xerr)];
|
9098
|
-
xerr = xerr.map(function(e) { return y(e) - y(0); });
|
9166
|
+
xerr = xerr.map(function(e) { return y(e + ((getY(d,i) < 0) ? 0 : getY(d,i))) - y(0); });
|
9099
9167
|
var a = [[xerr[0],-mid], [xerr[0],mid], [xerr[0],0], [xerr[1],0], [xerr[1],-mid], [xerr[1],mid]];
|
9100
9168
|
return a.map(function (path) { return path.join(',') }).join(' ');
|
9101
9169
|
})
|
9102
9170
|
.attr('transform', function(d,i) {
|
9103
9171
|
var mid = x.rangeBand() / ((stacked ? 1 : data.length) * 2);
|
9104
|
-
return 'translate(
|
9172
|
+
return 'translate(0, ' + mid + ')';
|
9105
9173
|
});
|
9106
9174
|
}
|
9107
9175
|
|
@@ -9269,8 +9337,10 @@ nv.models.multiBarHorizontalChart = function() {
|
|
9269
9337
|
, height = null
|
9270
9338
|
, color = nv.utils.defaultColor()
|
9271
9339
|
, showControls = true
|
9340
|
+
, controlsPosition = 'top'
|
9272
9341
|
, controlLabels = {}
|
9273
9342
|
, showLegend = true
|
9343
|
+
, legendPosition = 'top'
|
9274
9344
|
, showXAxis = true
|
9275
9345
|
, showYAxis = true
|
9276
9346
|
, stacked = false
|
@@ -9407,14 +9477,21 @@ nv.models.multiBarHorizontalChart = function() {
|
|
9407
9477
|
g.select('.nv-legendWrap')
|
9408
9478
|
.datum(data)
|
9409
9479
|
.call(legend);
|
9480
|
+
if (legendPosition === 'bottom') {
|
9481
|
+
margin.bottom = xAxis.height() + legend.height();
|
9482
|
+
availableHeight = nv.utils.availableHeight(height, container, margin);
|
9483
|
+
g.select('.nv-legendWrap')
|
9484
|
+
.attr('transform', 'translate(' + controlWidth() + ',' + (availableHeight + xAxis.height()) +')');
|
9485
|
+
} else if (legendPosition === 'top') {
|
9410
9486
|
|
9411
|
-
|
9412
|
-
|
9413
|
-
|
9414
|
-
|
9487
|
+
if (!marginTop && legend.height() !== margin.top) {
|
9488
|
+
margin.top = legend.height();
|
9489
|
+
availableHeight = nv.utils.availableHeight(height, container, margin);
|
9490
|
+
}
|
9415
9491
|
|
9416
|
-
|
9417
|
-
|
9492
|
+
g.select('.nv-legendWrap')
|
9493
|
+
.attr('transform', 'translate(' + controlWidth() + ',' + (-margin.top) +')');
|
9494
|
+
}
|
9418
9495
|
}
|
9419
9496
|
|
9420
9497
|
// Controls
|
@@ -9427,10 +9504,21 @@ nv.models.multiBarHorizontalChart = function() {
|
|
9427
9504
|
];
|
9428
9505
|
|
9429
9506
|
controls.width(controlWidth()).color(['#444', '#444', '#444']);
|
9430
|
-
|
9431
|
-
|
9432
|
-
|
9433
|
-
|
9507
|
+
|
9508
|
+
if (controlsPosition === 'bottom') {
|
9509
|
+
margin.bottom = xAxis.height() + legend.height();
|
9510
|
+
availableHeight = nv.utils.availableHeight(height, container, margin);
|
9511
|
+
g.select('.nv-controlsWrap')
|
9512
|
+
.datum(controlsData)
|
9513
|
+
.attr('transform', 'translate(0,' + (availableHeight + xAxis.height()) +')')
|
9514
|
+
.call(controls);
|
9515
|
+
|
9516
|
+
} else if (controlsPosition === 'top') {
|
9517
|
+
g.select('.nv-controlsWrap')
|
9518
|
+
.datum(controlsData)
|
9519
|
+
.attr('transform', 'translate(0,' + (-margin.top) +')')
|
9520
|
+
.call(controls);
|
9521
|
+
}
|
9434
9522
|
}
|
9435
9523
|
|
9436
9524
|
wrap.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');
|
@@ -9587,6 +9675,8 @@ nv.models.multiBarHorizontalChart = function() {
|
|
9587
9675
|
width: {get: function(){return width;}, set: function(_){width=_;}},
|
9588
9676
|
height: {get: function(){return height;}, set: function(_){height=_;}},
|
9589
9677
|
showLegend: {get: function(){return showLegend;}, set: function(_){showLegend=_;}},
|
9678
|
+
legendPosition: {get: function(){return legendPosition;}, set: function(_){legendPosition=_;}},
|
9679
|
+
controlsPosition: {get: function(){return controlsPosition;}, set: function(_){controlsPosition=_;}},
|
9590
9680
|
showControls: {get: function(){return showControls;}, set: function(_){showControls=_;}},
|
9591
9681
|
controlLabels: {get: function(){return controlLabels;}, set: function(_){controlLabels=_;}},
|
9592
9682
|
showXAxis: {get: function(){return showXAxis;}, set: function(_){showXAxis=_;}},
|
@@ -9834,17 +9924,36 @@ nv.models.multiChart = function() {
|
|
9834
9924
|
var stack2Wrap = g.select('.stack2Wrap')
|
9835
9925
|
.datum(dataStack2.filter(function(d){return !d.disabled}));
|
9836
9926
|
|
9837
|
-
var
|
9838
|
-
|
9839
|
-
|
9840
|
-
|
9841
|
-
|
9842
|
-
|
9843
|
-
|
9844
|
-
|
9927
|
+
var extraValue1BarStacked = [];
|
9928
|
+
if (bars1.stacked() && dataBars1.length) {
|
9929
|
+
var extraValue1BarStacked = dataBars1.filter(function(d){return !d.disabled}).map(function(a){return a.values});
|
9930
|
+
|
9931
|
+
if (extraValue1BarStacked.length > 0)
|
9932
|
+
extraValue1BarStacked = extraValue1BarStacked.reduce(function(a,b){
|
9933
|
+
return a.map(function(aVal,i){return {x: aVal.x, y: aVal.y + b[i].y}})
|
9934
|
+
});
|
9935
|
+
}
|
9936
|
+
if (dataBars1.length) {
|
9937
|
+
extraValue1BarStacked.push({x:0, y:0});
|
9938
|
+
}
|
9939
|
+
|
9940
|
+
var extraValue2BarStacked = [];
|
9941
|
+
if (bars2.stacked() && dataBars2.length) {
|
9942
|
+
var extraValue2BarStacked = dataBars2.filter(function(d){return !d.disabled}).map(function(a){return a.values});
|
9943
|
+
|
9944
|
+
if (extraValue2BarStacked.length > 0)
|
9945
|
+
extraValue2BarStacked = extraValue2BarStacked.reduce(function(a,b){
|
9946
|
+
return a.map(function(aVal,i){return {x: aVal.x, y: aVal.y + b[i].y}})
|
9947
|
+
});
|
9948
|
+
}
|
9949
|
+
if (dataBars2.length) {
|
9950
|
+
extraValue2BarStacked.push({x:0, y:0});
|
9951
|
+
}
|
9952
|
+
|
9953
|
+
yScale1 .domain(yDomain1 || d3.extent(d3.merge(series1).concat(extraValue1BarStacked), function(d) { return d.y } ))
|
9845
9954
|
.range([0, availableHeight]);
|
9846
9955
|
|
9847
|
-
yScale2 .domain(yDomain2 || d3.extent(d3.merge(series2).concat(
|
9956
|
+
yScale2 .domain(yDomain2 || d3.extent(d3.merge(series2).concat(extraValue2BarStacked), function(d) { return d.y } ))
|
9848
9957
|
.range([0, availableHeight]);
|
9849
9958
|
|
9850
9959
|
lines1.yDomain(yScale1.domain());
|
@@ -9920,7 +10029,7 @@ nv.models.multiChart = function() {
|
|
9920
10029
|
//------------------------------------------------------------
|
9921
10030
|
|
9922
10031
|
function mouseover_line(evt) {
|
9923
|
-
var yaxis =
|
10032
|
+
var yaxis = evt.series.yAxis === 2 ? yAxis2 : yAxis1;
|
9924
10033
|
evt.value = evt.point.x;
|
9925
10034
|
evt.series = {
|
9926
10035
|
value: evt.point.y,
|
@@ -9940,7 +10049,7 @@ nv.models.multiChart = function() {
|
|
9940
10049
|
}
|
9941
10050
|
|
9942
10051
|
function mouseover_scatter(evt) {
|
9943
|
-
var yaxis =
|
10052
|
+
var yaxis = evt.series.yAxis === 2 ? yAxis2 : yAxis1;
|
9944
10053
|
evt.value = evt.point.x;
|
9945
10054
|
evt.series = {
|
9946
10055
|
value: evt.point.y,
|
@@ -9960,7 +10069,7 @@ nv.models.multiChart = function() {
|
|
9960
10069
|
}
|
9961
10070
|
|
9962
10071
|
function mouseover_stack(evt) {
|
9963
|
-
var yaxis =
|
10072
|
+
var yaxis = evt.series.yAxis === 2 ? yAxis2 : yAxis1;
|
9964
10073
|
evt.point['x'] = stack1.x()(evt.point);
|
9965
10074
|
evt.point['y'] = stack1.y()(evt.point);
|
9966
10075
|
tooltip
|
@@ -9976,7 +10085,7 @@ nv.models.multiChart = function() {
|
|
9976
10085
|
}
|
9977
10086
|
|
9978
10087
|
function mouseover_bar(evt) {
|
9979
|
-
var yaxis =
|
10088
|
+
var yaxis = evt.series.yAxis === 2 ? yAxis2 : yAxis1;
|
9980
10089
|
|
9981
10090
|
evt.value = bars1.x()(evt.data);
|
9982
10091
|
evt['series'] = {
|
@@ -11266,6 +11375,7 @@ nv.models.pie = function() {
|
|
11266
11375
|
, labelsOutside = false
|
11267
11376
|
, labelType = "key"
|
11268
11377
|
, labelThreshold = .02 //if slice percentage is under this, don't show label
|
11378
|
+
, hideOverlapLabels = false //Hide labels that don't fit in slice
|
11269
11379
|
, donut = false
|
11270
11380
|
, title = false
|
11271
11381
|
, growOnHover = true
|
@@ -11302,7 +11412,7 @@ nv.models.pie = function() {
|
|
11302
11412
|
|
11303
11413
|
container = d3.select(this)
|
11304
11414
|
if (arcsRadius.length === 0) {
|
11305
|
-
var outer = radius - radius /
|
11415
|
+
var outer = radius - radius / 10;
|
11306
11416
|
var inner = donutRatio * radius;
|
11307
11417
|
for (var i = 0; i < data[0].length; i++) {
|
11308
11418
|
arcsRadiusOuter.push(outer);
|
@@ -11310,9 +11420,9 @@ nv.models.pie = function() {
|
|
11310
11420
|
}
|
11311
11421
|
} else {
|
11312
11422
|
if(growOnHover){
|
11313
|
-
arcsRadiusOuter = arcsRadius.map(function (d) { return (d.outer - d.outer /
|
11314
|
-
arcsRadiusInner = arcsRadius.map(function (d) { return (d.inner - d.inner /
|
11315
|
-
donutRatio = d3.min(arcsRadius.map(function (d) { return (d.inner - d.inner /
|
11423
|
+
arcsRadiusOuter = arcsRadius.map(function (d) { return (d.outer - d.outer / 10) * radius; });
|
11424
|
+
arcsRadiusInner = arcsRadius.map(function (d) { return (d.inner - d.inner / 10) * radius; });
|
11425
|
+
donutRatio = d3.min(arcsRadius.map(function (d) { return (d.inner - d.inner / 10); }));
|
11316
11426
|
} else {
|
11317
11427
|
arcsRadiusOuter = arcsRadius.map(function (d) { return d.outer * radius; });
|
11318
11428
|
arcsRadiusInner = arcsRadius.map(function (d) { return d.inner * radius; });
|
@@ -11587,6 +11697,44 @@ nv.models.pie = function() {
|
|
11587
11697
|
return label;
|
11588
11698
|
})
|
11589
11699
|
;
|
11700
|
+
|
11701
|
+
if (hideOverlapLabels) {
|
11702
|
+
pieLabels
|
11703
|
+
.each(function (d, i) {
|
11704
|
+
if (!this.getBBox) return;
|
11705
|
+
var bb = this.getBBox(),
|
11706
|
+
center = labelsArc[i].centroid(d);
|
11707
|
+
var topLeft = {
|
11708
|
+
x : center[0] + bb.x,
|
11709
|
+
y : center[1] + bb.y
|
11710
|
+
};
|
11711
|
+
|
11712
|
+
var topRight = {
|
11713
|
+
x : topLeft.x + bb.width,
|
11714
|
+
y : topLeft.y
|
11715
|
+
};
|
11716
|
+
|
11717
|
+
var bottomLeft = {
|
11718
|
+
x : topLeft.x,
|
11719
|
+
y : topLeft.y + bb.height
|
11720
|
+
};
|
11721
|
+
|
11722
|
+
var bottomRight = {
|
11723
|
+
x : topLeft.x + bb.width,
|
11724
|
+
y : topLeft.y + bb.height
|
11725
|
+
};
|
11726
|
+
|
11727
|
+
d.visible = nv.utils.pointIsInArc(topLeft, d, arc) &&
|
11728
|
+
nv.utils.pointIsInArc(topRight, d, arc) &&
|
11729
|
+
nv.utils.pointIsInArc(bottomLeft, d, arc) &&
|
11730
|
+
nv.utils.pointIsInArc(bottomRight, d, arc);
|
11731
|
+
})
|
11732
|
+
.style('display', function (d) {
|
11733
|
+
return d.visible ? null : 'none';
|
11734
|
+
})
|
11735
|
+
;
|
11736
|
+
}
|
11737
|
+
|
11590
11738
|
}
|
11591
11739
|
|
11592
11740
|
|
@@ -11628,6 +11776,7 @@ nv.models.pie = function() {
|
|
11628
11776
|
title: {get: function(){return title;}, set: function(_){title=_;}},
|
11629
11777
|
titleOffset: {get: function(){return titleOffset;}, set: function(_){titleOffset=_;}},
|
11630
11778
|
labelThreshold: {get: function(){return labelThreshold;}, set: function(_){labelThreshold=_;}},
|
11779
|
+
hideOverlapLabels: {get: function(){return hideOverlapLabels;}, set: function(_){hideOverlapLabels=_;}},
|
11631
11780
|
valueFormat: {get: function(){return valueFormat;}, set: function(_){valueFormat=_;}},
|
11632
11781
|
x: {get: function(){return getX;}, set: function(_){getX=_;}},
|
11633
11782
|
id: {get: function(){return id;}, set: function(_){id=_;}},
|
@@ -11823,6 +11972,16 @@ nv.models.pieChart = function() {
|
|
11823
11972
|
.datum(data)
|
11824
11973
|
.call(legend)
|
11825
11974
|
.attr('transform', 'translate(' + (availableWidth) +',0)');
|
11975
|
+
} else if (legendPosition === "bottom") {
|
11976
|
+
legend.width( availableWidth ).key(pie.x());
|
11977
|
+
wrap.select('.nv-legendWrap')
|
11978
|
+
.datum(data)
|
11979
|
+
.call(legend);
|
11980
|
+
|
11981
|
+
margin.bottom = legend.height();
|
11982
|
+
availableHeight = nv.utils.availableHeight(height, container, margin);
|
11983
|
+
wrap.select('.nv-legendWrap')
|
11984
|
+
.attr('transform', 'translate(0,' + availableHeight +')');
|
11826
11985
|
}
|
11827
11986
|
}
|
11828
11987
|
wrap.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');
|
@@ -12548,6 +12707,7 @@ nv.models.scatter = function() {
|
|
12548
12707
|
//------------------------------------------------------------
|
12549
12708
|
|
12550
12709
|
var x0, y0, z0 // used to store previous scales
|
12710
|
+
, xDom, yDom // used to store previous domains
|
12551
12711
|
, width0
|
12552
12712
|
, height0
|
12553
12713
|
, timeoutID
|
@@ -12557,6 +12717,31 @@ nv.models.scatter = function() {
|
|
12557
12717
|
, _cache = {}
|
12558
12718
|
;
|
12559
12719
|
|
12720
|
+
//============================================================
|
12721
|
+
// Diff and Cache Utilities
|
12722
|
+
//------------------------------------------------------------
|
12723
|
+
// getDiffs is used to filter unchanged points from the update
|
12724
|
+
// selection. It implicitly updates it's cache when called and
|
12725
|
+
// therefor the diff is based upon the previous invocation NOT
|
12726
|
+
// the previous update.
|
12727
|
+
//
|
12728
|
+
// getDiffs takes a point as its first argument followed by n
|
12729
|
+
// key getter pairs (d, [key, get... key, get]) this approach
|
12730
|
+
// was chosen for efficiency. (The filter will call it a LOT).
|
12731
|
+
//
|
12732
|
+
// It is important to call delCache on point exit to prevent a
|
12733
|
+
// memory leak. It is also needed to prevent invalid caches if
|
12734
|
+
// a new point uses the same series and point id key.
|
12735
|
+
//
|
12736
|
+
// Argument Performance Concerns:
|
12737
|
+
// - Object property lists for key getter pairs would be very
|
12738
|
+
// expensive (points * objects for the GC every update).
|
12739
|
+
// - ES6 function names for implicit keys would be nice but
|
12740
|
+
// they are not guaranteed to be unique.
|
12741
|
+
// - function.toString to obtain implicit keys is possible
|
12742
|
+
// but long object keys are not free (internal hash).
|
12743
|
+
// - Explicit key without objects are the most efficient.
|
12744
|
+
|
12560
12745
|
function getCache(d) {
|
12561
12746
|
var key, val;
|
12562
12747
|
key = d[0].series + ':' + d[1];
|
@@ -12602,7 +12787,7 @@ nv.models.scatter = function() {
|
|
12602
12787
|
});
|
12603
12788
|
|
12604
12789
|
// Setup Scales
|
12605
|
-
var logScale = chart.yScale().
|
12790
|
+
var logScale = (typeof(chart.yScale().base) === "function"); // Only log scale has a method "base()"
|
12606
12791
|
// remap and flatten the data for use in calculating the scales' domains
|
12607
12792
|
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
|
12608
12793
|
d3.merge(
|
@@ -12669,6 +12854,16 @@ nv.models.scatter = function() {
|
|
12669
12854
|
|
12670
12855
|
var sizeDiff = width0 !== width || height0 !== height;
|
12671
12856
|
|
12857
|
+
// Domain Diffs
|
12858
|
+
|
12859
|
+
xDom = xDom || [];
|
12860
|
+
var domainDiff = xDom[0] !== x.domain()[0] || xDom[1] !== x.domain()[1];
|
12861
|
+
xDom = x.domain();
|
12862
|
+
|
12863
|
+
yDom = yDom || [];
|
12864
|
+
domainDiff = domainDiff || yDom[0] !== y.domain()[0] || yDom[1] !== y.domain()[1];
|
12865
|
+
yDom = y.domain();
|
12866
|
+
|
12672
12867
|
// Setup containers and skeleton of chart
|
12673
12868
|
var wrap = container.selectAll('g.nv-wrap.nv-scatter').data([data]);
|
12674
12869
|
var wrapEnter = wrap.enter().append('g').attr('class', 'nvd3 nv-wrap nv-scatter nv-chart-' + id);
|
@@ -12687,7 +12882,7 @@ nv.models.scatter = function() {
|
|
12687
12882
|
.attr('id', 'nv-edge-clip-' + id)
|
12688
12883
|
.append('rect')
|
12689
12884
|
.attr('transform', 'translate( -10, -10)');
|
12690
|
-
|
12885
|
+
|
12691
12886
|
wrap.select('#nv-edge-clip-' + id + ' rect')
|
12692
12887
|
.attr('width', availableWidth + 20)
|
12693
12888
|
.attr('height', (availableHeight > 0) ? availableHeight + 20 : 0);
|
@@ -12703,20 +12898,23 @@ nv.models.scatter = function() {
|
|
12703
12898
|
|
12704
12899
|
// inject series and point index for reference into voronoi
|
12705
12900
|
if (useVoronoi === true) {
|
12901
|
+
|
12902
|
+
// nuke all voronoi paths on reload and recreate them
|
12903
|
+
wrap.select('.nv-point-paths').selectAll('path').remove();
|
12904
|
+
|
12706
12905
|
var vertices = d3.merge(data.map(function(group, groupIndex) {
|
12707
12906
|
return group.values
|
12708
12907
|
.map(function(point, pointIndex) {
|
12709
12908
|
// *Adding noise to make duplicates very unlikely
|
12710
12909
|
// *Injecting series and point index for reference
|
12711
|
-
|
12712
|
-
*/
|
12910
|
+
// *Adding a 'jitter' to the points, because there's an issue in d3.geom.voronoi.
|
12713
12911
|
var pX = getX(point,pointIndex);
|
12714
12912
|
var pY = getY(point,pointIndex);
|
12715
12913
|
|
12716
|
-
return [nv.utils.NaNtoZero(x(pX))+ Math.random() * 1e-4,
|
12717
|
-
nv.utils.NaNtoZero(y(pY))+ Math.random() * 1e-4,
|
12914
|
+
return [nv.utils.NaNtoZero(x(pX)) + Math.random() * 1e-4,
|
12915
|
+
nv.utils.NaNtoZero(y(pY)) + Math.random() * 1e-4,
|
12718
12916
|
groupIndex,
|
12719
|
-
pointIndex, point];
|
12917
|
+
pointIndex, point];
|
12720
12918
|
})
|
12721
12919
|
.filter(function(pointArray, pointIndex) {
|
12722
12920
|
return pointActive(pointArray[4], pointIndex); // Issue #237.. move filter to after map, so pointIndex is correct!
|
@@ -12742,6 +12940,18 @@ nv.models.scatter = function() {
|
|
12742
12940
|
[width + 10,-10]
|
12743
12941
|
]);
|
12744
12942
|
|
12943
|
+
// delete duplicates from vertices - essential assumption for d3.geom.voronoi
|
12944
|
+
var epsilon = 1e-4; // Uses 1e-4 to determine equivalence.
|
12945
|
+
vertices = vertices.sort(function(a,b){return ((a[0] - b[0]) || (a[1] - b[1]))});
|
12946
|
+
for (var i = 0; i < vertices.length - 1; ) {
|
12947
|
+
if ((Math.abs(vertices[i][0] - vertices[i+1][0]) < epsilon) &&
|
12948
|
+
(Math.abs(vertices[i][1] - vertices[i+1][1]) < epsilon)) {
|
12949
|
+
vertices.splice(i+1, 1);
|
12950
|
+
} else {
|
12951
|
+
i++;
|
12952
|
+
}
|
12953
|
+
}
|
12954
|
+
|
12745
12955
|
var voronoi = d3.geom.voronoi(vertices).map(function(d, i) {
|
12746
12956
|
return {
|
12747
12957
|
'data': bounds.clip(d),
|
@@ -12750,8 +12960,6 @@ nv.models.scatter = function() {
|
|
12750
12960
|
}
|
12751
12961
|
});
|
12752
12962
|
|
12753
|
-
// nuke all voronoi paths on reload and recreate them
|
12754
|
-
wrap.select('.nv-point-paths').selectAll('path').remove();
|
12755
12963
|
var pointPaths = wrap.select('.nv-point-paths').selectAll('path').data(voronoi);
|
12756
12964
|
var vPointPaths = pointPaths
|
12757
12965
|
.enter().append("svg:path")
|
@@ -12957,20 +13165,47 @@ nv.models.scatter = function() {
|
|
12957
13165
|
return 'translate(' + nv.utils.NaNtoZero(x(getX(d[0],d[1]))) + ',' + nv.utils.NaNtoZero(y(getY(d[0],d[1]))) + ')'
|
12958
13166
|
})
|
12959
13167
|
.remove();
|
12960
|
-
|
12961
|
-
|
12962
|
-
|
12963
|
-
|
12964
|
-
|
12965
|
-
|
12966
|
-
|
12967
|
-
//
|
12968
|
-
|
12969
|
-
|
12970
|
-
|
12971
|
-
|
12972
|
-
|
12973
|
-
|
13168
|
+
|
13169
|
+
//============================================================
|
13170
|
+
// Point Update Optimisation Notes
|
13171
|
+
//------------------------------------------------------------
|
13172
|
+
// The following update selections are filtered with getDiffs
|
13173
|
+
// (defined at the top of this file) this brings a performance
|
13174
|
+
// benefit for charts with large data sets that accumulate a
|
13175
|
+
// subset of changes or additions over time.
|
13176
|
+
//
|
13177
|
+
// Uneccesary and expensive DOM calls are avoided by culling
|
13178
|
+
// unchanged points from the selection in exchange for the
|
13179
|
+
// cheaper overhead of caching and diffing each point first.
|
13180
|
+
//
|
13181
|
+
// Due to the way D3 and NVD3 work, other global changes need
|
13182
|
+
// to be considered in addition to local point properties.
|
13183
|
+
// This is a potential source of bugs (if any of the global
|
13184
|
+
// changes that possibly affect points are missed).
|
13185
|
+
|
13186
|
+
// Update Point Positions [x, y]
|
13187
|
+
points.filter(function (d) {
|
13188
|
+
// getDiffs must always be called to update cache
|
13189
|
+
return getDiffs(d, 'x', getX, 'y', getY) ||
|
13190
|
+
scaleDiff || sizeDiff || domainDiff;
|
13191
|
+
})
|
13192
|
+
.watchTransition(renderWatch, 'scatter points')
|
13193
|
+
.attr('transform', function (d) {
|
13194
|
+
return 'translate(' +
|
13195
|
+
nv.utils.NaNtoZero(x(getX(d[0], d[1]))) + ',' +
|
13196
|
+
nv.utils.NaNtoZero(y(getY(d[0], d[1]))) + ')'
|
13197
|
+
});
|
13198
|
+
|
13199
|
+
// Update Point Appearance [shape, size]
|
13200
|
+
points.filter(function (d) {
|
13201
|
+
// getDiffs must always be called to update cache
|
13202
|
+
return getDiffs(d, 'shape', getShape, 'size', getSize) ||
|
13203
|
+
scaleDiff || sizeDiff || domainDiff;
|
13204
|
+
})
|
13205
|
+
.watchTransition(renderWatch, 'scatter points')
|
13206
|
+
.attr('d', nv.utils.symbol()
|
13207
|
+
.type(function (d) { return getShape(d[0]) })
|
13208
|
+
.size(function (d) { return z(getSize(d[0], d[1])) })
|
12974
13209
|
);
|
12975
13210
|
|
12976
13211
|
// add label a label to scatter chart
|
@@ -14625,7 +14860,7 @@ nv.models.stackedAreaChart = function() {
|
|
14625
14860
|
|
14626
14861
|
interactiveLayer.dispatch.on('elementMousemove', function(e) {
|
14627
14862
|
stacked.clearHighlights();
|
14628
|
-
var singlePoint, pointIndex, pointXLocation, allData = [], valueSum = 0, allNullValues = true;
|
14863
|
+
var singlePoint, pointIndex, pointXLocation, allData = [], valueSum = 0, allNullValues = true, atleastOnePoint = false;
|
14629
14864
|
data
|
14630
14865
|
.filter(function(series, i) {
|
14631
14866
|
series.seriesIndex = i;
|
@@ -14635,7 +14870,13 @@ nv.models.stackedAreaChart = function() {
|
|
14635
14870
|
pointIndex = nv.interactiveBisect(series.values, e.pointXValue, chart.x());
|
14636
14871
|
var point = series.values[pointIndex];
|
14637
14872
|
var pointYValue = chart.y()(point, pointIndex);
|
14638
|
-
if (pointYValue != null) {
|
14873
|
+
if (pointYValue != null && pointYValue > 0) {
|
14874
|
+
stacked.highlightPoint(i, pointIndex, true);
|
14875
|
+
atleastOnePoint = true;
|
14876
|
+
}
|
14877
|
+
|
14878
|
+
// Draw at least one point if all values are zero.
|
14879
|
+
if (i === (data.length - 1) && !atleastOnePoint) {
|
14639
14880
|
stacked.highlightPoint(i, pointIndex, true);
|
14640
14881
|
}
|
14641
14882
|
if (typeof point === 'undefined') return;
|
@@ -14914,7 +15155,13 @@ nv.models.sunburst = function() {
|
|
14914
15155
|
, labelFormat = function(d){if(mode === 'count'){return d.name + ' #' + d.value}else{return d.name + ' ' + (d.value || d.size)}}
|
14915
15156
|
, labelThreshold = 0.02
|
14916
15157
|
, sort = function(d1, d2){return d1.name > d2.name;}
|
14917
|
-
, key = function(d,i){
|
15158
|
+
, key = function(d,i){
|
15159
|
+
if (d.parent !== undefined) {
|
15160
|
+
return d.name + '-' + d.parent.name + '-' + i;
|
15161
|
+
} else {
|
15162
|
+
return d.name;
|
15163
|
+
}
|
15164
|
+
}
|
14918
15165
|
, groupColorByParent = true
|
14919
15166
|
, duration = 500
|
14920
15167
|
, dispatch = d3.dispatch('chartClick', 'elementClick', 'elementDblClick', 'elementMousemove', 'elementMouseover', 'elementMouseout', 'renderEnd');
|
@@ -15420,6 +15667,6 @@ nv.models.sunburstChart = function() {
|
|
15420
15667
|
|
15421
15668
|
};
|
15422
15669
|
|
15423
|
-
nv.version = "1.8.
|
15670
|
+
nv.version = "1.8.6";
|
15424
15671
|
})();
|
15425
15672
|
//# sourceMappingURL=nv.d3.js.map
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: novus-nvd3-rails
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.8.
|
4
|
+
version: 1.8.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- dbackowski
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2017-09-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -183,7 +183,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
183
183
|
version: '0'
|
184
184
|
requirements: []
|
185
185
|
rubyforge_project:
|
186
|
-
rubygems_version: 2.
|
186
|
+
rubygems_version: 2.6.11
|
187
187
|
signing_key:
|
188
188
|
specification_version: 4
|
189
189
|
summary: Nvd3 - reusable chart library for d3.js.
|