Search Unity

How can I Plot a graph in a Editor window with UIElements?

Discussion in 'UI Toolkit' started by Sangemdoko, Aug 23, 2019.

  1. Sangemdoko

    Sangemdoko

    Joined:
    Dec 15, 2013
    Posts:
    222
    Hi,

    I've done some research and I can't find a way to draw a plot in an editor window. I would like to plot a long set of data (an array of floats with a few thousand elements) which I could zoom and scroll through. I would like to have the plot in the same window as the rest of my editor UI as I would like to show and maybe edit some data as I am scrolling through the plot.

    Something similar to the curve panel of the animation Curve edit window would be great. Or if there was a way to simply draw lines/Curves in the content of a graphView that would also work.

    Does anyone have any suggestions, on how I could achieve that?
     
  2. uDamian

    uDamian

    Unity Technologies

    Joined:
    Dec 11, 2017
    Posts:
    1,231
  3. Sangemdoko

    Sangemdoko

    Joined:
    Dec 15, 2013
    Posts:
    222
    Thank you! I want the GUI to work for 2019.1 so I am now using ImmediateModeElement and GL to draw the plot.

    I have a class that inherits ImmediateModeElement and in ImmediateRepaint I use the GL calls to draw my line. This is the first time I use GL so I'm not sure if the calls are correct but it seems to work (Code at the end).

    My question now is how can I plot the element so that it fits its visualElement container? Is there a way to get the length/width of a visualElement dynamically? As in if my element has a style of flex-grow with flex direction row, how can I know its width in pixel at any time?

    My layout would look like:

    1 | plot (flex-grow) | 2
    1 | --------------------- | 2
    1 | The rest (flex-grow) | 2

    essentially having the plot in the center top and two bands with a fixed size on each side.

    Here is the code for Drawing the plot in a 100x100 pixel box for 100 data points (m_graph):
    Code (CSharp):
    1. void GLDrawPlot()
    2.     {
    3.         int W = 100;
    4.         int H = 100;
    5.  
    6.         AssignArray();
    7.         CreateLineMaterial();
    8.         lineMaterial.SetPass(0);
    9.  
    10.         GL.PushMatrix();
    11.         GL.LoadPixelMatrix();
    12.  
    13.         GL.Begin(GL.LINES);
    14.  
    15.         GL.Color(Color.yellow);
    16.  
    17.         for (int x = 0; x < W; x++) {
    18.            
    19.             float y = Mathf.InverseLerp(m_Max, m_Min, m_Graph[x]);
    20.  
    21.             int yPix = (int) (y * H);
    22.  
    23.             Plot(x, yPix);
    24.            
    25.         }
    26.  
    27.         GL.End();
    28.  
    29.         GL.PopMatrix();
    30.     }
    31.  
    32.     // plot an X
    33.     void Plot( float x, float y )
    34.     {
    35.         // first line of X
    36.         GL.Vertex3( x-1, y-1, 0 );
    37.         GL.Vertex3( x+1, y+1, 0 );
    38.  
    39.         // second
    40.         GL.Vertex3( x-1, y+1, 0 );
    41.         GL.Vertex3( x+1, y-1, 0 );
    42.     }
     
  4. antoine-unity

    antoine-unity

    Unity Technologies

    Joined:
    Sep 10, 2015
    Posts:
    780
    You can use
    element.resolvedStyle.width
    and
    .height
    .
     
  5. tonycoculuzzi

    tonycoculuzzi

    Joined:
    Jun 2, 2011
    Posts:
    301
    it'd be great if the mesh created with generateVisualContent could be modified with USS properties, like color, etc.

    for example: creating visual content with generateVisualContent, and then coloring the mesh red through a USS class, and changing the color with a :hover rule, instead of through Vertex.tint