show static method

void show(
  1. BuildContext context, {
  2. required ChartDataPoint? point,
  3. required PieData? segment,
  4. required Offset position,
  5. int? datasetIndex,
  6. int? elementIndex,
  7. String? datasetLabel,
  8. ChartTheme? theme,
  9. bool useGlassmorphism = false,
  10. bool useNeumorphism = false,
  11. bool backgroundBlur = false,
  12. VoidCallback? onViewDetails,
  13. VoidCallback? onExport,
  14. VoidCallback? onShare,
})

Implementation

static void show(
  BuildContext context, {
  required ChartDataPoint? point,
  required PieData? segment,
  required Offset position,
  int? datasetIndex,
  int? elementIndex,
  String? datasetLabel,
  ChartTheme? theme,
  bool useGlassmorphism = false,
  bool useNeumorphism = false,
  bool backgroundBlur = false,
  VoidCallback? onViewDetails,
  VoidCallback? onExport,
  VoidCallback? onShare,
}) {
  // If no actions are provided, don't show the context menu at all
  if (onViewDetails == null && onExport == null && onShare == null) {
    return;
  }

  // Close existing menu if any
  hide();

  final overlay = Overlay.of(context);
  final renderBox = context.findRenderObject() as RenderBox?;

  // Safely calculate global position with NaN checks
  Offset globalPosition;
  try {
    globalPosition =
        renderBox != null ? renderBox.localToGlobal(position) : position;

    // Validate position values (check for NaN or Infinity)
    if (!globalPosition.dx.isFinite || !globalPosition.dy.isFinite) {
      globalPosition = position; // Fallback to original position
    }
  } catch (e) {
    globalPosition = position; // Fallback to original position on error
  }

  // Get screen size safely
  final screenSize = MediaQuery.of(context).size;
  final screenWidth = screenSize.width.isFinite ? screenSize.width : 800.0;
  final screenHeight = screenSize.height.isFinite ? screenSize.height : 600.0;

  // Adjust position to keep menu on screen with NaN protection
  final adjustedPosition = Offset(
    globalPosition.dx.isFinite
        ? globalPosition.dx.clamp(16.0, screenWidth - 296)
        : 16.0,
    globalPosition.dy.isFinite
        ? globalPosition.dy.clamp(16.0, screenHeight - 400)
        : 16.0,
  );

  _currentMenu = OverlayEntry(
    builder: (context) => Stack(
      children: [
        // Backdrop - only captures taps outside the menu area
        // Use a custom approach to allow chart taps to pass through
        Positioned.fill(
          child: GestureDetector(
            onTap: () {
              // Hide menu when tapping outside
              hide();
            },
            behavior: HitTestBehavior.translucent,
            child: backgroundBlur
                ? ClipRect(
                    child: BackdropFilter(
                      filter: ui.ImageFilter.blur(sigmaX: 5, sigmaY: 5),
                      child: Container(
                        color: Colors.transparent,
                      ),
                    ),
                  )
                : Container(
                    color: Colors.transparent,
                  ),
          ),
        ),
        // Context Menu - positioned above backdrop
        ChartContextMenu(
          point: point,
          segment: segment,
          datasetIndex: datasetIndex,
          elementIndex: elementIndex,
          datasetLabel: datasetLabel,
          position: adjustedPosition,
          theme: theme,
          useGlassmorphism: useGlassmorphism,
          useNeumorphism: useNeumorphism,
          onClose: hide,
          onViewDetails: onViewDetails,
          onExport: onExport,
          onShare: onShare,
        ),
      ],
    ),
  );

  overlay.insert(_currentMenu!);
}