Spaces:
No application file
No application file
| import React from 'react'; | |
| import { LineChart, Line, XAxis, YAxis, CartesianGrid, Tooltip, ResponsiveContainer } from 'recharts'; | |
| const DataVisualization: React.FC = () => { | |
| // Generate sample data similar to your reference image | |
| const generateTimeSeriesData = () => { | |
| const data = []; | |
| for (let i = 0; i <= 15; i++) { | |
| data.push({ | |
| time: i, | |
| shoulder_pan_pos: 100 - i * 8 + Math.sin(i * 0.5) * 20, | |
| shoulder_lift_pos: -30 + Math.cos(i * 0.3) * 15, | |
| elbow_flex_pos: 50 - i * 2 + Math.sin(i * 0.8) * 10, | |
| wrist_flex_pos: 80 - i * 3 + Math.cos(i * 0.6) * 25, | |
| wrist_roll_pos: 10 + Math.sin(i * 0.4) * 8, | |
| gripper_pos: -5 + Math.cos(i * 0.2) * 12, | |
| }); | |
| } | |
| return data; | |
| }; | |
| const leftChartData = generateTimeSeriesData(); | |
| const rightChartData = generateTimeSeriesData().map(item => ({ | |
| ...item, | |
| wrist_flex_pos: item.wrist_flex_pos + 20, | |
| wrist_roll_pos: item.wrist_roll_pos - 10, | |
| gripper_pos: item.gripper_pos + 15, | |
| })); | |
| const metricsList = [ | |
| { name: 'shoulder_pan_pos', color: '#ef4444', value: '-15.33' }, | |
| { name: 'shoulder_lift_pos', color: '#22c55e', value: '-18.39' }, | |
| { name: 'elbow_flex_pos', color: '#3b82f6', value: '34.99' }, | |
| ]; | |
| const rightMetricsList = [ | |
| { name: 'wrist_flex_pos', color: '#ef4444', value: '68.87' }, | |
| { name: 'wrist_roll_pos', color: '#22c55e', value: '-4.01' }, | |
| { name: 'gripper_pos', color: '#3b82f6', value: '19.82' }, | |
| ]; | |
| return ( | |
| <div className="bg-gray-900 text-white rounded-2xl p-6 shadow-2xl"> | |
| {/* Header with observation images */} | |
| <div className="grid grid-cols-1 lg:grid-cols-2 gap-6 mb-6"> | |
| <div className="bg-gray-800 rounded-lg p-4"> | |
| <div className="flex items-center justify-between mb-2"> | |
| <h3 className="text-sm font-medium text-gray-300">observation_images_front</h3> | |
| <div className="flex gap-2"> | |
| <button className="w-4 h-4 bg-gray-600 rounded hover:bg-gray-500"></button> | |
| <button className="w-4 h-4 bg-gray-600 rounded hover:bg-gray-500">×</button> | |
| </div> | |
| </div> | |
| <div className="bg-red-200 rounded h-32 flex items-center justify-center"> | |
| <div className="text-orange-600 text-xs">📦 Dataset Sample View</div> | |
| </div> | |
| </div> | |
| <div className="bg-gray-800 rounded-lg p-4"> | |
| <div className="flex items-center justify-between mb-2"> | |
| <h3 className="text-sm font-medium text-gray-300">observation_images_side</h3> | |
| <div className="flex gap-2"> | |
| <button className="w-4 h-4 bg-gray-600 rounded hover:bg-gray-500"></button> | |
| <button className="w-4 h-4 bg-gray-600 rounded hover:bg-gray-500">×</button> | |
| </div> | |
| </div> | |
| <div className="bg-gray-200 rounded h-32 flex items-center justify-center"> | |
| <div className="text-gray-600 text-xs">🎯 Model Predictions</div> | |
| </div> | |
| </div> | |
| </div> | |
| {/* Time series charts */} | |
| <div className="grid grid-cols-1 lg:grid-cols-2 gap-6"> | |
| {/* Left Chart */} | |
| <div className="bg-gray-800 rounded-lg p-4"> | |
| <ResponsiveContainer width="100%" height={200}> | |
| <LineChart data={leftChartData}> | |
| <CartesianGrid strokeDasharray="1 1" stroke="#374151" /> | |
| <XAxis | |
| dataKey="time" | |
| axisLine={false} | |
| tickLine={false} | |
| tick={{ fontSize: 10, fill: '#9CA3AF' }} | |
| domain={[0, 15]} | |
| /> | |
| <YAxis | |
| axisLine={false} | |
| tickLine={false} | |
| tick={{ fontSize: 10, fill: '#9CA3AF' }} | |
| domain={[-100, 100]} | |
| /> | |
| <Tooltip | |
| contentStyle={{ | |
| backgroundColor: '#1F2937', | |
| border: '1px solid #374151', | |
| borderRadius: '6px', | |
| color: '#F9FAFB' | |
| }} | |
| /> | |
| <Line type="monotone" dataKey="shoulder_pan_pos" stroke="#ef4444" strokeWidth={1.5} dot={false} /> | |
| <Line type="monotone" dataKey="shoulder_lift_pos" stroke="#22c55e" strokeWidth={1.5} dot={false} /> | |
| <Line type="monotone" dataKey="elbow_flex_pos" stroke="#3b82f6" strokeWidth={1.5} dot={false} /> | |
| </LineChart> | |
| </ResponsiveContainer> | |
| {/* Metrics table */} | |
| <div className="mt-4 space-y-2"> | |
| {metricsList.map((metric, index) => ( | |
| <div key={index} className="flex items-center gap-2 text-xs"> | |
| <div className="flex items-center gap-1"> | |
| <div className="w-2 h-2 rounded-full" style={{ backgroundColor: metric.color }}></div> | |
| <span className="text-gray-300">{metric.name}</span> | |
| </div> | |
| <div className="flex gap-4"> | |
| <span className="text-gray-400">action</span> | |
| <span className="text-white">{metric.value}</span> | |
| </div> | |
| </div> | |
| ))} | |
| </div> | |
| </div> | |
| {/* Right Chart */} | |
| <div className="bg-gray-800 rounded-lg p-4"> | |
| <ResponsiveContainer width="100%" height={200}> | |
| <LineChart data={rightChartData}> | |
| <CartesianGrid strokeDasharray="1 1" stroke="#374151" /> | |
| <XAxis | |
| dataKey="time" | |
| axisLine={false} | |
| tickLine={false} | |
| tick={{ fontSize: 10, fill: '#9CA3AF' }} | |
| domain={[0, 15]} | |
| /> | |
| <YAxis | |
| axisLine={false} | |
| tickLine={false} | |
| tick={{ fontSize: 10, fill: '#9CA3AF' }} | |
| domain={[-30, 90]} | |
| /> | |
| <Tooltip | |
| contentStyle={{ | |
| backgroundColor: '#1F2937', | |
| border: '1px solid #374151', | |
| borderRadius: '6px', | |
| color: '#F9FAFB' | |
| }} | |
| /> | |
| <Line type="monotone" dataKey="wrist_flex_pos" stroke="#ef4444" strokeWidth={1.5} dot={false} /> | |
| <Line type="monotone" dataKey="wrist_roll_pos" stroke="#22c55e" strokeWidth={1.5} dot={false} /> | |
| <Line type="monotone" dataKey="gripper_pos" stroke="#3b82f6" strokeWidth={1.5} dot={false} /> | |
| </LineChart> | |
| </ResponsiveContainer> | |
| {/* Metrics table */} | |
| <div className="mt-4 space-y-2"> | |
| {rightMetricsList.map((metric, index) => ( | |
| <div key={index} className="flex items-center gap-2 text-xs"> | |
| <div className="flex items-center gap-1"> | |
| <div className="w-2 h-2 rounded-full" style={{ backgroundColor: metric.color }}></div> | |
| <span className="text-gray-300">{metric.name}</span> | |
| </div> | |
| <div className="flex gap-4"> | |
| <span className="text-gray-400">action</span> | |
| <span className="text-white">{metric.value}</span> | |
| </div> | |
| </div> | |
| ))} | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| ); | |
| }; | |
| export default DataVisualization; | |