II. Precautions: Non-Medical
- Not for Medical Care
- The author uses several software packages and programming languages to develop FPnotebook content
- For convenience, a dozen pages in FPNotebook are dedicated to quick notes on content creation
III. Technique: SVG Creation in Adobe Illustrator
- Create and illustration in Adobe Illustrator
- Create a new document using the web preset
- Found separate documents are easier to manage than art boards
- Shared layers are shared between art boards and this adds to complexity
- Place objects on well-named layers (layer names become ids in SVG)
- Sub-layer names also become ids in SVG, and sublayers will be grouped (g) within the parent layer
- For 2 items within a layer, put the top one on the right side for consistent convention (for later selection)
- For related images (e.g. slices of the spine and Brain Stem)
- Keep the layer names consistent (for CSS and javascript functionality)
- Use each prior image as the base file for the next and delete the content/paths but keep the layer names
- Reuse styles and colors
- Save styles and colors to library so they may be used across documents
- Readying for SVG ouput
- Resize the artboard (document setup) to include just the image (but without cropping the edges)
- Convert text to outlines (ctrl-shift-o)
- Convert strokes with non-uniform profiles to outlines
- Group objects which will change together (ctrl-g)
- Save as SVG
- SVG Profile: 1.1
- CSS Properties
- Choose "Presentation Attributes" if consolidating all svgs into one as a symbols (see below)
- Choose "Style Elements" if using as stand-alone image file (includes style section with consolidated css)
- Troubleshooting
- General Pearls
- When trying to identify the problematic elements, surround them with a named group
- Named groups are easier to find in the SVG markup
- When trying to identify the problematic elements, surround them with a named group
- Polygons that fail to appear
- Illustrator will output some paths as polygons (if composed of straight lines) when writing to SVG
- Polygons are supported in svg, but at first I could not get them to appear
- I had not set the css styles for polygons
- If you need to stick to paths:
- Solution 1
- Select object and "Compound Path > Make" (ctrl-8)
- Solution 2
- Introduce a small curve in paths (e.g. convert point to round joint, then straighten)
- Curved paths are not exported as polygons
- Solution 1
- General Pearls
IV. Technique: SVG Editing Manually
- Delete the first 3 lines (above the SVG element tag) that were added by Adobe Illustrator
- Manually editing ID names
- Give a meaningful "id" name to the containing SVG tag
- Add an "id" attribute to unnamed groups that will require later javascript or CSS manipulation
- Add a "defs" tag immediately under the SVG starting tag
- You may add a style section to defs: (style type="text/css")
- You may add a javascript section to defs: (script type="text/javascript")
V. Technique: SVG Editing via code
- Convert element IDs to classes
- Images cannot have duplicate ID names (e.g. multiple SVGs in the same page with the same IDs)
- Naming layers the same for similar SVG documents is the best way for cross compatibility
- However illustrator saves the layer names to IDs in SVG
- Classes are preferred to IDs in this case as they may be duplicated
- Process to convert SVG IDs to Classes
- Option 1: Use Node grunt plugin, iconic/grunt-svg-toolkit
- Requires phantom.js be installed and in system path
- Modify grunt-svg-toolkit/tasks/lib/svg/ids-to-classes.js
- Added ",g" to var shapesAndText (unless already added by toolkit author)
- Option 2: Create own Node/Gulp Tool
- I did this for all the SVG clean-up (see below)
- Option 1: Use Node grunt plugin, iconic/grunt-svg-toolkit
- Process to consolidate all svgs as symbols into one file (perform after svg IDs to classes)
- Indications
- Works for SVG elements that do not need dynamic modifications later (e.g. icons)
- However, for interactive SVGs, best to keep these as individual SVGs and avoid consolidating
- Use Node grunt plugin, FweinB/grunt-svgstore
- Coverts each svg into a symbol, taking only its viewport attribute and setting ID to filename without .svg ext
- Places all symbols into a single svg file
- Allows for the "use" statement with an xlink-href pointing to the symbol ID (see below)
- SvgStore Config options in gruntfile:
- Set to true: inheritviewbox, cleanup, cleanupdefs
- Choose includedemo if want to see html usage
- Include the svg in the html file (with the svg style to display: none)
- Either paste the full contents of svg inline into html OR
- Use ng-include directive
- Indications
- Process to further customize the svg file
- Custom coding options
- Javascript (preferred, see below)
- XSLT
- C# XLinq (or similar in python...)
- Reasons for pre-processing SVG (instead of via javascript)
- Speed up loading of file
- Image css styling may be corrupted if javascript manipulation occurs to soon or too late
- Some functionality (e.g. path Titles as tooltips) will only work if added before the SVG loads
- Javascript processing via Node
- Plug-ins
- Gulp
- Takes care of the file io, watching, pipeline...
- Cheerio (available for node, grunt, gulp)
- https://www.npmjs.com/package/gulp-cheerio
- JQuery like editing of XML or HTML files (extremely helpful for pre-processing)
- Gulp-Replace
- Used with regex to remove the first 3 lines of illustrator saved svg
- Path (included in node, just need require)
- Filename parsing
- Gulp
- Custom tasks (pre-process)
- Remove unwanted attributes (e.g. SVG height, width)
- Could not remove xml:preserve-space (tried multiple methods including xml\\:preserve-space)
- Could not remove, but could select it with $(this).find('')
- Convert classes to IDs (copied svg-toolkit code from ids-to-classes.js)
- Add additional classes based on json data
- Add titles to the paths to function as tool tips
- Add ID to svg element based on the filename (without path or extension)
- Remove unwanted attributes (e.g. SVG height, width)
- Plug-ins
- Custom coding options
VI. Technique: Using SVG in HTML
- Option 1: Html Embed
- Add the SVG within an embed element (embed src="content/icon2.svg" id="svg")
- Some javascript functionality may require that the "embed" element be placed within an "object" element
- Option 2: Inline (preferred)
- Include the svg in the file (inline or with ng-include in angular)
- Option 3: Symbols (with Inline)
- Use the inline method above, but load a single svg, with each image as a symbol within the svg element
- Embed a "use" element with xlink:href = symbol_ID
- Works well for reusable items that do not need later dynamic css (e.g. hover, animate)
- However dynamic css will not work with symbols reused with xlink
- These elements will still be accessible via javascript
VII. Technique: Using javascript with SVG
- Jquery (or jqlite in AngularJs)
- "addClass/removeClass" does not work with SVG selector
- "attr" works with SVG selector, but substituting attr(item,'') for removeClass removes all element classes
- Could use attr to assign a new "data-status=active" attribute, but the attribute css selector does not work well
- Add addClass/removeClass to the plain javascript SVGelement (best solution)
- http://toddmotto.com/hacking-svg-traversing-with-ease-addclass-removeclass-toggleclass-functions/
- Works for single elements (document.querySelector), but not multiple (querySelectorAll)
- Use Todd Moto's solution inside for loop, jquery(".class").each function or other iterator (e.g. lodash)
- "addClass/removeClass" does not work with SVG selector
- D3.js
- Use d3.xml to load the external svg file and add it to an element in the DOM
- http://bl.ocks.org/mbostock/1014829
- However, the svg embedded styles including media queries do not work
- Use d3.xml to load the external svg file and add it to an element in the DOM
- Angular
- Use svg as the component template instead of an html file (I prefer this)
- Allows SVG to be manipulated with code, css, trigger events, directives (e.g. ngClass)
- Use custom Angular Directive (older method, AngularJs)
- Use ng-include attribute on a div to load the svg
- Include filename must be in double AND single quotes "'file.svg'"
- This places the svg inline at runtime (allows for access to svg classes, dynamic styling)
- Keeps the source files small during development
- However, this does not make optimal use of angular
- Use svg as the component template instead of an html file (I prefer this)
VIII. Resources
- SVG Techniques
- SVG-News
- CSS-Tricks
- Smashing Magazine
- SVG Utilities
- PicSvg Bitmap to SVG Converter
- SvgCircus Looped SVG Animation Creator
- SVG Tutorials
- Brian Treese (2015) SVG Fundamentals, Pluralsight (subscription)
- Iam Johnson (2013) Interactive Data Visualization with D3, Pluralsight from Frontend Masters (subscription)
- SVG Trend Setters
- Mike Bostock (D3 Author)
- Sara Soueidan
- Chris Coyier
- Ian Johnson (d3 data visualization)
- SVG Javascript Libraries
- D3.js Data Visualization Library
- SnapSvg Javascript manipulation
- Vivus.Js line drawing animation
- JsPlumb SVG connector elements (e.g. schematic diagrams)