Web diagrams and flowcharts using SVG

One of the projects in which participated over the past few years was the development of the Saudi Clinical Practice Guidelines for ADHD. In addition to being a member of the adaptation group, I put together the web-based version of the guideline.

One part with which I was dissatisfied was the way I had displayed the Clinical Algorithm. To save time, I just inserted it on the page as a PNG image, but always intended to go back and re-create it as a simple flow diagram in an accessible web format. Yesterday, I was doing a quick refresh to the CPG micro-site to align it with the style of other sites in our network, so I decided to have a go at this diagram while I was at it.

In part 1, I describe my attempts in turning the existing diagram into a native web format (i.e. not just a flat image) and settling on SVG. In part 2, I describe my attempts to make the resulting SVG more accessible.

Part 1: Figuring out the right workflow

Since it is quite a simple diagram, it would be overkill to use some kind of flowchart script (e.g. flowchart.js or mermaid.js), so initially I decided to do it using a combination of Gutenberg Blocks and a little custom CSS for the joining lines. Let’s just say it worked, but was far from satisfactory.

Then I remembered having used SVG elements in a previous project and decided to give it a go. I searched for an SVG Gutenberg Block, before it occurred to me (face palm) that it is an HTML element, for which a block already exists.

Attempt 1:

Word – PDF – Illustrator – SVG

In my first attempt, I took a PDF that had been generated from the original Word copy of the diagram, opened it in Illustrator, and then saved an SVG copy. This resulted in a 1.4 megabyte file that was messy and missing some letters and words when inserted in the web page. Paying a bit more attention as I repeated these steps, I saw that while most text had remained text when importing into Illustrator, for some reason certain bits of text had been outlined (converted into shapes), even within the same line of text, and overall it was a messy file with too many clipping groups and clipping paths.

Tidied up in Illustrator

I tidied up the above file by replacing the fragmented bits of text with a single text box for each rectangle on the diagram. This remained a large file, and it worked but was still a bit messy – both visually and in terms of code complexity.

Attempt 1: Fail.

Attempt 2:

InDesign – Illustrator – SVG

I remembered that I had redrawn the diagram in Indesign when I made the print version of the guidelines, so I copied and pasted it from Indesign into Illustrator and exported it as an SVG. This was a big improvement, but still had some odd indentation and kerning issues.

Illustrator – SVG

I went to work on that version in Illustrator, all but redrawing it (which in hindsight would have been quicker – shortcuts usually end up taking longer!). When I pasted the diagram, each rectangle had been created as two overlapping rectangles, one with the border and one with the background. Each line of text within a paragraph had been created as individual lines of point type, so I replaced them with wrapped area type.

The bullets were also floating off in text boxes by themselves, so put them inline with the text and set the indent/first-line indent to position them correctly.

How to do inline bullets with proper indentation in Illustrator

I re-aligned the text boxes over the rectangles, and positioned the text correctly by giving each area type box 5px of indent spacing.

Using inset spacing to offset text inside a graphical element the right way

I ensured that the text used a system font (I chose Arial) and that all elements were styled consistently (to streamline the generated CSS). When this one was exported as SVG is was just 14 KB, and looked great when inserted into the web page.

Ahhh much better

Machine code-tidy

I searched online for a tool to tidy up generated SVG code, and found SVGOMG. I ran my diagram through this, and it reduced the size down to 11 KB, and looked a bit tidier.

Manual code-tidy

Examining this tidied version, I noticed that I still had some strange fragmentation of text happening. It was being inserted line-by-line rather than wrapping, but this is okay in the final file as I guess that’s how it is positioned relative to the bullet (I’ll experiment with that later). But it was actually fragmenting individual words and manually positioning each letter or group of letters next to the preceding letters. Looking back, this was happening at the export from Illustrator stage.

Within-word fragmentation

Rather than going back to Illustrator to try to figure out the root cause of this, I decided to manually tidy up the code, still keeping each individual line within a separate element, but merging fragmented words together. The resulting file is just 8 KB and looks very crisp and tidy when displayed on the web page.

Words re-assembled

SVG standards

When I came back to make some edits to the page one day later, it told me that an error had occurred in the block and would I like to attempt recovery. I compared the fixed SVG code with the original, and it turns out that it expects a slightly different standard of SVG, closing path elements with <path></path> rather than self-closing <path /> as was generated by Illustrator. There are various SVG versions offered by Illustrator; perhaps one of them uses the same standard.

SVG options (I’ll have to explore those SVG Profiles some time.)

Part 2: SVG a11y

The most basic elements to add for accessibility are a title and description. However, thus far I’ve been unable to work out how to apply markup to make the diagram work as a list for a screen reader.

The changes I’ve made to the code in an attempt to make it screen reader friendly are as follows:

1. Adding markup to the <svg> tag as well as adding <title> and <desc> elements (additions shown in bold):

<svg aria-labelledby="ClinicalAlgorithmTitle" aria-describedby="ClinicalAlgorithmDesc" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 590 743" xml:space="preserve">
	<title id="ClinicalAlgorithmTitle">Clinical Algorithm for ADHD Management</title>
	<desc id="ClinicalAlgorithmDesc">This algorithm describes the recommended steps to take from suspected ADHD, through diagnosis and treatment, for children, young people, and adults with ADHD.</desc>

2. I’d already grouped purely visual elements into their own layers in Illustrator, so I was able to effectively hide them from screen readers by setting their role to "none" and using aria-hidden="true":

  <g id="Arrows" role="none" aria-hidden="true">...</g>
  <g id="Boxes" role="none" aria-hidden="true">...</g>

3. Restructuring the SVG elements to represent a more logical flow. Initially it had Children, Young People, Adults, followed by Children details, Young people details, Adults details. Obviously this would be confusing without being able to see the implied structure graphically.

4. Adding markup to the existing <g> elements to identify them as list items (equivalent to <li>), wrapping them in additional <g> elements to define lists and sub-lists (equivalent to <ul>), and inserting <a> elements with appropriate markup to enhance navigation between elements. Below, I’ve omitted the non-accessibility related markup from the <path> and <text> tags (related to visual style and position) to make it easier to see the structure:

<g id="Text" role="list">
    <g role="list-item">
        <a xlink:href="#step-1">
            <path/>
            <text>Person with suspected ADHD</text>
        </a>
    </g>
    <g role="list-item">
        <a xlink:href="#step-2">
            <path/>
            <text>Recognition, identification and referral</text>
        </a>
    </g>    
    <g role="list-item">
        <a xlink:href="#step-3">
            <path/>
            <text>
                <tspan>Diagnosing ADHD</tspan>
                <tspan>...</tspan>
            </text>
        </a>
    </g>
    <!-- Primary List item 4 (has sub list) -->    
    <g role="list-item"> 
        <a xlink:href="#step-4">
            <path/>
            <text>Advice after diagnosis</text>
        </a>
        
        <!-- Sub List 4a -->
        <g role="list"> 
            <g role="list-item">
                <a xlink:href="#step-4a1">
                    <path />
                    <text>Children under 5 years</text>
                </a>
            </g>
            <g role="list-item">
                <a xlink:href="#step-4a2">
                    <path />
                    <text>Details</text>
                </a>
            </g>            
        </g>
        <!-- Sub List 4b -->        
         <g role="list">
            <g role="list-item">
                <a xlink:href="#step-4b1">
                    <path />
                    <text>Young People</text>
                </a>
            </g>
            <g role="list-item">
                <a xlink:href="#step-4b2">
                    <path />
                    <text>Details</text>
                </a>
            </g>
        </g>
       
        <!-- Sub List 4c -->
         <g role="list">
            <g role="list-item">
                <a xlink:href="#step-4c1">
                    <path />
                    <text>Adults</text>
                </a>
            </g>
            <g role="list-item">
                <a xlink:href="#step-4c2">
                    <path />
                    <text>Details</text>
                </a>
            </g>
        </g>
       
    </g> <!-- end of Primary list item 4 -->
        
    <g role="list-item">
        <a xlink:href="#step-5">
            <path />
            <text>Review and follow up</text>
        </a>
    </g>
    
</g>

Written in HTML, this would look like this:

I think that’s a good logical flow for a screen reader.

The result

Being text, it is immediately more accessible than using an image, and hopefully adding the markup I’ve described has made it more so. I think the final diagram has been worth the effort.

You can see the final SVG live at the link below:

https://cpg.adhd.org.sa/implementation-tools-considerations/clinical-algorithm/

Leave a Reply