Skip to content

Commit bc95e66

Browse files
authored
Merge pull request plotly#6083 from plotly/regl-build-setup
Provide regl-based traces in the strict bundle
2 parents 3eae6e9 + e34df29 commit bc95e66

File tree

54 files changed

+24216
-155
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

54 files changed

+24216
-155
lines changed

CONTRIBUTING.md

+17
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,23 @@ npm run schema
162162
163163
**IMPORTANT:** please do not change and commit any files in the "dist" folder
164164

165+
#### Step 9: REGL - Review & commit potential changes to precompiled regl shaders
166+
167+
If you are implementing a new feature that involves regl shaders, or if you are
168+
making changes that affect the usage of regl shaders, you would need to run
169+
170+
```bash
171+
npm run regl-codegen
172+
```
173+
174+
to regenerate the regl code. This opens a browser window, runs through all
175+
traces with 'regl' in the tags, and stores the captured code into
176+
[src/generated/regl-codegen](https://github.com/plotly/plotly.js/blob/master/src/generated/regl-codegen). If no updates are necessary, it would be a no-op, but
177+
if there are changes, you would need to commit them.
178+
179+
This is needed because regl performs codegen in runtime which breaks CSP
180+
compliance, and so for strict builds we pre-generate regl shader code here.
181+
165182
#### Other npm scripts that may be of interest in development
166183

167184
- `npm run preprocess`: pre-processes the css and svg source file in js. This

devtools/regl_codegen/devtools.js

+160
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,160 @@
1+
'use strict';
2+
3+
/* global Plotly:false */
4+
5+
var mocks = require('../../build/test_dashboard_mocks.json');
6+
var reglTraces = require('../../build/regl_traces.json');
7+
var Lib = require('@src/lib');
8+
9+
// Our gracious testing object
10+
var Tabs = {
11+
12+
// Return the specified plot container (or default one)
13+
getGraph: function(id) {
14+
id = id || 'graph';
15+
return document.getElementById(id);
16+
},
17+
18+
// Create a new plot container
19+
fresh: function(id) {
20+
id = id || 'graph';
21+
22+
var graphDiv = Tabs.getGraph(id);
23+
24+
if(graphDiv) {
25+
graphDiv.parentNode.removeChild(graphDiv);
26+
}
27+
28+
graphDiv = document.createElement('div');
29+
graphDiv.className = 'dashboard-plot';
30+
graphDiv.id = id;
31+
32+
var plotArea = document.getElementById('plots');
33+
plotArea.appendChild(graphDiv);
34+
35+
return graphDiv;
36+
},
37+
38+
// Plot a mock by name (without .json) to the default or specified container
39+
plotMock: function(mockName, id) {
40+
return new Promise(function(res) {
41+
var mockURL = '/test/image/mocks/' + mockName + '.json';
42+
43+
console.warn('Plotting:', mockURL);
44+
45+
var request = new XMLHttpRequest();
46+
request.open('GET', mockURL, true);
47+
request.responseType = '';
48+
request.send();
49+
50+
request.onreadystatechange = function() {
51+
if(this.readyState === 4) {
52+
if(this.status === 200) {
53+
var fig = JSON.parse(this.responseText);
54+
var graphDiv = Tabs.fresh(id);
55+
56+
Plotly.newPlot(graphDiv, fig);
57+
58+
graphDiv.on('plotly_afterplot', function() {
59+
res(graphDiv);
60+
});
61+
} else {
62+
console.error(this.statusText);
63+
}
64+
}
65+
};
66+
});
67+
},
68+
};
69+
70+
71+
// Bind things to the window
72+
window.Tabs = Tabs;
73+
window.Lib = Lib;
74+
window.onload = handleOnLoad;
75+
setInterval(function() {
76+
window.gd = Tabs.getGraph() || Tabs.fresh();
77+
window.fullLayout = window.gd._fullLayout;
78+
window.fullData = window.gd._fullData;
79+
}, 1000);
80+
81+
var mocksList = document.getElementById('mocks-list');
82+
83+
function handleOnLoad() {
84+
var mocksByReglTrace = {};
85+
86+
reglTraces.forEach(function(trace) {
87+
mocksByReglTrace[trace] = [];
88+
mocks.forEach(function(mock) {
89+
if(mock.keywords.indexOf(trace) !== -1) {
90+
mocksByReglTrace[trace].push(mock);
91+
}
92+
});
93+
});
94+
95+
Object.keys(mocksByReglTrace).forEach(function(trace) {
96+
var thisMocks = mocksByReglTrace[trace];
97+
var div = document.createElement('div');
98+
div.className = 'mock-group';
99+
div.innerHTML = '<h3>' + trace + '</h3>';
100+
mocksList.appendChild(div);
101+
thisMocks.forEach(function(mock) {
102+
var a = document.createElement('a');
103+
a.className = 'mock-link';
104+
a.innerHTML = mock.name;
105+
a.href = '#' + mock.name;
106+
a.onclick = function() {
107+
Tabs.plotMock(this.innerHTML);
108+
};
109+
div.appendChild(a);
110+
div.appendChild(document.createElement('br'));
111+
});
112+
});
113+
114+
// visit the mocks one by one.
115+
return Object.keys(mocksByReglTrace).reduce(function(p, trace) {
116+
return p.then(function() {
117+
var thisMocks = mocksByReglTrace[trace];
118+
var generated = {};
119+
120+
return thisMocks.reduce(function(p, mock) {
121+
return p.then(function() {
122+
return Tabs.plotMock(mock.name).then(function(gd) {
123+
var fullLayout = gd._fullLayout;
124+
fullLayout._glcanvas.each(function(d) {
125+
if(d.regl) {
126+
console.log('found regl', d.regl);
127+
var cachedCode = d.regl.getCachedCode();
128+
Object.entries(cachedCode).forEach(function(kv) {
129+
generated[kv[0]] = kv[1].toString();
130+
});
131+
console.log('merging entries', Object.keys(cachedCode));
132+
}
133+
});
134+
});
135+
});
136+
}, Promise.resolve())
137+
.then(function() {
138+
console.log(window.__regl_codegen_cache);
139+
var body = JSON.stringify({
140+
generated: generated,
141+
trace: trace
142+
});
143+
window.__regl_codegen_cache = {};
144+
return fetch('/api/submit-code', {
145+
method: 'POST',
146+
headers: {
147+
'Content-Type': 'application/json'
148+
},
149+
body: body
150+
});
151+
});
152+
});
153+
}, Promise.resolve())
154+
.then(function() {
155+
return fetch('/api/codegen-done');
156+
})
157+
.then(function() {
158+
window.close();
159+
});
160+
}

devtools/regl_codegen/index.html

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<title>REGL Codegen</title>
5+
<link rel="stylesheet" type="text/css" href="//fonts.googleapis.com/css?family=Open+Sans:600,400,300,200|Droid+Sans|PT+Sans+Narrow|Gravitas+One|Droid+Sans+Mono|Droid+Serif|Raleway|Old+Standard+TT"/>
6+
<link rel="stylesheet" type="text/css" href="../test_dashboard/style.css">
7+
</head>
8+
<body>
9+
<section id="mocks-list"></section>
10+
<div id="plots">
11+
<div id="graph"></div>
12+
</div>
13+
<div id="snapshot"></div>
14+
15+
<script src="../../node_modules/mathjax/MathJax.js?config=TeX-AMS-MML_SVG"></script>
16+
<script charset="utf-8" id="source" type="module">import "../../build/plotly.js"</script>
17+
<script charset="utf-8" src="../../build/regl_codegen-bundle.js"></script>
18+
</body>
19+
</html>

0 commit comments

Comments
 (0)