DIM (Dynamic Indicator Maker) SVG Images

DIM (Dynamic Indicator Maker)

Hey everyone! I created a new tool that creates fancy SVG based indicators that dynamically update based on an assigned percent complete column in your app.

2X_4_403b38038db71562bc70403eb2340eccdcdc7408.png

SVG stands for Scaleable Vector Graphics and these file types are special in that they are infinitely scaleable. Instead of being made of pixels like a regular image type, they are made from vectors, rays, circles, paths, etc so you can make the image as large (or small) as you need and the device will render these graphics on the fly in real-time without any quality loss.

Because SVG graphics are rendered in real-time we can create indicators that update dynamically as the value of another column changes. These images can be used as headers in โ€œdetailโ€ views, inline images in your โ€œtableโ€ views or an image in your โ€œdeckโ€ view. Below are just a few examples:

I have made this tool available as a sample app that can be found at the link below:

DIM (Dynamic Indicator Maker)

Here are some quick tips to get started:

  1. Enter the name of the โ€œpercent column typeโ€ you will be using in your app into the DIM tool.

  2. Select whether you want a circle, horizontal bar or vertical indicator.

  3. Adjust the corners of your indicator using the sliders provided.

  4. Change the colors of the indicator based on your preferences (you need to use hex codes, click the pallet icon above this section to open up htmlcolorcodes.com. You can adjust the progress color, background color and the text color.

  5. As you make these selections, you can view a realtime preview of the indicator you are making at the top of the screen*.

  6. When you are happy with the look, simply copy the formula provided at the bottom (or right side of the screen if in full screen) and create an โ€œimage type virtual columnโ€ in your app with the formula provided.

There are many more opportunities with this idea. I would love to see if anyone from the community can take this idea and make it even better. Please copy!

*while the app will show that values are trying to sync, this has no effect on what you see on the screen. All calculations are handled via virtual columns so all results/changes are instant.

51 45 8,346
  • UX
45 REPLIES 45

Cool tool! Super useful
@Grant_Stead @Suvrutt_Gurjar @Fabian @Rich

Thumbnails

One thing you might consider adding is dynamic svg thumbnails as a substitute for the native THUMBNAIL() function which relies on external thumbnail services. A simple thumbnail could be:

<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 80 80">
<rect width="100%" height="100%" fill="rgb(67, 135, 191)"/>
<text font-family="Sans-Serif" font-size="35px" text-anchor="middle" fill="white" x="50%" y="65%">JS</text>
</svg>

Which would render as:
2X_3_33225aeff9db7405d2f3fac008caf3a474601028.png

You could also get creative to create more rich dynamic thumbnails, such as highway placards: 2X_3_3f495097c161e654c38db9074d4f5d73121ea5ef.png

Dynamic Form Elements

One limitation of AppSheet that can be solved with SVGโ€™s is the creation of dynamic form headers/text or animations within forms. AppSheets format rules are applied upon initiating the form view - they DO NOT recalculate upon changing values in a form until after the form is saved.

For example, you might want text to show up as โ€œEverythings Good!โ€ in green, and then change to โ€œWarning!โ€ as red depending on specified values. Currently, the text will change, but the format rules which dictate its color will not. To get the desired behaviour without SVGโ€™s appsheet requires two virtual columns that are preformatted, and SHOW() rulesets to hide one or the other.

I have also used SVGโ€™s in applications to display dynamic images in forms. One example is modifying an excavator to appear to be digging further down / deeper as a user adjusts a numerical range column indicating depth. Another example is highlighting portions of serialized text as users input it:

2X_e_e0d80fe3d3a19d1b8628bf653ea9ec7ec7ccaeae.png

Pie Charts

You can read about how to create SVG pie charts here:

This is an awesome helpful tool. Thank you very much @Rich
Here are some Ideas:

  • When you choose โ€œCircleโ€ the [textColor] takes effect only for the โ€œ%โ€ sign, not for the Number value. Thatโ€™s because in your expression the Color value is static: fill=""rgb(88,89,91)""
  • You could add an Enum to choose the text font-family according to the fonts AppSheet offers under UX --> OPTIONS --> FONTS
  • For what do you use the columns [width] and [high] ?

Thanks @Fabian for the feedback. Good catch Ill be sure to update to app!

These were left in the app for future development, I wanted to give the option for folks to define the dimensions of the image instead of being static. For example you may want a horizontal bar that is thinner or thicker

@Grant_Stead You are right it was a pain to test these, iOS was very finicky. However, I have tested all the SVG options with apps iOS, PC, Mac, Android and in Chrome and Safari browsers. That said, if anyone sees an issue with other browsers Ill be sure to take a look at it.

Thanks a lot for this handy tool, @Rich_E! Is there a version of the sample app where the fix for the text color in the circle indicator was applied? The sample app version linked from the original post still has that issue.

This is amazing! Thank you.

Ok, Iโ€™m curious.
There was a massive thread in which @Jonathon and @Fabian really went back and forth on this, they even started a community based app with another member. This is how I learned about itโ€ฆ

One of the reasons I donโ€™t use SVG is because it didnโ€™t seem stable on different devices. Has appsheet fixed that, and SVG is better supported now?

This is awesome and makes creating the code for these indicators wicked easy!!

For colors, the app could include @Fabian color mixer found here:

Thank you @Rich. The DIM app is very neat with various settings that user can make to create an indicator of oneโ€™s chosen type , color choice and few other options. These indicators will make the app user experience much richer and certainly have numerous use cases wherever progress, status needs to be shown in the app.

Would appreciate further insights by you all - @Rich, @Jonathon and @Fabian on the points mentioned by @Grant_Stead as to how these SVG based indicators will render on various devcies.

Unless something has changed recently, the current limitations of SVGโ€™s in AS are:

  • They do not render properly in every browser, specifically older versions of internet explorer which plague most PCโ€™s
  • The SVGs always use the browsers default serif or sans-serif fonts, which are different across devices and browsers.
    • This is sometimes undesirable as the kerning and character widths vary which can cause text to run out of the viewport if you arenโ€™t careful.
    • It also introduces some inconsistency between other in-app fonts.
  • When SVGโ€™s reach a certain level of complexity, they may cause the application to run slowly. For example, undraw.co images if inserted as SVG code will result in a noticeable pause when switching between views containing them.
  • SVG images do not work with workflow templates. They will not show up in printed PDFโ€™s or work with the SNAPSHOT() function.
  • SVGโ€™s that include RASTERED images as part of the graphic will not work in AppSheet
  • SVGโ€™s can be used in the application branding backgrounds and logo. However, creating desktop or home screen shortcuts of applications with SVG logos will NOT work. Only use SVG logos for applications that will be accessed indirectly/via app launchers.

I will edit this as I think of more.


You could work around some of these limitations with a user setting (display enhanced graphics option, and then include a warning about not working on older browsersโ€ฆ)

@Grant_Stead @Suvrutt_Gurjar @Fabian @Rich @morgan

Thank you @Jonathon. Your insights are very useful as usual.

@Felipe_Engelberger_A

Oh thatโ€™s a shame, thank you anyway Fabian! I have been looking at an idea to show graphs in my reports using the script in google docs script tools but I donโ€™t know how to connect the Gdocs script tools with appsheet workflow report generator. Any idea on work around to maybe save an SVG to PNG to a Gdrive folder and the showing that pre saved image in the report. Any idea is welcome!

@Felipe_Engelberger_A Using Integromat and Cloud Convert Service as explained here. (instead of converting PDF in your case you convert SVG)

If no one else has come across this, I thought I would share. I (so far) have successfully imported a font for use in rendering SVGs in AppSheet. This can be done by converting the font to Base64:

"data:image/svg+xml;utf8,<svg xmlns=""http://www.w3.org/2000/svg"" viewBox=""0 0 100 50"">
<defs>
    <style type=""text/css"">
        @font-face {
            font-family: 'Roboto';
            font-style: normal;
            font-weight: 400;
            src: url(data:application/font-woff;charset=utf-8;base64, <...YOUR BASE64 CODE HERE...>) format('woff');
        }
    </style>
</defs>
    <text font-family=""Roboto"" ...other settings... >"&
        [Your Text]
    &"</text>
</svg>"

Replacing all of <โ€ฆYOUR BASE64 CODE HEREโ€ฆ> with your actual Base64 code from the converted .WOFF file. I literally canโ€™t show it here as it exceeds the maximum size limitations of a single post.

I think everything is double quoted correctly. I canโ€™t test it on everything though, so feel free to let me know if this doesnโ€™t work for other browsers/devices. As a proof of concept:
Default
3X_a_1_a1146e4ebeb8ea852dad56074976c83ba663d36a.png
vs
Roboto
3X_3_4_34143943e9eb6254c64f11231a08fe7c084b9355.png

The reason for this is because when the views are laid out the image is placed inside an HTML <img> tag which kills the ability to link to an external google font all easy peasy - appropriately as a security measure within the HTML itself. The downside being that this method can seriously impact rendering time and trying to navigate the editor with that giant string is a pain (did all the work in notepad).

Edit: After some testing between a VC and regular image column (and ~3000 rows) with the embedded font in the SVG, the performance difference is negligible (within 2 seconds of each other). Average full sync time: 45 seconds. Of which, I only force a full sync at specific moments (and might be able to completely eliminate).

And to make the editor less likely to struggle, I threw the Base64 code into a separate table so I can just grab it. This will, of course, also facilitate the use of multiple fonts if I so choose.

Super cool thanks

Thatโ€™s awesomeโ€ฆ
So then youโ€™re kinda posting the โ€œofficialโ€ Appsheet has tested and approves these specific SVG expressions to be used? โ€œBut, disclaimer SVG is still garbage town in internet explorer/Edge. But Appsheet doesnโ€™t โ€œreallyโ€ support these anywayโ€ฆโ€

One way AppSheet could help eliminate internet explorer use (sorry MSFT) is by making it easier for app developers to deploy progressive webapp installers for Chrome.

Thanks for sending me to my google machineโ€ฆ

Yep. If a browser supports SVG then I will see if I can fix any compatibility issues.

I was so excited about this App that I thought it should be possible to built an own Color Picker.
I already made this Color Picker for RGB, but I thought thatโ€™s not very handy.

So here you go

@Fabian That is awesome! You guys are so creative!

Dude, this is insanely creative!

@Fabian that is awesome! Amazing idea. When you have it ready to go, DM me and ill update the sample app.

Keep the ideas coming!

Hi @Rich Please feel free to grab the Color Picker from my App:
appName=DynamicIndicatorMaker-549987

Thanks for all these wonderful ideas and explanations. This is a very supportive community with a great archive.

Is @Fabian_Weller's color picker incorporated into @Rich_E's DIM or otherwise shared somewhere? I'm not finding it in the sample app linked from the original post nor among the other links in this conversation.

@dbaum I put it on my Portfolio Page

https://www.appsheet.com/portfolio/549987

Found it. Thanks for sharing!

This is great! It opens so many doors.

Iโ€™m having problems making it work on some browsers: Firefox (show only when click the image - desktop and mobile) and Edge (doesnt show at all).

It works perfectly on Chrome.

Hi Hugo - admittedly my testing of firefox has been minimal, but when I last checked my SVGโ€™s were working in that browser.

Care to share your svg code so I can rule out anything obvious?

Jon

Ill check into the Firefox issue. Not much I can do with Edge at this time. Last I check they had poor support of SVGs.

Cool looking tool. I think something is wrong though. Hereโ€™s what I see. On Firefox here, and just updated this morning.

Iโ€™m facing this exactly same problem on Firefox with any SVG, even on the DIM app. The SVG image appears briefly when I click on the blank box.

Interesting. Just doing some testing of my applications on Firefox now. All SVGโ€™s are working, but some are missing elements:

2X_2_2f9f420eb099148c76bb9c318ccf7614f3037d19.png

In my case it appears FireFox does not like a certain pattern of <Path> that render fine in other browsersโ€ฆ

I suspect there is some element in the SVGโ€™s generated by the DIM app that firefox is offended by, but it is certainly fixable. My radial progress bars/etc are working in FF.

Hi everyone do you have an idea on how can I insert one of the SVG graphs into a GoogleDocs Template report? Thank you in advance

You should be able to just add the virtual column into the template just like any other image.

Oh I understand, when I tried adding the virtual column I got the following error when I try to generate the PDF report, any idea on what Iโ€™m doing wrong? Thanks

Error: โ€œSystem.Exception: Failed to remove file extension from file name 'data:image/svg+xml;utf8, <svg xmlns=โ€œhttp://www.w3.org/2000/svgโ€ viewBox=โ€œ0 0 170 30โ€> \n\n\n <linearGradient id=โ€œgrad1โ€ x1=โ€œ0%โ€ y1=โ€œ0%โ€ x2=โ€œ100%โ€ y2=โ€œ0%โ€>\n <stop offset=โ€œ0%โ€ style=โ€œstop-color:%23008CE9;stop-opacity:1โ€ />\n <stop offset=โ€œ100%โ€ style=โ€œstop-color:%23008CE9;stop-opacity:1โ€ />\n \n \n<rect x=โ€œ10โ€ y=โ€œ5โ€ rx=โ€œ13โ€ ry=โ€œ10โ€ width=โ€œ150โ€ height=โ€œ20โ€ stroke=โ€œblackโ€ fill=โ€%23F3F3F3" />\n\n\n <rect x=โ€œ10โ€ y=โ€œ5โ€ rx=โ€œ13โ€ ry=โ€œ10โ€ width=โ€œ94.5โ€ \n\nheight=โ€œ20โ€ stroke=โ€œblackโ€ fill=โ€œurl(%23grad1)โ€ stroke-opacity=".5" />\n\n<rect x=โ€œ10โ€ y=โ€œ5โ€ rx=โ€œ13โ€ ry=โ€œ10โ€ width=โ€œ150โ€ height=โ€œ20โ€ stroke=โ€œblackโ€ stroke-width = โ€œ2โ€ fill=โ€œnoneโ€ />\n\n<text font-family=โ€œRoboto,Arial,sans-serifโ€ font-size=โ€œ20pxโ€ font-weight=โ€œ300โ€ stroke-width=โ€œ5โ€ text-anchor=โ€œmiddleโ€ fill="%23000000" x=โ€œ50%โ€ y=โ€œ22โ€>21%\nโ€™ because it contains Invalid characters: โ€˜"โ€™ (Hex Character โ€˜0022โ€™) โ€˜<โ€™ (Hex Character โ€˜003Cโ€™) โ€˜>โ€™ (Hex Character โ€˜003Eโ€™) โ€˜white space characterโ€™ (Hex Character โ€˜000Aโ€™) \r\n at Nirvana.Data.TemplateUtilities.GetFileNameWithoutExtension(String path) in d:\a\1\s\V2API\Workflow\Template\TemplateCommon\TemplateUtilities.cs:line 208\r\n at Nirvana.Data.ReplaceTemplateExpressions.ConstructImageValue(Context context, AppType appType, String src, String tableName, AllowedFormatSettings formatSettings) in d:\a\1\s\V2API\Workflow\Template\TemplateExpression\ReplaceTemplateExpressions.cs:line 172\r\n at Nirvana.Data.ReplaceTemplateExpressions.GetExpressionReplacementValue(Context context, WorkflowTemplateBindContext bindContext, TemplateExpression templateExpression, String tableName, Int32 columnSliceMapping, Change change, AppDataContext appDataContext, UpdateModeEnum updateMode, EmailExpressions emailExpressions) in d:\a\1\s\V2API\Workflow\Template\TemplateExpression\ReplaceTemplateExpressions.cs:line 503\r\n at Nirvana.Data.ReplaceTemplateExpressions.Replace(Context context, WorkflowTemplateBindContext bindContext, String templateText, TemplateExpressions templateExpressions, String tableName, Int32 columnSliceMapping, Change change, AppDataContext appDataContext, UpdateModeEnum updateMode, EmailExpressions emailExpressions, AppErrors appErrors) in d:\a\1\s\V2API\Workflow\Template\TemplateExpression\ReplaceTemplateExpressions.cs:line 677\r\n at Nirvana.Data.TemplateHtml.ReplaceTemplateExpressions(Context context, WorkflowTemplateBindContext bindContext, XElement rootElement, String tableName, Int32 columnSliceMapping, Change change, AppDataContext appDataContext, UpdateModeEnum updateMode, EmailExpressions emailExpressions, AppErrors appErrors) in d:\a\1\s\V2API\Workflow\Template\TemplateHtml\TemplateHtml.cs:line 53\r\n at Nirvana.Data.TemplateHtml.Replace(Context context, WorkflowTemplateBindContext bindContext, String tableName, Boolean compatibilityMode, Int32 columnSliceMapping, Change change, AppDataContext appDataContext, UpdateModeEnum updateMode, EmailExpressions emailExpressions, Templates templates, AppErrors appErrors) in d:\a\1\s\V2API\Workflow\Template\TemplateHtml\TemplateHtml.cs:line 82\r\n at Nirvana.Data.TemplateHtml.Replace(Context context, WorkflowTemplateBindContext bindContext, String tableName, Boolean compatibilityMode, Int32 columnSliceMapping, Change change, UpdateModeEnum updateMode, EmailExpressions emailExpressions, Templates templates, AppErrors appErrors) in d:\a\1\s\V2API\Workflow\Template\TemplateHtml\TemplateHtml.cs:line 273\r\n at Nirvana.Data.Templates.Replace(Context context, WorkflowTemplateBindContext bindContext, String tableName, Int32 columnSliceMapping, Change change, UpdateModeEnum updateMode, EmailExpressions emailExpressions, AppErrors appErrors) in d:\a\1\s\V2API\Workflow\Template\TemplateCommon\Templates.cs:line 74\r\n at Nirvana.Data.WorkflowTemplate.Replace(Context context, Int32 columnSliceMapping, Change change, UpdateModeEnum updateMode, EmailExpressions emailExpressions, AppErrors appErrors) in d:\a\1\s\V2API\Workflow\Template\WorkflowTemplate\WorkflowTemplate.cs:line 686\r\n at Nirvana.Data.WorkflowActionEmail.GetAttachment(Context context, String tableName, Int32 columnSliceMapping, Change change, UpdateModeEnum updateMode, EmailExpressions emailExpressions, AppErrors appErrors) in d:\a\1\s\V2API\Workflow\Action\WorkflowActionEmail.cs:line 228\r\n at Nirvana.Data.WorkflowActionEmail.Create(Context context, String tableName, Int32 columnSliceMapping, Change change, UpdateModeEnum updateMode, ActionDefinition actionDefinition, WorkflowLogEvent workflowLogEvent) in d:\a\1\s\V2API\Workflow\Action\WorkflowActionEmail.cs:line 49\r\n at Nirvana.Data.WorkflowRuleEvaluator.CreateActionResults(Context context, WorkflowActionBase workflowAction, AppTemplate appTemplate, String tableName, Int32 columnSliceMapping, Change change, UpdateModeEnum updateMode, WorkflowLogEvent workflowLogEvent) in d:\a\1\s\V2API\Workflow\Evaluators\WorkflowRuleEvaluator.cs:line 126\r\n at Nirvana.Data.WorkflowRuleEvaluator.PerformActions(Context context, AppTemplate appTemplate, String tableName, Int32 columnSliceMapping, Change change, UpdateModeEnum updateMode, WorkflowLogEvent workflowLogEvent) in d:\a\1\s\V2API\Workflow\Evaluators\WorkflowRuleEvaluator.cs:line 355\r\n at Nirvana.Data.WorkflowRuleEvaluator.ProcessRule(Context context, String tableName, Int32 columnSliceMapping, Change change, UpdateModeEnum updateMode) in d:\a\1\s\V2API\Workflow\Evaluators\WorkflowRuleEvaluator.cs:line 492"

Based on this part of the message it seems some of the characters used in the code are not considered valid. I would take a very careful look at how you have built the string - especially at the placement of quotations.

By the way, Does the Virtual Column show the information correctly?

yes it works perfectly

Really amazing @Rich thanks

Top Labels in this Space