chird / meteoJS

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

add only one isotherm line inside thermodynamicDiagram and move it by mouse #63

Closed HadjerSahariYassir closed 2 years ago

HadjerSahariYassir commented 2 years ago

Hi Chird , i should make isotherms one isotherm moved by hovering.

please, is that possible by this library?. otherwise what you suppose?

Thanks soooo much for help many times

chird commented 2 years ago

Hi hadjersh97,

You have to code it yourself. Via the diagram property, you have access to the thermodynamic diagram. And then via the svgNode property access to its SVG. I suggest to create a new group. This way you can add and remove lines in the SVG without modifying the other parts.

The diagram fires a mouse move event. It passes the pressure and air temperature at the position of the mouse pointer.

Futhermore with the coordinateSystem property, you can access the coordinate system and its conversion functions. The getXByYT(y, T) and the getYByXT(x, T) should do the further work if the isotherms are straight lines. (see the API docs)

I haven't tested the following code. But I would start with something like this:

const diagram = new ThermodynamicDiagram({
  renderTo
});
const group = diagram.diagram.svg.group();
const tdDiagram = diagram.diagram;
tdDiagram.on('mousemove', (p, T) => {
  group.clear();

  const y0 = tdDiagram.getYByXT(0, T);
  const y1 = tdDiagram.getYByXT(tdDiagram.width, T);
  const x0 = tdDiagram.getXByYT(0, T);
  const x1 = tdDiagram.getXByYT(tdDiagram.height, T);

  // and then draw a SVG-line in "group" from (x0,y0) to (x1,y1)
});

I hope this helps. Cheers.

HadjerSahariYassir commented 2 years ago

Hi Chird, Thanks for the proposition, actually that what i was doing. i have tried your suggestion , inside mousemove function i did : 1- i have tested if the new group doesn't exist before, otherwise i remove it. 2- i have created the new group. 3- then ,i created the new line with the coordinations that you gived in the answer , but T (parametere ) shows error is not defined then i replaced T by p.diagramTmpk.


tdTermo.diagram.on("mousemove", (p) => {
....
            let T = p.diagramTmpk;
            const y0 = tdDiagram.coordinateSystem.getYByXT(0, T);
            const y1 = tdDiagram.coordinateSystem.getYByXT(tdDiagram.width, T);
            const x0 = tdDiagram.coordinateSystem.getXByYT(0, T);
            const x1 = tdDiagram.coordinateSystem.getXByYT(tdDiagram.height, T);
.....

4- i appended the new line to the new group then i put the new group to tdTermo.diagram.svgGroups.isotherms.node

the issue now the isotherm line is not in same parallelism as isotherms, it means the line is inversed . so i guess the problem is in coordinations no?

chird commented 2 years ago

Hi hadjersh97,

I just wanted to know myself, how I have to implement it. Here is my tested code:

  const diagram = new meteoJS.ThermodynamicDiagram({
    renderTo
  });
  const tdDiagram = diagram.diagram;
  const hoverIsothermGroup = tdDiagram.svgNode.group();
  tdDiagram.on('mousemove', ({ diagramTmpk }) => {
    hoverIsothermGroup.clear();

    const y0 = tdDiagram.coordinateSystem.getYByXT(0, diagramTmpk);
    const y1 = tdDiagram.coordinateSystem.getYByXT(tdDiagram.width, diagramTmpk);

    hoverIsothermGroup.line(0, tdDiagram.height - y0, tdDiagram.width, tdDiagram.height - y1).stroke({ width: 1, color: 'red' });
  });

The misalignment stems from the inverse y axis between my coordinate system and the SVG coordinates. And, of course, the line must extend from left to right.

Probably, the animation would be smoother if you just move the line instead of redrawing it. And with my code, parts of the line are hidden. Specifically, the parts below and above the diagram. This could also be better solved in the code.

HadjerSahariYassir commented 2 years ago

isother3

hi again Chird, always the same , i tried your previous coordination , and as u see in the picture i got the new drawn line which is represented with the red one , but i want something same parallelism like the black line (an isotherm) .

for the animaton yes, it would be better as u said if i just move the line instead of hoveing over the diagram. like isobar. i guess this need another solution.

Thaanks a lot for your help .

chird commented 2 years ago

Could you post your code? Its strange because my code worked correctly.

Moving the line shouldn't be too complicated. I use this library: https://svgjs.dev/docs/3.0/ I think the "manipulating" chapter will give the solution.

HadjerSahariYassir commented 2 years ago

yes it's working now thanks so much it was my fault.

const plotIsothermLine = (tdTermo) => { 
      const tdGroup = tdTermo.diagram.svgNode.group();
      const tdDiagram = tdTermo.diagram;
      tdTermo.diagram.on("mousemove", (p) => {
         tdGroup.clear();
         let T = p.diagramTmpk;
        const y0 = tdDiagram.coordinateSystem.getYByXT(0, T);
        const y1 = tdDiagram.coordinateSystem.getYByXT(tdDiagram.width, T);
        tdGroup.line(0, tdDiagram.height - y0, tdDiagram.width, tdDiagram.height - y1).stroke({ width: 1, color: 'red' });

      })

    }

thanks for this link https://svgjs.dev/docs/3.0/ i'll read it.