Skip to content
/ ico Public
forked from alexyoung/ico

JavaScript graph library based on Raphaël

License

Notifications You must be signed in to change notification settings

uiteoi/ico

 
 

Repository files navigation

Introduction

Ico is a JavaScript graph library that uses Raphaël to render graphics. This means Ico can render charts in the vast majority of modern web browsers, using VML in IE (< 9), or SVG in SVG standard-compliant web browsers such as IE 9, Firefox, Apple Safari, Google Chrome, Opera, and Konqueror for Linux. Also because Raphaël does not rely on Flash, it works well (and is tested) on iPhone.

Ico’s goal is to provide effective visual reprensentation of data according to the work of Stephen Few and Edward Tufte. In particular, Ico provides an implementation of Edward tufte’s Sparklines and Stephen Few’s Bullet Graphs.

Effective visual reprensentation of data can be achieved by following Stephen Few’s graph design considerations:

  • Clarity: Use of white-space to help lend clarity to graphs, nominal scale vs. ordinal scale
  • Simplicity: Minimal use of decorations and lines, reliance on the Gestalt principle of closure
  • Conciseness: Avoidance of graph types that don’t efficiently present data (pie charts, radar maps)

Ico’s core provides the set of graphs and features to achieve this goal:

  • Sparklines, Sparbars, and Bullet Graphs
  • Line graphs
  • Horizontal and Vertical Bar Graphs

This version of Ico is designed to be extensible beyond its core by providing either new graph types or new graph components. A graph component automatically becomes available to all graph types.

The original version of Ico was written by Alex Young. The current version features a new API, mainly due to componentization of many graph features, comprehensive documentation, many bug fixes, new features, most importantly implements bullet graphs, angled labels, gradient backgrounds, proper negative bar graphs rendering. For a complete list of modifications read the release notes.

Demonstration, test suite

To see a demonstration of the capabilities of the current version, check the current test suite in index.html.

Unfortunatly tests cannot be automated because it is primaraly about rendering in supported web browsers, most of which do not provide an API suitable for test suites. The test suite is a set of graphs showing most of Ico features. This test suite is meant to be viewed in all supported web browsers where the following tests are performed:

  • scroll up and down, mouse over graphs
  • zoom page, mouse over graphs
  • check for font display defects such as characters mis-alignments
  • measure the time to render the entire test suite page

Dependencies

Ico requires:

Examples

Simple sparkline, no decoration:

new Ico.SparkLine(
  "market_trend_id",                                // DOM element where the sparkline is rendered
  [5, 2, -1, 17, 23, 15, 7, 6, -5, -2, 4, 7, 3, 9]  // List of values for market trend
)

Bullet graph with 3 graph background colors and gradient transtitions:

new Ico.BulletGraph(
  "gross_profit_id",      // DOM element where the bullet graph will be rendered
  85,                     // Actual gross profit for current period as a percentage of gross revenues
  {                       // Bullet graph options
    min: 0,               // Minimum gross profit value
    max: 100,             // Maximum gross profit value
    target: 65,           // Forecasted gross profit value
    graph_background: {   // Defines graph background for gross profit
      key_values: [50, 75],               // Less than 50% is bad, more than 75% is good, in between is ok
      key_colors: ['#555','#999','#ddd'], // The 3 colors representing the 3 quality zones
      colors_transition: 10               // 10% Gradient transition between the different zones
    }
  }
)

Line graph with 2 lines, angled labels, $ units, meanline, mouse pointer, mouse-over value in status bar, and grid:

var months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
new Ico.LineGraph(
  "gross_profit_id",                               // DOM element where the graph will be rendered
  [                                                // The 2 series
    [31, 5, 1, -5, 15, 33, 20, 25, 1, 12, 25, -3], // Drawn first
    [18, -1, -7, 17, 15, 21, 1, 25, 3, 21, 16, 4]  // Drawn last, on top of previous series
  ],
  {                                                // Graph components' options
    colors: ['#228899', '#339933' ],               // Series' colors
    curve_amount: 10,                              // Slightly curve series' lines path using Cubic B&eacute;zier
    mouseover_attributes: { stroke: 'green' },     // When hovering over values
    font_size: 16,                                 // for both labels and value labels and other elements
    labels: { values: months, angle: 30 },         // Set labels at a 30 degres angle
    x_padding_right: 40,                           // Make more room on the right to properly display labels
    units: '$',                                    // $ units to display values
    units_position: 0                              // Render $ before values
    value_labels: {                                // Controls value labels
      marker_size: 4                               // Value labels markers set to 4 pixels instead of 5
    },
    background: { color: '#ccf', corners: 5 },     // Set entire div background color and corner size 
    meanline: true,                                // Display mean value of all series
    grid: true,                                    // Display a grid from labels and value labels
    mouse_pointer: true,                           // Display a cross mouse pointer in graph area
    status_bar : true,                             // Display status bar to show values on mouse over
  }
)

See index.html for more examples.

Documentation

Graph classes

Graph classes provide defaults components appropriate for each type of graph:

Class name Base class Description
Ico.Base n/a Base class for all graphs, provides components architecture
Ico.SparkLine Ico.Base Draw a single serie as a line. Expected to be rendered as an inline-block
Ico.SparkBar Ico.SparkLine Draw a single serie of vertical bars. Expected to be rendered as an inline-block
Ico.BulletGraph Ico.Base Draw a single value as a horizontal bar. Expected to be rendered as an inline-block
Ico.BaseGraph Ico.Base Base class for more complex, multi lines and bars graphs
Ico.LineGraph Ico.BaseGraph Represent series as lines
Ico.BarGraph Ico.BaseGraph Vertical Bars Graph
Ico.HorizontalBarGraph Ico.BarGraph Horizontal Bars Graph

To create and render a graph, call new Ico.desired_graph_type, providing three parameters:

  • The DOM element where the graph will be rendered
  • Data series
  • Options (optional)

Example creating and rendering a line graph:

new Ico.LineGraph( dom_element, data_series, graph_options )

The DOM element can be provided as a DOM Element object:

new Ico.LineGraph( $( "sales" ), data_series, graph_options )

The DOM element can also be specified using a string containing a DOM id:

new Ico.LineGraph( "sales", data_series, graph_options )

Data series can provided as:

  • A single value (for a bullet graph only)
  • An array of values for a single data serie
  • An array of array of values for multiple series data

Examples:

// A single value for a bullet graph
data_series = -20

// An array of values for a single serie graph data_series = [5, 2, -1, 17, 23, 15, 7, 6, -5, -2, 4, 7, 3, 9]
// An array of arrays of values for multiple series graphs data_series = [ [31, 5, 1, -5, 15, 33, 20, 25, 1, 12, 25, -3], [18, -1, -7, 17, 15, 21, 1, 25, 3, 21, 16, 4] ]

Options are provided as a hash of options where each key is the option name and each value is the option value. Options hashes can be nested typically to group options by components.

Many options are Raphaël attributes which rely on the SVG Specification so please refer to these documents when further information is needed.

Example of options:

graph_options = {                     // Graph components' options
  colors: ['#228899', '#339933' ],               // Series' colors
  curve_amount: 10,                              // Slightly curve series' lines path using Cubic B&eacute;zier
  mouseover_attributes: { stroke: 'green' },     // When hovering over values
  font_size: 16,                                 // for both labels and value labels and other elements
  labels: { values: months, angle: 30 },         // Set labels at a 30 degres angle
  x_padding_right: 40,                           // Make more room on the right to properly display labels
  units: '$',                                    // $ units to display values
  units_position: 0                              // Render $ before values
  value_labels: {                                // Controls value labels
    marker_size: 4                               // Value labels markers set to 4 pixels instead of 5
  },
  background: { color: '#ccf', corners: 5 },     // Set entire div background color and corner size 
  meanline: true,                                // Display mean value of all series
  grid: true,                                    // Display a grid from labels and value labels
  mouse_pointer: true,                           // Display a cross mouse pointer in graph area
  status_bar : true,                             // Display status bar to show values on mouse over
}

Ico.Base options

The following are options shared by all graphs:

Option name Default value Description
width DOM element width Raphaël Canvas width
height DOM element height Raphaël Canvas height
x_padding_left 0 pixels Padding left of the graph array
x_padding_right 0 pixels Padding right of the graph array
y_padding_top 0 pixels Padding above the graph array
y_padding_bottom 0 pixels Padding under the graph array
color DOM element color Color for single data serie
mouseover_attributes see bellow Mouseover attributes for data series
mouseover_attributes.stroke red SVG stroke color
orientation 0 0: horizontal, 1:vertical
units Units to display with values
units_position 1 Position of units: 0 => before value, 1 => after value
font_size element’s font-family Text elements font size – e.g. ‘1cm’
font See below Font attributes for all text elements
font[‘font-family’] element’s font-family Font family – e.g. ‘Arial’
font[‘font-size’] font_size || element font-family Font size – e.g. ‘1cm’
font.fill element’s color Font fill – e.g. ‘blue’
font.stroke ‘none’ Font stroke color – e.g. ‘black’
axis X/Y axis, true => display, hash => see ‘axis’ component option attribute

Ico.SparkLine and Ico.SparkBar options

Option name Default value Description
highlight false Higlights a value by displaying a point in sparklines or a bar in sparkbars. true => highlight last value, hash => provide additional options
highlight.index Index of the value to highlight, 0 => first value, null => last value
highlight.color ‘red’ Highlight color
highlight.radius 2 Radius of the highlight circle, for sparklines only

Ico.BulletGraph options

Option name Default value Description
min 0 Minimum (start) value
max 100 Maximum (stop) value
color ‘#33e’ (blue) Color for value bar
target Target rendered as a vertical line, number => target value, hash => see below
target.value Target value rendered as a vertical bar
target.color ‘#666’ (dark grey) Color for target vertical bar
target.length 0.8 Length of target vertical bar, <= 1
target[‘stroke-width’] 2 (pixels) Width of vertical target line
graph_background see Ico.Component.Graph defaults Include graph background component, false => disable

Ico.BaseGraph options

Ico.BaseGraph is used as a base for more complex graphs possibly with multiple series whereas sparklines and sparkbars are limited to one serie.

Ico.BaseGraph extends Ico.Base with more default features such as value_labels, focus_hint and axis enabled by default.

The following options apply as defaults for bar and Line graphs unless overrided:

Option name Default value Description
x_padding_left 10 pixels Padding left of the graph array
x_padding_right 20 pixels Padding right of the graph array
y_padding_top 20 pixels Padding above the graph array
y_padding_bottom 10 pixels Padding under the graph array
colors[serie_key] Ico.Base color || Random color Line color for serie ‘serie_key’
value_labels See Component.ValueLabels Display value labels
focus_hint true Display focus hint if value labels do not start at zero. false => disable, hash => ‘focus_hint’ component options attribute
axis true Display x and y axis, false => disable, hash => see ‘axis’ component option attribute

Ico.LineGraph options

Option name Default value Description
series_attributes[] See bellow Attributes by data series
series_attributes[serie_key].stroke Ico.BaseGraph colors[serie_key] Color for line ‘serie_key’
series_attributes[serie_key][‘stroke-width’] 2 pixels Line ‘serie_key’ width
curve_amount 5 pixels Cubic Bézier curve amount, 0 => disable
dot_radius[] 3 pixels Radius of dots for values, 0 => no dot displayed, Array => per line values
dot_attributes[] See bellow Dot attributes for all data series
dot_attributes[serie_key][‘stroke-width’] 1 pixel Dot stroke width for serie_key
dot_attributes[serie_key].stroke Background component color || options.color[serie_key] Dot color for serie_key
dot_attributes[serie_key].fill options.color Dot fill color for serie_key
focus_radius[] 6 pixels Radius of focus, 0 => disable mouse over action, Array => per line values
focus_attributes { stroke: ‘none’, ‘fill’: ‘white’, ‘fill-opacity’ : 0 } Attributes hash for focus circle

Ico.BarGraph and Ico.HorizontalBarGraph options

Option name Default value Description
series_attributes[] See bellow Array by data series key for bar attributes
series_attributes[serie_key].stroke ‘none’ Stroke color for bar
series_attributes[serie_key][‘stroke-width’] 2 pixels Stroke width for bar
series_attributes[serie_key].gradient gradient based on option.color or random color Fill gradient for bar
bar_padding 5 pixels Padding between bars
bars_overlap 1/2 Overlapping between bars (unit fraction): 0 → no overlap, 1/1 → full overlap

Component Classes

Graph features are driven by components. Each graph type defines different default components and graph orientation (horizontal or vertical) and other graph-specific options. Default components can be disabled by explicitly setting their option attribute to false.
Each component is shown with the name of its options attribute hash:

Component Class Base Class Option Attribute Name Drawing Layer Description
Ico.Component Base class of all graph components
Ico.Component.Background Ico.Component background 0 Background of the entire canvas
Ico.Component.Grid Ico.Component grid 0 Grid
Ico.Component.Graph Ico.Component graph_background 1 Graph area, excluding canvas padding areas, background
Ico.Component.MousePointer Ico.Component mouse_pointer 2 Display the mouse pointer as a cross when in graph area
Ico.Component.StatusBar Ico.Component status_bar 2 Display values on mouse over in status area
Ico.Component.Meanline Ico.Component meanline 3 Mean line at the mean of all data values accross all series
Ico.Component.Labels Ico.Component labels 3 Labels along the data series
Ico.Component.ValueLabels Ico.Component.Labels value_labels 4 Label values accross data series
Ico.Component.Axis Ico.Component axis 4 X and Y Axis
Ico.Component.FocusHint Ico.Component focus_hint 5 Display hint if value labels do not contain zero

Component option attributes

Component options can be set with the following types of values:

  • false => disable feature, useful when a graph type sets the option by default
  • true => get default options for the component
  • hash => attributes for the component

If a hash is provided and one of the options name is ‘attributes’, it is a hash of Raphaël attributes. Attribute option tables bellow define only the subset of Ico default attributes although all valid Raphaël attributes can be used.

‘labels’ and ‘value_labels’ option attribute

Labels are series’ samples labels, while value labels are numerical labels associated with series’ data.

Labels are defined by the option attribute ‘labels’. If an array is provided, it reprensents the values of the labels. If more label options are provided, labels must be provided as a hash of options.

Label components always make room for themselves in the padding areas.

Values labels are always calculated. The calculation is optimized according to the following criteria:

  • If zero is in the range (between min and max values), zero is always one of the value labels
  • The maximum number of value labels is limited by the size of the graph area, the font, angle and orientation of the graph
  • The number of labels is chosen to minimize unused areas to maximize the size of displayed data series
  • The step beetween two value labels has a maximum of 2 significant digits and is a multiple of 5 if the 2 significant digits are required
  • Values labels are limited to 3 significant digits using string manipulations to avoid floating-point rounding errors
  • Once value labels are calculated, precision is fixed, possibly adding zeros to nicely align labels
  • Finally, appropriate padding is added to make room for calculated labels using just as much space as neccesary and according to labels angle
Option name Default value Description
values [1, .., # of data samples -1] Label values, ignored for value_labels which are always calculated
font Ico.Base font Label font hash
marker_size 5 pixels size of labels markers, 0 => disable
markers_attributes See bellow Label markers attributes hash
markers_attributes.stroke labels font fill Stroke color for label markers
markers_attributes[‘stroke-width’] 1 pixel Stroke width for label markers
angle 0 Clockwise Angle to display labels in degrees (-90 to +90)
grid grid component Grid attributes, overrides grid component

‘graph_background’ option attribute

The graph area is the area where data series are rendered. This does not include padding areas where labels and other graph features are rendered.

The graph_background option attribute, if present allows to display a grandient of colors in the graph area. The gradient is drawn along the value labels axis to add meaning to ranges of values. The default gradient meaning represents ranges where the values are ‘bad’, ‘acceptable’, and ‘good’. The actual meaning of these background colors is application-specific and the same colors could mean ‘small’, ‘average’, and ‘tall’ or any other meaning.

The graph_background attribute can be set to true to get the default background or a hash to provide specific attributes:

Option name Default value Description
key_colors [‘#aaa’,‘#ccc’,‘#eee’] Colors of the different areas of the background
key_values [50, 75] Values where the transitions occur, there should be one less value than key_colors
colors_transition 0 Percentage of key_values where colors transition with a gradient

‘background’ option attribute

The background is the entire Raphaël canvas area.

Option name Default value Description
color Background color
attributes See bellow Attribute hash for background
attributes.stroke ‘none’ Stroke color
attributes.fill color Fill color
corners Canvas height / 20 Radius of rounded corners, 0 to disable

‘grid’ option attribute

If the ‘grid’ option attribute is provided it can be set to true or a hash of additional options.

All Raphaël Element Attributes are valid, only listed here are those whith default values:

Option name Default value Description
through undefined true: grid line extends to graph borders
stroke ‘#eee’ (very light grey) Stroke color
‘stroke-width’ 1 pixel Grid stroke width

‘axis’ option attribute

If the ‘axis’ option attribute is provided it can be set to true or a hash of additional options:

Option name Default value Description
attributes See below Axis attributes
attributes.stroke ‘#666’ (grey) Stroke color
attributes[‘stroke-width’] 1 pixel Axis stroke width

‘meanline’ option attribute

If the ‘meanline’ attribute option is set to true or a hash of additional attributes, Ico calculates the mean of all values of all series and displays this mean value as line parallel to labels’ axis.

Option name Default value Description
attributes See below Meanline attributes
attributes.stroke ‘#bbb’ (light grey) Stroke color
attributes[‘stroke-width’] 2 pixels Meanline stroke width

‘focus_hint’ option attribute

A focus hint is displayed as two short lines crossing the value labels axis if the value range does not include zero in order to attract the attention of the users that the graph does not start at zero nor contains zero.

Option name Default value Description
length 6 pixels Length of each focus hint line
color options.labels_font.fill Hint lines color
attributes See below Hint lines attributes
attributes.stroke color Hint lines stroke color
attributes[‘stroke-width’] 2 pixels Hint lines stroke width

‘mouse_pointer’ option attribute

If the ‘mouse_pointer’ attribute option is set to true or a hash, a mouse pointer is displayed when the mouse is over the graph area as a cross spanning the entire width and height of the graph area.

Option name Default value Description
attributes See below Mouse Pointer attributes
attributes.stroke ‘#666’ (grey) Stroke color
attributes[‘stroke-dasharray’] '--' SVG stroke pattern

‘status_bar’ option attribute

If the ‘status_bar’ attribute option is set to true or a hash, value are displayed on mouse over in the top padding area.

Option name Default value Description
attributes See below Status bar attributes
attributes[‘text-anchor’] ‘end’ SVG anchor in the top padding area

Tested web browsers, known issues

  • Firefox: best compromize of quality and speed, some rendering problems of angled fonts
  • IE: best angled fonts rendering, slowest by far
  • Safari: fastest, bugs: while zooming
  • Google Chrome: good quality, bugs: while zooming
  • iPhone (Safari): pretty amazing, try it
  • Opera: good fonts rendering, bugs: zoom, mouse-over while scrolling

Wishlist

This section outlines the projected improvements for upcoming releases.

Features:

  • Display Value Labels Title either above the y axis, in the status bar or under value labels if horizontal graph
  • Allow greater control of labels positioning: left-justification, top, right
  • By default Draw labels on top (or right if orientation) if all values are negative
  • Enable values formatting with a function to allow custom numbers formatting, provide default formatters
  • Allow single axis (x or y) to be displayed
  • Display values in tooltips instead of status bar, tooltips implemented w/ an external DOM library to enable out-of-the-canvas tooltips
  • Zoom-in spark lines, spark bars, and bullet graphs on-mouse-over.
  • Display full graph of spark lines and spark bars on mouse-click, possibly in a tooltip
  • Facilitate user events definition on graph elements
  • Add zero line component to draw a line at zero when zero in the range. This can be done today by adding a dummy serie but this would make it easier.

Architechture:

  • Componentize series in a Ico.Serie class to allow bars and lines in the same graph but also to allow new types of data series rendering

Documentation:

  • Ico box model
  • methods beyond intitialization
  • (for contributors) Graph and Components extensions

About

JavaScript graph library based on Raphaël

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages

  • JavaScript 100.0%