Wednesday, December 3, 2014

Visual Weight And Direction

Every element on a web page exerts a visual force that attracts the eye of the viewer. The greater the force, the more the eye is attracted. These forces also appear to act on other elements, imparting a visual direction to their potential movement and suggesting where you should look next.
We refer to this force as visual weight and to the perceived direction of visual forces as visual direction. Both are important concepts to understand if you want to create hierarchy, flow, rhythm and balance in your composition.

Visual Weight

Physical weight is a measure of the force that gravity exerts on an object, but two-dimensional objects (such as elements on a web page) don’t have mass and, therefore, don’t have any physical weight. Visual weight is a measure of the force that an element exerts to attract the eye. Two-dimensional objects can attract attention. The more an element attracts the eye, the greater its visual weight.


For example, contrasting elements by making one very big and the other very small makes it clear that the elements are different.
Controlling the combination of these features is how you control visual weight. Red tends to attract the eye more than blue, and larger elements attract the eye more than smaller ones. A large red object carries more visual weight than a small blue object.
The sum of these characteristics or primitive features is what determines an element’s visual weight. It’s not any one feature, but rather their combination that determines the visual weight of an element. Some combinations of features will attract the eye more than others. To create elements of different visual weight, you would use different combinations of primitive features.

How Do You Measure Visual Weight?

There’s no way I know of to precisely measure the visual weight of a design element. You use your experience and judgment to determine which elements have greater or lesser weight. Develop an eye and then trust it. The areas of a composition that attract your eye are those that have greater visual weight. Learn to trust your eye.
This doesn’t mean that you have to randomly try things and see what attracts your eye the most and the least. You can isolate each characteristic to know that something bigger weighs more than something smaller, for example. It’s in the combination of features that your eye will help.
Fortunately, others have isolated and tested these characteristics. Below are some of the characteristics you can change on any element and a description of how changing them will either increase or decrease the element’s visual weight.
Let’s start with the primitive features that I mentioned in the last post: size, color, value, position, texture, shape and orientation.
  • Size
    Large elements have more visual weight than small elements.
  • Color
    Warm colors advance into the foreground and tend to weigh more than cool colors, which recede into the background. Red is considered the heaviest color and yellow the lightest.
  • Value
    Dark elements have more visual weight than light elements.
  • Position
    Elements located higher in the composition are perceived to weigh more than elements located lower in the composition. The further from the center or dominant area of a composition, the greater the visual weight an element will carry. Elements in the foreground carry more weight than elements in the background.
  • Texture
    Textured elements appear heavier than non-textured objects. Texture makes an element appear three-dimensional, which gives the appearance of mass and physical weight.
  • Shape
    Objects with a regular shape appear heavier than objects with an irregular shape. The irregularity gives the impression that mass has been removed from a regular shape.
  • Orientation
    Vertical objects appear heavier than horizontal objects. Diagonal elements carry the most weight.
You don’t have to limit yourself to the primitive features above. You can use additional characteristics to control visual weight.
  • Density
    Packing more elements into a given space increases the visual weight of the space. The viewer will perceive a larger or darker combined element as opposed to several smaller and lighter elements.
  • Local white space
    White space appears to have no visual weight because it’s seen as empty. Any object placed within that space will seem heavier because of the space around it.
  • Intrinsic interest
    Some things are more interesting than others. The more complex or intricate an element, the more interest it will draw and the more it will attract the eye. Your own interests also play a role. If you’re more interested in cars than in planes, then an image of a car will grab your attention more than an image of a plane.
  • Depth
    A larger depth of field gives an element in focus increased visual weight, likely due to the contrast between the focus and unfocused areas.
  • Saturation
    Saturated colors appear heavier than desaturated colors.
  • Perceived physical weight
    We know that a house weighs more than a shoe. An image of a house will weigh more visually than an image of a shoe, because we expect the house to weigh more.
In the previous post in this series about contrast and similarity, I mentioned that contrast draws attention to an element. In other words, an element that contrasts with its surroundings will appear visually heavier than its surroundings. For example, circles usually appear heavier than rectangles on a web page because most website elements are rectangular.
Not all characteristics contribute equally to visual weight. Most people will notice the color of an element before its shape, which suggests that color contributes more to visual weight. You also have to consider the uniqueness of a given composition, because contrasting elements appear weightier than the elements they contrast with. The specifics of your composition will determine what contrasts and what doesn’t.
Remember that visual weight is a combination of the above attributes. While big carries more visual weight than small, a small dark circle surrounded by a generous amount of white space and located at the top of the page will likely appear to weigh more than a larger yet irregularly shaped object of a cool light color at the bottom of the page.

Visual Weight and Gestalt

One of the ideas behind this series is to point out how much gestalt principles contribute to design principles.
  • Figure-ground
    Visual weights can be used to separate the two by giving the figure more weight than the background.
  • Proximity
    The space between elements leads to different amounts of local white space and different densities of the objects within the space.
  • Similarity and contrast
    You can use visual weight to signal either. Contrast will lead to greater visual weight in the contrasting element. Elements with similar visual weight will naturally exhibit similarity.
  • Focal point (the next topic in the series)
    Points of attraction in a composition are focal points, and they carry more visual weight than other elements.
  • Past experience
    The viewer’s experience will contribute to how much intrinsic interest they think an element holds.

Visual Direction

If visual weight is about attracting the eye to a particular location, then visual direction is about leading the eye to the next location. Visual direction is the perceived direction of visual forces. Think of it as the direction you would expect an element to move if it were in motion.
Visual direction serves a similar function to visual weight in that it’s trying to get you to notice certain parts of the composition. Whereas visual weight is shouting “Look at me!,” visual direction is saying “Look over there!”
As with visual weight, you can modify the characteristics of an element to suggest different directions, although fewer characteristics are at your disposal than with weight.
  • Shape of element
    An element’s shape might create an axis through it and this axis can suggest a direction. The prime axis is typically seen as running parallel to an element’s visual direction.
  • Location of elements
    Visual weight is a force that can appear to attract or repel a neighboring element. This force will move in a direction that connects both elements.
  • Subject matter of element
    An arrow, a pointing finger, or the gaze of the eye all suggest looking in a certain direction.
  • Movement
    An element could literally move through your design, and its movement will have a direction.
  • Structural skeleton
    Every composition has a structural skeleton, with forces that naturally run along and through different axes. This probably needs a little more explanation.

Structural Skeletons

In his book Art and Visual Perception: A Psychology of the Creative Eye, Rudolf Arnheim proposed the idea of a structural skeleton behind every canvas.
The idea is that every canvas has a structural network of forces running through it. Even if no elements are inside the canvas, our eye will be drawn to certain parts of the canvas because of this network of forces.

The center and the four corners of a rectangular canvas act like magnets to the eye. The strongest magnet is in the center, though not the geometric center of the canvas. Rather, the center that attracts the eye is the optical center, and it sits just above the true geometric center.
The axes run from corner to corner, and the points along these axes that are midway between center and corner also attract attention. These midway points can, then, be connected with vertical and horizontal lines, which create additional axes of visual force.
We’ll come back to this idea when we get to the post in the series about compositional flow. For now, consider that, in the absence of design, a viewer’s eye will be attracted to certain points in Arnheim’s structural skeleton, and the eye will move from point to point by following the directions of the different axes.
You can make use of the structural net by placing elements where they would naturally attract the eye, thereby increasing their attractive force.

Visual Direction and Gestalt

You can think of direction as real or imaginary lines that point from one element to another or that connect different elements. The lines don’t need to be visible.
  • Uniform connectedness
    The lines connecting elements have direction. An eye gaze creates an imaginary line between the eye and whatever the eye is gazing at.
  • Continuation
    This principle relates to elements arranged along a line or curve, as though they are moving in the direction of the line or curve.
  • Common fate
    Elements seen as having a common fate are those that move or appear to move in the same direction.
  • Parallelism
    In order for elements to be seen as parallel, their internal axes (the same ones that impart direction) must be established.

The Overall Direction Of A Composition

One more concept of visual direction is that every composition will be seen to have a dominant direction, whether horizontal, vertical or diagonal.
  • A horizontal direction makes the composition appear calm and stable.
  • A vertical direction adds a sense of formality, alertness and balance.
  • A diagonal direction suggests movement and action.
The dominant direction of a composition will be established by the direction of the majority of elements or perhaps a few key elements. The direction will help set a general mood according to the general meaning ascribed to different types of lines.
It is possible for a composition to have no dominant direction. The number of horizontal and number of vertical elements might be equal, for example. In this case, the viewer could decide which direction is dominant.

Examples

For the following examples, I’ve grabbed some screenshots of pages and will share some thoughts on how I see visual weight distributed in each. You might see it differently, and that’s OK.
Different eyes are attracted to different things. Again, I’m aware of no way to measure how much visual weight an element carries. Besides, two people could easily look to different areas of a composition because of their different interests. A bit of subjectivity is to be expected.
An easy way to tell which elements have the most weight is to use the squint test. Close your eyes a little until some elements fade away. Those that remain have more visual weight than those that disappear.

Bureau

Note: The screenshot for Bureau was captured with my browser set wider than 1280 pixels. Anything less and the design would collapse to a single column, instead of the two seen here.

Links gain some weight through their contrast with the surrounding text, although the cool color lessens the gain in my opinion.
The element with the least visual weight is the text in the right column. This makes sense because focus is most likely meant to be given to the article and not what’s in the sidebar.
Notice the small bit of red text at the top of the right column. It’s a link to the home page of the website. As small as it is, the red gives the text some additional weight, helping it to stand out from the other text in the column. Everything in the image appears larger when you’re viewing the website directly, so the small red text isn’t quite as small as it is here.
When you apply the squint test, the whole right column disappears, and you’re left with the main heading above the article and a large block of text below it.
The main direction of the composition is vertical because it’s two long columns down the page. The difference in background color between the columns creates a vertical line leading you down the page and adding to the vertical direction of the composition.

Create Digital Media

When the home page for Create Digital Media loads, the colorful elements animate into place, calling a lot of attention to themselves. Even if you miss the animation, you likely see these elements as carrying the most weight, due to the saturated pink, yellow and blue. These elements also occupy the same space, creating a dense area in the middle of empty space.
Note: Between the writing and publication of this post, Create Digital Media has closed its doors. Visit its home page if you’d like to know why.
The graphics at the bottom are the next weightiest for me. They’re dark, large and complex in shape. They pull you to each of the three sections, which contain the next most visually prominent elements, the section headings.
The main headline on the page is large and dark; compare it to the text directly below it. Other items that stand out for me, due to their higher visual weight, are the company’s name at the top and the logo at the bottom.
With the squint test, the colored shapes and text and the graphics at the bottom remain after most of the elements have faded away. The main headline fades for me, although I can still tell it’s there. I also somewhat notice the logo in the lower-left corner, although it fades much more quickly than the graphic near it.
Here, I think the main direction is horizontal. The lines run horizontally, as does the main heading and the navigation. Another of the more visually prominent elements, the highlighted text, is also horizontal.
The three gears could be regarded as a single triangular, albeit curvy, shape, thus establishing diagonal directions. They don’t run long, though, and they’re the only diagonals on the page.

Javier Marta

Three elements compete to be the visually weightiest on Javier Marta’s home page. The graphics, the green separators between sections, and the menu items at the top all call for attention.
  • Graphics
    These are large, dark and surrounded by white space. Each graphic intrinsically hold its own interest.
  • Green separators
    These have color, are larger and, like the graphics, are surrounded by white space
  • Menu items
    These are dark, large and, once again, surrounded by white space.
Javier’s logo carries a little less visual weight for me than the menu items around it, although it’s still very prominent among them. It does carry more weight than the text, but not as much as the menu items in my mind. You may disagree.
The squint test causes the menu items and logo to blend into a single unit. The graphics and separators are still visually prominent, and the text remains visible as large blocks. You can still see everything while squinting, even if you can’t make out what any of it says.
On my screen, only the header and the “El evento” section are visible, giving the page a horizontal direction. However, four sections in total are on the page. When the sections are viewed all at once, the alignment of the green separators gives the composition a vertical direction. And, of course, seeing the whole page at once changes the canvas from horizontal to vertical.
I wonder if the two graphics shown in the screenshot above would have been better on opposite sides. In the top graphic, the camera points right, which is where my eye follows. Better would be to guide the eye to the text.
In the bottom graphic, the woman’s umbrella does point right, but she’s walking left, which is where I then tend to look. Both graphics might work better if their direction led back into the text instead of away from it.

Stanford Arts

The image at the top of Stanford Arts’ home page carries the most visual weight. It’s the largest element on the page and, being an image, has a lot of intrinsic interest. It’s also located at the top of the composition. In truth, it takes up most of my screen.
Note: This website rotates images at the top of the page, and the images that rotate change over time. You probably won’t see this particular image if you visit the website and, because of that, you might assess the visual weights in the design differently than I do here.
I think the triangular images against the angular containers are the next weightiest elements. After that are the large red blocks that make up the header and footer.
When I perform the squint test, all of the elements are visible longer than I’d expect. The elements have a good deal of both light and dark contrast, which helps them stand out.
Eventually, the only things that remain are the images, although in less than full detail. I can make out the large image at the top but only the shapes of the triangular images below.
The design is also interesting for its visual direction. Diagonals dominate, and because most web pages are not dominated by diagonal directions, they capture more attention here. They subvert your expectation.
The particular photograph that I captured in the screenshot above also offers something of a diagonal, albeit a bit curved in parts and created by a moving line of people in others.
Both the woman (in the rightmost triangular image) and the photographer (in the center triangle) have a direction leading to the right. Better might have been to reverse the woman to face inward and move the camera to the left block to points inward, too.
Granted, the images change when you hover over any of the links in the blocks. Still, the images tend to lead outward instead of inward.

Summary

The visual weight of an element is a measure of how much the element attracts the eye of the viewer. A visually heavy element will attract the eye to it.
Visual direction is the perceived direction of forces acting on and exerted by elements. The direction is a cue to the viewer’s eye to move elsewhere.
Many intrinsic characteristics can be modified to make an element visually weightier or lighter. A few can be used to establish an element’s visual direction, as can the canvas itself.
Over the remaining posts in this series, we’ll see how visual weight and visual direction lead to principles like dominance and hierarchy, flow and rhythm and, ultimately, compositional balance.

Tuesday, December 2, 2014

Understanding Mobile Back End As A Service

What if you could create an entire back end for your mobile applications that was feature-complete in data synchronization, push-notification support, user management and file-handling before you even started building the mobile experience? What if it was architected in such a way that you could easily create new cross-platform native and web applications seamlessly on this back end?
While this might sound like a fairy tale, it is exactly what providers of mobile back end as a service (MBaaS) are aiming to give app developers. It is up to you to determine whether that is true for the experiences you are creating.
Through this article, I hope you gain four key pieces of information: the way MBaaS providers fit into modern mobile application development, the process of evaluating MBaaS providers, the core functionality provided by MBaaS providers and the downsides of leveraging this type of solution. With this information, you will have the pieces to determine whether an MBaaS provider fits in your digital strategy.

Framing The Discussion

Normalizing the discussion around MBaaS is extremely challenging. While MBaaS is an accepted term, everyone defines it differently. Kinvey recently mapped providers of back-end-as-a-service enterprise solutions. This map illustrates an extensive ecosystem, and defining different solution groups can be extremely challenging.
With the landscape changing by the minute, nailing down all of the players at any given point in time is hard. However, some key providers have proven themselves in the marketplace. Providers such as Parse, Kinvey and Salesforce.com have built mature platforms that are currently relied on by many of the applications you use daily. Other more nascent solutions, such as Amazon Web Services’ (AWS) Cognito, Microsoft Azure’s Mobile Services, Apple’s CloudKit, Kony MobileFabric and Pivotal CF still need time to be evaluated. Another key challenge in comparing MBaaS providers is that not all providers have feature parity.
Note: For this article, I will spend my time focusing on Parse and Kinvey because of their maturity and breadth of functionality. These two solutions could work for most uses cases, from an independent developer’s app to an enterprise solution across multiple digital properties.

MBaaS In Real Life

To help explain the purpose of MBaaS, I’ll use an example that we recently created out of our research and development group at Universal Mind. All of our offices at Universal Mind have flexible work spaces. We wanted to examine how to track available work spaces using iBeacons.
iBeacons are a class of sensors that follow Apple’s iBeacon specification. They utilize Bluetooth 4 low energy for communication, which allows an application to continually search for them without draining the user’s battery. They are ideal sensors for determining a user’s proximity (how close the user is to an object), which in certain settings (such as indoors) is more desirable than using GPS.
As a proof of concept, we wanted to create a quick cross-platform application prototype that illustrates how this idea could be leveraged on a large scale. The app itself was fairly basic. Here is a simplistic outline of the data relationships that describe how the application would function:
  • Users have accounts.
  • A user can be assigned to a work space if they are close enough to the iBeacon that is at a given station.
  • The work space can be occupied or vacant.
  • A work space exists at an office that has a specific location.
  • A user can get a list of vacant work spaces near them at that point.
In this application example, I’ll walk you through two different scenarios. First, we’ll see how we would have built this without an MBaaS solution. Then, I’ll contrast that with how we actually built it using an MBaaS solution. Through this, you will clearly see that the level of effort required to get something working is drastically different.

Without MBaaS

To create this cross-platform application, we need to put some core components in place:
  • Server
    I could probably fire up an AWS Elastic Compute Cloud (EC2) instance and run a Node.js server. I could even leverage Elastic Beanstalk or OpsWorks to handle some of the common deployment processes.
  • Database
    Because I am looking at AWS, I could leverage the Relational Database Service (RDS) or DynamoDB for the data store. There is also the option to deploy another solution on AWS, such as MongoLab.
  • Services
    I could create the entire integration with the database and then expose REST-based services to make it easy to perform CRUD operations on the data.
  • User management and security
    I need to include a user entity as part of the data, and then tie permissions within the services to data that a particular user and/or group owns. In addition, I need to give users the ability to sign up, reset their password, delete their account and so on.
  • Push notifications
    Within this Node.js application deployed on an EC2 server, I would need to integrate one of a handful of modules that allow for cross-platform notifications for both iOS and Android. While most of the heavy lifting would happen within these open-source modules, I would still need to integrate the application logic with the notifications.
  • iOS service integration
    Because iOS is a target operating system, I would need to integrate with this server on iOS in either Swift or Objective-C. In addition, I would need to determine how to handle service caching, data storage, offline handling, push-notification handling, etc.
  • Android service integration
    Because Android is a completely different platform, I would need to create the same server integration on that platform as well. I would need to handle all of the same concerns that I tackled on iOS as well.
With these items in place, I could begin actually building the views of the application and connecting them with the data. I could also begin handling iBeacon integrations and setting a workstation as “occupied” based on the user’s proximity. However, getting to that point and getting the infrastructure in place would take me a good deal of time and configuration. This is where the benefit of MBaaS is realized.

With MBaaS

The beauty here is that the biggest items are taken care of for me: I never have to deal with configuring the server, setting up and configuring the database, setting up the service, managing users, securing data, setting up push notifications or integrating native services. All of that is provided as a part of MBaaS. My steps now look a bit different:
  1. Create an app with the MBaaS provider.
  2. Include the native SDK in each application.
With these items in place, I can tackle the two main service interactions with minimal code: fetching nearby work spaces and changing the state of a work space from vacant to occupied (and vice versa). Below, I have detailed some sample iOS Objective-C code with these samples, using Parse as the MBaaS provider:
// In header file or class extension
@property (nonatomic,strong) NSArray *workstations;

// Within the implementation
/*
  After the view loads, we can asynchronously grab the user's location
  and then use that to query for a list of nearby workstations.
*/
- (void)viewDidLoad
{
  [super viewDidLoad];
  // Get the user's location as a Parse PFGeoPoint
  [PFGeoPoint geoPointForCurrentLocationInBackground:^(PFGeoPoint *geoPoint, NSError *error) {
    if (!error) {
      [self fetchWorkstationsNearPoint:geoPoint];
    }
  }];
}

/*
  This method asychronously fetches an array of the workstations
  that are within two miles of the user's current location.
*/
- (void)fetchWorkstationsNearPoint:(PFGeoPoint *)geoPoint
{
  PFQuery *query = [PFQuery queryWithClassName:@"Workstations"];
  [query whereKey:@"location" nearGeoPoint:userLocation withinMiles:2];
  [query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
    if (!error)
    {
      self.workstations = objects;
    }
  }];
}

In the code above, I’ve tackled the first challenge: fetching the data for workstations within two miles of the user’s current location. This starts with a call to grab the user’s current location after the application has finished loading. Parse provides a helper that gets this data, so that we don’t have to rely on CLLocationManager directly. Next, the fetchWorkstationsNearPoint method is called, which asynchronously queries Parse’ data store. Behind the scenes, the SDK is making REST calls to grab the data from Parse’s data store.
/*
  This method fetches a workstation data object given the iBeacon
  identifier. Then, it sets the occupied property and saves the
  object asynchronously.
*/
- (void)setWorkstationState:(BOOL)isOccupied
withBeaconIdentifier:(NSString *)beacon
completionHandler:^(NSError *error)completion
{
  PFQuery *query = [PFQuery queryWithClassName:@"Workstations"];
  [query whereKey:@"beaconIdentifier" equalTo:beaconIdentifier];
    [query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
    if (!error)
    {
      POWorkstation *workstation = [objects firstObject];
      workstation[@"occupied"] = [NSNumber numberWithBool:isOccupied];
      [workstation saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
        completion(error);
      }];
    }
  }];
}
In the code above, I’ve tackled the second challenge: setting the occupied state for a given workstation. This code is as terse as the first snippet. While you don’t see the iBeacon code that triggers this interaction, I wanted to capture all of the interactions with Parse. First, the specific workstation is fetched based on a beacon identifier. This string value is a property of the workstations in the data store. Next, I set the occupied property of the object and then save that value back to the data store in the background.
Very little code is needed to accomplish these tasks because a majority of the logic is happening within Parse’s iOS SDK. This handles things such as the service delegates, data translation and cached data storage, greatly reducing the code that a developer would have to write and maintain over time. While this isn’t a panacea, it provides a solid solution for the most common mobile use cases.

The Core Premise

Through this example, you can see that the core promise of MBaaS is that it solves the difficult challenge of supporting your mobile back end one time in such a way that it can be leveraged consistently across multiple projects. Instead of firing up a cloud-based database, push-notification server and user-management system, which you would have to manage, you can leverage an MBaaS vendor, which will provide all of this out of the box. In addition, you no longer have to be responsible for uptime and scalability of the back end, instead relying on the vendor for that.
While MBaaS certainly has its skeptics (which I will address later in this article), the focus on MBaaS over the last year has been undeniable. Early MBaaS provider Parse was acquired by Facebook; since then, Apple, Microsoft, Amazon and Google have emerged with their own cloud platforms. In addition, existing providers have thrived and are seeing a sharp uptake in adoption as their platforms have matured.

Distinguishing Between The Options

No two MBaaS solutions are the same, so knowing how to compare them is crucial. The key differences between providers lie in three areas: platform support, deployment methodology and feature focus.

Cross-Platform Support

A core benefit of MBaaS is the ability to support an application across multiple platforms. Some solutions, such as iCloud and CloudKit, do a great job of providing a deeply integrated data store (one component of MBaaS) on a single platform. While this works well for a single platform, it greatly limits the ability of an application to become cross-platform at a future time. However, if an application will only ever be on a single platform, this could be a good solution.
Some providers focus on native mobile platforms, while others support mobile web experiences and even desktop applications. At their core, most MBaaS experiences provide REST services, which allow for use on most any platform, but the technology-specific SDKs are a key benefit to developers. Picking an MBaaS provider that provides an SDK for all of the platforms you would like to support would be ideal.
  • Parse currently provides SDKs for iOS, Android, Windows Phone 8, Windows 8, PHP, JavaScript, Mac OS X and Unity.
  • Kinvey currently provides SDKs for iOS, Android, JavaScript, AngularJS, Backbone.js, Ember.js, Node.js, PhoneGap and Titanium.

Deployment Methodology

In addition to cross-platform support, MBaaS solutions differentiate according to how they are deployed. Determining which options make sense for an organization will depend on several factors, including existing infrastructure, regulations on data storage (for sensitive data) and cost threshold.
Here are the most popular deployment methods for MBaaS solutions:
  • managed, multi-tenant
    With a managed multi-tenant MBaaS solution, you don’t have to worry about deploying the environment on your infrastructure. In most cases, the provider will leverage an existing cloud provider, such as AWS, to deploy your application to a scalable environment. In this environment, your back end will run on servers alongside other applications for other users of the platform.
  • managed, dedicated
    With a managed dedicated solution, the provider will still leverage a public cloud, such as AWS, but you will ensure that the MBaaS environment is deployed to servers that are dedicated for your use.
  • managed, on-premise
    With an on-premise solution, the provider will deploy the MBaaS environment onto servers that you own. In most cases, this requires that you use a specific virtualization platform, such as VMware vCloud Air. For some organizations that deal with sensitive regulated data, this might be a requirement. In most cases, the provider will work together with an organization’s internal IT team to manage the platform.
  • open source
    With open-source MBaaS solutions (such as OpenKit and Helios), you will deploy and manage the solution yourself on any infrastructure you choose. This could be an on-premise or cloud-based solution. However, you will have to maintain and update the system yourself. While these solutions give you total control, they also negate many of the benefits of an MBaaS solution.
For most small organizations, the managed multi-tenant options will work perfectly. Larger enterprises could be facing privacy concerns, state and federal regulations and corporate mandates that dictate one solution over another. For example, financial organizations generally have tight restrictions on where account data may be stored. In such cases, a managed on-premise solution might be the only possibility.
Parse currently offers a managed multi-tenant option. Kinvey currently offers managed multi-tenant, managed dedicated and managed on-premise options.

Feature Focus

Most every MBaaS solution has an area of focus. Some primarily target independent app developers, while other providers focus on the enterprise. Knowing where your effort lies will also help you determine which MBaaS solution is worth the investment of your time and money.
One good example of this is the focus that Kinvey has placed on the enterprise. Kinvey provides a data-connector specification that allows enterprises to hook outside data sources into the existing MBaaS data store, as well as an AuthLink to integrate with enterprise authentication and authorization. These features are fairly insignificant for most independent app developers, but they are absolutely essential for enterprises looking to integrate an MBaaS solution into their existing systems.
Parse has a different focus. It hasn’t focused as much on the enterprise since its acquisition by Facebook, but due to its integration by Facebook, it now provides a good deal of integration with the social juggernaut. Parse’s SDK now provide several utilities specifically geared to making it easier to access particular pieces of Facebook data.

Core MBaaS Functionality

Most core services offered through MBaaS solutions address the core needs of a mobile application. The main MBaaS providers share four key functions: user management, synchronized data with security, push notifications and file handling. Understanding these key areas of functionality will help you understand how a MBaaS provider could be a part of your digital strategy.

User Management

Most providers offer user management as a core feature. With this feature, you can give each user an account to which you can attach meta data. Some services take this a step further by allowing you to easily integrate email verification, password resetting, social login and support for anonymous users. This is a central facet of MBaaS functionality because it ties directly to the entire platform’s security.
For enterprise-focused MBaaS, this solution goes a step further. Vendors such as Kinvey offer integration with existing LDAP providers and even enable users to authenticate with Salesforce.com credentials. The key here is that very few enterprise customers want to reinvent user management and rather just want to integrate with existing solutions. Some enterprise-level MBaaS vendors fit this need nicely.

Synchronized Data With Security

In today’s digital landscape, a user will rarely interact with only one device or even one platform. While a solution such as iCloud enables developers to persist data for users with multiple devices on the same platform, it does nothing to address situations in which a user needs to access the same data from a website as they do from a mobile application. Synchronized cross-platform data is essential for any application that aims to expose itself to users in all areas of their lives. Because of this, synchronized data is the center of most every MBaaS solution.

Push Notifications

Real-time push notifications are an essential element of many mobile applications. However, integrating with Apple Push Notification service (APNs) or Google Cloud Messaging often requires a dedicated server application. Many organizations have set up their own cross-platform notification server to manage these interactions.
Both Parse and Kinvey provide a basic level of push-notification integration for both Android and iOS.

File Storage and Delivery

From the uploading of user-generated content to the global delivery of remote application content, applications need to interact with files. Many applications work with existing services such as Amazon CloudFront to leverage a global content delivery network (CDN) for their remote content. Most MBaaS providers offer an abstraction of CDN solutions to enable application developers to work a network of edge servers in order to ensure that their content is delivered in a consistent and performant manner worldwide.

Additional Features

After this core set of functionality, MBaaS providers branch off into many different feature sets. For example, Kinvey has iBeacon integration, while Parse has third-party integration for functionality such as sending SMS messages. If you are looking to leverage particular functionality, finding a platform that fits the road map of your application is crucial. Evaluating solutions side by side here becomes difficult because the available options do not have full feature parity.

Downsides And Skeptics

While this functionality might seem like a dream for organizations that are looking to reduce the overall time to market for their apps and provide back-end consistency across their digital properties, consider a few things:
  • In most cases, MBaaS solutions are designed to provide a very low barrier to entry in regards to cost. However, as app usage grows, there is usually a fairly steep slope in the cost curve as well.
  • Because MBaaS solutions do not all correspond to a standard specification and because mass data migration is not always simple, applications are locked into the MBaaS solution that is initially chosen. This isn’t to say that it can’t be changed, but the cost and effort to do so is extensive in many cases.
  • MBaaS providers are hot commodities. You need look no further than Facebook’s aquisition of Parse to see that an MBaaS provider can certainly get acquired. Thoroughly review the terms of every MBaaS provider you are considering to understand how this could affect your application.
Nevertheless, the advantages in many cases outweigh the downsides. Because of the downsides, investigate potential MBaaS solutions extensively before incorporating one in the development plan for your application.
MBaaS certainly has its share of skeptics. I counted myself among that group in the early days of MBaaS. The main question among skeptics is, How can a single solution provide the flexibility needed for every application? The truth is that no solution has the flexiblity to meet every need. It is up to an experience’s owner to choose the solution that most closely maps to the functionality desired alongside the platforms that will be used to present the experience. In some cases, no match will be found and a custom back end would be the best approach.
In the particular use case that I mentioned earlier, this approach has probably saved me a few weeks of development. In addition, it has saved me from having to monitor and administer server instances as part of the overall solution. For me, the benefit was a reduced time to market for this prototype. However, as we’ll discuss in the next section, this isn’t the only benefit.

MBaaS And Digital Standards

I am a big fan of establishing digital standards within an organization (no matter the size of the organization). Digital standards do require foresight, but when done properly they yield a great degree of efficiency and consistency across an organization’s digital properties. Most organizations, however, focus on user interface standards only. In many cases, an organization using MBaaS across multiple digital projects could lead to a similar standardization of back-end interaction as well.
Adopting MBaaS across a single project obviously holds some benefit for organizations, but the shared learning and consistency derived from using it across multiple projects is where the most value lies.

Who Should Consider This Approach

MBaaS holds value for organizations of almost any size, but the advantages are different:
  • enterprise
    For a large organization, an enterprise-level solution (such as Kinvey) will set back-end standards for how the organization’s mobile applications perform common tasks. In addition, it standardizes how mobile applications access data outside of the MBaaS cloud (with solutions like Kinvey’s data connectors).
  • small and medium-sized organizations
    For small organizations, MBaaS provides a completely unmanaged scalable infrastructure. Organizations can deploy experiences without needing a dedicated team to monitor the infrastructure 24/7. In addition, it can greatly reduce both the time to market and the amount of code to be maintained over time.
Many companies today are taking advantage of this approach. Cadillac, The Travel Channel and The Food Network are just a few of the companies leveraging MBaaS. Experiences like GovTribe, Hipmunk and Timbre are all powered by MBaaS providers.
Both Parse and Kinvey provide several case studies that will help you evaluate successful experiences.

Final Thoughts And Next Steps

In my next article, I’ll walk you through the creation of a cross-platform MBaaS application. The article will highlight key areas where efficiencies are gained by leveraging an MBaaS provider instead of developing a custom solution.
If you are ready to jump into MBaaS now, then your next step is to check out some of the samples from the providers and examine the functionality and pricing of each platform. The following resources will assist you in your effort to determine the best solution for your experience.

Kinvey Resources

Parse Resources

Monday, December 1, 2014

Chartist.js, An Open-Source Library For Responsive Charts

The list of charting libraries for the web is already quite long, and you might ask yourself why we would need to make it any longer. Whenever you need to develop an application’s dashboard, embed some usage statistics or simply visualize some data, you will find yourself looking for a charting library that fits your needs.
Chartist was developed for a very particular need: to create simple responsive charts. While other charting libraries do a great job of visualizing data, something is always missing to satisfy this simple yet demanding need.
In this article, we’ll show you how to use Chartist to create your own beautiful responsive charts. You’ll learn some key concepts of Chartist, how to easily extend it and also some advanced features, like responsive configuration overrides and the animation API.

Your Individual Setup

You can integrate the Chartist library in your project in many ways. It’s available from Bower and NPM but also directly from a content delivery network (CDN). It’s also exposed as a CommonJS module, as an AMD module or just in the global window object. You can decide on the best way to integrate the library according to your project’s setup.
Chartist currently uses a Universal Module Definition wrapper, to satisfy a broad range of use cases. Instead of using Chartist directly from the Chartist namespace in the window object, you could use module loaders, like RequireJS, or bundle your charts into your application with Browserify or webpack.

Bower

To install Chartist as a front-end dependency using Bower, simply execute the following command in your project’s folder:
bower install chartist --save

NPM

If you prefer NPM as a repository or if you’re using a CommonJS browser bundler like Browserify or webpack, then you’ll want to install Chartist using NPM:
npm install chartist --save

CDN

Another quick way to get started with Chartist is to use a CDN. The folks at jsDelivr do a fantastic job of keeping a huge number of libraries up to date with their custom load balancing, and they do it all for free. To use Chartist’s resources from a CDN, include the following in your HTML:
<script src="//cdn.jsdelivr.net/chartist.js/latest/chartist.min.js"></script>
<link href="//cdn.jsdelivr.net/chartist.js/latest/chartist.min.css" rel="stylesheet" type="text/css" />

Create Your First Chart

Once you have chosen the method that fits your needs, you can start crafting your first chart. Over the course of this article, we’ll use JSBin to create our charts. JSBin is a great collaborative web development debugging tool, and Chartist is available directly in the “Add library” menu. If you’d like to try out Chartist quickly, I’d recommend using JSBin.
Let’s start with a simple line chart. For this, we’ll first add a container element to our body with the class ct-chart.
Simple line chart with three series
Simple line chart with three series
<!DOCTYPE html>
<html>
<head>
  <script src="//cdn.jsdelivr.net/chartist.js/latest/chartist.min.js"></script>
  <link href="//cdn.jsdelivr.net/chartist.js/latest/chartist.min.css" rel="stylesheet" type="text/css" />
  <meta charset="utf-8">
  <title>Chartist | Simple line chart</title>
</head>
<body>
  <div class="ct-chart"></div>
</body>
</html>
Now we can initialize a line chart on the container with only a few lines of JavaScript. Let’s create three series, with five values each. We’ll also set a list of labels for the x-axis. As a second argument, the Chartist.Line constructor accepts an options object. Here, we can specify a fixed width and height for our chart.
new Chartist.Line('.ct-chart', {
  labels: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri'],
  series: [
    [2, 3, 2, 4, 5],
    [0, 2.5, 3, 2, 3],
    [1, 2, 2.5, 3.5, 4]
  ]
}, {
  width: 320,
  height: 240
});

Responsive Containers With Intrinsic Ratios

In the example above, we used a fixed width and height for the chart. This is not always desired, and in responsive design we should keep our elements fluid and not think in fixed dimensions.
Chartist uses its own classes to set containers with fixed aspect ratios (intrinsic ratios). Usually, this is a technique applied to responsive videos and iframes, and it uses the intrinsic ratio CSS trick to establish a fixed ratio container. With the implementation in Chartist, you can even set the width of a container while preserving the aspect ratio.
Let’s use one of the generated responsive container classes in Chartist to size our chart. I’ve picked ct-golden-section, but you can choose any from the list of generated container classes. When using the Sass version of Chartist, you can also generate your own fixed-aspect-ratio containers easily.
<body>
  <div class="ct-chart ct-golden-section"></div>
</body>
Because we are now specifying a container with a fixed aspect ratio on our chart, we no longer need to rely on fixed dimensions when initializing our chart. Let’s remove the width and height in our configuration.
new Chartist.Line('.ct-chart', {
  labels: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri'],
  series: [
    [2, 3, 2, 4, 5],
    [0, 2.5, 3, 2, 3],
    [1, 2, 2.5, 3.5, 4]
  ]
});
Now we have a chart that responds to changes in media. Try resizing the output panel on JSBin to see how the chart adapts to changes in window size.

Advanced Configuration

One of Chartist’s core principles is a clean separation of concerns via standard web technologies. This includes applying all appearance-related settings with CSS. Also, a number of settings allow you to control the behavior of your chart. These settings are applied using JavaScript and can be passed to your chart during initialization.
Let’s create a simple bar chart that visualizes some data for weekdays.

A simple bar chart with two series
new Chartist.Bar('.ct-chart', {
  labels: ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday'],
  series: [
    [2, 8, 2, 4, 5, 8, 10],
    [4, 5, 8, 2, 6, 3, 10]
  ]
}, {
  seriesBarDistance: 30,
  axisX: {
    showGrid: false
  }
});

In the options, we can control the distance of the bars and tell Chartist not to render the grid on the x-axis. For a complete list of options, you can always visit Chartist’s API documentation.
By default, the labels on the x-axis are left-aligned. To make them center-aligned, we need to add a CSS style. We also want to change the bar’s width to 20 pixels.
.ct-chart .ct-bar {
  stroke-width: 20px;
}
.ct-chart .ct-label.ct-horizontal {
  text-align: center;
}

Already, we’ve got a nice-looking bar chart for large screens.

Responsive Configuration Override

The example above works nicely on desktop screens, but not on devices with tight screen resolutions. The bars are too wide, the labels too large and the names of the weekdays are written in full. Also, the distance of the bars needs to be adjusted.
Some of these changes can be done in CSS by modifying the bar’s width in a media query. But how do we go about applying different configurations in JavaScript? Chartist provides a mechanism for this purpose called responsive configuration override.
Let’s look at the previous example and rewrite it with a mobile-first approach. We’ll optimize our media queries for the content we’re working with, introducing a breakpoint at 300 pixels and another at 600 pixels.
.ct-chart .ct-label.ct-horizontal {
  text-align: center;
}
.ct-chart .ct-bar {
  stroke-width: 5px;
}
@media screen and (min-width: 300px) {
  .ct-chart .ct-bar {
    stroke-width: 10px;
  }
}
@media screen and (min-width: 600px) {
  .ct-chart .ct-bar {
    stroke-width: 20px;
  }
}
If we’d like to tailor our chart to a particular medium, we can use the responsive configuration overrides. We simply tell Chartist to inherit and override our configuration based on the same media queries in our CSS. Chartist uses window.matchMedia to implement an inheritance in our settings similar to what CSS does with our styles.

The following example uses labelInterpolationFnc to pass a function that enables us to interpolate or even replace the label’s original value for the given axis. This means we can control how the weekdays’ names are displayed on the x-axis.
new Chartist.Bar('.ct-chart', {
  labels: ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday'],
  series: [
    [2, 8, 2, 4, 5, 8, 10],
    [4, 5, 8, 2, 6, 3, 10]
  ]
}, {
  seriesBarDistance: 6,
  axisX: {
    showGrid: false,
    // Only return first letter of weekday names
    labelInterpolationFnc: function(value) {
      return value[0];
    }
  }
}, [
  // Over 300px, we change the bar distance and show the first three letters of the weekdays
  ['screen and (min-width: 300px)', {
    seriesBarDistance: 15,
    axisX: {
      labelInterpolationFnc: function(value) {
        return value.slice(0, 3);
      }
    }
  }],
  // Over 600px, we increase the bar distance one more time and show the full weekdays
  ['screen and (min-width: 600px)', {
    seriesBarDistance: 30,
    axisX: {
      labelInterpolationFnc: function(value) { return value; }
    }
  }]
]);
Edit on JSBin
In the example above, you can see how easy it is to create a chart that works on both mobile and desktop, while maintaining a clean separation of concerns.

Styling SVG With CSS

Styling inline SVG with CSS is easy and efficient because you’re able to reuse styles for different charts. You can include CSS classes that define the look and feel of your charts and that keep the logic separated from the appearance.
Here are some of the most useful CSS properties for styling inline SVG:
  • fill
    Sets the color of a shape’s fill. You may use RGBa.
  • stroke
    Sets the color of the outline around your shape.
  • stroke-width
    Sets the width of an outline.
  • stroke-dasharray
    Specifies a dashed stroke for an outline.
  • stroke-linecap
    Sets the line-cap stroke for the outline of a shape. This can be set to round, butt or square.
Check the SVG 1.1 specification for a complete list of SVG styling properties.
Let’s apply our new styling skills and create a line chart with three different looking series. We’ll use all of the above styling properties to give our chart a unique look.
.ct-chart .ct-label.ct-vertical,
.ct-chart .ct-label.ct-horizontal {
  color: rgba(255, 255, 255, 0.5);
}
.ct-chart .ct-grid.ct-vertical,
.ct-chart .ct-grid.ct-horizontal {
  stroke: rgba(255, 255, 255, 0.1);
  shape-rendering: crispEdges;
}
.ct-chart .ct-series.ct-series-a .ct-line {
  stroke: #4ECDC4;
  stroke-width: 10px;
  stroke-linecap: round;
}
.ct-chart .ct-series.ct-series-b .ct-line {
  stroke: #C7F464;
  stroke-width: 2px;
  stroke-dasharray: 5px 2px;
}
.ct-chart .ct-series.ct-series-c .ct-line {
  stroke: #FF6B6B;
  stroke-width: 3px;
  stroke-linecap: round;
  stroke-dasharray: 30px 5px;
}
Edit on JSBin
If you play around with this example a bit, you’ll quickly see how easy it is to style SVG with CSS. Also, you might have noticed the shape-rendering: crispEdges style on the grid lines. While I haven’t included the shape-rendering property in the list of useful styling properties, you’ll find it quite handy in some situations. It allows you to give the browser some hints on how to render SVG. The values auto, optimizeSpeed, crispEdges and geometricPrecision are supported by the specification. Intended for performance control, this property is also handy for rendering certain shapes without anti-aliasing. In some charts, including the example above, making the grid lines look very crisp with the crispEdges value has a very nice effect.

CSS Animation Craziness

I’m a huge fan of animation… well, as long as it supports the content and conveys information to the user. It can mean the difference between a UX playing nicely and not. Google’s material design is a great example of functional animation design. However, for this article, we will not focus on functional animation, but instead go a bit crazy with the possibilities at our disposal. Browser support for animation of SVG properties is pretty stable now, and you can even animate the stroke-dasharray and stroke-dashoffset properties. Let’s enhance the previous example with some meaningful animation.
Simply by using some CSS3, we are able to create some crazy animations in our chart.
@keyframes width-pulse {
  0% {
    stroke-width: 6px
  }
  50% {
    stroke-width: 14px;
  }
  100% {
    stroke-width: 6px;
  }
}
@keyframes dashoffset-seven {
  0% {
    stroke-dashoffset: 7px;
  }
  100% {
    stroke-dashoffset: 0px;
  }
}
@keyframes dasharray-craziness {
  0% {
    stroke-dasharray: 7px 2px;
  }
  80% {
    stroke-dasharray: 7px 100px;
    stroke-width: 10px
  }
  100% {
    stroke-dasharray: 7px 2px;
  }
}
.ct-chart .ct-label.ct-vertical,
.ct-chart .ct-label.ct-horizontal {
  color: rgba(255, 255, 255, 0.5);
}
.ct-chart .ct-grid.ct-vertical,
.ct-chart .ct-grid.ct-horizontal {
  stroke: rgba(255, 255, 255, 0.1);
  stroke-dasharray: 2px;
  shape-rendering: crispEdges;
}
.ct-chart .ct-series.ct-series-a .ct-line {
  stroke: #4ECDC4;
  stroke-width: 10px;
  stroke-linecap: round;
  animation: width-pulse 2s infinite;
}
.ct-chart .ct-series.ct-series-b .ct-line {
  stroke: #C7F464;
  stroke-width: 2px;
  stroke-dasharray: 5px 2px;
  animation: dashoffset-seven 200ms infinite linear;
}
.ct-chart .ct-series.ct-series-c .ct-line {
  stroke: #FF6B6B;
  stroke-width: 3px;
  stroke-linecap: round;
  stroke-dasharray: 30px 5px;
  animation: dasharray-craziness 10s infinite linear;
}
Edit on JSBin
As you can see, styling and animating SVG using CSS is a lot of fun. If you’d like more information, I recommend the article by Sara Soueidan “Styling and Animating SVGs With CSS.”

Animating With SMIL

CSS animation is a great way to inject some life into a chart. There are some things you can’t animate with CSS, though. If you want to animate individual parameters of an SVG element to morph a shape, then you would use the Chartist.Svg APIs to conveniently create SMIL animations.
SMIL is powerful, but the declarative API, which uses <animate> elements, can be confusing in its complexity. Chartist offers a high-level API that enables you to easily take advantage of SMIL animations in your charts.
The goal of Chartist is to simplify the handling of SMIL while preserving the semantics specified by the W3C. Chartist uses its own SVG manipulation library, which is accessible through Chartist.Svg. Similar to jQuery, it provides a wrapper object around real SVG DOM nodes, giving you some convenient methods to manipulate the underlying SVG. You can get a complete overview by browsing the Chartist.Svg API documentation.
To animate an SVG element, you first need to obtain a wrapper object by passing an SVG node to the Chartist.Svg constructor.
var element = new Chartist.Svg(document.querySelector('#my-specific-svg-element'));
You can then call the animate function on your wrapped element with an animation definition object:
element.animate({
  opacity: {
    dur: 1000,
    from: 0,
    to: 1
  },
  x1: {
    dur: '1000ms',
    from: 100,
    to: 200,
    easing: 'easeOutQuart'
  },
  y1: {
    begin: 1000,
    dur: '2s',
    from: 0,
    to: 100
  }
});
This will create three SMIL <animate> elements, each of which contains the SMIL animation attributes specified in the definition objects. The Chartist animation API has a few particularities. The begin and dur (i.e. duration) properties may be specified as unitless numbers; Chartist will convert the numbers to milliseconds automatically. Chartist also supports an easing property in the animation definition object that is not directly supported by SMIL. The easing property allows you to specify an easing function from Chartist.Svg.Easing, which will be translated to a SMIL interpolation function.
Chartist handles SMIL animations in a special guided mode by default. The guided mode includes the following behavior, which makes handling and optimization easier for immediately triggered animations:
  • Before the animation starts (even when delayed with begin), the animated attribute will already be set to the from value of the animation.
  • begin is explicitly set to indefinite so that it can be started manually without relying on the document’s begin time (i.e. creation).
  • The animate element is forced to use fill="freeze".
  • The animation is triggered with beginElement() in a timeout, where the beginning of the definition object is interpreted in milliseconds. If no beginning is specified, then the timeout is triggered immediately.
  • After the animation, the element’s attribute value is set to the to value of the animation.
  • The animate element is then deleted from the DOM.
You can also disable guided mode by passing false as the second argument to the animate function.

Animating Chart Elements Using the Event API

Chartist provides a few events that you can use to intercept the creation process of charts. The draw events of Chartist get triggered each time a chart element is created in the DOM. Since we have the Chartist.Svg wrapper and all relevant data available in the event callback, this makes it a perfect spot to add our animations.

Example looks more like a confetti party than a chart, but it should illustrate how easy it is to create custom animations. The example makes use of the Chartist event API and adds animations to points in a line chart.
var seq = 0;

chart.on('created', function() {
  seq = 0;
});

chart.on('draw', function(data) {
  if(data.type === 'point') {
    seq++;

    data.element.animate({
      x1: {
        from: data.x - 50,
        to: data.x,
        begin: seq * 80,
        dur: 800,
        easing: Chartist.Svg.Easing.easeOutQuint
      },
      opacity: {
        from: 0,
        to: 1,
        begin: seq * 80,
        dur: 300,
      }
    });
  }
});

Extensibility

Because Chartist uses inline SVG in the DOM, extending the core functionality is very easy. While SVG elements in the DOM have the same events as regular DOM elements, you can easily use the DOM library of your choice and add custom functionality to your chart’s elements.

Example shows you how to add a simple tooltip to a chart using jQuery. When the user hovers over a data point, the tooltip should become visible and display the data value.
var $tooltip = $('<div class="tooltip tooltip-hidden"></div>').appendTo($('.ct-chart'));

$(document).on('mouseenter', '.ct-point', function() {
  var seriesName = $(this).closest('.ct-series').attr('ct:series-name'),
      value = $(this).attr('ct:value');

  $tooltip.text(seriesName + ': ' + value);
  $tooltip.removeClass('tooltip-hidden');
});

$(document).on('mouseleave', '.ct-point', function() {
  $tooltip.addClass('tooltip-hidden');
});

$(document).on('mousemove', '.ct-point', function(event) {
  $tooltip.css({
    left: event.offsetX - $tooltip.width() / 2,
    top: event.offsetY - $tooltip.height() - 20
  });
});
The example above uses regular DOM events to add a simple tooltip. You might have noticed the use of the ct:value attribute from the line chart’s point element and the ct:series-name attribute from the series group. Chartist has its own XML namespace, which it uses to expose some meta data to the SVG. This makes it easy to extract information from the DOM and use it for custom functionality.

Extending the Drawing Pipeline

The event system of Chartist is powerful and is a great tool to extend your chart with custom features.
var smashingImgTag = '<img src="http://media.mediatemple.netdna-cdn.com/wp-content/themes/smashing-magazine/images/smashing-windows-icon-70-70.png" style="width: 40px; height: 40px" alt="Smashing Logo" />';

chart.on('draw', function(data) {
  if(data.type === 'point') {
    var smashingFoob = data.element.parent().foreignObject(smashingImgTag, {
      width: 40,
      height: 40,
      x: data.x - 20,
      y: data.y - 20
    });

    data.element.replace(smashingFoob);
  }
});
In the example above, we’ve replaced each point element just after it has been drawn (inserted in the DOM tree) with a foreignObject that contains an image. A foreignObject allows you to embed HTML elements in an SVG. The Chartist.Svg API provides an easy and convenient way to create foreignObjects. For details on the Chartist.Svg API, visit the API documentation.

Resources

Contribute

 If you have some spare time and are interested in contributing, please grab an issue to work on or open a new one.