HTML5 Sparkline chart for data-intense, small-scale Data Visualization

Damyan Petev / Tuesday, October 08, 2013

HTML5 / jQuery Sparkline chartIt’s a scaled-down, simplified version of your normal chart that is excellent for quick analysis of a lot of data and trend-spotting. For the more curious ones, the inventor of the Sparkline hosts a Q&A board on Sparkline theory and practice where you can find some general DO's and DON'Ts as well as various scenarios people found Sparklines useful in. There’s also a very visually-rich blog on Sparklines in the Excel Blogs if you want more. Described as “intense, simple, word-sized graphics”, Sparklines go beyond a simple line. The typical example is “inline with text”, however there are multiple cases where it would be useful as a part of a grid. At least from what I have seen, I accept the term as a synonym for small visualization of any kind suitable – lines and areas, of course, but also columns and bars, with/or without axes, ranges, markers, trend lines. It’s not the plethora of switches and knobs the Data Chart has, but it can be just as data-intensive while keeping it small. Just as note – these charts are still meant to be simple and even if you can show every extra bit of information on one, it might not always be the best design!

The Ignite UI Sparkline

After a series of Data Visualization controls have made their appearance in our Ignite UI product – the mighty Data Chart, then Pie, the Geographic map, translated from C# to jQuery, it was only logical to expand more. The Sparkline is a part of another wave of controls taking the HTML5 Canvas route, which means no plugins and available on most mobile devices. This specific chart is designed to be lightweight, so don’t expect too much extra bulk – single series supported with 4 display types and a single set of axes with limited amount of labeling and so on.

The default is line series:

  1. $("#Spark0").igSparkline({
  2.     displayType: "line",
  3.     dataSource: employees,
  4.     valueMemberPath: "SickLeaveHours",
  5.     height: "50px",
  6.     width: "50%",
  7.     normalRangeMaximum: 49,
  8.     normalRangeMinimum: 45,
  9.     normalRangeVisibility: "visible",
  10.     verticalAxisVisibility: "visible",
  11.     highMarkerVisibility: "visible",
  12.     lowMarkerVisibility: "visible"
  13. });

Line with normal range and high/low markers

Swap the line for area and markers for another axis:

Area with both axes visible

Column series with a trend line:

Column with  'quinticFit' trendline

and Win / Loss :

Win/Loss with vertical axis and 'exponentialAverage' trendline showing the same data as the columns above

Both bar charts use the same data. The difference between is that Win-Loss is on a Boolean scale, which is to say that the points presented don’t match their values – it’s either full gain, full loss or neutral.

There are a few types of markers and 13 different trend line types and there’s a very nice igSparkline Overview article with visuals for everything, so you totally need to check that one out in case you haven’t seen all this control has to offer. Of course, as you would notice in the linked articles, the Sparkline is mainly intended for inline and the ones above are somewhat bigger. With some tweaking you can make them work inline as well:

Sparklines with tweaked CSS (inline, removed border and background) and reduced size to show alongside text

It’s all in the name of having meaningful visualization for very high amounts of data squished in a very tiny space and make the most out of that. So, yes inline with text is a great and so is inside grid cells where such a chart can provide the ‘gist’ of a whole another table in a single cell and be easier to read as well. More on that on a follow up blog I have coming up real soon!

Tips and Tricks

So here comes an assortment of things you might find interesting and useful. Like for example, the fact that  values and member paths are optional – the data source can be a simple array of numbers and then you don’t need to specify a value path. Label path is only needed when you are displaying an axis.

All your base… chart!

If you visit the API Documentation for Data Visualization controls you are likely to find the igBaseChart. It is exactly as it sounds –  the control the Sparkline and some others extend. This is where the data source and tooltip handling come from and you may notice there are events for those. However, and this has to do with how events work in jQuery UI widgets, the actual control triggering the events is the Sparkline – so instead of “igbasechartupdatetooltip” you see listed, you should use “igsparklineupdatetooltip” for example. Controls trigger the event by name and their namespace is prefixed automatically. This way you can do additional work before showing or hiding the tooltip. Like changing the position to be to the side of the chart, which I think might be better for mobile experience:

  1. $("#Spark0").on("igsparklineupdatetooltip", function (evt, ui) {
  2.      ui.x = ui.owner.element.outerWidth() + 2;
  3.      ui.y = Math.abs(ui.owner.element.outerHeight() - ui.element.outerHeight())/2;
  4.  });

The Sparkline tooltip with position modified to be to the right of the control

Or change the text and you can provide handler in initialization:

  1. $("#Spark0").igSparkline({
  2.     updateTooltip: function(evt, ui) {
  3.         ui.text += "
    You can also type here and modify the tooltip element via ui.element"
    ;
  4.     }
  5.     //...
  6. });

Tooltip text modified using the event handler argument

In the tooltip template you have 4 values available – the first, last, the highest and lowest values. Keep in mind those can easily be the same ones, depending on data. Here’s a small MVC helper snippet for using them all in a template:

  1. @(Html.Infragistics().Sparkline<IQueryableEmployee>>()
  2. .ID("Spark")
  3. .DataSource(Model.AsQueryable())
  4. .TooltipTemplate("High: ${High}
    Low: ${Low}
    First: ${First}
    Last: ${Last}"
    )
  5. .ValueMemberPath("SickLeaveHours")
  6. .Height("50px").Width("200px")
  7. .DataBind()
  8. .Render())

Beautify your data: Styling Guide

Yet another interesting topic, as it is still a Data Visualization control and it’s intended for the Web. So I’m hoping you’ve most seen the Styling igDataChart with Themes and perhaps for some other controls and if you are wondering if the Sparkline can do the same… Why yes, yes it can! And here comes a nice list of CSS classes that can be used to modify the looks of this control.

All of the classes are prefixed with “ui-sparkline-” and state what do they apply to – “sparkpath”, “negativesparkpath”, “trendline”, “markers”, “firstmarker”, “lastmarker”, “highmarker”, “lowmarker”, “negativemarkers”, “range”. For example, you have the spark path, the high and low markers:

A representation of how CSS Sparkline classes map to options of the visual elements

The CSS background color along with CSS opacity, if you provide it, map to the brush color of the element in question. The border width (and width alone, regardless of this example showing a shorthand declaration) corresponds to the brush size (e.g “highMarkerSize”). I think it’s visible enough to see that the high marker is bigger than the low one. Note that almost everything has a minimum value of 1.5px and will merely ignore lower values. There values are available for all markers, lines and range:

  1. /* "background-color", "opacity", "border-width" apply */
  2. .ui-sparkline-sparkpath {
  3.     background:#00AADE;
  4.     border:1.5px solid
  5. }
  6. .ui-sparkline-negativesparkpath {
  7.     background:#D0284C;
  8.     border:1px solid
  9. }
  10. .ui-sparkline-trendline {
  11.     background:#555;
  12.     border:2px solid
  13. }
  14. .ui-sparkline-markers {
  15.     background:#36C0F3;
  16.     border:3px solid
  17. }
  18. .ui-sparkline-firstmarker {
  19.     background:#19994F;
  20.     border:5px solid
  21. }
  22. .ui-sparkline-lastmarker {
  23.     background:#FCB025;
  24.     border:5px solid
  25. }
  26. .ui-sparkline-highmarker {
  27.     background:#BFE107;
  28.     border:4px solid
  29. }
  30. .ui-sparkline-lowmarker {
  31.     background:#AF39FF;
  32.     border:3px solid
  33. }
  34. .ui-sparkline-negativemarkers {
  35.     background:#E5516F;
  36.     border:3px solid
  37. }
  38. .ui-sparkline-range {
  39.     background:gray;
  40.     opacity:.2
  41. }

In terms of columns the path is obviously applied as fill as well. For the axes you have slightly different rules – border corresponds to the axis stroke this time with color taken into account as well, there’s obviously no background, however font and color for the axis labels are used:

  1. /* "border-width", "border-color", "color", "font" apply */
  2. .ui-sparkline-axis-x {
  3.     font-family:"Segoe UI", Arial, sans-serif;
  4.     border:2px solid #989EA3;
  5.     color:#4B4B4D
  6. }
  7. .ui-sparkline-axis-y {
  8.     font-family:"Segoe UI", Arial, sans-serif;
  9.     border:2px solid #989EA3;
  10.     color:#4B4B4D;
  11. }

An important note is that those classes correspond to the control options you see in the API, however they are taken into account during initialization. So it’s nice to have a separation of concerns between visuals and functionality.. and let designers pick better colors than I would, for example :) However, if you want to modify the looks in runtime you will have to use the jQuery options.

Naturally, you can have the classes you can find in the Theming reference – they are applied to the actual HTML container and tooltip elements so any valid CSS is applicable. This is where you can override the background and border (coming from the standard jQuery UI “ui-widget-content” class), the canvas chart components have no background and no border. Note that if you don’t provide any styling for the other classes and no options are set, the styling will be inherited, because CSS is taken from inside the container with “ui-widget-content” applied, the various elements of the chart will probably inherit the theme’s default border color, size and font. Which is not too bad – you can use this to provide styling for all labels on both axes without using their specific CSS for example or know that the Sparkline will always be in tune with the rest of the page.

Misc

As you may have noticed in the snippets, the width of the Sparkline can be set in percentages and, like the other Ignite UI charts, it has a built-in handling of resizing. That means this chart is good to go for Responsive design and also will work well inside containing elements with varying size  - that will play an important role when we try the chart as a grid cell.

Also, since the scenario that makes the most sense (regardless of the bad data in my demos) is for analyzing trends, which means continuity and usually time-bound axis – and we all know the hell of JavaScript dates’ default string output. It is by far not appropriate for such a tiny chart, however you can format the labels to your liking with a simple function. It takes the “would’ve-been” value as parameter and should return the desired new label value instead. Keep in mind this event can and probably will fire multiple times and will also fire for the other axis (if you have one visible) – in which case, always check if you are formatting the right value. And one last thing – date values are already converted to string when they reach you, thus:

  1. $("#Spark1").igSparkline({
  2.     labelMemberPath: "HireDate",
  3.     verticalAxisVisibility: "visible",
  4.     horizontalAxisVisibility: "visible",
  5.     formatLabel : function formatFunction(val) {
  6.         if (typeof val === "string") {
  7.             // remove time from the label
  8.             val = val.split("T")[0];
  9.         }
  10.         return val;
  11.     }
  12.     //...
  13. });

Closing & Resources

I really hope the information above will come in handy. There’s a link to demos below with different types of Sparkline visuals, examples for inline setting, initializations, tooltip event handling and styling. I have one more post building on this information coming up soon, so keep an eye out for that one too.

I’d love to hear some thoughts, so leave a comment down below or @DamyanPetev.

And as always, you can follow us on Twitter @Infragistics and stay in touch on Facebook, Google+ and LinkedIn!