Creating visually attractive charts with AmCharts
For the municipality of The Hague I recently worked on a challenging project. In this project I had to import csv-files, parse them to json and show the output in html. The values should be displayed in text, tables and charts. Both tables and text are not that hard to make in code, but creating good interactive charts is a wholly different thing. This is why I searched for a good plugin.
Which plugin shall we pick?
I was looking for a plugin that was customizable both visually and in functionality. For the project we needed to have multiple types of graphs (for instance bar and line) with guidelines and it was very important that the chart was responsive and easy to use. I found AmCharts to be a good base to expand on, in the way we wanted.
From design to plug-in
We wanted to show several types of charts on one page, such as a bar-chart, stacked-bar-chart, line-chart and donut-chart. To do this, the plugin works with separate ‘code-blocks’ (see the figure). The valueaxis, categoryaxis, balloons and the graph itself are created separately and then added to the main-chart. This makes it possible to put the separate parts of the plugin into different functions which can be called when needed. In this way it’s also possible to pass arguments to the functions that create those chart-parts. Because of this I could style each chart as I wanted without rewriting a lot of code.
The design we made was fresh, simple, clean and understandable. Especially when using a plugin, it can be difficult to translate these properties to code properly. Luckily AmCharts has many options to style (for example) thickness of the lines, margins, custom fonts and colors. This way I could translate the design into code almost literally.
We wanted to customize the color of the bars in the charts depending on their values, to make the charts visually more understandable. For this we used a chart with two bars combined; the first bar serves as the ‘comparison’, the second one changes color depending on the first one. For instance if the second value is higher than the first it should turn red, if it’s the same or lower it should turn green.
The plugin uses json to pass the data to the chart. Because of this, I could make a custom function that compares both values and adds the right hex-value to the color-field.
Labels and balloons
Besides using the fields in the data-json for customizing styles, it’s also possible to add custom functions. I used this to rewrite the ‘balloon’ that shows when a user hovers over a data-point in the graph. One of the things we wanted to do, was show data in the balloon that is not in the chart-data-json. I rewrote the labelFunction and the balloonFunction for this purpose. It’s not possible to pass arguments to these functions directly but I worked around this by putting the chart-function inside another function which does accept arguments. This function then uses those arguments to create the correct content and returns the chart-function with this content back to the chart.
AmLegend vs HTML/CSS
The plugin has many options for creating a legend, such as showing a value at the legend when hovering over the chart. It can also calculate and display the sum of the values. Although it’s nice to have so many options for displaying the values I missed those options for customizing the label itself. There are options to choose the kind of marker you want (round, square) but it’s not possible to add your own marker or style the existing ones. I also ran into problems because, in some of our charts the colors are depended on another value so the colors of the graph can change. The legend function doesn’t provide enough options to show multiple colors for one key. In the end I chose to not use the legend functionality and I added the legend myself using html and css.
Adding comments to data-points
Sometimes some values exist in the data that are out-of-spec, which is why we wanted the possibility to add comments to explain these data-points. AmCharts doesn’t provide this kind of functionality and because the comments should also appear on other parts of the page I chose to create a custom function for this. The tricky thing was to determine where the comment balloon should be added. AmCharts uses SVG to render the charts, so I used the ‘:contains’ selector to target the category-axis label for the specific data-point and added the comment-icon and balloon to those coordinates. The same could be done for other elements on the page, such as tables, which use the same label-format.
I was quite happy with the many options AmCharts provides to customize both functionality and looks. Because the chart-configuration could be split in separate code-blocks it was possible to use my own functions together with the plugin’s functionality. This way I could create the experience we designed instead of the experience of a standard plugin.