Geek Culture
Published in

Geek Culture

Visualize Your Skills with D3

Create a Bubble Chart in Javascript and CSS

Photo by Max Gotts on Unsplash

The wave of Web 2.0, alongside the advance of mobile devices and the Internet infrastructure a decade ago, embraced a new paradigm of creating web and mobile application. It has changed our digital life to the next level, so do the skills we’ve learnt and used.

While technologies keep evolving rapidly, digital citizens have been accumulating a broad spectrum of skills throughout the journey. It is a challenge to match skills among job hunters and employers. A candidate proficient in specific skills a few years ago may not be interested in investing in it, whereas new abilities may promise more attractive salaries and compelling demands.

It is crucial to identify skill recency and competency. Today we will demonstrate how expressive a Bubble plot can help us in this situation. We use web developer skills as an example, but this approach applies to any technical or business domains. A basic understanding of HMTL, CSS and Javascript are sufficient to complete the tutorial.

What is a bubble plot?

According to Wikipedia, a bubble plot/ chart is a type of chart that displays three dimensions of data. (see details)

Visit here for the final product.

The X and Y axises are obvious to understand. The dot size depicts the competency. The bigger the point, the more proficient it is.

With a single glance on the right portion, we can instantly identity the most proficient skills, and in which Node, React, Git and CSS are the core competencies. All of them are practised more than five years, and used recently.

Simple idea and expressive presentation, isn’t it?

Let’s move to the next section to create one.

Section 1: Reading data

Look into the data set followed. The skill is a unique label for data points. There are four attributes attached to a data point. The category is the only string attribute for categorising the points. The exp (Year of experience) and lastUse (Last used year) attributes position the data point in the X-Y plane. The level of competency reflects in the size of the circle.

D3 provides a csv() function to load the CSV (Comma Separated Value) data. We will implement the chart in the callback function.

d3.csv(url, () => {


In the fact that the modern browser such as Chrome has posed stricter control in CORS in 2020. d3.csv() will encounter CORS policy error if we access a file in a local path, or a valid URL but CORS not enabled.

Fetch API cannot load file:///PATH_TO_YOUR_FILE/data.csv. URL scheme must be "http" or "https" for CORS request.

To avoid this hassle, we will host the CSV data on a Node server and allow CORS in the response headers.

This is the API endpoint to serve our bubble chart in this tutorial. 👉 Skills API

If you want to expose a CSV file as an API and deploy to a free Kubernetes cluster, don’t miss this tutorial. 🔥 Deploy API on Kubernetes for Free 🔥

Section 2: Making bubble chart


First create index.html with the followed HTML. There is a <div> with id skills_bubble_plot as the placeholder of the graph. Next we import D3 v4.13.0 and color scale library (d3-scale-chromatic). Then import plot.js and plot.css where we are going to implement today.


  1. Define the margins, width and height (line 1 to 4)
  2. Position the chart (line 12 to 17)
  3. Implement the bubble plots in the callback function of d3.csv (line 7)

Next implement the bubble chart in the then block (line 7).

X-axis (Year)

We use .domain() to create a range of years and .range() to define the width of the plot.

const x = d3.scaleLinear().domain([2013, 2022]).range([0, width]);

Y-axis (Experience)

Likewise, the y-axis is created the same way but notice the parameter of range start with a the height and then zero.

const y = d3.scaleLinear().domain([0, 10]).range([height, 0]);

It looks weird at first but when we check out the specification of .range()

.range([closer_to_the_origin, further_from_the_origin])

and realise the reference point of the HTML coordinate system is at the most top left corner [0, 0]. For details.

Z-axis (Competency)

const z = d3.scaleLinear().domain([0, 30]).range([4, 40]);


To colour the data points by categories (line 4 to 11) with a color scale, we will use schemeSet2 in line 13 and import the library in the <head>.

<script src=”"></script>


The label of Y-axis is tricky because it flip 90 degree anti-clockwise.


To illustrate a basic tooltip, first we attach a div on the skills_bubble_plot element and create a rounded corner label for data points.

Next, create three events for showing, hiding, and moving respectively.

Plot the data points

We will draw each data point by positioning at d.lastUse and d.exp. The radius of the point is based on d.competency ** 3 / 100 (the power to 3 of the value divided by 100) to make an exponential behaviour. Then we colour it according to its category. Last, we bind the mouseover, mousemove, mouseleave events.

Congratulation! We have created a four dimensional bubble chart to highlight the strength of an example candidate.

Complete source code 👈

Thank you for your time! I hope you like this tutorial.

If you want to impress recruiters with your ordinary CV in A4 format, check out Power up your CV part 1 & part 2.




A new tech publication by Start it up (

Recommended from Medium

How to make Dapp using solidity and web3js

Make scrolling on your React app fun using react-scroll

Mastering JavaScript’s Promises

Optimize Twilio IVR for Multi market contact centre

Advanced Type Composition with TypeScript

The better side of the Single value Observables in RxJs

Call the Cloud Vision API with Cloud Functions for Firebase

JavaScript sent you a friend request…

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Anthony Ng

Anthony Ng

Software Engineer

More from Medium

Dropdown problem with using UI Scaling

Boost up your confidence while merging a (front-end) PR

Aggressive Frontend Error Reporting

Chart showing a blue line of errors below yellow and red thresholds

Remote Workshop Best Practices