From 8c19893cf7b4cfa799bc052e3710b43981dd956d Mon Sep 17 00:00:00 2001 From: Duane Nykamp Date: Mon, 3 Apr 2023 23:17:07 -0500 Subject: [PATCH] graph inside graph renders children inside parent graph (#2007) --- cypress/e2e/DoenetML/tagSpecific/graph.cy.js | 41 +++++++- src/Core/components/Graph.js | 103 +++++++++++++++++-- src/Viewer/renderers/graph.jsx | 15 +++ 3 files changed, 150 insertions(+), 9 deletions(-) diff --git a/cypress/e2e/DoenetML/tagSpecific/graph.cy.js b/cypress/e2e/DoenetML/tagSpecific/graph.cy.js index 2a9c2f0b6d..0455c4e2a4 100644 --- a/cypress/e2e/DoenetML/tagSpecific/graph.cy.js +++ b/cypress/e2e/DoenetML/tagSpecific/graph.cy.js @@ -2008,4 +2008,43 @@ describe('Graph Tag Tests', function () { }); -}); \ No newline at end of file + it('graph inside graph renders children in parent graph', () => { + cy.window().then(async (win) => { + win.postMessage({ + doenetML: ` + a + + (4,-5) + + (6,9) + + + + + + + + + $g1 + + + `}, "*"); + + cy.get('#\\/_text1').should('have.text', 'a') //wait for page to load + + // Not sure what to test as the interesting part is the graph renderer + // The only new part from core is that the inner graph ignores its xmin, etc. attributes + cy.window().then(async (win) => { + let stateVariables = await win.returnAllStateVariables1(); + expect(stateVariables["/g1inner"].stateValues.xmin).eq(-10); + expect(stateVariables["/g1inner"].stateValues.xmax).eq(10); + expect(stateVariables["/g1inner"].stateValues.ymin).eq(-10); + expect(stateVariables["/g1inner"].stateValues.ymax).eq(10); + }) + + }); + + }); + +}) \ No newline at end of file diff --git a/src/Core/components/Graph.js b/src/Core/components/Graph.js index 0a55646205..46a38d44f4 100644 --- a/src/Core/components/Graph.js +++ b/src/Core/components/Graph.js @@ -222,6 +222,10 @@ export default class Graph extends BlockComponent { group: "graphical", componentTypes: ["_graphical", "text", "image", "math", "m", "md", "label"] }, + { + group: "graphs", + componentTypes: ["graph"] + }, { group: "childrenThatShouldNotBeHere", componentTypes: ["_base"], @@ -473,19 +477,19 @@ export default class Graph extends BlockComponent { stateVariableDefinitions.childIndicesToRender = { returnDependencies: () => ({ - graphicalChildren: { + graphicalOrGraphChildren: { dependencyType: "child", - childGroups: ["graphical"], + childGroups: ["graphical", "graphs"], }, allChildren: { dependencyType: "child", - childGroups: ["graphical", "xlabels", "ylabels", "childrenThatShouldNotBeHere"], + childGroups: ["graphical", "xlabels", "ylabels", "graphs", "childrenThatShouldNotBeHere"], }, }), definition({ dependencyValues }) { let childIndicesToRender = []; - let graphicalChildNames = dependencyValues.graphicalChildren.map(x => x.componentName); + let graphicalChildNames = dependencyValues.graphicalOrGraphChildren.map(x => x.componentName); for (let [ind, child] of dependencyValues.allChildren.entries()) { if (graphicalChildNames.includes(child.componentName)) { @@ -713,6 +717,21 @@ export default class Graph extends BlockComponent { } } + stateVariableDefinitions.haveGraphParent = { + forRenderer: true, + returnDependencies: () => ({ + graphParent: { + dependencyType: "parentIdentity", + parentComponentType: "graph" + } + }), + definition({ dependencyValues }) { + return { + setValue: { haveGraphParent: dependencyValues.graphParent !== null } + } + } + } + stateVariableDefinitions.xmin = { stateVariablesDeterminingDependencies: ["identicalAxisScales", "aspectRatioFromAxisScales"], public: true, @@ -734,6 +753,11 @@ export default class Graph extends BlockComponent { xminPrelim: { dependencyType: "stateVariable", variableName: "xminPrelim" + }, + graphParentXmin: { + dependencyType: "parentStateVariable", + parentComponentType: "graph", + variableName: "xmin" } } @@ -758,6 +782,9 @@ export default class Graph extends BlockComponent { return dependencies; }, definition({ dependencyValues, usedDefault }) { + if (dependencyValues.graphParentXmin !== null) { + return { setValue: { xmin: dependencyValues.graphParentXmin } } + } if (!dependencyValues.identicalAxisScales || dependencyValues.aspectRatioFromAxisScales) { return { setValue: { xmin: dependencyValues.xminPrelim } } } @@ -794,7 +821,16 @@ export default class Graph extends BlockComponent { } }, - async inverseDefinition({ desiredStateVariableValues, stateValues }) { + async inverseDefinition({ desiredStateVariableValues, dependencyValues, stateValues }) { + if (dependencyValues.graphParentXmin !== null) { + return { + success: true, + instructions: [{ + setDependency: "graphParentXmin", + desiredValue: desiredStateVariableValues.xmin + }] + } + } if (await stateValues.fixAxes) { return { success: false } } @@ -829,6 +865,11 @@ export default class Graph extends BlockComponent { xmaxPrelim: { dependencyType: "stateVariable", variableName: "xmaxPrelim" + }, + graphParentXmax: { + dependencyType: "parentStateVariable", + parentComponentType: "graph", + variableName: "xmax" } } @@ -853,6 +894,9 @@ export default class Graph extends BlockComponent { return dependencies; }, definition({ dependencyValues, usedDefault }) { + if (dependencyValues.graphParentXmax !== null) { + return { setValue: { xmax: dependencyValues.graphParentXmax } } + } if (!dependencyValues.identicalAxisScales || dependencyValues.aspectRatioFromAxisScales) { return { setValue: { xmax: dependencyValues.xmaxPrelim } } } @@ -900,7 +944,16 @@ export default class Graph extends BlockComponent { } }, - async inverseDefinition({ desiredStateVariableValues, stateValues }) { + async inverseDefinition({ desiredStateVariableValues, dependencyValues, stateValues }) { + if (dependencyValues.graphParentXmax !== null) { + return { + success: true, + instructions: [{ + setDependency: "graphParentXmax", + desiredValue: desiredStateVariableValues.xmax + }] + } + } if (await stateValues.fixAxes) { return { success: false } } @@ -936,6 +989,11 @@ export default class Graph extends BlockComponent { yminPrelim: { dependencyType: "stateVariable", variableName: "yminPrelim" + }, + graphParentYmin: { + dependencyType: "parentStateVariable", + parentComponentType: "graph", + variableName: "ymin" } } @@ -960,6 +1018,9 @@ export default class Graph extends BlockComponent { return dependencies; }, definition({ dependencyValues, usedDefault }) { + if (dependencyValues.graphParentYmin !== null) { + return { setValue: { ymin: dependencyValues.graphParentYmin } } + } if (!dependencyValues.identicalAxisScales || dependencyValues.aspectRatioFromAxisScales) { return { setValue: { ymin: dependencyValues.yminPrelim } } } @@ -996,7 +1057,16 @@ export default class Graph extends BlockComponent { } }, - async inverseDefinition({ desiredStateVariableValues, stateValues }) { + async inverseDefinition({ desiredStateVariableValues, dependencyValues, stateValues }) { + if (dependencyValues.graphParentYmin !== null) { + return { + success: true, + instructions: [{ + setDependency: "graphParentYmin", + desiredValue: desiredStateVariableValues.ymin + }] + } + } if (await stateValues.fixAxes) { return { success: false } } @@ -1031,6 +1101,11 @@ export default class Graph extends BlockComponent { ymaxPrelim: { dependencyType: "stateVariable", variableName: "ymaxPrelim" + }, + graphParentYmax: { + dependencyType: "parentStateVariable", + parentComponentType: "graph", + variableName: "ymax" } } @@ -1055,6 +1130,9 @@ export default class Graph extends BlockComponent { return dependencies; }, definition({ dependencyValues, usedDefault }) { + if (dependencyValues.graphParentYmax !== null) { + return { setValue: { ymax: dependencyValues.graphParentYmax } } + } if (!dependencyValues.identicalAxisScales || dependencyValues.aspectRatioFromAxisScales) { return { setValue: { ymax: dependencyValues.ymaxPrelim } } } @@ -1105,7 +1183,16 @@ export default class Graph extends BlockComponent { }, - async inverseDefinition({ desiredStateVariableValues, stateValues }) { + async inverseDefinition({ desiredStateVariableValues, dependencyValues, stateValues }) { + if (dependencyValues.graphParentYmax !== null) { + return { + success: true, + instructions: [{ + setDependency: "graphParentYmax", + desiredValue: desiredStateVariableValues.ymax + }] + } + } if (await stateValues.fixAxes) { return { success: false } } diff --git a/src/Viewer/renderers/graph.jsx b/src/Viewer/renderers/graph.jsx index 1da5272493..183427cf9c 100644 --- a/src/Viewer/renderers/graph.jsx +++ b/src/Viewer/renderers/graph.jsx @@ -45,6 +45,9 @@ export default React.memo(function Graph(props) { } useEffect(() => { + if (SVs.haveGraphParent) { + return; + } return () => { callAction({ action: actions.recordVisibilityChange, @@ -55,6 +58,10 @@ export default React.memo(function Graph(props) { //Draw Board after mounting component useEffect(() => { + if (SVs.haveGraphParent) { + return; + } + let boundingbox = [SVs.xmin, SVs.ymax, SVs.xmax, SVs.ymin]; previousBoundingbox.current = boundingbox; @@ -139,6 +146,14 @@ export default React.memo(function Graph(props) { } }, [board]) + if (SVs.haveGraphParent) { + // have have graph parent, then don't render graph + // but just render children so that will be inside parent graph + return <> + + {children} + + } const divStyle = { width: sizeToCSS(SVs.width),