Close Sun Nov 18 14:39:50 GMT 2018

Server-side image generation on SFDC

Sometimes the most useful information isn't a field, it's an image:

formula-icons2formula-icons3formula-icons4formula-icons1

But the important source data might be stuck in a related list. Or in a relationship that doesn't support formulas. Perhaps it should display something more meaningful than a just a numeric count or average.

Tables and listviews only show static data. Apart from JavaScript hacks, one might not notice the elegant opportunity to inject rich content or components:

Introducing dynamic SVG images

On the platform, we can generate any image on-demand by using SVG markup. SVG is a vector image format that scales without pixellating. When combined with Visualforce it can be extremely powerful.

Instead of uploading static image data, a Visualforce page can render it on the fly for each request. This means we can embed live graphics directly into anything that can display a field: reports, list views, compact layouts...

Example - files at a glance

View which files hang off records without drilling in:

order-list

Example - approval status

Display whether an Approval Process Instance is pending for each record:

process-status

How it works:

  1. On the object, create a formula field: IMAGE("/apex/InlineSvg?id=" + Id, "")
  2. Create an InlineSvg Visualforce page with Content Type: image/svg+xml
  3. In the page, use SVG markup to draw elements into the image!

Ideas and tips:

  • Sparkline charts sparks
  • Use fill "none" for transparent backgrounds
  • Did you know SVG images support animation?
  • In the IMAGE() function, pass the Record ID with the URL
  • Use data URIs to embed other raster images in the SVG markup
  • Back the VF page with an Apex controller for even more possibilities

Here's the markup from the first example:

<apex:page contentType="image/svg+xml" standardController="Order">

<!-- count number of attachments to calculate image height -->
<apex:variable var="ids" value="{!''}{!Order.Attachments}" />
<apex:variable var="size" value="{!ROUND(LEN(ids)/20,0)}" />
<apex:variable var="height" value="{!MAX(1, 20 * size)}" />

<!-- begin SVG markup -->
<svg width="150" height="{!height}" xmlns="http://www.w3.org/2000/svg">
<g fill="none" text-anchor="middle" font-family="sans-serif" font-size="12">
<foreignObject width="150" height="300">
<textArea xmlns="http://www.w3.org/1999/xhtml" style="width: 200px;">

<!-- loop over each attachment -->
<apex:repeat value="{!Order.Attachments}" var="attachment">

<!-- embed white page icon -->
<img src="{!'data:image/png;base64,'
+ 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAQAAAC1+jfqAAAABGdBTUEAAK/INwWK6QAAA'
+ 'Bl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAC4SURBVCjPdZFbDsIgEE'
+ 'WnrsMm7oGGfZrohxvU+Iq1TyjU60Bf1pac4Yc5YS4ZAtGWBMk/drQBOVwJlZrWYkLhsB8'
+ 'UV9K0BUrPGy9cWbng2CtEEUmLGppPjRwpbixUKHBiZRS0p+ZGhvs4irNEvWD8heHpbsyD'
+ 'XznPhYFOyTjJc13olIqzZCHBouE0FRMUjA+s1gTjaRgVFpqRwC8mfoXPPEVPS7LbRaJL2'
+ 'y7bOifRCTEli3U7BMWgLzKlW/CuebZPAAAAAElFTkSuQmCC'}" />

<!-- list each filename -->
{!attachment.Name}<br /></apex:repeat></textArea></foreignObject></g></svg>
</apex:page>

Have fun! How would you use this?



Related