JSXGraph library: startResizeObserver() doesn't work

39 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 answers

0
Alfred Wassermann 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?