Search Unity

[Released] Graph Maker - UGUI - NGUI - DFGUI (line graphs, bar graphs, pie graphs, etc)

Discussion in 'Assets and Asset Store' started by rorakin3, Sep 26, 2013.

  1. Sebioff

    Sebioff

    Joined:
    Dec 22, 2013
    Posts:
    218
    Hey,

    when enabling Compute Shader for Area Shading I'm getting the following exception:
     
  2. rorakin3

    rorakin3

    Joined:
    Jan 2, 2013
    Posts:
    464
    Hi there,

    Are you enabling compute shader right after instantiating graph? If so be sure to call Init() on your graph after instantiation to ensure the graph has been initialized. If that wasn't the issue feel free to email me more info / how to reproduce the error you get.
     
  3. Sebioff

    Sebioff

    Joined:
    Dec 22, 2013
    Posts:
    218
    Turns out we had some broken prefabs after updating to the latest version. All good now :)
     
  4. rorakin3

    rorakin3

    Joined:
    Jan 2, 2013
    Posts:
    464
    Ah ok, gotcha.
     
  5. rorakin3

    rorakin3

    Joined:
    Jan 2, 2013
    Posts:
    464
    The next update is coming fairly soon. So anyone feel free to email / post here any issues you find no matter how small or feature requests. Some of things that will be included:

    1. A more robust auto padding feature. The existing autoPadding feature sort of works, but could be greatly improved. The new auto padding feature will basically automatically set the left / right / top / bottom padding values and you will be able to control some things about what gets padded. Overall you will be able to use it to ensure x / y axis labels, legend, graph title, x / y axis titles fit within the borders / graph rect transform. You will also be able to control what gets included in the autopadding calculation (e.g. include legend or not).

    2. An example scene with world space graph, as well as example to subscribe the graph tooltip to a different object such as one that is in a separate screen space canvas. So that in the end you can have graph in world space and screen space tooltip.

    upload_2016-12-22_13-25-41.png

    3. A new 'pie mode' for the ring graph which can basically be used to create pie graphs, but have all the things that ring graphs have such as anti-aliased edges / labels coming the slices. The ring graph is based on procedural generated texture and thus can work at any resolution. Additionally it can use compute shader (if your building for platform that supports compute shader) for better texture update performance. There will be a new example scene that basically has something like this:

    upload_2016-12-22_13-18-37.png

    And of course there will be various fixes. You can expect next update sometime early next year. Happy holidays!
     
  6. RolfBertram_dot_me

    RolfBertram_dot_me

    Joined:
    Mar 1, 2011
    Posts:
    128
    Axis label color - can it be changed? I am using white background, which of cause makes white text and graphics invisible. I was able to change all graphics and text to black or any color, except for the axis labels (tried only bar graph so far). I just don't see the color selector for the x/y axis labels in the inspector.
     
  7. rorakin3

    rorakin3

    Joined:
    Jan 2, 2013
    Posts:
    464
    Hey, you can change the text color in the prefab Graph_Maker/Prefabs/Nodes/xAxisLabel. The next Graph Maker version has this option exposed, but not on the asset store yet. You can email me with your invoice number if you want the next version now.
     
    RolfBertram_dot_me likes this.
  8. RolfBertram_dot_me

    RolfBertram_dot_me

    Joined:
    Mar 1, 2011
    Posts:
    128
    Thanks - works!
     
  9. RolfBertram_dot_me

    RolfBertram_dot_me

    Joined:
    Mar 1, 2011
    Posts:
    128
    WMG_Data_Source script: I know this has been asked before, and I looked at the answer, but this did not help. There seems no example that uses this specific script, and no example similar to my project. I setup a graph using inspector. I tried to control the graph variables with the WMG_Data_Source script, attached to the camera, where also my own script is attached, which has the variables. I dropped the camera into the Real Time Data Source and Point Data Source fields in the WMG_Series in the inspector. What to do with the Variable Types and Variable Names fields in the WMG_Data_Source is not clear to me. And ultimately, how to get the variables in my script to control the graph is also not clear.
     
  10. rorakin3

    rorakin3

    Joined:
    Jan 2, 2013
    Posts:
    464

    So, for the WMG_Data_Source component, there are a couple main uses:

    The example at the end of the X_Dynamic example scene is the "real-time" updating. In this case a WMG_Data_Source component is linked with a variable "Transform.localPosition.x", and the graph pulls data from this variable constantly over time. In this case the x-axis is always time or "real-time" and the y-axis is the one variable being continuously graphed over time. This essentially means the source variable must be a single float (no control over the x-axis). Example of how to set this up / use it can be found in the function realTimeTests() in X_Dynamic.cs. This method is useful if you want to graph a single variable continuously, such as a Player's ammunition count in a game. There is some fairly complicated logic that determines when a data point is actually plotted with this method. Basically, the method calculates slope differentials from previous points, and if the slopes are significantly different from the point that is about to be plotted, then a new point is plotted. This is to avoid plotting excessive amounts of data which would otherwise lead to performance issues.

    The other example using WMG_Data_Source component is also in the X_Dynamic example scene. It is the "Dynamic data population via reflection". With this method the x and y axes must both be specified and can be whatever you want them to be. However in this case your data source must correspond to either a List<Vector2> or just a Vector2 if you go with the "multi-objects single variable" setting on the data source. Once the data source has been setup, then the graph's data will automatically change based on any changes made to the source data (List<Vector2> variable from an arbitrary script object, or a Vector2 on a collection of arbitrary script objects). Take a look at function dynamicDataPopulationViaReflectionTests() in X_Dynamic.cs if this is what you want to do. There isn't really anything special with setting things up with this, it just bypasses the need to write your own code to update a Series List<Vector> of pointValues. This methodology was originally created so Graph Maker could be used with PlayMaker, to essentially make a graph that automatically updates corresponding with a PlayMaker variable.

    So, that about covers WMG_Data_Source component. Another way to plot data in "real-time" is to instead use your own custom Coroutine function. The method of using Coroutine is shown in the "Plot Overtime" example scene. In this example a random value is plotted overtime continuously, however it is not difficult to modify the example to work with arbitrary data and / or to plot data very fast with no special animations in between points.
     
  11. ttomas59

    ttomas59

    Joined:
    Jul 31, 2016
    Posts:
    1
    Hello. I have version 1.3.3 and I use NGUI. I have a problem with Canvas, because all of examples are 3D objects with Transform. Is there chance to use it in canvas panel ?
    Thanks.
     
    Last edited: Jan 10, 2017
  12. rorakin3

    rorakin3

    Joined:
    Jan 2, 2013
    Posts:
    464
    Hi, please upgrade your Graph Maker version. The graphs no longer use transform component in later versions.
     
  13. RolfBertram_dot_me

    RolfBertram_dot_me

    Joined:
    Mar 1, 2011
    Posts:
    128
    Thanks for your detailed answer, which helped a lot. I almost got it working. But there is still one problem. Even though the dataProviders (as seen in inspector when running) fill the vector2List's with fresh data from Update, but the reflection to the series does not work. In inspector when changing a value in the vector2List in the series it shows in the graph. So that works. But I expected the vector2List's in the series to update with the values from the dataProvider's vector2List's. This does not happen. Can you point out what I have configured wrong in the code below?
    Code (CSharp):
    1.  
    2.     IEnumerator Graphics() {
    3.  
    4.         GameObject graphGO = GameObject.Instantiate(graphPrefab) as GameObject;
    5.         graph = graphGO.GetComponent<WMG_Axis_Graph>();
    6.  
    7.         graph.changeSpriteParent(graphGO, graphPanel);
    8.         graph.stretchToParent(graphGO);
    9.         graph.graphBackground.SetActive(false);
    10.         graph.xAxis.changeSpriteColor(graph.xAxis.AxisLine,  Color.black);
    11.         graph.yAxis.changeSpriteColor(graph.yAxis.AxisLine,  Color.black);
    12.  
    13.         graph.xAxis.hideLabels = true;
    14.         graph.yAxis.hideLabels = true;
    15.         graph.xAxis.AxisNumTicks = 5;
    16.         graph.yAxis.AxisNumTicks = 7;
    17.         graph.xAxis.hideTicks = true;
    18.         graph.yAxis.hideTicks = true;
    19.         graph.xAxis.AxisMinValue = 0f;
    20.         graph.xAxis.AxisMaxValue = 240f;
    21.         graph.yAxis.AxisMinValue = -3f;
    22.         graph.yAxis.AxisMaxValue = 3f;
    23.  
    24.         graph.axesType = WMG_Axis_Graph.axesTypes.CENTER;
    25.         graph.axisWidth = 1;
    26.  
    27.  
    28.         graph.changeSpritePositionTo(graphGO, Vector3.zero);
    29.         graph.graphTitleString = "";
    30.         graph.legend.hideLegend = true;
    31.         graph.graphType = WMG_Axis_Graph.graphTypes.line;
    32.         graph.xAxis.LabelType = WMG_Axis.labelTypes.ticks ;
    33.         graph.useGroups = true;
    34.         //series1.hidePoints = true;
    35.  
    36.         graph.autoAnimationsEnabled = false;
    37.  
    38.         WMG_Data_Source dsX = this.gameObject.AddComponent<WMG_Data_Source>();
    39.         WMG_Data_Source dsY = this.gameObject.AddComponent<WMG_Data_Source>();
    40.         WMG_Data_Source dsZ = this.gameObject.AddComponent<WMG_Data_Source>();
    41.         WMG_Data_Source dsV = this.gameObject.AddComponent<WMG_Data_Source>();
    42.  
    43.         /*
    44.         dsX.dataSourceType = WMG_Data_Source.WMG_DataSourceTypes.Multiple_Objects_Single_Variable; // in this example we'll use multiple objects
    45.         dsY.dataSourceType = WMG_Data_Source.WMG_DataSourceTypes.Multiple_Objects_Single_Variable; // in this example we'll use multiple objects
    46.         dsZ.dataSourceType = WMG_Data_Source.WMG_DataSourceTypes.Multiple_Objects_Single_Variable; // in this example we'll use multiple objects
    47.         dsV.dataSourceType = WMG_Data_Source.WMG_DataSourceTypes.Multiple_Objects_Single_Variable; // in this example we'll use multiple objects
    48.         */
    49.  
    50.         dsX.dataSourceType = WMG_Data_Source.WMG_DataSourceTypes.Single_Object_Single_Variable; //
    51.         dsY.dataSourceType = WMG_Data_Source.WMG_DataSourceTypes.Single_Object_Single_Variable; //
    52.         dsZ.dataSourceType = WMG_Data_Source.WMG_DataSourceTypes.Single_Object_Single_Variable; //
    53.         dsV.dataSourceType = WMG_Data_Source.WMG_DataSourceTypes.Single_Object_Single_Variable; //
    54.  
    55.  
    56.         /*
    57.         dsX.dataSourceType = WMG_Data_Source.WMG_DataSourceTypes.Single_Object_Multiple_Variables; //
    58.         dsY.dataSourceType = WMG_Data_Source.WMG_DataSourceTypes.Single_Object_Multiple_Variables; //
    59.         dsZ.dataSourceType = WMG_Data_Source.WMG_DataSourceTypes.Single_Object_Multiple_Variables; //
    60.         dsV.dataSourceType = WMG_Data_Source.WMG_DataSourceTypes.Single_Object_Multiple_Variables; //
    61.         */
    62.  
    63.         /*
    64.         dsX.variableType = WMG_Data_Source.WMG_VariableTypes.Field; // optional - set the variable type to slightly improve performance.
    65.         dsY.variableType = WMG_Data_Source.WMG_VariableTypes.Field; // optional - set the variable type to slightly improve performance.
    66.         dsZ.variableType = WMG_Data_Source.WMG_VariableTypes.Field; // optional - set the variable type to slightly improve performance.
    67.         dsV.variableType = WMG_Data_Source.WMG_VariableTypes.Field; // optional - set the variable type to slightly improve performance.
    68.         */
    69.  
    70.         List<GameObject> dataProviders = new List<GameObject>();
    71.         GameObject emptyObjX = new GameObject();
    72.         emptyObjX.name = "X_Data_Provider";
    73.         dataProviders.Add(emptyObjX);
    74.         WMG_X_Data_Provider dpX = emptyObjX.AddComponent<WMG_X_Data_Provider>();
    75.         dpX.vector2List = gArrayXList;
    76.         dsX.setDataProvider(dpX);
    77.  
    78.         GameObject emptyObjY = new GameObject();
    79.         emptyObjY.name = "Y_Data_Provider";
    80.         dataProviders.Add(emptyObjY);
    81.         WMG_X_Data_Provider dpY = emptyObjY.AddComponent<WMG_X_Data_Provider>();
    82.         dpY.vector2List = gArrayYList;
    83.         dsY.setDataProvider(dpY);
    84.  
    85.         GameObject emptyObjZ = new GameObject();
    86.         emptyObjZ.name = "Z_Data_Provider";
    87.         dataProviders.Add(emptyObjZ);
    88.         WMG_X_Data_Provider dpZ = emptyObjZ.AddComponent<WMG_X_Data_Provider>();
    89.         dpZ.vector2List = gArrayZList;
    90.         dsZ.setDataProvider(dpZ);
    91.  
    92.         GameObject emptyObjV = new GameObject();
    93.         emptyObjV.name = "V_Data_Provider";
    94.         dataProviders.Add(emptyObjV);
    95.         WMG_X_Data_Provider dpV = emptyObjV.AddComponent<WMG_X_Data_Provider>();
    96.         dpV.vector2List = gArrayVList;
    97.         dsV.setDataProvider(dpV);
    98.  
    99.  
    100.         // assign the data source to the series, once this happens, the series will detect that the dataSource is not null
    101.         // and attempt to pull data from data providers on the referenced data source.
    102.  
    103.         WMG_Series xPlot = graph.lineSeries[0].GetComponent<WMG_Series>();
    104.         List<Vector2> xPlotData = xPlot.pointValues.list; // just grab current data so we can reset the graph to its original state later
    105.         xPlot.pointValuesDataSource = dsX; // assign the data source to a series.
    106.  
    107.         WMG_Series yPlot = graph.lineSeries[0].GetComponent<WMG_Series>();
    108.         List<Vector2> yPlotData = yPlot.pointValues.list; // just grab current data so we can reset the graph to its original state later
    109.         yPlot.pointValuesDataSource = dsY; // assign the data source to a series.
    110.  
    111.         WMG_Series zPlot = graph.lineSeries[0].GetComponent<WMG_Series>();
    112.         List<Vector2> zPlotData = zPlot.pointValues.list; // just grab current data so we can reset the graph to its original state later
    113.         zPlot.pointValuesDataSource = dsZ; // assign the data source to a series.
    114.  
    115.         WMG_Series vPlot = graph.lineSeries[0].GetComponent<WMG_Series>();
    116.         List<Vector2> vPlotData = vPlot.pointValues.list; // just grab current data so we can reset the graph to its original state later
    117.         vPlot.pointValuesDataSource = dsV; // assign the data source to a series.
    118.  
    119.         graph.deleteSeriesAt(0);//delete prefab1series
    120.         graph.deleteSeriesAt(0);//delete prefab2series
    121.  
    122.         xPlot = graph.addSeries();
    123.         xPlot.pointColor = Color.red;
    124.         xPlot.lineColor = Color.red;
    125.         //xPlot.lineScale = 1f;
    126.         xPlot.pointWidthHeight = 0;
    127.  
    128.         yPlot = graph.addSeries();
    129.         yPlot.pointColor = Color.green;
    130.         yPlot.lineColor = Color.green;
    131.         //yPlot.lineScale = 1f;
    132.         yPlot.pointWidthHeight = 0;
    133.  
    134.         zPlot = graph.addSeries();
    135.         zPlot.pointColor = Color.blue;
    136.         zPlot.lineColor = Color.blue;
    137.         //zPlot.lineScale = 1f;
    138.         zPlot.pointWidthHeight = 0;
    139.  
    140.         vPlot = graph.addSeries();
    141.         vPlot.pointColor = Color.black;
    142.         vPlot.lineColor = Color.black;
    143.         //vPlot.lineScale = 1f;
    144.         vPlot.pointWidthHeight = 0;
    145.  
    146.  
    147.         //draws plots directly  (not using Reflection) with initial data:
    148.         xPlot.pointValues.SetList(gArrayXList);
    149.         yPlot.pointValues.SetList(gArrayYList);
    150.         zPlot.pointValues.SetList(gArrayZList);
    151.         vPlot.pointValues.SetList(gArrayVList);
    152.  
    153.  
    154.         dsX.setVariableName("vector2List"); // set the variable name on the data source which matches the Vector2 on the data provider which we are interested in graphing
    155.         //dsX.variableType = WMG_Data_Source.WMG_VariableTypes.Field; // optional - set the variable type to slightly improve performance.
    156.  
    157.         dsY.setVariableName("vector2List"); // set the variable name on the data source which matches the Vector2 on the data provider which we are interested in graphing
    158.         //dsY.variableType = WMG_Data_Source.WMG_VariableTypes.Field; // optional - set the variable type to slightly improve performance.
    159.  
    160.         dsZ.setVariableName("vector2List"); // set the variable name on the data source which matches the Vector2 on the data provider which we are interested in graphing
    161.         //dsZ.variableType = WMG_Data_Source.WMG_VariableTypes.Field; // optional - set the variable type to slightly improve performance.
    162.  
    163.         dsV.setVariableName("vector2List"); // set the variable name on the data source which matches the Vector2 on the data provider which we are interested in graphing
    164.         //dsV.variableType = WMG_Data_Source.WMG_VariableTypes.Field; // optional - set the variable type to slightly improve performance.
    165.  
    166.  
    167.         // dp filled by Update
    168.         dpX.GetComponent<WMG_X_Data_Provider>().vector2List = gArrayXList;
    169.         dpY.GetComponent<WMG_X_Data_Provider>().vector2List = gArrayYList;
    170.         dpZ.GetComponent<WMG_X_Data_Provider>().vector2List = gArrayZList;
    171.         dpV.GetComponent<WMG_X_Data_Provider>().vector2List = gArrayVList;
    172.         // now if data changes occur on the data provider(s), the changes will be automatically applied to the graph:
    173.         //Not working. It fills the dataProvider's vector2List's, but reflection to series does not work.
    174.  
    175.         bool done = true;
    176.         yield return done;
    177.     }
    178.  
     
  14. rorakin3

    rorakin3

    Joined:
    Jan 2, 2013
    Posts:
    464
    Hey, it looks like you need to set the data source for the series later in the code:

    xPlot.pointValuesDataSource= dsX; // assign the data source to a series.

    should be done after you create your series. Right now you're setting it to series 1 and then deleting the series (along with its datasource reference) and then creating series.

    I see also that you are using the groups feature:

    graph.useGroups = true;

    For grouping, remember that the groups list of strings must be set on the graph, and then the x-value of the vector2 data should correspond with the index of the group (see the later half of my youtube video on creating graphs for more info about using grouping)
     
  15. RolfBertram_dot_me

    RolfBertram_dot_me

    Joined:
    Mar 1, 2011
    Posts:
    128
    Thanks! ;-) Works - after following your advice.
     
  16. rorakin3

    rorakin3

    Joined:
    Jan 2, 2013
    Posts:
    464
    Hey guys, version 1.5.8 has been submitted to the store!

    With this version I've added many Doxygen style comments to the code base as well as generated API docs as a better way to document Graph Maker. There are also some code snippets embedded within the documentation itself, for example for events to make it easier to see what code you need to write to subscribe to / use the various Graph Maker events.

    upload_2017-2-8_21-16-14.png

    I hope this will be helpful going forward.

    Docs:
    http://stew-soft.com/GraphMaker/Docs/html/annotated.html

    Change log:
    1.5.8
    - NEW: Worldspace graph example scene.
    - NEW: Equation plotter example scene.
    - NEW: New type of pie graph from the ring graph, and accompanying example scene.
    - NEW: New auto padding functionality for axis graphs for ensuring axis labels fit within the graph.
    - NEW: Ring graph can now optionally use compute shader for improved performance.
    - NEW: New Doxygen style code commenting and Doxygen generated API documentation.
    - FIX: Axis auto scaling issue for dual-y axis charts.
    - FIX: Auto animations issue with area shading.
    - FIX: Tooltip positioning issue for worldspace graphs.
    - FIX: Area shading blocking mouse click / hover events issue.
    - FIX: Area shading masking issue within e.g. a Scroll View.
    - CHANGE: Default bar chart spacing behaviour slightly changed so that bars are between ticks.
    - CHANGE: Mouse click events now also pass UnityEngine.EventSystems.PointerEventData to distinguish double click.
    - CHANGE: WhiteSquare 2048 / 1024 / 512 textures removed, and texture resolution now configurable in affected places.
    - CHANGE: Axis titles / graph title text now anchored to graph edges.
    - CHANGE: Move data generator functions to static WMG_Util class.
     
  17. Neamtzu

    Neamtzu

    Joined:
    Dec 12, 2012
    Posts:
    3
    Hello,

    First of all, congratulation for this great asset.
    I'm wondering if there is a easy way to add a slider on the X axis. I have a large amount of data and it gets a bit crowded.

    Thanks,
    Daniel
     
  18. rorakin3

    rorakin3

    Joined:
    Jan 2, 2013
    Posts:
    464
    Hey,

    Thanks, no problem this is a pretty common request / question.

    In general, when you want to visualize lots of data such as a time series of thousands of data points over several years. There are basically 2 main approaches:

    Approach 1 - The user interacts with a limited set of options such as forward / back buttons or dropdown list of options.

    In this case, you can more finely tune how you want the graph to appear and also animate between these options. This is the most common approach and if you look closely, is widely used all over the place on the web and in mobile apps.

    You listen for the button click / UI event, and when it occurs, you animate in the set of data corresponding to the data that was chosen. For example maybe the time shifts over, or maybe everything fades out and then new data fades in. In this case the user has less control over what they see, but the program has more control over how it is displayed and animated for the given options.


    Approach 2 - Create a scrollable graph.

    This approach has the advantage that the user has more control over what they are able to see at any given time, but with the disadvantage that there are no nice animations, it's just based on how fast the user moves their mouse.

    - Let's say you have 10,000 points and want 1,000 points visible at a time. You can create a scrollbar UI element. If it ranges from 0 to 0.9 inclusive, then a value of 0 would correspond to points 0 - 1,000, and a value of 0.9 would correspond to points 9,000 - 10,000.

    In the onValueChanged() callback for the UI slider, you would then figure out which range of points should be displayed based on the value of the slider and then update the graph's points as well as x-axis min and max values based on that.


    Note that in these approaches you have to update the series point values. Alternatively, you could create all the data points for the entire graph at the beginning and use for example a UI ScrollView component to mask out the visual appearance of the data that is outside the mask. This approach would be similar to approach 2, but worse performance wise, and you might get errors / crash Unity depending on how much data you have as there is a vertex limit for UI canvases.

    I hope this info was helpful!
     
  19. elPanda

    elPanda

    Joined:
    May 8, 2013
    Posts:
    3
    Hi there,

    First, thanks for such an amazing job.

    I'm trying to get the radar graph, but can't get how to add values... I might be missing something really obvious, so feel free to laugh :)

    Best
     
  20. rorakin3

    rorakin3

    Joined:
    Jan 2, 2013
    Posts:
    464
    Hey, no worries, it's actually not really obvious in this case and I should probably make an example scene for this, but here is a little script called TestRadar to show how to add data. First uncheck "Random Data" on the radar graph, it is just for demonstration purpose and should be unchecked when using your own data.

    Code (csharp):
    1.  
    2.  
    3. using System.Collections;
    4. using System.Collections.Generic;
    5. using UnityEngine;
    6.  
    7. public class TestRadar : MonoBehaviour {
    8.  
    9.     public WMG_Radar_Graph graph;
    10.     public List<float> points;
    11.  
    12.     // Update is called once per frame
    13.     void Update () {
    14.         if (Input.GetKeyDown(KeyCode.A)) {
    15.             for (int i = 0; i < graph.numDataSeries; i++) { // loop through each radar data series (other series are grids and labels)
    16.                 WMG_Series aSeries = graph.lineSeries[i + graph.numGrids].GetComponent<WMG_Series>();
    17.                 aSeries.pointValues.SetList(graph.GenRadar(points, graph.offset.x, graph.offset.y, graph.degreeOffset));
    18.             }
    19.         }
    20.     }
    21. }
    22.  
    23.  
    Attach that script to any object in your scene, drag and drop the reference to the radar graph on it, and enter in some data in the points list on this script. For the points list the number of points should be same as the number of points specified on the radar graph (e.g. pentagon shape needs 5 points). And then the point values themselves should be within the minimum and maximum values specified on the radar graph "Radar Min Val" and "Radar Max Val". Once it is setup, you can play your application and press the A key.
     
  21. elPanda

    elPanda

    Joined:
    May 8, 2013
    Posts:
    3
    Sweet, thanks :)

    FYI, I had to change
    Code (CSharp):
    1. aSeries.pointValues.SetList(graph.GenRadar(points, graph.offset.x, graph.offset.y, graph.degreeOffset));    
    to
    Code (CSharp):
    1. aSeries.pointValues.SetList(WMG_Util.GenRadar(points, graph.offset.x, graph.offset.y, graph.degreeOffset));
    Thanks again, realy amazing work

    Best
     
  22. mespino

    mespino

    Joined:
    Nov 26, 2015
    Posts:
    15
    Hello!

    I am doing a Graph pretty much like Plot Overtime.

    But I have a question. The plot is updated in realtime with ingame data. I am able to animate the graph adding and removing points of the serie and changing the xAxis.AxisMinValue and xAxis.AxisMaxValue.

    The major problem I have right now is with the xGrid. Because of the data is moving along the time, the grid should move too, but I do not know how this can be done.

    Other problem that I have is I should be able to scroll to the previous data, so I can not remove them. But If I do not remove them, the values are drawn altought they are out of the canvas. Is there any option to mask this data?
     

    Attached Files:

  23. rorakin3

    rorakin3

    Joined:
    Jan 2, 2013
    Posts:
    464
    Hi there, I believe I have a solution for you. If you can send me an email with your invoice number then I can send you an updated package or specific code files if you prefer.
     
    mespino likes this.
  24. Deleted User

    Deleted User

    Guest

    Hello! I am using TextMeshPro (The Unity Beta Version). I followed your tutorial video (
    ).

    My graphs are populating, but they are spamming a null reference. It is on line 144 of WMG_GUI_Functions.cs. I am guessing that it is searching for a UGUI Text Component that has been replaced by a TextMeshProUGUI Component. How can I fix this issue? Thanks!

    //http://answers.unity3d.com/questions/921726/how-to-get-the-size-of-a-unityengineuitext-for-whi.html
    public float getTextWidth(GameObject obj)
    {
    Text textComp = obj.GetComponent<Text>();
    return textComp.cachedTextGeneratorForLayout.GetPreferredWidth(
    textComp.text, textComp.GetGenerationSettings(textComp.GetComponent<RectTransform>().rect.size));
    }
    //http://answers.unity3d.com/questions/921726/how-to-get-the-size-of-a-unityengineuitext-for-whi.html
    public float getTextHeight(GameObject obj)
    {
    Text textComp = obj.GetComponent<Text>();
    return textComp.cachedTextGeneratorForLayout.GetPreferredHeight(
    textComp.text, textComp.GetGenerationSettings(textComp.GetComponent<RectTransform>().rect.size));
    }​
     
  25. rorakin3

    rorakin3

    Joined:
    Jan 2, 2013
    Posts:
    464
    Thanks for reporting this issue with 1.5.8, to fix:

    Add this to WMG_TMP_Text_Functions.cs

    public float getTextWidth(GameObject obj) {
    return getTextSize(obj).x;
    }

    public float getTextHeight(GameObject obj) {
    return getTextSize(obj).y;
    }


    Also, delete these functions from WMG_GUI_Functions:

    public float getTextWidth(GameObject obj)
    public float getTextHeight(GameObject obj)
     
  26. dashticle

    dashticle

    Joined:
    May 25, 2016
    Posts:
    4
    On trying to change the graph background sprite alpha to make it opaque on mouse over, I have:

    Code (CSharp):
    1.     public void OnPointerEnter(PointerEventData eventData)
    2.     {
    3.         Debug.Log("Moused Over");
    4.         graph.changeSpriteAlpha(graphGO, 1.0f);
    5.     }
    And am setting graphGO from the inspector for this test:

    Code (CSharp):
    1.     public GameObject graphGO;
    2.     public WMG_Axis_Graph graph;
    I am getting a null reference exception, although I have checked that the object is referenced and not null:

    Code (CSharp):
    1. NullReferenceException: Object reference not set to an instance of an object
    2. WMG_GUI_Functions.changeSpriteAlpha (UnityEngine.GameObject obj, Single alpha) (at Assets/Graph_Maker/Scripts/GUIDependent/WMG_GUI_Functions.cs:49)
    3. GraphScript.OnPointerEnter (UnityEngine.EventSystems.PointerEventData eventData) (at Assets/GraphScript.cs:22)
    4. UnityEngine.EventSystems.ExecuteEvents.Execute (IPointerEnterHandler handler, UnityEngine.EventSystems.BaseEventData eventData) (at C:/buildslave/unity/build/Extensions/guisystem/UnityEngine.UI/EventSystem/ExecuteEvents.cs:24)
    5. UnityEngine.EventSystems.ExecuteEvents.Execute[IPointerEnterHandler] (UnityEngine.GameObject target, UnityEngine.EventSystems.BaseEventData eventData, UnityEngine.EventSystems.EventFunction`1 functor) (at C:/buildslave/unity/build/Extensions/guisystem/UnityEngine.UI/EventSystem/ExecuteEvents.cs:269)
    6. UnityEngine.EventSystems.EventSystem:Update()
    7.  
    I can get around it I'm pretty sure by just changing the alpha of the background image, but any idea what's going on?

    Overall I've found it really difficult to use the tool effectively, changing the graph prefab I made in the editor seems tempermental (not displaying changes correctly though this could be a unity issue), and changing it through code is a crapshoot as I can't understand the different functions, and the documentation is pretty scarce. Disappointing for a $60+ purchase that the answers to simple use cases must be found through a combo of digging through the boxed examples, one or two useful FAQ answers and this thread.

    Could really do with a better manual basically, for us poor inexperienced ones who want to use what seems to be a powerful tool!
     
  27. rorakin3

    rorakin3

    Joined:
    Jan 2, 2013
    Posts:
    464
    Hey there,
    So there are a couple main ways to change sprite colors / alpha color. One is to use the Canvas Group component:
    https://docs.unity3d.com/Manual/class-CanvasGroup.html
    You can attach this to any UI element, and change the alpha value on it. This controls the alpha of that element with the CanvasGroup as well as all of its children.

    The other way is to simply change the color on the UI Image:
    https://docs.unity3d.com/Manual/script-Image.html
    It looks like this is what you were trying to do with your code. You were close, but it's not correct because the graph object itself has no Image component. Instead you need the graph background object that has the Image component, which is this guy:
    http://stew-soft.com/GraphMaker/Doc..._graph.html#aac6ff13be26a1ccffcc506e65d3cb006

    For your other points, making changes in the editor should be fine if you save the scene. You can also create your own prefab by duplicating an existing prefab and modifying it.
    Yes, documentation is indeed an on going improvement. Ideally, I could anticipate all customer questions and create an example and / or FAQ for all of them, but it is not realistic. However, changing graph background has been asked a couple times now, so I think it's time to add that one to the FAQ along with the info on CanvasGroup.

    Please don't hesitate to post here or email with any more issues you run into.
     
    Last edited: May 5, 2017
  28. dashticle

    dashticle

    Joined:
    May 25, 2016
    Posts:
    4
    Yes, I did it in the end by referencing the background image.

    Code (CSharp):
    1.     public void OnPointerEnter(PointerEventData eventData)
    2.     {
    3.         Debug.Log("Moused Over");
    4.         //graph.changeSpriteAlpha(graphGO, 1.0f);
    5.         Color bgColor = background.color;
    6.         bgColor.a = 1.0f;
    7.         background.color = bgColor;
    8.  
    9.     }
    I was originally hoping to do it with your graph functions though, just didn't know which one! Looks like the one you linked was it.

    Thanks, I appreciate you are on the ball in replying to this thread and helping people out. And a lot of my problems stem from inexperience. Just if the basic text guides were a bit better, I could have found this myself - beefing up the function descriptions in the API, or providing more info on important class/functions in the manual would solve a lot of issues I bet.

    Thanks again.
     
  29. EmeralLotus

    EmeralLotus

    Joined:
    Aug 10, 2012
    Posts:
    1,462
    Graph Maker is getting more and more awesome with each new version.

    I'm testing Unity 2017 beta 3 and Graph Maker.
    All of the examples work great. Only one that is not working is

    Area_Shading_Test

    Kernel 'CSMain' not found
    UnityEngine.ComputeShader:FindKernel(String)
    WMG_Compute_Shader:Init(Int32) (at Assets/Graph_Maker/Scripts/WMG_Compute_Shader.cs:28)
    WMG_Series:createOrDeleteAreaShading(Int32) (at Assets/Graph_Maker/Scripts/WMG_Series.cs:1484)
    WMG_Series:CreateOrDeleteSpritesBasedOnPointValues() (at Assets/Graph_Maker/Scripts/WMG_Series.cs:1242)
    WMG_Series:pointValuesCountChanged() (at Assets/Graph_Maker/Scripts/WMG_Series.cs:858)
    WMG_Series:pointValuesCountChanged() (at Assets/Graph_Maker/Scripts/WMG_Series.cs:892)
    WMG_Change_Obj:Changed() (at Assets/Graph_Maker/Scripts/Utils/WMG_Change_Obj.cs:20)
    WMG_Series:ResumeCallbacks() (at Assets/Graph_Maker/Scripts/WMG_Series.cs:819)
    WMG_Axis_Graph:ResumeCallbacks() (at Assets/Graph_Maker/Scripts/Graphs/WMG_Axis_Graph.cs:838)
    WMG_Axis_Graph:Refresh() (at Assets/Graph_Maker/Scripts/Graphs/WMG_Axis_Graph.cs:773)
    WMG_Axis_Graph:Update() (at Assets/Graph_Maker/Scripts/Graphs/WMG_Axis_Graph.cs:765)
     
  30. rorakin3

    rorakin3

    Joined:
    Jan 2, 2013
    Posts:
    464
    Hey Rocki, long time no see!

    I tried it out Unity 2017 beta 3 and didn't run into an issue -

    upload_2017-5-6_17-23-21.png

    Maybe the platform you ran it on does not support compute shaders, if this is the case you can disable compute shader usage on the series by unchecking "Area Shading Uses Compute Shader". Graph Maker will then use an alternative method for area shading.

    upload_2017-5-6_17-24-48.png

    The downside will be lower performance as well as additional draw calls (N-1) drawcalls in total for the shading, where N is the number of points in your series.
     
  31. username132323232

    username132323232

    Joined:
    Dec 9, 2014
    Posts:
    477
    What is the best way to place a Pie Graph over a UI Panel so that it inherits the Panel's dimensions and position?

    I'm asking because I would like to show several graphs on the same screen and let the Panels with the associated layout scripts to take care of all the resizing and positioning.
     
  32. rorakin3

    rorakin3

    Joined:
    Jan 2, 2013
    Posts:
    464
    Hey, having the pie graph be a child of the panel, and the pie graph set to stretch to its parent is the best way. To stretch to parent, alt click on the pie graphs RectTransform's anchor preset icon and click the bottom right corner in the popup:

    upload_2017-5-15_10-0-31.png

    The pie graph should then automatically grow and increase in size when it can. I say 'when it can' because the pie graph itself won't stretch, it will maintain aspect ratio so you don't get for example a squished pie graph. If the aspect ratio of your parent panels is significantly different, you can change various legend settings to try and get the aspect ratio close to the aspect ratio of your parent panels.
     
  33. username132323232

    username132323232

    Joined:
    Dec 9, 2014
    Posts:
    477
    Thanks!!! That worked great.

    UPDATE: Sorry, but there seems to be a problem if I turn Animation on (set Animation Duration to a non-zero value). The pie becomes about 50% larger, all slice labels disappear and legend background is gone too.


    I have a couple of other questions. If they are covered anywhere in the docs, please let me know :)

    1) Is it possible to position the Legend box under the pie?

    2) How would I change color and thickness of the lines between the pie slices?

    BTW, any plans for a 3D Pie Graph?
     
    Last edited: May 15, 2017
  34. rorakin3

    rorakin3

    Joined:
    Jan 2, 2013
    Posts:
    464
    No problem,

    Yeah, you can do it either in the inspector by changing the 'Legend Type' from 'Right' to 'Bottom' here:
    upload_2017-5-15_16-40-34.png

    upload_2017-5-15_16-40-13.png

    or via code:
    Code (csharp):
    1.  
    2. pieGraph.legend.legendType = WMG_Legend.legendTypes.Bottom;
    3.  
    2) On the pie graph settings you can change the "Explode Length" which determines the gap between the slices. There aren't actually lines between them just a gap of space, and there is a background circle image behind that you could change the color of.

    No current plans for 3d, it does look like there is another graph package on the asset store that focuses on 3d graphs though.
     
  35. username132323232

    username132323232

    Joined:
    Dec 9, 2014
    Posts:
    477
    Thanks again! Everything worked as you explained.

    It seems that setting up PieGraph via code is easier. Is there a reference to all the settings?
     
  36. rorakin3

    rorakin3

    Joined:
    Jan 2, 2013
    Posts:
    464
    Hey, no problem. Yeah, the API docs has the list, for example pie graph is here:
    http://stew-soft.com/GraphMaker/Docs/html/class_w_m_g___pie___graph.html
    Most of the things you may want to change will be listed under the "Properties" section for each of the classes in these docs.
     
  37. username132323232

    username132323232

    Joined:
    Dec 9, 2014
    Posts:
    477
    Got it. Thanks again for a great plug-in and support!
     
  38. sunnf

    sunnf

    Joined:
    Dec 3, 2016
    Posts:
    1
    Two or more curves are displayed together,x_plot_Overtime
     
  39. eleicht

    eleicht

    Joined:
    Apr 21, 2016
    Posts:
    9
    Hello,

    I have quite an urgent request. We need three scatter plots in our screen that contain up to 5000 points each. We're adding a point to each plot within some milliseconds from a live data stream.
    Up to the first couple of hundred points, the framerate is okay. But it quickly decreases down to 30 FPS (GUI update framerate), the actual plot update rate is even slower, like seconds.

    Our plots looks like this:
    upload_2017-5-23_11-21-41.png

    That's at the beginning where the FPS are still alright.

    I already tried the following to increase performance:
    - Split the points into a "running" series which contains 100 points max, then get copied to a "static" series.
    - Create a new, "static" series each 100 points.
    - Stop auto resize when 1000 points are reached in total.

    Nothing has changed yet. I digged a bit into your code, but I don't have the time to rewrite the Update() routine which iterates over literally everything.

    There must be a way to workaround this performance drop, because the old points stay where they are, only new points are added. Isn't there a flag somewhere which updates only the new point(s) each frame and changes size of the plot, if necessary, but doesn't iterate over all points?

    Thanks in advance,
    Best regards
     
  40. Mikael-H

    Mikael-H

    Joined:
    Apr 26, 2013
    Posts:
    309
    Hi,

    Just started using graph maker. My first task is to draw an organizational graph for military units. Is there a way to draw the links like in this image:
    infcoy.jpg
    The nodes I'll take care of myself but the links in this type of tree graph would be very nice if it was supported out of the box. Of course I'll do it myself anyway, I just think it would be a nice addition to the package.

    A bit more info about hierarchical trees in the manual wouldn't hurt, the doxygen docs do not really tell me much.

    Also, why no namespaces?

    Cheers,
    Mike
     
  41. rorakin3

    rorakin3

    Joined:
    Jan 2, 2013
    Posts:
    464
    Hey there,
    Your use case sounds like it might be a bit of a stretch for Unity UI system, but let's see what we can do. Firstly, I would say to try to 'pre-create' a graph with all the points you will need. For example randomly generate 1,000 points on a graph when your application first loads. Next hide all those points, for example by iterating through the points and setting their alpha color to 0. Next when ever you 'add' a new data point, just modify the pointValues for the one point you are adding. Graph Maker will change only that data point. This code is in WMG_Series.PointValuesValChanged().

    Another option. Are you exporting to platform that supports compute shaders? https://docs.unity3d.com/Manual/ComputeShaders.html
    If so, it's possible to do 1,000 of points in real-time no problem using a single rectangle and single draw call, by dynamically generating a texture in parallel using the GPU. I do this for the compute shader area shading. You will basically want to modify the ComputeLineGraph.compute code to generate little circles of pixels for each point you have.
     
  42. rorakin3

    rorakin3

    Joined:
    Jan 2, 2013
    Posts:
    464
    Yeah, for sure. You can create that type of link now, it requires creating 'invisible nodes'. So for that example you would have 5 actual nodes and 5 invisible nodes (1 for each 90 degree bend in the links). In the future, I would like to make small example scene that makes it possible to 'draw' any kind of trees / graphs you want using mouse clicks / drags.

    I'll probably do namespaces with Graph Maker 1.6. I've put off doing for awhile mainly because I don't want to break people's existing code when they update.
     
    Mikael-H likes this.
  43. Mikael-H

    Mikael-H

    Joined:
    Apr 26, 2013
    Posts:
    309
    Thanks, that works :) Is there documentation concerning invisible nodes that I missed somewhere? Took me some time to figure it out but I got it now... One based index and negative indices for invisible nodes, makes sense now that I understand it :D

    I've had to rewrite some parts of WMG_Hierarchical_Tree.cs to get it to draw/redraw dynamically. Did you intend for it to work drawing dynamically out of the box or was that not the intent of the control?
     
  44. rorakin3

    rorakin3

    Joined:
    Jan 2, 2013
    Posts:
    464
    It was created mainly for before-run time creation purpose, such as design a skill tree to be used in a game and save it as a prefab. But feel free to modify it so that you can add nodes / links to it during run-time.

    I see now the documentation doesn't really describe the invisible nodes, I'll add that.
     
    Mikael-H likes this.
  45. eleicht

    eleicht

    Joined:
    Apr 21, 2016
    Posts:
    9
    Hey, first of all: Many thanks for your quick and helpful answers!
    I've tried this idea before with a set of 5k points at (0,0), but that hasn't helped at all. Is it a difference if the points have a non-zero value at init?
    However, I've changed these points' values by accessing the series point values manually, but not using WMG_Series.PointValuesValChanged(). I'll have a look at that as soon as I get back to work.
    Question here: Do I have to somehow cancel the Update() routine for the series or just keep it going?

    Platform is Windows, compute shaders possible depending on graphics card. So I'd say 50/50. But, when the abovementioned idea doesn't work, I'll dig into that.
     
  46. rorakin3

    rorakin3

    Joined:
    Jan 2, 2013
    Posts:
    464
    The Update() routine only checks to see if there has been any changes since the last Update() using a small number of WMG_Change_Obj fields which keep track of changes for various sets of properties. If there has been change(s) then relevant code will run to do the actual update. So, a series of 5000 points is the same as a series of 1 point for Update() if nothing changed between frames.

    It's probably that you are changing more than 1 point in a single frame, in which case the performance boosted code that only runs changes for 1 point is not getting run. In this case I would recommend trying out calling WMG_Axis_Graph.Refresh()
    http://stew-soft.com/GraphMaker/Doc..._graph.html#a1fdada9da12073f623ef7fc18394e55f
    after each point you add if more than 1 added in a single frame. You may end up calling Refresh() several times per frame, but it shouldn't matter too much as it will only do the changes since the last Refresh() / last Update(), and the performance boosted code of only updating a single point will run.
     
  47. eleicht

    eleicht

    Joined:
    Apr 21, 2016
    Posts:
    9
    I'm sorry, but it still behaves the other way in my project. With just a few points it's alright, but the more points I get, the more my FPS drop.

    What I did/tried:
    1. Put the three scatter plots to a new Canvas in order to avoid refreshing the huge main canvas and thus eliminating a Unity UI bottleneck. This worked as far as the Canvas.RenderOverlay FPS drop is a lot less. The idea came from here and in general useful for fast changing graphs I think: https://support.unity3d.com/hc/en-us/articles/115000355466-Split-canvas-for-dynamic-objects
    2. I added 2000 points at (0,0) at initialization, with and without alpha set to 0 for each points. No change in performance, the bottleneck in this case is the OnValueChanged() from the beginning.
    3. When I keep adding the points (so 0 points at init) -and- following your advice with Refresh() after each point add, still the perfomance is bad:
      upload_2017-5-31_9-58-27.png

      In this example I've got 155 points in each graph in three series: 1 points, 5 points, 149 points (the 149 are the blue ones which will increase, the 1 and 5 are just for indication of latest points).
      The FPS hit clearly happens in the Update() function, not the manual Refresh()ing.
      There is a huge GC allocation, which I think could be the issue (?!).

      Note: When I stop adding points, the framerate stays at constant 30 FPS (around 40 ms per frame), so the "Time ms" values of the functions in the profiler go down. However, the relations keep same, that means, the functions in the profiler shown above are the FPS killers.

      Note 2: Actually you're right - the amount of points is not that critical. But with just 100-200 points staying at 50 FPS mean (30 using deep profiler), it goes down to unusable values at around 1000 points.
    Do you have an other suggestion?#


    Edit:
    I've just retried the method using 2000 points in advance with (0,0) values. From start, the performance lacks totally, leading to these results:
    upload_2017-5-31_13-31-25.png

    Looking into the code, the ".Count" variable is really accessed each time in the loop, leading to 24k calls and 20 ms just for getting the size of the lists again and again.
    So to speak, there seems to be space for performance improvements.
    I just tried avoiding the frequent Count accesses, but the code is not documented at all. I don't know what totalPointValues really means (and some other variables), and I don't want to mess around. Could you provide an update on this performance issue for huge, fast changing data sets like mine?
     
    Last edited: May 31, 2017
  48. rorakin3

    rorakin3

    Joined:
    Jan 2, 2013
    Posts:
    464
    Hey, I'll take a look into this tonight. Please send me an email with your invoice #, if I've found some performance improvements, I'll email an updated package.
     
  49. engbrianlee

    engbrianlee

    Joined:
    May 19, 2017
    Posts:
    2
    Hi Rorakin3,

    I'm interested in using your asset for graphs in a Hololens AR application. I'm worried about the integration, however. Is it possible to send me a demo that I can test to see if it imports properly?

    Regards,
    engbrianlee
     
  50. rorakin3

    rorakin3

    Joined:
    Jan 2, 2013
    Posts:
    464
    Hi, unfortunately there is not a separate demo I can send. Graph Maker uses the Unity UI system, I would make sure it works for you, here are the steps you need to follow:
    https://forum.unity3d.com/threads/unity-ui-on-the-hololens.394629/
    Also here are some example videos using / interacting with Graph Maker graphs in VR:
    http://virtualrealitynau.weebly.com/demonstrations.html
     
    Last edited: Jun 1, 2017