Skip to Content

I recently received a request to incorporate a gauge component in my Design Studio dashboards. The higher-ups had seen an Xcelsius dashboard utilizing gauges, and wanted the same functionality in the dashboards I was building. As we all know, a gauge component is not included out-of-the-box with Design Studio, and searching on SCN turned up nothing but requests from others for the same component. So, with my limited knowledge of HTML and absolutely zero experience with JavaScript, I decided to roll up my sleeves and build one myself. The following is a brief chronicle of the process. This is not meant to be a literal step-by-step tutorial, but to demonstrate the thought process behind the creation of the component and provide direction to those looking to create something similar.

I started with a copy of the clock component provided in the DS 1.3 SDK Samples pack, and followed the steps in section 3.2 of the Design Studio SDK Developer Guide to rename the proper components of the extension.

/wp-content/uploads/2014/06/clock_477826.png

I removed the hour and minute hands by deleting the appropriate sections of the component.js file. I recolored the outer boarder with a gradient fill and added an inner boarder with the reverse gradient fill to give a 3 dimensional look to the exterior ring. To achieve the correct dimensions, I increased the UNIT variable to 145 (from 100) and moved the tick marks outwards by changing their respective start/end variables.

/wp-content/uploads/2014/06/img2_477885.png

I wanted the number of tick marks to be dynamic, so I created user inputs in the contribution.xml for the number of major and minor tick marks to create. Using these variables, I changed the for-loops which draw the hour and minute tick marks to create the specified number of tick marks with equidistant spacing across the upper 2/3 of the gauge face.

/wp-content/uploads/2014/06/img3_477886.png

I then changed the look of the gauge needle by editing the “draw second hand” section of the component.js file. To set where the needle is pointing, I replaced the variable “seconds” with one that the user can input either in the properties pane (in the contribution.xml) or with a setValue method (in the contribution.ztl). I created three triangles which together form the needle. The shading of the needle changes as the needle crosses the direction from which the light appears to come from (top left corner). I also embellished the “boss” by adding some transparency and a linear gradient.

/wp-content/uploads/2014/06/img4_477888.png

To emulate the Xcelsius color ranges in the gauge component, I created arcs that rest above the ticks that are colored red, orange, yellow, and green. The positions of these ranges should be input by the user, so I created inputs in the contribution.xml for the ends of the red, orange, and yellow ranges (each range begins where the previous one ends — red always begins at the minimum, green always ends at the maximum). I also created a setting that allows the user to select a continuous color distribution across the range instead of the discrete sections.

/wp-content/uploads/2014/06/img5_477889.png

I wanted the option to have numbers on the dial, so I again created a user option to display numbers. The numbers are created when the tick marks are drawn by rotating the canvas inside of the “for” loop, placing the number text in the correct location, and rotating the canvas back before the next loop iteration. Correct placement of the numbers was moderately difficult to accomplish, mostly because by this point I had lost track of which direction the canvas was rotated and, subsequently, how to place the labels in the correct position relative to the center of the gauge. I created user inputs for the minimum and maximum of the dial, and allowed the gauge values to scale with the number of major tick marks the user selects (calculated based on the loop counter, the step size, and the min). One side effect of this approach: Since the labels are integers, we get some interesting results if the user selects a number of tick marks which does not evenly divide the range, as seen below.

/wp-content/uploads/2014/06/img6_477890.png

The position of the needle is calculated based on the value (input by the user either in the properties pane or with the setValue method) relative to the max-min range (as seen above, if the value is 50, the needle points to 50 regardless of the min and max). As a finishing touch, I created a label in the bottom portion of the gauge to display the value the gauge is currently pointing to, as well as a user definable unit for the value (such as ‘%’ or ‘$’). This label can also be turned on and off.

/wp-content/uploads/2014/06/img7_477891.png

I decided to add a bit of a “reflection” to the dial to simulate it being covered in glass. Then, last but not least, I let the user choose a “theme”: the default ‘silver’ or a slick ‘black’

/wp-content/uploads/2014/06/img8_478425.png

So ends my first adventure using the Design Studio SDK, the creation of my first custom component, and my first contribution to SCN. Your questions, comments, and suggestions are always welcome in the comments section below.

— Nick Stein

To report this post you need to login first.

44 Comments

You must be Logged on to comment or reply to a post.

  1. Mike Howles

    This is terrific.  I like the progression you show in the screenshots.  The end product looks really slick!  Any plans on sharing the source on Github or as a .ZIP?  馃檪

    (0) 
    1. Nicholas Stein Post author

      Hi Michael,

          

           I’m waiting for permission from my parent company to release the source. As soon as I get the go-ahead, I’ll attach it to my post.

      Thanks!

      (0) 
    1. Nicholas Stein Post author

      Hi Dave,

           Any component which is not included out-of-the-box in Design Studio, one of the SDK examples, or available here on SCN from another contributor would require similar treatment. A few that come to mind immediately are a dial component and combination charts (e.g. a chart that shows a column graph of one data set in the same plot as a line graph from another). Of course, the number of components one could build is really only limited by the imagination of the designer (and the client).

      -Nick

      (0) 
  2. Stephen Fogwill

    Hi Nicholas

    Thanks for this post.

    It is certainly a very time consuming task, at least for me, to change this clock into a Gauge. I spent quite a few hours and decided to give up, due to the effort required.

    Would you be willing to share your .js source code? If so, thanks in advance! I will add animation to it and share back.

    Best regards 

    (0) 
    1. Nicholas Stein Post author

      Hi Stephen,

           It was time consuming for me as well, since I had no previous experience with JavaScript or the HTML canvas element. Are you using only Eclipse? One thing that helped me greatly was the use of a separate HTML IDE for a real-time view of the component as I changed code. It makes the development process much faster as there is no need to launch Design Studio to see what the component looks like (85% of the process is just getting the thing to look right). You can test functionality by creating variables for values you intend the user to input.

           As for your question, unfortunately since the component design was done for a client, my parent company retains the rights to the source. At the moment, they are unwilling to release the source publicly. If that changes, I’ll be sure to update my post.

      –Nick

      (0) 
          1. Alex Cruickshank

            Hi Nicholas

            This is great work and im hoping it will help me build a custom component I have been tasked with. Need to create a thermometer 馃檪

            Did u use the Eclipse Plugin for Aptana or aptana studio standalone?

            Thanks

            (0) 
        1. Mike Howles

          Thanks!

          I’ve added it to the Utility Pack post which includes that deployable version that non-SDKers can use.  I’ve not modified the source aside from where needed to package it.

          (0) 
    1. Nicholas Stein Post author

      Antonio,

      Fantastic implementation! I really like the options to choose the range colors and the animation you added. Your component will certainly be a valuable resource for all.

      Keep up the good work!

      — Nick

      (0) 
    2. Stephen Fogwill

      Hi

      I noticed the component’s methods do not fire.

      In order to resolve it, I corrected the contribution.ztl as follows: the code was referring to ‘val’ which I replaced with ‘value’.

      I am now able to set the ‘properties’ in Design Studio with scripting.

      Thanks again.

      (0) 
    3. Kevin Rheeder

      Hi Antonio

      I’ve downloaded your gauge and have used it in some of our reports.

      My concern is to use it for some measure bigger than 100. When I have a value bigger than 100, the gauge passes the set max value and stops wherever the gauge thinks the value would be past 100.

      customgauge.JPG

      This is a simple example. I have a value of 150 assigned. Essentially it should stop at 150 but passes 200 and stops on 0. Any feedback or help would greatly be appreciated. PS, I’m very new to Design Studio and the SDK’s.

      Kind Regards,

      Kevin

      (0) 
  3. Stefanos Leon

    Dear all,

    I like this gauge and have embedded the component to my Design Studio 1.3 Installation.

    Is there a way to bind this gauge to a data source, like it is possible for a pi or colum Chart? I can not find the Data Binding element in th eproperties.

    Any idea would be great.

    Thanks and best regards,

    Stefanos L.

    (0) 
    1. Pablo Marcelo Mu帽oz Nant贸n

      Hi Stefanos,

      What I did is simply script a bit in the On Select property of the chart from where you want to trigger the action, this is what I did and works perfectly:

      PERC_A_VALUE = MY_DATASET.getData(“00O2TKFI2HZUO5CIQ7SLZLTHA”, {“0DATE”:MY_CHART.getSelectedMember(“0DATE”).internalKey}).value;

      SPEEDOMETER_PERC_A.setNeedle(PERC_A_VALUE); SPEEDOMETER_PERC_A.setShowedValue(Convert.floatToString(PERC_A_VALUE/100, “#.## %”));

      This is just looking for the selected date value in a line chart, getting the corresponding value in another dataset (using that date as reference) and finally setting this value in the gauge.

      Of course you could always trigger from any other component.

      I hope this helps.

      Regards,

      Pablo

      (0) 
      1. Stavros Vorkas

        hey Pablo I know this is 1 year later posting but I have tried to replicate something similar, basically set the speedo from 0-1million, and i am trying to capture salary value (just to try make it work im keeping it simple)

        I created a drop down box which filters results from the DS. Here is a snippet of that:

        DS_1.setFilterExt(“_n0o3cO1zEeOnHuJd3MXOCA”, DROPDOWN_STATE.getSelectedValue());  ///////Filters the state

        Then I created a variable to capture the result as a value:

        var myvalue= DS_1.getData(“_n07yYO1zEeOnHuJd3MXOCA”, {}).value;

        And then I applied the following script to alter the state of the needle:

        SPEEDOMETER_1.setNeedle(myvalue);

        SPEEDOMETER_1.setShowedValue(Convert.floatToString(myvalue));

        Problem is every time I chose a state from the dropdown(with state names for filter) the needle starts spinning endlessly..

        Any ideas?

        Thanks

        -Stav

        (0) 
  4. Pablo Marcelo Mu帽oz Nant贸n

    Hi Nicholas,

    This is absolutely amazing.

    I have been using this for a some days and found out that sometimes when you play around with it moving around different containers it suddenly disappears (yeah, that’s the word).

    I placed it into a Grid Layout, put 5px to each margin, saved and then poof! it became invisible, the object is already there, I can select it and modify it (of course the html code appears in the browser) but nothing is displayed.

    If I recreate it from scratch it works perfectly even in the new container. Have you ever experienced something like this? Do you have any idea of what could be happening?

    Again, thanks for your collaboration, I really appreciate it!

    Pablo

    (0) 
      1. Mustafa Bensan

        Hi Antonino,

        I have also encountered the issue of disappearing SDK components when the margins are set to “auto”.  In your case, was there a particular technical reason for this behaviour and how did you resolve it?

        Thanks,

        Mustafa.

        (0) 
          1. Pablo Marcelo Mu帽oz Nant贸n

            Nice! Do you have the .jar file around there? I don’t have the SDK to build the solution and I have to reach the support team to install it, during that roundtrip I would like to start playing with this, it is too much to ask? Thanks Antonino!

            (0) 
          2. Pablo Marcelo Mu帽oz Nant贸n

            OK, I finally got it working 馃檪 .

            Now even having auto for Width and Height it’s being displayed (BTW, thanks Mustafa for clarifying the issued scenario). Anyway, It’s not resizing in the browser when the container does it (I tried with Chrome 36.0 and IE10) is this the expected behavior?

            Thanks!

            (0) 
            1. Antonino Cacace

              This component is drawn by javascript in a canvas tag, It simply can’t resize after it render once.
              So once it is rendered it cannot resize, sorry.

              (0) 
  5. Jagannadha Vedula

    My Value in Gauge is showing up right.

    but my Needle rotates almost 350 deg for a value of 72 馃檨

                                       

    var val=DS_2.getData(“00O2SNODRJTRZENZHDITULUC8”,{}).value;                                                                                                        GAUGE_1.setIndicatorValue(val);                                                                                                 GAUGE_1.setShowedValue(Convert.floatToString(val));

    (0) 
  6. Luiz Fernando Oliveira

    Hey Karol !

    What I’m doing wrong ??

    In database:

    VL_ENDIVIDAMENTO = 69,0

    VL_RAZAO = 3,87

    ——————————-My code————————

    /*Limpa os Filtros*/

    KPI.clearAllFilters();

    /*Realiza o Filtro*/

    KPI.setFilter(“NM_EMPRESA”, RADIOBUTTONGROUP_1.getSelectedValue());

    KPI_GRAPH.setFilter(“NM_EMPRESA”, RADIOBUTTONGROUP_1.getSelectedValue());

    PRINCIPAIS_CREDORES.setFilter(“EMPRESA”, RADIOBUTTONGROUP_1.getSelectedValue());

    /*KPI 1 */

    var valor_KPIT1_original = Convert.replaceAll((KPI.getDataAsString(“VL_ENDIVIDAMENTO”, {})), “,”, “.”);

    var test = TEXT_13.setText(valor_KPIT1_original); //Result 69.0

    var valor_novo1 = Convert.stringToFloat(valor_KPIT1_original);

    GAUGE_1.setIndicatorValue(valor_novo1);

    GAUGE_1.setShowedValue(Convert.floatToString(valor_novo1));

    ……

    ——————————–end my code ————————

    ERROR:

    )

    (0) 
  7. Shlomi Weiss

    Hi

    The component is greta, thanks

    I do have 1 issue with it

    When I set the width of height or it to ‘auto’, it doesn’t show up at all.

    Any ideas???

    Shlomi

    (0) 

Leave a Reply