Real-time
Epoch's real-time charts have been fine tuned for displaying frequently updating timeseries data. To make them performant (aka not crash the browser) we've implemented the charts using a hybrid approach of d3 SVG with custom HTML5 Canvas rendering.
Overview
Every real-time chart has a name prefixed with time.
and was built to use the same workflow, here's an overview:
- Create an HTML container.
- Epoch automagically sizes charts to fit their containers.
<div id="myChart" style="width: 200px; height: 200px"></div>
- Fetch and format your data.
- Each type of chart uses a specific (though often familiar) data format.
- See the documentation below for how each chart is expecting the data.
- Use the jQuery method
.epoch
to create, append, and draw the chart.var myChart = $('#myChart').epoch({ type: 'time.line', data: myData });
- When you have a new data point to append to the chart, use the
.push
method:myChart.push(nextDataPoint);
CSS Styling and Redrawing
Each real-time chart can be styled using CSS just like the basic charts. Epoch uses an internal CSS cache
to quickly retrieve the color, size, and position values for each of the canvas rendered elements. When
changing styles (via a class change, etc.) use the .redraw()
method to purge the cache and requery
the CSS styles.
Here is an example of how to dynamically switch styles via jQuery:
<div id="chart" class="styles1"></div>
<button id="toggle">Switch Styles</button>
<script>
var chart = $('#chart').epoch({
type: 'time.area',
data: []
});
// The button swtiches the chart's class from styles1 to styles2 and back
$('#toggle').click(function (e) {
// This switches the class names...
var className = $('#chart').attr('class');
var newClassName = className === 'styles1' ? 'styles2' : 'styles1';
$('#chart').removeClass(className).addClass(newClassName);
// And this is required to see the updated styles...
chart.redraw();
});
</script>
Device Pixel Ratio
Epoch supports high resolution displays by automatically detecting and setting the appropriate pixel ratio for the canvas based real-time charts. You can override this behavior by explicitly setting the pixel ratio for any chart described below. Here's an example of how to do this:
$('#my-chart').epoch({
type: 'time.line',
pixelRatio: 1
})
Note that the pixelRatio
option must be an integer >= 1.
Common Options
Unless otherwise stated, Epoch's real-time charts have the following common options:
Name | Description |
---|---|
axes |
Which axes to display. Example: axes: ['top', 'right', 'bottom', 'left'] |
ticks |
Number of ticks to display on each axis. Example: { time: 10, right: 5, left: 5 } |
tickFormats |
What formatting function to use when displaying tick labels. Example: tickFormats: { time: function(d) { return new Date(time*1000).toString(); } } |
fps |
Number of frames per second that transitions animations should use. For most people, frame rates in excess of 60fps imperceptible and can cause a big performance hit. The default value of 24 tends to work very well, but you can increase it to get smoother animations.Example: fps: 60 |
windowSize |
Number of entries to display in the graph. Example: windowSize: 60 |
historySize |
Maximum number of historical entries to track in the chart. Example: historySize: 240 |
queueSize |
Number of entries to keep in working memory while the chart is not animating transitions. Some browsers will not run animation intervals if a tab is inactive. This parameter allows you to bound the number of entries that have been recieved via the `.push` in this case (so as to reduce memory bloating). Example: queueSize: 120 |
margins |
Explicit margin overrides for the chart. Example: margins: { top: 50, right: 30, bottom: 100, left: 40 } |
width |
Override automatic width with an explicit pixel value. Example: width: 320 |
height |
Override automatic height with an explicit pixel value. Example: height: 240 |
pixelRatio |
Override detected pixel ratio with an explicit value. Example: pixelRatio: 1 |
Area
The real-time area chart works in a very similar way to the basic area chart detailed above. It is used to show relative sizes of multi-series data as it evolves over time.
var areaChartData = [
// The first layer
{
label: "Layer 1",
values: [ {time: 1370044800, y: 100}, {time: 1370044801, y: 1000}, ... ]
},
// The second layer
{
label: "Layer 2",
values: [ {time: 1370044800, y: 78}, {time: 1370044801, y: 98}, ... ]
},
...
];
As you can see the data is arranged as an array of layers. Each layer is an object that has the following properties:
label
- The name of the layervalues
- An array of values each value having a unix timestamp (time
) and a value at that time (y
)
The real-time chart requires that values in each layer have the exact same number of elements and that each corresponding
entry have the same time
value.
Given that you have data in the appropriate format, instantiating a new chart is fairly easy. Simply create a container element in HTML and use the jQuery bindings to create, place, and draw the chart:
<div id="areaChart" style="width: 800px; height: 200px"></div>
<script>
$('#areaChart').epoch({
type: 'time.area',
data: areaChartData
});
</script>
Bar
The real-time bar chart is used to show relative sizes of multi-series data in the form of stacked bars as it evolves over time.
var barChartData = [
// First series
{
label: "Series 1",
values: [ {time: 1370044800, y: 100}, {time: 1370044801, y: 1000}, ... ]
},
// The second series
{
label: "Series 2",
values: [ {time: 1370044800, y: 78}, {time: 1370044801, y: 98}, ... ]
},
...
];
As you can see the data is arranged as an array of layers. Each layer is an object that has the following properties:
label
- The name of the layervalues
- An array of values each value having a unix timestamp (time
) and a value at that time (y
)
The real-time chart requires that values in each layer have the exact same number of elements and that each corresponding
entry have the same time
value.
Given that you have data in the appropriate format, instantiating a new chart is fairly easy. Simply create a container element in HTML and use the jQuery bindings to create, place, and draw the chart:
<div id="barChart" style="width: 800px; height: 200px"></div>
<script>
$('#barChart').epoch({
type: 'time.bar',
data: barChartData
});
</script>
Gauge
The gauge chart is used to monitor values over a particular range as they change over time. The chart displays a gauge that is similar to an automobile speedometer.
Unlike most Epoch charts the time gauge does not accept a data
parameter upon initialization. Instead it has no memory and only knows
about its current value
.
The real-time gauge chart is also programmed to fit a specific aspect ratio (4:3). To aid programmers we have included a few css classes you can use to automatically size the chart:
gauge-tiny
(120px by 90px)gauge-small
(180px by 135px)gauge-medium
(240px by 180px)gauge-large
(320px by 240px)
You do not have to use these classes, but you must ensure that your chart container is constrained to the 4 to 3 aspect ratio in order for the chart to render correctly. Let's take a look at how one might create a new gauge chart:
<div id="gaugeChart" class="epoch gauge-small"></div>
<script>
$('#gaugeChart').epoch({
type: 'time.gauge',
value: 0.5
});
</script>
Options
The gauge chart implements the following common options:
fps
- Animation frames per second.pixelRatio
- Explicit pixel ratio override.
And has follow custom options:
Name | Description |
---|---|
domain |
The input domain when setting the value for the gauge chart. Essentially this is an array with the first element representing the minimum value to expect and the second element representing the maximum. Example: domain: [0, 1] |
ticks |
Number of tick marks to display on the chart. Example: ticks: 10 |
tickSize |
Size in pixels for each tick. Example: tickSize: 5 |
tickOffset |
Number of pixels to offset ticks by from the outter arc of the gauge. Example: tickOffset: 10 |
format |
The number formatter to use for the gauge's internal display label. Example: format: function(v) { return (v*100).toFixed(2) + '%'; } |
Heatmap
The real-time heatmap chart is used to visualize normalized histogram data over time. It works by first sorting incoming histograms into a small set of discrete buckets. For multi-series data it uses color blending to show series concentration.
This type of chart has the most "intense" data format, with each entry expecting a sparse histogram. Let's examine this format using and example:
var heatmapData = [
// First Series
{
label: 'Series 1',
values: [
{
time: 1370044800,
histogram: {
18: 49,
104: 10,
...
}
},
{
time: 1370044801,
histogram: {
9: 8,
120: 17,
...
}
},
]
},
...
];
As you can see the data is arranged as an array of layers. Each layer is an object that has the following properties:
label
- The name of the layervalue
- A list of unix timestamp associated sparse histograms:time
- The unix timestam for the entryhistogram
- A "sparse" frequency hash that maps values to frequencies
Given that you have data in the appropriate format, instantiating a new chart is fairly easy. Simply create a container element in HTML and use the jQuery bindings to create, place, and draw the chart:
<div id="heatmapChart" style="width: 800px; height: 200px"></div>
<script>
$('#heatmapChart').epoch({
type: 'time.heatmap',
data: heatmapData
});
</script>
Options
In addition to the common options listed in the overview section, the heatmap has the following custom options:
Name | Description |
---|---|
buckets |
Number of buckets to display in each column of the visible chart window. Example: buckets: 20 |
bucketRange |
The range covered by the buckets. Note: values that fall above the range will be placed in the top most bucket, and values that fall below the range will be placed in the bottom must bucket. Example: bucketRange: [0, 1000] |
bucketPadding |
Amount of padding to place around buckets in the display. Example: bucketPadding: 0 |
opacity |
The opacity function to use when rendering buckets.
opacity: function(value, max) { return Math.pow(value/max, 0.384); } |
paintZeroValues |
Tells the chart whether or not to skip rendering entirely for buckets that have a value of 0, defaults to false . This is useful for overrding the default behavior of the chart when implementing different custom color progressions.Example: paintZeroValues: true |
Line
The real-time line chart is used to display multi-series data as it changes over time. To begin, the chart uses the following data format:
var lineChartData = [
// First series
{
label: "Series 1",
values: [ {time: 1370044800, y: 100}, {time: 1370044801, y: 1000}, ... ]
},
// The second series
{
label: "Series 2",
values: [ {time: 1370044800, y: 78}, {time: 1370044801, y: 98}, ... ]
},
...
];
As you can see the data is arranged as an array of layers. Each layer is an object that has the following properties:
label
- The name of the layervalues
- An array of values each value having a unix timestamp (time
) and a value at that time (y
)
The real-time chart requires that values in each layer have the exact same number of elements and that each corresponding
entry have the same time
value.
Given that you have data in the appropriate format, instantiating a new chart is fairly easy. Simply create a container element in HTML and use the jQuery bindings to create, place, and draw the chart:
<div id="lineChart" style="width: 800px; height: 200px"></div>
<script>
$('#lineChart').epoch({
type: 'time.line',
data: lineChartData
});
</script>
Left and Right Axes Ranges
By default when left
and right
axes are configured, both display the same value range. Each can be given custom ranges by providing a [min, max]
2-element array:
// Specify the left and right ranges
var leftRange = [0, 100];
var rightRange = [-10, 10];
With the ranges defined, they can be applied to the datasets:
// Setup two series, each using a different range
var data = [
{
label: 'Left Ranged Series',
values: [
{ time: 0, y: 0 },
...
],
// This is how your tell a layer to use a specific range...
range: leftRange
},
{
label: 'Right Ranged Series',
values: [
{ time: 0, y: -9.8 },
...
],
// Again, we must define the range for this particular series...
range: rightRange
}
];
Finally, apply the ranges to the chart
// Create the real-time line plot with two ranges
var chart = new Epoch.Time.Line({
range: {
left: leftRange,
right: rightRange
},
data: data,
axes: ['left', 'right', 'bottom']
});
Dynamic Left and Right Axes Ranges
The above produces a chart with fixed ranges on the left and right axes. A range label can be provided instead of a [min, max]
array in order to dynamically calculate what the axis range. For example, take the data definition below:
var data = [
{ label: 'Layer 1', range: 'range-l', data: [...] },
{ label: 'Layer 2', range: 'range-r', data: [...] },
{ label: 'Layer 3', range: 'range-l', data: [...] }
];
Each layer in the data is associated with a "range label" which can then be applied to the left or right side of the chart when you make it:
var chart = new Epoch.Time.Line({
data: data,
range: {
left: 'range-l',
right: 'range-r'
}
});