@d3plus/core 3.0.0-alpha.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6219 -0
- package/es/index.js +4 -0
- package/es/src/charts/AreaPlot.js +86 -0
- package/es/src/charts/BarChart.js +93 -0
- package/es/src/charts/BoxWhisker.js +97 -0
- package/es/src/charts/BumpChart.js +148 -0
- package/es/src/charts/Donut.js +84 -0
- package/es/src/charts/Geomap.js +833 -0
- package/es/src/charts/LinePlot.js +84 -0
- package/es/src/charts/Matrix.js +358 -0
- package/es/src/charts/Network.js +787 -0
- package/es/src/charts/Pack.js +318 -0
- package/es/src/charts/Pie.js +242 -0
- package/es/src/charts/Plot.js +2212 -0
- package/es/src/charts/Priestley.js +312 -0
- package/es/src/charts/Radar.js +365 -0
- package/es/src/charts/RadialMatrix.js +393 -0
- package/es/src/charts/Rings.js +777 -0
- package/es/src/charts/Sankey.js +413 -0
- package/es/src/charts/StackedArea.js +80 -0
- package/es/src/charts/Tree.js +312 -0
- package/es/src/charts/Treemap.js +406 -0
- package/es/src/charts/Viz.js +2017 -0
- package/es/src/charts/drawSteps/drawAttribution.js +14 -0
- package/es/src/charts/drawSteps/drawBack.js +23 -0
- package/es/src/charts/drawSteps/drawColorScale.js +69 -0
- package/es/src/charts/drawSteps/drawLegend.js +120 -0
- package/es/src/charts/drawSteps/drawSubtitle.js +31 -0
- package/es/src/charts/drawSteps/drawTimeline.js +80 -0
- package/es/src/charts/drawSteps/drawTitle.js +31 -0
- package/es/src/charts/drawSteps/drawTotal.js +32 -0
- package/es/src/charts/drawSteps/zoomControls.js +254 -0
- package/es/src/charts/events/click.legend.js +76 -0
- package/es/src/charts/events/click.shape.js +26 -0
- package/es/src/charts/events/mouseenter.js +31 -0
- package/es/src/charts/events/mouseleave.js +21 -0
- package/es/src/charts/events/mousemove.legend.js +64 -0
- package/es/src/charts/events/mousemove.shape.js +42 -0
- package/es/src/charts/events/touchstart.body.js +7 -0
- package/es/src/charts/helpers/matrixData.js +104 -0
- package/es/src/charts/helpers/tileAttributions.js +34 -0
- package/es/src/charts/index.js +21 -0
- package/es/src/charts/plotBuffers/Bar.js +65 -0
- package/es/src/charts/plotBuffers/Box.js +60 -0
- package/es/src/charts/plotBuffers/Circle.js +39 -0
- package/es/src/charts/plotBuffers/Line.js +30 -0
- package/es/src/charts/plotBuffers/Rect.js +40 -0
- package/es/src/charts/plotBuffers/discreteBuffer.js +24 -0
- package/es/src/charts/plotBuffers/numericBuffer.js +111 -0
- package/es/src/components/Axis.js +1567 -0
- package/es/src/components/AxisBottom.js +77 -0
- package/es/src/components/AxisLeft.js +77 -0
- package/es/src/components/AxisRight.js +77 -0
- package/es/src/components/AxisTop.js +77 -0
- package/es/src/components/ColorScale.js +958 -0
- package/es/src/components/Legend.js +673 -0
- package/es/src/components/Message.js +95 -0
- package/es/src/components/TextBox.js +752 -0
- package/es/src/components/Timeline.js +760 -0
- package/es/src/components/Tooltip.js +726 -0
- package/es/src/components/index.js +11 -0
- package/es/src/shapes/Area.js +361 -0
- package/es/src/shapes/Bar.js +342 -0
- package/es/src/shapes/Box.js +482 -0
- package/es/src/shapes/Circle.js +201 -0
- package/es/src/shapes/Image.js +255 -0
- package/es/src/shapes/Line.js +289 -0
- package/es/src/shapes/Path.js +186 -0
- package/es/src/shapes/Rect.js +215 -0
- package/es/src/shapes/Shape.js +1156 -0
- package/es/src/shapes/Whisker.js +330 -0
- package/es/src/shapes/index.js +10 -0
- package/es/src/utils/BaseClass.js +204 -0
- package/es/src/utils/RESET.js +4 -0
- package/es/src/utils/accessor.js +19 -0
- package/es/src/utils/configPrep.js +76 -0
- package/es/src/utils/constant.js +15 -0
- package/es/src/utils/getProp.js +9 -0
- package/es/src/utils/index.js +7 -0
- package/es/src/utils/uuid.js +13 -0
- package/package.json +68 -0
- package/umd/d3plus-core.full.js +56459 -0
- package/umd/d3plus-core.full.js.map +1 -0
- package/umd/d3plus-core.full.min.js +7241 -0
- package/umd/d3plus-core.js +14422 -0
- package/umd/d3plus-core.js.map +1 -0
- package/umd/d3plus-core.min.js +4564 -0
|
@@ -0,0 +1,2212 @@
|
|
|
1
|
+
/* eslint no-cond-assign: 0 */ function _array_like_to_array(arr, len) {
|
|
2
|
+
if (len == null || len > arr.length) len = arr.length;
|
|
3
|
+
for(var i = 0, arr2 = new Array(len); i < len; i++)arr2[i] = arr[i];
|
|
4
|
+
return arr2;
|
|
5
|
+
}
|
|
6
|
+
function _array_with_holes(arr) {
|
|
7
|
+
if (Array.isArray(arr)) return arr;
|
|
8
|
+
}
|
|
9
|
+
function _assert_this_initialized(self) {
|
|
10
|
+
if (self === void 0) {
|
|
11
|
+
throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
|
|
12
|
+
}
|
|
13
|
+
return self;
|
|
14
|
+
}
|
|
15
|
+
function _call_super(_this, derived, args) {
|
|
16
|
+
derived = _get_prototype_of(derived);
|
|
17
|
+
return _possible_constructor_return(_this, _is_native_reflect_construct() ? Reflect.construct(derived, args || [], _get_prototype_of(_this).constructor) : derived.apply(_this, args));
|
|
18
|
+
}
|
|
19
|
+
function _class_call_check(instance, Constructor) {
|
|
20
|
+
if (!(instance instanceof Constructor)) {
|
|
21
|
+
throw new TypeError("Cannot call a class as a function");
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
function _defineProperties(target, props) {
|
|
25
|
+
for(var i = 0; i < props.length; i++){
|
|
26
|
+
var descriptor = props[i];
|
|
27
|
+
descriptor.enumerable = descriptor.enumerable || false;
|
|
28
|
+
descriptor.configurable = true;
|
|
29
|
+
if ("value" in descriptor) descriptor.writable = true;
|
|
30
|
+
Object.defineProperty(target, descriptor.key, descriptor);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
function _create_class(Constructor, protoProps, staticProps) {
|
|
34
|
+
if (protoProps) _defineProperties(Constructor.prototype, protoProps);
|
|
35
|
+
if (staticProps) _defineProperties(Constructor, staticProps);
|
|
36
|
+
return Constructor;
|
|
37
|
+
}
|
|
38
|
+
function _define_property(obj, key, value) {
|
|
39
|
+
if (key in obj) {
|
|
40
|
+
Object.defineProperty(obj, key, {
|
|
41
|
+
value: value,
|
|
42
|
+
enumerable: true,
|
|
43
|
+
configurable: true,
|
|
44
|
+
writable: true
|
|
45
|
+
});
|
|
46
|
+
} else {
|
|
47
|
+
obj[key] = value;
|
|
48
|
+
}
|
|
49
|
+
return obj;
|
|
50
|
+
}
|
|
51
|
+
function _get(target, property, receiver) {
|
|
52
|
+
if (typeof Reflect !== "undefined" && Reflect.get) {
|
|
53
|
+
_get = Reflect.get;
|
|
54
|
+
} else {
|
|
55
|
+
_get = function get(target, property, receiver) {
|
|
56
|
+
var base = _super_prop_base(target, property);
|
|
57
|
+
if (!base) return;
|
|
58
|
+
var desc = Object.getOwnPropertyDescriptor(base, property);
|
|
59
|
+
if (desc.get) {
|
|
60
|
+
return desc.get.call(receiver || target);
|
|
61
|
+
}
|
|
62
|
+
return desc.value;
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
return _get(target, property, receiver || target);
|
|
66
|
+
}
|
|
67
|
+
function _get_prototype_of(o) {
|
|
68
|
+
_get_prototype_of = Object.setPrototypeOf ? Object.getPrototypeOf : function getPrototypeOf(o) {
|
|
69
|
+
return o.__proto__ || Object.getPrototypeOf(o);
|
|
70
|
+
};
|
|
71
|
+
return _get_prototype_of(o);
|
|
72
|
+
}
|
|
73
|
+
function _inherits(subClass, superClass) {
|
|
74
|
+
if (typeof superClass !== "function" && superClass !== null) {
|
|
75
|
+
throw new TypeError("Super expression must either be null or a function");
|
|
76
|
+
}
|
|
77
|
+
subClass.prototype = Object.create(superClass && superClass.prototype, {
|
|
78
|
+
constructor: {
|
|
79
|
+
value: subClass,
|
|
80
|
+
writable: true,
|
|
81
|
+
configurable: true
|
|
82
|
+
}
|
|
83
|
+
});
|
|
84
|
+
if (superClass) _set_prototype_of(subClass, superClass);
|
|
85
|
+
}
|
|
86
|
+
function _instanceof(left, right) {
|
|
87
|
+
if (right != null && typeof Symbol !== "undefined" && right[Symbol.hasInstance]) {
|
|
88
|
+
return !!right[Symbol.hasInstance](left);
|
|
89
|
+
} else {
|
|
90
|
+
return left instanceof right;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
function _iterable_to_array_limit(arr, i) {
|
|
94
|
+
var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"];
|
|
95
|
+
if (_i == null) return;
|
|
96
|
+
var _arr = [];
|
|
97
|
+
var _n = true;
|
|
98
|
+
var _d = false;
|
|
99
|
+
var _s, _e;
|
|
100
|
+
try {
|
|
101
|
+
for(_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true){
|
|
102
|
+
_arr.push(_s.value);
|
|
103
|
+
if (i && _arr.length === i) break;
|
|
104
|
+
}
|
|
105
|
+
} catch (err) {
|
|
106
|
+
_d = true;
|
|
107
|
+
_e = err;
|
|
108
|
+
} finally{
|
|
109
|
+
try {
|
|
110
|
+
if (!_n && _i["return"] != null) _i["return"]();
|
|
111
|
+
} finally{
|
|
112
|
+
if (_d) throw _e;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
return _arr;
|
|
116
|
+
}
|
|
117
|
+
function _non_iterable_rest() {
|
|
118
|
+
throw new TypeError("Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
|
|
119
|
+
}
|
|
120
|
+
function _possible_constructor_return(self, call) {
|
|
121
|
+
if (call && (_type_of(call) === "object" || typeof call === "function")) {
|
|
122
|
+
return call;
|
|
123
|
+
}
|
|
124
|
+
return _assert_this_initialized(self);
|
|
125
|
+
}
|
|
126
|
+
function _set_prototype_of(o, p) {
|
|
127
|
+
_set_prototype_of = Object.setPrototypeOf || function setPrototypeOf(o, p) {
|
|
128
|
+
o.__proto__ = p;
|
|
129
|
+
return o;
|
|
130
|
+
};
|
|
131
|
+
return _set_prototype_of(o, p);
|
|
132
|
+
}
|
|
133
|
+
function _sliced_to_array(arr, i) {
|
|
134
|
+
return _array_with_holes(arr) || _iterable_to_array_limit(arr, i) || _unsupported_iterable_to_array(arr, i) || _non_iterable_rest();
|
|
135
|
+
}
|
|
136
|
+
function _super_prop_base(object, property) {
|
|
137
|
+
while(!Object.prototype.hasOwnProperty.call(object, property)){
|
|
138
|
+
object = _get_prototype_of(object);
|
|
139
|
+
if (object === null) break;
|
|
140
|
+
}
|
|
141
|
+
return object;
|
|
142
|
+
}
|
|
143
|
+
function _type_of(obj) {
|
|
144
|
+
"@swc/helpers - typeof";
|
|
145
|
+
return obj && typeof Symbol !== "undefined" && obj.constructor === Symbol ? "symbol" : typeof obj;
|
|
146
|
+
}
|
|
147
|
+
function _unsupported_iterable_to_array(o, minLen) {
|
|
148
|
+
if (!o) return;
|
|
149
|
+
if (typeof o === "string") return _array_like_to_array(o, minLen);
|
|
150
|
+
var n = Object.prototype.toString.call(o).slice(8, -1);
|
|
151
|
+
if (n === "Object" && o.constructor) n = o.constructor.name;
|
|
152
|
+
if (n === "Map" || n === "Set") return Array.from(n);
|
|
153
|
+
if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _array_like_to_array(o, minLen);
|
|
154
|
+
}
|
|
155
|
+
function _is_native_reflect_construct() {
|
|
156
|
+
try {
|
|
157
|
+
var result = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function() {}));
|
|
158
|
+
} catch (_) {}
|
|
159
|
+
return (_is_native_reflect_construct = function() {
|
|
160
|
+
return !!result;
|
|
161
|
+
})();
|
|
162
|
+
}
|
|
163
|
+
import { deviation, extent, max, mean, merge, min, range, sum } from "d3-array";
|
|
164
|
+
import { nest } from "d3-collection";
|
|
165
|
+
import * as scales from "d3-scale";
|
|
166
|
+
import * as d3Shape from "d3-shape";
|
|
167
|
+
import { colorAssign, colorContrast, colorDefaults, colorLegible } from "@d3plus/color";
|
|
168
|
+
import { merge as d3plusMerge, unique } from "@d3plus/data";
|
|
169
|
+
import { assign, date, elem, rtl, textWidth } from "@d3plus/dom";
|
|
170
|
+
import { largestRect } from "@d3plus/math";
|
|
171
|
+
import { formatAbbreviate } from "@d3plus/format";
|
|
172
|
+
import { AxisBottom, AxisLeft, AxisRight, AxisTop, TextBox } from "../components/index.js";
|
|
173
|
+
import * as shapes from "../shapes/index.js";
|
|
174
|
+
import { accessor, configPrep, constant } from "../utils/index.js";
|
|
175
|
+
var testLineShape = new shapes.Line();
|
|
176
|
+
var testTextBox = new TextBox();
|
|
177
|
+
import Viz from "./Viz.js";
|
|
178
|
+
import { default as discreteBuffer } from "./plotBuffers/discreteBuffer.js";
|
|
179
|
+
import { default as BarBuffer } from "./plotBuffers/Bar.js";
|
|
180
|
+
import { default as BoxBuffer } from "./plotBuffers/Box.js";
|
|
181
|
+
import { default as CircleBuffer } from "./plotBuffers/Circle.js";
|
|
182
|
+
import { default as LineBuffer } from "./plotBuffers/Line.js";
|
|
183
|
+
import { default as RectBuffer } from "./plotBuffers/Rect.js";
|
|
184
|
+
var defaultBuffers = {
|
|
185
|
+
Bar: BarBuffer,
|
|
186
|
+
Box: BoxBuffer,
|
|
187
|
+
Circle: CircleBuffer,
|
|
188
|
+
Line: LineBuffer,
|
|
189
|
+
Rect: RectBuffer
|
|
190
|
+
};
|
|
191
|
+
/**
|
|
192
|
+
@desc Logic for determining default sizes of shapes using the sizeScaleD3 internal function.
|
|
193
|
+
@private
|
|
194
|
+
*/ function defaultSize(d) {
|
|
195
|
+
return this._sizeScaleD3(this._size ? this._size(d) : null);
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
@desc Logic for determining stackOrder ascending using groups.
|
|
199
|
+
@private
|
|
200
|
+
*/ function stackOrderAscending(series) {
|
|
201
|
+
var sums = series.map(stackSum);
|
|
202
|
+
var keys = series.map(function(d) {
|
|
203
|
+
return d.key.split("_")[0];
|
|
204
|
+
});
|
|
205
|
+
return d3Shape.stackOrderNone(series).sort(function(a, b) {
|
|
206
|
+
return keys[b].localeCompare(keys[a]) || sums[a] - sums[b];
|
|
207
|
+
});
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
@desc Logic for determining stackOrder descending using groups.
|
|
211
|
+
@private
|
|
212
|
+
*/ function stackOrderDescending(series) {
|
|
213
|
+
return stackOrderAscending(series).reverse();
|
|
214
|
+
}
|
|
215
|
+
/**
|
|
216
|
+
@desc Logic for determining default sum of shapes using the stackSum function used in d3Shape.
|
|
217
|
+
@private
|
|
218
|
+
*/ function stackSum(series) {
|
|
219
|
+
var i = -1, s = 0, v;
|
|
220
|
+
var n = series.length;
|
|
221
|
+
while(++i < n)if (v = +series[i][1]) s += v;
|
|
222
|
+
return s;
|
|
223
|
+
}
|
|
224
|
+
/**
|
|
225
|
+
@desc Logic for determining default sum of shapes using the stackSum function used in d3Shape.
|
|
226
|
+
@private
|
|
227
|
+
*/ function stackOffsetDiverging(series, order) {
|
|
228
|
+
var n;
|
|
229
|
+
if (!((n = series.length) > 0)) return;
|
|
230
|
+
var d, dy, i, yn, yp;
|
|
231
|
+
var m = series[order[0]].length;
|
|
232
|
+
for(var j = 0; j < m; ++j){
|
|
233
|
+
for(yp = yn = 0, i = 0; i < n; ++i){
|
|
234
|
+
if ((dy = (d = series[order[i]][j])[1] - d[0]) >= 0) {
|
|
235
|
+
d[0] = yp, d[1] = yp += dy;
|
|
236
|
+
} else if (dy < 0) {
|
|
237
|
+
d[1] = yn, d[0] = yn += dy;
|
|
238
|
+
} else {
|
|
239
|
+
d[0] = yp;
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
/**
|
|
245
|
+
* Determines if a Bar label should be placed outside of the Bar.
|
|
246
|
+
* @param {@} d
|
|
247
|
+
* @param {*} i
|
|
248
|
+
* @private
|
|
249
|
+
*/ function outside(d, i) {
|
|
250
|
+
// Force all Stacked Bars to use "inside" labels.
|
|
251
|
+
if (this._stacked) return false;
|
|
252
|
+
// Detect user "outside" or "inside" override.
|
|
253
|
+
var labelPosition = this._labelPosition(d, i);
|
|
254
|
+
if (labelPosition === "outside") return true;
|
|
255
|
+
else if (labelPosition === "inside") return false;
|
|
256
|
+
// Run "auto" logic based on available space.
|
|
257
|
+
var other = this._discrete.charAt(0) === "x" ? "y" : "x";
|
|
258
|
+
var nonDiscrete = this._discrete.replace(this._discrete.charAt(0), other);
|
|
259
|
+
var range = this["_".concat(nonDiscrete, "Axis")]._d3Scale.range();
|
|
260
|
+
var value = this["_".concat(nonDiscrete)](d, i);
|
|
261
|
+
var negative = value < 0;
|
|
262
|
+
var zero = this["_".concat(nonDiscrete, "Axis")]._getPosition(0);
|
|
263
|
+
var space = nonDiscrete === "y" ? negative ? range[1] - zero : zero - range[0] : negative ? zero - range[0] : range[1] - zero;
|
|
264
|
+
var pos = this["_".concat(nonDiscrete, "Axis")]._getPosition(value);
|
|
265
|
+
var size = Math.abs(negative ? zero - pos : pos - zero);
|
|
266
|
+
return size < space / 2;
|
|
267
|
+
}
|
|
268
|
+
var Plot = /*#__PURE__*/ function(Viz) {
|
|
269
|
+
"use strict";
|
|
270
|
+
_inherits(Plot, Viz);
|
|
271
|
+
function Plot() {
|
|
272
|
+
_class_call_check(this, Plot);
|
|
273
|
+
var _this;
|
|
274
|
+
_this = _call_super(this, Plot);
|
|
275
|
+
_this._axisPersist = false;
|
|
276
|
+
_this._annotations = [];
|
|
277
|
+
_this._backgroundConfig = {
|
|
278
|
+
duration: 0,
|
|
279
|
+
fill: "transparent"
|
|
280
|
+
};
|
|
281
|
+
_this._barPadding = 0;
|
|
282
|
+
_this._buffer = assign({}, defaultBuffers, {
|
|
283
|
+
Bar: false,
|
|
284
|
+
Line: false
|
|
285
|
+
});
|
|
286
|
+
_this._confidenceConfig = {
|
|
287
|
+
fill: function(d, i) {
|
|
288
|
+
var c = typeof _this._shapeConfig.Line.stroke === "function" ? _this._shapeConfig.Line.stroke(d, i) : _this._shapeConfig.Line.stroke;
|
|
289
|
+
return c;
|
|
290
|
+
},
|
|
291
|
+
fillOpacity: constant(0.5)
|
|
292
|
+
};
|
|
293
|
+
_this._discreteCutoff = 100;
|
|
294
|
+
_this._groupPadding = 5;
|
|
295
|
+
_this._labelConnectorConfig = {
|
|
296
|
+
strokeDasharray: "1 1"
|
|
297
|
+
};
|
|
298
|
+
_this._labelPosition = constant("auto");
|
|
299
|
+
_this._lineMarkerConfig = {
|
|
300
|
+
fill: function(d, i) {
|
|
301
|
+
return colorAssign(_this._id(d, i));
|
|
302
|
+
},
|
|
303
|
+
r: constant(3)
|
|
304
|
+
};
|
|
305
|
+
_this._lineMarkers = false;
|
|
306
|
+
_this._previousAnnotations = {
|
|
307
|
+
back: [],
|
|
308
|
+
front: []
|
|
309
|
+
};
|
|
310
|
+
_this._previousShapes = [];
|
|
311
|
+
_this._shape = constant("Circle");
|
|
312
|
+
_this._shapeConfig = assign(_this._shapeConfig, {
|
|
313
|
+
Area: {
|
|
314
|
+
label: function(d, i) {
|
|
315
|
+
return _this._stacked ? _this._drawLabel(d, i) : false;
|
|
316
|
+
},
|
|
317
|
+
labelBounds: function(d, i, aes) {
|
|
318
|
+
var r = largestRect(aes.points, {
|
|
319
|
+
angle: range(-20, 20, 5)
|
|
320
|
+
});
|
|
321
|
+
if (!r || r.height < 20 || r.width < 50) r = largestRect(aes.points, {
|
|
322
|
+
angle: range(-80, 80, 5)
|
|
323
|
+
});
|
|
324
|
+
if (!r) return null;
|
|
325
|
+
var x = min(aes.points, function(d) {
|
|
326
|
+
return d[0];
|
|
327
|
+
});
|
|
328
|
+
var y = max(aes.points.filter(function(d) {
|
|
329
|
+
return d[0] === x;
|
|
330
|
+
}), function(d) {
|
|
331
|
+
return d[1];
|
|
332
|
+
});
|
|
333
|
+
return {
|
|
334
|
+
angle: r.angle,
|
|
335
|
+
width: r.width,
|
|
336
|
+
height: r.height,
|
|
337
|
+
x: r.cx - r.width / 2 - x,
|
|
338
|
+
y: r.cy - r.height / 2 - y
|
|
339
|
+
};
|
|
340
|
+
},
|
|
341
|
+
labelConfig: {
|
|
342
|
+
fontMin: 6,
|
|
343
|
+
fontResize: true,
|
|
344
|
+
padding: 10
|
|
345
|
+
}
|
|
346
|
+
},
|
|
347
|
+
ariaLabel: function(d, i) {
|
|
348
|
+
var ariaLabelStr = "";
|
|
349
|
+
if (d.nested) ariaLabelStr = "".concat(_this._drawLabel(d.data, d.i));
|
|
350
|
+
else {
|
|
351
|
+
ariaLabelStr = "".concat(_this._drawLabel(d, i));
|
|
352
|
+
if (_this._x(d, i) !== undefined) ariaLabelStr += ", x: ".concat(_this._x(d, i));
|
|
353
|
+
if (_this._y(d, i) !== undefined) ariaLabelStr += ", y: ".concat(_this._y(d, i));
|
|
354
|
+
if (_this._x2(d, i) !== undefined) ariaLabelStr += ", x2: ".concat(_this._x2(d, i));
|
|
355
|
+
if (_this._y2(d, i) !== undefined) ariaLabelStr += ", y2: ".concat(_this._y2(d, i));
|
|
356
|
+
}
|
|
357
|
+
return "".concat(ariaLabelStr, ".");
|
|
358
|
+
},
|
|
359
|
+
Bar: {
|
|
360
|
+
labelBounds: function labelBounds(d, i, s) {
|
|
361
|
+
var padding = 1;
|
|
362
|
+
var width = this._discrete === "y" ? "width" : "height";
|
|
363
|
+
var height = this._discrete === "y" ? "height" : "width";
|
|
364
|
+
var other = this._discrete.charAt(0) === "x" ? "y" : "x";
|
|
365
|
+
var invert = other === "y";
|
|
366
|
+
var nonDiscrete = this._discrete.replace(this._discrete.charAt(0), other);
|
|
367
|
+
var range = this["_".concat(nonDiscrete, "Axis")]._d3Scale.range();
|
|
368
|
+
var space = Math.abs(range[1] - range[0]);
|
|
369
|
+
var negative = this["_".concat(nonDiscrete)](d, i) < 0;
|
|
370
|
+
if (outside.bind(this)(d, i)) {
|
|
371
|
+
var _obj;
|
|
372
|
+
return _obj = {}, _define_property(_obj, width, space - s[width]), _define_property(_obj, height, s[height]), _define_property(_obj, "x", invert ? -s.width / 2 : negative ? -space : s.width + padding), _define_property(_obj, "y", invert ? negative ? s.height + padding : -space : -s.height / 2 + 1), _obj;
|
|
373
|
+
}
|
|
374
|
+
var _obj1;
|
|
375
|
+
return _obj1 = {}, _define_property(_obj1, width, s[width]), _define_property(_obj1, height, s[height]), _define_property(_obj1, "x", invert ? -s.width / 2 : negative ? this._stacked ? padding - s.width : padding - s.width : -padding), _define_property(_obj1, "y", invert ? negative ? this._stacked ? padding : padding : -s.height + padding : -s.height / 2 + padding), _obj1;
|
|
376
|
+
},
|
|
377
|
+
labelConfig: {
|
|
378
|
+
fontMax: 16,
|
|
379
|
+
fontMin: 6,
|
|
380
|
+
fontResize: true,
|
|
381
|
+
fontColor: function fontColor(d, i) {
|
|
382
|
+
return outside.bind(this)(d, i) ? this._backgroundConfig.fill === "transparent" ? colorDefaults.dark : colorContrast(this._backgroundConfig.fill) : colorContrast(typeof this._shapeConfig.fill === "function" ? this._shapeConfig.fill(d, i) : this._shapeConfig.fill);
|
|
383
|
+
},
|
|
384
|
+
fontStroke: function fontStroke(d, i) {
|
|
385
|
+
return outside.bind(this)(d, i) ? this._backgroundConfig.fill === "transparent" ? colorDefaults.dark : colorContrast(this._backgroundConfig.fill) : "transparent";
|
|
386
|
+
},
|
|
387
|
+
fontStrokeWidth: function fontStrokeWidth(d, i) {
|
|
388
|
+
return outside.bind(this)(d, i) ? 0.1 : 0;
|
|
389
|
+
},
|
|
390
|
+
padding: 3,
|
|
391
|
+
textAnchor: function textAnchor(d, i) {
|
|
392
|
+
var other = this._discrete.charAt(0) === "x" ? "y" : "x";
|
|
393
|
+
var invert = other === "y";
|
|
394
|
+
var nonDiscrete = this._discrete.replace(this._discrete.charAt(0), other);
|
|
395
|
+
var negative = this["_".concat(nonDiscrete)](d, i) < 0;
|
|
396
|
+
var anchor = invert ? "middle" : outside.bind(this)(d, i) ? negative ? "end" : "start" : negative ? "start" : "end";
|
|
397
|
+
return rtl() ? anchor === "start" ? "end" : anchor === "end" ? "start" : anchor : anchor;
|
|
398
|
+
},
|
|
399
|
+
verticalAlign: function verticalAlign(d, i) {
|
|
400
|
+
var other = this._discrete.charAt(0) === "x" ? "y" : "x";
|
|
401
|
+
var invert = other === "y";
|
|
402
|
+
var nonDiscrete = this._discrete.replace(this._discrete.charAt(0), other);
|
|
403
|
+
var negative = this["_".concat(nonDiscrete)](d, i) < 0;
|
|
404
|
+
return invert ? outside.bind(this)(d, i) ? negative ? "top" : "bottom" : negative ? "bottom" : "top" : "middle";
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
},
|
|
408
|
+
Circle: {
|
|
409
|
+
r: defaultSize.bind(_this)
|
|
410
|
+
},
|
|
411
|
+
Line: {
|
|
412
|
+
curve: function() {
|
|
413
|
+
return _this._discrete ? "monotone".concat(_this._discrete.charAt(0).toUpperCase()) : "linear";
|
|
414
|
+
},
|
|
415
|
+
fill: constant("none"),
|
|
416
|
+
labelConfig: {
|
|
417
|
+
fontColor: function(d, i) {
|
|
418
|
+
var c = typeof _this._shapeConfig.Line.stroke === "function" ? _this._shapeConfig.Line.stroke(d, i) : _this._shapeConfig.Line.stroke;
|
|
419
|
+
return colorLegible(c);
|
|
420
|
+
},
|
|
421
|
+
fontResize: false,
|
|
422
|
+
padding: 5,
|
|
423
|
+
textAnchor: "start",
|
|
424
|
+
verticalAlign: "middle"
|
|
425
|
+
},
|
|
426
|
+
strokeWidth: constant(2)
|
|
427
|
+
},
|
|
428
|
+
Rect: {
|
|
429
|
+
height: function(d) {
|
|
430
|
+
return defaultSize.bind(_this)(d) * 2;
|
|
431
|
+
},
|
|
432
|
+
width: function(d) {
|
|
433
|
+
return defaultSize.bind(_this)(d) * 2;
|
|
434
|
+
}
|
|
435
|
+
}
|
|
436
|
+
});
|
|
437
|
+
_this._shapeOrder = [
|
|
438
|
+
"Area",
|
|
439
|
+
"Path",
|
|
440
|
+
"Bar",
|
|
441
|
+
"Box",
|
|
442
|
+
"Line",
|
|
443
|
+
"Rect",
|
|
444
|
+
"Circle"
|
|
445
|
+
];
|
|
446
|
+
_this._shapeSort = function(a, b) {
|
|
447
|
+
return _this._shapeOrder.indexOf(a) - _this._shapeOrder.indexOf(b);
|
|
448
|
+
};
|
|
449
|
+
_this._sizeMax = 20;
|
|
450
|
+
_this._sizeMin = 5;
|
|
451
|
+
_this._sizeScale = "sqrt";
|
|
452
|
+
_this._stackOffset = stackOffsetDiverging;
|
|
453
|
+
_this._stackOrder = stackOrderDescending;
|
|
454
|
+
_this._timelineConfig = assign(_this._timelineConfig, {
|
|
455
|
+
brushing: true,
|
|
456
|
+
brushMin: function() {
|
|
457
|
+
return _this._xTime || _this._yTime || _this._x2Time || _this._y2Time ? 2 : 1;
|
|
458
|
+
}
|
|
459
|
+
});
|
|
460
|
+
_this._x = accessor("x");
|
|
461
|
+
_this._xAxis = new AxisBottom().align("end");
|
|
462
|
+
_this._xTest = new AxisBottom().align("end").gridSize(0);
|
|
463
|
+
_this._xConfig = {
|
|
464
|
+
gridConfig: {
|
|
465
|
+
stroke: function(d) {
|
|
466
|
+
if (_this._discrete && _this._discrete.charAt(0) === "x") return "transparent";
|
|
467
|
+
var range = _this._xAxis.range();
|
|
468
|
+
// hides left-most x gridline so it doesn't overlap with the y axis
|
|
469
|
+
return range[0] === _this._xAxis._getPosition.bind(_this._xAxis)(d.id) ? "transparent" : "#eee";
|
|
470
|
+
}
|
|
471
|
+
}
|
|
472
|
+
};
|
|
473
|
+
_this._xCutoff = 150;
|
|
474
|
+
_this._x2 = accessor("x2");
|
|
475
|
+
_this._x2Axis = new AxisTop().align("start");
|
|
476
|
+
_this._x2Test = new AxisTop().align("start").gridSize(0);
|
|
477
|
+
_this._x2Config = {
|
|
478
|
+
padding: 0
|
|
479
|
+
};
|
|
480
|
+
_this._y = accessor("y");
|
|
481
|
+
_this._yAxis = new AxisLeft().align("start");
|
|
482
|
+
_this._yTest = new AxisLeft().align("start").gridSize(0);
|
|
483
|
+
_this._yConfig = {
|
|
484
|
+
gridConfig: {
|
|
485
|
+
stroke: function(d) {
|
|
486
|
+
if (_this._discrete && _this._discrete.charAt(0) === "y") return "transparent";
|
|
487
|
+
var range = _this._yAxis.range();
|
|
488
|
+
// hides bottom-most y gridline so it doesn't overlap with the x axis
|
|
489
|
+
return range[range.length - 1] === _this._yAxis._getPosition.bind(_this._yAxis)(d.id) ? "transparent" : "#eee";
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
};
|
|
493
|
+
_this._yCutoff = 150;
|
|
494
|
+
_this._y2 = accessor("y2");
|
|
495
|
+
_this._y2Axis = new AxisRight().align("end");
|
|
496
|
+
_this._y2Test = new AxisLeft().align("end").gridSize(0);
|
|
497
|
+
_this._y2Config = {};
|
|
498
|
+
return _this;
|
|
499
|
+
}
|
|
500
|
+
_create_class(Plot, [
|
|
501
|
+
{
|
|
502
|
+
/**
|
|
503
|
+
Extends the preDraw behavior of the abstract Viz class.
|
|
504
|
+
@private
|
|
505
|
+
*/ key: "_preDraw",
|
|
506
|
+
value: function _preDraw() {
|
|
507
|
+
var _this = this;
|
|
508
|
+
// logic repeated for each axis
|
|
509
|
+
[
|
|
510
|
+
"x",
|
|
511
|
+
"y",
|
|
512
|
+
"x2",
|
|
513
|
+
"y2"
|
|
514
|
+
].forEach(function(k) {
|
|
515
|
+
// if user has supplied a String key as the main method value
|
|
516
|
+
if (_this["_".concat(k, "Key")]) {
|
|
517
|
+
var str = _this["_".concat(k, "Key")];
|
|
518
|
+
// if axis is discrete and numerical, do not sum values
|
|
519
|
+
if (!_this._aggs[str] && _this._discrete === k) {
|
|
520
|
+
_this._aggs[str] = function(a, c) {
|
|
521
|
+
var v = Array.from(new Set(a.map(c)));
|
|
522
|
+
return v.length === 1 ? v[0] : v;
|
|
523
|
+
};
|
|
524
|
+
}
|
|
525
|
+
// set axis title if not discrete
|
|
526
|
+
if (str !== k && _this["_".concat(k, "Title")] === _this["_".concat(k, "Config")].title && _this._discrete !== k) {
|
|
527
|
+
_this["_".concat(k, "Title")] = str;
|
|
528
|
+
_this["_".concat(k, "Config")].title = str;
|
|
529
|
+
}
|
|
530
|
+
}
|
|
531
|
+
});
|
|
532
|
+
_get(_get_prototype_of(Plot.prototype), "_preDraw", this).call(this);
|
|
533
|
+
}
|
|
534
|
+
},
|
|
535
|
+
{
|
|
536
|
+
/**
|
|
537
|
+
Extends the draw behavior of the abstract Viz class.
|
|
538
|
+
@private
|
|
539
|
+
*/ key: "_draw",
|
|
540
|
+
value: function _draw(callback) {
|
|
541
|
+
var _this = this;
|
|
542
|
+
if (!this._filteredData.length) return this;
|
|
543
|
+
/* Determines whether or not any of the x or y axes are a "time" axis. */ var firstElemTime = this._time ? this._time(this._filteredData[0], 0) : false;
|
|
544
|
+
var x2Time = this._x2Time = firstElemTime && this._x2(this._filteredData[0], 0) === firstElemTime, xTime = this._xTime = firstElemTime && this._x(this._filteredData[0], 0) === firstElemTime, y2Time = this._y2Time = firstElemTime && this._y2(this._filteredData[0], 0) === firstElemTime, yTime = this._yTime = firstElemTime && this._y(this._filteredData[0], 0) === firstElemTime;
|
|
545
|
+
var timeAxis = xTime || x2Time || yTime || y2Time;
|
|
546
|
+
var stackGroup = function(d, i) {
|
|
547
|
+
return "".concat(!timeAxis && _this._time ? _this._time(d, i) : "time", "_").concat(_this._stacked ? "".concat(_this._groupBy.length > 1 ? _this._ids(d, i).slice(0, -1).join("_") : "group") : "".concat(_this._ids(d, i).join("_")));
|
|
548
|
+
};
|
|
549
|
+
var prepData = function(d, i) {
|
|
550
|
+
var newD = {
|
|
551
|
+
__d3plus__: true,
|
|
552
|
+
data: d,
|
|
553
|
+
group: stackGroup(d, i),
|
|
554
|
+
i: i,
|
|
555
|
+
hci: _this._confidence && _this._confidence[1] && _this._confidence[1](d, i),
|
|
556
|
+
id: _this._ids(d, i).slice(0, _this._drawDepth + 1).join("_"),
|
|
557
|
+
lci: _this._confidence && _this._confidence[0] && _this._confidence[0](d, i),
|
|
558
|
+
shape: _this._shape(d, i),
|
|
559
|
+
x: xTime ? date(_this._x(d, i)) : _this._x(d, i),
|
|
560
|
+
x2: x2Time ? date(_this._x2(d, i)) : _this._x2(d, i),
|
|
561
|
+
y: yTime ? date(_this._y(d, i)) : _this._y(d, i),
|
|
562
|
+
y2: y2Time ? date(_this._y2(d, i)) : _this._y2(d, i)
|
|
563
|
+
};
|
|
564
|
+
newD.discrete = newD.shape === "Bar" ? "".concat(newD[_this._discrete], "_").concat(newD.group) : "".concat(newD[_this._discrete]);
|
|
565
|
+
newD.id = newD.shape === "Bar" ? "".concat(newD.id, "_").concat(newD[_this._discrete]) : newD.id;
|
|
566
|
+
return newD;
|
|
567
|
+
};
|
|
568
|
+
var data = this._formattedData = this._filteredData.map(prepData);
|
|
569
|
+
var axisData = this._axisPersist ? this._data.map(prepData) : data;
|
|
570
|
+
if (this._size) {
|
|
571
|
+
var rExtent = extent(axisData, function(d) {
|
|
572
|
+
return _this._size(d.data);
|
|
573
|
+
});
|
|
574
|
+
this._sizeScaleD3 = scales["scale".concat(this._sizeScale.charAt(0).toUpperCase()).concat(this._sizeScale.slice(1))]().domain(rExtent).range([
|
|
575
|
+
rExtent[0] === rExtent[1] ? this._sizeMax : min([
|
|
576
|
+
this._sizeMax / 2,
|
|
577
|
+
this._sizeMin
|
|
578
|
+
]),
|
|
579
|
+
this._sizeMax
|
|
580
|
+
]);
|
|
581
|
+
} else {
|
|
582
|
+
this._sizeScaleD3 = function() {
|
|
583
|
+
return _this._sizeMin;
|
|
584
|
+
};
|
|
585
|
+
}
|
|
586
|
+
var x2Exists = axisData.some(function(d) {
|
|
587
|
+
return d.x2 !== undefined;
|
|
588
|
+
}), y2Exists = axisData.some(function(d) {
|
|
589
|
+
return d.y2 !== undefined;
|
|
590
|
+
});
|
|
591
|
+
var height = this._height - this._margin.top - this._margin.bottom, opp = this._discrete ? this._discrete === "x" ? "y" : "x" : undefined, opp2 = this._discrete ? this._discrete === "x" ? "y2" : "x2" : undefined, opps = [
|
|
592
|
+
opp,
|
|
593
|
+
opp2
|
|
594
|
+
].filter(function(d) {
|
|
595
|
+
return d;
|
|
596
|
+
}), parent = this._select, transition = this._transition, width = this._width - this._margin.left - this._margin.right;
|
|
597
|
+
/**
|
|
598
|
+
* @desc Returns all unique values for a given axis.
|
|
599
|
+
* @param {String} axis
|
|
600
|
+
* @returns {Array}
|
|
601
|
+
* @private
|
|
602
|
+
*/ function getAxisValues(axis) {
|
|
603
|
+
var _this = this;
|
|
604
|
+
var timeData = this["_".concat(axis, "Time")];
|
|
605
|
+
var localData = timeData ? data : axisData;
|
|
606
|
+
var filteredData = localData.filter(function(d) {
|
|
607
|
+
return ![
|
|
608
|
+
NaN,
|
|
609
|
+
undefined,
|
|
610
|
+
false
|
|
611
|
+
].includes(d[axis]);
|
|
612
|
+
});
|
|
613
|
+
if (!filteredData.length) return [];
|
|
614
|
+
var numericValue = typeof filteredData[0][axis] === "number";
|
|
615
|
+
var myData = this._discrete === axis ? nest().key(function(d) {
|
|
616
|
+
return d[axis];
|
|
617
|
+
}).rollup(function(leaves) {
|
|
618
|
+
return leaves.length === 1 ? leaves[0].data : d3plusMerge(leaves.map(function(d) {
|
|
619
|
+
return d.data;
|
|
620
|
+
}), _this._aggs);
|
|
621
|
+
}).entries(filteredData).sort(function(a, b) {
|
|
622
|
+
if (_this["_".concat(axis, "Sort")]) return _this["_".concat(axis, "Sort")](a.value, b.value);
|
|
623
|
+
var aKey = timeData || numericValue ? parseFloat(a.key, 10) : a.key;
|
|
624
|
+
var bKey = timeData || numericValue ? parseFloat(b.key, 10) : b.key;
|
|
625
|
+
return aKey - bKey;
|
|
626
|
+
}).map(function(d) {
|
|
627
|
+
return timeData ? date(d.key) : numericValue ? parseFloat(d.key, 10) : d.key;
|
|
628
|
+
}) : unique(filteredData.sort(function(a, b) {
|
|
629
|
+
return _this["_".concat(axis, "Sort")] ? _this["_".concat(axis, "Sort")](a.data, b.data) : a[axis] - b[axis];
|
|
630
|
+
}).map(function(d) {
|
|
631
|
+
return d[axis];
|
|
632
|
+
}), function(d) {
|
|
633
|
+
return "".concat(d);
|
|
634
|
+
});
|
|
635
|
+
if (this._discrete !== axis.charAt(0) && this._confidence) {
|
|
636
|
+
if (this._confidence[0]) myData = myData.concat(localData.map(function(d) {
|
|
637
|
+
return d.lci;
|
|
638
|
+
}));
|
|
639
|
+
if (this._confidence[1]) myData = myData.concat(localData.map(function(d) {
|
|
640
|
+
return d.hci;
|
|
641
|
+
}));
|
|
642
|
+
}
|
|
643
|
+
return myData;
|
|
644
|
+
}
|
|
645
|
+
var xData = getAxisValues.bind(this)("x");
|
|
646
|
+
var x2Data = getAxisValues.bind(this)("x2");
|
|
647
|
+
var yData = getAxisValues.bind(this)("y");
|
|
648
|
+
var y2Data = getAxisValues.bind(this)("y2");
|
|
649
|
+
var discreteKeys, domains, stackData, stackKeys;
|
|
650
|
+
if (this._stacked) {
|
|
651
|
+
var stackedData = axisData.filter(function(d) {
|
|
652
|
+
return [
|
|
653
|
+
"Area",
|
|
654
|
+
"Bar"
|
|
655
|
+
].includes(d.shape);
|
|
656
|
+
});
|
|
657
|
+
var groupValues = nest().key(function(d) {
|
|
658
|
+
return d.group;
|
|
659
|
+
}).entries(stackedData).reduce(function(obj, d) {
|
|
660
|
+
if (!obj[d.key]) obj[d.key] = 0;
|
|
661
|
+
obj[d.key] += sum(d.values, function(dd) {
|
|
662
|
+
return dd[opp];
|
|
663
|
+
});
|
|
664
|
+
return obj;
|
|
665
|
+
}, {});
|
|
666
|
+
axisData.sort(function(a, b) {
|
|
667
|
+
if (_this["_".concat(_this._discrete, "Sort")]) return _this["_".concat(_this._discrete, "Sort")](a.data, b.data);
|
|
668
|
+
var a1 = a[_this._discrete], b1 = b[_this._discrete];
|
|
669
|
+
if (a1 - b1 !== 0) return a1 - b1;
|
|
670
|
+
if (a.group !== b.group) return groupValues[b.group] - groupValues[a.group];
|
|
671
|
+
return b[opp] - a[opp];
|
|
672
|
+
});
|
|
673
|
+
discreteKeys = Array.from(new Set(axisData.map(function(d) {
|
|
674
|
+
return d.discrete;
|
|
675
|
+
})));
|
|
676
|
+
stackKeys = Array.from(new Set(axisData.map(function(d) {
|
|
677
|
+
return d.id;
|
|
678
|
+
})));
|
|
679
|
+
stackData = nest().key(function(d) {
|
|
680
|
+
return d.discrete;
|
|
681
|
+
}).entries(axisData).map(function(d) {
|
|
682
|
+
return d.values;
|
|
683
|
+
});
|
|
684
|
+
stackData.forEach(function(g) {
|
|
685
|
+
var ids = Array.from(new Set(g.map(function(d) {
|
|
686
|
+
return d.id;
|
|
687
|
+
})));
|
|
688
|
+
if (ids.length < stackKeys.length) {
|
|
689
|
+
stackKeys.forEach(function(k) {
|
|
690
|
+
if (!ids.includes(k)) {
|
|
691
|
+
var d = axisData.filter(function(d) {
|
|
692
|
+
return d.id === k;
|
|
693
|
+
})[0];
|
|
694
|
+
if (d.shape === "Area") {
|
|
695
|
+
var group = stackGroup(d.data, d.i);
|
|
696
|
+
var _obj;
|
|
697
|
+
var fillerPoint = (_obj = {
|
|
698
|
+
__d3plus__: true,
|
|
699
|
+
data: d.data,
|
|
700
|
+
discrete: d.shape === "Bar" ? "".concat(g[0][_this._discrete], "_").concat(group) : "".concat(g[0][_this._discrete]),
|
|
701
|
+
group: group,
|
|
702
|
+
id: d.id,
|
|
703
|
+
ids: k,
|
|
704
|
+
shape: d.shape
|
|
705
|
+
}, _define_property(_obj, _this._discrete, g[0][_this._discrete]), _define_property(_obj, opp, 0), _obj);
|
|
706
|
+
data.push(fillerPoint);
|
|
707
|
+
}
|
|
708
|
+
}
|
|
709
|
+
});
|
|
710
|
+
}
|
|
711
|
+
});
|
|
712
|
+
if (this["_".concat(this._discrete, "Sort")]) {
|
|
713
|
+
data.sort(function(a, b) {
|
|
714
|
+
return _this["_".concat(_this._discrete, "Sort")](a.data, b.data);
|
|
715
|
+
});
|
|
716
|
+
} else {
|
|
717
|
+
data.sort(function(a, b) {
|
|
718
|
+
return a[_this._discrete] - b[_this._discrete];
|
|
719
|
+
});
|
|
720
|
+
}
|
|
721
|
+
var order = this._stackOrder;
|
|
722
|
+
if (_instanceof(order, Array)) stackKeys.sort(function(a, b) {
|
|
723
|
+
return order.indexOf(a) - order.indexOf(b);
|
|
724
|
+
});
|
|
725
|
+
else if (order === d3Shape.stackOrderNone) stackKeys.sort(function(a, b) {
|
|
726
|
+
return a.localeCompare(b);
|
|
727
|
+
});
|
|
728
|
+
stackData = d3Shape.stack().keys(stackKeys).offset(this._stackOffset).order(_instanceof(order, Array) ? d3Shape.stackOrderNone : order).value(function(group, key) {
|
|
729
|
+
var d = group.filter(function(g) {
|
|
730
|
+
return g.id === key;
|
|
731
|
+
});
|
|
732
|
+
return d.length ? d[0][opp] : 0;
|
|
733
|
+
})(stackData);
|
|
734
|
+
var discreteData = this._discrete === "x" ? xData : yData;
|
|
735
|
+
var _obj;
|
|
736
|
+
domains = (_obj = {}, _define_property(_obj, this._discrete, this["_".concat(this._discrete, "Time")] ? extent(discreteData) : discreteData), _define_property(_obj, opp, [
|
|
737
|
+
min(stackData.map(function(g) {
|
|
738
|
+
return min(g.map(function(p) {
|
|
739
|
+
return p[0];
|
|
740
|
+
}));
|
|
741
|
+
})),
|
|
742
|
+
max(stackData.map(function(g) {
|
|
743
|
+
return max(g.map(function(p) {
|
|
744
|
+
return p[1];
|
|
745
|
+
}));
|
|
746
|
+
}))
|
|
747
|
+
]), _obj);
|
|
748
|
+
} else {
|
|
749
|
+
var discrete = this._discrete || "x";
|
|
750
|
+
if (this["_".concat(this._discrete, "Sort")]) {
|
|
751
|
+
axisData.sort(function(a, b) {
|
|
752
|
+
return _this["_".concat(_this._discrete, "Sort")](a.data, b.data);
|
|
753
|
+
});
|
|
754
|
+
} else {
|
|
755
|
+
axisData.sort(function(a, b) {
|
|
756
|
+
return a[discrete] - b[discrete];
|
|
757
|
+
});
|
|
758
|
+
}
|
|
759
|
+
domains = {
|
|
760
|
+
x: !xTime && this._discrete === "x" || this._xSort ? xData : extent(xData),
|
|
761
|
+
x2: !x2Time && this._discrete === "x" || this._x2Sort ? x2Data : extent(x2Data),
|
|
762
|
+
y: !yTime && this._discrete === "y" || this._ySort ? yData : extent(yData),
|
|
763
|
+
y2: !y2Time && this._discrete === "y" || this._y2Sort ? y2Data : extent(y2Data)
|
|
764
|
+
};
|
|
765
|
+
}
|
|
766
|
+
/**
|
|
767
|
+
* Determins default scale type and domain for a given axis.
|
|
768
|
+
* @param {String} axis
|
|
769
|
+
* @private
|
|
770
|
+
*/ function domainScaleSetup(axis) {
|
|
771
|
+
var scale = this["_".concat(axis, "Time")] ? "Time" : this._discrete === axis || this["_".concat(axis, "Sort")] ? "Point" : "Linear";
|
|
772
|
+
var domain = this["_".concat(axis, "Domain")] ? this["_".concat(axis, "Domain")].slice() : domains[axis], domain2 = this["_".concat(axis, "2Domain")] ? this["_".concat(axis, "2Domain")].slice() : domains["".concat(axis, "2")];
|
|
773
|
+
if (scale !== "Point") {
|
|
774
|
+
if (domain && domain[0] === void 0) domain[0] = domains[axis][0];
|
|
775
|
+
if (domain && domain[1] === void 0) domain[1] = domains[axis][1];
|
|
776
|
+
if (domain2 && domain2[0] === void 0) domain2[0] = domains["".concat(axis, "2")][0];
|
|
777
|
+
if (domain2 && domain2[1] === void 0) domain2[1] = domains["".concat(axis, "2")][1];
|
|
778
|
+
}
|
|
779
|
+
return [
|
|
780
|
+
domain,
|
|
781
|
+
scale,
|
|
782
|
+
domain2,
|
|
783
|
+
scale
|
|
784
|
+
];
|
|
785
|
+
}
|
|
786
|
+
var _domainScaleSetup_bind = _sliced_to_array(domainScaleSetup.bind(this)("x"), 4), xAutoDomain = _domainScaleSetup_bind[0], xScale = _domainScaleSetup_bind[1], x2AutoDomain = _domainScaleSetup_bind[2], x2Scale = _domainScaleSetup_bind[3];
|
|
787
|
+
var _domainScaleSetup_bind1 = _sliced_to_array(domainScaleSetup.bind(this)("y"), 4), yAutoDomain = _domainScaleSetup_bind1[0], yScale = _domainScaleSetup_bind1[1], y2AutoDomain = _domainScaleSetup_bind1[2], y2Scale = _domainScaleSetup_bind1[3];
|
|
788
|
+
var autoScale = function(axis, fallback) {
|
|
789
|
+
var userScale = _this["_".concat(axis, "Config")].scale;
|
|
790
|
+
if (userScale === "auto") {
|
|
791
|
+
if (_this._discrete === axis) return fallback;
|
|
792
|
+
var values = axisData.map(function(d) {
|
|
793
|
+
return d[axis];
|
|
794
|
+
});
|
|
795
|
+
return deviation(values) / mean(values) > 3 ? "log" : "linear";
|
|
796
|
+
}
|
|
797
|
+
return userScale || fallback;
|
|
798
|
+
};
|
|
799
|
+
var yConfigScale = this._yConfigScale = autoScale("y", yScale).toLowerCase();
|
|
800
|
+
var y2ConfigScale = this._y2ConfigScale = autoScale("y2", y2Scale).toLowerCase();
|
|
801
|
+
var xConfigScale = this._xConfigScale = autoScale("x", xScale).toLowerCase();
|
|
802
|
+
var x2ConfigScale = this._x2ConfigScale = autoScale("x2", x2Scale).toLowerCase();
|
|
803
|
+
domains = {
|
|
804
|
+
x: xAutoDomain,
|
|
805
|
+
x2: x2AutoDomain || xAutoDomain,
|
|
806
|
+
y: yAutoDomain,
|
|
807
|
+
y2: y2AutoDomain || yAutoDomain
|
|
808
|
+
};
|
|
809
|
+
Object.keys(domains).forEach(function(axis) {
|
|
810
|
+
if (_this["_".concat(axis, "ConfigScale")] === "log" && domains[axis].includes(0)) {
|
|
811
|
+
if (min(domains[axis]) < 0) domains[axis][1] = max(data.map(function(d) {
|
|
812
|
+
return d[axis];
|
|
813
|
+
}).filter(function(d) {
|
|
814
|
+
return ![
|
|
815
|
+
NaN,
|
|
816
|
+
undefined,
|
|
817
|
+
false
|
|
818
|
+
].includes(d);
|
|
819
|
+
}));
|
|
820
|
+
else domains[axis][0] = min(axisData.map(function(d) {
|
|
821
|
+
return d[axis];
|
|
822
|
+
}).filter(function(d) {
|
|
823
|
+
return ![
|
|
824
|
+
NaN,
|
|
825
|
+
undefined,
|
|
826
|
+
false
|
|
827
|
+
].includes(d);
|
|
828
|
+
}));
|
|
829
|
+
}
|
|
830
|
+
});
|
|
831
|
+
opps.forEach(function(opp) {
|
|
832
|
+
if (_this["_".concat(opp, "Config")].domain) {
|
|
833
|
+
var d = _this["_".concat(opp, "Config")].domain;
|
|
834
|
+
if (_this._discrete === "x") d.reverse();
|
|
835
|
+
domains[opp] = d;
|
|
836
|
+
} else if (opp && _this._baseline !== void 0) {
|
|
837
|
+
var b = _this._baseline;
|
|
838
|
+
if (domains[opp] && domains[opp][0] > b) domains[opp][0] = b;
|
|
839
|
+
else if (domains[opp] && domains[opp][1] < b) domains[opp][1] = b;
|
|
840
|
+
}
|
|
841
|
+
});
|
|
842
|
+
var x = scales["scale".concat(xScale)]().domain(domains.x).range(range(0, width + 1, width / (domains.x.length - 1))), x2 = scales["scale".concat(x2Scale)]().domain(domains.x2).range(range(0, width + 1, width / (domains.x2.length - 1))), y = scales["scale".concat(yScale)]().domain(domains.y.reverse()).range(range(0, height + 1, height / (domains.y.length - 1))), y2 = scales["scale".concat(y2Scale)]().domain(domains.y2.reverse()).range(range(0, height + 1, height / (domains.y2.length - 1)));
|
|
843
|
+
var shapeData = nest().key(function(d) {
|
|
844
|
+
return d.shape;
|
|
845
|
+
}).entries(data).sort(function(a, b) {
|
|
846
|
+
return _this._shapeSort(a.key, b.key);
|
|
847
|
+
});
|
|
848
|
+
var oppScale = this._discrete === "x" ? yScale : xScale;
|
|
849
|
+
if (oppScale !== "Point") {
|
|
850
|
+
var allShapeData = nest().key(function(d) {
|
|
851
|
+
return d.shape;
|
|
852
|
+
}).entries(axisData);
|
|
853
|
+
allShapeData.forEach(function(d) {
|
|
854
|
+
if ([
|
|
855
|
+
"Bar",
|
|
856
|
+
"Box"
|
|
857
|
+
].includes(d.key)) {
|
|
858
|
+
discreteBuffer(_this._discrete === "x" ? x : y, data, _this._discrete);
|
|
859
|
+
}
|
|
860
|
+
if (_this._buffer[d.key]) {
|
|
861
|
+
var res = _this._buffer[d.key].bind(_this)({
|
|
862
|
+
data: d.values,
|
|
863
|
+
x: x,
|
|
864
|
+
y: y,
|
|
865
|
+
yScale: yConfigScale,
|
|
866
|
+
xScale: xConfigScale,
|
|
867
|
+
config: _this._shapeConfig[d.key]
|
|
868
|
+
});
|
|
869
|
+
x = res[0];
|
|
870
|
+
y = res[1];
|
|
871
|
+
var res2 = _this._buffer[d.key].bind(_this)({
|
|
872
|
+
data: d.values,
|
|
873
|
+
x: x2,
|
|
874
|
+
y: y2,
|
|
875
|
+
yScale: y2ConfigScale,
|
|
876
|
+
xScale: x2ConfigScale,
|
|
877
|
+
x2: true,
|
|
878
|
+
y2: true,
|
|
879
|
+
config: _this._shapeConfig[d.key]
|
|
880
|
+
});
|
|
881
|
+
x2 = res2[0];
|
|
882
|
+
y2 = res2[1];
|
|
883
|
+
}
|
|
884
|
+
});
|
|
885
|
+
}
|
|
886
|
+
var xDomain = x.domain();
|
|
887
|
+
var x2Domain = x2.domain();
|
|
888
|
+
var yDomain = y.domain();
|
|
889
|
+
var y2Domain = y2.domain();
|
|
890
|
+
var defaultConfig = {
|
|
891
|
+
barConfig: {
|
|
892
|
+
"stroke-width": 0
|
|
893
|
+
},
|
|
894
|
+
gridSize: 0,
|
|
895
|
+
labels: [],
|
|
896
|
+
title: false,
|
|
897
|
+
tickSize: 0
|
|
898
|
+
};
|
|
899
|
+
var defaultX2Config = x2Exists ? {
|
|
900
|
+
data: x2Data
|
|
901
|
+
} : defaultConfig;
|
|
902
|
+
var defaultY2Config = y2Exists ? {
|
|
903
|
+
data: y2Data
|
|
904
|
+
} : defaultConfig;
|
|
905
|
+
var showX = this._discrete === "x" && this._width > this._discreteCutoff || this._width > this._xCutoff;
|
|
906
|
+
var showY = this._discrete === "y" && this._height > this._discreteCutoff || this._height > this._yCutoff;
|
|
907
|
+
var yC = {
|
|
908
|
+
data: yData,
|
|
909
|
+
locale: this._locale,
|
|
910
|
+
rounding: this._yDomain ? "none" : "outside",
|
|
911
|
+
scalePadding: y.padding ? y.padding() : 0
|
|
912
|
+
};
|
|
913
|
+
if (!showX) {
|
|
914
|
+
yC.barConfig = {
|
|
915
|
+
stroke: "transparent"
|
|
916
|
+
};
|
|
917
|
+
yC.tickSize = 0;
|
|
918
|
+
yC.shapeConfig = {
|
|
919
|
+
labelBounds: function(d, i) {
|
|
920
|
+
var _d_labelBounds = d.labelBounds, width = _d_labelBounds.width, y = _d_labelBounds.y;
|
|
921
|
+
var height = _this._height / 2;
|
|
922
|
+
var x = i ? -height : 0;
|
|
923
|
+
return {
|
|
924
|
+
x: x,
|
|
925
|
+
y: y,
|
|
926
|
+
width: width,
|
|
927
|
+
height: height
|
|
928
|
+
};
|
|
929
|
+
},
|
|
930
|
+
labelConfig: {
|
|
931
|
+
padding: 0,
|
|
932
|
+
rotate: 0
|
|
933
|
+
},
|
|
934
|
+
labelRotation: false
|
|
935
|
+
};
|
|
936
|
+
}
|
|
937
|
+
var testGroup = elem("g.d3plus-plot-test", {
|
|
938
|
+
enter: {
|
|
939
|
+
opacity: 0
|
|
940
|
+
},
|
|
941
|
+
parent: this._select
|
|
942
|
+
});
|
|
943
|
+
/**
|
|
944
|
+
* Hides an axis' ticks and labels if they all exist as labels for the data to be displayed,
|
|
945
|
+
* primarily occuring in simple BarChart visualizations where the both the x-axis ticks and
|
|
946
|
+
* the Bar rectangles would be displaying the same text.
|
|
947
|
+
*/ // generates an Array of String labels using the current label function for Bar shapes
|
|
948
|
+
var barConfig = configPrep.bind(this)(this._shapeConfig, "shape", "Bar");
|
|
949
|
+
var barLabelFunction = barConfig.label !== undefined ? typeof barConfig.label === "function" ? barConfig.label : constant(barConfig.label) : this._drawLabel;
|
|
950
|
+
var barLabels = axisData.map(function(d) {
|
|
951
|
+
return barLabelFunction(d.data, d.i);
|
|
952
|
+
}).filter(function(d) {
|
|
953
|
+
return typeof d === "number" || d;
|
|
954
|
+
}).map(String);
|
|
955
|
+
// sets an axis' ticks to [] if the axis scale is "Point" (discrete) and every tick String
|
|
956
|
+
// is also in the barLabels Array
|
|
957
|
+
var x2Ticks = unique(axisData.map(function(d) {
|
|
958
|
+
return d.x2;
|
|
959
|
+
}));
|
|
960
|
+
x2Ticks = x2Scale === "Point" && x2Ticks.every(function(t) {
|
|
961
|
+
return barLabels.includes("".concat(t));
|
|
962
|
+
}) ? [] : null;
|
|
963
|
+
var xTicks = unique(axisData.map(function(d) {
|
|
964
|
+
return d.x;
|
|
965
|
+
}));
|
|
966
|
+
xTicks = xScale === "Point" && xTicks.every(function(t) {
|
|
967
|
+
return barLabels.includes("".concat(t));
|
|
968
|
+
}) ? [] : null;
|
|
969
|
+
var y2Ticks = unique(axisData.map(function(d) {
|
|
970
|
+
return d.y2;
|
|
971
|
+
}));
|
|
972
|
+
y2Ticks = y2Scale === "Point" && y2Ticks.every(function(t) {
|
|
973
|
+
return barLabels.includes("".concat(t));
|
|
974
|
+
}) ? [] : null;
|
|
975
|
+
var yTicks = unique(axisData.map(function(d) {
|
|
976
|
+
return d.y;
|
|
977
|
+
}));
|
|
978
|
+
yTicks = yScale === "Point" && yTicks.every(function(t) {
|
|
979
|
+
return barLabels.includes("".concat(t));
|
|
980
|
+
}) ? [] : null;
|
|
981
|
+
if (showY) {
|
|
982
|
+
this._yTest.domain(yDomain).height(height).maxSize(width / 2).range([
|
|
983
|
+
undefined,
|
|
984
|
+
undefined
|
|
985
|
+
]).select(testGroup.node()).ticks(yTicks).width(width).config(yC).config(this._yConfig).scale(yConfigScale).render();
|
|
986
|
+
}
|
|
987
|
+
var yBounds = this._yTest.outerBounds();
|
|
988
|
+
var yWidth = yBounds.width ? yBounds.width + this._yTest.padding() : undefined;
|
|
989
|
+
if (y2Exists) {
|
|
990
|
+
this._y2Test.domain(y2Domain).height(height).range([
|
|
991
|
+
undefined,
|
|
992
|
+
undefined
|
|
993
|
+
]).select(testGroup.node()).ticks(y2Ticks).width(width).config(yC).config(defaultY2Config).config(this._y2Config).scale(y2ConfigScale).render();
|
|
994
|
+
}
|
|
995
|
+
var y2Bounds = this._y2Test.outerBounds();
|
|
996
|
+
var y2Width = y2Bounds.width ? y2Bounds.width + this._y2Test.padding() : undefined;
|
|
997
|
+
var xC = {
|
|
998
|
+
data: xData,
|
|
999
|
+
locale: this._locale,
|
|
1000
|
+
rounding: this._xDomain ? "none" : "outside",
|
|
1001
|
+
scalePadding: x.padding ? x.padding() : 0
|
|
1002
|
+
};
|
|
1003
|
+
if (!showY) {
|
|
1004
|
+
xC.barConfig = {
|
|
1005
|
+
stroke: "transparent"
|
|
1006
|
+
};
|
|
1007
|
+
xC.tickSize = 0;
|
|
1008
|
+
xC.shapeConfig = {
|
|
1009
|
+
labelBounds: function(d, i) {
|
|
1010
|
+
var _d_labelBounds = d.labelBounds, height = _d_labelBounds.height, y = _d_labelBounds.y;
|
|
1011
|
+
var width = _this._width / 2;
|
|
1012
|
+
var x = i ? -width : 0;
|
|
1013
|
+
return {
|
|
1014
|
+
x: x,
|
|
1015
|
+
y: y,
|
|
1016
|
+
width: width,
|
|
1017
|
+
height: height
|
|
1018
|
+
};
|
|
1019
|
+
},
|
|
1020
|
+
labelConfig: {
|
|
1021
|
+
padding: 0,
|
|
1022
|
+
rotate: 0,
|
|
1023
|
+
textAnchor: function(d) {
|
|
1024
|
+
return d.id === xTicks[0] ? "start" : "end";
|
|
1025
|
+
}
|
|
1026
|
+
},
|
|
1027
|
+
labelRotation: false
|
|
1028
|
+
};
|
|
1029
|
+
}
|
|
1030
|
+
var xRangeMax = undefined;
|
|
1031
|
+
if (showX) {
|
|
1032
|
+
this._xTest.domain(xDomain).height(height).maxSize(height / 2).range([
|
|
1033
|
+
undefined,
|
|
1034
|
+
xRangeMax
|
|
1035
|
+
]).select(testGroup.node()).ticks(xTicks).width(width).config(xC).config(this._xConfig).scale(xConfigScale).render();
|
|
1036
|
+
}
|
|
1037
|
+
var largestLabel, labelWidths = [];
|
|
1038
|
+
var showLineLabels = this._lineLabels && !y2Exists;
|
|
1039
|
+
if (showLineLabels) {
|
|
1040
|
+
var labelData = data.filter(function(d) {
|
|
1041
|
+
if (d.shape !== "Line") return false;
|
|
1042
|
+
return typeof _this._lineLabels === "function" ? _this._lineLabels(d.data, d.i) : true;
|
|
1043
|
+
});
|
|
1044
|
+
var lineData = nest().key(function(d) {
|
|
1045
|
+
return d.id;
|
|
1046
|
+
}).entries(labelData);
|
|
1047
|
+
if (lineData.length) {
|
|
1048
|
+
var userConfig = configPrep.bind(this)(this._shapeConfig, "shape", "Line");
|
|
1049
|
+
testLineShape.config(userConfig);
|
|
1050
|
+
var lineLabelConfig = testLineShape.labelConfig();
|
|
1051
|
+
var fontColorAccessor = lineLabelConfig.fontColor !== undefined ? lineLabelConfig.fontColor : testTextBox.fontColor();
|
|
1052
|
+
var fontSizeAccessor = lineLabelConfig.fontSize !== undefined ? lineLabelConfig.fontSize : testTextBox.fontSize();
|
|
1053
|
+
var fontWeightAccessor = lineLabelConfig.fontWeight !== undefined ? lineLabelConfig.fontWeight : testTextBox.fontWeight();
|
|
1054
|
+
var fontFamilyAccessor = lineLabelConfig.fontFamily !== undefined ? lineLabelConfig.fontFamily : testTextBox.fontFamily();
|
|
1055
|
+
var paddingAccessor = lineLabelConfig.padding !== undefined ? lineLabelConfig.padding : testTextBox.padding();
|
|
1056
|
+
var labelFunction = userConfig.label || this._drawLabel;
|
|
1057
|
+
var xEstimate = function(d) {
|
|
1058
|
+
if (xConfigScale === "log" && d === 0) d = xDomain[0] < 0 ? _this._xTest._d3Scale.domain()[1] : _this._xTest._d3Scale.domain()[0];
|
|
1059
|
+
return _this._xTest._getPosition.bind(_this._xTest)(d);
|
|
1060
|
+
};
|
|
1061
|
+
var yEstimate = function(d) {
|
|
1062
|
+
if (yConfigScale === "log" && d === 0) d = yDomain[0] < 0 ? _this._yTest._d3Scale.domain()[1] : _this._yTest._d3Scale.domain()[0];
|
|
1063
|
+
return _this._yTest._getPosition.bind(_this._yTest)(d);
|
|
1064
|
+
};
|
|
1065
|
+
labelWidths = lineData.map(function(group) {
|
|
1066
|
+
var d = group.values[group.values.length - 1];
|
|
1067
|
+
var i;
|
|
1068
|
+
while(d.__d3plus__ && d.data){
|
|
1069
|
+
d = d.data;
|
|
1070
|
+
i = d.i;
|
|
1071
|
+
}
|
|
1072
|
+
var label = typeof labelFunction === "function" ? labelFunction(d, i) : labelFunction;
|
|
1073
|
+
var fontColor = typeof fontColorAccessor === "function" ? fontColorAccessor(d, i) : fontColorAccessor;
|
|
1074
|
+
var fontSize = typeof fontSizeAccessor === "function" ? fontSizeAccessor(d, i) : fontSizeAccessor;
|
|
1075
|
+
var fontWeight = typeof fontWeightAccessor === "function" ? fontWeightAccessor(d, i) : fontWeightAccessor;
|
|
1076
|
+
var fontFamily = typeof fontFamilyAccessor === "function" ? fontFamilyAccessor(d, i) : fontFamilyAccessor;
|
|
1077
|
+
if (_instanceof(fontFamily, Array)) fontFamily = fontFamily.map(function(f) {
|
|
1078
|
+
return "'".concat(f, "'");
|
|
1079
|
+
}).join(", ");
|
|
1080
|
+
var labelPadding = typeof paddingAccessor === "function" ? paddingAccessor(d, i) : paddingAccessor;
|
|
1081
|
+
var labelWidth = textWidth(label, {
|
|
1082
|
+
"font-size": fontSize,
|
|
1083
|
+
"font-family": fontFamily,
|
|
1084
|
+
"font-weight": fontWeight
|
|
1085
|
+
});
|
|
1086
|
+
var coords = group.values.map(function(d) {
|
|
1087
|
+
return [
|
|
1088
|
+
xEstimate(d.x),
|
|
1089
|
+
yEstimate(d.y)
|
|
1090
|
+
];
|
|
1091
|
+
});
|
|
1092
|
+
var myMaxX = max(group.values.map(function(d) {
|
|
1093
|
+
return xEstimate(d.x);
|
|
1094
|
+
}));
|
|
1095
|
+
var labelY = group.values.find(function(d) {
|
|
1096
|
+
return xEstimate(d.x) === myMaxX;
|
|
1097
|
+
}).y;
|
|
1098
|
+
return {
|
|
1099
|
+
id: group.key,
|
|
1100
|
+
labelWidth: labelWidth + labelPadding * 2,
|
|
1101
|
+
spaceNeeded: labelWidth + labelPadding * 4,
|
|
1102
|
+
value: labelY,
|
|
1103
|
+
yEstimate: yEstimate(labelY),
|
|
1104
|
+
padding: labelPadding,
|
|
1105
|
+
fontSize: fontSize,
|
|
1106
|
+
fontColor: fontColor,
|
|
1107
|
+
maxX: myMaxX,
|
|
1108
|
+
xValue: max(group.values, function(d) {
|
|
1109
|
+
return d.x;
|
|
1110
|
+
}),
|
|
1111
|
+
coords: coords
|
|
1112
|
+
};
|
|
1113
|
+
}).sort(function(a, b) {
|
|
1114
|
+
return yDomain[1] > yDomain[0] ? a.value - b.value : b.value - a.value;
|
|
1115
|
+
}).filter(function(d, i, arr) {
|
|
1116
|
+
var fontSize = d.fontSize, id = d.id, labelWidth = d.labelWidth, maxX = d.maxX, yEstimate = d.yEstimate;
|
|
1117
|
+
var closeLabels = arr.filter(function(l) {
|
|
1118
|
+
return l.id !== id && l.coords.some(function(c) {
|
|
1119
|
+
return (c[0] > maxX || c[0] === maxX && l.maxX !== maxX) && c[0] <= maxX + labelWidth && c[1] <= yEstimate + fontSize * 0.75 && c[1] >= yEstimate - fontSize * 0.75;
|
|
1120
|
+
});
|
|
1121
|
+
});
|
|
1122
|
+
return closeLabels.length === 0;
|
|
1123
|
+
});
|
|
1124
|
+
var maxX = max(labelWidths, function(d) {
|
|
1125
|
+
return d.maxX;
|
|
1126
|
+
});
|
|
1127
|
+
largestLabel = max(labelWidths.map(function(d) {
|
|
1128
|
+
return d.labelWidth;
|
|
1129
|
+
}));
|
|
1130
|
+
var spaceNeeded = maxX === this._xTest._getRange.bind(this._xTest)()[1] ? max(labelWidths.filter(function(d) {
|
|
1131
|
+
return d.maxX === maxX;
|
|
1132
|
+
}), function(d) {
|
|
1133
|
+
return d.spaceNeeded;
|
|
1134
|
+
}) : 0;
|
|
1135
|
+
if (spaceNeeded) {
|
|
1136
|
+
var labelSpace = min([
|
|
1137
|
+
spaceNeeded,
|
|
1138
|
+
width / 4
|
|
1139
|
+
]);
|
|
1140
|
+
xRangeMax = width - labelSpace - this._margin.right;
|
|
1141
|
+
}
|
|
1142
|
+
}
|
|
1143
|
+
}
|
|
1144
|
+
if (showX && xRangeMax) {
|
|
1145
|
+
this._xTest.domain(xDomain).height(height).maxSize(height / 2).range([
|
|
1146
|
+
undefined,
|
|
1147
|
+
xRangeMax
|
|
1148
|
+
]).select(testGroup.node()).ticks(xTicks).width(width).config(xC).config(this._xConfig).scale(xConfigScale).render();
|
|
1149
|
+
}
|
|
1150
|
+
if (x2Exists) {
|
|
1151
|
+
this._x2Test.domain(x2Domain).height(height).range([
|
|
1152
|
+
undefined,
|
|
1153
|
+
xRangeMax
|
|
1154
|
+
]).select(testGroup.node()).ticks(x2Ticks).width(width).config(xC).tickSize(0).config(defaultX2Config).config(this._x2Config).scale(x2ConfigScale).render();
|
|
1155
|
+
}
|
|
1156
|
+
var xTestRange = this._xTest._getRange();
|
|
1157
|
+
var x2TestRange = this._x2Test._getRange();
|
|
1158
|
+
var x2Bounds = this._x2Test.outerBounds();
|
|
1159
|
+
var x2Height = x2Exists ? x2Bounds.height + this._x2Test.padding() : 0;
|
|
1160
|
+
var xOffsetLeft = max([
|
|
1161
|
+
yWidth,
|
|
1162
|
+
xTestRange[0],
|
|
1163
|
+
x2TestRange[0]
|
|
1164
|
+
]);
|
|
1165
|
+
if (showX) {
|
|
1166
|
+
this._xTest.range([
|
|
1167
|
+
xOffsetLeft,
|
|
1168
|
+
undefined
|
|
1169
|
+
]).render();
|
|
1170
|
+
}
|
|
1171
|
+
var topOffset = showY ? this._yTest.shapeConfig().labelConfig.fontSize() / 2 : 0;
|
|
1172
|
+
var xOffsetRight = max([
|
|
1173
|
+
y2Width,
|
|
1174
|
+
width - xTestRange[1],
|
|
1175
|
+
width - x2TestRange[1]
|
|
1176
|
+
]);
|
|
1177
|
+
var xBounds = this._xTest.outerBounds();
|
|
1178
|
+
var xHeight = xBounds.height + (showY ? this._xTest.padding() : 0);
|
|
1179
|
+
this._padding.left += xOffsetLeft;
|
|
1180
|
+
this._padding.right += xOffsetRight;
|
|
1181
|
+
this._padding.bottom += xHeight;
|
|
1182
|
+
this._padding.top += x2Height + topOffset;
|
|
1183
|
+
_get(_get_prototype_of(Plot.prototype), "_draw", this).call(this, callback);
|
|
1184
|
+
var horizontalMargin = this._margin.left + this._margin.right;
|
|
1185
|
+
var verticalMargin = this._margin.top + this._margin.bottom;
|
|
1186
|
+
var yRange = [
|
|
1187
|
+
x2Height,
|
|
1188
|
+
height - (xHeight + topOffset + verticalMargin)
|
|
1189
|
+
];
|
|
1190
|
+
if (showY) {
|
|
1191
|
+
this._yTest.domain(yDomain).height(height).maxSize(width / 2).range(yRange).select(testGroup.node()).ticks(yTicks).width(width).config(yC).config(this._yConfig).scale(yConfigScale).render();
|
|
1192
|
+
}
|
|
1193
|
+
yBounds = this._yTest.outerBounds();
|
|
1194
|
+
yWidth = yBounds.width ? yBounds.width + this._yTest.padding() : undefined;
|
|
1195
|
+
xOffsetLeft = max([
|
|
1196
|
+
yWidth,
|
|
1197
|
+
xTestRange[0],
|
|
1198
|
+
x2TestRange[0]
|
|
1199
|
+
]);
|
|
1200
|
+
if (y2Exists) {
|
|
1201
|
+
this._y2Test.config(yC).domain(y2Domain).gridSize(0).height(height).range(yRange).select(testGroup.node()).width(width - max([
|
|
1202
|
+
0,
|
|
1203
|
+
xOffsetRight - y2Width
|
|
1204
|
+
])).title(false).config(this._y2Config).config(defaultY2Config).scale(y2ConfigScale).render();
|
|
1205
|
+
}
|
|
1206
|
+
y2Bounds = this._y2Test.outerBounds();
|
|
1207
|
+
y2Width = y2Bounds.width ? y2Bounds.width + this._y2Test.padding() : undefined;
|
|
1208
|
+
xOffsetRight = max([
|
|
1209
|
+
0,
|
|
1210
|
+
y2Width,
|
|
1211
|
+
width - xTestRange[1],
|
|
1212
|
+
width - x2TestRange[1]
|
|
1213
|
+
]);
|
|
1214
|
+
var xRange = [
|
|
1215
|
+
xOffsetLeft,
|
|
1216
|
+
width - (xOffsetRight + horizontalMargin)
|
|
1217
|
+
];
|
|
1218
|
+
var rectGroup = elem("g.d3plus-plot-background", {
|
|
1219
|
+
parent: parent,
|
|
1220
|
+
transition: transition
|
|
1221
|
+
});
|
|
1222
|
+
var transform = "translate(".concat(this._margin.left, ", ").concat(this._margin.top + x2Height + topOffset, ")");
|
|
1223
|
+
var x2Transform = "translate(".concat(this._margin.left, ", ").concat(this._margin.top + topOffset, ")");
|
|
1224
|
+
var xGroup = showX && elem("g.d3plus-plot-x-axis", {
|
|
1225
|
+
parent: parent,
|
|
1226
|
+
transition: transition,
|
|
1227
|
+
enter: {
|
|
1228
|
+
transform: transform
|
|
1229
|
+
},
|
|
1230
|
+
update: {
|
|
1231
|
+
transform: transform
|
|
1232
|
+
}
|
|
1233
|
+
});
|
|
1234
|
+
var x2Group = x2Exists && elem("g.d3plus-plot-x2-axis", {
|
|
1235
|
+
parent: parent,
|
|
1236
|
+
transition: transition,
|
|
1237
|
+
enter: {
|
|
1238
|
+
transform: x2Transform
|
|
1239
|
+
},
|
|
1240
|
+
update: {
|
|
1241
|
+
transform: x2Transform
|
|
1242
|
+
}
|
|
1243
|
+
});
|
|
1244
|
+
var xTrans = xOffsetLeft > yWidth ? xOffsetLeft - yWidth : 0;
|
|
1245
|
+
var yTransform = "translate(".concat(this._margin.left + xTrans, ", ").concat(this._margin.top + topOffset, ")");
|
|
1246
|
+
var yGroup = showY && elem("g.d3plus-plot-y-axis", {
|
|
1247
|
+
parent: parent,
|
|
1248
|
+
transition: transition,
|
|
1249
|
+
enter: {
|
|
1250
|
+
transform: yTransform
|
|
1251
|
+
},
|
|
1252
|
+
update: {
|
|
1253
|
+
transform: yTransform
|
|
1254
|
+
}
|
|
1255
|
+
});
|
|
1256
|
+
var y2Transform = "translate(-".concat(this._margin.right, ", ").concat(this._margin.top + topOffset, ")");
|
|
1257
|
+
var y2Group = y2Exists && elem("g.d3plus-plot-y2-axis", {
|
|
1258
|
+
parent: parent,
|
|
1259
|
+
transition: transition,
|
|
1260
|
+
enter: {
|
|
1261
|
+
transform: y2Transform
|
|
1262
|
+
},
|
|
1263
|
+
update: {
|
|
1264
|
+
transform: y2Transform
|
|
1265
|
+
}
|
|
1266
|
+
});
|
|
1267
|
+
this._xAxis.domain(xDomain).height(height - (x2Height + topOffset + verticalMargin)).maxSize(height / 2).range(xRange).select(showX ? xGroup.node() : undefined).ticks(xTicks).width(width).config(xC).config(this._xConfig).scale(xConfigScale).render();
|
|
1268
|
+
if (x2Exists) {
|
|
1269
|
+
this._x2Axis.domain(x2Domain).height(height - (xHeight + topOffset + verticalMargin)).range(xRange).select(x2Group.node()).ticks(x2Ticks).width(width).config(xC).config(defaultX2Config).config(this._x2Config).scale(x2ConfigScale).render();
|
|
1270
|
+
}
|
|
1271
|
+
this._xFunc = x = function(d, x) {
|
|
1272
|
+
if (x === "x2") {
|
|
1273
|
+
if (x2ConfigScale === "log" && d === 0) d = x2Domain[0] < 0 ? _this._x2Axis._d3Scale.domain()[1] : _this._x2Axis._d3Scale.domain()[0];
|
|
1274
|
+
return _this._x2Axis._getPosition.bind(_this._x2Axis)(d);
|
|
1275
|
+
} else {
|
|
1276
|
+
if (xConfigScale === "log" && d === 0) d = xDomain[0] < 0 ? _this._xAxis._d3Scale.domain()[1] : _this._xAxis._d3Scale.domain()[0];
|
|
1277
|
+
return _this._xAxis._getPosition.bind(_this._xAxis)(d);
|
|
1278
|
+
}
|
|
1279
|
+
};
|
|
1280
|
+
yRange = [
|
|
1281
|
+
this._xAxis.outerBounds().y + x2Height,
|
|
1282
|
+
height - (xHeight + topOffset + verticalMargin)
|
|
1283
|
+
];
|
|
1284
|
+
this._yAxis.domain(yDomain).height(height).maxSize(width / 2).range(yRange).select(showY ? yGroup.node() : undefined).ticks(yTicks).width(xRange[xRange.length - 1]).config(yC).config(this._yConfig).scale(yConfigScale).render();
|
|
1285
|
+
if (y2Exists) {
|
|
1286
|
+
this._y2Axis.config(yC).domain(y2Exists ? y2Domain : yDomain).gridSize(0).height(height).range(yRange).select(y2Group.node()).width(width - max([
|
|
1287
|
+
0,
|
|
1288
|
+
xOffsetRight - y2Width
|
|
1289
|
+
])).title(false).config(this._y2Config).config(defaultY2Config).scale(y2ConfigScale).render();
|
|
1290
|
+
}
|
|
1291
|
+
var labelPositions = {};
|
|
1292
|
+
if (labelWidths) {
|
|
1293
|
+
nest().key(function(d) {
|
|
1294
|
+
return d.xValue;
|
|
1295
|
+
}).entries(labelWidths).forEach(function(param) {
|
|
1296
|
+
var values = param.values;
|
|
1297
|
+
var minFontSize = max(values.map(function(d) {
|
|
1298
|
+
return d.fontSize;
|
|
1299
|
+
}));
|
|
1300
|
+
var yBuckets = range(yRange[0], yRange[1], minFontSize).reverse();
|
|
1301
|
+
var bumpLimit = (yRange[1] - yRange[0]) / 8;
|
|
1302
|
+
/** */ function bumpPrevious(d, i, arr) {
|
|
1303
|
+
if (!d.defaultY) d.defaultY = this._yAxis._getPosition(d.value);
|
|
1304
|
+
if (i) {
|
|
1305
|
+
var prev = arr[i - 1];
|
|
1306
|
+
var fontSize = d.fontSize, padding = d.padding;
|
|
1307
|
+
var y = d.newY || d.defaultY;
|
|
1308
|
+
var prevY = prev.newY || prev.defaultY;
|
|
1309
|
+
if (y - fontSize / 2 - padding < prevY) {
|
|
1310
|
+
var newY = yBuckets.find(function(n) {
|
|
1311
|
+
return n < prevY;
|
|
1312
|
+
});
|
|
1313
|
+
var change = d.defaultY - newY;
|
|
1314
|
+
if (change < bumpLimit) {
|
|
1315
|
+
prev.newY = newY;
|
|
1316
|
+
if (i) bumpPrevious(prev, i - 1, arr);
|
|
1317
|
+
}
|
|
1318
|
+
}
|
|
1319
|
+
}
|
|
1320
|
+
}
|
|
1321
|
+
values.forEach(bumpPrevious.bind(_this));
|
|
1322
|
+
});
|
|
1323
|
+
labelPositions = labelWidths.reduce(function(obj, d) {
|
|
1324
|
+
if (d.newY) obj[d.id] = d.newY;
|
|
1325
|
+
return obj;
|
|
1326
|
+
}, {});
|
|
1327
|
+
}
|
|
1328
|
+
this._yFunc = y = function(d, y) {
|
|
1329
|
+
if (y === "y2") {
|
|
1330
|
+
if (y2ConfigScale === "log" && d === 0) d = y2Domain[1] < 0 ? _this._y2Axis._d3ScaleNegative.domain()[0] : _this._y2Axis._d3Scale.domain()[1];
|
|
1331
|
+
return _this._y2Axis._getPosition.bind(_this._y2Axis)(d) - x2Height;
|
|
1332
|
+
} else {
|
|
1333
|
+
if (yConfigScale === "log" && d === 0) d = yDomain[1] < 0 ? _this._yAxis._d3ScaleNegative.domain()[0] : _this._yAxis._d3Scale.domain()[1];
|
|
1334
|
+
return _this._yAxis._getPosition.bind(_this._yAxis)(d) - x2Height;
|
|
1335
|
+
}
|
|
1336
|
+
};
|
|
1337
|
+
new shapes.Rect().data([
|
|
1338
|
+
{}
|
|
1339
|
+
]).select(rectGroup.node()).x(xRange[0] + (xRange[1] - xRange[0]) / 2).width(xRange[1] - xRange[0]).y(this._margin.top + topOffset + yRange[0] + (yRange[1] - yRange[0]) / 2).height(yRange[1] - yRange[0]).config(this._backgroundConfig).render();
|
|
1340
|
+
var labelConnectors = labelWidths.filter(function(d) {
|
|
1341
|
+
return d.newY !== undefined;
|
|
1342
|
+
});
|
|
1343
|
+
if (labelConnectors.length) {
|
|
1344
|
+
var connectorGroup = elem("g.d3plus-plot-connectors", {
|
|
1345
|
+
parent: parent,
|
|
1346
|
+
transition: transition,
|
|
1347
|
+
enter: {
|
|
1348
|
+
transform: transform
|
|
1349
|
+
},
|
|
1350
|
+
update: {
|
|
1351
|
+
transform: transform
|
|
1352
|
+
}
|
|
1353
|
+
}).node();
|
|
1354
|
+
var data1 = labelConnectors.map(function(d) {
|
|
1355
|
+
return assign({
|
|
1356
|
+
x: _this._xAxis._getPosition.bind(_this._xAxis)(d.xValue),
|
|
1357
|
+
y: d.defaultY
|
|
1358
|
+
}, d);
|
|
1359
|
+
}).concat(labelConnectors.map(function(d) {
|
|
1360
|
+
return assign({
|
|
1361
|
+
x: _this._xAxis._getPosition.bind(_this._xAxis)(d.xValue) + d.padding - 1,
|
|
1362
|
+
y: d.newY || d.defaultY
|
|
1363
|
+
}, d);
|
|
1364
|
+
}));
|
|
1365
|
+
new shapes.Line().config({
|
|
1366
|
+
data: data1,
|
|
1367
|
+
stroke: function(d) {
|
|
1368
|
+
return d.fontColor;
|
|
1369
|
+
},
|
|
1370
|
+
x: function(d) {
|
|
1371
|
+
return d.x;
|
|
1372
|
+
},
|
|
1373
|
+
y: function(d) {
|
|
1374
|
+
return d.y;
|
|
1375
|
+
}
|
|
1376
|
+
}).config(this._labelConnectorConfig).select(connectorGroup).render();
|
|
1377
|
+
}
|
|
1378
|
+
var annotationGroupBack = elem("g.d3plus-plot-annotations", {
|
|
1379
|
+
parent: parent,
|
|
1380
|
+
transition: transition,
|
|
1381
|
+
enter: {
|
|
1382
|
+
transform: transform
|
|
1383
|
+
},
|
|
1384
|
+
update: {
|
|
1385
|
+
transform: transform
|
|
1386
|
+
}
|
|
1387
|
+
}).node();
|
|
1388
|
+
var shapeGroup = elem("g.d3plus-plot-shapes", {
|
|
1389
|
+
parent: parent,
|
|
1390
|
+
transition: transition,
|
|
1391
|
+
enter: {
|
|
1392
|
+
transform: transform
|
|
1393
|
+
},
|
|
1394
|
+
update: {
|
|
1395
|
+
transform: transform
|
|
1396
|
+
}
|
|
1397
|
+
}).node();
|
|
1398
|
+
var annotationGroupFront = elem("g.d3plus-plot-annotations-front", {
|
|
1399
|
+
parent: parent,
|
|
1400
|
+
transition: transition,
|
|
1401
|
+
enter: {
|
|
1402
|
+
transform: transform
|
|
1403
|
+
},
|
|
1404
|
+
update: {
|
|
1405
|
+
transform: transform
|
|
1406
|
+
}
|
|
1407
|
+
}).node();
|
|
1408
|
+
Object.keys(this._previousAnnotations).forEach(function(layer) {
|
|
1409
|
+
var group = layer === "front" ? annotationGroupFront : annotationGroupBack;
|
|
1410
|
+
var annotationData = _this._annotations.filter(function(d) {
|
|
1411
|
+
return layer === "back" && !d.layer || d.layer === layer;
|
|
1412
|
+
});
|
|
1413
|
+
var annotationShapes = annotationData.map(function(d) {
|
|
1414
|
+
return d.shape;
|
|
1415
|
+
});
|
|
1416
|
+
annotationData.forEach(function(annotation) {
|
|
1417
|
+
new shapes[annotation.shape]().config(annotation).config({
|
|
1418
|
+
x: function(d) {
|
|
1419
|
+
return d.x2 ? x(d.x2, "x2") : x(d.x);
|
|
1420
|
+
},
|
|
1421
|
+
x0: _this._discrete === "x" ? function(d) {
|
|
1422
|
+
return d.x2 ? x(d.x2, "x2") : x(d.x);
|
|
1423
|
+
} : x(domains.x[0]),
|
|
1424
|
+
x1: _this._discrete === "x" ? null : function(d) {
|
|
1425
|
+
return d.x2 ? x(d.x2, "x2") : x(d.x);
|
|
1426
|
+
},
|
|
1427
|
+
y: function(d) {
|
|
1428
|
+
return d.y2 ? y(d.y2, "y2") : y(d.y);
|
|
1429
|
+
},
|
|
1430
|
+
y0: _this._discrete === "y" ? function(d) {
|
|
1431
|
+
return d.y2 ? y(d.y2, "y2") : y(d.y);
|
|
1432
|
+
} : y(domains.y[1]) - yOffset,
|
|
1433
|
+
y1: _this._discrete === "y" ? null : function(d) {
|
|
1434
|
+
return d.y2 ? y(d.y2, "y2") : y(d.y) - yOffset;
|
|
1435
|
+
}
|
|
1436
|
+
}).select(group).render();
|
|
1437
|
+
});
|
|
1438
|
+
var exitAnnotations = _this._previousAnnotations[layer].filter(function(d) {
|
|
1439
|
+
return !annotationShapes.includes(d);
|
|
1440
|
+
});
|
|
1441
|
+
exitAnnotations.forEach(function(shape) {
|
|
1442
|
+
new shapes[shape]().data([]).select(group).render();
|
|
1443
|
+
});
|
|
1444
|
+
_this._previousAnnotations[layer] = annotationShapes;
|
|
1445
|
+
});
|
|
1446
|
+
var yOffset = this._xAxis.barConfig()["stroke-width"];
|
|
1447
|
+
if (yOffset) yOffset /= 2;
|
|
1448
|
+
var discrete1 = this._discrete || "x";
|
|
1449
|
+
var shapeConfig = {
|
|
1450
|
+
discrete: this._discrete,
|
|
1451
|
+
duration: this._duration,
|
|
1452
|
+
label: function(d) {
|
|
1453
|
+
return _this._drawLabel(d.data, d.i);
|
|
1454
|
+
},
|
|
1455
|
+
select: shapeGroup,
|
|
1456
|
+
x: function(d) {
|
|
1457
|
+
return d.x2 !== undefined ? x(d.x2, "x2") : x(d.x);
|
|
1458
|
+
},
|
|
1459
|
+
x0: discrete1 === "x" ? function(d) {
|
|
1460
|
+
return d.x2 ? x(d.x2, "x2") : x(d.x);
|
|
1461
|
+
} : x(typeof this._baseline === "number" ? this._baseline : domains.x[0]),
|
|
1462
|
+
x1: discrete1 === "x" ? null : function(d) {
|
|
1463
|
+
return d.x2 ? x(d.x2, "x2") : x(d.x);
|
|
1464
|
+
},
|
|
1465
|
+
y: function(d) {
|
|
1466
|
+
return d.y2 !== undefined ? y(d.y2, "y2") : y(d.y);
|
|
1467
|
+
},
|
|
1468
|
+
y0: discrete1 === "y" ? function(d) {
|
|
1469
|
+
return d.y2 ? y(d.y2, "y2") : y(d.y);
|
|
1470
|
+
} : y(typeof this._baseline === "number" ? this._baseline : domains.y[1]) - yOffset,
|
|
1471
|
+
y1: discrete1 === "y" ? null : function(d) {
|
|
1472
|
+
return d.y2 ? y(d.y2, "y2") : y(d.y) - yOffset;
|
|
1473
|
+
}
|
|
1474
|
+
};
|
|
1475
|
+
var events = Object.keys(this._on);
|
|
1476
|
+
shapeData.forEach(function(d) {
|
|
1477
|
+
var _loop = function(e) {
|
|
1478
|
+
s.on(globalEvents[e], function(d, i, x, event) {
|
|
1479
|
+
return _this._on[globalEvents[e]](d.data, d.i, x, event);
|
|
1480
|
+
});
|
|
1481
|
+
}, _loop1 = function(e1) {
|
|
1482
|
+
s.on(shapeEvents[e1], function(d, i, x, event) {
|
|
1483
|
+
return _this._on[shapeEvents[e1]](d.data, d.i, x, event);
|
|
1484
|
+
});
|
|
1485
|
+
}, _loop2 = function(e2) {
|
|
1486
|
+
s.on(classEvents[e2], function(d, i, x, event) {
|
|
1487
|
+
return _this._on[classEvents[e2]](d.data, d.i, x, event);
|
|
1488
|
+
});
|
|
1489
|
+
};
|
|
1490
|
+
var shapeConfigInner = Object.assign({}, shapeConfig);
|
|
1491
|
+
if (_this._stacked && [
|
|
1492
|
+
"Area",
|
|
1493
|
+
"Bar"
|
|
1494
|
+
].includes(d.key)) {
|
|
1495
|
+
var scale = opp === "x" ? x : y;
|
|
1496
|
+
shapeConfigInner["".concat(opp)] = shapeConfigInner["".concat(opp, "0")] = function(d) {
|
|
1497
|
+
var dataIndex = stackKeys.indexOf(d.id), discreteIndex = discreteKeys.indexOf(d.discrete);
|
|
1498
|
+
var scaleIndex = d[opp] < 0 ? 1 : 0;
|
|
1499
|
+
return dataIndex >= 0 ? scale(stackData[dataIndex][discreteIndex][scaleIndex]) : scale(domains[opp][opp === "x" ? 0 : 1]);
|
|
1500
|
+
};
|
|
1501
|
+
shapeConfigInner["".concat(opp, "1")] = function(d) {
|
|
1502
|
+
var dataIndex = stackKeys.indexOf(d.id), discreteIndex = discreteKeys.indexOf(d.discrete);
|
|
1503
|
+
var scaleIndex = d[opp] < 0 ? 0 : 1;
|
|
1504
|
+
return dataIndex >= 0 ? scale(stackData[dataIndex][discreteIndex][scaleIndex]) : scale(domains[opp][opp === "x" ? 0 : 1]);
|
|
1505
|
+
};
|
|
1506
|
+
}
|
|
1507
|
+
var s = new shapes[d.key]().config(shapeConfigInner).data(d.values);
|
|
1508
|
+
if (d.key === "Bar") {
|
|
1509
|
+
var space;
|
|
1510
|
+
var scale1 = _this._discrete === "x" ? x : y;
|
|
1511
|
+
var scaleType = _this._discrete === "x" ? xScale : yScale;
|
|
1512
|
+
var vals = _this._discrete === "x" ? xDomain : yDomain;
|
|
1513
|
+
var _$range = _this._discrete === "x" ? xRange : yRange;
|
|
1514
|
+
if (scaleType !== "Point" && vals.length === 2) {
|
|
1515
|
+
var allPositions = Array.from(new Set(d.values.map(function(d) {
|
|
1516
|
+
return scale1(d[_this._discrete]);
|
|
1517
|
+
})));
|
|
1518
|
+
allPositions.unshift(_$range[0] - allPositions[0] - _$range[0]);
|
|
1519
|
+
allPositions.push(_$range[1] + _$range[1] - allPositions[allPositions.length - 1]);
|
|
1520
|
+
space = allPositions.reduce(function(n, d, i, arr) {
|
|
1521
|
+
if (i) {
|
|
1522
|
+
var dist = Math.abs(d - arr[i - 1]);
|
|
1523
|
+
if (dist < n) n = dist;
|
|
1524
|
+
}
|
|
1525
|
+
return n;
|
|
1526
|
+
}, Infinity);
|
|
1527
|
+
} else if (vals.length > 1) space = scale1(vals[1]) - scale1(vals[0]);
|
|
1528
|
+
else space = _$range[_$range.length - 1] - _$range[0];
|
|
1529
|
+
if (_this._groupPadding < space) space -= _this._groupPadding;
|
|
1530
|
+
var barSize = space || 1;
|
|
1531
|
+
var groups = nest().key(function(d) {
|
|
1532
|
+
return d[_this._discrete];
|
|
1533
|
+
}).key(function(d) {
|
|
1534
|
+
return d.group;
|
|
1535
|
+
}).entries(d.values);
|
|
1536
|
+
var ids = merge(groups.map(function(d) {
|
|
1537
|
+
return d.values.map(function(v) {
|
|
1538
|
+
return v.key;
|
|
1539
|
+
});
|
|
1540
|
+
}));
|
|
1541
|
+
var uniqueIds = Array.from(new Set(ids));
|
|
1542
|
+
if (max(groups.map(function(d) {
|
|
1543
|
+
return d.values.length;
|
|
1544
|
+
})) === 1) {
|
|
1545
|
+
s[_this._discrete](function(d, i) {
|
|
1546
|
+
return shapeConfig[_this._discrete](d, i);
|
|
1547
|
+
});
|
|
1548
|
+
} else {
|
|
1549
|
+
barSize = (barSize - _this._barPadding * uniqueIds.length - 1) / uniqueIds.length;
|
|
1550
|
+
var offset = space / 2 - barSize / 2;
|
|
1551
|
+
var xMod = scales.scaleLinear().domain([
|
|
1552
|
+
0,
|
|
1553
|
+
uniqueIds.length - 1
|
|
1554
|
+
]).range([
|
|
1555
|
+
-offset,
|
|
1556
|
+
offset
|
|
1557
|
+
]);
|
|
1558
|
+
s[_this._discrete](function(d, i) {
|
|
1559
|
+
return shapeConfig[_this._discrete](d, i) + xMod(uniqueIds.indexOf(d.group));
|
|
1560
|
+
});
|
|
1561
|
+
}
|
|
1562
|
+
s.width(barSize);
|
|
1563
|
+
s.height(barSize);
|
|
1564
|
+
} else if (d.key === "Line") {
|
|
1565
|
+
s.duration(width * 1.5);
|
|
1566
|
+
if (_this._confidence) {
|
|
1567
|
+
var areaConfig = Object.assign({}, shapeConfig);
|
|
1568
|
+
var discrete = _this._discrete || "x";
|
|
1569
|
+
var key = discrete === "x" ? "y" : "x";
|
|
1570
|
+
var scaleFunction = discrete === "x" ? y : x;
|
|
1571
|
+
areaConfig["".concat(key, "0")] = function(d) {
|
|
1572
|
+
return scaleFunction(_this._confidence[0] ? d.lci : d[key]);
|
|
1573
|
+
};
|
|
1574
|
+
areaConfig["".concat(key, "1")] = function(d) {
|
|
1575
|
+
return scaleFunction(_this._confidence[1] ? d.hci : d[key]);
|
|
1576
|
+
};
|
|
1577
|
+
var area = new shapes.Area().config(areaConfig).data(d.values);
|
|
1578
|
+
var confidenceConfig = Object.assign(_this._shapeConfig, _this._confidenceConfig);
|
|
1579
|
+
area.config(assign(configPrep.bind(_this)(confidenceConfig, "shape", "Line"), configPrep.bind(_this)(confidenceConfig, "shape", "Area"))).render();
|
|
1580
|
+
_this._shapes.push(area);
|
|
1581
|
+
}
|
|
1582
|
+
s.config({
|
|
1583
|
+
discrete: shapeConfig.discrete || "x",
|
|
1584
|
+
label: showLineLabels ? function(d, i) {
|
|
1585
|
+
var visible = typeof _this._lineLabels === "function" ? _this._lineLabels(d.data, d.i) : true;
|
|
1586
|
+
if (!visible) return false;
|
|
1587
|
+
var labelData = labelWidths.find(function(l) {
|
|
1588
|
+
return l.id === d.id;
|
|
1589
|
+
});
|
|
1590
|
+
if (labelData) {
|
|
1591
|
+
var yPos = labelData.newY || labelData.defaultY;
|
|
1592
|
+
var allLabels = labelWidths.filter(function(l) {
|
|
1593
|
+
return l.newY === yPos;
|
|
1594
|
+
});
|
|
1595
|
+
if (allLabels.length > 1) return allLabels[0].id !== d.id ? false : "+".concat(formatAbbreviate(allLabels.length, _this._locale), " ").concat(_this._translate("more"));
|
|
1596
|
+
return _this._drawLabel(d, i);
|
|
1597
|
+
}
|
|
1598
|
+
return false;
|
|
1599
|
+
} : false,
|
|
1600
|
+
labelBounds: showLineLabels ? function(d, i, s) {
|
|
1601
|
+
var _s_points_ = _sliced_to_array(s.points[0], 2), firstX = _s_points_[0], firstY = _s_points_[1];
|
|
1602
|
+
var _s_points_1 = _sliced_to_array(s.points[s.points.length - 1], 2), lastX = _s_points_1[0], lastY = _s_points_1[1];
|
|
1603
|
+
var height = _this._height / 4;
|
|
1604
|
+
var mod = labelPositions[d.id] ? lastY - labelPositions[d.id] : 0;
|
|
1605
|
+
return {
|
|
1606
|
+
x: lastX - firstX,
|
|
1607
|
+
y: lastY - firstY - height / 2 - mod,
|
|
1608
|
+
width: largestLabel,
|
|
1609
|
+
height: height
|
|
1610
|
+
};
|
|
1611
|
+
} : false
|
|
1612
|
+
});
|
|
1613
|
+
}
|
|
1614
|
+
var classEvents = events.filter(function(e) {
|
|
1615
|
+
return e.includes(".".concat(d.key));
|
|
1616
|
+
}), globalEvents = events.filter(function(e) {
|
|
1617
|
+
return !e.includes(".");
|
|
1618
|
+
}), shapeEvents = events.filter(function(e) {
|
|
1619
|
+
return e.includes(".shape");
|
|
1620
|
+
});
|
|
1621
|
+
for(var e = 0; e < globalEvents.length; e++)_loop(e);
|
|
1622
|
+
for(var e1 = 0; e1 < shapeEvents.length; e1++)_loop1(e1);
|
|
1623
|
+
for(var e2 = 0; e2 < classEvents.length; e2++)_loop2(e2);
|
|
1624
|
+
var userConfig = configPrep.bind(_this)(_this._shapeConfig, "shape", d.key);
|
|
1625
|
+
if (_this._shapeConfig.duration === undefined) delete userConfig.duration;
|
|
1626
|
+
s.config(userConfig).render();
|
|
1627
|
+
_this._shapes.push(s);
|
|
1628
|
+
if (d.key === "Line") {
|
|
1629
|
+
var _loop3 = function(e3) {
|
|
1630
|
+
markers.on(globalEvents[e3], function(d, i, x, event) {
|
|
1631
|
+
return _this._on[globalEvents[e3]](d.data, d.i, x, event);
|
|
1632
|
+
});
|
|
1633
|
+
}, _loop4 = function(e4) {
|
|
1634
|
+
markers.on(shapeEvents[e4], function(d, i, x, event) {
|
|
1635
|
+
return _this._on[shapeEvents[e4]](d.data, d.i, x, event);
|
|
1636
|
+
});
|
|
1637
|
+
}, _loop5 = function(e5) {
|
|
1638
|
+
markers.on(classEvents[e5], function(d, i, x, event) {
|
|
1639
|
+
return _this._on[classEvents[e5]](d.data, d.i, x, event);
|
|
1640
|
+
});
|
|
1641
|
+
};
|
|
1642
|
+
var markers = new shapes.Circle().data(_this._lineMarkers ? d.values : []).config(shapeConfig).config(_this._lineMarkerConfig).id(function(d) {
|
|
1643
|
+
return "".concat(d.id, "_").concat(d.discrete);
|
|
1644
|
+
});
|
|
1645
|
+
for(var e3 = 0; e3 < globalEvents.length; e3++)_loop3(e3);
|
|
1646
|
+
for(var e4 = 0; e4 < shapeEvents.length; e4++)_loop4(e4);
|
|
1647
|
+
for(var e5 = 0; e5 < classEvents.length; e5++)_loop5(e5);
|
|
1648
|
+
markers.render();
|
|
1649
|
+
_this._shapes.push(markers);
|
|
1650
|
+
}
|
|
1651
|
+
});
|
|
1652
|
+
var dataShapes = shapeData.map(function(d) {
|
|
1653
|
+
return d.key;
|
|
1654
|
+
});
|
|
1655
|
+
if (dataShapes.includes("Line")) {
|
|
1656
|
+
if (this._confidence) dataShapes.push("Area");
|
|
1657
|
+
if (this._lineMarkers) dataShapes.push("Circle");
|
|
1658
|
+
}
|
|
1659
|
+
var exitShapes = this._previousShapes.filter(function(d) {
|
|
1660
|
+
return !dataShapes.includes(d);
|
|
1661
|
+
});
|
|
1662
|
+
exitShapes.forEach(function(shape) {
|
|
1663
|
+
new shapes[shape]().config(shapeConfig).data([]).render();
|
|
1664
|
+
});
|
|
1665
|
+
this._previousShapes = dataShapes;
|
|
1666
|
+
return this;
|
|
1667
|
+
}
|
|
1668
|
+
},
|
|
1669
|
+
{
|
|
1670
|
+
/**
|
|
1671
|
+
@memberof Plot
|
|
1672
|
+
@desc Allows drawing custom shapes to be used as annotations in the provided x/y plot. This method accepts custom config objects for the [Shape](http://d3plus.org/docs/#Shape) class, either a single config object or an array of config objects. Each config object requires an additional parameter, the "shape", which denotes which [Shape](http://d3plus.org/docs/#Shape) sub-class to use ([Rect](http://d3plus.org/docs/#Rect), [Line](http://d3plus.org/docs/#Line), etc).
|
|
1673
|
+
|
|
1674
|
+
Additionally, each config object can also contain an optional "layer" key, which defines whether the annotations will be displayed in "front" or in "back" of the primary visualization shapes. This value defaults to "back" if not present.
|
|
1675
|
+
@param {Array|Object} *annotations* = []
|
|
1676
|
+
@chainable
|
|
1677
|
+
*/ key: "annotations",
|
|
1678
|
+
value: function annotations(_) {
|
|
1679
|
+
return arguments.length ? (this._annotations = _instanceof(_, Array) ? _ : [
|
|
1680
|
+
_
|
|
1681
|
+
], this) : this._annotations;
|
|
1682
|
+
}
|
|
1683
|
+
},
|
|
1684
|
+
{
|
|
1685
|
+
/**
|
|
1686
|
+
@memberof Plot
|
|
1687
|
+
@desc Determines whether the x and y axes should have their scales persist while users filter the data, the timeline being the prime example (set this to `true` to make the axes stay consistent when the timeline changes).
|
|
1688
|
+
@param {Boolean} [*value* = false]
|
|
1689
|
+
@chainable
|
|
1690
|
+
*/ key: "axisPersist",
|
|
1691
|
+
value: function axisPersist(_) {
|
|
1692
|
+
return arguments.length ? (this._axisPersist = _, this) : this._axisPersist;
|
|
1693
|
+
}
|
|
1694
|
+
},
|
|
1695
|
+
{
|
|
1696
|
+
/**
|
|
1697
|
+
@memberof Plot
|
|
1698
|
+
@desc A d3plus-shape configuration Object used for styling the background rectangle of the inner x/y plot (behind all of the shapes and gridlines).
|
|
1699
|
+
@param {Object} [*value*]
|
|
1700
|
+
@chainable
|
|
1701
|
+
*/ key: "backgroundConfig",
|
|
1702
|
+
value: function backgroundConfig(_) {
|
|
1703
|
+
return arguments.length ? (this._backgroundConfig = assign(this._backgroundConfig, _), this) : this._backgroundConfig;
|
|
1704
|
+
}
|
|
1705
|
+
},
|
|
1706
|
+
{
|
|
1707
|
+
/**
|
|
1708
|
+
@memberof Plot
|
|
1709
|
+
@desc Sets the pixel space between each bar in a group of bars.
|
|
1710
|
+
@param {Number} *value* = 0
|
|
1711
|
+
@chainable
|
|
1712
|
+
*/ key: "barPadding",
|
|
1713
|
+
value: function barPadding(_) {
|
|
1714
|
+
return arguments.length ? (this._barPadding = _, this) : this._barPadding;
|
|
1715
|
+
}
|
|
1716
|
+
},
|
|
1717
|
+
{
|
|
1718
|
+
/**
|
|
1719
|
+
@memberof Plot
|
|
1720
|
+
@desc Sets the baseline for the x/y plot. If *value* is not specified, returns the current baseline.
|
|
1721
|
+
@param {Number} *value*
|
|
1722
|
+
@chainable
|
|
1723
|
+
*/ key: "baseline",
|
|
1724
|
+
value: function baseline(_) {
|
|
1725
|
+
return arguments.length ? (this._baseline = _, this) : this._baseline;
|
|
1726
|
+
}
|
|
1727
|
+
},
|
|
1728
|
+
{
|
|
1729
|
+
/**
|
|
1730
|
+
@memberof Plot
|
|
1731
|
+
@desc Determines whether or not to add additional padding at the ends of x or y scales. The most commone use for this is in Scatter Plots, so that the shapes do not appear directly on the axis itself. The value provided can either be `true` or `false` to toggle the behavior for all shape types, or a keyed Object for each shape type (ie. `{Bar: false, Circle: true, Line: false}`).
|
|
1732
|
+
@param {Object|Boolean} [*value*]
|
|
1733
|
+
@chainable
|
|
1734
|
+
*/ key: "buffer",
|
|
1735
|
+
value: function buffer(_) {
|
|
1736
|
+
if (arguments.length) {
|
|
1737
|
+
if (!_) this._buffer = {};
|
|
1738
|
+
else if (_ === true) this._buffer = defaultBuffers;
|
|
1739
|
+
else {
|
|
1740
|
+
this._buffer = assign({}, this._buffer, _);
|
|
1741
|
+
for(var key in this._buffer){
|
|
1742
|
+
if (this._buffer[key] === true) this._buffer[key] = defaultBuffers[key];
|
|
1743
|
+
}
|
|
1744
|
+
}
|
|
1745
|
+
return this;
|
|
1746
|
+
}
|
|
1747
|
+
return this._buffer;
|
|
1748
|
+
}
|
|
1749
|
+
},
|
|
1750
|
+
{
|
|
1751
|
+
/**
|
|
1752
|
+
@memberof Plot
|
|
1753
|
+
@desc Sets the confidence to the specified array of lower and upper bounds.
|
|
1754
|
+
@param {String[]|Function[]} *value*
|
|
1755
|
+
@chainable
|
|
1756
|
+
@example <caption>Can be called with accessor functions or static keys:</caption>
|
|
1757
|
+
var data = {id: "alpha", value: 10, lci: 9, hci: 11};
|
|
1758
|
+
...
|
|
1759
|
+
// Accessor functions
|
|
1760
|
+
.confidence([function(d) { return d.lci }, function(d) { return d.hci }])
|
|
1761
|
+
|
|
1762
|
+
// Or static keys
|
|
1763
|
+
.confidence(["lci", "hci"])
|
|
1764
|
+
*/ key: "confidence",
|
|
1765
|
+
value: function confidence(_) {
|
|
1766
|
+
if (arguments.length && _instanceof(_, Array)) {
|
|
1767
|
+
this._confidence = [];
|
|
1768
|
+
var lower = _[0];
|
|
1769
|
+
this._confidence[0] = typeof lower === "function" || !lower ? lower : accessor(lower);
|
|
1770
|
+
var upper = _[1];
|
|
1771
|
+
this._confidence[1] = typeof upper === "function" || !upper ? upper : accessor(upper);
|
|
1772
|
+
return this;
|
|
1773
|
+
} else return this._confidence;
|
|
1774
|
+
}
|
|
1775
|
+
},
|
|
1776
|
+
{
|
|
1777
|
+
/**
|
|
1778
|
+
@memberof Plot
|
|
1779
|
+
@desc If *value* is specified, sets the config method for each shape rendered as a confidence interval and returns the current class instance.
|
|
1780
|
+
@param {Object} [*value*]
|
|
1781
|
+
@chainable
|
|
1782
|
+
*/ key: "confidenceConfig",
|
|
1783
|
+
value: function confidenceConfig(_) {
|
|
1784
|
+
return arguments.length ? (this._confidenceConfig = assign(this._confidenceConfig, _), this) : this._confidenceConfig;
|
|
1785
|
+
}
|
|
1786
|
+
},
|
|
1787
|
+
{
|
|
1788
|
+
/**
|
|
1789
|
+
@memberof Plot
|
|
1790
|
+
@desc Sets the discrete axis to the specified string. If *value* is not specified, returns the current discrete axis.
|
|
1791
|
+
@param {String} *value*
|
|
1792
|
+
@chainable
|
|
1793
|
+
*/ key: "discrete",
|
|
1794
|
+
value: function discrete(_) {
|
|
1795
|
+
return arguments.length ? (this._discrete = _, this) : this._discrete;
|
|
1796
|
+
}
|
|
1797
|
+
},
|
|
1798
|
+
{
|
|
1799
|
+
/**
|
|
1800
|
+
@memberof Plot
|
|
1801
|
+
@desc When the width or height of the chart is less than or equal to this pixel value, the discrete axis will not be shown. This helps produce slick sparklines. Set this value to `0` to disable the behavior entirely.
|
|
1802
|
+
@param {Number} *value*
|
|
1803
|
+
@chainable
|
|
1804
|
+
*/ key: "discreteCutoff",
|
|
1805
|
+
value: function discreteCutoff(_) {
|
|
1806
|
+
return arguments.length ? (this._discreteCutoff = _, this) : this._discreteCutoff;
|
|
1807
|
+
}
|
|
1808
|
+
},
|
|
1809
|
+
{
|
|
1810
|
+
/**
|
|
1811
|
+
@memberof Plot
|
|
1812
|
+
@desc Sets the pixel space between groups of bars.
|
|
1813
|
+
@param {Number} [*value* = 5]
|
|
1814
|
+
@chainable
|
|
1815
|
+
*/ key: "groupPadding",
|
|
1816
|
+
value: function groupPadding(_) {
|
|
1817
|
+
return arguments.length ? (this._groupPadding = _, this) : this._groupPadding;
|
|
1818
|
+
}
|
|
1819
|
+
},
|
|
1820
|
+
{
|
|
1821
|
+
/**
|
|
1822
|
+
@memberof Plot
|
|
1823
|
+
@desc The d3plus-shape config used on the Line shapes created to connect lineLabels to the end of their associated Line path.
|
|
1824
|
+
@param {Object} [*value*]
|
|
1825
|
+
@chainable
|
|
1826
|
+
*/ key: "labelConnectorConfig",
|
|
1827
|
+
value: function labelConnectorConfig(_) {
|
|
1828
|
+
return arguments.length ? (this._labelConnectorConfig = assign(this._labelConnectorConfig, _), this) : this._labelConnectorConfig;
|
|
1829
|
+
}
|
|
1830
|
+
},
|
|
1831
|
+
{
|
|
1832
|
+
/**
|
|
1833
|
+
@memberof Viz
|
|
1834
|
+
@desc The behavior to be used when calculating the position and size of each shape's label(s). The value passed can either be the _String_ name of the behavior to be used for all shapes, or an accessor _Function_ that will be provided each data point and will be expected to return the behavior to be used for that data point. The availability and options for this method depend on the default logic for each Shape. As an example, the values "outside" or "inside" can be set for Bar shapes, whose "auto" default will calculate the best position dynamically based on the available space.
|
|
1835
|
+
@param {Function|String} [*value* = "auto"]
|
|
1836
|
+
@chainable
|
|
1837
|
+
*/ key: "labelPosition",
|
|
1838
|
+
value: function labelPosition(_) {
|
|
1839
|
+
return arguments.length ? (this._labelPosition = typeof _ === "function" ? _ : constant(_), this) : this._labelPosition;
|
|
1840
|
+
}
|
|
1841
|
+
},
|
|
1842
|
+
{
|
|
1843
|
+
/**
|
|
1844
|
+
@memberof Plot
|
|
1845
|
+
@desc Draws labels on the right side of any Line shapes that are drawn on the plot.
|
|
1846
|
+
@param {Boolean|Function} [*value* = false]
|
|
1847
|
+
@chainable
|
|
1848
|
+
*/ key: "lineLabels",
|
|
1849
|
+
value: function lineLabels(_) {
|
|
1850
|
+
return arguments.length ? (this._lineLabels = _, this) : this._lineLabels;
|
|
1851
|
+
}
|
|
1852
|
+
},
|
|
1853
|
+
{
|
|
1854
|
+
/**
|
|
1855
|
+
@memberof Plot
|
|
1856
|
+
@desc Shape config for the Circle shapes drawn by the lineMarkers method.
|
|
1857
|
+
@param {Object} *value*
|
|
1858
|
+
@chainable
|
|
1859
|
+
*/ key: "lineMarkerConfig",
|
|
1860
|
+
value: function lineMarkerConfig(_) {
|
|
1861
|
+
return arguments.length ? (this._lineMarkerConfig = assign(this._lineMarkerConfig, _), this) : this._lineMarkerConfig;
|
|
1862
|
+
}
|
|
1863
|
+
},
|
|
1864
|
+
{
|
|
1865
|
+
/**
|
|
1866
|
+
@memberof Plot
|
|
1867
|
+
@desc Draws circle markers on each vertex of a Line.
|
|
1868
|
+
@param {Boolean} [*value* = false]
|
|
1869
|
+
@chainable
|
|
1870
|
+
*/ key: "lineMarkers",
|
|
1871
|
+
value: function lineMarkers(_) {
|
|
1872
|
+
return arguments.length ? (this._lineMarkers = _, this) : this._lineMarkers;
|
|
1873
|
+
}
|
|
1874
|
+
},
|
|
1875
|
+
{
|
|
1876
|
+
/**
|
|
1877
|
+
@memberof Plot
|
|
1878
|
+
@desc A JavaScript [sort comparator function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort) that receives each shape Class (ie. "Circle", "Line", etc) as it's comparator arguments. Shapes are drawn in groups based on their type, so you are defining the layering order for all shapes of said type.
|
|
1879
|
+
@param {Function} *value*
|
|
1880
|
+
@chainable
|
|
1881
|
+
*/ key: "shapeSort",
|
|
1882
|
+
value: function shapeSort(_) {
|
|
1883
|
+
return arguments.length ? (this._shapeSort = _, this) : this._shapeSort;
|
|
1884
|
+
}
|
|
1885
|
+
},
|
|
1886
|
+
{
|
|
1887
|
+
/**
|
|
1888
|
+
@memberof Plot
|
|
1889
|
+
@desc Sets the size of bubbles to the given Number, data key, or function.
|
|
1890
|
+
@param {Function|Number|String} *value* = 10
|
|
1891
|
+
@chainable
|
|
1892
|
+
*/ key: "size",
|
|
1893
|
+
value: function size(_) {
|
|
1894
|
+
return arguments.length ? (this._size = typeof _ === "function" || !_ ? _ : accessor(_), this) : this._size;
|
|
1895
|
+
}
|
|
1896
|
+
},
|
|
1897
|
+
{
|
|
1898
|
+
/**
|
|
1899
|
+
@memberof Plot
|
|
1900
|
+
@desc Sets the size scale maximum to the specified number.
|
|
1901
|
+
@param {Number} *value* = 20
|
|
1902
|
+
@chainable
|
|
1903
|
+
*/ key: "sizeMax",
|
|
1904
|
+
value: function sizeMax(_) {
|
|
1905
|
+
return arguments.length ? (this._sizeMax = _, this) : this._sizeMax;
|
|
1906
|
+
}
|
|
1907
|
+
},
|
|
1908
|
+
{
|
|
1909
|
+
/**
|
|
1910
|
+
@memberof Plot
|
|
1911
|
+
@desc Sets the size scale minimum to the specified number.
|
|
1912
|
+
@param {Number} *value* = 5
|
|
1913
|
+
@chainable
|
|
1914
|
+
*/ key: "sizeMin",
|
|
1915
|
+
value: function sizeMin(_) {
|
|
1916
|
+
return arguments.length ? (this._sizeMin = _, this) : this._sizeMin;
|
|
1917
|
+
}
|
|
1918
|
+
},
|
|
1919
|
+
{
|
|
1920
|
+
/**
|
|
1921
|
+
@memberof Plot
|
|
1922
|
+
@desc Sets the size scale to the specified string.
|
|
1923
|
+
@param {String} *value* = "sqrt"
|
|
1924
|
+
@chainable
|
|
1925
|
+
*/ key: "sizeScale",
|
|
1926
|
+
value: function sizeScale(_) {
|
|
1927
|
+
return arguments.length ? (this._sizeScale = _, this) : this._sizeScale;
|
|
1928
|
+
}
|
|
1929
|
+
},
|
|
1930
|
+
{
|
|
1931
|
+
/**
|
|
1932
|
+
@memberof Plot
|
|
1933
|
+
@desc If *value* is specified, toggles shape stacking. If *value* is not specified, returns the current stack value.
|
|
1934
|
+
@param {Boolean} *value* = false
|
|
1935
|
+
@chainable
|
|
1936
|
+
*/ key: "stacked",
|
|
1937
|
+
value: function stacked(_) {
|
|
1938
|
+
return arguments.length ? (this._stacked = _, this) : this._stacked;
|
|
1939
|
+
}
|
|
1940
|
+
},
|
|
1941
|
+
{
|
|
1942
|
+
/**
|
|
1943
|
+
@memberof Plot
|
|
1944
|
+
@desc Sets the stack offset. If *value* is not specified, returns the current stack offset function.
|
|
1945
|
+
@param {Function|String} *value* = "descending"
|
|
1946
|
+
@chainable
|
|
1947
|
+
*/ key: "stackOffset",
|
|
1948
|
+
value: function stackOffset(_) {
|
|
1949
|
+
return arguments.length ? (this._stackOffset = typeof _ === "function" ? _ : d3Shape["stackOffset".concat(_.charAt(0).toUpperCase() + _.slice(1))], this) : this._stackOffset;
|
|
1950
|
+
}
|
|
1951
|
+
},
|
|
1952
|
+
{
|
|
1953
|
+
/**
|
|
1954
|
+
@memberof Plot
|
|
1955
|
+
@desc Sets the stack order. If *value* is not specified, returns the current stack order function.
|
|
1956
|
+
@param {Function|String|Array} *value* = "none"
|
|
1957
|
+
@chainable
|
|
1958
|
+
*/ key: "stackOrder",
|
|
1959
|
+
value: function stackOrder(_) {
|
|
1960
|
+
if (arguments.length) {
|
|
1961
|
+
if (typeof _ === "string") this._stackOrder = _ === "ascending" ? stackOrderAscending : _ === "descending" ? stackOrderDescending : d3Shape["stackOrder".concat(_.charAt(0).toUpperCase() + _.slice(1))];
|
|
1962
|
+
else this._stackOrder = _;
|
|
1963
|
+
return this;
|
|
1964
|
+
} else return this._stackOrder;
|
|
1965
|
+
}
|
|
1966
|
+
},
|
|
1967
|
+
{
|
|
1968
|
+
/**
|
|
1969
|
+
@memberof Plot
|
|
1970
|
+
@desc Sets the x accessor to the specified function or number. If *value* is not specified, returns the current x accessor.
|
|
1971
|
+
@param {Function|Number} *value*
|
|
1972
|
+
@chainable
|
|
1973
|
+
*/ key: "x",
|
|
1974
|
+
value: function x(_) {
|
|
1975
|
+
if (arguments.length) {
|
|
1976
|
+
if (typeof _ === "function") this._x = _;
|
|
1977
|
+
else {
|
|
1978
|
+
this._x = accessor(_);
|
|
1979
|
+
this._xKey = _;
|
|
1980
|
+
}
|
|
1981
|
+
return this;
|
|
1982
|
+
} else return this._x;
|
|
1983
|
+
}
|
|
1984
|
+
},
|
|
1985
|
+
{
|
|
1986
|
+
/**
|
|
1987
|
+
@memberof Plot
|
|
1988
|
+
@desc Sets the x2 accessor to the specified function or number. If *value* is not specified, returns the current x2 accessor.
|
|
1989
|
+
@param {Function|Number} *value*
|
|
1990
|
+
@chainable
|
|
1991
|
+
*/ key: "x2",
|
|
1992
|
+
value: function x2(_) {
|
|
1993
|
+
if (arguments.length) {
|
|
1994
|
+
if (typeof _ === "function") this._x2 = _;
|
|
1995
|
+
else {
|
|
1996
|
+
this._x2 = accessor(_);
|
|
1997
|
+
this._x2Key = _;
|
|
1998
|
+
}
|
|
1999
|
+
return this;
|
|
2000
|
+
} else return this._x2;
|
|
2001
|
+
}
|
|
2002
|
+
},
|
|
2003
|
+
{
|
|
2004
|
+
/**
|
|
2005
|
+
@memberof Plot
|
|
2006
|
+
@desc A pass-through to the underlying [Axis](http://d3plus.org/docs/#Axis) config used for the x-axis. Includes additional functionality where passing "auto" as the value for the [scale](http://d3plus.org/docs/#Axis.scale) method will determine if the scale should be "linear" or "log" based on the provided data.
|
|
2007
|
+
@param {Object} *value*
|
|
2008
|
+
@chainable
|
|
2009
|
+
*/ key: "xConfig",
|
|
2010
|
+
value: function xConfig(_) {
|
|
2011
|
+
return arguments.length ? (this._xConfig = assign(this._xConfig, _), this) : this._xConfig;
|
|
2012
|
+
}
|
|
2013
|
+
},
|
|
2014
|
+
{
|
|
2015
|
+
/**
|
|
2016
|
+
@memberof Plot
|
|
2017
|
+
@desc When the width of the chart is less than or equal to this pixel value, and the x-axis is not the discrete axis, it will not be shown. This helps produce slick sparklines. Set this value to `0` to disable the behavior entirely.
|
|
2018
|
+
@param {Number} *value*
|
|
2019
|
+
@chainable
|
|
2020
|
+
*/ key: "xCutoff",
|
|
2021
|
+
value: function xCutoff(_) {
|
|
2022
|
+
return arguments.length ? (this._xCutoff = _, this) : this._xCutoff;
|
|
2023
|
+
}
|
|
2024
|
+
},
|
|
2025
|
+
{
|
|
2026
|
+
/**
|
|
2027
|
+
@memberof Plot
|
|
2028
|
+
@desc A pass-through to the underlying [Axis](http://d3plus.org/docs/#Axis) config used for the secondary x-axis. Includes additional functionality where passing "auto" as the value for the [scale](http://d3plus.org/docs/#Axis.scale) method will determine if the scale should be "linear" or "log" based on the provided data.
|
|
2029
|
+
@param {Object} *value*
|
|
2030
|
+
@chainable
|
|
2031
|
+
*/ key: "x2Config",
|
|
2032
|
+
value: function x2Config(_) {
|
|
2033
|
+
return arguments.length ? (this._x2Config = assign(this._x2Config, _), this) : this._x2Config;
|
|
2034
|
+
}
|
|
2035
|
+
},
|
|
2036
|
+
{
|
|
2037
|
+
/**
|
|
2038
|
+
@memberof Plot
|
|
2039
|
+
@desc Sets the x domain to the specified array. If *value* is not specified, returns the current x domain. Additionally, if either value of the array is undefined, it will be calculated from the data.
|
|
2040
|
+
@param {Array} *value*
|
|
2041
|
+
@chainable
|
|
2042
|
+
*/ key: "xDomain",
|
|
2043
|
+
value: function xDomain(_) {
|
|
2044
|
+
return arguments.length ? (this._xDomain = _, this) : this._xDomain;
|
|
2045
|
+
}
|
|
2046
|
+
},
|
|
2047
|
+
{
|
|
2048
|
+
/**
|
|
2049
|
+
@memberof Plot
|
|
2050
|
+
@desc Sets the x2 domain to the specified array. If *value* is not specified, returns the current x2 domain. Additionally, if either value of the array is undefined, it will be calculated from the data.
|
|
2051
|
+
@param {Array} *value*
|
|
2052
|
+
@chainable
|
|
2053
|
+
*/ key: "x2Domain",
|
|
2054
|
+
value: function x2Domain(_) {
|
|
2055
|
+
return arguments.length ? (this._x2Domain = _, this) : this._x2Domain;
|
|
2056
|
+
}
|
|
2057
|
+
},
|
|
2058
|
+
{
|
|
2059
|
+
/**
|
|
2060
|
+
@memberof Plot
|
|
2061
|
+
@desc Defines a custom sorting comparitor function to be used for discrete x axes.
|
|
2062
|
+
@param {Function} *value*
|
|
2063
|
+
@chainable
|
|
2064
|
+
*/ key: "xSort",
|
|
2065
|
+
value: function xSort(_) {
|
|
2066
|
+
return arguments.length ? (this._xSort = _, this) : this._xSort;
|
|
2067
|
+
}
|
|
2068
|
+
},
|
|
2069
|
+
{
|
|
2070
|
+
/**
|
|
2071
|
+
@memberof Plot
|
|
2072
|
+
@desc Defines a custom sorting comparitor function to be used for discrete x2 axes.
|
|
2073
|
+
@param {Function} *value*
|
|
2074
|
+
@chainable
|
|
2075
|
+
*/ key: "x2Sort",
|
|
2076
|
+
value: function x2Sort(_) {
|
|
2077
|
+
return arguments.length ? (this._x2Sort = _, this) : this._x2Sort;
|
|
2078
|
+
}
|
|
2079
|
+
},
|
|
2080
|
+
{
|
|
2081
|
+
/**
|
|
2082
|
+
@memberof Plot
|
|
2083
|
+
@desc Sets the y accessor to the specified function or number. If *value* is not specified, returns the current y accessor.
|
|
2084
|
+
@param {Function|Number} *value*
|
|
2085
|
+
@chainable
|
|
2086
|
+
*/ key: "y",
|
|
2087
|
+
value: function y(_) {
|
|
2088
|
+
if (arguments.length) {
|
|
2089
|
+
if (typeof _ === "function") this._y = _;
|
|
2090
|
+
else {
|
|
2091
|
+
this._y = accessor(_);
|
|
2092
|
+
this._yKey = _;
|
|
2093
|
+
}
|
|
2094
|
+
return this;
|
|
2095
|
+
} else return this._y;
|
|
2096
|
+
}
|
|
2097
|
+
},
|
|
2098
|
+
{
|
|
2099
|
+
/**
|
|
2100
|
+
@memberof Plot
|
|
2101
|
+
@desc Sets the y2 accessor to the specified function or number. If *value* is not specified, returns the current y2 accessor.
|
|
2102
|
+
@param {Function|Number} *value*
|
|
2103
|
+
@chainable
|
|
2104
|
+
*/ key: "y2",
|
|
2105
|
+
value: function y2(_) {
|
|
2106
|
+
if (arguments.length) {
|
|
2107
|
+
if (typeof _ === "function") this._y2 = _;
|
|
2108
|
+
else {
|
|
2109
|
+
this._y2 = accessor(_);
|
|
2110
|
+
this._y2Key = _;
|
|
2111
|
+
}
|
|
2112
|
+
return this;
|
|
2113
|
+
} else return this._y2;
|
|
2114
|
+
}
|
|
2115
|
+
},
|
|
2116
|
+
{
|
|
2117
|
+
/**
|
|
2118
|
+
@memberof Plot
|
|
2119
|
+
@desc A pass-through to the underlying [Axis](http://d3plus.org/docs/#Axis) config used for the y-axis. Includes additional functionality where passing "auto" as the value for the [scale](http://d3plus.org/docs/#Axis.scale) method will determine if the scale should be "linear" or "log" based on the provided data.
|
|
2120
|
+
|
|
2121
|
+
*Note:* If a "domain" array is passed to the y-axis config, it will be reversed.
|
|
2122
|
+
@param {Object} *value*
|
|
2123
|
+
@chainable
|
|
2124
|
+
*/ key: "yConfig",
|
|
2125
|
+
value: function yConfig(_) {
|
|
2126
|
+
if (arguments.length) {
|
|
2127
|
+
if (_.domain) _.domain = _.domain.slice().reverse();
|
|
2128
|
+
this._yConfig = assign(this._yConfig, _);
|
|
2129
|
+
return this;
|
|
2130
|
+
}
|
|
2131
|
+
return this._yConfig;
|
|
2132
|
+
}
|
|
2133
|
+
},
|
|
2134
|
+
{
|
|
2135
|
+
/**
|
|
2136
|
+
@memberof Plot
|
|
2137
|
+
@desc When the height of the chart is less than or equal to this pixel value, and the y-axis is not the discrete axis, it will not be shown. This helps produce slick sparklines. Set this value to `0` to disable the behavior entirely.
|
|
2138
|
+
@param {Number} *value*
|
|
2139
|
+
@chainable
|
|
2140
|
+
*/ key: "yCutoff",
|
|
2141
|
+
value: function yCutoff(_) {
|
|
2142
|
+
return arguments.length ? (this._yCutoff = _, this) : this._yCutoff;
|
|
2143
|
+
}
|
|
2144
|
+
},
|
|
2145
|
+
{
|
|
2146
|
+
/**
|
|
2147
|
+
@memberof Plot
|
|
2148
|
+
@desc A pass-through to the underlying [Axis](http://d3plus.org/docs/#Axis) config used for the secondary y-axis. Includes additional functionality where passing "auto" as the value for the [scale](http://d3plus.org/docs/#Axis.scale) method will determine if the scale should be "linear" or "log" based on the provided data.
|
|
2149
|
+
@param {Object} *value*
|
|
2150
|
+
@chainable
|
|
2151
|
+
*/ key: "y2Config",
|
|
2152
|
+
value: function y2Config(_) {
|
|
2153
|
+
if (arguments.length) {
|
|
2154
|
+
if (_.domain) _.domain = _.domain.slice().reverse();
|
|
2155
|
+
this._y2Config = assign(this._y2Config, _);
|
|
2156
|
+
return this;
|
|
2157
|
+
}
|
|
2158
|
+
return this._y2Config;
|
|
2159
|
+
}
|
|
2160
|
+
},
|
|
2161
|
+
{
|
|
2162
|
+
/**
|
|
2163
|
+
@memberof Plot
|
|
2164
|
+
@desc Sets the y domain to the specified array. If *value* is not specified, returns the current y domain. Additionally, if either value of the array is undefined, it will be calculated from the data.
|
|
2165
|
+
@param {Array} *value*
|
|
2166
|
+
@chainable
|
|
2167
|
+
*/ key: "yDomain",
|
|
2168
|
+
value: function yDomain(_) {
|
|
2169
|
+
return arguments.length ? (this._yDomain = _, this) : this._yDomain;
|
|
2170
|
+
}
|
|
2171
|
+
},
|
|
2172
|
+
{
|
|
2173
|
+
/**
|
|
2174
|
+
@memberof Plot
|
|
2175
|
+
@desc Sets the y2 domain to the specified array. If *value* is not specified, returns the current y2 domain. Additionally, if either value of the array is undefined, it will be calculated from the data.
|
|
2176
|
+
@param {Array} *value*
|
|
2177
|
+
@chainable
|
|
2178
|
+
*/ key: "y2Domain",
|
|
2179
|
+
value: function y2Domain(_) {
|
|
2180
|
+
return arguments.length ? (this._y2Domain = _, this) : this._y2Domain;
|
|
2181
|
+
}
|
|
2182
|
+
},
|
|
2183
|
+
{
|
|
2184
|
+
/**
|
|
2185
|
+
@memberof Plot
|
|
2186
|
+
@desc Defines a custom sorting comparitor function to be used for discrete y axes.
|
|
2187
|
+
@param {Function} *value*
|
|
2188
|
+
@chainable
|
|
2189
|
+
*/ key: "ySort",
|
|
2190
|
+
value: function ySort(_) {
|
|
2191
|
+
return arguments.length ? (this._ySort = _, this) : this._ySort;
|
|
2192
|
+
}
|
|
2193
|
+
},
|
|
2194
|
+
{
|
|
2195
|
+
/**
|
|
2196
|
+
@memberof Plot
|
|
2197
|
+
@desc Defines a custom sorting comparitor function to be used for discrete y2 axes.
|
|
2198
|
+
@param {Function} *value*
|
|
2199
|
+
@chainable
|
|
2200
|
+
*/ key: "y2Sort",
|
|
2201
|
+
value: function y2Sort(_) {
|
|
2202
|
+
return arguments.length ? (this._y2Sort = _, this) : this._y2Sort;
|
|
2203
|
+
}
|
|
2204
|
+
}
|
|
2205
|
+
]);
|
|
2206
|
+
return Plot;
|
|
2207
|
+
}(Viz);
|
|
2208
|
+
/**
|
|
2209
|
+
@class Plot
|
|
2210
|
+
@extends Viz
|
|
2211
|
+
@desc Creates an x/y plot based on an array of data.
|
|
2212
|
+
*/ export { Plot as default };
|