forked from plotly/plotly.js
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcalc.js
125 lines (99 loc) · 3.98 KB
/
calc.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
/**
* 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 isNumeric = require('fast-isnumeric');
var Axes = require('../../plots/cartesian/axes');
var Lib = require('../../lib');
var subTypes = require('./subtypes');
var calcColorscale = require('./colorscale_calc');
module.exports = function calc(gd, trace) {
var xa = Axes.getFromId(gd, trace.xaxis || 'x'),
ya = Axes.getFromId(gd, trace.yaxis || 'y');
var x = xa.makeCalcdata(trace, 'x'),
y = ya.makeCalcdata(trace, 'y');
var serieslen = Math.min(x.length, y.length),
marker,
s,
i;
// cancel minimum tick spacings (only applies to bars and boxes)
xa._minDtick = 0;
ya._minDtick = 0;
if(x.length > serieslen) x.splice(serieslen, x.length - serieslen);
if(y.length > serieslen) y.splice(serieslen, y.length - serieslen);
// check whether bounds should be tight, padded, extended to zero...
// most cases both should be padded on both ends, so start with that.
var xOptions = {padded: true},
yOptions = {padded: true};
if(subTypes.hasMarkers(trace)) {
// Treat size like x or y arrays --- Run d2c
// this needs to go before ppad computation
marker = trace.marker;
s = marker.size;
if(Array.isArray(s)) {
// I tried auto-type but category and dates dont make much sense.
var ax = {type: 'linear'};
Axes.setConvert(ax);
s = ax.makeCalcdata(trace.marker, 'size');
if(s.length > serieslen) s.splice(serieslen, s.length - serieslen);
}
var sizeref = 1.6 * (trace.marker.sizeref || 1),
markerTrans;
if(trace.marker.sizemode === 'area') {
markerTrans = function(v) {
return Math.max(Math.sqrt((v || 0) / sizeref), 3);
};
}
else {
markerTrans = function(v) {
return Math.max((v || 0) / sizeref, 3);
};
}
xOptions.ppad = yOptions.ppad = Array.isArray(s) ?
s.map(markerTrans) : markerTrans(s);
}
calcColorscale(trace);
// TODO: text size
// include zero (tight) and extremes (padded) if fill to zero
// (unless the shape is closed, then it's just filling the shape regardless)
if(((trace.fill === 'tozerox') ||
((trace.fill === 'tonextx') && gd.firstscatter)) &&
((x[0] !== x[serieslen - 1]) || (y[0] !== y[serieslen - 1]))) {
xOptions.tozero = true;
}
// if no error bars, markers or text, or fill to y=0 remove x padding
else if(!trace.error_y.visible && (
['tonexty', 'tozeroy'].indexOf(trace.fill) !== -1 ||
(!subTypes.hasMarkers(trace) && !subTypes.hasText(trace))
)) {
xOptions.padded = false;
xOptions.ppad = 0;
}
// now check for y - rather different logic, though still mostly padded both ends
// include zero (tight) and extremes (padded) if fill to zero
// (unless the shape is closed, then it's just filling the shape regardless)
if(((trace.fill === 'tozeroy') || ((trace.fill === 'tonexty') && gd.firstscatter)) &&
((x[0] !== x[serieslen - 1]) || (y[0] !== y[serieslen - 1]))) {
yOptions.tozero = true;
}
// tight y: any x fill
else if(['tonextx', 'tozerox'].indexOf(trace.fill) !== -1) {
yOptions.padded = false;
}
Axes.expand(xa, x, xOptions);
Axes.expand(ya, y, yOptions);
// create the "calculated data" to plot
var cd = new Array(serieslen);
for(i = 0; i < serieslen; i++) {
cd[i] = (isNumeric(x[i]) && isNumeric(y[i])) ?
{x: x[i], y: y[i]} : {x: false, y: false};
}
// this has migrated up from arraysToCalcdata as we have a reference to 's' here
if(typeof s !== undefined) Lib.mergeArray(s, cd, 'ms');
gd.firstscatter = false;
return cd;
};