@windborne/grapher 1.0.27 → 1.0.29
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/dist/bundle.cjs +1 -1
- package/dist/bundle.cjs.map +1 -1
- package/dist/bundle.esm.js +1 -1
- package/dist/bundle.esm.js.map +1 -1
- package/package.json +1 -1
- package/src/components/graph_body.jsx +10 -2
- package/src/renderer/graph_body_renderer.js +53 -15
- package/src/renderer/shadow_program.js +19 -2
package/package.json
CHANGED
|
@@ -171,7 +171,11 @@ function GraphBody({ stateController, webgl, bodyHeight, boundsSelectionEnabled,
|
|
|
171
171
|
clientX: touch.clientX,
|
|
172
172
|
clientY: touch.clientY
|
|
173
173
|
});
|
|
174
|
-
|
|
174
|
+
|
|
175
|
+
// Only prevent default if touch is within grapher bounds
|
|
176
|
+
if (event.cancelable && event.target.closest('.graph-body')) {
|
|
177
|
+
event.preventDefault();
|
|
178
|
+
}
|
|
175
179
|
};
|
|
176
180
|
|
|
177
181
|
const onGlobalTouchMove = (event) => {
|
|
@@ -184,7 +188,11 @@ function GraphBody({ stateController, webgl, bodyHeight, boundsSelectionEnabled,
|
|
|
184
188
|
clientX: touch.clientX,
|
|
185
189
|
clientY: touch.clientY
|
|
186
190
|
});
|
|
187
|
-
|
|
191
|
+
|
|
192
|
+
// Only prevent default if touch is within grapher bounds
|
|
193
|
+
if (event.cancelable && event.target.closest('.graph-body')) {
|
|
194
|
+
event.preventDefault();
|
|
195
|
+
}
|
|
188
196
|
};
|
|
189
197
|
|
|
190
198
|
const onGlobalTouchEnd = () => {
|
|
@@ -8,8 +8,7 @@ import drawBars from './draw_bars';
|
|
|
8
8
|
import drawLine from './draw_line';
|
|
9
9
|
import LineProgram from './line_program';
|
|
10
10
|
import ShadowProgram from './shadow_program';
|
|
11
|
-
import sizeCanvas from './size_canvas';
|
|
12
|
-
import { applyReducedOpacity } from "../helpers/colors";
|
|
11
|
+
import sizeCanvas, { DPI_INCREASE } from './size_canvas';
|
|
13
12
|
|
|
14
13
|
export default class GraphBodyRenderer extends Eventable {
|
|
15
14
|
|
|
@@ -161,21 +160,34 @@ export default class GraphBodyRenderer extends Eventable {
|
|
|
161
160
|
}
|
|
162
161
|
}
|
|
163
162
|
|
|
164
|
-
const getIndividualPoints = (useDataSpace) => {
|
|
163
|
+
const getIndividualPoints = (useDataSpace, includeBeyondBounds = false) => {
|
|
165
164
|
if (!useDataSpace && inRenderSpace && inRenderSpace.yValues) {
|
|
165
|
+
if (!bounds) {
|
|
166
|
+
bounds = singleSeries.axis.currentBounds;
|
|
167
|
+
}
|
|
168
|
+
|
|
166
169
|
const individualPoints = [];
|
|
167
170
|
const { yValues, nullMask } = inRenderSpace;
|
|
171
|
+
const threshold = yValues.length / 2;
|
|
172
|
+
let pastThreshold = 0;
|
|
173
|
+
const samples = [];
|
|
168
174
|
|
|
169
175
|
for (let pixelX = 0; pixelX < yValues.length; pixelX++) {
|
|
170
176
|
if (nullMask[pixelX] === 0) {
|
|
171
|
-
|
|
177
|
+
const xCoord = pixelX * DPI_INCREASE;
|
|
178
|
+
individualPoints.push([xCoord, yValues[pixelX]]);
|
|
179
|
+
|
|
180
|
+
if (pixelX > threshold) {
|
|
181
|
+
pastThreshold++;
|
|
182
|
+
if (samples.length < 3) samples.push({pixelX, xCoord, nullMask: nullMask[pixelX]});
|
|
183
|
+
}
|
|
172
184
|
}
|
|
173
185
|
}
|
|
174
186
|
|
|
175
|
-
if (individualPoints.length
|
|
176
|
-
return getIndividualPoints(true);
|
|
187
|
+
if (individualPoints.length < 50) {
|
|
188
|
+
return getIndividualPoints(true, includeBeyondBounds);
|
|
177
189
|
}
|
|
178
|
-
|
|
190
|
+
|
|
179
191
|
return individualPoints;
|
|
180
192
|
}
|
|
181
193
|
|
|
@@ -189,6 +201,12 @@ export default class GraphBodyRenderer extends Eventable {
|
|
|
189
201
|
data = singleSeries.inDataSpace;
|
|
190
202
|
}
|
|
191
203
|
|
|
204
|
+
let boundsMinX = bounds.minX instanceof Date ? bounds.minX.getTime() : bounds.minX;
|
|
205
|
+
let boundsMaxX = bounds.maxX instanceof Date ? bounds.maxX.getTime() : bounds.maxX;
|
|
206
|
+
|
|
207
|
+
let foundBeyondBounds = false;
|
|
208
|
+
let lastPointBeforeBounds = null;
|
|
209
|
+
|
|
192
210
|
for (let i = 0; i < data.length; i++) {
|
|
193
211
|
let x, y;
|
|
194
212
|
|
|
@@ -206,15 +224,36 @@ export default class GraphBodyRenderer extends Eventable {
|
|
|
206
224
|
}
|
|
207
225
|
|
|
208
226
|
let xValue = x instanceof Date ? x.getTime() : x;
|
|
209
|
-
|
|
210
|
-
|
|
227
|
+
|
|
228
|
+
if (xValue < boundsMinX) {
|
|
229
|
+
if (includeBeyondBounds) {
|
|
230
|
+
lastPointBeforeBounds = [xValue, y];
|
|
231
|
+
}
|
|
232
|
+
continue;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
if (xValue > boundsMaxX) {
|
|
236
|
+
if (includeBeyondBounds && !foundBeyondBounds) {
|
|
237
|
+
foundBeyondBounds = true;
|
|
238
|
+
} else {
|
|
239
|
+
break;
|
|
240
|
+
}
|
|
241
|
+
}
|
|
211
242
|
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
243
|
+
const renderWidth = this._sizing.renderWidth / DPI_INCREASE;
|
|
244
|
+
const xCoord = (xValue - boundsMinX) / (boundsMaxX - boundsMinX) * (renderWidth - 1) * DPI_INCREASE;
|
|
245
|
+
const yCoord = (1.0 - (y - bounds.minY) / (bounds.maxY - bounds.minY)) * this._sizing.renderHeight;
|
|
246
|
+
|
|
247
|
+
individualPoints.push([xCoord, yCoord]);
|
|
216
248
|
}
|
|
217
249
|
|
|
250
|
+
if (lastPointBeforeBounds && includeBeyondBounds) {
|
|
251
|
+
const [beforeXValue, beforeY] = lastPointBeforeBounds;
|
|
252
|
+
const renderWidth = this._sizing.renderWidth / DPI_INCREASE;
|
|
253
|
+
const beforeXCoord = (beforeXValue - boundsMinX) / (boundsMaxX - boundsMinX) * (renderWidth - 1) * DPI_INCREASE;
|
|
254
|
+
const beforeYCoord = (1.0 - (beforeY - bounds.minY) / (bounds.maxY - bounds.minY)) * this._sizing.renderHeight;
|
|
255
|
+
individualPoints.unshift([beforeXCoord, beforeYCoord]);
|
|
256
|
+
}
|
|
218
257
|
|
|
219
258
|
return individualPoints;
|
|
220
259
|
};
|
|
@@ -424,7 +463,7 @@ export default class GraphBodyRenderer extends Eventable {
|
|
|
424
463
|
shadowParams.selectionBounds = selection || bounds;
|
|
425
464
|
}
|
|
426
465
|
|
|
427
|
-
this._shadowProgram.draw(getIndividualPoints(false), shadowParams);
|
|
466
|
+
this._shadowProgram.draw(getIndividualPoints(false, true), shadowParams);
|
|
428
467
|
|
|
429
468
|
if (this._webgl) {
|
|
430
469
|
const gl = this._context;
|
|
@@ -433,7 +472,6 @@ export default class GraphBodyRenderer extends Eventable {
|
|
|
433
472
|
gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
|
|
434
473
|
}
|
|
435
474
|
|
|
436
|
-
|
|
437
475
|
if (singleSeries.zeroLineWidth && singleSeries.zeroLineWidth > 0) {
|
|
438
476
|
if (this._context2d) {
|
|
439
477
|
this._context2d.save();
|
|
@@ -253,10 +253,28 @@ export default class ShadowProgram {
|
|
|
253
253
|
});
|
|
254
254
|
}
|
|
255
255
|
} else {
|
|
256
|
-
|
|
256
|
+
// Skip trapezoids completely outside canvas
|
|
257
|
+
if (x1 > width || x2 < 0) {
|
|
258
|
+
continue;
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
// Clip trapezoid to canvas bounds if it extends beyond
|
|
262
|
+
let finalX2 = x2;
|
|
263
|
+
let finalY2 = y2;
|
|
264
|
+
let finalBottomY2 = bottomY2;
|
|
265
|
+
|
|
266
|
+
if (x2 > width) {
|
|
267
|
+
const ratio = (width - x1) / (x2 - x1);
|
|
268
|
+
finalX2 = width;
|
|
269
|
+
finalY2 = y1 + (y2 - y1) * ratio;
|
|
270
|
+
finalBottomY2 = bottomY1 + (bottomY2 - bottomY1) * ratio;
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
const trapezoid = { x1, y1, x2: finalX2, y2: finalY2, bottomY1, bottomY2: finalBottomY2 };
|
|
257
274
|
trapezoids.push(trapezoid);
|
|
258
275
|
}
|
|
259
276
|
}
|
|
277
|
+
|
|
260
278
|
|
|
261
279
|
|
|
262
280
|
if (trapezoids.length === 0) {
|
|
@@ -264,7 +282,6 @@ export default class ShadowProgram {
|
|
|
264
282
|
}
|
|
265
283
|
|
|
266
284
|
const geometry = this.generateTrapezoidGeometry(trapezoids);
|
|
267
|
-
|
|
268
285
|
const positionLoc = gl.getAttribLocation(this._program, "position");
|
|
269
286
|
const trapezoidBoundsLoc = gl.getAttribLocation(
|
|
270
287
|
this._program,
|