fix: arreglar leyenda, utilizar colores importados desde config en step2 y step3

This commit is contained in:
Alexis
2026-03-27 13:47:55 +01:00
parent 89ebf99c7f
commit 46250af1eb
2 changed files with 114 additions and 82 deletions
@@ -1,11 +1,21 @@
import Chart from '../membershipFunction/Chart'; import Chart from '../membershipFunction/Chart';
import Controls from '../membershipFunction/Controls'; import Controls from '../membershipFunction/Controls';
import { CHART_COLORS } from '../../config';
const COLORS = ['#ef4444', '#f59e0b', '#10b981', '#3b82f6', '#d946ef', '#06b6d4', '#8b5cf6', '#f43f5e', '#6366f1']; export default function Step2FuzzyModeling({
baseScale,
export default function Step2FuzzyModeling({baseScale, mfDefinitions, selectedTerm, setSelectedTerm, updateCurrentMf, handleFinalSubmit, onBack, subscales, onOpenSubscale}) { mfDefinitions,
selectedTerm,
setSelectedTerm,
updateCurrentMf,
handleFinalSubmit,
onBack,
subscales,
onOpenSubscale
}) {
const scaleKeys = Object.keys(baseScale); const scaleKeys = Object.keys(baseScale);
const selectedColor = COLORS[scaleKeys.indexOf(selectedTerm) % COLORS.length] || '#2563eb';
const selectedColor = CHART_COLORS[scaleKeys.indexOf(selectedTerm) % CHART_COLORS.length] || '#2563eb';
return ( return (
<div className="w-full bg-white p-6 rounded-2xl shadow-sm border border-slate-200 animate-fade-in relative overflow-visible"> <div className="w-full bg-white p-6 rounded-2xl shadow-sm border border-slate-200 animate-fade-in relative overflow-visible">
@@ -17,11 +27,18 @@ export default function Step2FuzzyModeling({baseScale, mfDefinitions, selectedTe
<div className="flex flex-wrap justify-center gap-3 mb-6"> <div className="flex flex-wrap justify-center gap-3 mb-6">
{scaleKeys.map((name, index) => { {scaleKeys.map((name, index) => {
const color = COLORS[index % COLORS.length];
const isSelected = selectedTerm === name; const isSelected = selectedTerm === name;
const color = CHART_COLORS[index % CHART_COLORS.length];
return ( return (
<button key={name} onClick={() => setSelectedTerm(name)} style={isSelected ? { backgroundColor: color, borderColor: color, color: '#fff' } : { borderColor: color, color: '#475569' }} className={`px-5 py-2 rounded-lg font-bold border-2 transition-all duration-300 flex flex-col items-center shadow-sm hover:shadow-md ${isSelected ? 'transform scale-105' : 'bg-white opacity-80 hover:opacity-100'}`}> <button
<span>{name}</span><span className="text-[10px] font-normal opacity-80">(X: {baseScale[name].toFixed(2)})</span> key={name}
onClick={() => setSelectedTerm(name)}
style={isSelected ? { backgroundColor: color, borderColor: color, color: '#fff' } : { borderColor: color, color: '#475569' }}
className={`px-5 py-2 rounded-lg font-bold border-2 transition-all duration-300 flex flex-col items-center shadow-sm hover:shadow-md ${isSelected ? 'transform scale-105' : 'bg-white opacity-80 hover:opacity-100'}`}
>
<span>{name}</span>
<span className="text-[10px] font-normal opacity-80">(X: {baseScale[name].toFixed(2)})</span>
</button> </button>
); );
})} })}
@@ -31,7 +48,7 @@ export default function Step2FuzzyModeling({baseScale, mfDefinitions, selectedTe
baseScale={baseScale} baseScale={baseScale}
mfDefinitions={mfDefinitions} mfDefinitions={mfDefinitions}
selectedTerm={selectedTerm} selectedTerm={selectedTerm}
colors={COLORS} colors={CHART_COLORS}
/> />
<Controls <Controls
@@ -46,11 +63,10 @@ export default function Step2FuzzyModeling({baseScale, mfDefinitions, selectedTe
/> />
<div className="w-full mt-8 flex justify-center"> <div className="w-full mt-8 flex justify-center">
<button onClick={handleFinalSubmit} className="px-10 py-3 bg-slate-900 text-white text-lg font-bold rounded-xl shadow-md hover:bg-black hover:shadow-lg transition-all"> <button onClick={handleFinalSubmit} className="px-10 py-3 bg-slate-900 text-white text-lg font-bold rounded-xl shadow-md hover:bg-slate-800 transition-colors">
Guardar Todo el Espectro Difuso Guardar Todo el Espectro Difuso
</button> </button>
</div> </div>
</div> </div>
); );
} }
@@ -1,30 +1,36 @@
import { import { useMemo } from 'react';
LineChart, Line, XAxis, YAxis, CartesianGrid, Tooltip, Legend, ResponsiveContainer import { LineChart, Line, XAxis, YAxis, CartesianGrid, Tooltip, ResponsiveContainer } from 'recharts';
} from 'recharts';
import { CHART_COLORS } from '../../config'; import { CHART_COLORS } from '../../config';
const Step3FinalGraph = ({ data }) => { const Step3FinalGraph = ({ data }) => {
if (!data || !data.results) return <p>Cargando gráfico final...</p>; const sortedResults = useMemo(() => {
if (!data || !data.results) return [];
const resultsWithOriginalIndex = data.results.map((item, index) => ({ const withPermanentColors = data.results.map((item, index) => ({
...item, ...item,
originalIndex: index color: CHART_COLORS[index % CHART_COLORS.length]
})); }));
const sortedResults = [...resultsWithOriginalIndex].sort((a, b) => { return withPermanentColors.sort((a, b) => {
const valA = a.core ? a.core[0] : 0; const coreA = Array.isArray(a.core) ? Number(a.core[0]) : 0;
const valB = b.core ? b.core[0] : 0; const coreB = Array.isArray(b.core) ? Number(b.core[0]) : 0;
return valA - valB; return coreA - coreB;
}); });
}, [data]);
if (!data || !data.results) {
return <p className="text-center mt-10 text-slate-500">Cargando gráfico final...</p>;
}
return ( return (
<div className="w-full h-[500px] mt-2 bg-white p-6 rounded-2xl shadow-sm border border-slate-200"> <div className="w-full h-[550px] mt-2 bg-white p-6 rounded-2xl shadow-sm border border-slate-200 flex flex-col">
<h3 className="text-2xl font-bold mb-8 text-center text-slate-800">Espectro Difuso Final</h3> <h3 className="text-2xl font-bold mb-4 text-center text-slate-800">Espectro Difuso Final</h3>
<ResponsiveContainer width="100%" height="90%"> {/* Gráfica */}
<LineChart margin={{ top: 10, right: 30, left: 10, bottom: 40 }}> <div className="flex-1 w-full min-h-[400px]">
<ResponsiveContainer width="100%" height="100%">
<LineChart margin={{ top: 10, right: 30, left: 10, bottom: 10 }}>
<CartesianGrid strokeDasharray="3 3" opacity={0.5} vertical={false} /> <CartesianGrid strokeDasharray="3 3" opacity={0.5} vertical={false} />
<XAxis <XAxis
dataKey="x" dataKey="x"
type="number" type="number"
@@ -38,28 +44,16 @@ const Step3FinalGraph = ({ data }) => {
tickCount={6} tickCount={6}
tick={{ fill: '#475569', fontSize: 14 }} tick={{ fill: '#475569', fontSize: 14 }}
/> />
<Tooltip <Tooltip
formatter={(value, name) => [value.toFixed(3), name]} formatter={(value, name) => [Number(value).toFixed(3), name]}
labelFormatter={(label) => `X: ${Number(label).toFixed(3)}`} labelFormatter={(label) => `X: ${Number(label).toFixed(3)}`}
contentStyle={{ borderRadius: '12px', border: 'none', boxShadow: '0 10px 15px -3px rgb(0 0 0 / 0.1)' }} contentStyle={{ borderRadius: '12px', border: 'none', boxShadow: '0 10px 15px -3px rgb(0 0 0 / 0.1)' }}
/> />
<Legend
wrapperStyle={{ paddingTop: '30px' }}
iconType="circle"
payload={sortedResults.map(item => ({
id: item.term,
type: 'circle',
value: item.term.toUpperCase(),
color: CHART_COLORS[item.originalIndex % CHART_COLORS.length]
}))}
/>
{sortedResults.map((item) => { {sortedResults.map((item) => {
const lineData = [...item.left_nodes, ...item.right_nodes].map(node => ({ const lineData = [...(item.left_nodes || []), ...(item.right_nodes || [])].map(node => ({
x: node[0], x: Number(node[0]),
y: node[1] y: Number(node[1])
})); }));
return ( return (
@@ -69,7 +63,7 @@ const Step3FinalGraph = ({ data }) => {
type="linear" type="linear"
dataKey="y" dataKey="y"
name={item.term.toUpperCase()} name={item.term.toUpperCase()}
stroke={CHART_COLORS[item.originalIndex % CHART_COLORS.length]} stroke={item.color}
strokeWidth={4} strokeWidth={4}
dot={{ r: 5, strokeWidth: 2, fill: '#fff' }} dot={{ r: 5, strokeWidth: 2, fill: '#fff' }}
activeDot={{ r: 8 }} activeDot={{ r: 8 }}
@@ -81,6 +75,28 @@ const Step3FinalGraph = ({ data }) => {
</LineChart> </LineChart>
</ResponsiveContainer> </ResponsiveContainer>
</div> </div>
{/* Leyenda */}
<div className="flex flex-wrap justify-center gap-x-8 gap-y-3 mt-6 pb-2">
{sortedResults.map((item) => (
<div key={`legend-${item.term}`} className="flex items-center gap-2">
<span
className="w-3.5 h-3.5 rounded-full shadow-sm"
style={{ backgroundColor: item.color }}
/>
<span
className="text-sm font-medium uppercase tracking-wide"
style={{ color: item.color }}
>
{item.term}
</span>
</div>
))}
</div>
</div>
); );
}; };