import { Card } from '../common/Card'; interface ParallelCoordinatesPlotProps { data: any[]; dimensions: string[]; colorBy?: string; } export const ParallelCoordinatesPlot = ({ data, dimensions }: ParallelCoordinatesPlotProps) => { // Filter out null/undefined data points const validData = data.filter(d => d && dimensions.every(dim => d[dim] !== null && d[dim] !== undefined)); if (validData.length === 0 || dimensions.length === 0) { return (
No data available for parallel coordinates
); } // Calculate min/max for each dimension for normalization const ranges = dimensions.map(dim => { const values = validData.map(d => d[dim]); return { min: Math.min(...values), max: Math.max(...values) }; }); // Normalize function const normalize = (value: number, dimIdx: number): number => { const range = ranges[dimIdx]; if (range.max === range.min) return 0.5; return (value - range.min) / (range.max - range.min); }; // Chart dimensions const width = 800; const height = 400; const margin = { top: 80, right: 20, bottom: 40, left: 20 }; const plotWidth = width - margin.left - margin.right; const plotHeight = height - margin.top - margin.bottom; const axisSpacing = plotWidth / (dimensions.length - 1); return ( {/* Draw axes */} {dimensions.map((dim, i) => { const x = i * axisSpacing; return ( {/* Axis line */} {/* Axis label */} {dim} {/* Min/max labels */} {ranges[i].min.toFixed(2)} {ranges[i].max.toFixed(2)} ); })} {/* Draw lines for each trial */} {validData.map((trial, trialIdx) => { // Build path const pathData = dimensions.map((dim, i) => { const x = i * axisSpacing; const normalizedY = normalize(trial[dim], i); const y = plotHeight * (1 - normalizedY); return i === 0 ? `M ${x} ${y}` : `L ${x} ${y}`; }).join(' '); return ( ); })} {/* Legend */}
Pareto Front
Other Solutions
); };