aura-glass
Version:
A comprehensive glassmorphism design system for React applications with 142+ production-ready components
871 lines (868 loc) • 34.4 kB
JavaScript
'use client';
import { jsxs, jsx } from 'react/jsx-runtime';
import React, { useState, useRef, useEffect, useCallback, useImperativeHandle } from 'react';
import { cn } from '../../lib/utilsComprehensive.js';
import { usePredictiveEngine, useInteractionRecorder } from '../advanced/GlassPredictiveEngine.js';
import { useAchievements } from '../advanced/GlassAchievementSystem.js';
import { useBiometricAdaptation } from '../advanced/GlassBiometricAdaptation.js';
import { useEyeTracking } from '../advanced/GlassEyeTracking.js';
import { useSpatialAudio } from '../advanced/GlassSpatialAudio.js';
import { ChartContainer, ChartHeader, ChartTitle, ChartSubtitle } from './styles/ChartContainerStyles.js';
import { ChartToolbar, ChartTypeSelector, TypeButton, EnhancedExportButton, ChartLegend, LegendItem, LegendColor, LegendLabel } from './styles/ChartElementStyles.js';
import { useQualityTier, getQualityBasedPhysicsParams, getQualityBasedGlassParams } from './hooks/useQualityTier.js';
import { useAccessibilitySettings } from '../../hooks/useAccessibilitySettings.js';
import { useGlassTheme } from '../../hooks/useGlassTheme.js';
import { createThemeContext } from '../../core/themeContext.js';
import { KpiChart } from './components/KpiChart.js';
import { ChartTooltip } from './components/ChartTooltip.js';
import '../../tokens/glass.js';
import { ChartRenderer } from './components/ChartRenderer.js';
import { Chart, CategoryScale, LinearScale, PointElement, LineElement, BarElement, ArcElement, Tooltip, Legend, Filler, RadialLinearScale } from 'chart.js';
// Helper function to convert elevation strings to numbers
const getNumericElevation = elevation => {
if (typeof elevation === "number") return elevation;
switch (elevation) {
case "level1":
return 1;
case "level2":
return 2;
case "level3":
return 3;
case "level4":
return 4;
case "level5":
return 5;
default:
return 3;
// default to level3
}
};
Chart.register(CategoryScale, LinearScale, PointElement, LineElement, BarElement, ArcElement, Tooltip, Legend, Filler, RadialLinearScale);
/**
* ModularGlassDataChart Component
*
* An advanced glass-styled chart component with physics-based interactions,
* smooth animations, and rich customization options. Enhanced with consciousness interface features.
*/
const ModularGlassDataChart = /*#__PURE__*/React.forwardRef((props, ref) => {
// Theme & accessibility hooks
const theme = useGlassTheme();
theme ? theme.isDarkMode : false;
const {
settings: accessibilitySettings
} = useAccessibilitySettings();
const isReducedMotion = accessibilitySettings?.reducedMotion || false;
theme ? createThemeContext(theme.theme) : undefined;
const isTestEnvironment = typeof process !== "undefined" && process.env?.JEST_WORKER_ID !== undefined;
// Extract all props with defaults
const {
title,
subtitle,
variant = "line",
datasets,
width = "100%",
height = 400,
glassVariant = "frosted",
blurStrength = "standard",
color = "primary",
// Consciousness features
predictive = false,
preloadData = false,
eyeTracking = false,
gazeResponsive = false,
adaptive = false,
biometricResponsive = false,
spatialAudio = false,
audioFeedback = false,
trackAchievements = false,
achievementId,
usageContext = "dashboard",
animation = {
physicsEnabled: true,
duration: 1000,
tension: 300,
friction: 30,
mass: 1,
easing: "easeOutQuart",
staggerDelay: 100
},
interaction = {
zoomPanEnabled: false,
physicsHoverEffects: true,
hoverSpeed: 150,
showTooltips: true,
tooltipStyle: "frosted",
tooltipFollowCursor: false
},
legend = {
show: true,
position: "top",
align: "center",
style: "default",
glassEffect: false
},
axis = {
showXGrid: true,
showYGrid: true,
showXLabels: true,
showYLabels: true,
axisColor: '${glassStyles.borderColor || "var(--glass-bg-hover)"}',
gridColor: '${glassStyles.surface?.base || "var(--glass-bg-default)"}',
gridStyle: "solid"
},
initialSelection,
showToolbar = true,
allowDownload = true,
palette = ["#6366F1",
// primary
"#8B5CF6",
// secondary
"var(--glass-color-primary)",
// blue
"var(--glass-color-success)",
// green
"var(--glass-color-warning)",
// yellow
"var(--glass-color-danger)",
// red
"#EC4899",
// pink
"var(--glass-gray-500)" // gray
],
allowTypeSwitch = true,
backgroundColor,
borderRadius = 12,
borderColor,
elevation = "level3",
className,
style,
onDataPointClick,
onSelectionChange,
onZoomPan,
onTypeChange,
exportOptions = {
filename: "chart",
quality: 0.9,
format: "png",
backgroundColor: "transparent",
includeTitle: true,
includeTimestamp: true
},
renderExportButton,
kpi,
useAdaptiveQuality = true,
...restProps
} = props;
const {
["aria-label"]: ariaLabelOverride,
["aria-describedby"]: ariaDescribedByOverride,
["aria-labelledby"]: ariaLabelledByOverride,
role: providedRole,
...nativeContainerProps
} = restProps;
const chartRole = providedRole ?? "group";
const safeDatasets = React.useMemo(() => Array.isArray(datasets) ? datasets.filter(Boolean) : [], [datasets]);
const totalDataPoints = React.useMemo(() => safeDatasets.reduce((sum, dataset) => sum + (Array.isArray(dataset?.data) ? dataset.data.length : 0), 0), [safeDatasets]);
const qualityMetrics = React.useMemo(() => ({
dataPointCount: totalDataPoints,
seriesCount: safeDatasets.length,
animationComplexity: "medium",
interactionComplexity: "medium"
}), [totalDataPoints, safeDatasets.length]);
// Quality tier system integration
const qualityTier = useQualityTier(qualityMetrics, variant, useAdaptiveQuality ? undefined : "high");
// State
const [chartType, setChartType] = useState(variant);
const [hoveredPoint, setHoveredPoint] = useState(null);
const [selectedIndices, setSelectedIndices] = useState(initialSelection !== undefined ? Array.isArray(initialSelection) ? initialSelection : [initialSelection] : []);
// Consciousness features state
const [chartInsights, setChartInsights] = useState([]);
const [dataPatterns, setDataPatterns] = useState([]);
const [isPreloading, setIsPreloading] = useState(false);
const [adaptiveComplexity, setAdaptiveComplexity] = useState("medium");
const [currentDataFocus, setCurrentDataFocus] = useState(null);
// Refs
const containerRef = useRef(null);
const chartRef = useRef(null);
// Consciousness feature hooks - only initialize if features are enabled
const predictiveEngine = predictive ? usePredictiveEngine() : null;
const eyeTracker = eyeTracking ? useEyeTracking() : null;
const biometricAdapter = adaptive ? useBiometricAdaptation() : null;
const spatialAudioEngine = spatialAudio ? useSpatialAudio() : null;
const achievementTracker = trackAchievements ? useAchievements() : null;
const recordInteraction = predictiveEngine?.recordInteraction;
predictive || trackAchievements ? useInteractionRecorder(`modular-chart-${usageContext}`) : null;
// Determine the active quality tier
const activeQuality = useAdaptiveQuality ? qualityTier : "high";
// Get physics and glass parameters based on quality tier
const activeQualityTier = typeof activeQuality === "object" ? activeQuality.tier : activeQuality;
const qualityPhysicsParams = getQualityBasedPhysicsParams(activeQualityTier);
getQualityBasedGlassParams(activeQualityTier);
// Determine if we're using physics-based animations
const enablePhysicsAnimation = animation.physicsEnabled && !isReducedMotion;
// Animation state management with physics support
const [animationValues, setAnimationValues] = useState({});
const [isAnimating, setIsAnimating] = useState(false);
const animate = React.useCallback((key, from, to, duration = 500) => {
setIsAnimating(true);
setAnimationValues(prev => ({
...prev,
[key]: from
}));
if (isTestEnvironment) {
setAnimationValues(prev => ({
...prev,
[key]: to
}));
setIsAnimating(false);
return;
}
if (enablePhysicsAnimation) {
// Use spring physics animation
const startTime = Date.now();
const animateFrame = () => {
const elapsed = Date.now() - startTime;
const progress = Math.min(elapsed / duration, 1);
// Spring easing function
const easeSpring = t => {
return 1 - Math.pow(1 - t, 3) * Math.cos(t * Math.PI * 2);
};
const currentValue = from + (to - from) * easeSpring(progress);
setAnimationValues(prev => ({
...prev,
[key]: currentValue
}));
if (progress < 1) {
requestAnimationFrame(animateFrame);
} else {
setIsAnimating(false);
}
};
requestAnimationFrame(animateFrame);
} else {
// Simple linear animation
const steps = 60;
const stepValue = (to - from) / steps;
let currentStep = 0;
const interval = setInterval(() => {
currentStep++;
const currentValue = from + stepValue * currentStep;
setAnimationValues(prev => ({
...prev,
[key]: currentValue
}));
if (currentStep >= steps) {
clearInterval(interval);
setIsAnimating(false);
}
}, duration / steps);
}
}, [enablePhysicsAnimation, isTestEnvironment]);
const getValue = key => animationValues[key] ?? 1;
// Chart insights and pattern analysis
useEffect(() => {
if (!predictive || !predictiveEngine || safeDatasets.length === 0) return;
const analyzeChartData = async () => {
try {
// Analyze data patterns for insights
// Note: analyzeDataPatterns and generateInsights methods not available in current predictive engine
setDataPatterns([]);
setChartInsights([]);
if (achievementTracker && trackAchievements) {
achievementTracker.recordAction("modular_chart_insights_generated", {
chartType: chartType,
insightsCount: 0,
patternsFound: 0,
context: usageContext
});
}
} catch (error) {
console.warn("Modular chart insights analysis failed:", error);
}
};
analyzeChartData();
}, [predictive, predictiveEngine, safeDatasets, chartType, usageContext, achievementTracker, trackAchievements]);
// Biometric adaptation for chart complexity
useEffect(() => {
if (!biometricResponsive || !biometricAdapter) return;
const adaptChartComplexity = () => {
const stressLevel = biometricAdapter.currentStressLevel;
const cognitiveLoad = biometricAdapter.currentStressLevel; // Use stress level as proxy for cognitive load
// Adapt chart complexity based on biometric data
if (stressLevel > 0.7 || cognitiveLoad > 0.8) {
setAdaptiveComplexity("low"); // Simplified chart when stressed
} else if (stressLevel < 0.3 && cognitiveLoad < 0.4) {
setAdaptiveComplexity("high"); // Full complexity when relaxed
} else {
setAdaptiveComplexity("medium"); // Balanced complexity
}
};
// Initial adaptation
adaptChartComplexity();
// Listen for biometric changes
const interval = setInterval(adaptChartComplexity, 3000);
return () => clearInterval(interval);
}, [biometricResponsive, biometricAdapter]);
// Eye tracking for chart element focus
useEffect(() => {
if (!gazeResponsive || !eyeTracker || !containerRef.current) return;
// Note: onGazeEnter/onGazeLeave not available on current eye tracker interface
// eyeTracker.onGazeEnter?.(containerRef.current, handleGazeOnDataPoint);
// eyeTracker.onGazeLeave?.(containerRef.current, handleGazeOffDataPoint);
return () => {
if (containerRef.current) ;
};
}, [gazeResponsive, eyeTracker, spatialAudioEngine, audioFeedback, achievementTracker, trackAchievements, chartType, usageContext]);
// Data preloading for chart interactions
useEffect(() => {
if (!preloadData || !predictiveEngine) return;
const preloadChartData = async () => {
setIsPreloading(true);
try {
// Note: preloadData method not available in current predictive engine
// await predictiveEngine.preloadData({
// chartType: chartType,
// context: usageContext,
// currentData: datasets,
// patterns: dataPatterns
// });
} catch (error) {
console.warn("Modular chart data preloading failed:", error);
} finally {
setIsPreloading(false);
}
};
preloadChartData();
}, [preloadData, predictiveEngine, chartType, usageContext, safeDatasets, dataPatterns]);
// Apply initial animations based on quality tier
useEffect(() => {
if (!enablePhysicsAnimation) {
return;
}
// Trigger a pop-in animation on mount for better visual impact
if (activeQualityTier !== "low") {
// Start a simple animation from 0 to 1
animate("chart-mount", 0, 1, 500);
}
}, [enablePhysicsAnimation, activeQualityTier, animate]);
// Handle chart type change with consciousness features
const handleTypeChange = type => {
const previousType = chartType;
setChartType(type);
// Consciousness-enhanced type change tracking
if (recordInteraction) {
recordInteraction({
type: "click",
element: "chart-type-selector",
context: {
viewport: {
width: window.innerWidth,
height: window.innerHeight
},
timeOfDay: new Date().getHours(),
deviceType: window.innerWidth < 768 ? "mobile" : window.innerWidth < 1024 ? "tablet" : "desktop"
},
metadata: {
action: "type-change"
}
});
}
// Spatial audio feedback for type changes
if (spatialAudioEngine && audioFeedback) {
spatialAudioEngine.playGlassSound("chart_type_change", {
x: 0,
y: 0,
z: 0
});
}
// Achievement tracking for chart exploration
if (achievementTracker && trackAchievements) {
achievementTracker.recordAction("modular_chart_type_switch", {
fromType: previousType,
toType: type,
context: usageContext,
timestamp: Date.now()
});
}
if (onTypeChange) {
onTypeChange(type);
}
};
// Handle data point click with consciousness features
const handleDataPointClick = (datasetIndex, dataIndex) => {
if (!onDataPointClick || safeDatasets.length === 0) return;
const dataset = safeDatasets[datasetIndex];
if (!dataset) return;
const dataPoint = dataset.data[dataIndex];
// Spatial audio feedback for data point interactions
if (spatialAudioEngine && audioFeedback) {
spatialAudioEngine.playGlassSound("data_point_click", {
x: 0,
y: 0,
z: 0
});
}
// Track data point interactions
if (recordInteraction && typeof window !== "undefined") {
recordInteraction({
type: "click",
element: "data-point",
context: {
viewport: {
width: window.innerWidth,
height: window.innerHeight
},
timeOfDay: new Date().getHours(),
deviceType: window.innerWidth < 768 ? "mobile" : window.innerWidth < 1024 ? "tablet" : "desktop"
},
metadata: {
action: "data-point-click"
}
});
}
// Achievement tracking for data exploration
if (achievementTracker && trackAchievements) {
achievementTracker.recordAction("modular_chart_data_point_interaction", {
datasetIndex,
dataIndex,
datasetLabel: dataset.label,
pointValue: dataPoint.y,
chartType: chartType,
context: usageContext,
hasInsights: chartInsights.length > 0
});
}
onDataPointClick(datasetIndex, dataIndex, dataPoint);
// Handle selection logic
if (onSelectionChange) {
const index = dataIndex;
const newSelectedIndices = [...selectedIndices];
if (newSelectedIndices.includes(index)) {
// Deselect
const indexPosition = newSelectedIndices.indexOf(index);
newSelectedIndices.splice(indexPosition, 1);
} else {
// Select
newSelectedIndices.push(index);
}
setSelectedIndices(newSelectedIndices);
onSelectionChange(newSelectedIndices);
}
};
// Handle chart hover for tooltips
const handleChartHover = event => {
if (!chartRef.current || !interaction.showTooltips || safeDatasets.length === 0) return;
const chart = chartRef.current;
const points = chart.getElementsAtEventForMode(event.nativeEvent, "nearest", {
intersect: false
}, false);
if (points.length > 0) {
const firstPoint = points[0];
const datasetIndex = firstPoint.datasetIndex;
const dataIndex = firstPoint.index;
const dataset = safeDatasets[datasetIndex];
if (!dataset) return;
const dataPoint = dataset.data[dataIndex];
// Get position in canvas coordinates
const rect = chart.canvas.getBoundingClientRect();
event.clientX - rect.left;
event.clientY - rect.top;
setHoveredPoint({
datasetIndex,
dataIndex,
x: event.clientX,
y: event.clientY,
value: {
dataset: dataset.label,
label: dataPoint.label || dataPoint.x,
value: dataPoint.y,
color: dataset.style?.lineColor || palette[datasetIndex % palette.length],
extra: dataPoint.extra
}
});
} else {
setHoveredPoint(null);
}
};
// Handle chart hover leave
const handleChartLeave = () => {
setHoveredPoint(null);
};
// Handle chart export
const handleExport = useCallback(() => {
if (!chartRef.current) return;
// Get chart canvas
const chart = chartRef.current;
const canvas = chart.canvas;
// Create a temporary canvas to include title if needed
const tempCanvas = document.createElement("canvas");
const ctx = tempCanvas.getContext("2d");
if (!ctx) return;
// Set temp canvas dimensions
const canvasWidth = canvas.width;
const canvasHeight = canvas.height;
// Add extra space for title if needed
const extraHeight = exportOptions.includeTitle && title ? 40 : 0;
tempCanvas.width = canvasWidth;
tempCanvas.height = canvasHeight + extraHeight;
// Fill background
ctx.fillStyle = exportOptions.backgroundColor || "transparent";
ctx.fillRect(0, 0, tempCanvas.width, tempCanvas.height);
// Add title if needed
if (exportOptions.includeTitle && title) {
ctx.fillStyle = "var(--glass-white)";
ctx.font = "bold 16px Inter, sans-serif";
ctx.textAlign = "center";
ctx.fillText(title, tempCanvas.width / 2, 25);
if (subtitle) {
ctx.fillStyle = '${glassStyles.text?.secondary || "rgba(var(--glass-color-white) / var(--glass-opacity-70))"}';
ctx.font = "12px Inter, sans-serif";
ctx.fillText(subtitle, tempCanvas.width / 2, 45);
}
}
// Draw chart onto temp canvas
ctx.drawImage(canvas, 0, extraHeight);
// Generate filename
let filename = exportOptions.filename || "chart";
// Add timestamp if requested
if (exportOptions.includeTimestamp) {
const now = new Date();
const timestamp = `${now.getFullYear()}-${(now.getMonth() + 1).toString().padStart(2, "0")}-${now.getDate().toString().padStart(2, "0")}_${now.getHours().toString().padStart(2, "0")}-${now.getMinutes().toString().padStart(2, "0")}`;
filename = `${filename}_${timestamp}`;
}
// Convert to data URL and download
const dataUrl = tempCanvas.toDataURL(`image/${exportOptions.format || "png"}`, exportOptions.quality);
const link = document.createElement("a");
link.download = `${filename}.${exportOptions.format || "png"}`;
link.href = dataUrl;
link.click();
}, [chartRef, title, subtitle, exportOptions]);
// Expose chart methods via ref
useImperativeHandle(ref, () => ({
getChartInstance: () => chartRef.current,
exportChart: handleExport,
updateChart: () => {
if (chartRef.current) {
chartRef.current.update();
}
},
getContainerElement: () => containerRef.current,
switchChartType: type => {
handleTypeChange(type);
},
getChartState: () => ({
hoveredPoint,
selectedIndices,
chartType,
qualityTier: activeQuality
}),
forceUpdate: () => {
if (chartRef.current) {
chartRef.current.update("none");
}
}
}), [chartRef, handleExport, hoveredPoint, selectedIndices, chartType, activeQuality]);
// Prepare axis options, adjusting color for clear variant
const effectiveAxisOptions = {
...axis,
// Use a more visible grid color for the clear variant
gridColor: glassVariant === "clear" ? "rgba(var(--glass-color-black) / var(--glass-opacity-15))" // Darker, semi-transparent
: axis.gridColor || '${glassStyles.surface?.base || "var(--glass-bg-default)"}' // Original default
};
// Special case for KPI chart type
if (chartType === "kpi" && kpi) {
return jsxs(ChartContainer, {
className: cn(className, gazeResponsive && currentDataFocus && "glass-chart-gaze-focused", isPreloading && "glass-chart-preloading", adaptiveComplexity === "low" && "glass-chart-simplified", adaptiveComplexity === "high" && "glass-chart-enhanced"),
"data-preloading": isPreloading ? "true" : undefined,
"$glassVariant": glassVariant,
"$blurStrength": blurStrength,
"$color": color,
"$borderRadius": typeof borderRadius === "number" ? `${borderRadius}px` : borderRadius,
"$borderColor": borderColor,
"$elevation": getNumericElevation(elevation),
ref: containerRef,
"data-chart-type": chartType,
"data-usage-context": usageContext,
"data-consciousness-level": `${[predictive, eyeTracking, adaptive, spatialAudio].filter(Boolean).length}`,
"data-adaptive-complexity": adaptiveComplexity,
"data-insights-count": chartInsights.length,
"data-patterns-count": dataPatterns.length,
"aria-label": ariaLabelOverride ?? (ariaLabelledByOverride ? undefined : `Interactive KPI chart${title ? ` titled ${title}` : ""}${chartInsights.length > 0 ? ` with ${chartInsights.length} insights` : ""}`),
"aria-labelledby": ariaLabelledByOverride,
"aria-describedby": ariaDescribedByOverride,
role: chartRole,
...nativeContainerProps,
children: [(title || subtitle || chartInsights.length > 0) && jsxs(ChartHeader, {
children: [title && jsx(ChartTitle, {
children: title
}), subtitle && jsx(ChartSubtitle, {
children: subtitle
}), predictive && chartInsights.length > 0 && jsxs("div", {
className: 'mt-2 glass-px-3 glass-py-2 glass-radius glass-border text-primary glass-surface-primary/10 glass-contrast-guard',
"data-insights-panel": "true",
children: [jsx("strong", {
children: "\uD83D\uDCA1 KPI Insights:"
}), " ", chartInsights.slice(0, 2).map(insight => insight.title || insight.message).join(", "), chartInsights.length > 2 && ` (+${chartInsights.length - 2} more)`]
})]
}), jsx(KpiChart, {
kpi: kpi,
animation: {
enabled: enablePhysicsAnimation,
stiffness: qualityPhysicsParams.stiffness,
dampingRatio: qualityPhysicsParams.dampingRatio,
mass: qualityPhysicsParams.mass
},
qualityTier: activeQualityTier,
color: color,
isReducedMotion: isReducedMotion
})]
});
}
// Render standard chart with consciousness enhancements
return jsxs(ChartContainer, {
className: cn(className, gazeResponsive && currentDataFocus && "glass-chart-gaze-focused", isPreloading && "glass-chart-preloading", adaptiveComplexity === "low" && "glass-chart-simplified", adaptiveComplexity === "high" && "glass-chart-enhanced"),
"data-preloading": isPreloading ? "true" : undefined,
"$glassVariant": glassVariant,
"$blurStrength": blurStrength,
"$color": color,
"$borderRadius": typeof borderRadius === "number" ? `${borderRadius}px` : borderRadius,
"$borderColor": borderColor,
"$elevation": getNumericElevation(elevation),
ref: containerRef,
"data-chart-type": chartType,
"data-usage-context": usageContext,
"data-consciousness-level": `${[predictive, eyeTracking, adaptive, spatialAudio].filter(Boolean).length}`,
"data-adaptive-complexity": adaptiveComplexity,
"data-insights-count": chartInsights.length,
"data-patterns-count": dataPatterns.length,
"aria-label": ariaLabelOverride ?? (ariaLabelledByOverride ? undefined : `Interactive ${chartType} chart${title ? ` titled ${title}` : ""}${chartInsights.length > 0 ? ` with ${chartInsights.length} insights` : ""}`),
"aria-labelledby": ariaLabelledByOverride,
"aria-describedby": ariaDescribedByOverride,
role: chartRole,
...nativeContainerProps,
children: [(title || subtitle || chartInsights.length > 0) && jsxs(ChartHeader, {
children: [title && jsx(ChartTitle, {
children: title
}), subtitle && jsx(ChartSubtitle, {
children: subtitle
}), predictive && chartInsights.length > 0 && jsxs("div", {
className: 'mt-2 glass-px-3 glass-py-2 glass-radius glass-border text-primary glass-surface-primary/10 glass-contrast-guard',
"data-insights-panel": "true",
children: [jsx("strong", {
children: "\uD83D\uDCA1 Insights:"
}), " ", chartInsights.slice(0, 2).map(insight => insight.title || insight.message).join(", "), chartInsights.length > 2 && ` (+${chartInsights.length - 2} more)`]
}), biometricResponsive && adaptiveComplexity !== "medium" && jsxs("div", {
className: 'mt-1 glass-text-xs glass-text-secondary',
"data-adaptation-indicator": "true",
children: ["\uD83E\uDDE0 Adapted for ", adaptiveComplexity, " cognitive load"]
})]
}), showToolbar && jsxs(ChartToolbar, {
children: [allowTypeSwitch && jsxs(ChartTypeSelector, {
children: [jsx(TypeButton, {
type: "button",
"$active": chartType === "line",
onClick: e => handleTypeChange("line"),
children: "Line"
}), jsx(TypeButton, {
type: "button",
"$active": chartType === "bar",
onClick: e => handleTypeChange("bar"),
children: "Bar"
}), jsx(TypeButton, {
type: "button",
"$active": chartType === "area",
onClick: e => handleTypeChange("area"),
children: "Area"
}), jsx(TypeButton, {
type: "button",
"$active": chartType === "pie",
onClick: e => handleTypeChange("pie"),
children: "Pie"
})]
}), allowDownload && (renderExportButton ? renderExportButton(handleExport) : jsx(EnhancedExportButton, {
onClick: handleExport,
children: "Export"
}))]
}), legend.show && legend.position === "top" && jsx(ChartLegend, {
"$position": legend.position,
"$glassEffect": legend.glassEffect || false,
children: safeDatasets.map((dataset, index) => {
const color = dataset.style?.lineColor || palette[index % palette.length];
const isActive = selectedIndices.includes(index);
return jsxs(LegendItem, {
"$active": isActive,
children: [jsx(LegendColor, {
"$color": color,
"$active": isActive
}), jsx(LegendLabel, {
"$active": isActive,
children: dataset.label
})]
}, dataset.id || index);
})
}), jsx(ChartRenderer, {
chartType: chartType === "default" ? "line" : chartType === "minimal" ? "line" : chartType === "detailed" ? "area" : chartType === "heatmap" ? "scatter" : chartType === "radar" ? "line" : chartType,
datasets: safeDatasets,
palette: palette,
qualityTier: activeQualityTier,
animation: animation,
interaction: interaction,
axis: effectiveAxisOptions,
isReducedMotion: isReducedMotion,
springValue: getValue("chart-mount"),
enablePhysicsAnimation: enablePhysicsAnimation,
onDataPointClick: handleDataPointClick,
onChartHover: handleChartHover,
onChartLeave: handleChartLeave,
chartRefCallback: chart => chartRef.current = chart,
glassVariant: glassVariant
}), legend.show && legend.position === "bottom" && jsx(ChartLegend, {
"$position": legend.position,
"$glassEffect": legend.glassEffect || false,
children: safeDatasets.map((dataset, index) => {
const color = dataset.style?.lineColor || palette[index % palette.length];
const isActive = selectedIndices.includes(index);
return jsxs(LegendItem, {
"$active": isActive,
children: [jsx(LegendColor, {
"$color": color,
"$active": isActive
}), jsx(LegendLabel, {
"$active": isActive,
children: dataset.label
})]
}, dataset.id || index);
})
}), jsx(ChartTooltip, {
tooltipData: hoveredPoint,
datasets: safeDatasets,
color: color,
qualityTier: activeQualityTier,
tooltipStyle: (interaction.tooltipStyle === "dynamic" ? "frosted" : interaction.tooltipStyle) || "frosted",
followCursor: interaction.tooltipFollowCursor
}), currentDataFocus && gazeResponsive && jsx("div", {
className: 'glass-absolute glass-inset-0 glass-surface-primary/10 pointer-events-none glass-z-10 glass-focus glass-touch-target glass-contrast-guard',
"data-gaze-overlay": "true"
}), isPreloading && jsx("div", {
className: 'glass-absolute glass-z-50 glass-top-2 glass-left-2 glass-surface-primary text-primary glass-px-3 glass-py-2 glass-radius glass-contrast-guard',
children: "\uD83D\uDD04 Analyzing data patterns..."
}), (chartInsights.length > 0 || currentDataFocus) && jsxs("div", {
className: 'glass-absolute glass-px-2 glass-py-1 glass-surface-primary/10 text-primary glass-radius glass-z-10 glass-contrast-guard',
"data-consciousness-footer": "true",
children: [chartInsights.length > 0 && `📊 ${chartInsights.length} insights`, currentDataFocus && chartInsights.length > 0 && " | ", currentDataFocus && `Focus: S${currentDataFocus.seriesIndex + 1}P${currentDataFocus.pointIndex + 1}`]
})]
});
});
// Add display name for debugging
ModularGlassDataChart.displayName = "ModularGlassDataChart";
/**
* Enhanced ModularGlassDataChart with consciousness features enabled by default
* Use this for data-heavy charts that need intelligent insights
*/
const ConsciousModularGlassDataChart = /*#__PURE__*/React.forwardRef((props, ref) => jsx(ModularGlassDataChart, {
ref: ref,
predictive: true,
preloadData: true,
adaptive: true,
biometricResponsive: true,
trackAchievements: true,
achievementId: "conscious_modular_chart_usage",
...props
}));
ConsciousModularGlassDataChart.displayName = "ConsciousModularGlassDataChart";
/**
* Predictive ModularGlassDataChart optimized for complex data analysis
*/
const PredictiveModularGlassDataChart = /*#__PURE__*/React.forwardRef((props, ref) => jsx(ModularGlassDataChart, {
ref: ref,
predictive: true,
preloadData: true,
eyeTracking: true,
gazeResponsive: true,
trackAchievements: true,
achievementId: "predictive_modular_chart_analysis",
usageContext: "analytics",
...props
}));
PredictiveModularGlassDataChart.displayName = "PredictiveModularGlassDataChart";
/**
* Adaptive ModularGlassDataChart that responds to user cognitive load
*/
const AdaptiveModularGlassDataChart = /*#__PURE__*/React.forwardRef((props, ref) => jsx(ModularGlassDataChart, {
ref: ref,
adaptive: true,
biometricResponsive: true,
spatialAudio: true,
audioFeedback: true,
trackAchievements: true,
achievementId: "adaptive_modular_chart_usage",
...props
}));
AdaptiveModularGlassDataChart.displayName = "AdaptiveModularGlassDataChart";
/**
* Immersive ModularGlassDataChart for dashboard and presentation contexts
*/
const ImmersiveModularGlassDataChart = /*#__PURE__*/React.forwardRef((props, ref) => jsx(ModularGlassDataChart, {
ref: ref,
predictive: true,
preloadData: true,
eyeTracking: true,
gazeResponsive: true,
adaptive: true,
biometricResponsive: true,
spatialAudio: true,
audioFeedback: true,
trackAchievements: true,
achievementId: "immersive_modular_chart_experience",
usageContext: "dashboard",
...props
}));
ImmersiveModularGlassDataChart.displayName = "ImmersiveModularGlassDataChart";
/**
* Pre-configured consciousness modular chart presets
*/
const ModularChartConsciousnessPresets = {
/**
* Minimal consciousness features for performance-sensitive modular charts
*/
minimal: {
predictive: true,
trackAchievements: true
},
/**
* Balanced consciousness features for general modular chart usage
*/
balanced: {
predictive: true,
adaptive: true,
biometricResponsive: true,
trackAchievements: true
},
/**
* Full consciousness features for immersive modular chart experiences
*/
immersive: {
predictive: true,
preloadData: true,
eyeTracking: true,
gazeResponsive: true,
adaptive: true,
biometricResponsive: true,
spatialAudio: true,
audioFeedback: true,
trackAchievements: true
},
/**
* Analytics-focused consciousness features for data exploration
*/
analytics: {
predictive: true,
preloadData: true,
eyeTracking: true,
gazeResponsive: true,
trackAchievements: true,
usageContext: "analytics"
}
};
export { AdaptiveModularGlassDataChart, ConsciousModularGlassDataChart, ImmersiveModularGlassDataChart, ModularChartConsciousnessPresets, ModularGlassDataChart, PredictiveModularGlassDataChart, ModularGlassDataChart as default };
//# sourceMappingURL=ModularGlassDataChart.js.map