A graphical toolkit for visualization
Protovis
Overview
Examples
Documentation
Paper
Download
Index
« Previous / Next »

Sizing the Horizon

View full screen.

Horizon graphs are a space-saving refinement of area charts. They work by combining color and position encodings: data is sliced into layered bands that are drawn with different colors, reducing vertical space and increasing data density. All the charts on the left show the same data; the 2-band charts at the bottom require only 25% of space as an area chart of the same resolution.

For more on this type of visualization, read "Sizing the Horizon: The Effects of Chart Size and Layering on the Graphical Perception of Time Series Visualizations" by Heer et al., published in CHI 2009.

Next: Parallel Coordinates

Source

<html>
  <head>
    <title>Sizing the Horizon</title>
    <link type="text/css" rel="stylesheet" href="ex.css?3.1"/>
    <script type="text/javascript" src="../protovis-r3.1.0.js"></script>
    <script type="text/javascript" src="horizon.js"></script>
    <style type="text/css">
      #fig {
        width: 300px;
        height: 430px;
      }
      .label {
        font-size: 13px;
        padding-top: 2px;
        padding-bottom: 10px;
      }
    </style>
  </head>
  <body><div id="center"><div id="fig">

    <script type="text/javascript+protovis">
new pv.Panel()
    .width(300)
    .height(70)
  .add(pv.Area)
    .data(data)
    .fillStyle("rgba(0, 0, 255, .4)")
    .bottom(35)
    .height(function(d) d * 20)
    .left(function() this.index * 3)
  .root.render();
    </script>
    <div class="label">Filled line chart.</div>

    <script type="text/javascript+protovis">
new pv.Panel()
    .width(300)
    .height(70)
  .add(pv.Area)
    .data(data)
    .fillStyle("rgba(0, 0, 255, .4)")
    .bottom(35)
    .height(function(d) Math.max(0, d * 20))
    .left(function() this.index * 3)
  .add(pv.Area)
    .fillStyle("rgba(255, 0, 0, .4)")
    .height(function(d) Math.min(0, d * 20))
  .root.render();
    </script>
    <div class="label">Two-color filled line chart.</div>

    <script type="text/javascript+protovis">
new pv.Panel()
    .width(300)
    .height(35)
  .add(pv.Area)
    .data(data)
    .fillStyle("rgba(0, 0, 255, .4)")
    .bottom(0)
    .height(function(d) Math.max(0, d * 20))
    .left(function() this.index * 3)
  .add(pv.Area)
    .fillStyle("rgba(255, 0, 0, .4)")
    .height(function(d) -Math.min(0, d * 20))
  .root.render();
    </script>
    <div class="label">Mirrored chart.</div>

    <script type="text/javascript+protovis">
new pv.Panel()
    .width(300)
    .height(35)
  .add(pv.Area)
    .data(data)
    .fillStyle("rgba(0, 0, 255, .4)")
    .bottom(0)
    .height(function(d) Math.max(0, d * 20))
    .left(function() this.index * 3)
  .add(pv.Area)
    .fillStyle("rgba(255, 0, 0, .4)")
    .top(0)
    .height(function(d) -Math.min(0, d * 20))
  .root.render();
    </script>
    <div class="label">Offset chart.</div>

    <script type="text/javascript+protovis">
new pv.Panel()
    .width(300)
    .height(20)
  .add(pv.Area)
    .data(data)
    .fillStyle("rgba(0, 0, 255, .4)")
    .bottom(0)
    .height(function(d) Math.max(0, Math.min(20, d * 20)))
    .left(function() this.index * 3)
  .add(pv.Area)
    .height(function(d) Math.max(0, Math.min(20, d * 20 - 20)))
  .add(pv.Area)
    .fillStyle("rgba(255, 0, 0, .4)")
    .height(function(d) -Math.min(0, Math.max(-20, d * 20)))
  .add(pv.Area)
    .height(function(d) -Math.min(0, Math.max(-20, d * 20 + 20)))
  .root.render();
    </script>
    <div class="label">2-band mirrored chart.</div>

    <script type="text/javascript+protovis">
new pv.Panel()
    .width(300)
    .height(20)
  .add(pv.Area)
    .data(data)
    .fillStyle("rgba(0, 0, 255, .4)")
    .bottom(0)
    .height(function(d) Math.max(0, Math.min(20, d * 20)))
    .left(function() this.index * 3)
  .add(pv.Area)
    .height(function(d) Math.max(0, Math.min(20, d * 20 - 20)))
  .add(pv.Area)
    .fillStyle("rgba(255, 0, 0, .4)")
    .top(0)
    .height(function(d) -Math.min(0, Math.max(-20, d * 20)))
  .add(pv.Area)
    .height(function(d) -Math.min(0, Math.max(-20, d * 20 + 20)))
  .root.render();
    </script>
    <div class="label">2-band offset chart.</div>

  </div></div></body>
</html>

Data

var data = pv.range(101).map(function(d) {
    return Math.sin(d / 3) + Math.sin(d / 6);
  });
Copyright 2009 Stanford Visualization Group