JSXGraph library: startResizeObserver() doesn't work

66 Views Asked by At

Need to adjust vectors position on JSXGraph number line while resizing a browser screen. Think to utilize in-build method startResizeObserver() to get a tick height and then recalculate vectors y-coordinate. But came that startResizeObserver doesn't work at all. Please, any suggestions. thank you!

// Here is my board with resize attribute:

brdRef.current = JSXGraph.initBoard(id, {
      boundingbox: [topLeftX, topLeftY, bottomRightX, bottomRightY],
      resize: { enabled: true, throttle: 500 },
    });

  useEffect(() => {
    if (brdRef.current) {
      console.log('startResizeObserver useEffect started');
      brdRef.current.startResizeObserver();
      brdRef.current.on('resize', divResized);
    }

    return () => {
      if (brdRef.current) {
        brdRef.current.off('resize', divResized);
      }
    };
  }, []);

// my divResized method to get a tick height

  const divResized = () => {
    if (!divRef.current) return;
    const svgElement = divRef.current.querySelector('svg');
    if (svgElement) {
      const rect = svgElement.getBoundingClientRect();
      const svgHeight = rect.height;
           if (brdRef.current) {
             tickHeightRef.current = svgHeight / (Math.abs(boundingBox.topLeftY) +          Math.abs(boundingBox.bottomRightY));
              }
      const arrowKeys = Object.keys(brdRef.current.objects).filter(key => {
        const obj: BoardObject = brdRef.current.objects[key];
        return obj.elType === 'arrow';
      });
      arrowKeys.forEach(arrowKey => {
        const vectorObj = brdRef.current.objects[arrowKey];
        console.log('vectorObj', vectorObj);
        if (vectorMethodsRef.current) {
          vectorMethodsRef.current.adjustPointYPosition(vectorObj, tickHeightRef.current);
        }
      });
      brdRef.current.update();
    }
  };
1

There are 1 best solutions below

0
On

Usually, the integrated ResizeObserver of JSXGraph should work quite stable. However in your case, it is advisable to start your own ResizeOserver. This can be done like this:

  1. Create a JSXGraph board and a vector:
const board = JXG.JSXGraph.initBoard('jxgbox', { 
    boundingbox: [-5, 5, 5, -5], axis:true
});

// Vector at an initial position
var v1 = board.create('arrow', [[-3, 0], [2, 2]]);
  1. Start a resizeObserver on the div that hosts the board:
var myResizeOb = new ResizeObserver(function (entries) {
   // Do something as reaction to a resize event
});

myResizeOb.observe(board.containerObj);
  1. Here is a full example in which the vector is positioned using pixel coordinates that depend on the width of the hosting div:
const board = JXG.JSXGraph.initBoard('jxgbox', { 
    boundingbox: [-5, 5, 5, -5], axis:true
});

// Vector at an initial position
var v1 = board.create('arrow', [[-3, 0], [2, 2]]);

// Reposition the vector
var myResizeOb = new ResizeObserver(function (entries) {
  var id, el, lst;

  // Select all arrow elements
  lst = board.select({
    elType: 'arrow'
  });
  
  // Do something with each arrow element:
  for (id in lst.elements) {
    el = lst.elements[id];
    el.point1.setPositionDirectly(JXG.COORDS_BY_SCREEN, 
        [20, 100]);
    el.point2.setPositionDirectly(JXG.COORDS_BY_SCREEN, 
      [board.canvasWidth - 20, 200]);
  }
});

myResizeOb.observe(board.containerObj);

See it live at https://jsfiddle.net/8nvL5og4/3/. The question is if you can achieve your desired functionality with JSXGraph internal methods?