Marvin
Oct 23, 2022   ·   5 min read

Bubble Chart with Class Coloring

Color Filtering Vector Graphics

Why and How

Applying color filters on elements can be a useful technique for adding visual effects and enhancing the overall design or informational content of an image. Using color filters therefore allows you to create a more dynamic and engaging user experience.

A common use case for applying color filters to elements on this page is to change the color of an image to match a specific mastery level or champion class. For example, you might want to get a quick overview on how many mastery points you've accumulated on mages. Applying a blue color filter on all mages will allow you to get a solid idea on how much time you spent playing mages in comparison to other classes.

To reach this goal, usually, when you're trying to overlay an image in HTML with a color, you can just make use of your trusty old background CSS property, which allows you to specify multiple attribute values to get a basic color overlay on top of an image:

        
background: linear-gradient(to top, #ff000044, #ff0000ff), url('your/image/url');
        
        

When working with Scalable Vector Graphics (SVG), this will not work as the backgroundproperty has no effect on SVG elements, which instead works with the fillproperty. For simple cases like a simple solid background color or a background image linked via URL, fillwill work just the same. As soon as you'd like to use other properties such as gradients, their similarities quickly dwindle.

One possible way to combat this problem would be by layering a second, equally sized SVG element on top of the one containing the image and assigning it a transparent, colored background:


circle {
    fill: #ff0000;
    fill-opacity: 0.5;
}

This "hack" might be just enough for simple cases with few, static elements, but doesn't hit the mark for my use-case:

This page's core visualization, the Bubble Chart (such as the one displayed in the header) can hold over 150 separate circle SVG elements generated with D3.js that can be moved by changing the grouping type or manually by dragging them. The bubbles will interact with each other while being moved. Each of these bubbles contains an image. For a mobile browser, this can be quite a heavy task that will make the site laggy and worsen the user experience.

A different, lightweight solution is needed.

Our savior will be the SVG attribute filter, which supports all common CSS filters. To achieve our target color, we can apply a sepia(1) filter, which brings us to a color filtered image in a predictable color. This allows us to manipulate the color with other filters like hue-rotate, brightness and saturate. Luckily, someone already built a tool to find out which filters we need to reach a certain hex color.

The resulting color filtered element will be structured somewhat like this:


<circle fill="url('your/image/url')" filter="brightness(0.45) sepia(1) hue-rotate(310deg) saturate(5);"></circle>