I am a junior Frontend Developer. I need help for this issue.
I am trying to use JSXGraph with React+Vite. When I put the example codes on my React component, the height of SVG goes infinitive. Here is the code :
import { JSXGraph } from "jsxgraph";
function JSXBoard () {
const BOARDID = 'board-0';
// input data from LMS
let input = [
2, 4, // point A(x, y)
12, 6, // point B(x, y)
8, 12, // point C(x, y)
2 // unit
];
// JSXGraph board
const board = JXG.JSXGraph.initBoard(BOARDID, {
boundingbox: [0, 15, 15, 0],
axis: true,
showCopyright:true,
showNavigation:true,
});
let A = board.create('point', [input[0], input[1]], {
name: '\(A\)',
snapToGrid: true,
label: {offset: [-25, -10], fontSize: 16}
});
let B = board.create('point', [input[2], input[3]], {
name: '\(B\)',
snapToGrid: true,
label: {offset: [10, -5], fontSize: 16}
});
let C = board.create('point', [input[4], input[5]], {
name: '\(C\)',
snapToGrid: true,
label: {offset: [0, 15], fontSize: 16}
});
let ABC = board.create('polygon', [A, B, C], {
borders: {strokeWidth: 2}
});
return (
<>
</>
)
}
export default JSXBoard;
and HTML code is :
<div id="board-0-wrapper" className="jxgbox-wrapper">
<div id="board-0" className="jxgbox" data-ar="1 / 1"></div>
</div>
and plese find the codes at https://github.com/ozdilkazim/React-Structural-Engineering-Project
and the deployed version of infinite height : https://structuralengineering.netlify.app/
I have tried to convert the code to an other component and still have same issue
2
Answers
In the HTML it is not
className
, it’sclass
.className
is a React thing and is for actual JSX in the component return, and you currently have none (<></>
).That means the styles aren’t being applied and those include a
height
property on the container which will prevent this behaviour. However, that HTML shouldn’t exist outside the component anyway, so let’s shelve that for now and look at the overall approach.It is strange for a React component to reach out into DOM that exists outside of the React component itself. You really want to render that wrapping HTML in the React component and then load this "JsxGraph" library into it.
That can be done by using a ref that stores the HTML element reference for the
board-0
element and passing this toinitBoard
. We also need to wrap the initialisation in an effect so that this runs only once on mount and not on every render. We also return a cleanup function from the effect that unbinds the library if/when when the parent component is unmounted.You can also delete any HTML snippet you added after this.
It’s worth noting many graphing libs exist that are built for React.
JsxGraph
is not hence binding it to work inside a React component means you have to write the glue code like above. I don’t know if it’s an option for you but things like visx and chart.js exist, to name only a couple of many.This is a problem which is independent from react and has been noted by a few developers before:
A look at the source code shows that there is no
height
ormax-height
property set for the JSXGraph div which generates an infinite loop. Responsible for the infinite loop seems to be the combination of the CSS propertybox-sizing:box-content
and the JSXGraph board attributeresize:{enabled: true}
(the default) value.resize
adapts to JSXGraph to a change of the div size and so doesbox-sizing
. The solution is either to setheight
ormax-height
of the div or to disable resizing of JSXGraph byresize:{enabled: false}
.Regarding JSXGraph with react: there are two projects on github about this: https://github.com/sytabaresa/jsxgraph-react-js (seems to be abandoned) and https://gist.github.com/stemcstudio/3ea4e381d4595d2e022a4db2b7b20f66. An "official" wrapper would be very welcome but we, the JSXGraph, can not do that. Help from the community would be very welcome here.