Recently I have been using Scalable Vector Graphics (SVG) in my applications, in place of typical raster images or even text in some cases. SVG graphics are defined through code, as per the examples here: https://www.w3schools.com/graphics/svg_examples.asp
As the images are defined with code, you can CONCATENATE() strings of code together while including application variables, to make the images dynamic. In this way, you could have animated images which react to user input.
Another thing to note, is SVG graphics scale/resize losslessly (unlike raster images). So everything will always look crisp! Also, when properly optimized, the file-sizes are often smaller than raster images.
There is a trade-off, in that the device must decode and render the graphics. Older devices/computers may have a hard time rendering poorly optimized or complex SVG code. Also, older browsers do not support some SVG functionality.
Some examples:
Richer looking detail headers, and small filesize gradient backgrounds:
SVG thumbnails, without having to rely on external services like Image Placeholder:
Dynamic progress bars:
Makes senseโฆ
How quickly do they load?
Hey Grant,
As long as your SVG graphics are properly optimized, their filesize will be much smaller than a similar .png or .jpg. In adition, the image clarity will be better and scale/resize lossless across devices.
As of yet, I have not had any issues rendering the svg images I have used. With this said, in my use cases loading times have improved vs similar png / jpg images.
One โdownsideโ is I have begun incorporating A LOT more images into my applications, since this functionality is so fun to mess around with. So, in some ways my performance may be net negative as a result of thisโฆ but really, it hasnโt been noticeable.
Bahaha, thatโs awesome!
so farโฆ faster than my PNGโs.
I havenโt used with Edge. There are some issues with how IE handles SVGโsโฆ
Just tested one of my apps in Edge. Static SVGโs encoded to base64, which are loaded from a database, work in Edge. Dynamic SVGโs stored in the app virtual columns do not appear to work.
So, I wouldnโt write SVGโs off completely if you have users in Edge. At the very least, static assets like banners and icons can be made use of.
While testing this, I also noticed a few global AppSheet UI bugs which occur in Edgeโฆ So if you have Edge users, this may not be your biggest concern
@Jonathon @Mike This is a little video showing you something iโm seeing, and iโm curious if you see this issue as well? Long story short, virtual column, type image, gets reset back to grey after syncโฆ
And, this is my code:
SWITCH([complete_pct],
100, CONCATENATE(
โdata:image/svg+xml;utf8,<svg xmlns=โโhttp://www.w3.org/2000/svgโ" viewBox="โ0 0 240 120"โ>
<text font-family="โRoboto,Arial,sans-serifโ" font-size="โ30pxโ" font-weight="โ300"โ text-anchor="โmiddleโ" fill="โrgb(88,89,91)โ" x="โ52.5%โ" y="โ60%โ">100<tspan font-size="โ20pxโ" fill="โrgb(167,169,172)โ" style="โbaseline-shift: superโ">%
<circle cx="โ120"โ cy="โ60"โ r="โ54"โ fill="โnoneโ" stroke="โlimeโ" stroke-width="โ12"โ />
"
),
CONCATENATE(โdata:image/svg+xml;utf8,<svg xmlns=โโhttp://www.w3.org/2000/svgโ" viewBox="โ0 0 240 120"โ>
<text font-family="โRoboto,Arial,sans-serifโ" font-size="โ30pxโ" font-weight="โ300"โ text-anchor="โmiddleโ" fill="โrgb(88,89,91)โ" x="โ52.5%โ" y="โ60%โ">",[complete_pct],"<tspan font-size="โ20pxโ" fill="โrgb(167,169,172)โ" style="โbaseline-shift: superโ">%
<circle cx="โ120"โ cy="โ60"โ r="โ54"โ fill="โnoneโ" stroke="โsilverโ" stroke-width="โ12"โ />
<circle cx="โ120"โ cy="โ60"โ r="โ54"โ fill="โnoneโ" stroke="โblueโ" stroke-width="โ12"โ stroke-dasharray="โ339.292"โ stroke-dashoffset=""",339.292*(1-([complete_pct]/100)),""" transform="โrotate(-90 120 60)โ"/>
")
)
Grant, are you experiencing that behavior in Chrome as well? Specifically regarding the virtual column resetting itself, I have not experienced that.
Regarding the SHOW() type resizing, try changing your viewBox variable to โ0 0 120 120โ instead of " 0 0 240 120"
For your troubleshooting, maybe try a simplified svg, without the SWITCH() clause:
CONCATENATE(โdata:image/svg+xml;utf8,<svg xmlns=โโhttp://www.w3.org/2000/svgโ" viewBox="โ0 0 120 =120"โ>
<text font-size="โ30pxโ" font-weight="โ300"โ text-anchor="โmiddleโ" fill="โrgb(88,89,91)โ" x="โ52.5%โ" y="โ60%โ">",[complete_pct],"<tspan font-size="โ20pxโ" fill="โrgb(167,169,172)โ" style="โbaseline-shift: superโ">%
<circle cx="โ120"โ cy="โ60"โ r="โ54"โ fill="โnoneโ" stroke="โsilverโ" stroke-width="โ12"โ />
<circle cx="โ120"โ cy="โ60"โ r="โ54"โ fill="โnoneโ" stroke="โblueโ" stroke-width="โ12"โ stroke-dasharray="โ339.292"โ stroke-dashoffset=""",339.292*(1-([complete_pct]/100)),""" transform="โrotate(-90 120 60)โ"/>
</svg>")
Also, note that the above code seems to have the word stylized โโ quotes. Iโm not sure how that will impact the performance, but its probably worth replacing them all with the UTF8 simple quotes (")
@Mike and @Jonathon Thank you for the help! My eyes are open now.
Jon, for posterity you should fix your code snippet itโs missing some code at the end of text, and missing the svg closureโฆ
I ended up with a single VC_Show column, and it looks great in the deck view and is responsive everywhereโฆ it seems you canโt put it as a background in detail, or on the card / gallery views. It still doesnโt render in Microsoft Edge, which is used in businesses way more than you imagineโฆ
Here is my code.
SWITCH([complete_pct],
100, CONCATENATE(
"data:image/svg+xml;utf8,<svg xmlns=""http://www.w3.org/2000/svg"" viewBox=""0 0 120 120"">
<text font-family=""Roboto,Arial,sans-serif"" font-size=""30px"" font-weight=""300"" text-anchor=""middle"" fill=""rgb(88,89,91)"" x=""52.5%"" y=""60%"">",[complete_pct],"<tspan font-size=""20px"" fill=""rgb(167,169,172)"" style=""baseline-shift: super"">%</tspan></text>
<circle cx=""60"" cy=""60"" r=""54"" fill=""none"" stroke=""Lime"" stroke-width=""12"" />
</svg>"),
CONCATENATE(
"data:image/svg+xml;utf8,<svg xmlns=""http://www.w3.org/2000/svg"" viewBox=""0 0 120 120"">
<text font-family=""Roboto,Arial,sans-serif"" font-size=""30px"" font-weight=""300"" text-anchor=""middle"" fill=""rgb(88,89,91)"" x=""52.5%"" y=""60%"">",[complete_pct],"<tspan font-size=""20px"" fill=""rgb(167,169,172)"" style=""baseline-shift: super"">%</tspan></text>
<circle cx=""60"" cy=""60"" r=""54"" fill=""none"" stroke=""lightgrey"" stroke-width=""12"" />
<circle cx=""60"" cy=""60"" r=""54"" fill=""none"" stroke=""Blue"" stroke-width=""12"" stroke-dasharray=""339.292"" stroke-dashoffset=""",339.292*(1-([complete_pct]/100)),""" transform=""rotate(-90 60 60)""/>
</svg>")
)
Edit, I guess I should drop a screen shot
@Grant_Stead youโr da man bud!
Meh, suffering through itโฆ
No pain, no gain buddy
Iโm Just uncomfortable with it not being decent in edgeโฆ
Yesโฆ there are gaps hereโฆ and it requires more comfort with raw SVG syntax than I might like, but you have to admit the potential is big!
If Appsheet could make a field type for this (to handle the compatibility issues, remove the need to pre-pend formula with โdata:image/svg+xml;utf8,โ, and automate the double quotes, i still think this is a way to make the Appsheet experience richer. Might only be 10-29 of users that work at this level, but even for Marketing the Appsheet solution, it might be worth it
As a side note, in a prior community comment, I suggested to @Peter that we add a section for โAdvanced Topicsโ like google script, svgโs, apiโs, etc - so people pushing the envelope had a way to discuss and not overload the โno codeโ section.
Agreed, it makes many, many things possibleโฆ Thanks for the primer course. I hope the team figures out a clean way to integrate it into the platform.
Thanks to @Jonathon for โpushing the envelopeโ!!!
Without a doubt! He is such a trouble maker
Some inspiration; my take on a mobile-friendly dashboard of sorts:
Hoping to add more to it when I can think of useful visualizations; maybe turn the produced/placed/wasted to a pie chart.
I have to admit โฆpain or not, he does nice work thoughโฆ
Nice layout @Jonathon!
Yes, it does it in chrome emulator and full and Androidโฆ
Iโll check out your recommendations and report back
Upon doing some testing today, I have not been able to get the svg images to display in reports
I recall someone from AppSheet had rigged something up to take a snapshot of the native AppSheet charts to include in reports. Would this system be modifiable to work with SVGโs?
In the meantime Iโm going to look into the possibility of using Zapier and some external API to convert the svg to pngโฆ
Thatโs interesting because AFAIK a template is first converted to HTML and SVG should render like in the browser before conversion to PDF.
Tagging @Phil
I think it was @brian that was introducing the SNAPSHOT() expression.
Hi @Jonathon did you find a way to include SVG in a Workflow PDF template?
Iโm getting this error Message:
System.Exception: Failed to remove file extension from file name 'data:image/svg+xml;utf8,<svg xmlns=\"http://www.w3.org/2000/svg\" height=\"100\" width=\"100\"> <circle cx=\"50\" cy=\"50\" r=\"40\" stroke=\"black\" stroke-width=\"3\" fill=\"blue\"/></svg>' because it contains Invalid characters: '\"' (Hex Character '0022') '<' (Hex Character '003C') '>' (Hex Character '003E')
My SVG looks like this:
โdata:image/svg+xml;utf8,<svg xmlns=""http://www.w3.org/2000/svg"" height=""100"" width=""100""> <circle cx=""50"" cy=""50"" r=""40"" stroke=""black"" stroke-width=""3"" fill=""blue""/></svg>โ
Hey Fabian, unfortunately as of my last tests, SVGs do not render in PDFs.
Adding @Phil
Straight up, itโs fun, but not near stable enough for production use.
I would say that you just need to know the limits of SVGs within AppSheet and work within those constraints. If your user base will be using edge or IE, I suppose this isnโt an option.
If your users are going to be heavily mobile based, there is no reason not to use them. When it comes to browsers, I have always instructed people to install chrome anyway so I could make an app shortcut on their desktop.
Agreed. Thatโs what Iโm saying though, itโs basically a hack, and Iโve seen these kinds of things fall apart with Appsheet before. So I would just issue caution. Example: using the VC show image with it in a deck view makes iOS not scroll the deckโฆ All Iโm saying is there is simply too many places in which it doesnโt work well. I do agree that itโs awesome, and I hope that appsheet supports it furtherโฆ
Yes we have the SNAPSHOT() expression but itโs still in a beta phase and not ready for the production.
@Jonathon Can you recomend a tool to convert a Logo (image) to a SVG path?
(Iโm not Jonathon, but I am a Graphic Designer)
Website I found: https://convertio.co/
What I got out of it was pretty solid using QREWโs Logo. (our logo has a lot of straight lines so I donโt know how itโd work with more organically shaped logos & text).
Ideally using Adobe Illustrator would be best but the barrier of entry has a paywall and learning curve. โInkscapeโ is apparently the best free software at converting pixel based images to vector.
Logos like QREWโs may work well with some of the online converters - more complex logos I have had better luck retracing in software like Inkscape or Illustrator.
Even in the case of a retraced logo, there is still a significant amount of โoptimizationโ that can be done by manually editing the SVG code, however.
What logo are you wanting to convert to SVG @Fabian
Canva, convertio
Thank you very much. I want to use the Font Awesome images.
I saw that you can download a SVG also from the Font Awesome page like
https://fontawesome.com/icons/bolt?style=solid
<svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="bolt" class="svg-inline--fa fa-bolt fa-w-10" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512"><path fill="currentColor" d="M296 160H180.6l42.6-129.8C227.2 15 215.7 0 200 0H56C44 0 33.8 8.9 32.2 20.8l-32 240C-1.7 275.2 9.5 288 24 288h118.7L96.6 482.5c-3.6 15.2 8 29.5 23.3 29.5 8.4 0 16.4-4.4 20.8-12l176-304c9.3-15.9-2.2-36-20.7-36z"></path></svg>
How can I use this in an AppSheet image column with Hex color #3F818D ?
I canโt get it done
the fill property should be set to that color; however โ#โ characters do not work unless you wrap them in ENCODEURL(). To avoid this I tend to just convert the HEX color to rgb, which are not prefaced with the #.
In this case, #3F818D = rgb(63,129,141)
Another thing you can do is remove much of the data classifiers, such as the data-icon=โboltโ, etc. This will reduce the size:
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512">
<path fill="rgb(63,129,141)" d="M296 160H180.6l42.6-129.8C227.2 15 215.7 0 200 0H56C44 0 33.8 8.9 32.2 20.8l-32 240C-1.7 275.2 9.5 288 24 288h118.7L96.6 482.5c-3.6 15.2 8 29.5 23.3 29.5 8.4 0 16.4-4.4 20.8-12l176-304c9.3-15.9-2.2-36-20.7-36z"></path>
</svg>
When you go to include this in appsheet, you will need to preface the code with
data:image/svg+xml;utf8,
And you may also have to double quote all of the quotes in the code for AppSheet to understand.
If you intend for this image to be static, then you could pre-encode it to base64 and just use that as your app formula:
data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAzMjAg%0D%0ANTEyIj4KPHBhdGggZmlsbD0icmdiKDYzLDEyOSwxNDEpIiBkPSJNMjk2IDE2MEgxODAuNmw0Mi42%0D%0ALTEyOS44QzIyNy4yIDE1IDIxNS43IDAgMjAwIDBINTZDNDQgMCAzMy44IDguOSAzMi4yIDIwLjhs%0D%0ALTMyIDI0MEMtMS43IDI3NS4yIDkuNSAyODggMjQgMjg4aDExOC43TDk2LjYgNDgyLjVjLTMuNiAx%0D%0ANS4yIDggMjkuNSAyMy4zIDI5LjUgOC40IDAgMTYuNC00LjQgMjAuOC0xMmwxNzYtMzA0YzkuMy0x%0D%0ANS45LTIuMi0zNi0yMC43LTM2eiI+PC9wYXRoPgo8L3N2Zz4=