Animated Number Counter

Blog covering another custom component I just built.

Featured image

Welcome

As always these blogs are my own opinions and thoughts, I do not get paid to write these, I just try to give honest reviews and feed-back.

So I swear I was watching some introduction to either materialize or react dashboards to try and learn more about the whole world of HTML to try and beef up my universaldashboard skills, and I saw this dashboard that had several counters on it, with icons like how the old universaldashboard counters used to look, except these counters were animating until it reached the given number. I thought wow that looks really cool, and a good way of getting the end-user to focus on your dashboard, by giving them something flashy to look at, then before you know it, the actual number is then displayed.

Then lots of time past…

Although I thought this looked super cool, I didn’t really give it much thought. I guess all the entertainment of 4 daughters and a Mrs to keep happy I had other things on my mind.

Then even more time past…

Then last night when I was on npmjs I thought I would randomly search for number counter and I got back to this result number-counter

This was it. This is what I had seen all that time ago in the video that I cannot really remember, but this is it.

Very happy I had found this number counter animation I then went to look at what dependencies it had listed, as it was showing 3.

So without knowing too much, but knowing enough, I thought, universaldashboard is built on top of react, so this is already in the custom template I mentioned in my previous blog that I use to create custom components. And I am pretty damn sure that webpack is what is used to build the compoent get the JSX compiled into a powershell function. So that just left me with prop-types which I have previously used in some other custom components

If you click on prop-types you will see to install this (remember you must be in the SRC directory of the custom template) you type the following command npm i prop-types --save however as also mentioned in a previous blog, you now have to download all the dependencies of prop-types for this to work:-

Remember this is just one extra dependency that we needed, and we have had to actually install another 4 things on-top of the 1 prop-type we needed.

This is why I do not build everything people ask for. As if that component relies on 14 dependencies, and each of those could have multiple dependencies, then you looking at spending a long time to download all these dependencies, and you might not even get the component working.

Start small

It was always on my bucket list to put something on github. Prior to using universal dashboard I had used github to find certain powershell code, and thought wow this is a super cool place for code. Also on my bucket list was to put something on the powershell gallery, as again I had used this prior to using universal dashboard and again though wow super cool, would love to be listed on here.

So I managed to contribute a theme towards powershell universal dashboard on github, then I published a custom component to the powershell gallery. Since then I been creating lots of repositories on github of the components I been building and posting onto the powershell gallery which in-turn goes onto the powershell universal dashboard market place.

I really need to still learn a lot as binding controls in universaldashboard is still a tricky subject to me, and I have had help on doing this on previous components, and only so far pulled it off by myself once.

So this component seemed pretty basic, and after reading the example this is my finished JSX code:-

import React from 'react';
import NumberCounter from 'number-counter';
class <%=$PLASTER_PARAM_ControlName%> extends React.Component {
  render() {
      return (
        <NumberCounter
          start={this.props.start}
          end={this.props.end}
          delay={this.props.delay}
          preFix={this.props.preFix}
          postFix={this.props.postFix}
          reverse={this.props.reverse}
        />
    );

  }
}
export default <%=$PLASTER_PARAM_ControlName%>

I did originally include the header in the div tag, but as I was using a custom theme on my dashboard, this had adverse effects displaying the text, so I removed it.

Powershell code

function <%=$PLASTER_PARAM_CommandName%> {
    param(
        [Parameter()]
        [string]$Id = (New-Guid).ToString(),
        [Parameter()]
        [int]$End,
        [Parameter()]
        [int]$Start,
        [Parameter()]
        [int]$Delay,
        [Parameter()]
        [string]$PreFix,
        [Parameter()]
        [string]$PostFix,
        [Parameter()]
        [bool]$Reverse
    )

    End {

        @{
            # The AssetID of the main JS File
            assetId  = $AssetId
            # Tell UD this is a plugin
            isPlugin = $true
            # This ID must be the same as the one used in the JavaScript to register the control with UD
            type     = "<%=$PLASTER_PARAM_ControlTypeName%>"
            # An ID is mandatory
            id       = $Id

            # This is where you can put any other properties. They are passed to the React control's props
            # function <%=$PLASTER_PARAM_CommandName%> {
    param(
        [Parameter()]
        [string]$Id = (New-Guid).ToString(),
        [Parameter()]
        [int]$End,
        [Parameter()]
        [int]$Start,
        [Parameter()]
        [int]$Delay,
        [Parameter()]
        [string]$PreFix,
        [Parameter()]
        [string]$PostFix,
        [Parameter()]
        [bool]$Reverse
    )

    End {

        @{
            # The AssetID of the main JS File
            assetId  = $AssetId
            # Tell UD this is a plugin
            isPlugin = $true
            # This ID must be the same as the one used in the JavaScript to register the control with UD
            type     = "<%=$PLASTER_PARAM_ControlTypeName%>"
            # An ID is mandatory
            id       = $Id

            # This is where you can put any other properties. They are passed to the React control's props
            # The keys are case-sensitive in JS.
            end      = $End
            start    = $Start
            delay    = $Delay
            preFix   = $PreFix
            postFix  = $PostFix
            reverse  = $Reverse
        }

    }
}
            end      = $End
            start    = $Start
            delay    = $Delay
            preFix   = $PreFix
            postFix  = $PostFix
            reverse  = $Reverse
        }

    }
}

I forgot to mention it, although it is in the comments, but incase you don’t read the comments here it is The keys are case-sensitive in JS this means it must match the case of the text in the JSX file for the props you are referencing.

Images

This was a little demo example I knocked up

placeholder

I did this using some simple code:-

Import-Module -Name UniversalDashboard.Community
$theme = get-udtheme DarkRounded
Import-Module -Name UniversalDashboard.UDNumber
Get-UDDashboard | Stop-UDDashboard
Start-UDDashboard -Port 10005 -Dashboard (
    New-UDDashboard -Title "Powershell UniversalDashboard" -theme $theme -Content {
        New-UDRow -Columns {
            New-UDColumn -Content {
                [int]$Finish = 12 / 555 * 100
                $number = (get-process).count
                if ($number -gt 1) {
                    New-UDElement -Tag H4 -Attributes @{
                        style = @{
                            color = 'white'
                        }
                    } -Content { New-UDNumber -End $number -Delay 2 -PreFix "Complaints you raised"
                        New-UDNumber -Start 100 -End $Finish -Delay 4 -Prefix "This equates to" -PostFix "%" -reverse $true
                    }
                }
            }
        }
    }
) -AutoReload

Top tip

So when I am developing a dashboard, I like to use the -AutoReload parameter on my dashboard. This means that when I change my code, and save it, this will automatically reload the dashboard in my browser. This means I don’t have to even run my script, and I don’t even have to refresh my browser, as the -AutoReload parameter takes care of that. This means less faffing about and more dashboard development time.

More Dynamic

So you can get this component working more dynamically for you by placing the code inside an endpoint script block. So for this to work, you need to download and install the UD Number module in the default powershell module folder, which should be done automatically something like %programfiles%\WindowsPowerShell\Modules once the module is in there, you can then use the module in your endpoints by importing the module into the New-UDEndpointInitialization command. So now on every page refresh using the following code you will get a different set of results:-

Import-Module UniversalDashboard.Community
Import-Module UniversalDashboard.UDNumber
Get-UDDashboard | Stop-UDDashboard
$endpointinit = New-UDEndpointInitialization -Module @("UniversalDashboard.UDNumber")
$theme = get-udtheme "DarkRounded"
$dashboard = New-UDDashboard -Title "New-UDNumber" -theme $theme -Content {
    New-UDRow -columns {
        New-UDColumn -Endpoint {
            New-UDCard -Content {
                [int]$Finish = get-random -Maximum 99
                $number = get-random -Maximum 100
                New-UDElement -Tag H4 -Attributes @{
                    style = @{
                        color = 'white'
                    }
                } -Content { New-UDNumber -End $number -Delay 2 -PreFix "You have" -PostFix "friends"
                    New-UDNumber -Start 100 -End $Finish -Delay 6 -Prefix "This is" -PostFix "% more than me" -reverse $true
                }
            }
        }

    }

} -EndpointInitialization $endpointinit
Start-UDDashboard -Dashboard $dashboard -Port 10005

If you want the numbers to automatically refresh, then you need to use the -AutoRefresh -RefreshInterval 15 which would then refresh these numbers being automatically generated by the get-random cmdlet every 15 seconds (you can specify any number here which is represented in seconds). For this example I only wanted the numbers refreshing on a page load hence I did not include those additional parameters on the endpoint parameter.

placeholder

Conclusion

As I was about to write this I just posted this component to the powershell gallery which if you search simpleud you will see all my collection of components I have done. I hope this helps to inspire you to get building your own custom component for this awesome module which is powershell universal dashboard