Example
- Sarah Padilla (Unlicensed)
Here is an example of what can be done with the dashboard. In this example we have three buttons. The first one with mixed data (a point, icon gauge, and AM chart). The next button displays all the virtual points on that graphic. The last button is based off a query, and shows the items returned from the query.
Ractive Code
Here is the code for the main Ractive component. Drag out Ractive rom the components menu and under properties click on Ractive Editor and copy and paste the corresponding code in the following tabs of the editor.
Template
<div class="fin horizontal wrap flex"> {{#each points}} <div class="bottom vertical fin flex view-container pla mst msl s-container"> {{> view }} <div class="horizontal fin fWd s-height"> <label class="{{btIcon}} fin mnv s-icon pnr" on-click="today"> {{btIconText}}</label> {{> options }} </div> </div> {{/each}} </div> {{#partial icon}} <div class="horizontal fin fHt fWd middle"> {{#if ./mainIconImage}} <img src="{{mainIconImage}}" alt="{{mainIcon}}" style="height:50px;"> {{else}} <label class="{{mainIcon}}" style="color: {{iconColor}}; font-size: 3em;"></label> {{/if}} <div class="fin middle vertical center fHt fWd "> <label class="s-topLabel psb"> {{mainText}}</label> <label class="s-bottomLabel"> {{mainValue}}</label> </div> </div> {{/partial}} {{#partial amChart}} <div id="{{amId}}" class="horizontal fin n-chart mnb"></div> {{/partial}} {{#partial battery}} <div class="horizontal fin fHt fWd middle "> <div class="svgIcon"> <svg id="battery" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 40 100"> <title>battery</title> <rect id="valueIndicator" x="-34" y="-94" width="28" height="{{./fillValue}}" transform="rotate(180 0 0)" style="fill:#22b573" /> <polygon points="14.37 68.13 17.77 52.65 12.9 52.65 15.53 38.54 25.26 38.54 21.8 48.22 27.1 48.22 14.37 68.13" style="opacity:0.1" /> <path id="background" d="M62,6H59V2a2,2,0,0,0-2-2H43a2,2,0,0,0-2,2V6H38a8,8,0,0,0-8,8V92a8,8,0,0,0,8,8H62a8,8,0,0,0,8-8V14A8,8,0,0,0,62,6Zm2,86a2,2,0,0,1-2,2H38a2,2,0,0,1-2-2V14a2,2,0,0,1,2-2H62a2,2,0,0,1,2,2Z" transform="translate(-30)" style="fill:{{#if ./svgBackColor}}{{./svgBackColor}}{{else}}#d2d2d2{{/if}}" /> </svg> </div> {{> label }} </div> {{/partial}} {{#partial light}} <div class="horizontal fin fHt fWd middle "> <div class="svgIcon"> <svg id="light" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 100 100"> <defs> <clipPath id="clip-path"> <path d="M50,0C33.43,0,20,14.49,20,32.37a34.43,34.43,0,0,0,2.55,13.09s1.75,4.32,4.24,9c1.94,3.67,7.55,16.59,8.11,19.65L34,75.55V76.8l1,1.53h.33c0,.06,0,.12,0,.17v2H35L34,82v1.26l1,1.53h.34V87H35L34,88.5v1.26l1,1.53h.34v2.1L44.13,100H55.87l8.81-6.61v-2.1h.38l1-1.53V88.5l-1-1.53h-.38V84.81h.38l1-1.53V82l-1-1.53h-.38v-2c0-.06,0-.12,0-.17h.37l1-1.53V75.55l-.92-1.46c.56-3,6.16-15.92,8.1-19.59,2.49-4.71,4.24-9,4.24-9A34.43,34.43,0,0,0,80,32.37C80,14.49,66.57,0,50,0Z" style="fill:none" /> </clipPath> </defs> <title>light</title> <path id="background" d="M50,0C33.43,0,20,14.49,20,32.37a34.43,34.43,0,0,0,2.55,13.09s1.75,4.32,4.24,9c1.94,3.67,7.55,16.59,8.11,19.65L34,75.55V76.8l1,1.53h.33c0,.06,0,.12,0,.17v2H35L34,82v1.26l1,1.53h.34V87H35L34,88.5v1.26l1,1.53h.34v2.1L44.13,100H55.87l8.81-6.61v-2.1h.38l1-1.53V88.5l-1-1.53h-.38V84.81h.38l1-1.53V82l-1-1.53h-.38v-2c0-.06,0-.12,0-.17h.37l1-1.53V75.55l-.92-1.46c.56-3,6.16-15.92,8.1-19.59,2.49-4.71,4.24-9,4.24-9A34.43,34.43,0,0,0,80,32.37C80,14.49,66.57,0,50,0Z" style="fill:{{#if ./svgBackColor}}{{./svgBackColor}}{{else}}#d2d2d2{{/if}}" /> <g id="mask"> <g style="clip-path:url(#clip-path)"> <rect x="-100" y="-100" width="100" height="{{./fillValue}}" transform = "rotate(180 0 0)" style="fill:{{#if ./fillColor}}{{./fillColor}}{{else}}#1b75bc{{/if}}" /> </g> </g> </svg> </div> {{> label }} </div> {{/partial}} {{#partial snowflake}} <div class="horizontal fin fHt fWd middle "> <div class="svgIcon"> <svg id="snowflake" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 100 100"> <defs> <clipPath id="clip-path"> <path d="M92.16,70.73l-7.49-4.32,7.49-4.33A3.13,3.13,0,1,0,89,56.67L78.42,62.8l-7.28-4.21L86,50,71.13,41.41l7.28-4.21L89,43.33a3.13,3.13,0,0,0,3.13-5.41l-7.49-4.32,7.49-4.32A3.13,3.13,0,0,0,89,23.86l-7.49,4.32V19.53a3.13,3.13,0,1,0-6.25,0V31.79L68,36V18.8L53.13,27.4V19l10.62-6.13a3.13,3.13,0,1,0-3.12-5.41l-7.49,4.33V3.13a3.13,3.13,0,0,0-6.25,0v8.65l-7.5-4.33a3.13,3.13,0,1,0-3.12,5.41L46.88,19V27.4L32,18.8V36l-7.28-4.21V19.53a3.13,3.13,0,0,0-6.25,0v8.65L11,23.86a3.13,3.13,0,1,0-3.12,5.41l7.49,4.32L7.84,37.92A3.13,3.13,0,0,0,11,43.33L21.58,37.2l7.28,4.21L14,50l14.88,8.59L21.58,62.8,11,56.67a3.13,3.13,0,1,0-3.12,5.41l7.49,4.32L7.84,70.73A3.13,3.13,0,0,0,11,76.14l7.49-4.32v8.65a3.12,3.12,0,0,0,6.25,0V68.21L32,64V81.2l14.88-8.6V81L36.26,87.14a3.13,3.13,0,0,0,3.13,5.41l7.49-4.33v8.65a3.12,3.12,0,0,0,6.25,0V88.22l7.5,4.33a3.13,3.13,0,0,0,3.13-5.41L53.13,81V72.6L68,81.2V64l7.28,4.21V80.47a3.13,3.13,0,0,0,6.25,0V71.82L89,76.14a3.13,3.13,0,0,0,3.13-5.41ZM73.52,50l-8.63,5-8.63-5,8.63-5ZM61.76,29.63v10l-8.63,5v-10Zm-23.52,0,8.63,5v10l-8.63-5ZM26.48,50l8.63-5,8.63,5-8.63,5ZM38.24,70.37v-10l8.63-5v10Zm23.52,0-8.63-5v-10l8.63,5Z" style="fill:none" /> </clipPath> </defs> <title>snowflake</title> <path id="background" d="M92.16,70.73l-7.49-4.32,7.49-4.33A3.13,3.13,0,1,0,89,56.67L78.42,62.8l-7.28-4.21L86,50,71.13,41.41l7.28-4.21L89,43.33a3.13,3.13,0,0,0,3.13-5.41l-7.49-4.32,7.49-4.32A3.13,3.13,0,0,0,89,23.86l-7.49,4.32V19.53a3.13,3.13,0,1,0-6.25,0V31.79L68,36V18.8L53.13,27.4V19l10.62-6.13a3.13,3.13,0,1,0-3.12-5.41l-7.49,4.33V3.13a3.13,3.13,0,0,0-6.25,0v8.65l-7.5-4.33a3.13,3.13,0,1,0-3.12,5.41L46.88,19V27.4L32,18.8V36l-7.28-4.21V19.53a3.13,3.13,0,0,0-6.25,0v8.65L11,23.86a3.13,3.13,0,1,0-3.12,5.41l7.49,4.32L7.84,37.92A3.13,3.13,0,0,0,11,43.33L21.58,37.2l7.28,4.21L14,50l14.88,8.59L21.58,62.8,11,56.67a3.13,3.13,0,1,0-3.12,5.41l7.49,4.32L7.84,70.73A3.13,3.13,0,0,0,11,76.14l7.49-4.32v8.65a3.12,3.12,0,0,0,6.25,0V68.21L32,64V81.2l14.88-8.6V81L36.26,87.14a3.13,3.13,0,0,0,3.13,5.41l7.49-4.33v8.65a3.12,3.12,0,0,0,6.25,0V88.22l7.5,4.33a3.13,3.13,0,0,0,3.13-5.41L53.13,81V72.6L68,81.2V64l7.28,4.21V80.47a3.13,3.13,0,0,0,6.25,0V71.82L89,76.14a3.13,3.13,0,0,0,3.13-5.41ZM73.52,50l-8.63,5-8.63-5,8.63-5ZM61.76,29.63v10l-8.63,5v-10Zm-23.52,0,8.63,5v10l-8.63-5ZM26.48,50l8.63-5,8.63,5-8.63,5ZM38.24,70.37v-10l8.63-5v10Zm23.52,0-8.63-5v-10l8.63,5Z" style="fill:{{#if ./svgBackColor}}{{./svgBackColor}}{{else}}#d2d2d2{{/if}}" /> <g id="mask"> <g style="clip-path:url(#clip-path)"> <rect id="valueIndicator" x="-100" y="-100" width="100" height="{{./fillValue}}" transform="rotate(180 0 0)" style="fill:{{#if ./fillColor}}{{./fillColor}}{{else}}#27aae1{{/if}}" /> </g> </g> </svg> </div> {{> label }} </div> {{/partial}} {{#partial sun}} <div class="horizontal fin fHt fWd middle "> <div class="svgIcon"> <svg id="sun" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 100 100"> <defs> <clipPath id="clip-path"> <path d="M87,50,98.75,38.87,83.37,33.93l5.72-15.1L73.09,21,71.69,5,58.25,13.9,50,0,41.76,13.9,28.31,5,26.91,21l-16-2.22,5.73,15.1L1.25,38.87,13,50,1.25,61.13l15.39,4.94L10.91,81.17l16-2.22L28.31,95l13.46-8.94L50,100l8.24-13.89L71.69,95,73.09,79l16,2.22L83.37,66.07l15.38-4.94ZM50,80.35A30.35,30.35,0,1,1,80.35,50,30.35,30.35,0,0,1,50,80.35Zm0-54.93A24.58,24.58,0,1,0,74.58,50,24.61,24.61,0,0,0,50,25.42Z" style="fill:none" /> </clipPath> </defs> <title>sun&apos;</title> <path d="M87,50,98.75,38.87,83.37,33.93l5.72-15.1L73.09,21,71.69,5,58.25,13.9,50,0,41.76,13.9,28.31,5,26.91,21l-16-2.22,5.73,15.1L1.25,38.87,13,50,1.25,61.13l15.39,4.94L10.91,81.17l16-2.22L28.31,95l13.46-8.94L50,100l8.24-13.89L71.69,95,73.09,79l16,2.22L83.37,66.07l15.38-4.94ZM50,80.35A30.35,30.35,0,1,1,80.35,50,30.35,30.35,0,0,1,50,80.35Zm0-54.93A24.58,24.58,0,1,0,74.58,50,24.61,24.61,0,0,0,50,25.42Z" style="fill:{{#if ./svgBackColor}}{{./svgBackColor}}{{else}}#d2d2d2{{/if}}" /> <g id="mask"> <g style="clip-path:url(#clip-path)"> <rect id="valueIndicator" x="-100" y="-100" width="100" height="{{./fillValue}}" transform="rotate(180 0 0)" style="fill:{{#if ./fillColor}}{{./fillColor}}{{else}}#f7941d{{/if}}" /> </g> </g> </svg> </div> {{> label }} </div> {{/partial}} {{#partial light2}} <div class="horizontal fin fHt fWd middle "> <div class="svgIcon"> <svg id="light" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 100 100"> <defs> <clipPath id="clip-path" transform="translate(0 0)"> <path d="M70.44,26.24,51,29.91,72.79,19.23a3.12,3.12,0,0,0-2-5.87l-21.7,4.1L69.32,7.06a3.13,3.13,0,0,0-2-5.85L47.58,4.94A3.12,3.12,0,0,0,43.41.46L30.48,8.39a3.12,3.12,0,0,0,2.21,5.73l14.65-2.77L27.16,21.75a3.13,3.13,0,0,0,2,5.85l20.17-3.81L27.6,34.45a3.12,3.12,0,0,0,2,5.87l22-4.15L32.39,46.39a3.13,3.13,0,0,0,1.47,5.88,3,3,0,0,0,.58-.05l5.45-1v8.16H38.28a3.91,3.91,0,0,0-3.91,3.91v3.21c0,8.79,3.13,12.82,5.57,15.26a8.12,8.12,0,0,1,2.24,5.74v4.73a7.81,7.81,0,1,0,15.62,0V87.46a8.12,8.12,0,0,1,2.24-5.74c2.44-2.44,5.57-6.47,5.57-15.26V63.25a3.91,3.91,0,0,0-3.91-3.91H60.11v-12l6.61-1.25A3.12,3.12,0,1,0,65.56,40L53.37,42.28,72.49,32.07a3.12,3.12,0,0,0-2.05-5.83ZM53.86,48.54v10.8H46.14V50Z" style="fill:none" /> </clipPath> </defs> <title>light2</title> <path id="background" d="M70.44,26.24,51,29.91,72.79,19.23a3.12,3.12,0,0,0-2-5.87l-21.7,4.1L69.32,7.06a3.13,3.13,0,0,0-2-5.85L47.58,4.94A3.12,3.12,0,0,0,43.41.46L30.48,8.39a3.12,3.12,0,0,0,2.21,5.73l14.65-2.77L27.16,21.75a3.13,3.13,0,0,0,2,5.85l20.17-3.81L27.6,34.45a3.12,3.12,0,0,0,2,5.87l22-4.15L32.39,46.39a3.13,3.13,0,0,0,1.47,5.88,3,3,0,0,0,.58-.05l5.45-1v8.16H38.28a3.91,3.91,0,0,0-3.91,3.91v3.21c0,8.79,3.13,12.82,5.57,15.26a8.12,8.12,0,0,1,2.24,5.74v4.73a7.81,7.81,0,1,0,15.62,0V87.46a8.12,8.12,0,0,1,2.24-5.74c2.44-2.44,5.57-6.47,5.57-15.26V63.25a3.91,3.91,0,0,0-3.91-3.91H60.11v-12l6.61-1.25A3.12,3.12,0,1,0,65.56,40L53.37,42.28,72.49,32.07a3.12,3.12,0,0,0-2.05-5.83ZM53.86,48.54v10.8H46.14V50Z" transform="translate(0 0)" style="fill:{{#if ./svgBackColor}}{{./svgBackColor}}{{else}}#d2d2d2{{/if}}" /> <g id="mask"> <g style="clip-path:url(#clip-path)"> <rect id="valueIndicator" x="-100" y="-100" width="100" height="{{./fillValue}}" transform="rotate(180 0 0)" style="fill:{{#if ./fillColor}}{{./fillColor}}{{else}}#f7941d{{/if}}" /> </g> </g> </svg> </div> {{> label }} </div> {{/partial}} {{#partial energy}} <div class="horizontal fin fHt fWd middle "> <div class="svgIcon"> <svg id="energy" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 100 100"> <defs> <clipPath id="clip-path"> <polygon points="30.96 100 42.45 47.7 26 47.7 34.89 0 67.79 0 56.08 32.73 74 32.73 30.96 100" style="fill:none" /> </clipPath> </defs> <title>energy</title> <polygon id="background" points="30.96 100 42.45 47.7 26 47.7 34.89 0 67.79 0 56.08 32.73 74 32.73 30.96 100" style="fill:{{#if ./svgBackColor}}{{./svgBackColor}}{{else}}#d2d2d2{{/if}}" /> <g id="mask"> <g style="clip-path:url(#clip-path)"> <rect id="valueIndicator" x="-100" y="-100" width="100" height="{{fillValue}}" transform="rotate(180 0 0)" style="fill:{{#if ./fillColor}}{{./fillColor}}{{else}}#fff563{{/if}}" /> </g> </g> </svg> </div> {{> label }} </div> {{/partial}} {{#partial tree}} <div class="horizontal fin fHt fWd middle "> <div class="svgIcon"> <svg id="tree" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 100 100"> <defs> <clipPath id="clip-path"> <path id="mask" d="M87.51,44.75a10.4,10.4,0,0,0-4.17-8.33,10.41,10.41,0,0,0-4.79-16.91A10.42,10.42,0,0,0,65.28,7a10.37,10.37,0,0,0-12-2.22A10.41,10.41,0,0,0,34.51,7.59l-.4,0A10.43,10.43,0,0,0,23.68,18a10.56,10.56,0,0,0,.06,1.08h-.06a10.42,10.42,0,0,0-7.46,17.7,10.41,10.41,0,0,0,6.06,18.38,10.4,10.4,0,0,0,16.38,5.5l8.67,6.68S46.41,88.58,40,96.69l8.14-1.14L53.69,100l4.07-4.45,8.14.13S57,78.77,56.14,67.33l9.53-7a10.38,10.38,0,0,0,12.91-5.28A10.42,10.42,0,0,0,87.51,44.75ZM40.62,58.69a10.37,10.37,0,0,0,1.83-3.84,12.92,12.92,0,0,0,5.1,2.68l-.22,3.76ZM55,61.7l-.4-4.26a12.93,12.93,0,0,0,5-2.84A10.45,10.45,0,0,0,63.14,59Z" style="fill:none" /> </clipPath> </defs> <title>tree</title> <path id="background" d="M87.51,44.75a10.4,10.4,0,0,0-4.17-8.33,10.41,10.41,0,0,0-4.79-16.91A10.42,10.42,0,0,0,65.28,7a10.37,10.37,0,0,0-12-2.22A10.41,10.41,0,0,0,34.51,7.59l-.4,0A10.43,10.43,0,0,0,23.68,18a10.56,10.56,0,0,0,.06,1.08h-.06a10.42,10.42,0,0,0-7.46,17.7,10.41,10.41,0,0,0,6.06,18.38,10.4,10.4,0,0,0,16.38,5.5l8.67,6.68S46.41,88.58,40,96.69l8.14-1.14L53.69,100l4.07-4.45,8.14.13S57,78.77,56.14,67.33l9.53-7a10.38,10.38,0,0,0,12.91-5.28A10.42,10.42,0,0,0,87.51,44.75ZM40.62,58.69a10.37,10.37,0,0,0,1.83-3.84,12.92,12.92,0,0,0,5.1,2.68l-.22,3.76ZM55,61.7l-.4-4.26a12.93,12.93,0,0,0,5-2.84A10.45,10.45,0,0,0,63.14,59Z" style="fill:{{#if ./svgBackColor}}{{./svgBackColor}}{{else}}#d2d2d2{{/if}}" /> <g style="clip-path:url(#clip-path)"> <rect id="valueIndicator" x="-100" y="-100" width="100" height="{{./fillValue}}" transform = "rotate(180 0 0)" style="fill:{{#if ./fillColor}}{{./fillColor}}{{else}}#006838{{/if}}" /> </g> </svg> </div> {{> label }} </div> {{/partial}} {{#partial waterdrop}} <div class="horizontal fin fHt fWd middle "> <div class="svgIcon"> <svg id="water" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 100 100"> <defs> <clipPath id="clip-path"> <path d="M80,69.23C80,86.22,66.57,100,50,100S20,86.22,20,69.23,50,0,50,0,80,52.24,80,69.23Z" style="fill:none" /> </clipPath> </defs> <title>waterdrop</title> <path id="background" d="M80,69.23C80,86.22,66.57,100,50,100S20,86.22,20,69.23,50,0,50,0,80,52.24,80,69.23Z" style="fill:{{#if ./svgBackColor}}{{./svgBackColor}}{{else}}{{#if ./svgBackColor}}{{./svgBackColor}}{{else}}#d2d2d2{{/if}}{{/if}}" /> <g id="mask"> <g style="clip-path:url(#clip-path)"> <rect id="valueIndicator" x="-100" y="-100" width="100" height="{{./fillValue}}" transform="rotate(180 0 0)" style="fill:{{#if ./fillColor}}{{./fillColor}}{{else}}#27aae1{{/if}}" /> </g> </g> </svg> </div> {{> label }} </div> {{/partial}} {{#partial label}} <div class="fin middle vertical center fHt fWd "> <label class="s-topLabel psb"> {{mainText}}</label> <label class="s-bottomLabel"> {{mainValue}}</label> </div> {{/partial}} {{#partial showButtons}} <div class="fin horizontal right s-date middle"> <label class="mnv"></label> <select class="view-container s-select mnt" on-change="foldUpdate"> {{#foldOptions}} <option value="{{./val}}" {{#if ./val == ../fold}}selected{{/if}}>{{./label}}</option> {{/foldOptions}} </select> </div> {{/partial}} {{#partial hideButtons}} <div class="fin horizontal right s-date middle"> </div> {{/partial}}
Model
{ data : { points : null, pointPollId : null, pointIdToIndex : null, foldOptions : [{ label:'Live', val:'live' }, { label:'Min', val:'min' }, { label:'Max', val:'max' }, { label:'Avg', val:'avg' }], updatePoll : function(switchOff) { var oldPollId = this.get('pointPollId'); var self = this; // before you init a watch // close the old one first if (oldPollId) finstack.unbind(oldPollId); var points = this.get('points'); // after you've turned off the polling // just go back if the switch off flag is true // or when the points are not there, go back again if (!points || !points.length || switchOff) return; var ids = []; var idToIndex = []; points.forEach(function(p, index) { if (p.fold == 'live') { ids.push(p.pointId); idToIndex[p.pointId] = index; } }); if (!ids || !ids.length) return; var pollId = finstack.bindMultipleToMethod(ids, 'curVal', function(updatedVal, point) { var pObj = point.toObj(); var pIdToIdx = self.get('pointIdToIndex'); if (pIdToIdx && pIdToIdx[pObj.id]) self.set('points.' +pIdToIdx[pObj.id]+ '.mainValue', fin.Data.PointUtil.GetPrettyValue(pObj)); }); self.set({ pointPollId : pollId, pointIdToIndex : idToIndex }); }, updateChartForElementIdWithConfig : function(elementId, config) { setTimeout(function() { AmCharts.makeChart(elementId, config); }, 200) }, getUpdatedQueryStringForItem : function(item) { if (!item || !item.query) return ""; var query = item.query; var matches = query.match(/(\$[a-zA-Z0-9]+)/g); if (matches && matches.length) { matches.forEach(function(m) { var prop = m.replace('$', ''); query = query.replace(new RegExp("\\" +m, 'g'), item[prop]); }); } console.log("Returning the query: ", query); return query; } }, }
Style
.s-container{ min-width: 300px; } .s-height{ height: 40px; border-top: solid #d2d2d2; } .s-icon{ font-size: 16px; width:50%; font-weight: bold; } .s-date{ width:50%; } .n-chart{ min-height: 350px; max-height: 400px; min-width: 500px; } .s-bottomLabel{ font-size: 2vw; font-weight: bold; } .s-topLabel{ font-size: 1.3vw; } .iconHeight{ min-height: 400px; max-height: 450px; } .svgIcon{ height:100px; width:125px; } .s-select{ height:24px; width:85px; } .fHt{ height: 100%; } .fWd{ width: 100%; } .horizontal{ display: flex; flex-direction: row; } .middle{ align-items: center; } .vertical{ display: flex; flex-direction: column; } .center{ align-items: center; } .wrap{ flex-wrap: wrap; } .flex{ flex: 1 1 auto; } .mst{ margin-top: 5px; } .msl{ margin-left: 5px; } .mnv{ margin-top: 10px; margin-bottom: 10px; } .mnt{ margin-top: 10px; } .mnb{ margin-bottom: 10px; } .pla{ padding: 15px; } .pnr{ padding-right: 10px; } .psb{ padding-bottom: 5px; } .bottom{ justify-content: flex-end; } .right{ justify-content: flex-end; }
Init
var self = this; var model = self.ractive; model.observe('points.*.view points.*.query', function(nVal,oVal,kPath){ var pathToPoint = kPath.substring(0, kPath.lastIndexOf('.')); var point = model.get(pathToPoint); if (point) { if (kPath.indexOf('query') != -1) { var nQuery = model.get('getUpdatedQueryStringForItem').call(model, point); if (!nQuery || !nQuery.length) return; finstack.eval(nQuery).then(function(data) { if (data && data.result && !data.result.isErrorGrid) { point.chartConfig.dataProvider = data.result.toObj(); model.get('updateChartForElementIdWithConfig').call(model, point.amId, point.chartConfig); } else { console.log(data); } }, function(err) { console.error(err); }); } else if (point && point.view == 'amChart') { model.get('updateChartForElementIdWithConfig').call(model, point.amId, point.chartConfig); } } }); model.on('unrender', function() { model.get('updatePoll').call(model, true); }); model.on('foldUpdate', function(event) { var point = model.get(event.resolve()); var fVal = event.node.value; model.set(event.resolve()+ '.fold', fVal); model.get('updatePoll').call(model); if (fVal != 'live') { var q = 'readById(' +point.pointId+ ').hisRead(' +point.range+ ').foldCol("v0",'+point.fold+')'; console.log("Setting out...", q); finstack.eval(q).then(function(data) { model.set(event.resolve()+ '.mainValue', fin.Data.PointUtil.GetPrettyValue(point.original,data.result.toObj(false,false,true))); }, function(err) { console.log(err); }); } }); this.ractive.on("calendar", function(event){ var point = self.ractive.get(event.resolve()); var model = self.ractive; top.app.ShowCalendar(true,function(calEvent){ var date = top.app.Utils.DateRangeToAxonDate(calEvent.range, calEvent.mode); model.set(event.resolve()+ '.range', date);//.then(function() { if (point.fold != 'live') { var q = 'readById(' +point.pointId+ ').hisRead(' +point.range+ ').foldCol("v0",'+point.fold+')'; console.log("Setting out...", q); finstack.eval(q).then(function(data) { model.set(event.resolve()+ '.mainValue', fin.Data.PointUtil.GetPrettyValue(point.original,data.result.toObj(false,false,true))); }, function(err) { console.log(err); }); } }, {periods:true}); }); // Init Data self.ractive.set({points: [{ mainIcon: "sm-oil", iconColor: "#3488b2", mainText: "Main Water", mainValue: "150L", btIcon: "icon-calendar", btIconText: "Today", view: 'icon', range:"Date", options: "hideButtons" },{ mainIcon: "icon-location", iconColor: "red", mainText: "Rain Water", mainValue: "50L", btIcon: "icon-calendar", btIconText: "Today", view: 'waterdrop', fillColor:"lightblue", svgBackColor:"#d2d2d2", fillValue:50, myStart:"Select", myEnd:"Date", options: "hideButtons" },{ mainIcon: "icon-graph-line", iconColor: "#b083e0", mainText: "Errors", mainValue: "23", btIcon: "icon-graph-line", btIconText: "Data", view: 'amChart', options: "hideButtons", amId: top.app.Utils.GetPseudoId(), range:"today()", fold:"avg", chartConfig: { "type": "pie", "theme": "light", dataProvider: [{ "country": "IT", "value": 31.32 }, { "country": "Heating", "value": 27.47 }, { "country": "Cooling", "value": 25.55 }, { "country": "Lighting", "value": 15.66 } ], "valueField": "value", "titleField": "country", "outlineAlpha": 0.4, "depth3D": 15, "balloonText": "[[title]]<br><span style='font-size:14px'><b>[[value]]:</b> ([[percents]]%)</span>", "angle": 30, "export": { "enabled": true } } }]});
Buttons
To add a button, drag and drop button from the HTML components under the components menu. To add the code, right click on the button and select create event, mouse, mouse click. It then will pull up a script editor. In the script editor copy and paste the code for the buttons.
Mixed Data Button
var ractiveComponent = query('stackRactive'); ractiveComponent.ractive.set('points',[{ mainIcon : "wi-fire", iconColor : "#c34c46", mainText : "Hot Water Boiler", mainValue : "80ºC", btIcon : "icon-location", btIconText : "Heating", view : 'icon', options : "hideButtons", range :"Date" },{ mainIcon : "icon-location", iconColor : "red", mainText : "Energy", mainValue : "66%", btIcon : "icon-calendar", btIconText : "Today", view : 'light2', options : "hideButtons", fillValue : 66, myStart : "Select", myEnd : "Date" },{ mainIcon : "sm-oil", iconColor : "#3488b2", mainText : "Main Water", mainValue : "150L", btIcon : "icon-graph-line", btIconText : "Data", mainText2 : "Rain Water", mainValue2 : "50L", view : 'amChart', options : "hideButtons", amId : top.app.Utils.GetPseudoId(), range :"today()", query :'dashboardData()', chartConfig : { "type" : "serial", "theme" : "light", "marginRight" : 80, "dataProvider" : null, "valueAxes" : [{ "axisAlpha" : 0.1 }], "graphs": [{ "balloonText" : "[[title]]: [[value]]", "columnWidth" : 20, "fillAlphas" : 1, "title" : "Energy", "type" : "column", "valueField" : "v0" }, { "balloonText" : "[[title]]: [[value]]", "lineThickness" : 2, "title" : "intra-day", "valueField" : "v1" }], "zoomOutButtonRollOverAlpha" : 0.15, "chartCursor": { "categoryBalloonDateFormat" : "MMM DD JJ:NN", "cursorPosition" : "mouse", "showNextAvailable" : true }, "autoMarginOffset" : 5, "columnWidth" : 1, "categoryField" : "ts", "categoryAxis" : { "minPeriod" : "hh", "parseDates": true }, "export": { "enabled": true } }}]);
Virtual Point Button
This component will display all the virtual points in the graphic
var ractiveComponent = query('stackRactive'); var virtualPoints = queryAll('virtualPoint and curVal'); var myPoints = []; virtualPoints.forEach(function(item){ myPoints.push({ mainIcon : "icon-location", iconColor : "#c9b4e0", mainText : item.navName, mainValue : GetPrettyValue(item), btIcon : "sm-site", btIconText : item.siteRefDis, view : 'icon', range : "Today", options : "hideButtons", pollPointId : item.id }); }); ractiveComponent.ractive.set('points',myPoints);
Query Button
In line 3, is where we define the query. For this example we are reading 4 points.
var ractiveComponent = query('stackRactive'); finstack.eval("readAll(point and his and curVal).get(0..3)").then(function(data) { var points = []; var realPoints = data.result.toObj(); realPoints.forEach(function(p,index) { points.push({ mainIcon : "icon-graph-bar", iconColor : "#47a3da", backgroundColor : "#ff0000", mainText : p.navName, mainValue : fin.Data.PointUtil.GetPrettyValue(p), btIcon : "sm-site", btIconText : p.siteRefDis, view : 'icon', range : "today()", pointId : p.id, index : index, original : p, options : "showButtons", fold : "live" }); }); ractiveComponent.ractive.set({points:points}); ractiveComponent.ractive.get('updatePoll').call(ractiveComponent); }, function(err) { console.error(err); });