@windborne/grapher 1.0.37 → 1.0.39

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@windborne/grapher",
3
- "version": "1.0.37",
3
+ "version": "1.0.39",
4
4
  "description": "Graphing library",
5
5
  "main": "src/index.js",
6
6
  "module": "dist/bundle.esm.js",
@@ -21,7 +21,7 @@ import binarySearch from '../helpers/binary_search';
21
21
 
22
22
  export default React.memo(GraphBody);
23
23
 
24
- function GraphBody({ stateController, webgl, bodyHeight, boundsSelectionEnabled, showTooltips, tooltipOptions, checkIntersection, draggablePoints, onPointDrag, onDraggablePointsDoubleClick, verticalLines, clockStyle, timeZone, onPointClick }) {
24
+ function GraphBody({ stateController, webgl, bodyHeight, boundsSelectionEnabled, showTooltips, showContextMenu=true, tooltipOptions, checkIntersection, draggablePoints, onPointDrag, onDraggablePointsDoubleClick, verticalLines, clockStyle, timeZone, onPointClick }) {
25
25
  const canvasEl = useCallback((el) => {
26
26
  if (stateController.primaryRenderer) {
27
27
  stateController.primaryRenderer.dispose();
@@ -278,11 +278,13 @@ function GraphBody({ stateController, webgl, bodyHeight, boundsSelectionEnabled,
278
278
 
279
279
  const onContextMenu = (event) => {
280
280
  event.preventDefault();
281
- stateController.setContextMenuMousePosition({
282
- clientX: event.clientX,
283
- clientY: event.clientY,
284
- showing: true
285
- });
281
+ if (showContextMenu !== false) {
282
+ stateController.setContextMenuMousePosition({
283
+ clientX: event.clientX,
284
+ clientY: event.clientY,
285
+ showing: true
286
+ });
287
+ }
286
288
  };
287
289
 
288
290
  return (
package/src/grapher.jsx CHANGED
@@ -239,6 +239,7 @@ function Grapher(props) {
239
239
  bodyHeight={props.bodyHeight}
240
240
  boundsSelectionEnabled={props.boundsSelectionEnabled}
241
241
  showTooltips={props.showTooltips}
242
+ showContextMenu={props.showContextMenu}
242
243
  tooltipOptions={props.tooltipOptions}
243
244
  checkIntersection={props.checkIntersection}
244
245
  draggablePoints={props.draggablePoints}
package/src/index.d.ts CHANGED
@@ -131,6 +131,7 @@ export interface GrapherProps {
131
131
  showRangeSelectors?: boolean;
132
132
  showSeriesKey?: boolean;
133
133
  showTooltips?: boolean;
134
+ showContextMenu?: boolean;
134
135
  showGrid?: boolean;
135
136
  showAxisColors?: boolean;
136
137
  bigLabels?: boolean;
@@ -29,6 +29,11 @@ export default function drawLine(dataInRenderSpace, {
29
29
  return;
30
30
  }
31
31
 
32
+ if (!context.setLineDash) {
33
+ console.error('drawLine called with WebGL context instead of 2D context');
34
+ return;
35
+ }
36
+
32
37
  if (highlighted) {
33
38
  width += 2;
34
39
  }
@@ -96,6 +96,12 @@ export default class GraphBodyRenderer extends Eventable {
96
96
  clear() {
97
97
  if (this._webgl) {
98
98
  this._lineProgram.clear();
99
+ // Also clear the overlay canvas if it exists (for multi shadow charts)
100
+ if (this._overlayContext) {
101
+ this._overlayContext.clearRect(0, 0, this._overlayCanvas.width, this._overlayCanvas.height);
102
+ }
103
+ // Reset the initialization flag so canvas can be resized if needed
104
+ this._overlayCanvasInitialized = false;
99
105
  } else {
100
106
  this._context.clearRect(0, 0, this._context.canvas.width, this._context.canvas.height);
101
107
  }
@@ -564,8 +570,8 @@ export default class GraphBodyRenderer extends Eventable {
564
570
  // since WebGL and 2D contexts can't coexist on the same canvas
565
571
  let drawContext = this._context;
566
572
 
567
- if (this._webgl && singleSeries.rendering === 'shadow' && (width > 0 || shouldShowIndividualPoints)) {
568
- // Only create overlay if we're actually drawing lines or points
573
+ if (this._webgl && singleSeries.rendering === 'shadow') {
574
+ // Always create overlay for shadow charts since they need 2D context for drawLine
569
575
  if (!this._overlayCanvas) {
570
576
  this._overlayCanvas = document.createElement('canvas');
571
577
  this._overlayCanvas.style.position = 'absolute';
@@ -576,19 +582,28 @@ export default class GraphBodyRenderer extends Eventable {
576
582
  this._canvas.parentNode.insertBefore(this._overlayCanvas, this._canvas.nextSibling);
577
583
  }
578
584
 
579
- // Size the overlay canvas to match the main canvas
580
- this._overlayCanvas.width = this._canvas.width;
581
- this._overlayCanvas.height = this._canvas.height;
582
- this._overlayCanvas.style.width = this._canvas.style.width;
583
- this._overlayCanvas.style.height = this._canvas.style.height;
584
-
585
- // Clear the overlay before drawing
586
- this._overlayContext.clearRect(0, 0, this._overlayCanvas.width, this._overlayCanvas.height);
587
-
585
+ // Size the overlay canvas to match the main canvas (only once when creating)
586
+ if (!this._overlayCanvasInitialized) {
587
+ this._overlayCanvas.width = this._canvas.width;
588
+ this._overlayCanvas.height = this._canvas.height;
589
+ this._overlayCanvas.style.width = this._canvas.style.width;
590
+ this._overlayCanvas.style.height = this._canvas.style.height;
591
+ this._overlayCanvasInitialized = true;
592
+ }
588
593
  drawContext = this._overlayContext;
589
594
  } else if (this._context2d) {
590
595
  // For non-WebGL or non-shadow charts with 2D context
591
596
  drawContext = this._context2d;
597
+ } else if (this._webgl) {
598
+ // Fallback for WebGL: create a temporary context for drawing lines
599
+ console.warn('Creating fallback 2D context for WebGL shadow chart');
600
+ if (!this._fallbackContext) {
601
+ const fallbackCanvas = document.createElement('canvas');
602
+ fallbackCanvas.width = this._canvas.width;
603
+ fallbackCanvas.height = this._canvas.height;
604
+ this._fallbackContext = fallbackCanvas.getContext('2d');
605
+ }
606
+ drawContext = this._fallbackContext;
592
607
  }
593
608
 
594
609
  const drawParams = {
@@ -66,10 +66,18 @@ export default function calculateTooltipState({mousePresent, mouseX, mouseY, siz
66
66
  continue;
67
67
  }
68
68
 
69
- const dataMinX = data[0][0];
70
- const dataMaxX = data[data.length - 1][0];
69
+ let dataMinX = data[0][0];
70
+ let dataMaxX = data[data.length - 1][0];
71
+
72
+ if (dataMinX instanceof Date) {
73
+ dataMinX = dataMinX.getTime();
74
+ }
75
+ if (dataMaxX instanceof Date) {
76
+ dataMaxX = dataMaxX.getTime();
77
+ }
78
+
71
79
  const dataRange = dataMaxX - dataMinX;
72
- const padding = Math.max(dataRange * 0.05, (bounds.maxX - bounds.minX) * 0.02);
80
+ const padding = 0;
73
81
 
74
82
  if (trueX < dataMinX - padding || trueX > dataMaxX + padding) {
75
83
  continue;