Dynamic SVG graphics

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:

@morgan
@praveen

28 156 22.8K
  • UX
156 REPLIES 156

this link has 14 files, and a zip etc, just want to make sure you mean to have all this public,

Well the link is SUPPOSED to take you straight to the SVG file. But everything in that folder is my public folder.

EDIT: Nevermind, I see what you mean, but yeah, have at my Call of Cthulhu and Stellaris stuff.

Man this is cool. Good job Dave!

Thanks! Between this and the other thread, you guys helped a lot. Along with numerous Google searches, since none of the “internet” languages are a language I like and I won’t bother to commit learning fully.

The really fun part was figuring out a way to properly make that border match as the number of digits increases or decreases. And I’m also positive that I probably did it in the most backwards way. There is surely a much better way to accomplish what I did. But, I don’t know what that is and my way now works and updates instantly. So, improvements and simplifications would be great, but since it doesn’t impact time in any noticeable way, low priority.

Though as soon as I finished typing that last sentence, something clicked in my brain and I might know a more efficient way to do it. I’m gunna be real mad if it’s as easy as I think it is.

It’s been a while since I shared anything with the community, so I figured I could share some recent things I’ve been up to with SVGs… But first, a poll:

Approximately what percentage of your applications make use of SVG graphics
  • 75 - 100%
  • 50 - 75%
  • 25 - 50%
  • 0 - 25%
  • I don’t use SVGs in AppSheet

0 voters


Avoid asset load times

Image assets that are hosted on a cloud fileshare service (e.g. OneDrive / Google drive) are lazy-loaded, with a loading animation being shown unless the image was previously cached on the device:

This behavior is good for user uploaded images, but not so desirable for application assets such as navigation imagery. I have found that including the SVG code directly in a virtual column, as opposed to referencing a .svg hosted elsewhere, eliminates the delay. The same concept can be applied to raster images by converting them to base64, and appending data:image/png;base64.


Solution to the double-quote nightmare

@Bahbus recently pointed out on a separate thread that you can avoid having to double-quote everything by alternating the use of " and ’ characters. As a practical example, the below SVG will render as a virtual column and has no double-quoting:

CONCATENATE("data:image/svg+xml;utf8,
<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'>
  <rect x='25' y='25' height='50' width='50' fill='red'/>
</svg>
")

And to inject your variables occurs in one of two ways, depending if the SVG variable is bounded by quotes ("") or angled brackets (><😞

CONCATENATE("data:image/svg+xml;utf8,
<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'>
  <text>",[YOUR >< VARIABLE],"</text>
  <rect x='25' y='25' height='50' width='50' fill=' ",[YOUR "" VARIABLE]," '/>
</svg>
")

SVG chart freebies

Here are some examples of SVG charts I’m using in my applications. When I have some more time I will explain how they work; until then, if you are SVG-savvy, I’m sure you can download them and figure it out yourself.


Example workflow involving SVG animations and dynamic charts:

All images in this example are SVG


@Fabian @WillowMobileSystems @Grant_Stead @LeventK @Steve @MultiTech_Visions @GreenFlux @tsuji_koichi @Suvrutt_Gurjar

Thanks for initiating this interesting thread.

Honestly , I have no idea how SVG would work as i m not a coder.

It is quie helpful and useful if we could have access to the template of SVGs with the final image/views with the set of the SVG codes so that we can copy and modify the appropriate part of the code to fit with our schema.

Thank you again.

Hi @Jonathon ,

Thank you very much for practically useful updates on the SVG front. You have shared some excellent examples of powerful SVG usage.

SVGs indeed seem to have great potential. I also tried in the past mainly inspired by your guidance. That time I think the use of double quotes involving an elaborate coding of the VC having SVG code and non rendering of SVGs on certain devices , OS , browsers seemed to limit the extensive use,

Will appreciate if you have any more guidance/ experience to share on SVGs rendering on different OS versions, browsers etc. Of course you have mentioned that Microsoft IE and AppSheet side there have been some improvements in the SVG direction.

That’s a fiiiiiiiiiiine looking app right there, thanks for the pointers, i will look more into svg, but first i gotta ask, how did you make that small loading gif? is that SVG too?

I agree, very sexy app. The font size changes layouts, etc… I mean very very polished. Very nice work.

I too want to know how you did the pending graphic that comes through after the sync went through.

As always. Awesome stuff!!

I’m curious how you are building the part of the view shown in the image below:

Took a while to get to this, apologies. That is also just an SVG. The charts and metrics are the same as any other, just arranged on a larger viewport.

I thought so. Very cool!

I don’t think I would have ever thought to do something this sophisticated. I see how we can create some very interesting UI’s this way. Time to roll up the sleeves and get intimate with SVG’s!

Boss mode for your apps

Is the value being changed by a database trigger? It looks like a similar behavior to what I have when using triggers to update data which causes a slight delay in when the value is shown in app and they kind a just pop in.

The app attempts to group each record by some criteria. If no matching group is found, then a new one must be created. To ensure groups are numbered sequentially, this occurs server-side. In the meantime, the record will be initialized with a group id of 0, which tells it to show the loading animation:

IF([id]="0",
  CONCATENATE("data:image/svg+xml;utf8,
    <svg xmlns='http://www.w3.org/2000/svg' viewBox='-7 -7 14 14' height='15' fill='none' stroke-width='3'>
      <circle r='5' stroke='rgb(225,227,230)'/>
      <path d='M0 -5 A 5 5 0 0 1 5 0' stroke='rgb(44,49,54)' stroke-linecap='round'>
      <animateTransform attributeName='transform' type='rotate' from='0' to='360' dur='1.9s' repeatCount='indefinite'/>
      </path>
  </svg>")
,"")

@Grant_Stead @Austin_Lambeth

Thank you for creating this post! It has been extremely helpful over the past few months.

I cannot seem to be able to use an image column containing a SVG to group rows in a table view, like you did in your app with the loading animation. Am I missing something? I swear I had it working, but now it no longer works.

it’s a pretty basic SVG, it works inside table or detail views just fine.

The rows in my table are grouped by a REF column. This REF column has the loading animation set as its image label!

Thank you for your reply!

How did you get both the SVG and the text inline together?

3X_2_a_2a0b97ca06dbee4f4f976d30a86393818cf2852e.png

I tried Including two columns as labels, the SVG virtual column and a column containing the text, however they are stacked on top of each other, not inline.

3X_f_c_fc5d1164dd14d270d51cddb8f2b1cffe6a87ac9e.png

I tried including the text in the SVG, however it seems the aspect ratio is fixed to a 1:1 square when using an image as a label. If I try to make the view-box wider to accommodate text, I cannot change the 1:1 ratio of the label so the SVG just shrinks in height. Sorry If I am not explaining it well. In the test example below I doubled the width of the view-box, the view box just shrinks down instead of expanding horizontally.

This is what it looks like with the SVG view box at 1:1 ratio.

3X_1_f_1fe5d47c7e94fe6bb07eae3e5e43b7b12e1d0f60.png

This is a PS mockup of what I was expecting to happen when I doubled the width of the view box

3X_6_b_6bc7e4d73c6f10f18a13fc720d5c8238863e868a.jpeg

Instead, this is what happened.

3X_3_e_3ed1e4925494e52105ac672d6c2a18e77074c882.png

This is a PS mock-up of the layout I am trying to achieve
3X_9_4_94e51416049b77c1f6459bf664187e05ed4f8817.jpeg

Yes, unfortunately the UI for that location is bound by a set width, and set to “contain” image. However, I believe a feature request to change that to be bound to the currently rendered max height (based on text size, format rules, etc) with a more flexible width would be appropriate.

As @Bahbus Bahbus said, you will have to use a 1:1 aspect ratio viewport here.

By your description it sounds like you’ve set things up properly (1:1 aspect ratio image label, and a text label). Here is my setup for comparison:

Perhaps the image and text labels are stacked on top of eachother for different viewtypes? My implementation uses a simple inline table, yours appears to be using a card view.

The viewtype was my initial guess, however I encountered the same issue when I tested in an inline table.

I also tried using a regular image instead of SVG, same issue. I tried shortening the length of the text, same issue. I tried using regular columns instead of virtual columns, same issue. I have tried using your animated loading SVG to see if the issue was in my SVG, same issue.

However I believe it is a browser issue. All the screenshots I have provided are from either the preview window in the app editor, or the dashboard where the card view resides. All on my desktop. I installed the app on my phone and there is no issue.

Yay! Issue resolved. However the app is a desktop dashboard

I will do some more testing and see If I can resolve the issue.

I don’t want to bog this thread down with my issues, hopefully it has been somewhat relevant to the discussion and can help others understand how you achieved the loading SVG in your app and some of the issues they may encounter along the way.

I want to thank you for taking the time to help me out

@cwenger

ATR
Bronze 5
Bronze 5

Guys awesome work with SVG’s. Since i’m new to AppSheet and coding, after reading the post i tried to set an static image as icon on a app i’m creating, i encoded to base 64 and inserted the App Formula bellow:

When i create a new record the image shows until the app sync, and then it shows the triangle alert image. I checked the spreadsheet and the column value wasn’t the same as the app formula. So for the existing values i mannually inserted on the spreadsheet and then regenerated the data. But for new values i’ll get the error again

3X_b_a_ba8f34d8a61b17260bef37258455b27bb4a55038.png

If inserting directly into your spreadsheet, try this:

data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='100' height='100' viewBox='0 0 24 24' fill='none' stroke='rgb(0,171,251)' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'><rect x='5' y='3' width='14' height='18' rx='2'/><line x1='9' y1='7' x2='15' y2='7'/><line x1='9' y1='11' x2='15' y2='11'/><line x1='9' y1='15' x2='13' y2='15'/></svg>

If you want to do it as a virtual column, just enclose the above in quotes.

Greyscale
<svg xmlns='http://www.w3.org/2000/svg' viewBox='-10 -10 480 150' font-family='sans-serif' text-anchor='middle'>
  <defs><filter id='s'>
    <feDropShadow dx='0' dy='1' stdDeviation='2' flood-color='rgb(168,168,168)'/>
    </filter></defs>
  <g fill='rgb(248,249,250)' filter='url(#s)'>
    <rect width='100' height='130' rx='5'/>
    <rect x='120' width='100' height='130' rx='5'/>
    <rect x='240' width='100' height='130' rx='5'/>
    <rect x='360' width='100' height='130' rx='5'/>
  </g>
  <text fill='rgb(80,80,80)' font-size='17' x='50' y='28'>Charged<tspan x='170'>Time Off</tspan><tspan x='290'>Weather</tspan><tspan x='410'>Other</tspan></text>
  <text fill='rgb(60,60,60)' font-size='36' font-weight='900' x='50' y='114'>7<tspan x='170'>2</tspan><tspan x='290'>0</tspan><tspan x='410'>1</tspan></text>
  <path fill='rgb(168,168,168)' transform='translate(50 48) scale(0.04)' d='M68 242l-116-33c-16-5-29-17-31-34c-4-25 15-47 40-47h74c16 0 32 5 44 14c6 5 15 4 21-2l23-23c7-7 6-18-2-24c-25-19-55-29-86-29h-3v-48c0-9-7-16-16-16h-32c-9 0-16 7-16 16v48h-3c-49 0-94 32-106 80c-14 56 20 111 73 126l116 33c16 5 29 17 31 34c4 25-15 47-40 47h-74c-16 0-32-5-44-14c-6-5-15-4-21 2l-23 23c-7 7-6 18 2 24c25 19 55 29 86 29h3v48c0 9 7 16 16 16h32c9 0 16-7 16-16v-48h3c49 0 95-32 106-80c14-56-20-111-73-126zM3000 8a1 1 0 000 496a1 1 0 000-496m0 448a1 1 0 010-400a1 1 0 010 400m62-104-85-62c-3-2-5-6-5-10v-164c0-7 5-12 12-12h32c7 0 12 5 12 12v142l67 49c5 4 7 11 3 17l-19 25c-4 5-11 7-17 3zM6263 296c-9-48-46-93-118-87c-24-21-56-33-89-33c-64 0-118 45-132 105c-32 24-52 62-52 103c0 71 57 128 128 128h204c64 0 116-52 116-116c0-42-23-79-57-100zm-59 168h-204c-44 0-80-36-80-80c0-33 20-61 48-73c1-48 40-87 88-87c31 0 58 16 74 41c48-26 96 17 83 64c33 5 59 33 59 67c0 38-30 68-68 68zm-417-123 15-75-63-43 63-43-15-75 75 15 42-63 43 64 75-15-8 44c14-4 29-7 50-5l9-47a35 35 0 00-42-41l-62 12-35-52c-7-11-18-17-30-17c-11 0-23 5-29 15l-35 52-62-12c-16-2-25 3-32 9c-8 8-12 20-10 32l12 62-52 36c-10 7-16 18-16 30c0 12 6 23 16 29l52 35-12 62a35 35 0 0042 41l63-11c0-18 4-36 10-52l-64 13zm109-78a39.8 39.8 0 1138-65c11-12 24-22 38-30a87.8 87.8 0 10-108 134c9-14 20-27 32-39zM8888 208c-18 0-32 14-32 32s14 32 32 32s32-14 32-32s-14-32-32-32zm112 0c-18 0-32 14-32 32s14 32 32 32s32-14 32-32s-14-32-32-32zm112 0c-18 0-32 14-32 32s14 32 32 32s32-14 32-32s-14-32-32-32zm-112-176c-141 0-256 93-256 208c0 48 20 91 53 126c-15 40-45 73-46 74c-7 7-8 17-5 26s12 14 22 14c62 0 110-26 139-46c29 9 60 14 93 14c141 0 256-93 256-208s-115-208-256-208zm0 368c-27 0-53-4-78-12l-23-7c-33 24-54 35-78 43c7-12 16-29 31-68c-39-39-60-74-60-116c0-88 93-160 208-160s208 72 208 160s-93 160-208 160z'/>
</svg>
Colored Icons
<svg xmlns='http://www.w3.org/2000/svg' viewBox='-10 -10 480 150' font-family='sans-serif' text-anchor='middle'>
  <defs><filter id='s'>
    <feDropShadow dx='0' dy='1' stdDeviation='2' flood-color='rgb(168,168,168)'/>
    </filter></defs>
  <g fill='rgb(248,249,250)' filter='url(#s)'>
    <rect width='100' height='130' rx='5'/>
    <rect x='120' width='100' height='130' rx='5'/>
    <rect x='240' width='100' height='130' rx='5'/>
    <rect x='360' width='100' height='130' rx='5'/>
  </g>
  <text fill='rgb(80,80,80)' font-size='17' x='50' y='28'>Charged<tspan x='170'>Time Off</tspan><tspan x='290'>Weather</tspan><tspan x='410'>Other</tspan></text>
  <text fill='rgb(60,60,60)' font-size='36' font-weight='900' x='50' y='114'>7<tspan x='170'>2</tspan><tspan x='290'>0</tspan><tspan x='410'>1</tspan></text>

  <g transform='translate(50 48) scale(0.04)'>
    <path fill='rgb(26,188,156,0.7)' d='M68 242l-116-33c-16-5-29-17-31-34c-4-25 15-47 40-47h74c16 0 32 5 44 14c6 5 15 4 21-2l23-23c7-7 6-18-2-24c-25-19-55-29-86-29h-3v-48c0-9-7-16-16-16h-32c-9 0-16 7-16 16v48h-3c-49 0-94 32-106 80c-14 56 20 111 73 126l116 33c16 5 29 17 31 34c4 25-15 47-40 47h-74c-16 0-32-5-44-14c-6-5-15-4-21 2l-23 23c-7 7-6 18 2 24c25 19 55 29 86 29h3v48c0 9 7 16 16 16h32c9 0 16-7 16-16v-48h3c49 0 95-32 106-80c14-56-20-111-73-126z'/>
    <path fill='rgb(46,204,113,0.7)' d='M3000 8a1 1 0 000 496a1 1 0 000-496m0 448a1 1 0 010-400a1 1 0 010 400m62-104-85-62c-3-2-5-6-5-10v-164c0-7 5-12 12-12h32c7 0 12 5 12 12v142l67 49c5 4 7 11 3 17l-19 25c-4 5-11 7-17 3z'/>
    <path fill='rgb(52,152,219,0.7)' d='M6263 296c-9-48-46-93-118-87c-24-21-56-33-89-33c-64 0-118 45-132 105c-32 24-52 62-52 103c0 71 57 128 128 128h204c64 0 116-52 116-116c0-42-23-79-57-100zm-59 168h-204c-44 0-80-36-80-80c0-33 20-61 48-73c1-48 40-87 88-87c31 0 58 16 74 41c48-26 96 17 83 64c33 5 59 33 59 67c0 38-30 68-68 68zm-417-123 15-75-63-43 63-43-15-75 75 15 42-63 43 64 75-15-8 44c14-4 29-7 50-5l9-47a35 35 0 00-42-41l-62 12-35-52c-7-11-18-17-30-17c-11 0-23 5-29 15l-35 52-62-12c-16-2-25 3-32 9c-8 8-12 20-10 32l12 62-52 36c-10 7-16 18-16 30c0 12 6 23 16 29l52 35-12 62a35 35 0 0042 41l63-11c0-18 4-36 10-52l-64 13zm109-78a39.8 39.8 0 1138-65c11-12 24-22 38-30a87.8 87.8 0 10-108 134c9-14 20-27 32-39z'/>
    <path fill='rgb(155,89,182,0.7)' d='M8888 208c-18 0-32 14-32 32s14 32 32 32s32-14 32-32s-14-32-32-32zm112 0c-18 0-32 14-32 32s14 32 32 32s32-14 32-32s-14-32-32-32zm112 0c-18 0-32 14-32 32s14 32 32 32s32-14 32-32s-14-32-32-32zm-112-176c-141 0-256 93-256 208c0 48 20 91 53 126c-15 40-45 73-46 74c-7 7-8 17-5 26s12 14 22 14c62 0 110-26 139-46c29 9 60 14 93 14c141 0 256-93 256-208s-115-208-256-208zm0 368c-27 0-53-4-78-12l-23-7c-33 24-54 35-78 43c7-12 16-29 31-68c-39-39-60-74-60-116c0-88 93-160 208-160s208 72 208 160s-93 160-208 160z'/>
  </g>
</svg>
Full color
<svg xmlns='http://www.w3.org/2000/svg' viewBox='-10 -10 480 150' font-family='sans-serif' text-anchor='middle'>
  <defs>
    <filter id='s'>
      <feDropShadow dx='0' dy='1' stdDeviation='2' flood-color='rgb(168,168,168)'/>
    </filter>
    <linearGradient id='g' gradientTransform='rotate(90)'>
      <stop offset='0' stop-color='rgb(255,255,255)' stop-opacity='0.4'/>
      <stop offset='1' stop-color='rgb(255,255,255)' stop-opacity='0'/>
    </linearGradient>
  </defs>
  <g filter='url(#s)'>
    <rect fill='rgb(26,188,156)' width='100' height='130' rx='5'/>
    <rect fill='rgb(46,204,113)' x='120' width='100' height='130' rx='5'/>
    <rect fill='rgb(52,152,219)' x='240' width='100' height='130' rx='5'/>
    <rect fill='rgb(155,89,182)' x='360' width='100' height='130' rx='5'/>
  </g>
  <rect fill='url(#g)' x='-20' y='-10' width='500' height='150'/>
  <g fill='rgb(60,60,60)'>
    <text font-size='17' x='50' y='28'>Charged<tspan x='170'>Time Off</tspan><tspan x='290'>Weather</tspan><tspan x='410'>Other</tspan></text>
    <text font-size='36' font-weight='900' x='50' y='114'>7<tspan x='170'>2</tspan><tspan x='290'>0</tspan><tspan x='410'>1</tspan></text>
  </g>
  <path fill='white' transform='translate(50 48) scale(0.04)' d='M68 242l-116-33c-16-5-29-17-31-34c-4-25 15-47 40-47h74c16 0 32 5 44 14c6 5 15 4 21-2l23-23c7-7 6-18-2-24c-25-19-55-29-86-29h-3v-48c0-9-7-16-16-16h-32c-9 0-16 7-16 16v48h-3c-49 0-94 32-106 80c-14 56 20 111 73 126l116 33c16 5 29 17 31 34c4 25-15 47-40 47h-74c-16 0-32-5-44-14c-6-5-15-4-21 2l-23 23c-7 7-6 18 2 24c25 19 55 29 86 29h3v48c0 9 7 16 16 16h32c9 0 16-7 16-16v-48h3c49 0 95-32 106-80c14-56-20-111-73-126zM3000 8a1 1 0 000 496a1 1 0 000-496m0 448a1 1 0 010-400a1 1 0 010 400m62-104-85-62c-3-2-5-6-5-10v-164c0-7 5-12 12-12h32c7 0 12 5 12 12v142l67 49c5 4 7 11 3 17l-19 25c-4 5-11 7-17 3zM6263 296c-9-48-46-93-118-87c-24-21-56-33-89-33c-64 0-118 45-132 105c-32 24-52 62-52 103c0 71 57 128 128 128h204c64 0 116-52 116-116c0-42-23-79-57-100zm-59 168h-204c-44 0-80-36-80-80c0-33 20-61 48-73c1-48 40-87 88-87c31 0 58 16 74 41c48-26 96 17 83 64c33 5 59 33 59 67c0 38-30 68-68 68zm-417-123 15-75-63-43 63-43-15-75 75 15 42-63 43 64 75-15-8 44c14-4 29-7 50-5l9-47a35 35 0 00-42-41l-62 12-35-52c-7-11-18-17-30-17c-11 0-23 5-29 15l-35 52-62-12c-16-2-25 3-32 9c-8 8-12 20-10 32l12 62-52 36c-10 7-16 18-16 30c0 12 6 23 16 29l52 35-12 62a35 35 0 0042 41l63-11c0-18 4-36 10-52l-64 13zm109-78a39.8 39.8 0 1138-65c11-12 24-22 38-30a87.8 87.8 0 10-108 134c9-14 20-27 32-39zM8888 208c-18 0-32 14-32 32s14 32 32 32s32-14 32-32s-14-32-32-32zm112 0c-18 0-32 14-32 32s14 32 32 32s32-14 32-32s-14-32-32-32zm112 0c-18 0-32 14-32 32s14 32 32 32s32-14 32-32s-14-32-32-32zm-112-176c-141 0-256 93-256 208c0 48 20 91 53 126c-15 40-45 73-46 74c-7 7-8 17-5 26s12 14 22 14c62 0 110-26 139-46c29 9 60 14 93 14c141 0 256-93 256-208s-115-208-256-208zm0 368c-27 0-53-4-78-12l-23-7c-33 24-54 35-78 43c7-12 16-29 31-68c-39-39-60-74-60-116c0-88 93-160 208-160s208 72 208 160s-93 160-208 160z'/>
</svg>


Beautiful.

Yes indeed. @Jonathon ’ s SVG / graphics work is always so elegant.

How do you put the image full and wide
Is it composed of three columns of type show
Or just one column
Or something else
My image leaves space here and doesn’t show up in full

Cleaned up the code and shared it in the above post, expand the detail arrows!

Thank you very much @Jonathon. Your code will help us as a valuable SVG reference.

May I request you to share your insights on the SVG’s rendering on various OS. I recollect initially, a couple of years ago, there were some challenges in that direction.

There are some subtle differences in how SVG’s are rendered in various browsers, but I haven’t had to give much thought to this issue in well over a year… a summary of browser support can be found here.

The biggest outstanding ‘issue’ is with fonts… iOS devices have different default serif/sans-serif fonts, so they will render different than android / windows default fonts. Currently, importing or including our own fonts in SVG’s is (while possible) not practical. This isn’t really an issue though.

SVG’s wont work on internet explorer… but if your userbase is using IE still, you have different problems

Got it. The reference chart on browser compatibility you have shared is useful. Thank you @Jonathon.

Here’s a 5-parameter radar chart. To set it up, simply replace the [ParamValue#] columns with your appropriate column. The values in these columns should be a value between 0 and 1. If anyone has thoughts on ways to cut down on some of the total code that I’m currently showing, that could be nice. Anyways, enjoy.

3X_e_4_e42db2797a70d7cbd1779e04d198afabb42754b5.jpeg

CONCATENATE(
"data:image/svg+xml;utf8,
<svg
   viewBox=""0 0 54 54""
   version=""1.1""
   id=""radar-chart-pentagon""
   xmlns=""http://www.w3.org/2000/svg"">
   
  <defs id=""defs2"" />
  <g
     id=""ref""
     style=""display:inline"">
    <circle
       style=""fill:none;fill-opacity:0.954315;fill-rule:nonzero;stroke:%23000000;stroke-width:0.25;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:normal""
       id=""border""
       cy=""27""
       cx=""27""
       r=""25"" />
  </g>
  
  <g
     id=""border""
     style=""display:inline"">
    <path
       style=""fill:none;stroke:%23370096;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1""
       d=""m 26.999999,2 -23.7764146,17.274581 9.0817866,27.950846 29.389258,-1e-6 9.081784,-27.950846 z""
       id=""full-percent""/>
  </g>
  <g
     id=""rules-radial""
     style=""display:inline"">
    <path
       style=""fill:none;stroke:%23370096;stroke-width:0.125;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1""
       d=""m 26.999999,14.5 -11.888208,8.637291 4.540894,13.975423 14.694629,-10e-7 4.540892,-13.975423 z""
       id=""half-percent""/>
    <path
       style=""fill:none;stroke:%23370096;stroke-width:0.125;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1""
       d=""M 26.999999,8.25 9.1676884,21.205936 15.979028,42.16907 H 38.020971 L 44.83231,21.205935 Z""
       id=""three-quarter-percent""/>
    <path
       style=""display:inline;fill:none;stroke:%23370096;stroke-width:0.125;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1""
       d=""m 26.999999,20.749997 -5.944105,4.318645 2.270447,6.987711 h 7.347314 l 2.270446,-6.987711 z""
       id=""quarter-percent""/>
  </g>
  <g
     id=""rules-to-center""
     style=""display:inline"">
    <path
       style=""display:inline;fill:none;stroke:%23ff0000;stroke-width:0.215565;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1""
       d=""M 26.999999,27 V 2""
       id=""north-line""/>
    <path
       style=""display:inline;fill:none;stroke:%23ff0000;stroke-width:0.186045;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1""
       d=""M 26.999999,27 3.2185064,19.261896""
       id=""north-west""/>
    <path
       style=""display:inline;fill:none;stroke:%23ff0000;stroke-width:0.18598;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1""
       d=""M 26.999999,27 12.292948,47.231497""
       id=""south-west""/>
    <path
       style=""display:inline;fill:none;stroke:%23ff0000;stroke-width:0.186015;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1""
       d=""M 26.999999,27 41.707812,47.237869""
       id=""south-east""/>
    <path
       style=""display:inline;fill:none;stroke:%23ff0000;stroke-width:0.185911;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1""
       d=""M 26.999999,27 50.775394,19.271133""
       id=""north-east""/>
  </g>
  <g
     id=""overlay""
     style=""display:inline"">
    <path
       style=""display:inline;opacity:0.344828;fill:%23ff0000;fill-opacity:0.954315;stroke:%23370096;stroke-width:0.16036;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1""
       d=""M ",
       27, ",", -25 * [ParamValue1] + 27," ",
 			-23.7814936 * [ParamValue2] + 27, ",", -7.738104 * [ParamValue2] + 27," ",
			-14.707052 * [ParamValue3] + 27, ",", 20.231497 * [ParamValue3] + 27," ",
			14.707812 * [ParamValue4] + 27, ",", 20.237869 * [ParamValue4] + 27," ",
			23.775394 * [ParamValue5] + 27, ",", -7.728867 * [ParamValue5] + 27,"Z""
       id=""skill-net""/>
    <circle
       style=""opacity:1;fill:%23ffffff;fill-opacity:1;fill-rule:nonzero;stroke:%23000000;stroke-width:0.125;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:normal""
       id=""handle-north""
       cx=""27""
       cy=""",-25 * [ParamValue1] + 27,"""
       r=""0.25964805"" />
    <circle
       style=""fill:%23ffffff;fill-opacity:1;fill-rule:nonzero;stroke:%23000000;stroke-width:0.125;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:normal""
       id=""handle-north-west""
       cx=""",-23.7814936 * [ParamValue2] + 27,"""
       cy=""",-7.738104 * [ParamValue2] + 27,"""
       r=""0.25964805"" />
    <circle
       style=""fill:%23ffffff;fill-opacity:1;fill-rule:nonzero;stroke:%23000000;stroke-width:0.125;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:normal""
       id=""handle-south-west""
       cx=""",-14.707052 * [ParamValue3] + 27,"""
       cy=""",20.231497 * [ParamValue3] + 27,"""
       r=""0.25964805"" />
    <circle
       style=""fill:%23ffffff;fill-opacity:1;fill-rule:nonzero;stroke:%23000000;stroke-width:0.125;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:normal""
       id=""handle-south-east""
       cx=""",14.707812 * [ParamValue4] + 27,"""
       cy=""",20.237869 * [ParamValue4] + 27,"""
       r=""0.25964805"" />
    <circle
       style=""fill:%23ffffff;fill-opacity:1;fill-rule:nonzero;stroke:%23000000;stroke-width:0.125;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:normal""
       id=""handle-north-east""
       cx=""",23.775394 * [ParamValue5] + 27,"""
       cy=""",-7.728867 * [ParamValue5] + 27,"""
       r=""0.25964805"" />
  </g>
</svg>"
)

11129
New Member

Is there any way to link a raster image as a background of a SVG in AppSheet? I can’t achieve that and always get a broken image icon. Could somebody please explain me how to do that?

@Jonathon

@Koichi_Tsuji 

@MultiTech 

@Fabian_Weller 

Good day Gents

Noob here. Referencing this topic: https://www.googlecloudcommunity.com/gc/Tips-Tricks/Just-for-fun-Or-any-use-case-Create-users-avatar...

I also found that the Avatar Builder is not working. Since Appsheet is not rendering the Avatar and giving error "Unsupported image mime type image/svg+xml", would it not be possible to put link in svg style and get it to work? and if so what would the code be?

Hope my thought works 🤔 🤞

Thanks @Jonathon for this major contribution.  I hate to look a gift horse in the mouth but I've been having trouble actually getting the code shared in this thread to work in my app.  If anyone would be willing to take code examples discussed in this thread and then publish them as sample apps, that would really help code-challenged people like me.
By the way, there are a few examples of sample apps that do this:

If progress bars, etc. that differ from those above could be added as sample apps, I'd really appreciate it.

Returning once more, following the introduction of the New desktop UI and the implementation of LongText HTML. Has anyone successfully incorporated SVG via the IMG SRC method? I'm aiming to maintain its dynamism, allowing for conditional control of the RGB fill from within the application. Below, you'll find a code snippet that encapsulates my current requirement

<table>
  <tr>
    <td>
      <img src="data&colon;image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='18' height='70'>
        <rect x='0' y='0' width='6' height='70' rx='4' ry='4' fill='rgba(76, 110, 249, 1)'/>
      </svg>">
    </td>
    <td>
      <b>The text goes here</b><br>
    </td>
  </tr>
</table>

My goal is to get output like this 

Screenshot 2023-10-25 at 11.46.51 PM.png

Top Labels in this Space