diff --git a/frontend/src/components/membershipFunction/Chart.jsx b/frontend/src/components/membershipFunction/Chart.jsx
index ac96c84..7c0134b 100644
--- a/frontend/src/components/membershipFunction/Chart.jsx
+++ b/frontend/src/components/membershipFunction/Chart.jsx
@@ -1,7 +1,7 @@
import React from 'react';
import { ComposedChart, Line, XAxis, YAxis, CartesianGrid, ReferenceArea, ReferenceLine, ResponsiveContainer, Tooltip } from 'recharts';
-export default function MembershipFunctionChart({ baseScale, mfDefinitions, selectedTerm, colors }) {
+export default function Chart({ baseScale, mfDefinitions, selectedTerm, colors }) {
const scaleKeys = Object.keys(baseScale);
return (
diff --git a/frontend/src/components/membershipFunction/Controls.jsx b/frontend/src/components/membershipFunction/Controls.jsx
index 6457562..9b653ae 100644
--- a/frontend/src/components/membershipFunction/Controls.jsx
+++ b/frontend/src/components/membershipFunction/Controls.jsx
@@ -1,19 +1,23 @@
-import React from 'react';
-
-export default function MembershipFunctionControls({ selectedTerm, currentMf, selectedColor, baseScale, updateCurrentMf }) {
+export default function Controls({ selectedTerm, currentMf, selectedColor, baseScale, mfDefinitions, updateCurrentMf }) {
if (!selectedTerm || !currentMf) return null;
const scaleKeys = Object.keys(baseScale);
const selectedIndex = scaleKeys.indexOf(selectedTerm);
- let minBound = 0;
- let maxBound = 1;
+ let prevCoreEnd = 0;
+ let prevSupportEnd = 0;
+ let nextCoreStart = 1;
+ let nextSupportStart = 1;
if (selectedIndex > 0) {
- minBound = baseScale[scaleKeys[selectedIndex - 1]];
+ const prevTerm = scaleKeys[selectedIndex - 1];
+ prevCoreEnd = mfDefinitions[prevTerm].coreEnd;
+ prevSupportEnd = mfDefinitions[prevTerm].supportEnd;
}
- if (selectedIndex >= 0 && selectedIndex < scaleKeys.length - 1) {
- maxBound = baseScale[scaleKeys[selectedIndex + 1]];
+ if (selectedIndex < scaleKeys.length - 1) {
+ const nextTerm = scaleKeys[selectedIndex + 1];
+ nextCoreStart = mfDefinitions[nextTerm].coreStart;
+ nextSupportStart = mfDefinitions[nextTerm].supportStart;
}
return (
@@ -25,35 +29,41 @@ export default function MembershipFunctionControls({ selectedTerm, currentMf, se
+ {/* Columna izquierda: Inicios */}
+ {/* Columna derecha: Fines */}
diff --git a/frontend/src/pages/AdvancedMode.jsx b/frontend/src/pages/AdvancedMode.jsx
index 9119856..fb0b57b 100644
--- a/frontend/src/pages/AdvancedMode.jsx
+++ b/frontend/src/pages/AdvancedMode.jsx
@@ -3,8 +3,8 @@ import CriterionInput from '../components/CriterionInput';
import CardEditor from '../components/CardEditor';
import BlankCardsCounter from '../components/BlankCardsCounter';
import AddLevelButton from '../components/AddLevelButton';
-import MembershipFunctionChart from '../components/membershipFunction/Chart';
-import MembershipFunctionControls from '../components/membershipFunction/Controls';
+import Chart from '../components/membershipFunction/Chart';
+import Controls from '../components/membershipFunction/Controls';
import { calculateValueFunction } from '../services/docService';
const COLORS = ['#ef4444', '#f59e0b', '#10b981', '#3b82f6', '#d946ef', '#06b6d4', '#8b5cf6', '#f43f5e', '#6366f1'];
@@ -24,7 +24,7 @@ export default function AdvancedMode() {
const [selectedTerm, setSelectedTerm] = useState(null);
const [mfDefinitions, setMfDefinitions] = useState({});
- // --- Manejadores de Escala ---
+ // Manejadores de Escala
const handleCriterionChange = (val) => { setCriterionName(val); if (errors.criterion) setErrors({ ...errors, criterion: false }); };
const handleLevelChange = (index, newValue) => { const newLevels = [...levels]; newLevels[index] = newValue; setLevels(newLevels); if (errors.levels[index]) setErrors({ ...errors, levels: errors.levels.map((e, i) => i === index ? false : e) }); };
const handleAddLevel = () => { setLevels([...levels, '']); setBlankCards([...blankCards, 0]); setErrors({ ...errors, levels: [...errors.levels, false] }); };
@@ -32,9 +32,11 @@ export default function AdvancedMode() {
const handleBlankCardChange = (index, delta) => { const newCards = [...blankCards]; if (newCards[index] + delta >= 0) { newCards[index] += delta; setBlankCards(newCards); } };
const handleGenerateBaseScale = async () => {
- let hasError = false;
const newErrors = { criterion: !criterionName.trim(), levels: levels.map(l => !l.trim()) };
- if (newErrors.criterion || newErrors.levels.includes(true)) { setErrors(newErrors); return alert("Por favor, rellena todos los campos."); }
+ if (newErrors.criterion || newErrors.levels.includes(true)) {
+ setErrors(newErrors);
+ return alert("Por favor, rellena todos los campos.");
+ }
setIsLoading(true);
try {
@@ -51,17 +53,38 @@ export default function AdvancedMode() {
} catch (error) { alert("Error: " + error); } finally { setIsLoading(false); }
};
- // --- Manejadores de Franjas ---
+ // Manejadores de Franjas
const updateCurrentMf = (field, value) => {
if (!selectedTerm) return;
- const numValue = parseFloat(value);
+ let numValue = parseFloat(value);
setMfDefinitions(prev => {
+ const scaleKeys = Object.keys(baseScale);
+ const selectedIndex = scaleKeys.indexOf(selectedTerm);
+
+ let prevCoreEnd = 0, prevSupportEnd = 0, nextCoreStart = 1, nextSupportStart = 1;
+
+ if (selectedIndex > 0) {
+ prevCoreEnd = prev[scaleKeys[selectedIndex - 1]].coreEnd;
+ prevSupportEnd = prev[scaleKeys[selectedIndex - 1]].supportEnd;
+ }
+ if (selectedIndex < scaleKeys.length - 1) {
+ nextCoreStart = prev[scaleKeys[selectedIndex + 1]].coreStart;
+ nextSupportStart = prev[scaleKeys[selectedIndex + 1]].supportStart;
+ }
+
+ if (field === 'supportStart' && numValue < prevCoreEnd) numValue = prevCoreEnd;
+ if (field === 'coreStart' && numValue < prevSupportEnd) numValue = prevSupportEnd;
+ if (field === 'coreEnd' && numValue > nextSupportStart) numValue = nextSupportStart;
+ if (field === 'supportEnd' && numValue > nextCoreStart) numValue = nextCoreStart;
+
const current = { ...prev[selectedTerm], [field]: numValue };
+
if (field === 'supportStart' && current.supportStart > current.coreStart) current.coreStart = current.supportStart;
if (field === 'coreStart') { if (current.coreStart < current.supportStart) current.supportStart = current.coreStart; if (current.coreStart > current.coreEnd) current.coreEnd = current.coreStart; }
if (field === 'coreEnd') { if (current.coreEnd < current.coreStart) current.coreStart = current.coreEnd; if (current.coreEnd > current.supportEnd) current.supportEnd = current.coreEnd; }
if (field === 'supportEnd' && current.supportEnd < current.coreEnd) current.coreEnd = current.supportEnd;
+
return { ...prev, [selectedTerm]: current };
});
};
@@ -75,6 +98,7 @@ export default function AdvancedMode() {
const scaleKeys = Object.keys(baseScale);
const selectedColor = COLORS[scaleKeys.indexOf(selectedTerm) % COLORS.length] || '#2563eb';
+
return (
@@ -122,10 +146,16 @@ export default function AdvancedMode() {
})}
-
-
-
+
+