-
-
Notifications
You must be signed in to change notification settings - Fork 1.9k
/
Copy pathplot.js
128 lines (96 loc) · 3.44 KB
/
plot.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
/**
* Copyright 2012-2016, Plotly, Inc.
* All rights reserved.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
'use strict';
var d3 = require('d3');
var isNumeric = require('fast-isnumeric');
var Lib = require('../../lib');
var subTypes = require('../../traces/scatter/subtypes');
module.exports = function plot(traces, plotinfo) {
var xa = plotinfo.x(),
ya = plotinfo.y();
traces.each(function(d) {
var trace = d[0].trace,
// || {} is in case the trace (specifically scatterternary)
// doesn't support error bars at all, but does go through
// the scatter.plot mechanics, which calls ErrorBars.plot
// internally
xObj = trace.error_x || {},
yObj = trace.error_y || {};
var sparse = (
subTypes.hasMarkers(trace) &&
trace.marker.maxdisplayed > 0
);
var keyFunc;
if(trace.key) {
keyFunc = function(d) { return d.key; };
}
if(!yObj.visible && !xObj.visible) return;
var selection = d3.select(this).selectAll('g.errorbar');
var join = selection.data(Lib.identity, keyFunc);
join.enter().append('g')
.classed('errorbar', true);
join.exit().remove();
join.each(function(d) {
var errorbar = d3.select(this);
var coords = errorCoords(d, xa, ya);
if(sparse && !d.vis) return;
var path;
if(yObj.visible && isNumeric(coords.x) &&
isNumeric(coords.yh) &&
isNumeric(coords.ys)) {
var yw = yObj.width;
path = 'M' + (coords.x - yw) + ',' +
coords.yh + 'h' + (2 * yw) + // hat
'm-' + yw + ',0V' + coords.ys; // bar
if(!coords.noYS) path += 'm-' + yw + ',0h' + (2 * yw); // shoe
errorbar.append('path')
.classed('yerror', true)
.attr('d', path);
}
if(xObj.visible && isNumeric(coords.y) &&
isNumeric(coords.xh) &&
isNumeric(coords.xs)) {
var xw = (xObj.copy_ystyle ? yObj : xObj).width;
path = 'M' + coords.xh + ',' +
(coords.y - xw) + 'v' + (2 * xw) + // hat
'm0,-' + xw + 'H' + coords.xs; // bar
if(!coords.noXS) path += 'm0,-' + xw + 'v' + (2 * xw); // shoe
errorbar.append('path')
.classed('xerror', true)
.attr('d', path);
}
});
});
};
// compute the coordinates of the error-bar objects
function errorCoords(d, xa, ya) {
var out = {
x: xa.c2p(d.x),
y: ya.c2p(d.y)
};
// calculate the error bar size and hat and shoe locations
if(d.yh !== undefined) {
out.yh = ya.c2p(d.yh);
out.ys = ya.c2p(d.ys);
// if the shoes go off-scale (ie log scale, error bars past zero)
// clip the bar and hide the shoes
if(!isNumeric(out.ys)) {
out.noYS = true;
out.ys = ya.c2p(d.ys, true);
}
}
if(d.xh !== undefined) {
out.xh = xa.c2p(d.xh);
out.xs = xa.c2p(d.xs);
if(!isNumeric(out.xs)) {
out.noXS = true;
out.xs = xa.c2p(d.xs, true);
}
}
return out;
}