chird / meteoJS

Javascript Library for meteorological and atmospheric tools
Apache License 2.0
25 stars 6 forks source link

make isobar isotherm, ..lines dragable #69

Closed HadjerSahariYassir closed 1 year ago

HadjerSahariYassir commented 1 year ago

Hi Chird,

hope you're fine, it's me again lol , trying to move 5 sorts of lines ( isobar, isotherm, mixingRatio, dryDiabats, pseudoaDiabats).

i made the five lines moved following your suggestion of last time and also the code of plot of each sort of line. i did some changes : ( i create the line at a specific position then when clicked the line, i followed the mouse mouvement then when the mouseup is fired on the line it will stoped moving). but using this logic make my application blocked because of firing the events and also, the detection of the line to move is difficult here one function that make isotherm moved and i followed the same logic for the other lines:

const draw = (tdTermo, line) => {
    const tdGroup = tdTermo.diagram.svgNode.group();
    const tdDiagram = tdTermo.diagram;
    if (firstTime) {
      line = tdGroup
        .line(0, 839.8933448791504, 803.88, 36.013344879150395)
        .stroke({ width: 3, color: "red" });
      firstTime = false;
    }
    line.on("click", () => {
      out = false;
      tdTermo.diagram.on("mousemove", (p) => {
        if (!out) {
          tdGroup.clear();
          let T = p.diagramTmpk;
          const y0 = tdDiagram.coordinateSystem.getYByXT(0, T);
          const y1 = tdDiagram.coordinateSystem.getYByXT(tdDiagram.width, T);
          line2 = tdGroup
            .line(
              0,
              tdDiagram.height - y0,
              tdDiagram.width,
              tdDiagram.height - y1
            )
            .stroke({ width: 3, color: "green" });
        }
        line2.on("mouseup", () => {
          out = true;
        });
        line2.on("click", () => {
          draw(tdTermo, line2);
        });
      });
    });
  }

so what i need is to create a line at specific place on the diagram then drag the line wating your help , Thanks

chird commented 1 year ago

Hi hadjersh97, I finally find the time to reply to you. The 'click' event stands for a connected mousedown/mouseup event. So you have to use the mousedown/mousemove/mouseup events. In your case, each click adds a new mousemove event listener. And after that every mouse movement adds again event listeners (namely the mouseup and click events). So you have hundreds of event listeners in no time and then the app blocks you. You have to add the three event listeners exactly once and then react according to the state. With the following code, a green line is displayed at the mouse pointer when the mouse button is pressed and the line is moved with the mouse pointer until the mouse button is released. I hope I can help you this way. Cheers chird.

        const tdDiagram = tdTermo.diagram;
        const svgNode = tdDiagram.svgNode.group();
        let line = undefined;
        tdDiagram.on('mousedown', e => {
          const T = e.diagramTmpk;
          const y0 = tdDiagram.coordinateSystem.getYByXT(0, T);
          const y1 = tdDiagram.coordinateSystem.getYByXT(tdDiagram.width, T);
          line = svgNode
            .line(
              0,
              tdDiagram.height - y0,
              tdDiagram.width,
              tdDiagram.height - y1
            )
            .stroke({ width: 3, color: "green" });
        });
        tdDiagram.on('mouseup', e => {
          line.remove();
          line = undefined;
        });
        tdDiagram.on('mousemove', e => {
          if (line === undefined)
            return;
          const T = e.diagramTmpk;
          const y0 = tdDiagram.coordinateSystem.getYByXT(0, T);
          const y1 = tdDiagram.coordinateSystem.getYByXT(tdDiagram.width, T);
          line
            .plot(
              0,
              tdDiagram.height - y0,
              tdDiagram.width,
              tdDiagram.height - y1
            );
        });
HadjerSahariYassir commented 1 year ago

Hi Chird,

Thanks for giving time to answer my question. I have tested your code and i understand your suggestion it's good, but what i'm supposed to do is to not remove the line when the mouse is up and i should always be able to click the line again and moved it . (something similar to drag the line). My best regards.

chird commented 1 year ago

Ok, I see your point. But then it's more a question about the SVG.js library and not about meteoJS. You have access to it via the svgNode property. You should not delete the line after the mouseup event and have to add a separate mousedown event (only once!) to the line when you create it. But this handling goes over the scope of meteoJS and is a pure SVG problem. But you have to calculate the temperature in Kelvin from the mouse coordinates. For this you can use the function getTByXY. Best regards.

HadjerSahariYassir commented 1 year ago

Exactly, yes i tried to do that few days ago, i have seen that i need to calculate Temperature using this function getTBYXY() , just a question the parameters X and Y here what represent exactly like properties of the mouse event : are they (event.x , event.y) or (event.clientX, event.clientY) ...? (event) => { T =diagram.coordinateSystem.getTByXY(event.x, diagram.coordinateSystem.height - event.y); }

chird commented 1 year ago

I use the following code:

        let svgNode = tdTermo.diagram.svgNode;
        svgNode.on('mousemove', e => {
          const point = svgNode.point(
            e.pageX - window.pageXOffset,
            e.pageY - window.pageYOffset);
          const T = tdTermo.diagram.coordinateSystem.getTByXY(
            point.x,
            tdTermo.diagram.coordinateSystem.height - point.y
          );
        });