Back in the day, before color printers (or printers at all), people still had to make good data visualization. One way to do that was by using patterns instead of solid colors to indicate changes in scale or category.
For example, take a look at this set of pie charts, using different patterns for different categories. This chart shows the “Sources of the Farm-Tax Dollar in the United States for the Years 1927, 1930, 1932, and 1934”. It is from the very excellent treasure trove of old timey charts: Graphic presentation.
Introducing Pattern Fills:
I’m excited to share Pattern Fills, a collection of patterns and a process for creating your own.
Patternfills comes with a collection of several patterns at various gradations. The patterns can be used in two ways: as CSS classnames or as SVG pattern defs.
How do SVG patterns work?
In order to use an SVG pattern, you can define an SVG document containing the design to be repeated. For example, a document might look like this:
<svg xmlns='http://www.w3.org/2000/svg' width='10' height='10'>
<rect width='10' height='10' fill='#fff' />
<circle cx="1" cy="1" r="1" fill="#000"/>
</svg>
If you were to use this SVG document as a pattern, it would look like this:
SVG Pattern Definition:
Now that you have an SVG document defined that you wish to use as a pattern, you can add it to an SVG defs
section as a pattern
element. Note that the SVG document gets compressed into a base64 encoded string.
<svg height="10" width="10" xmlns="http://www.w3.org/2000/svg" version="1.1">
<defs>
<pattern id="circles-1" patternUnits="userSpaceOnUse" width="10" height="10">
<image xlink:href="data:image/svg+xml;base64,PHN2ZyB4bWxucz0naHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnIHdpZHRoPScxMCcgaGVpZ2h0PScxMCc+CiAgPHJlY3Qgd2lkdGg9JzEwJyBoZWlnaHQ9JzEwJyBmaWxsPScjZmZmJyAvPgogIDxjaXJjbGUgY3g9IjEiIGN5PSIxIiByPSIxIiBmaWxsPSIjMDAwIi8+Cjwvc3ZnPg=="
x="0" y="0" width="10" height="10">
</image>
</pattern>
</defs>
</svg>
This allows us to use the pattern using the fill
style attribute like so:
<svg height="100" width="100" style="float:left" class="pattern-swatch">
<rect style="fill: url(#circles-1) #fff;" x="0" y="0" height="100" width="100"></rect>
</svg>
CSS Class Name:
To define a pattern that can be applied using a classname, you should first define a CSS block where the pattern string is used as the background-image
url. For example:
.circles-1 {
background-image: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0naHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnIHdpZHRoPScxMCcgaGVpZ2h0PScxMCc+CiAgPHJlY3Qgd2lkdGg9JzEwJyBoZWlnaHQ9JzEwJyBmaWxsPScjZmZmJyAvPgogIDxjaXJjbGUgY3g9IjEiIGN5PSIxIiByPSIxIiBmaWxsPSIjMDAwIi8+Cjwvc3ZnPg==");
background-repeat: repeat;
}
This allows us to use the pattern like so:
<div class="circles-1">
</div>
What does Pattern Fills do?
There are several ways to use Pattern Fills:
You can use the
patterns.css
file that contains all the current patterns. That will only work for non-SVG elements.You can use individual patterns, but copying them from the sample pages. CSS class definitions can be found here and SVG pattern defs can be found here
You can add your own patterns or modify mine! The conversion process from SVG document to pattern is very tedious. The purpose of the pattern fills toolchain is to simplify this process. You can clone the repo, run
npm install
andgrunt dev
to get a local server going. After that, any changes or additions to thesrc/patterns/**/*
files will be automatically picked up and will re-render the CSS file and the sample pages. If you make new patterns, send them over in a pull request!
Old Timey Chart Time
Of course, we immediately had to make an old timey chart that you can see here. The d3.js code for this chart lives here.
Next steps
We’d love to hear any feedback. In the meanwhile, we’re going to make a lot more patterns and add some color customization to the mix.
Comments
We moved off of Disqus for data privacy and consent concerns, and are currently searching for a new commenting tool.
Thank you for the fantastic idea. I wish the patterns had transparent backgrounds, it would make the example chart more authentic looking. ( http://bit.ly/1Cdp1tv )
Thinking about alternate approaches, wondering if you could make clever use of UTF-8 characters: http://copypastecharacter.c… — or possibly a custom web-font.
|> \”Note that the SVG document gets compressed into a base64 encoded string.\”
How did that happen? Did you use a tool, process, script, or preform fancy long arithmetic?
The compression happens using a node.js library. It’s built into the grunt process so that when you compile your patterns, it will just do that for you.
Using UTF-8 characters would be super interesting! I’ll have to try it out. In theory, anything inside an SVG can be used as a pattern, so the opportunities are endless.
This actually has some great implications for those who are color blind or visually impaired on the web.
Agreed! I really want to incorporate patterns as defaults, or as part of my color choices.
Thanks for reviving interest in an old form!
We love using color for categorical data, but it’s hard to create a graph with more than 15-20 perceptually distinguishable colors, and the smaller the areas, the greater the problem! How many times have we squinted at a pie chart or chloropleth map wondering whether two \”green\” regions represented the same category?
Another trick used by earlier practitioners was to use characteristics of the cross-hatch to encode magnitude information. For example, in the pie charts, the wedges with the highest proportions have the heaviest thatches, and in the second figure, line weight encodes data magnitude.
Absolutely! I’m really curious to explore whether patterns are easier to discern than colors after a certain number. It’d be really fascinating if that were the case.
This brings back memories of school tests and drawing legends for maps and charts. Thanks for reviving it!
Thank YOU! It definitely takes me back too.
You should check out Textures.js…http://riccardoscalco.github.io/te…
Thanks Matthew! That’s great! I do remember Textures.js coming out. It certainly simplifies some of the workflow, but this post hopefully helps explain how these work and how you could roll your own.
Hi, thanks for this acticle!
I want apply pattern to embed svg by clicking on button
How it to do?
I tried to set Style Fill to my svg but it doesn’t work
mysvg.style.fill = \”url(#circles-1)\”;
Many Thanks
You should set the fill style on an actual element in your SVG, like a rect, but not the entire SVG itself.
This is seriously genius!
Thanks Jason! So glad this is useful.
This is exactly what I look for! Excellent!. Only one question: How I can control tha transparency and the color? I could not do that in CSS. Maybe modify the svg? How?
Hi Zsolt! You would have to modify some of SVG most likely and use a fill-opacity attribute.
the best!