-
-
Notifications
You must be signed in to change notification settings - Fork 1.9k
/
Copy pathplot.js
158 lines (134 loc) · 5.77 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
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
/**
* Copyright 2012-2019, 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 parcoords = require('./parcoords');
var prepareRegl = require('../../lib/prepare_regl');
module.exports = function plot(gd, cdparcoords) {
var fullLayout = gd._fullLayout;
var svg = fullLayout._toppaper;
var root = fullLayout._paperdiv;
var container = fullLayout._glcontainer;
var success = prepareRegl(gd);
if(!success) return;
var gdDimensions = {};
var gdDimensionsOriginalOrder = {};
var fullIndices = {};
var inputIndices = {};
var size = fullLayout._size;
cdparcoords.forEach(function(d, i) {
var trace = d[0].trace;
fullIndices[i] = trace.index;
var iIn = inputIndices[i] = trace._fullInput.index;
gdDimensions[i] = gd.data[iIn].dimensions;
gdDimensionsOriginalOrder[i] = gd.data[iIn].dimensions.slice();
});
var filterChanged = function(i, originalDimensionIndex, newRanges) {
// Have updated `constraintrange` data on `gd.data` and raise `Plotly.restyle` event
// without having to incur heavy UI blocking due to an actual `Plotly.restyle` call
var gdDimension = gdDimensionsOriginalOrder[i][originalDimensionIndex];
var newConstraints = newRanges.map(function(r) { return r.slice(); });
// Store constraint range in preGUI
// This one doesn't work if it's stored in pieces in _storeDirectGUIEdit
// because it's an array of variable dimensionality. So store the whole
// thing at once manually.
var aStr = 'dimensions[' + originalDimensionIndex + '].constraintrange';
var preGUI = fullLayout._tracePreGUI[gd._fullData[fullIndices[i]]._fullInput.uid];
if(preGUI[aStr] === undefined) {
var initialVal = gdDimension.constraintrange;
preGUI[aStr] = initialVal || null;
}
var fullDimension = gd._fullData[fullIndices[i]].dimensions[originalDimensionIndex];
if(!newConstraints.length) {
delete gdDimension.constraintrange;
delete fullDimension.constraintrange;
newConstraints = null;
} else {
if(newConstraints.length === 1) newConstraints = newConstraints[0];
gdDimension.constraintrange = newConstraints;
fullDimension.constraintrange = newConstraints.slice();
// wrap in another array for restyle event data
newConstraints = [newConstraints];
}
var restyleData = {};
restyleData[aStr] = newConstraints;
gd.emit('plotly_restyle', [restyleData, [inputIndices[i]]]);
};
var hover = function(eventData) {
gd.emit('plotly_hover', eventData);
};
var unhover = function(eventData) {
gd.emit('plotly_unhover', eventData);
};
var axesMoved = function(i, visibleIndices) {
// Have updated order data on `gd.data` and raise `Plotly.restyle` event
// without having to incur heavy UI blocking due to an actual `Plotly.restyle` call
function visible(dimension) {return !('visible' in dimension) || dimension.visible;}
function newIdx(visibleIndices, orig, dim) {
var origIndex = orig.indexOf(dim);
var currentIndex = visibleIndices.indexOf(origIndex);
if(currentIndex === -1) {
// invisible dimensions initially go to the end
currentIndex += orig.length;
}
return currentIndex;
}
function sorter(orig) {
return function sorter(d1, d2) {
return (
newIdx(visibleIndices, orig, d1) -
newIdx(visibleIndices, orig, d2)
);
};
}
// drag&drop sorting of the visible dimensions
var orig = sorter(gdDimensionsOriginalOrder[i].filter(visible));
gdDimensions[i].sort(orig);
// invisible dimensions are not interpreted in the context of drag&drop sorting as an invisible dimension
// cannot be dragged; they're interspersed into their original positions by this subsequent merging step
gdDimensionsOriginalOrder[i].filter(function(d) {return !visible(d);})
.sort(function(d) {
// subsequent splicing to be done left to right, otherwise indices may be incorrect
return gdDimensionsOriginalOrder[i].indexOf(d);
})
.forEach(function(d) {
gdDimensions[i].splice(gdDimensions[i].indexOf(d), 1); // remove from the end
gdDimensions[i].splice(gdDimensionsOriginalOrder[i].indexOf(d), 0, d); // insert at original index
});
// TODO: we can't really store this part of the interaction state
// directly as below, since it incudes data arrays. If we want to
// persist column order we may have to do something special for this
// case to just store the order itself.
// Registry.call('_storeDirectGUIEdit',
// gd.data[inputIndices[i]],
// fullLayout._tracePreGUI[gd._fullData[fullIndices[i]]._fullInput.uid],
// {dimensions: gdDimensions[i]}
// );
gd.emit('plotly_restyle', [{dimensions: [gdDimensions[i]]}, [inputIndices[i]]]);
};
parcoords(
root,
svg,
container,
cdparcoords,
{
width: size.w,
height: size.h,
margin: {
t: size.t,
r: size.r,
b: size.b,
l: size.l
}
},
{
filterChanged: filterChanged,
hover: hover,
unhover: unhover,
axesMoved: axesMoved
});
};