Permalink
Browse files

Populated Git repo

  • Loading branch information...
joewalnes committed Aug 10, 2010
0 parents commit 30186282c1881283baa314afe04059f2f037a1c3
Showing with 576 additions and 0 deletions.
  1. +19 −0 LICENSE.txt
  2. +32 −0 docs/example-final.html
  3. +51 −0 docs/index.html
  4. +153 −0 docs/tutorial.html
  5. +24 −0 examples/example1.html
  6. +29 −0 examples/server-load.html
  7. +41 −0 examples/server-load.js
  8. +227 −0 smoothie.js
@@ -0,0 +1,19 @@
+Copyright (c) 2010, Joe Walnes
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
@@ -0,0 +1,32 @@
+<html>
+ <head>
+ <title>Smoothie Chart Example</title>
+ <script type="text/javascript" src="../smoothie.js"></script>
+ </head>
+ <body>
+
+ <h1>Smoothie Example</h1>
+
+ <canvas id="mycanvas" width="400" height="100"></canvas>
+
+ <script type="text/javascript">
+
+ // Random data
+ var line1 = new TimeSeries();
+ var line2 = new TimeSeries();
+ setInterval(function() {
+ line1.append(new Date().getTime(), Math.random());
+ line2.append(new Date().getTime(), Math.random());
+ }, 1000);
+
+ var smoothie = new SmoothieChart({ grid: { strokeStyle: 'rgb(125, 0, 0)', fillStyle: 'rgb(60, 0, 0)', lineWidth: 1, millisPerLine: 250, verticalSections: 6 } });
+ smoothie.addTimeSeries(line1, { strokeStyle: 'rgb(0, 255, 0)', fillStyle: 'rgba(0, 255, 0, 0.4)', lineWidth: 3 });
+ smoothie.addTimeSeries(line2, { strokeStyle: 'rgb(255, 0, 255)', fillStyle: 'rgba(255, 0, 255, 0.3)', lineWidth: 3 });
+
+ smoothie.streamTo(document.getElementById("mycanvas"), 1000);
+ </script>
+
+ <p><a href="tutorial.html">Return to tutorial</a></p>
+
+ </body>
+</html>
@@ -0,0 +1,51 @@
+<html>
+ <head>
+ <title>Smoothie Charts</title>
+ <script type="text/javascript" src="../smoothie.js"></script>
+ <style type="text/css">
+ body { font-family: sans-serif; }
+ </style>
+ </head>
+ <body>
+ <h1>Smoothie Charts</h1>
+
+ <canvas id="chart" width="500" height="100"></canvas>
+
+ <p><b>Smoothie Charts</b> is a really small chartling library designed for <i>live streaming data</i>. I build it to reduce
+ the headaches I was getting from watching charts jerkily updating every second. What you're looking up now is pretty much all
+ it does. If you like that, then read on.</p>
+
+ <p>It currently only works on Chrome.</p>
+
+ <h2>Getting started</h2>
+ <ul>
+ <li><a href="../examples/example1.html">Hello world example</a></li>
+ <li><a href="../examples/server-load.html">Another example (server CPU usage)</a></li>
+ <li><a href="tutorial.html"><b>Tutorial</b></a></li>
+ <li><a href="../smoothie.js"><code>smoothie.js</code></a> source code</li>
+ <li>Code: <code>git clone git@github.com:joewalnes/smoothie.git</code></li>
+ </ul>
+
+ <p>For help, use the <a href="http://groups.google.com/group/smoothie-charts">Smoothie Charts Google Group</a>.</p>
+
+
+ <script type="text/javascript">
+ var dataSet1 = new TimeSeries(), dataSet2 = new TimeSeries(), dataSet3 = new TimeSeries();
+
+ setInterval(function() {
+ var now = new Date().getTime();
+ dataSet1.append(now, Math.random());
+ dataSet2.append(now, Math.random());
+ dataSet3.append(now, Math.random());
+ }, 1000);
+
+ // Build the timeline
+ var smoothie = new SmoothieChart({ millisPerPixel: 20, grid: { strokeStyle: '#555555', lineWidth: 1, millisPerLine: 1000, verticalSections: 4 }});
+ smoothie.addTimeSeries(dataSet1, { strokeStyle: 'rgba(255, 0, 0, 1)', fillStyle: 'rgba(255, 0, 0, 0.2)', lineWidth: 3 });
+ smoothie.addTimeSeries(dataSet2, { strokeStyle: 'rgba(0, 255, 0, 1)', fillStyle: 'rgba(0, 255, 0, 0.2)', lineWidth: 3 });
+ smoothie.addTimeSeries(dataSet3, { strokeStyle: 'rgba(0, 0, 255, 1)', fillStyle: 'rgba(0, 0, 255, 0.2)', lineWidth: 3 });
+ smoothie.streamTo(document.getElementById('chart'), 1000);
+
+ </script>
+ </body>
+</html>
@@ -0,0 +1,153 @@
+<html>
+ <head>
+ <title>Smoothie Chart</title>
+ <style type="text/css">
+ .holder {
+ border: 1px solid black;
+ display: inline-block;
+ }
+ .code {
+ border: 1px solid #eeeeee;
+ background-color: #dddddd;
+ }
+ body {
+ font-family: sans-serif;
+ }
+ </style>
+ <script type="text/javascript" src="../smoothie.js"></script>
+ </head>
+ <body>
+ <h1>Smoothie Chart Tutorial</h1>
+
+ <p>Smoothie is a simple library for displaying smooth live time lines.</p>
+
+ <h3>1. Include smoothie.js</h3>
+ <p>Copy <a href="../smoothie.js">smoothie.js</a> to your project and include it:</p>
+ <pre class="code">&lt;script type="text/javascript" src="<a href="../smoothie.js">smoothie.js</a>"&gt;&lt;/script&gt;</pre>
+
+ <h3>2. Create a &lt;canvas&gt;</h3>
+ <pre class="code">&lt;canvas id="mycanvas" width="400" height="100"&gt;&lt;/canvas&gt;</pre>
+ <div class="holder"><canvas id="mycanvas2" width="400" height="100"></canvas></div>
+
+ <h3>3. Stream a SmoothieChart to the Canvas</h3>
+ <p>Use the default settings for now. These can be tweaked later.</p>
+ <pre class="code">
+var smoothie = new SmoothieChart();
+smoothie.streamTo(document.getElementById("mycanvas"));</pre>
+
+ <div class="holder"><canvas id="mycanvas3" width="400" height="100"></canvas></div>
+ <script type="text/javascript">
+ (function() {
+ var smoothie = new SmoothieChart();
+ smoothie.streamTo(document.getElementById("mycanvas3"));
+ })();
+ </script>
+
+ <h3>4. Add some data</h3>
+ <p>Each line requires a <code>TimeSeries</code> object.</p>
+ <p>For this example, we'' create 2 TimeSeries objects and append random data to them every second.</p>
+ <pre class="code">
+// Data
+var line1 = new TimeSeries();
+var line2 = new TimeSeries();
+
+// Add a random value to each line every second
+setInterval(function() {
+ line1.append(new Date().getTime(), Math.random());
+ line2.append(new Date().getTime(), Math.random());
+}, 1000);
+
+// Add to SmoothieChart
+smoothie.addTimeSeries(line1);
+smoothie.addTimeSeries(line2);</pre>
+
+ <div class="holder"><canvas id="mycanvas4" width="400" height="100"></canvas></div>
+ <script type="text/javascript">
+ (function() {
+ var line1 = new TimeSeries();
+ var line2 = new TimeSeries();
+ setInterval(function() {
+ line1.append(new Date().getTime(), Math.random());
+ line2.append(new Date().getTime(), Math.random());
+ }, 1000);
+
+ var smoothie = new SmoothieChart();
+ smoothie.addTimeSeries(line1);
+ smoothie.addTimeSeries(line2);
+ smoothie.streamTo(document.getElementById("mycanvas4"));
+ })();
+ </script>
+
+ <p><em>In reality, you'd probably want to get data from a WebSocket, rather than random generator.</em></p>
+
+ <p>Important notes:</p>
+ <ul>
+ <li>TimeSeries.append() takes two parameters: timestamp of the data point, and value of the data point.</li>
+ <li>The value can be any number. Smoothie will automatically scale the chart based on the minimum and maximum values seen across all time series.</li>
+ <li>Smoothie will automatically delete old data from the TimeSeries as it dissappears off the chart.</li>
+ </ul>
+
+
+ <h3>5. Add some delay</h3>
+ <p>The above chart shows an issue... we cannot plot a line until the next data point is known. To get around this,
+ we add a delay to the chart, so upcoming values are known before we need to plot the line.</p>
+ <p>This makes the chart look like a continual stream rather than very jumpy on the right hand side.</p>
+ <p>To add the delay, we modify the <code>SmoothieChart.streamTo()</code> call to include the delay.</p>
+ <pre class="code"> smoothie.streamTo(document.getElementById("mycanvas"), <strong>1000 /*delay*/</strong>); </pre>
+ <div class="holder"><canvas id="mycanvas5" width="400" height="100"></canvas></div>
+ <script type="text/javascript">
+ (function() {
+ var line1 = new TimeSeries();
+ var line2 = new TimeSeries();
+ setInterval(function() {
+ line1.append(new Date().getTime(), Math.random());
+ line2.append(new Date().getTime(), Math.random());
+ }, 1000);
+
+ var smoothie = new SmoothieChart();
+ smoothie.addTimeSeries(line1);
+ smoothie.addTimeSeries(line2);
+ smoothie.streamTo(document.getElementById("mycanvas5"), 1000);
+ })();
+ </script>
+ <p>That's much easier on the eye.</p>
+
+ <h3>6. Splash of color</h3>
+ <p>The API provides a few hooks for tweaking the style of the lines and the grid.</p>
+ <pre class="code">
+var smoothie = new SmoothieChart(<strong>{
+ grid: { strokeStyle:'rgb(125, 0, 0)', fillStyle:'rgb(60, 0, 0)',
+ lineWidth: 1, millisPerLine: 250, verticalSections: 6, },
+ labels: { fillStyle:'rgb(60, 0, 0)' }
+}</strong>);
+smoothie.addTimeSeries(line1,
+ <strong>{ strokeStyle:'rgb(0, 255, 0)', fillStyle:'rgba(0, 255, 0, 0.4)', lineWidth:3 }</strong>);
+smoothie.addTimeSeries(line2,
+ <strong>{ strokeStyle:'rgb(255, 0, 255)', fillStyle:'rgba(255, 0, 255, 0.3)', lineWidth:3 }</strong>);</pre>
+ <div class="holder"><canvas id="mycanvas6" width="400" height="100"></canvas></div>
+ <script type="text/javascript">
+ (function() {
+ var line1 = new TimeSeries();
+ var line2 = new TimeSeries();
+ setInterval(function() {
+ line1.append(new Date().getTime(), Math.random());
+ line2.append(new Date().getTime(), Math.random());
+ }, 1000);
+
+ var smoothie = new SmoothieChart({
+ grid: { strokeStyle: 'rgb(125, 0, 0)', fillStyle: 'rgb(60, 0, 0)', lineWidth: 1, millisPerLine: 250, verticalSections: 6 },
+ labels: { fillStyle:'rgb(255, 255, 0)' }
+ });
+ smoothie.addTimeSeries(line1, { strokeStyle: 'rgb(0, 255, 0)', fillStyle: 'rgba(0, 255, 0, 0.4)', lineWidth: 3 });
+ smoothie.addTimeSeries(line2, { strokeStyle: 'rgb(255, 0, 255)', fillStyle: 'rgba(255, 0, 255, 0.3)', lineWidth: 3 });
+ smoothie.streamTo(document.getElementById("mycanvas6"), 1000);
+ })();
+ </script>
+
+ <h3>That's it.</h3>
+
+ <p>View the <a href="example-final.html">finished example</a>.</p>
+
+ <p>For help, use the <a href="http://groups.google.com/group/smoothie-charts">Smoothie Charts Google Group</a>.</p>
+ </body>
+</html>
@@ -0,0 +1,24 @@
+<html>
+ <head>
+ <script type="text/javascript" src="../smoothie.js"></script>
+ <script type="text/javascript">
+
+ // Randomly add a data point every 500ms
+ var random = new TimeSeries();
+ setInterval(function() {
+ random.append(new Date().getTime(), Math.random() * 10000);
+ }, 500);
+
+ function createTimeline() {
+ var chart = new SmoothieChart();
+ chart.addTimeSeries(random, { strokeStyle: 'rgba(0, 255, 0, 1)', fillStyle: 'rgba(0, 255, 0, 0.2)', lineWidth: 4 });
+ chart.streamTo(document.getElementById("chart"), 500);
+ }
+ </script>
+ </head>
+ <body onload="createTimeline()" style="background-color:#333333">
+
+ <canvas id="chart" width="100" height="100"></canvas>
+
+ </body>
+</html>
@@ -0,0 +1,29 @@
+<html>
+ <head>
+ <style type="text/css">
+ body {
+ background-color: #000000;
+ color: #eeeeee;
+ font-family: tahoma, arial, sans-serif;
+ }
+ </style>
+ <script type="text/javascript" src="../smoothie.js"></script>
+ <script type="text/javascript" src="server-load.js"></script>
+ </head>
+ <body onload="init()">
+
+ <h4>host1.example.com</h4>
+ <canvas id="host1Cpu" width="500" height="100"></canvas>
+
+ <h4>host2.example.com</h4>
+ <canvas id="host2Cpu" width="500" height="100"></canvas>
+
+ <h4>host3.example.com</h4>
+ <canvas id="host3Cpu" width="500" height="100"></canvas>
+
+ <h4>host4.example.com</h4>
+ <canvas id="host4Cpu" width="500" height="100"></canvas>
+
+ <em>This is fake data.</em>
+ </body>
+</html>
@@ -0,0 +1,41 @@
+function init() {
+ initHost('host1');
+ initHost('host2');
+ initHost('host3');
+ initHost('host4');
+}
+
+var seriesOptions = [
+ { strokeStyle: 'rgba(255, 0, 0, 1)', fillStyle: 'rgba(255, 0, 0, 0.1)', lineWidth: 3 },
+ { strokeStyle: 'rgba(0, 255, 0, 1)', fillStyle: 'rgba(0, 255, 0, 0.1)', lineWidth: 3 },
+ { strokeStyle: 'rgba(0, 0, 255, 1)', fillStyle: 'rgba(0, 0, 255, 0.1)', lineWidth: 3 },
+ { strokeStyle: 'rgba(255, 255, 0, 1)', fillStyle: 'rgba(255, 255, 0, 0.1)', lineWidth: 3 }
+];
+
+function initHost(hostId) {
+
+ // Initialize an empty TimeSeries for each CPU.
+ var cpuDataSets = [new TimeSeries(), new TimeSeries(), new TimeSeries(), new TimeSeries()];
+
+ var now = new Date().getTime();
+ for (var t = now - 1000 * 50; t <= now; t += 1000) {
+ addRandomValueToDataSets(t, cpuDataSets);
+ }
+ // Every second, simulate a new set of readings being taken from each CPU.
+ setInterval(function() {
+ addRandomValueToDataSets(new Date().getTime(), cpuDataSets);
+ }, 1000);
+
+ // Build the timeline
+ var timeline = new SmoothieChart({ millisPerPixel: 20, grid: { strokeStyle: '#555555', lineWidth: 1, millisPerLine: 1000, verticalSections: 4 }});
+ for (var i = 0; i < cpuDataSets.length; i++) {
+ timeline.addTimeSeries(cpuDataSets[i], seriesOptions[i]);
+ }
+ timeline.streamTo(document.getElementById(hostId + 'Cpu'), 1000);
+}
+
+function addRandomValueToDataSets(time, dataSets) {
+ for (var i = 0; i < dataSets.length; i++) {
+ dataSets[i].append(time, Math.random());
+ }
+}
Oops, something went wrong.

0 comments on commit 3018628

Please sign in to comment.