d3pie-rails 0.1.9 → 0.2.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +3 -0
- data/Gemfile +1 -1
- data/Gemfile.lock +4 -4
- data/README.md +1 -1
- data/app/assets/javascripts/d3pie.js +232 -210
- data/app/assets/javascripts/d3pie.min.js +4 -4
- data/d3pie-rails.gemspec +1 -1
- data/lib/d3pie/rails/version.rb +1 -1
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b10fe848d614c537fdfcbd5dad6660a3a3e067d6
|
4
|
+
data.tar.gz: 9e67fb6ac16d3f92565b9da55b9505d2d13e5d5d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c80a9530b82d2e6598c72df18148259fe78e213ac3dc4b4e4f3ff2305b835ad0194acb5237460a35ca26eea5e560c940bd1041b88fe0e50c7f322af6f669f29f
|
7
|
+
data.tar.gz: 43d499310cd0bfa06f339f589072e257c423f150e376b2374cdbc5dc19a408a3c48a7423a5064bc43101865e80967ff95a5c65676fb03a3f89b2a81735430768
|
data/CHANGELOG.md
CHANGED
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
d3pie-rails (0.1
|
5
|
-
d3-rails (>=
|
4
|
+
d3pie-rails (0.2.1)
|
5
|
+
d3-rails (>= 4.1)
|
6
6
|
railties (>= 3.1)
|
7
7
|
|
8
8
|
GEM
|
@@ -45,7 +45,7 @@ GEM
|
|
45
45
|
tzinfo (~> 1.1)
|
46
46
|
arel (6.0.3)
|
47
47
|
builder (3.2.2)
|
48
|
-
d3-rails (
|
48
|
+
d3-rails (4.7.0)
|
49
49
|
railties (>= 3.1)
|
50
50
|
erubis (2.7.0)
|
51
51
|
globalid (0.3.6)
|
@@ -104,6 +104,6 @@ PLATFORMS
|
|
104
104
|
ruby
|
105
105
|
|
106
106
|
DEPENDENCIES
|
107
|
-
d3-rails (>=
|
107
|
+
d3-rails (>= 4.1)
|
108
108
|
d3pie-rails!
|
109
109
|
rails (>= 3.1)
|
data/README.md
CHANGED
@@ -15,7 +15,7 @@ d3pie-rails provides d3pie for Rails 3.1 and higher.
|
|
15
15
|
|
16
16
|
## Version
|
17
17
|
|
18
|
-
d3pie-rails comes with version 0.1
|
18
|
+
d3pie-rails comes with version 0.2.1 of d3pie.js. The d3pie-rails version will
|
19
19
|
always mirror the version of d3pie. If you need a newer version of
|
20
20
|
d3pie-rails, see section Development (below).
|
21
21
|
|
@@ -22,7 +22,7 @@
|
|
22
22
|
}(this, function() {
|
23
23
|
|
24
24
|
var _scriptName = "d3pie";
|
25
|
-
var _version = "0.1
|
25
|
+
var _version = "0.2.1";
|
26
26
|
|
27
27
|
// used to uniquely generate IDs and classes, ensuring no conflict between multiple pies on the same page
|
28
28
|
var _uniqueIDCounter = 0;
|
@@ -598,13 +598,13 @@ var math = {
|
|
598
598
|
var h = size.canvasHeight - canvasPadding.top - canvasPadding.bottom;
|
599
599
|
|
600
600
|
// now factor in the footer, title & subtitle
|
601
|
-
|
602
|
-
|
603
|
-
|
601
|
+
if (pie.options.header.location !== "pie-center") {
|
602
|
+
h -= pie.textComponents.headerHeight;
|
603
|
+
}
|
604
604
|
|
605
|
-
|
606
|
-
|
607
|
-
|
605
|
+
if (pie.textComponents.footer.exists) {
|
606
|
+
h -= pie.textComponents.footer.h;
|
607
|
+
}
|
608
608
|
|
609
609
|
// for really teeny pies, h may be < 0. Adjust it back
|
610
610
|
h = (h < 0) ? 0 : h;
|
@@ -685,8 +685,6 @@ var math = {
|
|
685
685
|
return data;
|
686
686
|
},
|
687
687
|
|
688
|
-
|
689
|
-
|
690
688
|
// var pieCenter = math.getPieCenter();
|
691
689
|
getPieTranslateCenter: function(pieCenter) {
|
692
690
|
return "translate(" + pieCenter.x + "," + pieCenter.y + ")";
|
@@ -809,7 +807,7 @@ var labels = {
|
|
809
807
|
.attr("class", pie.cssPrefix + "labelGroup-" + section)
|
810
808
|
.style("opacity", 0);
|
811
809
|
|
812
|
-
|
810
|
+
var formatterContext = { section: section, sectionDisplayType: sectionDisplayType };
|
813
811
|
|
814
812
|
// 1. Add the main label
|
815
813
|
if (include.mainLabel) {
|
@@ -819,18 +817,18 @@ var labels = {
|
|
819
817
|
.text(function(d, i) {
|
820
818
|
var str = d.label;
|
821
819
|
|
822
|
-
|
823
|
-
|
820
|
+
// if a custom formatter has been defined, pass it the raw label string - it can do whatever it wants with it.
|
821
|
+
// we only apply truncation if it's not defined
|
824
822
|
if (settings.formatter) {
|
825
|
-
|
826
|
-
|
827
|
-
|
828
|
-
|
829
|
-
|
830
|
-
|
831
|
-
|
832
|
-
|
833
|
-
|
823
|
+
formatterContext.index = i;
|
824
|
+
formatterContext.part = 'mainLabel';
|
825
|
+
formatterContext.value = d.value;
|
826
|
+
formatterContext.label = str;
|
827
|
+
str = settings.formatter(formatterContext);
|
828
|
+
} else if (settings.truncation.enabled && d.label.length > settings.truncation.truncateLength) {
|
829
|
+
str = d.label.substring(0, settings.truncation.truncateLength) + "...";
|
830
|
+
}
|
831
|
+
return str;
|
834
832
|
})
|
835
833
|
.style("font-size", settings.mainLabel.fontSize + "px")
|
836
834
|
.style("font-family", settings.mainLabel.font)
|
@@ -843,17 +841,17 @@ var labels = {
|
|
843
841
|
.attr("id", function(d, i) { return pie.cssPrefix + "segmentPercentage" + i + "-" + section; })
|
844
842
|
.attr("class", pie.cssPrefix + "segmentPercentage-" + section)
|
845
843
|
.text(function(d, i) {
|
846
|
-
var percentage =
|
847
|
-
|
848
|
-
|
849
|
-
|
850
|
-
|
851
|
-
|
852
|
-
|
853
|
-
|
854
|
-
|
855
|
-
|
856
|
-
|
844
|
+
var percentage = d.percentage;
|
845
|
+
if (settings.formatter) {
|
846
|
+
formatterContext.index = i;
|
847
|
+
formatterContext.part = "percentage";
|
848
|
+
formatterContext.value = d.value;
|
849
|
+
formatterContext.label = d.percentage;
|
850
|
+
percentage = settings.formatter(formatterContext);
|
851
|
+
} else {
|
852
|
+
percentage += "%";
|
853
|
+
}
|
854
|
+
return percentage;
|
857
855
|
})
|
858
856
|
.style("font-size", settings.percentage.fontSize + "px")
|
859
857
|
.style("font-family", settings.percentage.font)
|
@@ -866,12 +864,12 @@ var labels = {
|
|
866
864
|
.attr("id", function(d, i) { return pie.cssPrefix + "segmentValue" + i + "-" + section; })
|
867
865
|
.attr("class", pie.cssPrefix + "segmentValue-" + section)
|
868
866
|
.text(function(d, i) {
|
869
|
-
|
870
|
-
|
871
|
-
|
872
|
-
|
873
|
-
|
874
|
-
|
867
|
+
formatterContext.index = i;
|
868
|
+
formatterContext.part = "value";
|
869
|
+
formatterContext.value = d.value;
|
870
|
+
formatterContext.label = d.value;
|
871
|
+
return settings.formatter ? settings.formatter(formatterContext, d.value) : d.value;
|
872
|
+
})
|
875
873
|
.style("font-size", settings.value.fontSize + "px")
|
876
874
|
.style("font-family", settings.value.font)
|
877
875
|
.style("fill", settings.value.color);
|
@@ -1001,8 +999,8 @@ var labels = {
|
|
1001
999
|
.append("g")
|
1002
1000
|
.attr("class", pie.cssPrefix + "lineGroup");
|
1003
1001
|
|
1004
|
-
|
1005
|
-
.
|
1002
|
+
var lineFunction = d3.line()
|
1003
|
+
.curve(d3.curveBasis)
|
1006
1004
|
.x(function(d) { return d.x; })
|
1007
1005
|
.y(function(d) { return d.y; });
|
1008
1006
|
|
@@ -1015,8 +1013,7 @@ var labels = {
|
|
1015
1013
|
.attr("fill", "none")
|
1016
1014
|
.style("opacity", function(d, i) {
|
1017
1015
|
var percentage = pie.options.labels.outer.hideWhenLessThanPercentage;
|
1018
|
-
var
|
1019
|
-
var isHidden = (percentage !== null && segmentPercentage < percentage) || pie.options.data.content[i].label === "";
|
1016
|
+
var isHidden = (percentage !== null && d.percentage < percentage) || pie.options.data.content[i].label === "";
|
1020
1017
|
return isHidden ? 0 : 1;
|
1021
1018
|
});
|
1022
1019
|
},
|
@@ -1072,8 +1069,7 @@ var labels = {
|
|
1072
1069
|
.duration(labelFadeInTime)
|
1073
1070
|
.style("opacity", function(d, i) {
|
1074
1071
|
var percentage = pie.options.labels.outer.hideWhenLessThanPercentage;
|
1075
|
-
|
1076
|
-
return (percentage !== null && segmentPercentage < percentage) ? 0 : 1;
|
1072
|
+
return (percentage !== null && d.percentage < percentage) ? 0 : 1;
|
1077
1073
|
});
|
1078
1074
|
|
1079
1075
|
d3.selectAll("." + pie.cssPrefix + "labelGroup-inner")
|
@@ -1081,8 +1077,7 @@ var labels = {
|
|
1081
1077
|
.duration(labelFadeInTime)
|
1082
1078
|
.style("opacity", function(d, i) {
|
1083
1079
|
var percentage = pie.options.labels.inner.hideWhenLessThanPercentage;
|
1084
|
-
|
1085
|
-
return (percentage !== null && segmentPercentage < percentage) ? 0 : 1;
|
1080
|
+
return (percentage !== null && d.percentage < percentage) ? 0 : 1;
|
1086
1081
|
});
|
1087
1082
|
|
1088
1083
|
d3.selectAll("g." + pie.cssPrefix + "lineGroups")
|
@@ -1204,7 +1199,7 @@ var labels = {
|
|
1204
1199
|
|
1205
1200
|
// if there's a conflict with this label group, shift the label to be AFTER the last known
|
1206
1201
|
// one that's been properly placed
|
1207
|
-
if (helpers.rectIntersect(curr, examinedLabelGroup)) {
|
1202
|
+
if (!labels.isLabelHidden(pie, i) && helpers.rectIntersect(curr, examinedLabelGroup)) {
|
1208
1203
|
labels.adjustLabelPos(pie, nextIndex, currLabelGroup, info);
|
1209
1204
|
break;
|
1210
1205
|
}
|
@@ -1216,7 +1211,7 @@ var labels = {
|
|
1216
1211
|
|
1217
1212
|
// if there's a conflict with this label group, shift the label to be AFTER the last known
|
1218
1213
|
// one that's been properly placed
|
1219
|
-
if (helpers.rectIntersect(curr, examinedLabelGroup)) {
|
1214
|
+
if (!labels.isLabelHidden(pie, i) && helpers.rectIntersect(curr, examinedLabelGroup)) {
|
1220
1215
|
labels.adjustLabelPos(pie, nextIndex, currLabelGroup, info);
|
1221
1216
|
break;
|
1222
1217
|
}
|
@@ -1225,6 +1220,11 @@ var labels = {
|
|
1225
1220
|
labels.checkConflict(pie, nextIndex, direction, size);
|
1226
1221
|
},
|
1227
1222
|
|
1223
|
+
isLabelHidden: function(pie, index) {
|
1224
|
+
var percentage = pie.options.labels.outer.hideWhenLessThanPercentage;
|
1225
|
+
return (percentage !== null && d.percentage < percentage) || pie.options.data.content[index].label === "";
|
1226
|
+
},
|
1227
|
+
|
1228
1228
|
// does a little math to shift a label into a new position based on the last properly placed one
|
1229
1229
|
adjustLabelPos: function(pie, nextIndex, lastCorrectlyPositionedLabel, info) {
|
1230
1230
|
var xDiff, yDiff, newXPos, newYPos;
|
@@ -1284,6 +1284,18 @@ var labels = {
|
|
1284
1284
|
//// --------- segments.js -----------
|
1285
1285
|
var segments = {
|
1286
1286
|
|
1287
|
+
effectMap: {
|
1288
|
+
"none": d3.easeLinear,
|
1289
|
+
"bounce": d3.easeBounce,
|
1290
|
+
"linear": d3.easeLinear,
|
1291
|
+
"sin": d3.easeSin,
|
1292
|
+
"elastic": d3.easeElastic,
|
1293
|
+
"back": d3.easeBack,
|
1294
|
+
"quad": d3.easeQuad,
|
1295
|
+
"circle": d3.easeCircle,
|
1296
|
+
"exp": d3.easeExp
|
1297
|
+
},
|
1298
|
+
|
1287
1299
|
/**
|
1288
1300
|
* Creates the pie chart segments and displays them according to the desired load effect.
|
1289
1301
|
* @private
|
@@ -1299,7 +1311,7 @@ var segments = {
|
|
1299
1311
|
.attr("transform", function() { return math.getPieTranslateCenter(pieCenter); })
|
1300
1312
|
.attr("class", pie.cssPrefix + "pieChart");
|
1301
1313
|
|
1302
|
-
var arc = d3.
|
1314
|
+
var arc = d3.arc()
|
1303
1315
|
.innerRadius(pie.innerRadius)
|
1304
1316
|
.outerRadius(pie.outerRadius)
|
1305
1317
|
.startAngle(0)
|
@@ -1331,7 +1343,7 @@ var segments = {
|
|
1331
1343
|
.style("stroke", segmentStroke)
|
1332
1344
|
.style("stroke-width", 1)
|
1333
1345
|
.transition()
|
1334
|
-
.ease(
|
1346
|
+
.ease(d3.easeCubicInOut)
|
1335
1347
|
.duration(loadSpeed)
|
1336
1348
|
.attr("data-index", function(d, i) { return i; })
|
1337
1349
|
.attrTween("d", function(b) {
|
@@ -1383,6 +1395,7 @@ var segments = {
|
|
1383
1395
|
var index = currentEl.attr("data-index");
|
1384
1396
|
segment = d3.select("#" + pie.cssPrefix + "segment" + index);
|
1385
1397
|
}
|
1398
|
+
|
1386
1399
|
var isExpanded = segment.attr("class") === pie.cssPrefix + "expanded";
|
1387
1400
|
segments.onSegmentEvent(pie, pie.options.callbacks.onClickSegment, segment, isExpanded);
|
1388
1401
|
if (pie.options.effects.pullOutSegmentOnClick.effect !== "none") {
|
@@ -1411,18 +1424,18 @@ var segments = {
|
|
1411
1424
|
segment.style("fill", helpers.getColorShade(segColor, pie.options.effects.highlightLuminosity));
|
1412
1425
|
}
|
1413
1426
|
|
1414
|
-
|
1415
|
-
|
1416
|
-
|
1417
|
-
|
1427
|
+
if (pie.options.tooltips.enabled) {
|
1428
|
+
index = segment.attr("data-index");
|
1429
|
+
tt.showTooltip(pie, index);
|
1430
|
+
}
|
1418
1431
|
|
1419
1432
|
var isExpanded = segment.attr("class") === pie.cssPrefix + "expanded";
|
1420
1433
|
segments.onSegmentEvent(pie, pie.options.callbacks.onMouseoverSegment, segment, isExpanded);
|
1421
1434
|
});
|
1422
1435
|
|
1423
|
-
|
1424
|
-
|
1425
|
-
|
1436
|
+
arc.on("mousemove", function() {
|
1437
|
+
tt.moveTooltip(pie);
|
1438
|
+
});
|
1426
1439
|
|
1427
1440
|
arc.on("mouseout", function() {
|
1428
1441
|
var currentEl = d3.select(this);
|
@@ -1444,10 +1457,10 @@ var segments = {
|
|
1444
1457
|
segment.style("fill", color);
|
1445
1458
|
}
|
1446
1459
|
|
1447
|
-
|
1448
|
-
|
1449
|
-
|
1450
|
-
|
1460
|
+
if (pie.options.tooltips.enabled) {
|
1461
|
+
index = segment.attr("data-index");
|
1462
|
+
tt.hideTooltip(pie, index);
|
1463
|
+
}
|
1451
1464
|
|
1452
1465
|
var isExpanded = segment.attr("class") === pie.cssPrefix + "expanded";
|
1453
1466
|
segments.onSegmentEvent(pie, pie.options.callbacks.onMouseoutSegment, segment, isExpanded);
|
@@ -1474,13 +1487,10 @@ var segments = {
|
|
1474
1487
|
}
|
1475
1488
|
pie.isOpeningSegment = true;
|
1476
1489
|
|
1477
|
-
|
1478
|
-
if (d3.selectAll("." + pie.cssPrefix + "expanded").length > 0) {
|
1479
|
-
segments.closeSegment(pie, d3.select("." + pie.cssPrefix + "expanded").node());
|
1480
|
-
}
|
1490
|
+
segments.maybeCloseOpenSegment();
|
1481
1491
|
|
1482
1492
|
d3.select(segment).transition()
|
1483
|
-
.ease(pie.options.effects.pullOutSegmentOnClick.effect)
|
1493
|
+
.ease(segments.effectMap[pie.options.effects.pullOutSegmentOnClick.effect])
|
1484
1494
|
.duration(pie.options.effects.pullOutSegmentOnClick.speed)
|
1485
1495
|
.attr("transform", function(d, i) {
|
1486
1496
|
var c = pie.arc.centroid(d),
|
@@ -1491,19 +1501,25 @@ var segments = {
|
|
1491
1501
|
|
1492
1502
|
return "translate(" + ((x/h) * pullOutSize) + ',' + ((y/h) * pullOutSize) + ")";
|
1493
1503
|
})
|
1494
|
-
.
|
1504
|
+
.on("end", function(d, i) {
|
1495
1505
|
pie.currentlyOpenSegment = segment;
|
1496
1506
|
pie.isOpeningSegment = false;
|
1497
|
-
d3.select(
|
1507
|
+
d3.select(segment).attr("class", pie.cssPrefix + "expanded");
|
1498
1508
|
});
|
1499
1509
|
},
|
1500
1510
|
|
1511
|
+
maybeCloseOpenSegment: function() {
|
1512
|
+
if (d3.selectAll("." + pie.cssPrefix + "expanded").size() > 0) {
|
1513
|
+
segments.closeSegment(pie, d3.select("." + pie.cssPrefix + "expanded").node());
|
1514
|
+
}
|
1515
|
+
},
|
1516
|
+
|
1501
1517
|
closeSegment: function(pie, segment) {
|
1502
1518
|
d3.select(segment).transition()
|
1503
1519
|
.duration(400)
|
1504
1520
|
.attr("transform", "translate(0,0)")
|
1505
|
-
.
|
1506
|
-
d3.select(
|
1521
|
+
.on("end", function(d, i) {
|
1522
|
+
d3.select(segment).attr("class", "");
|
1507
1523
|
pie.currentlyOpenSegment = null;
|
1508
1524
|
});
|
1509
1525
|
},
|
@@ -1555,15 +1571,6 @@ var segments = {
|
|
1555
1571
|
}
|
1556
1572
|
|
1557
1573
|
return angle;
|
1558
|
-
},
|
1559
|
-
|
1560
|
-
getPercentage: function(pie, index, decimalPlaces) {
|
1561
|
-
var relativeAmount = pie.options.data.content[index].value / pie.totalSize;
|
1562
|
-
if (decimalPlaces <= 0) {
|
1563
|
-
return Math.round(relativeAmount * 100);
|
1564
|
-
} else {
|
1565
|
-
return (relativeAmount * 100).toFixed(decimalPlaces);
|
1566
|
-
}
|
1567
1574
|
}
|
1568
1575
|
|
1569
1576
|
};
|
@@ -1573,17 +1580,17 @@ var text = {
|
|
1573
1580
|
offscreenCoord: -10000,
|
1574
1581
|
|
1575
1582
|
addTitle: function(pie) {
|
1583
|
+
|
1584
|
+
|
1576
1585
|
var title = pie.svg.selectAll("." + pie.cssPrefix + "title")
|
1577
1586
|
.data([pie.options.header.title])
|
1578
1587
|
.enter()
|
1579
1588
|
.append("text")
|
1580
1589
|
.text(function(d) { return d.text; })
|
1581
|
-
.attr(
|
1582
|
-
|
1583
|
-
|
1584
|
-
|
1585
|
-
y: text.offscreenCoord
|
1586
|
-
})
|
1590
|
+
.attr("id", pie.cssPrefix + "title")
|
1591
|
+
.attr("class", pie.cssPrefix + "title")
|
1592
|
+
.attr("x", text.offscreenCoord)
|
1593
|
+
.attr("y", text.offscreenCoord)
|
1587
1594
|
.attr("text-anchor", function() {
|
1588
1595
|
var location;
|
1589
1596
|
if (pie.options.header.location === "top-center" || pie.options.header.location === "pie-center") {
|
@@ -1748,126 +1755,120 @@ var text = {
|
|
1748
1755
|
}
|
1749
1756
|
};
|
1750
1757
|
|
1751
|
-
|
1758
|
+
//// --------- validate.js -----------
|
1752
1759
|
var tt = {
|
1753
|
-
|
1760
|
+
addTooltips: function(pie) {
|
1754
1761
|
|
1755
|
-
|
1756
|
-
|
1757
|
-
|
1762
|
+
// group the label groups (label, percentage, value) into a single element for simpler positioning
|
1763
|
+
var tooltips = pie.svg.insert("g")
|
1764
|
+
.attr("class", pie.cssPrefix + "tooltips");
|
1758
1765
|
|
1759
1766
|
tooltips.selectAll("." + pie.cssPrefix + "tooltip")
|
1760
|
-
|
1761
|
-
|
1762
|
-
|
1767
|
+
.data(pie.options.data.content)
|
1768
|
+
.enter()
|
1769
|
+
.append("g")
|
1763
1770
|
.attr("class", pie.cssPrefix + "tooltip")
|
1764
1771
|
.attr("id", function(d, i) { return pie.cssPrefix + "tooltip" + i; })
|
1765
1772
|
.style("opacity", 0)
|
1766
|
-
|
1767
|
-
.attr(
|
1768
|
-
|
1769
|
-
|
1770
|
-
|
1771
|
-
|
1772
|
-
})
|
1773
|
-
.style("fill", pie.options.tooltips.styles.backgroundColor);
|
1773
|
+
.append("rect")
|
1774
|
+
.attr("rx", pie.options.tooltips.styles.borderRadius)
|
1775
|
+
.attr("ry", pie.options.tooltips.styles.borderRadius)
|
1776
|
+
.attr("x", -pie.options.tooltips.styles.padding)
|
1777
|
+
.attr("opacity", pie.options.tooltips.styles.backgroundOpacity)
|
1778
|
+
.style("fill", pie.options.tooltips.styles.backgroundColor);
|
1774
1779
|
|
1775
1780
|
tooltips.selectAll("." + pie.cssPrefix + "tooltip")
|
1776
|
-
|
1777
|
-
|
1781
|
+
.data(pie.options.data.content)
|
1782
|
+
.append("text")
|
1778
1783
|
.attr("fill", function(d) { return pie.options.tooltips.styles.color; })
|
1779
1784
|
.style("font-size", function(d) { return pie.options.tooltips.styles.fontSize; })
|
1780
1785
|
.style("font-family", function(d) { return pie.options.tooltips.styles.font; })
|
1781
1786
|
.text(function(d, i) {
|
1782
|
-
|
1783
|
-
|
1784
|
-
|
1785
|
-
|
1786
|
-
|
1787
|
-
|
1788
|
-
|
1789
|
-
|
1790
|
-
|
1787
|
+
var caption = pie.options.tooltips.string;
|
1788
|
+
if (pie.options.tooltips.type === "caption") {
|
1789
|
+
caption = d.caption;
|
1790
|
+
}
|
1791
|
+
return tt.replacePlaceholders(pie, caption, i, {
|
1792
|
+
label: d.label,
|
1793
|
+
value: d.value,
|
1794
|
+
percentage: d.percentage
|
1795
|
+
});
|
1791
1796
|
});
|
1792
1797
|
|
1793
1798
|
tooltips.selectAll("." + pie.cssPrefix + "tooltip rect")
|
1794
|
-
.attr({
|
1795
|
-
|
1796
|
-
|
1797
|
-
|
1798
|
-
|
1799
|
-
|
1800
|
-
|
1801
|
-
|
1802
|
-
|
1803
|
-
|
1804
|
-
|
1805
|
-
|
1806
|
-
}
|
1807
|
-
});
|
1799
|
+
.attr("width", function (d, i) {
|
1800
|
+
var dims = helpers.getDimensions(pie.cssPrefix + "tooltip" + i);
|
1801
|
+
return dims.w + (2 * pie.options.tooltips.styles.padding);
|
1802
|
+
})
|
1803
|
+
.attr("height", function (d, i) {
|
1804
|
+
var dims = helpers.getDimensions(pie.cssPrefix + "tooltip" + i);
|
1805
|
+
return dims.h + (2 * pie.options.tooltips.styles.padding);
|
1806
|
+
})
|
1807
|
+
.attr("y", function (d, i) {
|
1808
|
+
var dims = helpers.getDimensions(pie.cssPrefix + "tooltip" + i);
|
1809
|
+
return -(dims.h / 2) + 1;
|
1810
|
+
});
|
1808
1811
|
},
|
1809
1812
|
|
1810
|
-
|
1811
|
-
|
1812
|
-
|
1813
|
-
|
1814
|
-
|
1815
|
-
}
|
1816
|
-
|
1817
|
-
tt.currentTooltip = index;
|
1818
|
-
d3.select("#" + pie.cssPrefix + "tooltip" + index)
|
1819
|
-
.transition()
|
1820
|
-
.duration(fadeInSpeed)
|
1821
|
-
.style("opacity", function() { return 1; });
|
1822
|
-
|
1823
|
-
tt.moveTooltip(pie);
|
1824
|
-
},
|
1825
|
-
|
1826
|
-
moveTooltip: function(pie) {
|
1827
|
-
d3.selectAll("#" + pie.cssPrefix + "tooltip" + tt.currentTooltip)
|
1828
|
-
.attr("transform", function(d) {
|
1829
|
-
var mouseCoords = d3.mouse(this.parentNode);
|
1830
|
-
var x = mouseCoords[0] + pie.options.tooltips.styles.padding + 2;
|
1831
|
-
var y = mouseCoords[1] - (2 * pie.options.tooltips.styles.padding) - 2;
|
1832
|
-
return "translate(" + x + "," + y + ")";
|
1833
|
-
});
|
1834
|
-
},
|
1835
|
-
|
1836
|
-
hideTooltip: function(pie, index) {
|
1837
|
-
d3.select("#" + pie.cssPrefix + "tooltip" + index)
|
1838
|
-
.style("opacity", function() { return 0; });
|
1839
|
-
|
1840
|
-
// move the tooltip offscreen. This ensures that when the user next mouseovers the segment the hidden
|
1841
|
-
// element won't interfere
|
1842
|
-
d3.select("#" + pie.cssPrefix + "tooltip" + tt.currentTooltip)
|
1843
|
-
.attr("transform", function(d, i) {
|
1844
|
-
|
1845
|
-
// klutzy, but it accounts for tooltip padding which could push it onscreen
|
1846
|
-
var x = pie.options.size.canvasWidth + 1000;
|
1847
|
-
var y = pie.options.size.canvasHeight + 1000;
|
1848
|
-
return "translate(" + x + "," + y + ")";
|
1849
|
-
});
|
1850
|
-
},
|
1851
|
-
|
1852
|
-
replacePlaceholders: function(pie, str, index, replacements) {
|
1853
|
-
|
1854
|
-
// if the user has defined a placeholderParser function, call it before doing the replacements
|
1855
|
-
if (helpers.isFunction(pie.options.tooltips.placeholderParser)) {
|
1856
|
-
pie.options.tooltips.placeholderParser(index, replacements);
|
1857
|
-
}
|
1813
|
+
showTooltip: function(pie, index) {
|
1814
|
+
var fadeInSpeed = pie.options.tooltips.styles.fadeInSpeed;
|
1815
|
+
if (tt.currentTooltip === index) {
|
1816
|
+
fadeInSpeed = 1;
|
1817
|
+
}
|
1858
1818
|
|
1859
|
-
|
1860
|
-
|
1861
|
-
|
1862
|
-
|
1863
|
-
|
1864
|
-
|
1865
|
-
|
1819
|
+
tt.currentTooltip = index;
|
1820
|
+
d3.select("#" + pie.cssPrefix + "tooltip" + index)
|
1821
|
+
.transition()
|
1822
|
+
.duration(fadeInSpeed)
|
1823
|
+
.style("opacity", function() { return 1; });
|
1824
|
+
|
1825
|
+
tt.moveTooltip(pie);
|
1826
|
+
},
|
1827
|
+
|
1828
|
+
moveTooltip: function(pie) {
|
1829
|
+
d3.selectAll("#" + pie.cssPrefix + "tooltip" + tt.currentTooltip)
|
1830
|
+
.attr("transform", function(d) {
|
1831
|
+
var mouseCoords = d3.mouse(this.parentNode);
|
1832
|
+
var x = mouseCoords[0] + pie.options.tooltips.styles.padding + 2;
|
1833
|
+
var y = mouseCoords[1] - (2 * pie.options.tooltips.styles.padding) - 2;
|
1834
|
+
return "translate(" + x + "," + y + ")";
|
1835
|
+
});
|
1836
|
+
},
|
1837
|
+
|
1838
|
+
hideTooltip: function(pie, index) {
|
1839
|
+
d3.select("#" + pie.cssPrefix + "tooltip" + index)
|
1840
|
+
.style("opacity", function() { return 0; });
|
1841
|
+
|
1842
|
+
// move the tooltip offscreen. This ensures that when the user next mouseovers the segment the hidden
|
1843
|
+
// element won't interfere
|
1844
|
+
d3.select("#" + pie.cssPrefix + "tooltip" + tt.currentTooltip)
|
1845
|
+
.attr("transform", function(d, i) {
|
1846
|
+
// klutzy, but it accounts for tooltip padding which could push it onscreen
|
1847
|
+
var x = pie.options.size.canvasWidth + 1000;
|
1848
|
+
var y = pie.options.size.canvasHeight + 1000;
|
1849
|
+
return "translate(" + x + "," + y + ")";
|
1850
|
+
});
|
1851
|
+
},
|
1852
|
+
|
1853
|
+
replacePlaceholders: function(pie, str, index, replacements) {
|
1854
|
+
|
1855
|
+
// if the user has defined a placeholderParser function, call it before doing the replacements
|
1856
|
+
if (helpers.isFunction(pie.options.tooltips.placeholderParser)) {
|
1857
|
+
pie.options.tooltips.placeholderParser(index, replacements);
|
1866
1858
|
}
|
1867
|
-
|
1868
|
-
|
1869
|
-
|
1870
|
-
|
1859
|
+
|
1860
|
+
var replacer = function() {
|
1861
|
+
return function(match) {
|
1862
|
+
var placeholder = arguments[1];
|
1863
|
+
if (replacements.hasOwnProperty(placeholder)) {
|
1864
|
+
return replacements[arguments[1]];
|
1865
|
+
} else {
|
1866
|
+
return arguments[0];
|
1867
|
+
}
|
1868
|
+
};
|
1869
|
+
};
|
1870
|
+
return str.replace(/\{(\w+)\}/g, replacer(replacements));
|
1871
|
+
}
|
1871
1872
|
};
|
1872
1873
|
|
1873
1874
|
|
@@ -1905,28 +1906,17 @@ var tt = {
|
|
1905
1906
|
d3.select(this.element).attr(_scriptName, _version);
|
1906
1907
|
|
1907
1908
|
// things that are done once
|
1908
|
-
|
1909
|
-
if (this.options.data.smallSegmentGrouping.enabled) {
|
1910
|
-
this.options.data.content = helpers.applySmallSegmentGrouping(this.options.data.content, this.options.data.smallSegmentGrouping);
|
1911
|
-
}
|
1912
|
-
this.options.colors = helpers.initSegmentColors(this);
|
1913
|
-
this.totalSize = math.getTotalPieSize(this.options.data.content);
|
1914
|
-
|
1909
|
+
_setupData.call(this);
|
1915
1910
|
_init.call(this);
|
1916
1911
|
};
|
1917
1912
|
|
1918
1913
|
d3pie.prototype.recreate = function() {
|
1919
1914
|
// now run some validation on the user-defined info
|
1920
1915
|
if (!validate.initialCheck(this)) {
|
1921
|
-
|
1922
|
-
|
1923
|
-
this.options.data.content = math.sortPieData(this);
|
1924
|
-
if (this.options.data.smallSegmentGrouping.enabled) {
|
1925
|
-
this.options.data.content = helpers.applySmallSegmentGrouping(this.options.data.content, this.options.data.smallSegmentGrouping);
|
1926
|
-
}
|
1927
|
-
this.options.colors = helpers.initSegmentColors(this);
|
1928
|
-
this.totalSize = math.getTotalPieSize(this.options.data.content);
|
1916
|
+
return;
|
1917
|
+
}
|
1929
1918
|
|
1919
|
+
_setupData.call(this);
|
1930
1920
|
_init.call(this);
|
1931
1921
|
};
|
1932
1922
|
|
@@ -1972,10 +1962,7 @@ var tt = {
|
|
1972
1962
|
};
|
1973
1963
|
|
1974
1964
|
d3pie.prototype.closeSegment = function() {
|
1975
|
-
|
1976
|
-
if (segment) {
|
1977
|
-
segments.closeSegment(this, segment);
|
1978
|
-
}
|
1965
|
+
segments.maybeCloseOpenSegment();
|
1979
1966
|
};
|
1980
1967
|
|
1981
1968
|
// this let's the user dynamically update aspects of the pie chart without causing a complete redraw. It
|
@@ -2026,6 +2013,32 @@ var tt = {
|
|
2026
2013
|
|
2027
2014
|
// ------------------------------------------------------------------------------------------------
|
2028
2015
|
|
2016
|
+
var _setupData = function () {
|
2017
|
+
this.options.data.content = math.sortPieData(this);
|
2018
|
+
if (this.options.data.smallSegmentGrouping.enabled) {
|
2019
|
+
this.options.data.content = helpers.applySmallSegmentGrouping(this.options.data.content, this.options.data.smallSegmentGrouping);
|
2020
|
+
}
|
2021
|
+
|
2022
|
+
|
2023
|
+
this.options.colors = helpers.initSegmentColors(this);
|
2024
|
+
this.totalSize = math.getTotalPieSize(this.options.data.content);
|
2025
|
+
|
2026
|
+
var dp = this.options.labels.percentage.decimalPlaces;
|
2027
|
+
|
2028
|
+
// add in percentage data to content
|
2029
|
+
for (var i=0; i<this.options.data.content.length; i++) {
|
2030
|
+
this.options.data.content[i].percentage = _getPercentage(this.options.data.content[i].value, this.totalSize, dp);
|
2031
|
+
}
|
2032
|
+
|
2033
|
+
// adjust the final item to ensure the percentage always adds up to precisely 100%. This is necessary
|
2034
|
+
var totalPercentage = 0;
|
2035
|
+
for (var j=0; j<this.options.data.content.length; j++) {
|
2036
|
+
if (j === this.options.data.content.length - 1) {
|
2037
|
+
this.options.data.content[j].percentage = (100 - totalPercentage).toFixed(dp);
|
2038
|
+
}
|
2039
|
+
totalPercentage += parseFloat(this.options.data.content[j].percentage);
|
2040
|
+
}
|
2041
|
+
};
|
2029
2042
|
|
2030
2043
|
var _init = function() {
|
2031
2044
|
|
@@ -2142,14 +2155,23 @@ var tt = {
|
|
2142
2155
|
labels.positionLabelGroups(self, "inner");
|
2143
2156
|
labels.fadeInLabelsAndLines(self);
|
2144
2157
|
|
2145
|
-
|
2146
|
-
|
2147
|
-
|
2148
|
-
|
2158
|
+
// add and position the tooltips
|
2159
|
+
if (self.options.tooltips.enabled) {
|
2160
|
+
tt.addTooltips(self);
|
2161
|
+
}
|
2149
2162
|
|
2150
|
-
|
2163
|
+
segments.addSegmentEventHandlers(self);
|
2151
2164
|
});
|
2152
2165
|
};
|
2153
2166
|
|
2154
|
-
|
2167
|
+
var _getPercentage = function(value, total, decimalPlaces) {
|
2168
|
+
var relativeAmount = value / total;
|
2169
|
+
if (decimalPlaces <= 0) {
|
2170
|
+
return Math.round(relativeAmount * 100);
|
2171
|
+
} else {
|
2172
|
+
return (relativeAmount * 100).toFixed(decimalPlaces);
|
2173
|
+
}
|
2174
|
+
};
|
2175
|
+
|
2176
|
+
return d3pie;
|
2155
2177
|
}));
|
@@ -1,9 +1,9 @@
|
|
1
1
|
/*!
|
2
2
|
* d3pie
|
3
3
|
* @author Ben Keen
|
4
|
-
* @version 0.1
|
5
|
-
* @date
|
4
|
+
* @version 0.2.1
|
5
|
+
* @date March 11, 2017
|
6
6
|
* @repo http://github.com/benkeen/d3pie
|
7
7
|
*/
|
8
|
-
!function(a,b){"function"==typeof define&&define.amd?define([],b):"object"==typeof exports?module.exports=b():a.d3pie=b(a)}(this,function(){var a="d3pie",b="0.1.6",c=0,d={header:{title:{text:"",color:"#333333",fontSize:18,font:"arial"},subtitle:{text:"",color:"#666666",fontSize:14,font:"arial"},location:"top-center",titleSubtitlePadding:8},footer:{text:"",color:"#666666",fontSize:14,font:"arial",location:"left"},size:{canvasHeight:500,canvasWidth:500,pieInnerRadius:"0%",pieOuterRadius:null},data:{sortOrder:"none",ignoreSmallSegments:{enabled:!1,valueType:"percentage",value:null},smallSegmentGrouping:{enabled:!1,value:1,valueType:"percentage",label:"Other",color:"#cccccc"},content:[]},labels:{outer:{format:"label",hideWhenLessThanPercentage:null,pieDistance:30},inner:{format:"percentage",hideWhenLessThanPercentage:null},mainLabel:{color:"#333333",font:"arial",fontSize:10},percentage:{color:"#dddddd",font:"arial",fontSize:10,decimalPlaces:0},value:{color:"#cccc44",font:"arial",fontSize:10},lines:{enabled:!0,style:"curved",color:"segment"},truncation:{enabled:!1,truncateLength:30},formatter:null},effects:{load:{effect:"default",speed:1e3},pullOutSegmentOnClick:{effect:"bounce",speed:300,size:10},highlightSegmentOnMouseover:!0,highlightLuminosity:-.2},tooltips:{enabled:!1,type:"placeholder",string:"",placeholderParser:null,styles:{fadeInSpeed:250,backgroundColor:"#000000",backgroundOpacity:.5,color:"#efefef",borderRadius:2,font:"arial",fontSize:10,padding:4}},misc:{colors:{background:null,segments:["#2484c1","#65a620","#7b6888","#a05d56","#961a1a","#d8d23a","#e98125","#d0743c","#635222","#6ada6a","#0c6197","#7d9058","#207f33","#44b9b0","#bca44a","#e4a14b","#a3acb2","#8cc3e9","#69a6f9","#5b388f","#546e91","#8bde95","#d2ab58","#273c71","#98bf6e","#4daa4b","#98abc5","#cc1010","#31383b","#006391","#c2643f","#b0a474","#a5a39c","#a9c2bc","#22af8c","#7fcecf","#987ac6","#3d3b87","#b77b1c","#c9c2b6","#807ece","#8db27c","#be66a2","#9ed3c6","#00644b","#005064","#77979f","#77e079","#9c73ab","#1f79a7"],segmentStroke:"#ffffff"},gradient:{enabled:!1,percentage:95,color:"#000000"},canvasPadding:{top:5,right:5,bottom:5,left:5},pieCenterOffset:{x:0,y:0},cssPrefix:null},callbacks:{onload:null,onMouseoverSegment:null,onMouseoutSegment:null,onClickSegment:null}},e={initialCheck:function(a){var b=a.cssPrefix,c=a.element,d=a.options;if(!window.d3||!window.d3.hasOwnProperty("version"))return console.error("d3pie error: d3 is not available"),!1;if(!(c instanceof HTMLElement||c instanceof SVGElement))return console.error("d3pie error: the first d3pie() param must be a valid DOM element (not jQuery) or a ID string."),!1;if(!/[a-zA-Z][a-zA-Z0-9_-]*$/.test(b))return console.error("d3pie error: invalid options.misc.cssPrefix"),!1;if(!f.isArray(d.data.content))return console.error("d3pie error: invalid config structure: missing data.content property."),!1;if(0===d.data.content.length)return console.error("d3pie error: no data supplied."),!1;for(var e=[],g=0;g<d.data.content.length;g++)"number"!=typeof d.data.content[g].value||isNaN(d.data.content[g].value)?console.log("not valid: ",d.data.content[g]):d.data.content[g].value<=0?console.log("not valid - should have positive value: ",d.data.content[g]):e.push(d.data.content[g]);return a.options.data.content=e,!0}},f={addSVGSpace:function(a){var b=a.element,c=a.options.size.canvasWidth,d=a.options.size.canvasHeight,e=a.options.misc.colors.background,f=d3.select(b).append("svg:svg").attr("width",c).attr("height",d);return"transparent"!==e&&f.style("background-color",function(){return e}),f},whenIdExists:function(a,b){var c=1,d=1e3,e=setInterval(function(){document.getElementById(a)&&(clearInterval(e),b()),c>d&&clearInterval(e),c++},1)},whenElementsExist:function(a,b){var c=1,d=1e3,e=setInterval(function(){for(var f=!0,g=0;g<a.length;g++)if(!document.getElementById(a[g])){f=!1;break}f&&(clearInterval(e),b()),c>d&&clearInterval(e),c++},1)},shuffleArray:function(a){for(var b,c,d=a.length;0!==d;)c=Math.floor(Math.random()*d),d-=1,b=a[d],a[d]=a[c],a[c]=b;return a},processObj:function(a,b,c){return"string"==typeof b?f.processObj(a,b.split("."),c):1===b.length&&void 0!==c?(a[b[0]]=c,a[b[0]]):0===b.length?a:f.processObj(a[b[0]],b.slice(1),c)},getDimensions:function(a){var b=document.getElementById(a),c=0,d=0;if(b){var e=b.getBBox();c=e.width,d=e.height}else console.log("error: getDimensions() "+a+" not found.");return{w:c,h:d}},rectIntersect:function(a,b){var c=b.x>a.x+a.w||b.x+b.w<a.x||b.y+b.h<a.y||b.y>a.y+a.h;return!c},getColorShade:function(a,b){a=String(a).replace(/[^0-9a-f]/gi,""),a.length<6&&(a=a[0]+a[0]+a[1]+a[1]+a[2]+a[2]),b=b||0;for(var c="#",d=0;3>d;d++){var e=parseInt(a.substr(2*d,2),16);e=Math.round(Math.min(Math.max(0,e+e*b),255)).toString(16),c+=("00"+e).substr(e.length)}return c},initSegmentColors:function(a){for(var b=a.options.data.content,c=a.options.misc.colors.segments,d=[],e=0;e<b.length;e++)d.push(b[e].hasOwnProperty("color")?b[e].color:c[e]);return d},applySmallSegmentGrouping:function(a,b){var c;"percentage"===b.valueType&&(c=h.getTotalPieSize(a));for(var d=[],e=[],f=0,g=0;g<a.length;g++)if("percentage"===b.valueType){var i=a[g].value/c*100;if(i<=b.value){e.push(a[g]),f+=a[g].value;continue}a[g].isGrouped=!1,d.push(a[g])}else{if(a[g].value<=b.value){e.push(a[g]),f+=a[g].value;continue}a[g].isGrouped=!1,d.push(a[g])}return e.length&&d.push({color:b.color,label:b.label,value:f,isGrouped:!0,groupedData:e}),d},showPoint:function(a,b,c){a.append("circle").attr("cx",b).attr("cy",c).attr("r",2).style("fill","black")},isFunction:function(a){var b={};return a&&"[object Function]"===b.toString.call(a)},isArray:function(a){return"[object Array]"===Object.prototype.toString.call(a)}},g=function(){var a,b,c,d,e,f,h=arguments[0]||{},i=1,j=arguments.length,k=!1,l=Object.prototype.toString,m=Object.prototype.hasOwnProperty,n={"[object Boolean]":"boolean","[object Number]":"number","[object String]":"string","[object Function]":"function","[object Array]":"array","[object Date]":"date","[object RegExp]":"regexp","[object Object]":"object"},o={isFunction:function(a){return"function"===o.type(a)},isArray:Array.isArray||function(a){return"array"===o.type(a)},isWindow:function(a){return null!==a&&a===a.window},isNumeric:function(a){return!isNaN(parseFloat(a))&&isFinite(a)},type:function(a){return null===a?String(a):n[l.call(a)]||"object"},isPlainObject:function(a){if(!a||"object"!==o.type(a)||a.nodeType)return!1;try{if(a.constructor&&!m.call(a,"constructor")&&!m.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(b){return!1}var c;for(c in a);return void 0===c||m.call(a,c)}};for("boolean"==typeof h&&(k=h,h=arguments[1]||{},i=2),"object"==typeof h||o.isFunction(h)||(h={}),j===i&&(h=this,--i),i;j>i;i++)if(null!==(a=arguments[i]))for(b in a)c=h[b],d=a[b],h!==d&&(k&&d&&(o.isPlainObject(d)||(e=o.isArray(d)))?(e?(e=!1,f=c&&o.isArray(c)?c:[]):f=c&&o.isPlainObject(c)?c:{},h[b]=g(k,f,d)):void 0!==d&&(h[b]=d));return h},h={toRadians:function(a){return a*(Math.PI/180)},toDegrees:function(a){return a*(180/Math.PI)},computePieRadius:function(a){var b=a.options.size,c=a.options.misc.canvasPadding,d=b.canvasWidth-c.left-c.right,e=b.canvasHeight-c.top-c.bottom;"pie-center"!==a.options.header.location&&(e-=a.textComponents.headerHeight),a.textComponents.footer.exists&&(e-=a.textComponents.footer.h),e=0>e?0:e;var f,g,h=(e>d?d:e)/3;if(null!==b.pieOuterRadius)if(/%/.test(b.pieOuterRadius)){g=parseInt(b.pieOuterRadius.replace(/[\D]/,""),10),g=g>99?99:g,g=0>g?0:g;var i=e>d?d:e;if("none"!==a.options.labels.outer.format){var j=2*parseInt(a.options.labels.outer.pieDistance,10);i-j>0&&(i-=j)}h=Math.floor(i/100*g)/2}else h=parseInt(b.pieOuterRadius,10);/%/.test(b.pieInnerRadius)?(g=parseInt(b.pieInnerRadius.replace(/[\D]/,""),10),g=g>99?99:g,g=0>g?0:g,f=Math.floor(h/100*g)):f=parseInt(b.pieInnerRadius,10),a.innerRadius=f,a.outerRadius=h},getTotalPieSize:function(a){for(var b=0,c=0;c<a.length;c++)b+=a[c].value;return b},sortPieData:function(a){var b=a.options.data.content,c=a.options.data.sortOrder;switch(c){case"none":break;case"random":b=f.shuffleArray(b);break;case"value-asc":b.sort(function(a,b){return a.value<b.value?-1:1});break;case"value-desc":b.sort(function(a,b){return a.value<b.value?1:-1});break;case"label-asc":b.sort(function(a,b){return a.label.toLowerCase()>b.label.toLowerCase()?1:-1});break;case"label-desc":b.sort(function(a,b){return a.label.toLowerCase()<b.label.toLowerCase()?1:-1})}return b},getPieTranslateCenter:function(a){return"translate("+a.x+","+a.y+")"},calculatePieCenter:function(a){var b=a.options.misc.pieCenterOffset,c=a.textComponents.title.exists&&"pie-center"!==a.options.header.location,d=a.textComponents.subtitle.exists&&"pie-center"!==a.options.header.location,e=a.options.misc.canvasPadding.top;c&&d?e+=a.textComponents.title.h+a.options.header.titleSubtitlePadding+a.textComponents.subtitle.h:c?e+=a.textComponents.title.h:d&&(e+=a.textComponents.subtitle.h);var f=0;a.textComponents.footer.exists&&(f=a.textComponents.footer.h+a.options.misc.canvasPadding.bottom);var g=(a.options.size.canvasWidth-a.options.misc.canvasPadding.left-a.options.misc.canvasPadding.right)/2+a.options.misc.canvasPadding.left,h=(a.options.size.canvasHeight-f-e)/2+e;g+=b.x,h+=b.y,a.pieCenter={x:g,y:h}},rotate:function(a,b,c,d,e){e=e*Math.PI/180;var f=Math.cos,g=Math.sin,h=(a-c)*f(e)-(b-d)*g(e)+c,i=(a-c)*g(e)+(b-d)*f(e)+d;return{x:h,y:i}},translate:function(a,b,c,d){var e=h.toRadians(d);return{x:a+c*Math.sin(e),y:b-c*Math.cos(e)}},pointIsInArc:function(a,b,c){var d=c.innerRadius()(b),e=c.outerRadius()(b),f=c.startAngle()(b),g=c.endAngle()(b),h=a.x*a.x+a.y*a.y,i=Math.atan2(a.x,-a.y);return i=0>i?i+2*Math.PI:i,h>=d*d&&e*e>=h&&i>=f&&g>=i}},i={add:function(a,b,c){var d=i.getIncludes(c),e=a.options.labels,f=a.svg.insert("g","."+a.cssPrefix+"labels-"+b).attr("class",a.cssPrefix+"labels-"+b),g=f.selectAll("."+a.cssPrefix+"labelGroup-"+b).data(a.options.data.content).enter().append("g").attr("id",function(c,d){return a.cssPrefix+"labelGroup"+d+"-"+b}).attr("data-index",function(a,b){return b}).attr("class",a.cssPrefix+"labelGroup-"+b).style("opacity",0),h={section:b,sectionDisplayType:c};d.mainLabel&&g.append("text").attr("id",function(c,d){return a.cssPrefix+"segmentMainLabel"+d+"-"+b}).attr("class",a.cssPrefix+"segmentMainLabel-"+b).text(function(a,b){var c=a.label;return e.formatter?(h.index=b,h.part="mainLabel",h.value=a.value,h.label=c,c=e.formatter(h)):e.truncation.enabled&&a.label.length>e.truncation.truncateLength&&(c=a.label.substring(0,e.truncation.truncateLength)+"..."),c}).style("font-size",e.mainLabel.fontSize+"px").style("font-family",e.mainLabel.font).style("fill",e.mainLabel.color),d.percentage&&g.append("text").attr("id",function(c,d){return a.cssPrefix+"segmentPercentage"+d+"-"+b}).attr("class",a.cssPrefix+"segmentPercentage-"+b).text(function(b,c){var d=j.getPercentage(a,c,a.options.labels.percentage.decimalPlaces);return e.formatter?(h.index=c,h.part="percentage",h.value=b.value,h.label=d,d=e.formatter(h)):d+="%",d}).style("font-size",e.percentage.fontSize+"px").style("font-family",e.percentage.font).style("fill",e.percentage.color),d.value&&g.append("text").attr("id",function(c,d){return a.cssPrefix+"segmentValue"+d+"-"+b}).attr("class",a.cssPrefix+"segmentValue-"+b).text(function(a,b){return h.index=b,h.part="value",h.value=a.value,h.label=a.value,e.formatter?e.formatter(h,a.value):a.value}).style("font-size",e.value.fontSize+"px").style("font-family",e.value.font).style("fill",e.value.color)},positionLabelElements:function(a,b,c){i["dimensions-"+b]=[];var d=d3.selectAll("."+a.cssPrefix+"labelGroup-"+b);d.each(function(){var c=d3.select(this).selectAll("."+a.cssPrefix+"segmentMainLabel-"+b),d=d3.select(this).selectAll("."+a.cssPrefix+"segmentPercentage-"+b),e=d3.select(this).selectAll("."+a.cssPrefix+"segmentValue-"+b);i["dimensions-"+b].push({mainLabel:null!==c.node()?c.node().getBBox():null,percentage:null!==d.node()?d.node().getBBox():null,value:null!==e.node()?e.node().getBBox():null})});var e=5,f=i["dimensions-"+b];switch(c){case"label-value1":d3.selectAll("."+a.cssPrefix+"segmentValue-"+b).attr("dx",function(a,b){return f[b].mainLabel.width+e});break;case"label-value2":d3.selectAll("."+a.cssPrefix+"segmentValue-"+b).attr("dy",function(a,b){return f[b].mainLabel.height});break;case"label-percentage1":d3.selectAll("."+a.cssPrefix+"segmentPercentage-"+b).attr("dx",function(a,b){return f[b].mainLabel.width+e});break;case"label-percentage2":d3.selectAll("."+a.cssPrefix+"segmentPercentage-"+b).attr("dx",function(a,b){return f[b].mainLabel.width/2-f[b].percentage.width/2}).attr("dy",function(a,b){return f[b].mainLabel.height})}},computeLabelLinePositions:function(a){a.lineCoordGroups=[],d3.selectAll("."+a.cssPrefix+"labelGroup-outer").each(function(b,c){return i.computeLinePosition(a,c)})},computeLinePosition:function(a,b){var c,d,e,f,g=j.getSegmentAngle(b,a.options.data.content,a.totalSize,{midpoint:!0}),i=h.rotate(a.pieCenter.x,a.pieCenter.y-a.outerRadius,a.pieCenter.x,a.pieCenter.y,g),k=a.outerLabelGroupData[b].h/5,l=6,m=Math.floor(g/90),n=4;switch(2===m&&180===g&&(m=1),m){case 0:c=a.outerLabelGroupData[b].x-l-(a.outerLabelGroupData[b].x-l-i.x)/2,d=a.outerLabelGroupData[b].y+(i.y-a.outerLabelGroupData[b].y)/n,e=a.outerLabelGroupData[b].x-l,f=a.outerLabelGroupData[b].y-k;break;case 1:c=i.x+(a.outerLabelGroupData[b].x-i.x)/n,d=i.y+(a.outerLabelGroupData[b].y-i.y)/n,e=a.outerLabelGroupData[b].x-l,f=a.outerLabelGroupData[b].y-k;break;case 2:var o=a.outerLabelGroupData[b].x+a.outerLabelGroupData[b].w+l;c=i.x-(i.x-o)/n,d=i.y+(a.outerLabelGroupData[b].y-i.y)/n,e=a.outerLabelGroupData[b].x+a.outerLabelGroupData[b].w+l,f=a.outerLabelGroupData[b].y-k;break;case 3:var p=a.outerLabelGroupData[b].x+a.outerLabelGroupData[b].w+l;c=p+(i.x-p)/n,d=a.outerLabelGroupData[b].y+(i.y-a.outerLabelGroupData[b].y)/n,e=a.outerLabelGroupData[b].x+a.outerLabelGroupData[b].w+l,f=a.outerLabelGroupData[b].y-k}a.lineCoordGroups[b]="straight"===a.options.labels.lines.style?[{x:i.x,y:i.y},{x:e,y:f}]:[{x:i.x,y:i.y},{x:c,y:d},{x:e,y:f}]},addLabelLines:function(a){var b=a.svg.insert("g","."+a.cssPrefix+"pieChart").attr("class",a.cssPrefix+"lineGroups").style("opacity",0),c=b.selectAll("."+a.cssPrefix+"lineGroup").data(a.lineCoordGroups).enter().append("g").attr("class",a.cssPrefix+"lineGroup"),d=d3.svg.line().interpolate("basis").x(function(a){return a.x}).y(function(a){return a.y});c.append("path").attr("d",d).attr("stroke",function(b,c){return"segment"===a.options.labels.lines.color?a.options.colors[c]:a.options.labels.lines.color}).attr("stroke-width",1).attr("fill","none").style("opacity",function(b,c){var d=a.options.labels.outer.hideWhenLessThanPercentage,e=j.getPercentage(a,c,a.options.labels.percentage.decimalPlaces),f=null!==d&&d>e||""===a.options.data.content[c].label;return f?0:1})},positionLabelGroups:function(a,b){"none"!==a.options.labels[b].format&&d3.selectAll("."+a.cssPrefix+"labelGroup-"+b).style("opacity",0).attr("transform",function(c,d){var e,i;if("outer"===b)e=a.outerLabelGroupData[d].x,i=a.outerLabelGroupData[d].y;else{var k=g(!0,{},a.pieCenter);if(a.innerRadius>0){var l=j.getSegmentAngle(d,a.options.data.content,a.totalSize,{midpoint:!0}),m=h.translate(a.pieCenter.x,a.pieCenter.y,a.innerRadius,l);k.x=m.x,k.y=m.y}var n=f.getDimensions(a.cssPrefix+"labelGroup"+d+"-inner"),o=n.w/2,p=n.h/4;e=k.x+(a.lineCoordGroups[d][0].x-k.x)/1.8,i=k.y+(a.lineCoordGroups[d][0].y-k.y)/1.8,e-=o,i+=p}return"translate("+e+","+i+")"})},fadeInLabelsAndLines:function(a){var b="default"===a.options.effects.load.effect?a.options.effects.load.speed:1;setTimeout(function(){var b="default"===a.options.effects.load.effect?400:1;d3.selectAll("."+a.cssPrefix+"labelGroup-outer").transition().duration(b).style("opacity",function(b,c){var d=a.options.labels.outer.hideWhenLessThanPercentage,e=j.getPercentage(a,c,a.options.labels.percentage.decimalPlaces);return null!==d&&d>e?0:1}),d3.selectAll("."+a.cssPrefix+"labelGroup-inner").transition().duration(b).style("opacity",function(b,c){var d=a.options.labels.inner.hideWhenLessThanPercentage,e=j.getPercentage(a,c,a.options.labels.percentage.decimalPlaces);return null!==d&&d>e?0:1}),d3.selectAll("g."+a.cssPrefix+"lineGroups").transition().duration(b).style("opacity",1),f.isFunction(a.options.callbacks.onload)&&setTimeout(function(){try{a.options.callbacks.onload()}catch(b){}},b)},b)},getIncludes:function(a){var b=!1,c=!1,d=!1;switch(a){case"label":b=!0;break;case"value":c=!0;break;case"percentage":d=!0;break;case"label-value1":case"label-value2":b=!0,c=!0;break;case"label-percentage1":case"label-percentage2":b=!0,d=!0}return{mainLabel:b,value:c,percentage:d}},computeOuterLabelCoords:function(a){a.svg.selectAll("."+a.cssPrefix+"labelGroup-outer").each(function(b,c){return i.getIdealOuterLabelPositions(a,c)}),i.resolveOuterLabelCollisions(a)},resolveOuterLabelCollisions:function(a){if("none"!==a.options.labels.outer.format){var b=a.options.data.content.length;i.checkConflict(a,0,"clockwise",b),i.checkConflict(a,b-1,"anticlockwise",b)}},checkConflict:function(a,b,c,d){var e,g;if(!(1>=d)){var h=a.outerLabelGroupData[b].hs;if(!("clockwise"===c&&"right"!==h||"anticlockwise"===c&&"left"!==h)){var j="clockwise"===c?b+1:b-1,k=a.outerLabelGroupData[b],l=a.outerLabelGroupData[j],m={labelHeights:a.outerLabelGroupData[0].h,center:a.pieCenter,lineLength:a.outerRadius+a.options.labels.outer.pieDistance,heightChange:a.outerLabelGroupData[0].h+1};if("clockwise"===c){for(e=0;b>=e;e++)if(g=a.outerLabelGroupData[e],f.rectIntersect(g,l)){i.adjustLabelPos(a,j,k,m);break}}else for(e=d-1;e>=b;e--)if(g=a.outerLabelGroupData[e],f.rectIntersect(g,l)){i.adjustLabelPos(a,j,k,m);break}i.checkConflict(a,j,c,d)}}},adjustLabelPos:function(a,b,c,d){var e,f,g,h;h=c.y+d.heightChange,f=d.center.y-h,e=Math.sqrt(Math.abs(d.lineLength)>Math.abs(f)?d.lineLength*d.lineLength-f*f:f*f-d.lineLength*d.lineLength),g="right"===c.hs?d.center.x+e:d.center.x-e-a.outerLabelGroupData[b].w,a.outerLabelGroupData[b].x=g,a.outerLabelGroupData[b].y=h},getIdealOuterLabelPositions:function(a,b){var c=d3.select("#"+a.cssPrefix+"labelGroup"+b+"-outer").node();if(c){var d=c.getBBox(),e=j.getSegmentAngle(b,a.options.data.content,a.totalSize,{midpoint:!0}),f=a.pieCenter.x,g=a.pieCenter.y-(a.outerRadius+a.options.labels.outer.pieDistance),i=h.rotate(f,g,a.pieCenter.x,a.pieCenter.y,e),k="right";e>180?(i.x-=d.width+8,k="left"):i.x+=8,a.outerLabelGroupData[b]={x:i.x,y:i.y,w:d.width,h:d.height,hs:k}}}},j={create:function(a){var b=a.pieCenter,c=a.options.colors,d=a.options.effects.load,e=a.options.misc.colors.segmentStroke,f=a.svg.insert("g","#"+a.cssPrefix+"title").attr("transform",function(){return h.getPieTranslateCenter(b)}).attr("class",a.cssPrefix+"pieChart"),g=d3.svg.arc().innerRadius(a.innerRadius).outerRadius(a.outerRadius).startAngle(0).endAngle(function(b){return b.value/a.totalSize*2*Math.PI}),i=f.selectAll("."+a.cssPrefix+"arc").data(a.options.data.content).enter().append("g").attr("class",a.cssPrefix+"arc"),k=d.speed;"none"===d.effect&&(k=0),i.append("path").attr("id",function(b,c){return a.cssPrefix+"segment"+c}).attr("fill",function(b,d){var e=c[d];return a.options.misc.gradient.enabled&&(e="url(#"+a.cssPrefix+"grad"+d+")"),e}).style("stroke",e).style("stroke-width",1).transition().ease("cubic-in-out").duration(k).attr("data-index",function(a,b){return b}).attrTween("d",function(b){var c=d3.interpolate({value:0},b);return function(b){return a.arc(c(b))}}),a.svg.selectAll("g."+a.cssPrefix+"arc").attr("transform",function(b,c){var d=0;return c>0&&(d=j.getSegmentAngle(c-1,a.options.data.content,a.totalSize)),"rotate("+d+")"}),a.arc=g},addGradients:function(a){var b=a.svg.append("defs").selectAll("radialGradient").data(a.options.data.content).enter().append("radialGradient").attr("gradientUnits","userSpaceOnUse").attr("cx",0).attr("cy",0).attr("r","120%").attr("id",function(b,c){return a.cssPrefix+"grad"+c});b.append("stop").attr("offset","0%").style("stop-color",function(b,c){return a.options.colors[c]}),b.append("stop").attr("offset",a.options.misc.gradient.percentage+"%").style("stop-color",a.options.misc.gradient.color)},addSegmentEventHandlers:function(a){var b=d3.selectAll("."+a.cssPrefix+"arc,."+a.cssPrefix+"labelGroup-inner,."+a.cssPrefix+"labelGroup-outer");b.on("click",function(){var b,c=d3.select(this);if(c.attr("class")===a.cssPrefix+"arc")b=c.select("path");else{var d=c.attr("data-index");b=d3.select("#"+a.cssPrefix+"segment"+d)}var e=b.attr("class")===a.cssPrefix+"expanded";j.onSegmentEvent(a,a.options.callbacks.onClickSegment,b,e),"none"!==a.options.effects.pullOutSegmentOnClick.effect&&(e?j.closeSegment(a,b.node()):j.openSegment(a,b.node()))}),b.on("mouseover",function(){var b,c,d=d3.select(this);if(d.attr("class")===a.cssPrefix+"arc"?b=d.select("path"):(c=d.attr("data-index"),b=d3.select("#"+a.cssPrefix+"segment"+c)),a.options.effects.highlightSegmentOnMouseover){c=b.attr("data-index");var e=a.options.colors[c];b.style("fill",f.getColorShade(e,a.options.effects.highlightLuminosity))}a.options.tooltips.enabled&&(c=b.attr("data-index"),l.showTooltip(a,c));var g=b.attr("class")===a.cssPrefix+"expanded";j.onSegmentEvent(a,a.options.callbacks.onMouseoverSegment,b,g)}),b.on("mousemove",function(){l.moveTooltip(a)}),b.on("mouseout",function(){var b,c,d=d3.select(this);if(d.attr("class")===a.cssPrefix+"arc"?b=d.select("path"):(c=d.attr("data-index"),b=d3.select("#"+a.cssPrefix+"segment"+c)),a.options.effects.highlightSegmentOnMouseover){c=b.attr("data-index");var e=a.options.colors[c];a.options.misc.gradient.enabled&&(e="url(#"+a.cssPrefix+"grad"+c+")"),b.style("fill",e)}a.options.tooltips.enabled&&(c=b.attr("data-index"),l.hideTooltip(a,c));var f=b.attr("class")===a.cssPrefix+"expanded";j.onSegmentEvent(a,a.options.callbacks.onMouseoutSegment,b,f)})},onSegmentEvent:function(a,b,c,d){if(f.isFunction(b)){var e=parseInt(c.attr("data-index"),10);b({segment:c.node(),index:e,expanded:d,data:a.options.data.content[e]})}},openSegment:function(a,b){a.isOpeningSegment||(a.isOpeningSegment=!0,d3.selectAll("."+a.cssPrefix+"expanded").length>0&&j.closeSegment(a,d3.select("."+a.cssPrefix+"expanded").node()),d3.select(b).transition().ease(a.options.effects.pullOutSegmentOnClick.effect).duration(a.options.effects.pullOutSegmentOnClick.speed).attr("transform",function(b){var c=a.arc.centroid(b),d=c[0],e=c[1],f=Math.sqrt(d*d+e*e),g=parseInt(a.options.effects.pullOutSegmentOnClick.size,10);return"translate("+d/f*g+","+e/f*g+")"}).each("end",function(){a.currentlyOpenSegment=b,a.isOpeningSegment=!1,d3.select(this).attr("class",a.cssPrefix+"expanded")}))},closeSegment:function(a,b){d3.select(b).transition().duration(400).attr("transform","translate(0,0)").each("end",function(){d3.select(this).attr("class",""),a.currentlyOpenSegment=null})},getCentroid:function(a){var b=a.getBBox();return{x:b.x+b.width/2,y:b.y+b.height/2}},getSegmentAngle:function(a,b,c,d){var e,f=g({compounded:!0,midpoint:!1},d),h=b[a].value;if(f.compounded){e=0;for(var i=0;a>=i;i++)e+=b[i].value}"undefined"==typeof e&&(e=h);var j=e/c*360;if(f.midpoint){var k=h/c*360;j-=k/2}return j},getPercentage:function(a,b,c){var d=a.options.data.content[b].value/a.totalSize;return 0>=c?Math.round(100*d):(100*d).toFixed(c)}},k={offscreenCoord:-1e4,addTitle:function(a){a.svg.selectAll("."+a.cssPrefix+"title").data([a.options.header.title]).enter().append("text").text(function(a){return a.text}).attr({id:a.cssPrefix+"title","class":a.cssPrefix+"title",x:k.offscreenCoord,y:k.offscreenCoord}).attr("text-anchor",function(){var b;return b="top-center"===a.options.header.location||"pie-center"===a.options.header.location?"middle":"left"}).attr("fill",function(a){return a.color}).style("font-size",function(a){return a.fontSize+"px"}).style("font-family",function(a){return a.font})},positionTitle:function(a){var b,c=a.textComponents,d=a.options.header.location,e=a.options.misc.canvasPadding,f=a.options.size.canvasWidth,g=a.options.header.titleSubtitlePadding;b="top-left"===d?e.left:(f-e.right)/2+e.left,b+=a.options.misc.pieCenterOffset.x;var h=e.top+c.title.h;if("pie-center"===d)if(h=a.pieCenter.y,c.subtitle.exists){var i=c.title.h+g+c.subtitle.h;h=h-i/2+c.title.h}else h+=c.title.h/4;a.svg.select("#"+a.cssPrefix+"title").attr("x",b).attr("y",h)},addSubtitle:function(a){var b=a.options.header.location;a.svg.selectAll("."+a.cssPrefix+"subtitle").data([a.options.header.subtitle]).enter().append("text").text(function(a){return a.text}).attr("x",k.offscreenCoord).attr("y",k.offscreenCoord).attr("id",a.cssPrefix+"subtitle").attr("class",a.cssPrefix+"subtitle").attr("text-anchor",function(){var a;return a="top-center"===b||"pie-center"===b?"middle":"left"}).attr("fill",function(a){return a.color}).style("font-size",function(a){return a.fontSize+"px"}).style("font-family",function(a){return a.font})},positionSubtitle:function(a){var b,c=a.options.misc.canvasPadding,d=a.options.size.canvasWidth;b="top-left"===a.options.header.location?c.left:(d-c.right)/2+c.left,b+=a.options.misc.pieCenterOffset.x;var e=k.getHeaderHeight(a);a.svg.select("#"+a.cssPrefix+"subtitle").attr("x",b).attr("y",e)},addFooter:function(a){a.svg.selectAll("."+a.cssPrefix+"footer").data([a.options.footer]).enter().append("text").text(function(a){return a.text}).attr("x",k.offscreenCoord).attr("y",k.offscreenCoord).attr("id",a.cssPrefix+"footer").attr("class",a.cssPrefix+"footer").attr("text-anchor",function(){var b="left";return"bottom-center"===a.options.footer.location?b="middle":"bottom-right"===a.options.footer.location&&(b="left"),b}).attr("fill",function(a){return a.color}).style("font-size",function(a){return a.fontSize+"px"}).style("font-family",function(a){return a.font})},positionFooter:function(a){var b,c=a.options.footer.location,d=a.textComponents.footer.w,e=a.options.size.canvasWidth,f=a.options.size.canvasHeight,g=a.options.misc.canvasPadding;b="bottom-left"===c?g.left:"bottom-right"===c?e-d-g.right:e/2,a.svg.select("#"+a.cssPrefix+"footer").attr("x",b).attr("y",f-g.bottom)},getHeaderHeight:function(a){var b;if(a.textComponents.title.exists){var c=a.textComponents.title.h+a.options.header.titleSubtitlePadding+a.textComponents.subtitle.h;b="pie-center"===a.options.header.location?a.pieCenter.y-c/2+c:c+a.options.misc.canvasPadding.top}else if("pie-center"===a.options.header.location){var d=a.options.misc.canvasPadding.bottom+a.textComponents.footer.h;b=(a.options.size.canvasHeight-d)/2+a.options.misc.canvasPadding.top+a.textComponents.subtitle.h/2}else b=a.options.misc.canvasPadding.top+a.textComponents.subtitle.h;return b}},l={addTooltips:function(a){var b=a.svg.insert("g").attr("class",a.cssPrefix+"tooltips");b.selectAll("."+a.cssPrefix+"tooltip").data(a.options.data.content).enter().append("g").attr("class",a.cssPrefix+"tooltip").attr("id",function(b,c){return a.cssPrefix+"tooltip"+c}).style("opacity",0).append("rect").attr({rx:a.options.tooltips.styles.borderRadius,ry:a.options.tooltips.styles.borderRadius,x:-a.options.tooltips.styles.padding,opacity:a.options.tooltips.styles.backgroundOpacity}).style("fill",a.options.tooltips.styles.backgroundColor),b.selectAll("."+a.cssPrefix+"tooltip").data(a.options.data.content).append("text").attr("fill",function(){return a.options.tooltips.styles.color}).style("font-size",function(){return a.options.tooltips.styles.fontSize}).style("font-family",function(){return a.options.tooltips.styles.font}).text(function(b,c){var d=a.options.tooltips.string;return"caption"===a.options.tooltips.type&&(d=b.caption),l.replacePlaceholders(a,d,c,{label:b.label,value:b.value,percentage:j.getPercentage(a,c,a.options.labels.percentage.decimalPlaces)})}),b.selectAll("."+a.cssPrefix+"tooltip rect").attr({width:function(b,c){var d=f.getDimensions(a.cssPrefix+"tooltip"+c);return d.w+2*a.options.tooltips.styles.padding},height:function(b,c){var d=f.getDimensions(a.cssPrefix+"tooltip"+c);return d.h+2*a.options.tooltips.styles.padding},y:function(b,c){var d=f.getDimensions(a.cssPrefix+"tooltip"+c);return-(d.h/2)+1}})},showTooltip:function(a,b){var c=a.options.tooltips.styles.fadeInSpeed;l.currentTooltip===b&&(c=1),l.currentTooltip=b,d3.select("#"+a.cssPrefix+"tooltip"+b).transition().duration(c).style("opacity",function(){return 1}),l.moveTooltip(a)},moveTooltip:function(a){d3.selectAll("#"+a.cssPrefix+"tooltip"+l.currentTooltip).attr("transform",function(){var b=d3.mouse(this.parentNode),c=b[0]+a.options.tooltips.styles.padding+2,d=b[1]-2*a.options.tooltips.styles.padding-2;return"translate("+c+","+d+")"})},hideTooltip:function(a,b){d3.select("#"+a.cssPrefix+"tooltip"+b).style("opacity",function(){return 0}),d3.select("#"+a.cssPrefix+"tooltip"+l.currentTooltip).attr("transform",function(){var b=a.options.size.canvasWidth+1e3,c=a.options.size.canvasHeight+1e3;return"translate("+b+","+c+")"})},replacePlaceholders:function(a,b,c,d){f.isFunction(a.options.tooltips.placeholderParser)&&a.options.tooltips.placeholderParser(c,d);var e=function(){return function(){var a=arguments[1];return d.hasOwnProperty(a)?d[arguments[1]]:arguments[0]}};return b.replace(/\{(\w+)\}/g,e(d))}},m=function(i,j){if(this.element=i,"string"==typeof i){var k=i.replace(/^#/,"");this.element=document.getElementById(k)}var l={};g(!0,l,d,j),this.options=l,null!==this.options.misc.cssPrefix?this.cssPrefix=this.options.misc.cssPrefix:(this.cssPrefix="p"+c+"_",c++),e.initialCheck(this)&&(d3.select(this.element).attr(a,b),this.options.data.content=h.sortPieData(this),this.options.data.smallSegmentGrouping.enabled&&(this.options.data.content=f.applySmallSegmentGrouping(this.options.data.content,this.options.data.smallSegmentGrouping)),this.options.colors=f.initSegmentColors(this),this.totalSize=h.getTotalPieSize(this.options.data.content),n.call(this))};m.prototype.recreate=function(){e.initialCheck(this)&&(this.options.data.content=h.sortPieData(this),this.options.data.smallSegmentGrouping.enabled&&(this.options.data.content=f.applySmallSegmentGrouping(this.options.data.content,this.options.data.smallSegmentGrouping)),this.options.colors=f.initSegmentColors(this),this.totalSize=h.getTotalPieSize(this.options.data.content),n.call(this))},m.prototype.redraw=function(){this.element.innerHTML="",n.call(this)},m.prototype.destroy=function(){this.element.innerHTML="",d3.select(this.element).attr(a,null)},m.prototype.getOpenSegment=function(){var a=this.currentlyOpenSegment;if(null!==a&&"undefined"!=typeof a){var b=parseInt(d3.select(a).attr("data-index"),10);return{element:a,index:b,data:this.options.data.content[b]}}return null},m.prototype.openSegment=function(a){a=parseInt(a,10),0>a||a>this.options.data.content.length-1||j.openSegment(this,d3.select("#"+this.cssPrefix+"segment"+a).node())},m.prototype.closeSegment=function(){var a=this.currentlyOpenSegment;a&&j.closeSegment(this,a)},m.prototype.updateProp=function(a,b){switch(a){case"header.title.text":var c=f.processObj(this.options,a);f.processObj(this.options,a,b),d3.select("#"+this.cssPrefix+"title").html(b),(""===c&&""!==b||""!==c&&""===b)&&this.redraw();break;case"header.subtitle.text":var d=f.processObj(this.options,a);f.processObj(this.options,a,b),d3.select("#"+this.cssPrefix+"subtitle").html(b),(""===d&&""!==b||""!==d&&""===b)&&this.redraw();break;case"callbacks.onload":case"callbacks.onMouseoverSegment":case"callbacks.onMouseoutSegment":case"callbacks.onClickSegment":case"effects.pullOutSegmentOnClick.effect":case"effects.pullOutSegmentOnClick.speed":case"effects.pullOutSegmentOnClick.size":case"effects.highlightSegmentOnMouseover":case"effects.highlightLuminosity":f.processObj(this.options,a,b);break;default:f.processObj(this.options,a,b),this.destroy(),this.recreate()}};var n=function(){this.svg=f.addSVGSpace(this),this.textComponents={headerHeight:0,title:{exists:""!==this.options.header.title.text,h:0,w:0},subtitle:{exists:""!==this.options.header.subtitle.text,h:0,w:0},footer:{exists:""!==this.options.footer.text,h:0,w:0}},this.outerLabelGroupData=[],this.textComponents.title.exists&&k.addTitle(this),this.textComponents.subtitle.exists&&k.addSubtitle(this),k.addFooter(this);
|
9
|
-
var a=this;
|
8
|
+
!function(a,b){"function"==typeof define&&define.amd?define([],b):"object"==typeof exports?module.exports=b():a.d3pie=b(a)}(this,function(){var a="d3pie",b="0.2.1",c=0,e={header:{title:{text:"",color:"#333333",fontSize:18,font:"arial"},subtitle:{text:"",color:"#666666",fontSize:14,font:"arial"},location:"top-center",titleSubtitlePadding:8},footer:{text:"",color:"#666666",fontSize:14,font:"arial",location:"left"},size:{canvasHeight:500,canvasWidth:500,pieInnerRadius:"0%",pieOuterRadius:null},data:{sortOrder:"none",ignoreSmallSegments:{enabled:!1,valueType:"percentage",value:null},smallSegmentGrouping:{enabled:!1,value:1,valueType:"percentage",label:"Other",color:"#cccccc"},content:[]},labels:{outer:{format:"label",hideWhenLessThanPercentage:null,pieDistance:30},inner:{format:"percentage",hideWhenLessThanPercentage:null},mainLabel:{color:"#333333",font:"arial",fontSize:10},percentage:{color:"#dddddd",font:"arial",fontSize:10,decimalPlaces:0},value:{color:"#cccc44",font:"arial",fontSize:10},lines:{enabled:!0,style:"curved",color:"segment"},truncation:{enabled:!1,truncateLength:30},formatter:null},effects:{load:{effect:"default",speed:1e3},pullOutSegmentOnClick:{effect:"bounce",speed:300,size:10},highlightSegmentOnMouseover:!0,highlightLuminosity:-.2},tooltips:{enabled:!1,type:"placeholder",string:"",placeholderParser:null,styles:{fadeInSpeed:250,backgroundColor:"#000000",backgroundOpacity:.5,color:"#efefef",borderRadius:2,font:"arial",fontSize:10,padding:4}},misc:{colors:{background:null,segments:["#2484c1","#65a620","#7b6888","#a05d56","#961a1a","#d8d23a","#e98125","#d0743c","#635222","#6ada6a","#0c6197","#7d9058","#207f33","#44b9b0","#bca44a","#e4a14b","#a3acb2","#8cc3e9","#69a6f9","#5b388f","#546e91","#8bde95","#d2ab58","#273c71","#98bf6e","#4daa4b","#98abc5","#cc1010","#31383b","#006391","#c2643f","#b0a474","#a5a39c","#a9c2bc","#22af8c","#7fcecf","#987ac6","#3d3b87","#b77b1c","#c9c2b6","#807ece","#8db27c","#be66a2","#9ed3c6","#00644b","#005064","#77979f","#77e079","#9c73ab","#1f79a7"],segmentStroke:"#ffffff"},gradient:{enabled:!1,percentage:95,color:"#000000"},canvasPadding:{top:5,right:5,bottom:5,left:5},pieCenterOffset:{x:0,y:0},cssPrefix:null},callbacks:{onload:null,onMouseoverSegment:null,onMouseoutSegment:null,onClickSegment:null}},f={initialCheck:function(a){var b=a.cssPrefix,c=a.element,d=a.options;if(!window.d3||!window.d3.hasOwnProperty("version"))return console.error("d3pie error: d3 is not available"),!1;if(!(c instanceof HTMLElement||c instanceof SVGElement))return console.error("d3pie error: the first d3pie() param must be a valid DOM element (not jQuery) or a ID string."),!1;if(!/[a-zA-Z][a-zA-Z0-9_-]*$/.test(b))return console.error("d3pie error: invalid options.misc.cssPrefix"),!1;if(!g.isArray(d.data.content))return console.error("d3pie error: invalid config structure: missing data.content property."),!1;if(0===d.data.content.length)return console.error("d3pie error: no data supplied."),!1;for(var e=[],f=0;f<d.data.content.length;f++)"number"!=typeof d.data.content[f].value||isNaN(d.data.content[f].value)?console.log("not valid: ",d.data.content[f]):d.data.content[f].value<=0?console.log("not valid - should have positive value: ",d.data.content[f]):e.push(d.data.content[f]);return a.options.data.content=e,!0}},g={addSVGSpace:function(a){var b=a.element,c=a.options.size.canvasWidth,d=a.options.size.canvasHeight,e=a.options.misc.colors.background,f=d3.select(b).append("svg:svg").attr("width",c).attr("height",d);return"transparent"!==e&&f.style("background-color",function(){return e}),f},whenIdExists:function(a,b){var c=1,d=1e3,e=setInterval(function(){document.getElementById(a)&&(clearInterval(e),b()),c>d&&clearInterval(e),c++},1)},whenElementsExist:function(a,b){var c=1,d=1e3,e=setInterval(function(){for(var f=!0,g=0;g<a.length;g++)if(!document.getElementById(a[g])){f=!1;break}f&&(clearInterval(e),b()),c>d&&clearInterval(e),c++},1)},shuffleArray:function(a){for(var b,c,d=a.length;0!==d;)c=Math.floor(Math.random()*d),d-=1,b=a[d],a[d]=a[c],a[c]=b;return a},processObj:function(a,b,c){return"string"==typeof b?g.processObj(a,b.split("."),c):1===b.length&&void 0!==c?(a[b[0]]=c,a[b[0]]):0===b.length?a:g.processObj(a[b[0]],b.slice(1),c)},getDimensions:function(a){var b=document.getElementById(a),c=0,d=0;if(b){var e=b.getBBox();c=e.width,d=e.height}else console.log("error: getDimensions() "+a+" not found.");return{w:c,h:d}},rectIntersect:function(a,b){var c=b.x>a.x+a.w||b.x+b.w<a.x||b.y+b.h<a.y||b.y>a.y+a.h;return!c},getColorShade:function(a,b){a=String(a).replace(/[^0-9a-f]/gi,""),a.length<6&&(a=a[0]+a[0]+a[1]+a[1]+a[2]+a[2]),b=b||0;for(var c="#",d=0;3>d;d++){var e=parseInt(a.substr(2*d,2),16);e=Math.round(Math.min(Math.max(0,e+e*b),255)).toString(16),c+=("00"+e).substr(e.length)}return c},initSegmentColors:function(a){for(var b=a.options.data.content,c=a.options.misc.colors.segments,d=[],e=0;e<b.length;e++)b[e].hasOwnProperty("color")?d.push(b[e].color):d.push(c[e]);return d},applySmallSegmentGrouping:function(a,b){var c;"percentage"===b.valueType&&(c=i.getTotalPieSize(a));for(var d=[],e=[],f=0,g=0;g<a.length;g++)if("percentage"===b.valueType){var h=a[g].value/c*100;if(h<=b.value){e.push(a[g]),f+=a[g].value;continue}a[g].isGrouped=!1,d.push(a[g])}else{if(a[g].value<=b.value){e.push(a[g]),f+=a[g].value;continue}a[g].isGrouped=!1,d.push(a[g])}return e.length&&d.push({color:b.color,label:b.label,value:f,isGrouped:!0,groupedData:e}),d},showPoint:function(a,b,c){a.append("circle").attr("cx",b).attr("cy",c).attr("r",2).style("fill","black")},isFunction:function(a){var b={};return a&&"[object Function]"===b.toString.call(a)},isArray:function(a){return"[object Array]"===Object.prototype.toString.call(a)}},h=function(){var a,b,c,d,e,f,g=arguments[0]||{},i=1,j=arguments.length,k=!1,l=Object.prototype.toString,m=Object.prototype.hasOwnProperty,n={"[object Boolean]":"boolean","[object Number]":"number","[object String]":"string","[object Function]":"function","[object Array]":"array","[object Date]":"date","[object RegExp]":"regexp","[object Object]":"object"},o={isFunction:function(a){return"function"===o.type(a)},isArray:Array.isArray||function(a){return"array"===o.type(a)},isWindow:function(a){return null!==a&&a===a.window},isNumeric:function(a){return!isNaN(parseFloat(a))&&isFinite(a)},type:function(a){return null===a?String(a):n[l.call(a)]||"object"},isPlainObject:function(a){if(!a||"object"!==o.type(a)||a.nodeType)return!1;try{if(a.constructor&&!m.call(a,"constructor")&&!m.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(b){return!1}var c;for(c in a);return void 0===c||m.call(a,c)}};for("boolean"==typeof g&&(k=g,g=arguments[1]||{},i=2),"object"==typeof g||o.isFunction(g)||(g={}),j===i&&(g=this,--i),i;j>i;i++)if(null!==(a=arguments[i]))for(b in a)c=g[b],d=a[b],g!==d&&(k&&d&&(o.isPlainObject(d)||(e=o.isArray(d)))?(e?(e=!1,f=c&&o.isArray(c)?c:[]):f=c&&o.isPlainObject(c)?c:{},g[b]=h(k,f,d)):void 0!==d&&(g[b]=d));return g},i={toRadians:function(a){return a*(Math.PI/180)},toDegrees:function(a){return a*(180/Math.PI)},computePieRadius:function(a){var b=a.options.size,c=a.options.misc.canvasPadding,d=b.canvasWidth-c.left-c.right,e=b.canvasHeight-c.top-c.bottom;"pie-center"!==a.options.header.location&&(e-=a.textComponents.headerHeight),a.textComponents.footer.exists&&(e-=a.textComponents.footer.h),e=0>e?0:e;var f,g,h=(e>d?d:e)/3;if(null!==b.pieOuterRadius)if(/%/.test(b.pieOuterRadius)){g=parseInt(b.pieOuterRadius.replace(/[\D]/,""),10),g=g>99?99:g,g=0>g?0:g;var i=e>d?d:e;if("none"!==a.options.labels.outer.format){var j=2*parseInt(a.options.labels.outer.pieDistance,10);i-j>0&&(i-=j)}h=Math.floor(i/100*g)/2}else h=parseInt(b.pieOuterRadius,10);/%/.test(b.pieInnerRadius)?(g=parseInt(b.pieInnerRadius.replace(/[\D]/,""),10),g=g>99?99:g,g=0>g?0:g,f=Math.floor(h/100*g)):f=parseInt(b.pieInnerRadius,10),a.innerRadius=f,a.outerRadius=h},getTotalPieSize:function(a){for(var b=0,c=0;c<a.length;c++)b+=a[c].value;return b},sortPieData:function(a){var b=a.options.data.content,c=a.options.data.sortOrder;switch(c){case"none":break;case"random":b=g.shuffleArray(b);break;case"value-asc":b.sort(function(a,b){return a.value<b.value?-1:1});break;case"value-desc":b.sort(function(a,b){return a.value<b.value?1:-1});break;case"label-asc":b.sort(function(a,b){return a.label.toLowerCase()>b.label.toLowerCase()?1:-1});break;case"label-desc":b.sort(function(a,b){return a.label.toLowerCase()<b.label.toLowerCase()?1:-1})}return b},getPieTranslateCenter:function(a){return"translate("+a.x+","+a.y+")"},calculatePieCenter:function(a){var b=a.options.misc.pieCenterOffset,c=a.textComponents.title.exists&&"pie-center"!==a.options.header.location,d=a.textComponents.subtitle.exists&&"pie-center"!==a.options.header.location,e=a.options.misc.canvasPadding.top;c&&d?e+=a.textComponents.title.h+a.options.header.titleSubtitlePadding+a.textComponents.subtitle.h:c?e+=a.textComponents.title.h:d&&(e+=a.textComponents.subtitle.h);var f=0;a.textComponents.footer.exists&&(f=a.textComponents.footer.h+a.options.misc.canvasPadding.bottom);var g=(a.options.size.canvasWidth-a.options.misc.canvasPadding.left-a.options.misc.canvasPadding.right)/2+a.options.misc.canvasPadding.left,h=(a.options.size.canvasHeight-f-e)/2+e;g+=b.x,h+=b.y,a.pieCenter={x:g,y:h}},rotate:function(a,b,c,d,e){e=e*Math.PI/180;var f=Math.cos,g=Math.sin,h=(a-c)*f(e)-(b-d)*g(e)+c,i=(a-c)*g(e)+(b-d)*f(e)+d;return{x:h,y:i}},translate:function(a,b,c,d){var e=i.toRadians(d);return{x:a+c*Math.sin(e),y:b-c*Math.cos(e)}},pointIsInArc:function(a,b,c){var d=c.innerRadius()(b),e=c.outerRadius()(b),f=c.startAngle()(b),g=c.endAngle()(b),h=a.x*a.x+a.y*a.y,i=Math.atan2(a.x,-a.y);return i=0>i?i+2*Math.PI:i,h>=d*d&&e*e>=h&&i>=f&&g>=i}},j={add:function(a,b,c){var d=j.getIncludes(c),e=a.options.labels,f=a.svg.insert("g","."+a.cssPrefix+"labels-"+b).attr("class",a.cssPrefix+"labels-"+b),g=f.selectAll("."+a.cssPrefix+"labelGroup-"+b).data(a.options.data.content).enter().append("g").attr("id",function(c,d){return a.cssPrefix+"labelGroup"+d+"-"+b}).attr("data-index",function(a,b){return b}).attr("class",a.cssPrefix+"labelGroup-"+b).style("opacity",0),h={section:b,sectionDisplayType:c};d.mainLabel&&g.append("text").attr("id",function(c,d){return a.cssPrefix+"segmentMainLabel"+d+"-"+b}).attr("class",a.cssPrefix+"segmentMainLabel-"+b).text(function(a,b){var c=a.label;return e.formatter?(h.index=b,h.part="mainLabel",h.value=a.value,h.label=c,c=e.formatter(h)):e.truncation.enabled&&a.label.length>e.truncation.truncateLength&&(c=a.label.substring(0,e.truncation.truncateLength)+"..."),c}).style("font-size",e.mainLabel.fontSize+"px").style("font-family",e.mainLabel.font).style("fill",e.mainLabel.color),d.percentage&&g.append("text").attr("id",function(c,d){return a.cssPrefix+"segmentPercentage"+d+"-"+b}).attr("class",a.cssPrefix+"segmentPercentage-"+b).text(function(a,b){var c=a.percentage;return e.formatter?(h.index=b,h.part="percentage",h.value=a.value,h.label=a.percentage,c=e.formatter(h)):c+="%",c}).style("font-size",e.percentage.fontSize+"px").style("font-family",e.percentage.font).style("fill",e.percentage.color),d.value&&g.append("text").attr("id",function(c,d){return a.cssPrefix+"segmentValue"+d+"-"+b}).attr("class",a.cssPrefix+"segmentValue-"+b).text(function(a,b){return h.index=b,h.part="value",h.value=a.value,h.label=a.value,e.formatter?e.formatter(h,a.value):a.value}).style("font-size",e.value.fontSize+"px").style("font-family",e.value.font).style("fill",e.value.color)},positionLabelElements:function(a,b,c){j["dimensions-"+b]=[];var d=d3.selectAll("."+a.cssPrefix+"labelGroup-"+b);d.each(function(c,d){var e=d3.select(this).selectAll("."+a.cssPrefix+"segmentMainLabel-"+b),f=d3.select(this).selectAll("."+a.cssPrefix+"segmentPercentage-"+b),g=d3.select(this).selectAll("."+a.cssPrefix+"segmentValue-"+b);j["dimensions-"+b].push({mainLabel:null!==e.node()?e.node().getBBox():null,percentage:null!==f.node()?f.node().getBBox():null,value:null!==g.node()?g.node().getBBox():null})});var e=5,f=j["dimensions-"+b];switch(c){case"label-value1":d3.selectAll("."+a.cssPrefix+"segmentValue-"+b).attr("dx",function(a,b){return f[b].mainLabel.width+e});break;case"label-value2":d3.selectAll("."+a.cssPrefix+"segmentValue-"+b).attr("dy",function(a,b){return f[b].mainLabel.height});break;case"label-percentage1":d3.selectAll("."+a.cssPrefix+"segmentPercentage-"+b).attr("dx",function(a,b){return f[b].mainLabel.width+e});break;case"label-percentage2":d3.selectAll("."+a.cssPrefix+"segmentPercentage-"+b).attr("dx",function(a,b){return f[b].mainLabel.width/2-f[b].percentage.width/2}).attr("dy",function(a,b){return f[b].mainLabel.height})}},computeLabelLinePositions:function(a){a.lineCoordGroups=[],d3.selectAll("."+a.cssPrefix+"labelGroup-outer").each(function(b,c){return j.computeLinePosition(a,c)})},computeLinePosition:function(a,b){var c,d,e,f,g=k.getSegmentAngle(b,a.options.data.content,a.totalSize,{midpoint:!0}),h=i.rotate(a.pieCenter.x,a.pieCenter.y-a.outerRadius,a.pieCenter.x,a.pieCenter.y,g),j=a.outerLabelGroupData[b].h/5,l=6,m=Math.floor(g/90),n=4;switch(2===m&&180===g&&(m=1),m){case 0:c=a.outerLabelGroupData[b].x-l-(a.outerLabelGroupData[b].x-l-h.x)/2,d=a.outerLabelGroupData[b].y+(h.y-a.outerLabelGroupData[b].y)/n,e=a.outerLabelGroupData[b].x-l,f=a.outerLabelGroupData[b].y-j;break;case 1:c=h.x+(a.outerLabelGroupData[b].x-h.x)/n,d=h.y+(a.outerLabelGroupData[b].y-h.y)/n,e=a.outerLabelGroupData[b].x-l,f=a.outerLabelGroupData[b].y-j;break;case 2:var o=a.outerLabelGroupData[b].x+a.outerLabelGroupData[b].w+l;c=h.x-(h.x-o)/n,d=h.y+(a.outerLabelGroupData[b].y-h.y)/n,e=a.outerLabelGroupData[b].x+a.outerLabelGroupData[b].w+l,f=a.outerLabelGroupData[b].y-j;break;case 3:var p=a.outerLabelGroupData[b].x+a.outerLabelGroupData[b].w+l;c=p+(h.x-p)/n,d=a.outerLabelGroupData[b].y+(h.y-a.outerLabelGroupData[b].y)/n,e=a.outerLabelGroupData[b].x+a.outerLabelGroupData[b].w+l,f=a.outerLabelGroupData[b].y-j}"straight"===a.options.labels.lines.style?a.lineCoordGroups[b]=[{x:h.x,y:h.y},{x:e,y:f}]:a.lineCoordGroups[b]=[{x:h.x,y:h.y},{x:c,y:d},{x:e,y:f}]},addLabelLines:function(a){var b=a.svg.insert("g","."+a.cssPrefix+"pieChart").attr("class",a.cssPrefix+"lineGroups").style("opacity",0),c=b.selectAll("."+a.cssPrefix+"lineGroup").data(a.lineCoordGroups).enter().append("g").attr("class",a.cssPrefix+"lineGroup"),d=d3.line().curve(d3.curveBasis).x(function(a){return a.x}).y(function(a){return a.y});c.append("path").attr("d",d).attr("stroke",function(b,c){return"segment"===a.options.labels.lines.color?a.options.colors[c]:a.options.labels.lines.color}).attr("stroke-width",1).attr("fill","none").style("opacity",function(b,c){var d=a.options.labels.outer.hideWhenLessThanPercentage,e=null!==d&&b.percentage<d||""===a.options.data.content[c].label;return e?0:1})},positionLabelGroups:function(a,b){"none"!==a.options.labels[b].format&&d3.selectAll("."+a.cssPrefix+"labelGroup-"+b).style("opacity",0).attr("transform",function(c,d){var e,f;if("outer"===b)e=a.outerLabelGroupData[d].x,f=a.outerLabelGroupData[d].y;else{var j=h(!0,{},a.pieCenter);if(a.innerRadius>0){var l=k.getSegmentAngle(d,a.options.data.content,a.totalSize,{midpoint:!0}),m=i.translate(a.pieCenter.x,a.pieCenter.y,a.innerRadius,l);j.x=m.x,j.y=m.y}var n=g.getDimensions(a.cssPrefix+"labelGroup"+d+"-inner"),o=n.w/2,p=n.h/4;e=j.x+(a.lineCoordGroups[d][0].x-j.x)/1.8,f=j.y+(a.lineCoordGroups[d][0].y-j.y)/1.8,e-=o,f+=p}return"translate("+e+","+f+")"})},fadeInLabelsAndLines:function(a){var b="default"===a.options.effects.load.effect?a.options.effects.load.speed:1;setTimeout(function(){var b="default"===a.options.effects.load.effect?400:1;d3.selectAll("."+a.cssPrefix+"labelGroup-outer").transition().duration(b).style("opacity",function(b,c){var d=a.options.labels.outer.hideWhenLessThanPercentage;return null!==d&&b.percentage<d?0:1}),d3.selectAll("."+a.cssPrefix+"labelGroup-inner").transition().duration(b).style("opacity",function(b,c){var d=a.options.labels.inner.hideWhenLessThanPercentage;return null!==d&&b.percentage<d?0:1}),d3.selectAll("g."+a.cssPrefix+"lineGroups").transition().duration(b).style("opacity",1),g.isFunction(a.options.callbacks.onload)&&setTimeout(function(){try{a.options.callbacks.onload()}catch(b){}},b)},b)},getIncludes:function(a){var b=!1,c=!1,d=!1;switch(a){case"label":b=!0;break;case"value":c=!0;break;case"percentage":d=!0;break;case"label-value1":case"label-value2":b=!0,c=!0;break;case"label-percentage1":case"label-percentage2":b=!0,d=!0}return{mainLabel:b,value:c,percentage:d}},computeOuterLabelCoords:function(a){a.svg.selectAll("."+a.cssPrefix+"labelGroup-outer").each(function(b,c){return j.getIdealOuterLabelPositions(a,c)}),j.resolveOuterLabelCollisions(a)},resolveOuterLabelCollisions:function(a){if("none"!==a.options.labels.outer.format){var b=a.options.data.content.length;j.checkConflict(a,0,"clockwise",b),j.checkConflict(a,b-1,"anticlockwise",b)}},checkConflict:function(a,b,c,d){var e,f;if(!(1>=d)){var h=a.outerLabelGroupData[b].hs;if(!("clockwise"===c&&"right"!==h||"anticlockwise"===c&&"left"!==h)){var i="clockwise"===c?b+1:b-1,k=a.outerLabelGroupData[b],l=a.outerLabelGroupData[i],m={labelHeights:a.outerLabelGroupData[0].h,center:a.pieCenter,lineLength:a.outerRadius+a.options.labels.outer.pieDistance,heightChange:a.outerLabelGroupData[0].h+1};if("clockwise"===c){for(e=0;b>=e;e++)if(f=a.outerLabelGroupData[e],!j.isLabelHidden(a,e)&&g.rectIntersect(f,l)){j.adjustLabelPos(a,i,k,m);break}}else for(e=d-1;e>=b;e--)if(f=a.outerLabelGroupData[e],!j.isLabelHidden(a,e)&&g.rectIntersect(f,l)){j.adjustLabelPos(a,i,k,m);break}j.checkConflict(a,i,c,d)}}},isLabelHidden:function(a,b){var c=a.options.labels.outer.hideWhenLessThanPercentage;return null!==c&&d.percentage<c||""===a.options.data.content[b].label},adjustLabelPos:function(a,b,c,d){var e,f,g,h;h=c.y+d.heightChange,f=d.center.y-h,e=Math.abs(d.lineLength)>Math.abs(f)?Math.sqrt(d.lineLength*d.lineLength-f*f):Math.sqrt(f*f-d.lineLength*d.lineLength),g="right"===c.hs?d.center.x+e:d.center.x-e-a.outerLabelGroupData[b].w,a.outerLabelGroupData[b].x=g,a.outerLabelGroupData[b].y=h},getIdealOuterLabelPositions:function(a,b){var c=d3.select("#"+a.cssPrefix+"labelGroup"+b+"-outer").node();if(c){var d=c.getBBox(),e=k.getSegmentAngle(b,a.options.data.content,a.totalSize,{midpoint:!0}),f=a.pieCenter.x,g=a.pieCenter.y-(a.outerRadius+a.options.labels.outer.pieDistance),h=i.rotate(f,g,a.pieCenter.x,a.pieCenter.y,e),j="right";e>180?(h.x-=d.width+8,j="left"):h.x+=8,a.outerLabelGroupData[b]={x:h.x,y:h.y,w:d.width,h:d.height,hs:j}}}},k={effectMap:{none:d3.easeLinear,bounce:d3.easeBounce,linear:d3.easeLinear,sin:d3.easeSin,elastic:d3.easeElastic,back:d3.easeBack,quad:d3.easeQuad,circle:d3.easeCircle,exp:d3.easeExp},create:function(a){var b=a.pieCenter,c=a.options.colors,d=a.options.effects.load,e=a.options.misc.colors.segmentStroke,f=a.svg.insert("g","#"+a.cssPrefix+"title").attr("transform",function(){return i.getPieTranslateCenter(b)}).attr("class",a.cssPrefix+"pieChart"),g=d3.arc().innerRadius(a.innerRadius).outerRadius(a.outerRadius).startAngle(0).endAngle(function(b){return b.value/a.totalSize*2*Math.PI}),h=f.selectAll("."+a.cssPrefix+"arc").data(a.options.data.content).enter().append("g").attr("class",a.cssPrefix+"arc"),j=d.speed;"none"===d.effect&&(j=0),h.append("path").attr("id",function(b,c){return a.cssPrefix+"segment"+c}).attr("fill",function(b,d){var e=c[d];return a.options.misc.gradient.enabled&&(e="url(#"+a.cssPrefix+"grad"+d+")"),e}).style("stroke",e).style("stroke-width",1).transition().ease(d3.easeCubicInOut).duration(j).attr("data-index",function(a,b){return b}).attrTween("d",function(b){var c=d3.interpolate({value:0},b);return function(b){return a.arc(c(b))}}),a.svg.selectAll("g."+a.cssPrefix+"arc").attr("transform",function(b,c){var d=0;return c>0&&(d=k.getSegmentAngle(c-1,a.options.data.content,a.totalSize)),"rotate("+d+")"}),a.arc=g},addGradients:function(a){var b=a.svg.append("defs").selectAll("radialGradient").data(a.options.data.content).enter().append("radialGradient").attr("gradientUnits","userSpaceOnUse").attr("cx",0).attr("cy",0).attr("r","120%").attr("id",function(b,c){return a.cssPrefix+"grad"+c});b.append("stop").attr("offset","0%").style("stop-color",function(b,c){return a.options.colors[c]}),b.append("stop").attr("offset",a.options.misc.gradient.percentage+"%").style("stop-color",a.options.misc.gradient.color)},addSegmentEventHandlers:function(a){var b=d3.selectAll("."+a.cssPrefix+"arc,."+a.cssPrefix+"labelGroup-inner,."+a.cssPrefix+"labelGroup-outer");b.on("click",function(){var b,c=d3.select(this);if(c.attr("class")===a.cssPrefix+"arc")b=c.select("path");else{var d=c.attr("data-index");b=d3.select("#"+a.cssPrefix+"segment"+d)}var e=b.attr("class")===a.cssPrefix+"expanded";k.onSegmentEvent(a,a.options.callbacks.onClickSegment,b,e),"none"!==a.options.effects.pullOutSegmentOnClick.effect&&(e?k.closeSegment(a,b.node()):k.openSegment(a,b.node()))}),b.on("mouseover",function(){var b,c,d=d3.select(this);if(d.attr("class")===a.cssPrefix+"arc"?b=d.select("path"):(c=d.attr("data-index"),b=d3.select("#"+a.cssPrefix+"segment"+c)),a.options.effects.highlightSegmentOnMouseover){c=b.attr("data-index");var e=a.options.colors[c];b.style("fill",g.getColorShade(e,a.options.effects.highlightLuminosity))}a.options.tooltips.enabled&&(c=b.attr("data-index"),m.showTooltip(a,c));var f=b.attr("class")===a.cssPrefix+"expanded";k.onSegmentEvent(a,a.options.callbacks.onMouseoverSegment,b,f)}),b.on("mousemove",function(){m.moveTooltip(a)}),b.on("mouseout",function(){var b,c,d=d3.select(this);if(d.attr("class")===a.cssPrefix+"arc"?b=d.select("path"):(c=d.attr("data-index"),b=d3.select("#"+a.cssPrefix+"segment"+c)),a.options.effects.highlightSegmentOnMouseover){c=b.attr("data-index");var e=a.options.colors[c];a.options.misc.gradient.enabled&&(e="url(#"+a.cssPrefix+"grad"+c+")"),b.style("fill",e)}a.options.tooltips.enabled&&(c=b.attr("data-index"),m.hideTooltip(a,c));var f=b.attr("class")===a.cssPrefix+"expanded";k.onSegmentEvent(a,a.options.callbacks.onMouseoutSegment,b,f)})},onSegmentEvent:function(a,b,c,d){if(g.isFunction(b)){var e=parseInt(c.attr("data-index"),10);b({segment:c.node(),index:e,expanded:d,data:a.options.data.content[e]})}},openSegment:function(a,b){a.isOpeningSegment||(a.isOpeningSegment=!0,k.maybeCloseOpenSegment(),d3.select(b).transition().ease(k.effectMap[a.options.effects.pullOutSegmentOnClick.effect]).duration(a.options.effects.pullOutSegmentOnClick.speed).attr("transform",function(b,c){var d=a.arc.centroid(b),e=d[0],f=d[1],g=Math.sqrt(e*e+f*f),h=parseInt(a.options.effects.pullOutSegmentOnClick.size,10);return"translate("+e/g*h+","+f/g*h+")"}).on("end",function(c,d){a.currentlyOpenSegment=b,a.isOpeningSegment=!1,d3.select(b).attr("class",a.cssPrefix+"expanded")}))},maybeCloseOpenSegment:function(){d3.selectAll("."+pie.cssPrefix+"expanded").size()>0&&k.closeSegment(pie,d3.select("."+pie.cssPrefix+"expanded").node())},closeSegment:function(a,b){d3.select(b).transition().duration(400).attr("transform","translate(0,0)").on("end",function(c,d){d3.select(b).attr("class",""),a.currentlyOpenSegment=null})},getCentroid:function(a){var b=a.getBBox();return{x:b.x+b.width/2,y:b.y+b.height/2}},getSegmentAngle:function(a,b,c,d){var e,f=h({compounded:!0,midpoint:!1},d),g=b[a].value;if(f.compounded){e=0;for(var i=0;a>=i;i++)e+=b[i].value}"undefined"==typeof e&&(e=g);var j=e/c*360;if(f.midpoint){var k=g/c*360;j-=k/2}return j}},l={offscreenCoord:-1e4,addTitle:function(a){a.svg.selectAll("."+a.cssPrefix+"title").data([a.options.header.title]).enter().append("text").text(function(a){return a.text}).attr("id",a.cssPrefix+"title").attr("class",a.cssPrefix+"title").attr("x",l.offscreenCoord).attr("y",l.offscreenCoord).attr("text-anchor",function(){var b;return b="top-center"===a.options.header.location||"pie-center"===a.options.header.location?"middle":"left"}).attr("fill",function(a){return a.color}).style("font-size",function(a){return a.fontSize+"px"}).style("font-family",function(a){return a.font})},positionTitle:function(a){var b,c=a.textComponents,d=a.options.header.location,e=a.options.misc.canvasPadding,f=a.options.size.canvasWidth,g=a.options.header.titleSubtitlePadding;b="top-left"===d?e.left:(f-e.right)/2+e.left,b+=a.options.misc.pieCenterOffset.x;var h=e.top+c.title.h;if("pie-center"===d)if(h=a.pieCenter.y,c.subtitle.exists){var i=c.title.h+g+c.subtitle.h;h=h-i/2+c.title.h}else h+=c.title.h/4;a.svg.select("#"+a.cssPrefix+"title").attr("x",b).attr("y",h)},addSubtitle:function(a){var b=a.options.header.location;a.svg.selectAll("."+a.cssPrefix+"subtitle").data([a.options.header.subtitle]).enter().append("text").text(function(a){return a.text}).attr("x",l.offscreenCoord).attr("y",l.offscreenCoord).attr("id",a.cssPrefix+"subtitle").attr("class",a.cssPrefix+"subtitle").attr("text-anchor",function(){var a;return a="top-center"===b||"pie-center"===b?"middle":"left"}).attr("fill",function(a){return a.color}).style("font-size",function(a){return a.fontSize+"px"}).style("font-family",function(a){return a.font})},positionSubtitle:function(a){var b,c=a.options.misc.canvasPadding,d=a.options.size.canvasWidth;b="top-left"===a.options.header.location?c.left:(d-c.right)/2+c.left,b+=a.options.misc.pieCenterOffset.x;var e=l.getHeaderHeight(a);a.svg.select("#"+a.cssPrefix+"subtitle").attr("x",b).attr("y",e)},addFooter:function(a){a.svg.selectAll("."+a.cssPrefix+"footer").data([a.options.footer]).enter().append("text").text(function(a){return a.text}).attr("x",l.offscreenCoord).attr("y",l.offscreenCoord).attr("id",a.cssPrefix+"footer").attr("class",a.cssPrefix+"footer").attr("text-anchor",function(){var b="left";return"bottom-center"===a.options.footer.location?b="middle":"bottom-right"===a.options.footer.location&&(b="left"),b}).attr("fill",function(a){return a.color}).style("font-size",function(a){return a.fontSize+"px"}).style("font-family",function(a){return a.font})},positionFooter:function(a){var b,c=a.options.footer.location,d=a.textComponents.footer.w,e=a.options.size.canvasWidth,f=a.options.size.canvasHeight,g=a.options.misc.canvasPadding;b="bottom-left"===c?g.left:"bottom-right"===c?e-d-g.right:e/2,a.svg.select("#"+a.cssPrefix+"footer").attr("x",b).attr("y",f-g.bottom)},getHeaderHeight:function(a){var b;if(a.textComponents.title.exists){var c=a.textComponents.title.h+a.options.header.titleSubtitlePadding+a.textComponents.subtitle.h;b="pie-center"===a.options.header.location?a.pieCenter.y-c/2+c:c+a.options.misc.canvasPadding.top}else if("pie-center"===a.options.header.location){var d=a.options.misc.canvasPadding.bottom+a.textComponents.footer.h;b=(a.options.size.canvasHeight-d)/2+a.options.misc.canvasPadding.top+a.textComponents.subtitle.h/2}else b=a.options.misc.canvasPadding.top+a.textComponents.subtitle.h;return b}},m={addTooltips:function(a){var b=a.svg.insert("g").attr("class",a.cssPrefix+"tooltips");b.selectAll("."+a.cssPrefix+"tooltip").data(a.options.data.content).enter().append("g").attr("class",a.cssPrefix+"tooltip").attr("id",function(b,c){return a.cssPrefix+"tooltip"+c}).style("opacity",0).append("rect").attr("rx",a.options.tooltips.styles.borderRadius).attr("ry",a.options.tooltips.styles.borderRadius).attr("x",-a.options.tooltips.styles.padding).attr("opacity",a.options.tooltips.styles.backgroundOpacity).style("fill",a.options.tooltips.styles.backgroundColor),b.selectAll("."+a.cssPrefix+"tooltip").data(a.options.data.content).append("text").attr("fill",function(b){return a.options.tooltips.styles.color}).style("font-size",function(b){return a.options.tooltips.styles.fontSize}).style("font-family",function(b){return a.options.tooltips.styles.font}).text(function(b,c){var d=a.options.tooltips.string;return"caption"===a.options.tooltips.type&&(d=b.caption),m.replacePlaceholders(a,d,c,{label:b.label,value:b.value,percentage:b.percentage})}),b.selectAll("."+a.cssPrefix+"tooltip rect").attr("width",function(b,c){var d=g.getDimensions(a.cssPrefix+"tooltip"+c);return d.w+2*a.options.tooltips.styles.padding}).attr("height",function(b,c){var d=g.getDimensions(a.cssPrefix+"tooltip"+c);return d.h+2*a.options.tooltips.styles.padding}).attr("y",function(b,c){var d=g.getDimensions(a.cssPrefix+"tooltip"+c);return-(d.h/2)+1})},showTooltip:function(a,b){var c=a.options.tooltips.styles.fadeInSpeed;m.currentTooltip===b&&(c=1),m.currentTooltip=b,d3.select("#"+a.cssPrefix+"tooltip"+b).transition().duration(c).style("opacity",function(){return 1}),m.moveTooltip(a)},moveTooltip:function(a){d3.selectAll("#"+a.cssPrefix+"tooltip"+m.currentTooltip).attr("transform",function(b){var c=d3.mouse(this.parentNode),d=c[0]+a.options.tooltips.styles.padding+2,e=c[1]-2*a.options.tooltips.styles.padding-2;return"translate("+d+","+e+")"})},hideTooltip:function(a,b){d3.select("#"+a.cssPrefix+"tooltip"+b).style("opacity",function(){return 0}),d3.select("#"+a.cssPrefix+"tooltip"+m.currentTooltip).attr("transform",function(b,c){var d=a.options.size.canvasWidth+1e3,e=a.options.size.canvasHeight+1e3;return"translate("+d+","+e+")"})},replacePlaceholders:function(a,b,c,d){g.isFunction(a.options.tooltips.placeholderParser)&&a.options.tooltips.placeholderParser(c,d);var e=function(){return function(a){var b=arguments[1];return d.hasOwnProperty(b)?d[arguments[1]]:arguments[0]}};return b.replace(/\{(\w+)\}/g,e(d))}},n=function(d,g){if(this.element=d,"string"==typeof d){var i=d.replace(/^#/,"");this.element=document.getElementById(i)}var j={};h(!0,j,e,g),this.options=j,null!==this.options.misc.cssPrefix?this.cssPrefix=this.options.misc.cssPrefix:(this.cssPrefix="p"+c+"_",c++),f.initialCheck(this)&&(d3.select(this.element).attr(a,b),o.call(this),p.call(this))};n.prototype.recreate=function(){f.initialCheck(this)&&(o.call(this),p.call(this))},n.prototype.redraw=function(){this.element.innerHTML="",p.call(this)},n.prototype.destroy=function(){this.element.innerHTML="",d3.select(this.element).attr(a,null)},n.prototype.getOpenSegment=function(){var a=this.currentlyOpenSegment;if(null!==a&&"undefined"!=typeof a){var b=parseInt(d3.select(a).attr("data-index"),10);return{element:a,index:b,data:this.options.data.content[b]}}return null},n.prototype.openSegment=function(a){a=parseInt(a,10),0>a||a>this.options.data.content.length-1||k.openSegment(this,d3.select("#"+this.cssPrefix+"segment"+a).node())},n.prototype.closeSegment=function(){k.maybeCloseOpenSegment()},n.prototype.updateProp=function(a,b){switch(a){case"header.title.text":var c=g.processObj(this.options,a);g.processObj(this.options,a,b),d3.select("#"+this.cssPrefix+"title").html(b),(""===c&&""!==b||""!==c&&""===b)&&this.redraw();break;case"header.subtitle.text":var d=g.processObj(this.options,a);g.processObj(this.options,a,b),d3.select("#"+this.cssPrefix+"subtitle").html(b),(""===d&&""!==b||""!==d&&""===b)&&this.redraw();break;case"callbacks.onload":case"callbacks.onMouseoverSegment":case"callbacks.onMouseoutSegment":case"callbacks.onClickSegment":case"effects.pullOutSegmentOnClick.effect":case"effects.pullOutSegmentOnClick.speed":case"effects.pullOutSegmentOnClick.size":case"effects.highlightSegmentOnMouseover":case"effects.highlightLuminosity":g.processObj(this.options,a,b);break;default:g.processObj(this.options,a,b),this.destroy(),this.recreate()}};var o=function(){this.options.data.content=i.sortPieData(this),this.options.data.smallSegmentGrouping.enabled&&(this.options.data.content=g.applySmallSegmentGrouping(this.options.data.content,this.options.data.smallSegmentGrouping)),this.options.colors=g.initSegmentColors(this),this.totalSize=i.getTotalPieSize(this.options.data.content);for(var a=this.options.labels.percentage.decimalPlaces,b=0;b<this.options.data.content.length;b++)this.options.data.content[b].percentage=q(this.options.data.content[b].value,this.totalSize,a);for(var c=0,d=0;d<this.options.data.content.length;d++)d===this.options.data.content.length-1&&(this.options.data.content[d].percentage=(100-c).toFixed(a)),c+=parseFloat(this.options.data.content[d].percentage)},p=function(){this.svg=g.addSVGSpace(this),this.textComponents={
|
9
|
+
headerHeight:0,title:{exists:""!==this.options.header.title.text,h:0,w:0},subtitle:{exists:""!==this.options.header.subtitle.text,h:0,w:0},footer:{exists:""!==this.options.footer.text,h:0,w:0}},this.outerLabelGroupData=[],this.textComponents.title.exists&&l.addTitle(this),this.textComponents.subtitle.exists&&l.addSubtitle(this),l.addFooter(this);var a=this;g.whenIdExists(this.cssPrefix+"footer",function(){l.positionFooter(a);var b=g.getDimensions(a.cssPrefix+"footer");a.textComponents.footer.h=b.h,a.textComponents.footer.w=b.w});var b=[];this.textComponents.title.exists&&b.push(this.cssPrefix+"title"),this.textComponents.subtitle.exists&&b.push(this.cssPrefix+"subtitle"),this.textComponents.footer.exists&&b.push(this.cssPrefix+"footer"),g.whenElementsExist(b,function(){if(a.textComponents.title.exists){var b=g.getDimensions(a.cssPrefix+"title");a.textComponents.title.h=b.h,a.textComponents.title.w=b.w}if(a.textComponents.subtitle.exists){var c=g.getDimensions(a.cssPrefix+"subtitle");a.textComponents.subtitle.h=c.h,a.textComponents.subtitle.w=c.w}if(a.textComponents.title.exists||a.textComponents.subtitle.exists){var d=0;a.textComponents.title.exists&&(d+=a.textComponents.title.h,a.textComponents.subtitle.exists&&(d+=a.options.header.titleSubtitlePadding)),a.textComponents.subtitle.exists&&(d+=a.textComponents.subtitle.h),a.textComponents.headerHeight=d}i.computePieRadius(a),i.calculatePieCenter(a),l.positionTitle(a),l.positionSubtitle(a),a.options.misc.gradient.enabled&&k.addGradients(a),k.create(a),j.add(a,"inner",a.options.labels.inner.format),j.add(a,"outer",a.options.labels.outer.format),j.positionLabelElements(a,"inner",a.options.labels.inner.format),j.positionLabelElements(a,"outer",a.options.labels.outer.format),j.computeOuterLabelCoords(a),j.positionLabelGroups(a,"outer"),j.computeLabelLinePositions(a),a.options.labels.lines.enabled&&"none"!==a.options.labels.outer.format&&j.addLabelLines(a),j.positionLabelGroups(a,"inner"),j.fadeInLabelsAndLines(a),a.options.tooltips.enabled&&m.addTooltips(a),k.addSegmentEventHandlers(a)})},q=function(a,b,c){var d=a/b;return 0>=c?Math.round(100*d):(100*d).toFixed(c)};return n});
|
data/d3pie-rails.gemspec
CHANGED
@@ -15,7 +15,7 @@ Gem::Specification.new do |s|
|
|
15
15
|
s.rubyforge_project = "d3pie-rails"
|
16
16
|
|
17
17
|
s.add_dependency "railties", ">= 3.1"
|
18
|
-
s.add_dependency "d3-rails", ">=
|
18
|
+
s.add_dependency "d3-rails", ">= 4.1"
|
19
19
|
s.add_development_dependency "rails", ">= 3.1"
|
20
20
|
|
21
21
|
s.files = `git ls-files`.split("\n")
|
data/lib/d3pie/rails/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: d3pie-rails
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1
|
4
|
+
version: 0.2.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Marshall Harnish
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2017-03-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: railties
|
@@ -30,14 +30,14 @@ dependencies:
|
|
30
30
|
requirements:
|
31
31
|
- - ">="
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: '
|
33
|
+
version: '4.1'
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: '
|
40
|
+
version: '4.1'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: rails
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|