Current state

This commit is contained in:
2026-02-07 08:23:18 +01:00
commit 0a4372c40d
22479 changed files with 1553543 additions and 0 deletions

View File

@@ -0,0 +1,44 @@
<!doctype>
<head>
<link type="text/css" rel="stylesheet" href="../src/css/graph.css">
<link type="text/css" rel="stylesheet" href="css/lines.css">
<script src="../vendor/d3.v3.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.1/jquery.min.js"></script>
<script src="../rickshaw.js"></script>
</head>
<body>
<div id="chart_container">
<div id="chart"></div>
</div>
<script>
var ajaxGraph = new Rickshaw.Graph.Ajax( {
element: document.getElementById("chart"),
width: 400,
height: 200,
renderer: 'line',
dataURL: 'data/data.json',
onData: function(d) { d[0].data[0].y = 80; return d },
series: [
{
name: 'New York',
color: '#c05020',
}, {
name: 'London',
color: '#30c020',
}, {
name: 'Tokyo',
color: '#6060c0'
}
]
} );
</script>
</body>

View File

@@ -0,0 +1,52 @@
<!doctype>
<head>
<link type="text/css" rel="stylesheet" href="../src/css/graph.css">
<script src="../vendor/d3.v3.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.15/jquery-ui.min.js"></script>
<script src="../rickshaw.js"></script>
</head>
<body>
<div id="chart"></div>
<script>
// set up our data series with 50 random data points
var seriesData = [ [], [], [] ];
var random = new Rickshaw.Fixtures.RandomData(150);
for (var i = 0; i < 70; i++) {
random.addData(seriesData);
}
// instantiate our graph!
var graph = new Rickshaw.Graph( {
element: document.getElementById("chart"),
width: 960,
height: 500,
renderer: 'bar',
series: [
{
color: "#c05020",
data: seriesData[0],
}, {
color: "#30c020",
data: seriesData[1],
}, {
color: "#6060c0",
data: seriesData[2],
}
]
} );
graph.render();
</script>
</body>

View File

@@ -0,0 +1,88 @@
<!doctype>
<link type="text/css" rel="stylesheet" href="../src/css/graph.css">
<link type="text/css" rel="stylesheet" href="css/lines.css">
<script src="../vendor/d3.v3.js"></script>
<script src="../rickshaw.min.js"></script>
<style>
section {
width: 300px;
height: 250px;
float: left;
margin: 16px;
}
section div {
width: 300px;
height: 200px;
}
span {
font-family: Arial, Helvetica, sans-serif;
color: #808080;
display: inline-block;
margin: 4px 0;
}
</style>
<body>
<script>
var schemes = [
'spectrum14',
'colorwheel',
'cool',
'spectrum2000',
'spectrum2001',
'classic9',
'munin'
];
schemes.forEach( function(name) {
var palette = new Rickshaw.Color.Palette( { scheme: name } );
var seriesData = [];
palette.scheme.forEach( function() {
seriesData.push([]);
} );
var random = new Rickshaw.Fixtures.RandomData(150);
for (var i = 0; i < 100; i++) {
random.addData(seriesData);
}
var section = document.createElement('section');
var element = document.createElement('div');
var caption = document.createElement('span');
caption.innerHTML = name;
section.appendChild(element);
section.appendChild(caption);
document.body.appendChild(section);
var series = [];
seriesData.forEach( function(s) {
series.push( {
data: s,
color: palette.color()
} );
} );
var graph = new Rickshaw.Graph( {
element: element,
series: series
} );
graph.render();
} );
</script>
</body>

View File

@@ -0,0 +1,167 @@
#chart {
display: inline-block;
}
#chart path {
-webkit-transition: opacity 0.2s linear;
}
#preview {
margin-top: 10px;
}
#legend {
display: inline-block;
position: relative;
left: 8px;
}
#legend_container {
position: absolute;
right: 0;
bottom: 26px;
width: 0;
}
#chart_container {
position: relative;
display: inline-block;
}
#smoother {
margin: 0 0 10px 16px;
width: 100px;
}
.rickshaw_graph .detail {
left: -1000;
}
#chart {
border: none;
width: 100%
}
#side_panel {
padding: 0 20px 20px 0;
width: 240px;
display: inline-block;
vertical-align: top;
}
#side_panel section {
color: #505050;
font-size: 12px;
}
#side_panel section h6 {
margin: 0 0 1em 0;
font-size: 12px;
font-weight: normal;
}
#side_panel .ui-slider-horizontal {
height: 1px !important;
border-color: #e0e0e0;
margin-bottom: 10px;
}
#side_panel .ui-slider-handle {
border-color: #a0a0a0;
height: 9px !important;
width: 9px !important;
top: -5px !important;
border-radius: 6px;
outline: none;
cursor: pointer;
}
#legend {
background-color: white;
margin-left: 0;
padding: 0;
left: 0;
}
#legend .label {
color: #404040;
}
#legend .action {
color: black;
opacity: 0.5;
}
#legend ul {
padding: 0;
}
#smoother {
margin: 5px 0 0 10px;
width: 90%;
}
#renderer_form.toggler {
display: block;
margin: 0;
}
#renderer_form.toggler input[type=radio]:checked {
outline: 2px solid steelblue;
}
#renderer_form.toggler input[type=radio] {
-moz-appearance: button;
background: white;
margin: 0 7px;
width: 39px;
height: 26px;
position: absolute;
visibility: hidden;
}
#renderer_form.toggler label {
display: inline-block;
padding: 0;
width: 39px;
padding-top: 27px;
text-align: center;
font-size: 10px;
color: #808080;
background-repeat: no-repeat;
position: relative;
margin: 0 7px;
cursor: pointer;
}
#interpolation_form,
#offset_form {
vertical-align: top;
display: inline-block;
width: 45%;
}
#interpolation_form label,
#offset_form label {
display: block;
}
label[for=area] {
background: url(../images/om_stack.png);
}
label[for=line] {
background: url(../images/om_lines.png);
}
label[for=bar] {
background: url(../images/om_bar.png);
}
label[for=scatter] {
background: url(../images/om_scatter.png);
}
#offset_form label,
#interpolation_form label {
background-repeat: no-repeat;
background-position: 2em center;
cursor: pointer;
cursor: hand;
}
#offset_form label span,
#interpolation_form label span {
padding-left: 36px;
}
label[for=stack] {
background-image: url(../images/offset_stack.png);
}
label[for=pct] {
background-image: url(../images/offset_pct.png);
}
label[for=stream] {
background-image: url(../images/offset_stream.png);
}
label[for=value] {
background-image: url(../images/offset_value.png);
}
label[for=cardinal] {
background-image: url(../images/interp_cardinal.png);
}
label[for=linear] {
background-image: url(../images/interp_linear.png);
}
label[for=step] {
background-image: url(../images/interp_step.png);
}

View File

@@ -0,0 +1,21 @@
div, span, p, td {
font-family: Arial, sans-serif;
}
#chart {
display: inline-block;
}
#legend {
display: inline-block;
position: relative;
left: 8px;
}
#legend_container {
position: absolute;
right: 0;
bottom: 26px;
width: 0;
}
#chart_container {
float: left;
position: relative;
}

View File

@@ -0,0 +1,14 @@
[
{
"color": "blue",
"name": "New York",
"data": [ { "x": 0, "y": 40 }, { "x": 1, "y": 49 }, { "x": 2, "y": 38 }, { "x": 3, "y": 30 }, { "x": 4, "y": 32 } ]
}, {
"name": "London",
"data": [ { "x": 0, "y": 19 }, { "x": 1, "y": 22 }, { "x": 2, "y": 29 }, { "x": 3, "y": 20 }, { "x": 4, "y": 14 } ]
}, {
"name": "Tokyo",
"data": [ { "x": 0, "y": 8 }, { "x": 1, "y": 12 }, { "x": 2, "y": 15 }, { "x": 3, "y": 11 }, { "x": 4, "y": 10 } ]
}
]

View File

@@ -0,0 +1,14 @@
callback([
{
'color': 'blue',
'name': 'London',
'data': [ { x: 0, y: 40 }, { x: 1, y: 49 }, { x: 2, y: 38 }, { x: 3, y: 30 }, { x: 4, y: 32 } ],
}, {
'name': 'New York',
'data': [ { x: 0, y: 19 }, { x: 1, y: 22 }, { x: 2, y: 29 }, { x: 3, y: 20 }, { x: 4, y: 14 } ],
}, {
'name': 'Tokyo',
'data': [ { x: 0, y: 8 }, { x: 1, y: 12 }, { x: 2, y: 15 }, { x: 3, y: 11 }, { x: 4, y: 10 } ],
}
]);

View File

@@ -0,0 +1,14 @@
[
{
"color": "blue",
"name": "New York",
"data": [ { "x": 0, "y": 50 }, { "x": 1, "y": 32 }, { "x": 2, "y": 38 }, { "x": 3, "y": 30 }, { "x": 4, "y": 32 } ]
}, {
"name": "London",
"data": [ { "x": 0, "y": 19 }, { "x": 1, "y": 76 }, { "x": 2, "y": 28 }, { "x": 3, "y": 20 }, { "x": 4, "y": 14 } ]
}, {
"name": "Tokyo",
"data": [ { "x": 0, "y": 8 }, { "x": 1, "y": 12 }, { "x": 2, "y": 14 }, { "x": 3, "y": 11 }, { "x": 4, "y": 28 } ]
}
]

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,280 @@
<!doctype html>
<head>
<link type="text/css" rel="stylesheet" href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8/themes/base/jquery-ui.css">
<link type="text/css" rel="stylesheet" href="../src/css/graph.css">
<link type="text/css" rel="stylesheet" href="../src/css/detail.css">
<link type="text/css" rel="stylesheet" href="../src/css/legend.css">
<link type="text/css" rel="stylesheet" href="css/extensions.css?v=2">
<script src="../vendor/d3.v3.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js"></script>
<script>
jQuery.noConflict();
</script>
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.15/jquery-ui.min.js"></script>
<script src="../src/js/Rickshaw.js"></script>
<script src="../src/js/Rickshaw.Class.js"></script>
<script src="../src/js/Rickshaw.Compat.ClassList.js"></script>
<script src="../src/js/Rickshaw.Graph.js"></script>
<script src="../src/js/Rickshaw.Graph.Renderer.js"></script>
<script src="../src/js/Rickshaw.Graph.Renderer.Area.js"></script>
<script src="../src/js/Rickshaw.Graph.Renderer.Line.js"></script>
<script src="../src/js/Rickshaw.Graph.Renderer.Bar.js"></script>
<script src="../src/js/Rickshaw.Graph.Renderer.ScatterPlot.js"></script>
<script src="../src/js/Rickshaw.Graph.Renderer.Stack.js"></script>
<script src="../src/js/Rickshaw.Graph.RangeSlider.js"></script>
<script src="../src/js/Rickshaw.Graph.RangeSlider.Preview.js"></script>
<script src="../src/js/Rickshaw.Graph.HoverDetail.js"></script>
<script src="../src/js/Rickshaw.Graph.Annotate.js"></script>
<script src="../src/js/Rickshaw.Graph.Legend.js"></script>
<script src="../src/js/Rickshaw.Graph.Axis.Time.js"></script>
<script src="../src/js/Rickshaw.Graph.Behavior.Series.Toggle.js"></script>
<script src="../src/js/Rickshaw.Graph.Behavior.Series.Order.js"></script>
<script src="../src/js/Rickshaw.Graph.Behavior.Series.Highlight.js"></script>
<script src="../src/js/Rickshaw.Graph.Smoother.js"></script>
<script src="../src/js/Rickshaw.Fixtures.Time.js"></script>
<script src="../src/js/Rickshaw.Fixtures.Time.Local.js"></script>
<script src="../src/js/Rickshaw.Fixtures.Number.js"></script>
<script src="../src/js/Rickshaw.Fixtures.RandomData.js"></script>
<script src="../src/js/Rickshaw.Fixtures.Color.js"></script>
<script src="../src/js/Rickshaw.Color.Palette.js"></script>
<script src="../src/js/Rickshaw.Graph.Axis.Y.js"></script>
<script src="js/extensions.js"></script>
</head>
<body>
<div id="content">
<form id="side_panel">
<h1>Random Data in the Future</h1>
<section><div id="legend"></div></section>
<section>
<div id="renderer_form" class="toggler">
<input type="radio" name="renderer" id="area" value="area" checked>
<label for="area">area</label>
<input type="radio" name="renderer" id="bar" value="bar">
<label for="bar">bar</label>
<input type="radio" name="renderer" id="line" value="line">
<label for="line">line</label>
<input type="radio" name="renderer" id="scatter" value="scatterplot">
<label for="scatter">scatter</label>
</div>
</section>
<section>
<div id="offset_form">
<label for="stack">
<input type="radio" name="offset" id="stack" value="zero" checked>
<span>stack</span>
</label>
<label for="stream">
<input type="radio" name="offset" id="stream" value="wiggle">
<span>stream</span>
</label>
<label for="pct">
<input type="radio" name="offset" id="pct" value="expand">
<span>pct</span>
</label>
<label for="value">
<input type="radio" name="offset" id="value" value="value">
<span>value</span>
</label>
</div>
<div id="interpolation_form">
<label for="cardinal">
<input type="radio" name="interpolation" id="cardinal" value="cardinal" checked>
<span>cardinal</span>
</label>
<label for="linear">
<input type="radio" name="interpolation" id="linear" value="linear">
<span>linear</span>
</label>
<label for="step">
<input type="radio" name="interpolation" id="step" value="step-after">
<span>step</span>
</label>
</div>
</section>
<section>
<h6>Smoothing</h6>
<div id="smoother"></div>
</section>
<section></section>
</form>
<div id="chart_container">
<div id="chart"></div>
<div id="timeline"></div>
<div id="preview"></div>
</div>
</div>
<script>
// set up our data series with 150 random data points
var seriesData = [ [], [], [], [], [], [], [], [], [] ];
var random = new Rickshaw.Fixtures.RandomData(150);
for (var i = 0; i < 150; i++) {
random.addData(seriesData);
}
var palette = new Rickshaw.Color.Palette( { scheme: 'classic9' } );
// instantiate our graph!
var graph = new Rickshaw.Graph( {
element: document.getElementById("chart"),
width: 900,
height: 500,
renderer: 'area',
stroke: true,
preserve: true,
series: [
{
color: palette.color(),
data: seriesData[0],
name: 'Moscow'
}, {
color: palette.color(),
data: seriesData[1],
name: 'Shanghai'
}, {
color: palette.color(),
data: seriesData[2],
name: 'Amsterdam'
}, {
color: palette.color(),
data: seriesData[3],
name: 'Paris'
}, {
color: palette.color(),
data: seriesData[4],
name: 'Tokyo'
}, {
color: palette.color(),
data: seriesData[5],
name: 'London'
}, {
color: palette.color(),
data: seriesData[6],
name: 'New York'
}
]
} );
graph.render();
var preview = new Rickshaw.Graph.RangeSlider( {
graph: graph,
element: document.getElementById('preview'),
} );
var hoverDetail = new Rickshaw.Graph.HoverDetail( {
graph: graph,
xFormatter: function(x) {
return new Date(x * 1000).toString();
}
} );
var annotator = new Rickshaw.Graph.Annotate( {
graph: graph,
element: document.getElementById('timeline')
} );
var legend = new Rickshaw.Graph.Legend( {
graph: graph,
element: document.getElementById('legend')
} );
var shelving = new Rickshaw.Graph.Behavior.Series.Toggle( {
graph: graph,
legend: legend
} );
var order = new Rickshaw.Graph.Behavior.Series.Order( {
graph: graph,
legend: legend
} );
var highlighter = new Rickshaw.Graph.Behavior.Series.Highlight( {
graph: graph,
legend: legend
} );
var smoother = new Rickshaw.Graph.Smoother( {
graph: graph,
element: document.querySelector('#smoother')
} );
var ticksTreatment = 'glow';
var xAxis = new Rickshaw.Graph.Axis.Time( {
graph: graph,
ticksTreatment: ticksTreatment,
timeFixture: new Rickshaw.Fixtures.Time.Local()
} );
xAxis.render();
var yAxis = new Rickshaw.Graph.Axis.Y( {
graph: graph,
tickFormat: Rickshaw.Fixtures.Number.formatKMBT,
ticksTreatment: ticksTreatment
} );
yAxis.render();
var controls = new RenderControls( {
element: document.querySelector('form'),
graph: graph
} );
// add some data every so often
var messages = [
"Changed home page welcome message",
"Minified JS and CSS",
"Changed button color from blue to green",
"Refactored SQL query to use indexed columns",
"Added additional logging for debugging",
"Fixed typo",
"Rewrite conditional logic for clarity",
"Added documentation for new methods"
];
setInterval( function() {
random.removeData(seriesData);
random.addData(seriesData);
graph.update();
}, 3000 );
function addAnnotation(force) {
if (messages.length > 0 && (force || Math.random() >= 0.95)) {
annotator.add(seriesData[2][seriesData[2].length-1].x, messages.shift());
annotator.update();
}
}
addAnnotation(true);
setTimeout( function() { setInterval( addAnnotation, 6000 ) }, 6000 );
var previewXAxis = new Rickshaw.Graph.Axis.Time({
graph: preview.previews[0],
timeFixture: new Rickshaw.Fixtures.Time.Local(),
ticksTreatment: ticksTreatment
});
previewXAxis.render();
</script>
</body>

View File

@@ -0,0 +1,54 @@
<!doctype>
<head>
<link type="text/css" rel="stylesheet" href="../src/css/graph.css">
<link type="text/css" rel="stylesheet" href="../src/css/detail.css">
<link type="text/css" rel="stylesheet" href="../src/css/legend.css">
<link type="text/css" rel="stylesheet" href="css/extensions.css">
<script src="../vendor/d3.v3.js"></script>
<script src="../rickshaw.js"></script>
</head>
<body>
<div id="content">
<div id="chart"></div>
</div>
<script>
var tv = 250;
// instantiate our graph!
var graph = new Rickshaw.Graph( {
element: document.getElementById("chart"),
width: 900,
height: 500,
renderer: 'line',
series: new Rickshaw.Series.FixedDuration([{ name: 'one' }], undefined, {
timeInterval: tv,
maxDataPoints: 100,
timeBase: new Date().getTime() / 1000
})
} );
graph.render();
// add some data every so often
var i = 0;
var iv = setInterval( function() {
var data = { one: Math.floor(Math.random() * 40) + 120 };
var randInt = Math.floor(Math.random()*100);
data.two = (Math.sin(i++ / 40) + 4) * (randInt + 400);
data.three = randInt + 300;
graph.series.addData(data);
graph.render();
}, tv );
</script>
</body>

View File

@@ -0,0 +1,83 @@
<!doctype>
<head>
<link type="text/css" rel="stylesheet" href="http://jqueryui.com/themes/base/jquery.ui.all.css">
<link type="text/css" rel="stylesheet" href="../src/css/graph.css">
<link type="text/css" rel="stylesheet" href="../src/css/detail.css">
<link type="text/css" rel="stylesheet" href="../src/css/legend.css">
<link type="text/css" rel="stylesheet" href="css/lines.css">
<script src="../vendor/d3.v3.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.15/jquery-ui.min.js"></script>
<script src="../rickshaw.js"></script>
<style>
.rickshaw_graph .detail .x_label { display: none }
.rickshaw_graph .detail .item { line-height: 1.4; padding: 0.5em }
.detail_swatch { float: right; display: inline-block; width: 10px; height: 10px; margin: 0 4px 0 0 }
.rickshaw_graph .detail .date { color: #a0a0a0 }
</style>
</head>
<body>
<div id="chart_container">
<div id="chart"></div>
<div id="legend_container">
<div id="smoother" title="Smoothing"></div>
<div id="legend"></div>
</div>
<div id="slider"></div>
</div>
<script>
// set up our data series with 50 random data points
var seriesData = [ [], [], [] ];
var random = new Rickshaw.Fixtures.RandomData(150);
for (var i = 0; i < 150; i++) {
random.addData(seriesData);
}
// instantiate our graph!
var graph = new Rickshaw.Graph( {
element: document.getElementById("chart"),
width: 960,
height: 500,
renderer: 'line',
series: [
{
color: "#c05020",
data: seriesData[0],
name: 'New York'
}, {
color: "#30c020",
data: seriesData[1],
name: 'London'
}, {
color: "#6060c0",
data: seriesData[2],
name: 'Tokyo'
}
]
} );
graph.render();
var hoverDetail = new Rickshaw.Graph.HoverDetail( {
graph: graph,
formatter: function(series, x, y) {
var date = '<span class="date">' + new Date(x * 1000).toUTCString() + '</span>';
var swatch = '<span class="detail_swatch" style="background-color: ' + series.color + '"></span>';
var content = swatch + series.name + ": " + parseInt(y) + '<br>' + date;
return content;
}
} );
</script>
</body>

View File

@@ -0,0 +1,46 @@
<!doctype html>
<link type="text/css" rel="stylesheet" href="../src/css/graph.css">
<link type="text/css" rel="stylesheet" href="css/lines.css">
<link type="text/css" rel="stylesheet" href="../rickshaw.css">
<script src="../vendor/d3.v3.js"></script>
<script src="../rickshaw.js"></script>
<div id="chart"></div>
<script>
var palette = new Rickshaw.Color.Palette();
var graph = new Rickshaw.Graph( {
element: document.getElementById("chart"),
renderer: 'area',
stroke: true,
series: [
{
data: [ { x: 0, y: 19 }, { x: 1, y: 30 }, { x: 2, y: 22 }, { x: 3, y: 29 }, { x: 4, y: 21 }, { x: 5, y: 29 } ],
name: 'new york',
color: palette.color()
}, {
data: [ { x: 0, y: 19 }, { x: 1, y: 29 }, { x: 2, y: 22 }, { x: 3, y: 27 }, { x: 4, y: 21 }, { x: 5, y: 29 } ],
name: 'boston',
color: palette.color()
}, {
data: [ { x: 0, y: 19 }, { x: 1, y: 22 }, { x: 2, y: 10 }, { x: 3, y: null }, { x: 4, y: 21 }, { x: 5, y: 29 } ],
name: 'los angeles',
color: palette.color()
}, {
data: [ { x: 0, y: 19 }, { x: 1, y: 10 }, { x: 2, y: 22 }, { x: 3, y: null }, { x: 4, y: 21 }, { x: 5, y: 29 } ],
name: 'san francisco',
color: palette.color()
}
]
} );
graph.render();
new Rickshaw.Graph.HoverDetail({ graph: graph });
</script>

View File

@@ -0,0 +1,130 @@
<!doctype>
<head>
<link type="text/css" rel="stylesheet" href="../src/css/graph.css">
<link type="text/css" rel="stylesheet" href="../src/css/detail.css">
<link type="text/css" rel="stylesheet" href="../src/css/legend.css">
<script src="../vendor/d3.v3.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js"></script>
<script src="../rickshaw.js"></script>
<style>
body {
font-family: Arial, sans-serif
}
#chart_container {
width: 960px;
}
.swatch {
display: inline-block;
width: 10px;
height: 10px;
margin: 0 8px 0 0;
}
.label {
display: inline-block;
}
.line {
display: inline-block;
margin: 0 0 0 30px;
}
#legend {
text-align: center;
}
.rickshaw_graph .detail {
background: none;
}
</style>
</head>
<body>
<div id="chart_container">
<div id="chart"></div><br>
<div id="legend"></div>
</div>
<script>
// set up our data series with 50 random data points
var seriesData = [ [], [], [] ];
var random = new Rickshaw.Fixtures.RandomData(150);
for (var i = 0; i < 150; i++) {
random.addData(seriesData);
}
// instantiate our graph!
var graph = new Rickshaw.Graph( {
element: document.getElementById("chart"),
width: 960,
height: 500,
renderer: 'line',
series: [
{
color: "#c05020",
data: seriesData[0],
name: 'New York'
}, {
color: "#30c020",
data: seriesData[1],
name: 'London'
}, {
color: "#6060c0",
data: seriesData[2],
name: 'Tokyo'
}
]
} );
graph.render();
var legend = document.querySelector('#legend');
var Hover = Rickshaw.Class.create(Rickshaw.Graph.HoverDetail, {
render: function(args) {
legend.innerHTML = args.formattedXValue;
args.detail.sort(function(a, b) { return a.order - b.order }).forEach( function(d) {
var line = document.createElement('div');
line.className = 'line';
var swatch = document.createElement('div');
swatch.className = 'swatch';
swatch.style.backgroundColor = d.series.color;
var label = document.createElement('div');
label.className = 'label';
label.innerHTML = d.name + ": " + d.formattedYValue;
line.appendChild(swatch);
line.appendChild(label);
legend.appendChild(line);
var dot = document.createElement('div');
dot.className = 'dot';
dot.style.top = graph.y(d.value.y0 + d.value.y) + 'px';
dot.style.borderColor = d.series.color;
this.element.appendChild(dot);
dot.className = 'dot active';
this.show();
}, this );
}
});
var hover = new Hover( { graph: graph } );
</script>
</body>

Binary file not shown.

After

Width:  |  Height:  |  Size: 570 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 571 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 382 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 642 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 686 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 879 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 707 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 418 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 454 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 950 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 298 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@@ -0,0 +1,46 @@
<!doctype html>
<link type="text/css" rel="stylesheet" href="../src/css/graph.css">
<link type="text/css" rel="stylesheet" href="css/lines.css">
<link type="text/css" rel="stylesheet" href="../rickshaw.css">
<script src="../vendor/d3.v3.js"></script>
<script src="../rickshaw.js"></script>
<div id="chart"></div>
<script>
var palette = new Rickshaw.Color.Palette();
var graph = new Rickshaw.Graph( {
element: document.getElementById("chart"),
renderer: 'line',
interpolation: 'cardinal',
series: [
{
data: [ { x: 0, y: 19 }, { x: 1, y: 30 }, { x: 2, y: 22 }, { x: 3, y: 29 }, { x: 4, y: 26 }, { x: 5, y: 35 } ],
name: 'new york',
color: palette.color()
}, {
data: [ { x: 0, y: 49 }, { x: 1, y: 35 }, { x: 2, y: 32 }, { x: 3, y: 38 }, { x: 4, y: 37 } ],
name: 'boston',
color: palette.color()
}, {
data: [ { x: 0, y: 19 }, { x: 1, y: 22 }, { x: 2, y: 10 }, { x: 4, y: 21 }, { x: 5, y: 17 } ],
name: 'los angeles',
color: palette.color()
}, {
data: [ { x: 1, y: 9 }, { x: 2, y: 3 }, { x: 3, y: 8 }, { x: 4, y: 14 }, { x: 5, y: 13 } ],
name: 'san francisco',
color: palette.color()
}
]
} );
graph.render();
new Rickshaw.Graph.HoverDetail({ graph: graph });
</script>

View File

@@ -0,0 +1,241 @@
<!doctype>
<link rel="stylesheet" href="../css/style.css">
<style>
body {
font-family: Arial, Helvetica, sans-serif;
font-size: 13px;
color: #282828;
line-height: 135%;
margin: 0;
}
.content {
width: 780px;
margin: auto;
display: block;
}
section img {
width: 25%;
display: inline-block;
vertical-align: top;
margin: 0 3% 0 0;
border: none;
}
div {
width: 70%;
display: inline-block;
vertical-align: top;
}
a {
text-decoration: none;
color: steelblue;
}
a:hover {
color: lightblue;
}
h1 {
margin: 1em 0 1em 0;
font-weight: normal;
}
h2 {
font-weight: normal;
margin: 0 0 0.7em 0;
color: black;
float: left;
}
section {
border-top: 1px solid #e0e0e0;
padding: 1.8em 0;
display: block;
}
span {
clear: both;
display: block;
}
.clear {
clear: both;
}
#start {
height: 70px;
}
hr {
margin-bottom: 40px;
border: none;
border-bottom: 1px solid #e0e0e0;
}
img {
border: none;
}
</style>
<script src="../js/header.js"></script>
<div class="content">
<h1>Rickshaw Examples</h1>
<section>
<a href="start.html"><img src="screenshots/start.png" id="start"></a>
<div>
<h2><a href="start.html">Getting Started</a></h2>
<span>
Bare minimum to get a graph on the page with a couple of points.
</span>
</div>
</section>
<section>
<a href="lines.html"><img src="screenshots/lines.png"></a>
<div>
<h2><a href="lines.html">Lines & Toggling</a></h2>
<span>
Basic lines with a legend and x-axis ticks and labels. Toggle lines on and off by clicking checkmarks.
</span>
</div>
</section>
<section>
<a href="extensions.html"><img src="screenshots/extensions.png"></a>
<div>
<h2><a href="extensions.html">Interactive Real-Time Data</a></h2>
<span>
Dig into continuously updating data. Change line interpolations, zoom in on the x-axis, apply smoothing, stack and un-stack, drag and drop to re-order the stack, toggle data on and off.
</span>
</div>
</section>
<section>
<a href="scatterplot.html"><img src="screenshots/scatterplot.png"></a>
<div>
<h2><a href="scatterplot.html">Scatter Plot with Multiple Series</a></h2>
<span>
Basic scatter plot with two overlapping series.
</span>
</div>
</section>
<section>
<a href="status.html"><img src="screenshots/status.png"></a>
<div>
<h2><a href="status.html">Stacked Bars with Deterministic Colors</a></h2>
<span>
Requests per second by HTTP status as stacked bars. Colors come from a deterministic palette that can carry across graphs.
</span>
</div>
</section>
<section>
<a href="colors.html"><img src="screenshots/colors.png"></a>
<div>
<h2><a href="colors.html">Color Schemes</a></h2>
<span>
A number of color schemes are built in. You can specify your own too.
</span>
</div>
</section>
<section>
<a href="stops.html"><img src="screenshots/stops.png"></a>
<div>
<h2><a href="stops.html">Interpolated Colors</a></h2>
<span>
Interpolate color schemes for graphs with many series.
</span>
</div>
</section>
<section>
<a href="ajax.html"><img src="screenshots/ajax.png"></a>
<div>
<h2><a href="ajax.html">Data via AJAX / JSONP</a></h2>
<span>
Ask Rickshaw to fetch data via AJAX, rather than specifying in the constructor. There's a JSONP impelementation too.
</span>
</div>
</section>
<section>
<a href="y_axis.html"><img src="screenshots/y_axis.png"></a>
<div>
<h2><a href="y_axis.html">Y-Axis Tick Marks and Grid Lines</a></h2>
<span>
Draw y-axis tick marks and grid lines with abbreviated numbers.
</span>
</div>
</section>
<section>
<a href="x_axis.html"><img src="screenshots/x_axis.png"></a>
<div>
<h2><a href="x_axis.html">Custom Values on the X-Axis</a></h2>
<span>
Add custom values and custom formatting along the x-axis.
</span>
</div>
</section>
<section>
<a href="fixed.html"><img src="screenshots/fixed.png"></a>
<div>
<h2><a href="fixed.html">Fixed Window Series for Streaming Data</a></h2>
<span>
Fixed-size time window, useful for real-time graphs with socket.io.
</span>
</div>
</section>
<section>
<a href="formatter.html"><img src="screenshots/formatter.png"></a>
<div>
<h2><a href="formatter.html">Hover Details Custom Formatting</a></h2>
<span>
Send a custom formatter callback for finer control in hover details.
</span>
</div>
</section>
<section>
<a href="hover.html"><img src="screenshots/hover.png"></a>
<div>
<h2><a href="hover.html">Subclassed Hover Behavior + Bottom Legend</a></h2>
<span>
Subclass hovers to provide an alternate legend at the bottom of the graph.
</span>
</div>
</section>
<section>
<a href="scaled.html"><img src="screenshots/scaled.png"></a>
<div>
<h2><a href="scaled.html">Scaled Series</a></h2>
<span>
Two series normalized with different scales, with two different scaled Y-axis.
</span>
</div>
</section>
<section>
<a href="logscale.html"><img src="screenshots/logscale.png"></a>
<div>
<h2><a href="logscale.html">Log and Absolute Scale</a></h2>
<span>
One series drawn using log and absolute scale on one graph.
</span>
</div>
</section>
<section>
<a href="multi.html"><img src="screenshots/multi.png"></a>
<div>
<h2><a href="multi.html">Multiple Renderers</a></h2>
<span>
Bars, lines, area, and scatterplot graphs all in one setting.
</span>
</div>
</section>
<hr>
<br>
</div>
<script src="../js/footer.js"></script>

View File

@@ -0,0 +1,76 @@
var RenderControls = function(args) {
var $ = jQuery;
this.initialize = function() {
this.element = args.element;
this.graph = args.graph;
this.settings = this.serialize();
this.inputs = {
renderer: this.element.elements.renderer
};
this.element.addEventListener('change', function(e) {
this.settings = this.serialize();
this.syncOptions();
this.settings = this.serialize();
var config = {
renderer: this.settings.renderer
};
this.graph.configure(config);
this.graph.render();
}.bind(this), false);
}
this.serialize = function() {
var values = {};
var pairs = $(this.element).serializeArray();
pairs.forEach( function(pair) {
values[pair.name] = pair.value;
} );
return values;
};
this.syncOptions = function() {
var options = this.rendererOptions[this.settings.renderer];
};
this.rendererOptions = {
area: {
interpolation: true,
offset: ['zero', 'wiggle', 'expand', 'value'],
defaults: { offset: 'zero' }
},
line: {
interpolation: true,
offset: ['expand', 'value'],
defaults: { offset: 'value' }
},
bar: {
interpolation: false,
offset: ['zero', 'wiggle', 'expand', 'value'],
defaults: { offset: 'zero' }
},
scatterplot: {
interpolation: false,
offset: ['value'],
defaults: { offset: 'value' }
}
};
this.initialize();
};

View File

@@ -0,0 +1,58 @@
<!doctype>
<head>
<link type="text/css" rel="stylesheet" href="../src/css/graph.css">
<link type="text/css" rel="stylesheet" href="css/lines.css">
<script src="../vendor/d3.v3.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.1/jquery.min.js"></script>
<script src="../rickshaw.js"></script>
</head>
<body>
<div id="chart_container">
<div id="chart"></div>
</div>
<script>
// subclass to hard-code callback name so we can call this in a static context
Rickshaw.Graph.JSONP.Static = Rickshaw.Class.create( Rickshaw.Graph.JSONP, {
request: function() {
$.ajax( {
url: this.dataURL,
success: this.success.bind(this),
error: this.error.bind(this),
dataType: 'jsonp',
jsonpCallback: 'callback'
} );
}
} );
var jsonpGraph = new Rickshaw.Graph.JSONP.Static( {
element: document.getElementById("chart"),
width: 400,
height: 200,
renderer: 'line',
dataURL: 'data/data.jsonp',
onData: function(d) { Rickshaw.Series.zeroFill(d); return d },
series: [
{
name: 'New York',
color: '#c05020',
}, {
name: 'London',
color: '#30c020',
}, {
name: 'Tokyo',
color: '#6060c0'
}
]
} );
</script>
</body>

View File

@@ -0,0 +1,88 @@
<!doctype>
<head>
<link type="text/css" rel="stylesheet" href="http://jqueryui.com/themes/base/jquery.ui.all.css">
<link type="text/css" rel="stylesheet" href="../src/css/graph.css">
<link type="text/css" rel="stylesheet" href="../src/css/detail.css">
<link type="text/css" rel="stylesheet" href="../src/css/legend.css">
<link type="text/css" rel="stylesheet" href="css/lines.css">
<script src="../vendor/d3.min.js"></script>
<script src="../vendor/d3.layout.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.15/jquery-ui.min.js"></script>
<script src="../rickshaw.js"></script>
</head>
<body>
<div id="chart_container">
<div id="chart"></div>
<div id="legend_container">
<div id="smoother" title="Smoothing"></div>
<div id="legend"></div>
</div>
<div id="slider"></div>
</div>
<script>
// set up our data series with 50 random data points
var seriesData = [ [], [], [] ];
var random = new Rickshaw.Fixtures.RandomData(150);
for (var i = 0; i < 150; i++) {
random.addData(seriesData);
}
// instantiate our graph!
var graph = new Rickshaw.Graph( {
element: document.getElementById("chart"),
width: 960,
height: 500,
renderer: 'area',
series: [
{
color: "#c05020",
data: seriesData[0],
name: 'New York'
}, {
color: "#30c020",
data: seriesData[1],
name: 'London'
}, {
color: "#6060c0",
data: seriesData[2],
name: 'Tokyo'
}
]
} );
graph.render();
var legend = new Rickshaw.Graph.Legend( {
graph: graph,
element: document.getElementById('legend')
} );
var shelving = new Rickshaw.Graph.Behavior.Series.Toggle( {
graph: graph,
legend: legend
} );
var order = new Rickshaw.Graph.Behavior.Series.Order( {
graph: graph,
legend: legend
} );
var highlight = new Rickshaw.Graph.Behavior.Series.Highlight( {
graph: graph,
legend: legend
} );
</script>
</body>

View File

@@ -0,0 +1,34 @@
<!doctype html>
<link type="text/css" rel="stylesheet" href="../rickshaw.css">
<script src="../vendor/d3.v3.js"></script>
<script src="../rickshaw.js"></script>
<div id="chart"></div>
<script>
var graph = new Rickshaw.Graph( {
width: 500,
element: document.getElementById("chart"),
renderer: 'lineplot',
padding: { top: 0.1 },
series: [
{
data: [ { x: 0, y: 40 }, { x: 1, y: 49 }, { x: 2, y: 38 }, { x: 3, y: 30 }, { x: 4, y: 32 } ],
color: 'steelblue',
name: "blue",
}, {
data: [ { x: 0, y: 19 }, { x: 1, y: 22 }, { x: 2, y: 32 }, { x: 3, y: 20 }, { x: 4, y: 21 } ],
color: 'lightblue',
name: "light blue"
}
]
} );
var hover = new Rickshaw.Graph.HoverDetail({ graph: graph });
graph.render();
</script>

View File

@@ -0,0 +1,82 @@
<!doctype>
<head>
<link type="text/css" rel="stylesheet" href="../src/css/graph.css">
<link type="text/css" rel="stylesheet" href="../src/css/detail.css">
<link type="text/css" rel="stylesheet" href="../src/css/legend.css">
<link type="text/css" rel="stylesheet" href="css/lines.css">
<script src="../vendor/d3.v3.js"></script>
<script src="../rickshaw.js"></script>
</head>
<body>
<div id="chart_container">
<div id="chart"></div>
<div id="legend_container">
<div id="smoother" title="Smoothing"></div>
<div id="legend"></div>
</div>
<div id="slider"></div>
</div>
<script>
// set up our data series with 50 random data points
var seriesData = [ [], [], [] ];
var random = new Rickshaw.Fixtures.RandomData(150);
for (var i = 0; i < 150; i++) {
random.addData(seriesData);
}
// instantiate our graph!
var graph = new Rickshaw.Graph( {
element: document.getElementById("chart"),
width: 960,
height: 500,
renderer: 'line',
series: [
{
color: "#c05020",
data: seriesData[0],
name: 'New York'
}, {
color: "#30c020",
data: seriesData[1],
name: 'London'
}, {
color: "#6060c0",
data: seriesData[2],
name: 'Tokyo'
}
]
} );
graph.render();
var hoverDetail = new Rickshaw.Graph.HoverDetail( {
graph: graph
} );
var legend = new Rickshaw.Graph.Legend( {
graph: graph,
element: document.getElementById('legend')
} );
var shelving = new Rickshaw.Graph.Behavior.Series.Toggle( {
graph: graph,
legend: legend
} );
var axes = new Rickshaw.Graph.Axis.Time( {
graph: graph
} );
axes.render();
</script>
</body>

View File

@@ -0,0 +1,100 @@
<!doctype html>
<link type="text/css" rel="stylesheet" href="../src/css/graph.css">
<link type="text/css" rel="stylesheet" href="css/lines.css">
<link type="text/css" rel="stylesheet" href="../src/css/detail.css">
<script src="../vendor/d3.v3.js"></script>
<script src="../rickshaw.js"></script>
<style>
#chart {
position: relative;
left: 40px;
width: 800px;
height: 300px;
}
#y_axis {
position: absolute;
top: 0;
bottom: 0;
width: 40px;
}
#y_axis_2 {
position: absolute;
top: 0;
left: 840px;
width: 40px;
}
</style>
<div id="chart_container">
<div id="y_axis"></div>
<div id="chart"></div>
<div id="y_axis_2"></div>
</div>
<script>
var random = new Rickshaw.Fixtures.RandomData(12 * 60 * 60);
var series = [[]];
for (var i = 0; i < 300; i++) {
random.addData(series);
}
var data = series[0]
var min = Number.MAX_VALUE;
var max = Number.MIN_VALUE;
for (i = 0; i < series[0].length; i++) {
min = Math.min(min, series[0][i].y);
max = Math.max(max, series[0][i].y);
}
var logScale = d3.scale.log().domain([min/4, max]);
var linearScale = d3.scale.linear().domain([min, max]).range(logScale.range());
var graph = new Rickshaw.Graph( {
element: document.getElementById("chart"),
renderer: 'line',
series: [
{
color: 'blue',
data: JSON.parse(JSON.stringify(data)),
name: 'Log View',
scale: logScale
},
{
color: 'red',
data: JSON.parse(JSON.stringify(data)),
name: 'Linear View',
scale: linearScale
}
]
} );
new Rickshaw.Graph.Axis.Y.Scaled( {
graph: graph,
orientation: 'left',
tickFormat: Rickshaw.Fixtures.Number.formatKMBT,
element: document.getElementById('y_axis'),
scale: logScale
} );
new Rickshaw.Graph.Axis.Y.Scaled( {
graph: graph,
orientation: 'right',
tickFormat: Rickshaw.Fixtures.Number.formatKMBT,
element: document.getElementById('y_axis_2'),
scale: linearScale,
grid: false
} );
new Rickshaw.Graph.HoverDetail(
{
graph: graph
} );
graph.render();
</script>

View File

@@ -0,0 +1,69 @@
<!doctype>
<head>
<link type="text/css" rel="stylesheet" href="../rickshaw.css">
<script src="../vendor/d3.v3.js"></script>
<script src="../rickshaw.js"></script>
</head>
<body>
<div id="chart_container">
<div id="chart"></div>
<div id="legend_container">
<div id="smoother" title="Smoothing"></div>
<div id="legend"></div>
</div>
<div id="slider"></div>
</div>
<script>
// set up our data series with 50 random data points
var seriesData = [ [], [], [] ];
var random = new Rickshaw.Fixtures.RandomData(0.01);
for (var i = 0; i < 150; i++) {
random.addData(seriesData);
}
// instantiate our graph!
var graph = new Rickshaw.Graph( {
element: document.getElementById("chart"),
width: 960,
height: 500,
renderer: 'line',
series: [
{
color: "#c05020",
data: seriesData[0],
name: 'New York'
}, {
color: "#30c020",
data: seriesData[1],
name: 'London'
}, {
color: "#6060c0",
data: seriesData[2],
name: 'Tokyo'
}
]
} );
graph.render();
var hoverDetail = new Rickshaw.Graph.HoverDetail( {
graph: graph
} );
var axes = new Rickshaw.Graph.Axis.Time( {
graph: graph,
timeFixture: new Rickshaw.Fixtures.Time.Local()
} );
axes.render();
</script>
</body>

View File

@@ -0,0 +1,102 @@
<!doctype html>
<head>
<link type="text/css" rel="stylesheet" href="../rickshaw.css">
<link type="text/css" rel="stylesheet" href="css/lines.css">
<link type="text/css" rel="stylesheet" href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8/themes/base/jquery-ui.css">
<script src="../vendor/d3.v3.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.15/jquery-ui.min.js"></script>
<script src="../rickshaw.js"></script>
<style>
.column { display: inline-block }
#legend { background: white }
#legend .line { color: #333 }
</style>
</head>
<body>
<div class="column">
<div id="chart"></div>
<div id="slider"></div>
</div>
<div class="column" id="legend"></div>
<script>
var seriesData = [ [], [], [], [], [] ];
var random = new Rickshaw.Fixtures.RandomData(50);
for (var i = 0; i < 75; i++) {
random.addData(seriesData);
}
var graph = new Rickshaw.Graph( {
element: document.getElementById("chart"),
renderer: 'multi',
width: 900,
height: 500,
dotSize: 2,
series: [
{
name: 'temperature',
data: seriesData.shift(),
color: 'rgba(255, 0, 0, 0.4)',
renderer: 'stack'
}, {
name: 'heat index',
data: seriesData.shift(),
color: 'rgba(255, 127, 0, 0.4)',
renderer: 'stack'
}, {
name: 'dewpoint',
data: seriesData.shift(),
color: 'rgba(127, 0, 0, 0.3)',
renderer: 'scatterplot'
}, {
name: 'pop',
data: seriesData.shift().map(function(d) { return { x: d.x, y: d.y / 4 } }),
color: 'rgba(0, 0, 127, 0.4)',
renderer: 'bar'
}, {
name: 'humidity',
data: seriesData.shift().map(function(d) { return { x: d.x, y: d.y * 1.5 } }),
renderer: 'line',
color: 'rgba(0, 0, 127, 0.25)'
}
]
} );
var slider = new Rickshaw.Graph.RangeSlider({
graph: graph,
element: $('#slider')
});
graph.render();
var detail = new Rickshaw.Graph.HoverDetail({
graph: graph
});
var legend = new Rickshaw.Graph.Legend({
graph: graph,
element: document.querySelector('#legend')
});
var highlighter = new Rickshaw.Graph.Behavior.Series.Highlight({
graph: graph,
legend: legend,
disabledColor: function() { return 'rgba(0, 0, 0, 0.2)' }
});
var highlighter = new Rickshaw.Graph.Behavior.Series.Toggle({
graph: graph,
legend: legend
});
</script>
</body>

View File

@@ -0,0 +1,32 @@
<!doctype>
<link type="text/css" rel="stylesheet" href="../src/css/graph.css">
<link type="text/css" rel="stylesheet" href="css/lines.css">
<script src="../vendor/d3.v3.js"></script>
<script src="../rickshaw.js"></script>
<div id="chart"></div>
<script>
var graph = new Rickshaw.Graph({
unstack: true,
element: document.querySelector("#chart"),
width: 580,
height: 250,
min: 'auto',
renderer: 'bar',
series: [ {
color: 'steelblue',
data: [ { x: 0, y: 20 }, { x: 1, y: 3 }, { x: 2, y: 15 }, { x: 3, y: 42 } ]
}, {
color: 'tomato',
data: [ { x: 0, y: 12 }, { x: 1, y: -20 }, { x: 2, y: 18 }, { x: 3, y: 8 } ]
} ]
});
graph.render();
</script>

View File

@@ -0,0 +1,50 @@
<!doctype html>
<head>
<link type="text/css" rel="stylesheet" href="../rickshaw.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.1/jquery.min.js"></script>
<script src="../vendor/d3.v3.js"></script>
<script src="../rickshaw.js"></script>
</head>
<body>
<div id="chart_container">
<div id="chart"></div>
<button id="refresh">refresh</button>
</div>
<script>
var dataURLs = ['data/data.json', 'data/data2.json'];
var ajaxGraph = new Rickshaw.Graph.Ajax( {
element: document.getElementById("chart"),
width: 400,
height: 200,
renderer: 'line',
dataURL: 'data/data.json',
series: [
{
name: 'New York',
color: '#c05020',
}, {
name: 'London',
color: '#30c020',
}, {
name: 'Tokyo',
color: '#6060c0'
}
]
} );
document.querySelector('#refresh').addEventListener('click', function() {
ajaxGraph.dataURL = ajaxGraph.dataURL === dataURLs[0] ? dataURLs[1] : dataURLs[0];
ajaxGraph.request();
});
</script>
</body>

View File

@@ -0,0 +1,38 @@
<!doctype html>
<link type="text/css" rel="stylesheet" href="../src/css/graph.css">
<link type="text/css" rel="stylesheet" href="css/lines.css">
<script src="../vendor/d3.v3.js"></script>
<script src="../rickshaw.min.js"></script>
<div id="chart"></div>
<script>
var graph = new Rickshaw.Graph( {
element: document.getElementById("chart"),
renderer: 'area',
series: [
{
data: [ { x: 0, y: 40 }, { x: 1, y: 49 }, { x: 2, y: 38 }, { x: 3, y: 30 }, { x: 4, y: 32 } ],
color: 'steelblue'
}, {
data: [ { x: 0, y: 19 }, { x: 1, y: 22 }, { x: 2, y: 32 }, { x: 3, y: 20 }, { x: 4, y: 21 } ],
color: 'lightblue'
}
]
} );
var resize = function() {
var padding = 40;
graph.configure({
width: window.innerWidth - padding,
height: window.innerHeight - padding
});
graph.render();
}
window.addEventListener('resize', resize);
resize();
</script>

View File

@@ -0,0 +1,109 @@
<!doctype html>
<link type="text/css" rel="stylesheet" href="../src/css/graph.css">
<link type="text/css" rel="stylesheet" href="../src/css/detail.css">
<link type="text/css" rel="stylesheet" href="css/lines.css">
<script src="../vendor/d3.v3.js"></script>
<script src="../rickshaw.js"></script>
<style type="text/css">
#axis0 {
position: absolute;
height: 800px;
width: 40px;
}
#axis1 {
position: absolute;
left: 1050px;
height: 800px;
width: 40px;
}
#chart {
left: 50px;
width: 1000px;
position: absolute;
}
</style>
<div id="axis0"></div>
<div id="chart"></div>
<div id="axis1"></div>
<script type="text/javascript">
var data, graph, i, max, min, point, random, scales, series, _i, _j, _k, _l, _len, _len1, _len2, _ref;
data = [[], []];
random = new Rickshaw.Fixtures.RandomData(12 * 60 * 60);
for (i = _i = 0; _i < 100; i = ++_i) {
random.addData(data);
}
scales = [];
_ref = data[1];
for (_j = 0, _len = _ref.length; _j < _len; _j++) {
point = _ref[_j];
point.y *= point.y;
}
for (_k = 0, _len1 = data.length; _k < _len1; _k++) {
series = data[_k];
min = Number.MAX_VALUE;
max = Number.MIN_VALUE;
for (_l = 0, _len2 = series.length; _l < _len2; _l++) {
point = series[_l];
min = Math.min(min, point.y);
max = Math.max(max, point.y);
}
if (_k === 0) {
scales.push(d3.scale.linear().domain([min, max]).nice());
} else {
scales.push(d3.scale.pow().domain([min, max]).nice());
}
}
graph = new Rickshaw.Graph({
element: document.getElementById("chart"),
renderer: 'line',
series: [
{
color: 'steelblue',
data: data[0],
name: 'Series A',
scale: scales[0]
}, {
color: 'lightblue',
data: data[1],
name: 'Series B',
scale: scales[1]
}
]
});
new Rickshaw.Graph.Axis.Y.Scaled({
element: document.getElementById('axis0'),
graph: graph,
orientation: 'left',
scale: scales[0],
tickFormat: Rickshaw.Fixtures.Number.formatKMBT
});
new Rickshaw.Graph.Axis.Y.Scaled({
element: document.getElementById('axis1'),
graph: graph,
grid: false,
orientation: 'right',
scale: scales[1],
tickFormat: Rickshaw.Fixtures.Number.formatKMBT
});
new Rickshaw.Graph.Axis.Time({
graph: graph
});
new Rickshaw.Graph.HoverDetail({
graph: graph
});
graph.render();
</script>

View File

@@ -0,0 +1,46 @@
<!doctype html>
<link type="text/css" rel="stylesheet" href="../rickshaw.css">
<script src="../vendor/d3.v3.js"></script>
<script src="../rickshaw.js"></script>
<div id="chart"></div>
<script>
// set up our data series with 50 random data points
var seriesData = [ [], [], [] ];
var random = new Rickshaw.Fixtures.RandomData(150);
for (var i = 0; i < 500; i++) {
random.addData(seriesData);
}
// instantiate our graph!
var graph = new Rickshaw.Graph( {
element: document.getElementById("chart"),
width: 960,
height: 500,
renderer: 'scatterplot',
series: [
{
color: "#ff9030",
data: seriesData[0],
}, {
color: "#ff4040",
data: seriesData[1],
}
]
} );
graph.renderer.dotSize = 6;
new Rickshaw.Graph.HoverDetail({ graph: graph });
graph.render();
</script>

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 158 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 108 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 65 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

View File

@@ -0,0 +1,166 @@
<!doctype>
<head>
<link type="text/css" rel="stylesheet" href="http://jqueryui.com/themes/base/jquery.ui.all.css">
<link type="text/css" rel="stylesheet" href="../src/css/graph.css">
<link type="text/css" rel="stylesheet" href="../src/css/detail.css">
<link type="text/css" rel="stylesheet" href="../src/css/legend.css">
<link type="text/css" rel="stylesheet" href="css/extensions.css">
<script src="../vendor/d3.v3.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.15/jquery-ui.min.js"></script>
<script src="../src/js/Rickshaw.js"></script>
<script src="../src/js/Rickshaw.Class.js"></script>
<script src="../src/js/Rickshaw.Graph.js"></script>
<script src="../src/js/Rickshaw.Graph.Renderer.js"></script>
<script src="../src/js/Rickshaw.Graph.Renderer.Stack.js"></script>
<script src="../src/js/Rickshaw.Graph.Renderer.Line.js"></script>
<script src="../src/js/Rickshaw.Graph.RangeSlider.js"></script>
<script src="../src/js/Rickshaw.Graph.HoverDetail.js"></script>
<script src="../src/js/Rickshaw.Graph.Annotate.js"></script>
<script src="../src/js/Rickshaw.Graph.Legend.js"></script>
<script src="../src/js/Rickshaw.Graph.Axis.Time.js"></script>
<script src="../src/js/Rickshaw.Graph.Behavior.Series.Toggle.js"></script>
<script src="../src/js/Rickshaw.Graph.Behavior.Series.Order.js"></script>
<script src="../src/js/Rickshaw.Graph.Behavior.Series.Highlight.js"></script>
<script src="../src/js/Rickshaw.Graph.Smoother.js"></script>
<script src="../src/js/Rickshaw.Graph.Unstacker.js"></script>
<script src="../src/js/Rickshaw.Fixtures.Time.js"></script>
<script src="../src/js/Rickshaw.Fixtures.RandomData.js"></script>
<script src="../src/js/Rickshaw.Fixtures.Color.js"></script>
<script src="../src/js/Rickshaw.Color.Palette.js"></script>
<script src="../src/js/Rickshaw.Series.js"></script>
</head>
<body>
<div id="content">
<div id="side_panel">
<h1>Random Data in the Future</h1>
<section><div id="legend"></div></section>
<section>
<form id="offset_form">
<input type="radio" name="offset" id="stack" value="zero" checked>
<label for="stack">stack</label>
<input type="radio" name="offset" id="percent" value="expand">
<label for="percent">percent</label>
<input type="radio" name="offset" id="stream" value="silhouette">
<label for="stream">stream</label>
<input type="radio" name="offset" id="lines" value="lines">
<label for="lines">lines</label>
</form>
</section>
<section>
<h6>Smoothing</h6>
<div id="smoother"></div>
</section>
<section></section>
</div>
<div id="chart_container">
<div id="chart"></div>
<div id="timeline"></div>
<div id="slider"></div>
</div>
</div>
<script>
// instantiate our graph!
var graph = new Rickshaw.Graph( {
element: document.getElementById("chart"),
width: 900,
height: 500,
interpolation: 'step-after',
series: new Rickshaw.Series([{ name: 'This' }])
} );
var slider = new Rickshaw.Graph.RangeSlider( {
graph: graph,
element: $('#slider')
} );
var hoverDetail = new Rickshaw.Graph.HoverDetail( {
graph: graph
} );
var annotator = new Rickshaw.Graph.Annotate( {
graph: graph,
element: document.getElementById('timeline')
} );
var legend = new Rickshaw.Graph.Legend( {
graph: graph,
element: document.getElementById('legend')
} );
var shelving = new Rickshaw.Graph.Behavior.Series.Toggle( {
graph: graph,
legend: legend
} );
// a little monkey punching
legend.shelving = shelving;
graph.series.legend = legend;
var order = new Rickshaw.Graph.Behavior.Series.Order( {
graph: graph,
legend: legend
} );
var highlighter = new Rickshaw.Graph.Behavior.Series.Highlight( {
graph: graph,
legend: legend
} );
var axes = new Rickshaw.Graph.Axis.Time( {
graph: graph
} );
axes.render();
var smoother = new Rickshaw.Graph.Smoother( {
graph: graph,
element: $('#smoother')
} );
var offset_form = document.getElementById('offset_form');
offset_form.addEventListener("change", function(e) {
var offsetMode = e.target.value;
if (offsetMode == 'lines') {
graph.setRenderer('line');
graph.offset = 'zero';
} else {
graph.setRenderer('stack');
graph.offset = offsetMode;
}
graph.update();
}, false );
// add some data every so often
var tv = 1000;
graph.series.setTimeInterval(tv);
setInterval( function() {
var data = { This: 3 };
var randInt = Math.floor(Math.random()*100);
if (randInt > 10) {
data.That = randInt;
}
if (randInt > 15) {
data.TheOtherThing = randInt;
}
graph.series.addData(data);
graph.update();
}, tv );
</script>
</body>

View File

@@ -0,0 +1,29 @@
<!doctype>
<link type="text/css" rel="stylesheet" href="../src/css/graph.css">
<link type="text/css" rel="stylesheet" href="css/lines.css">
<script src="../vendor/d3.v3.js"></script>
<script src="../rickshaw.min.js"></script>
<div id="chart"></div>
<script>
var graph = new Rickshaw.Graph( {
element: document.getElementById("chart"),
renderer: 'line',
series: [
{
data: [ { x: 0, y: 40 }, { x: 1, y: 49 }, { x: 2, y: 38 }, { x: 3, y: 30 }, { x: 4, y: 32 } ],
color: 'steelblue'
}, {
data: [ { x: 0, y: 19 }, { x: 1, y: 22 }, { x: 2, y: 32 }, { x: 3, y: 20 }, { x: 4, y: 21 } ],
color: 'lightblue'
}
]
} );
graph.render();
</script>

View File

@@ -0,0 +1,13 @@
# Rickshaw + Socket.io
Just a simple example for Websockets support using Rickshaw + Socket.io
# Usage
```
cd examples/socket.io
npm install
node app.js
```
Then visit `http://localhost:8000` to see your graphs updated every second.

View File

@@ -0,0 +1,41 @@
express = require('express');
app = express();
server = require('http').createServer(app)
io = require('socket.io').listen(server);
path = require('path');
server.listen(8000, function() {
console.log("Started a server on port 8000");
});
app.use(express.static(path.join(__dirname, '../../')));
app.get('/', function (req, res) {
res.sendfile(__dirname + '/socket.io.html');
});
io.sockets.on('connection', function (socket) {
incr = 0;
var sendData = function() {
data = [
{
"color": "blue",
"name": "New York",
"data": [ { "x": 0, "y": incr }, { "x": 1, "y": 49 }, { "x": 2, "y": 38 }, { "x": 3, "y": 30 }, { "x": 4, "y": 32 } ]
}, {
"color": "red",
"name": "London",
"data": [ { "x": 0, "y": 19 }, { "x": 1, "y": incr }, { "x": 2, "y": 29 }, { "x": 3, "y": 20 }, { "x": 4, "y": 14 } ]
}, {
"color": "black",
"name": "Tokyo",
"data": [ { "x": 0, "y": 8 }, { "x": 1, "y": 12 }, { "x": 2, "y": incr }, { "x": 3, "y": 11 }, { "x": 4, "y": 10 } ]
}
]
socket.emit('rickshaw', data);
incr++;
}
var run = setInterval(sendData, 1000);
socket.on('disconnect', function() {
clearInterval(run);
});
});

View File

@@ -0,0 +1,16 @@
{
"name": "rickshaw-socket.io",
"version": "0.0.1",
"description": "Rickshaw socket.io support",
"main": "app.js",
"private": true,
"scripts": {
"start": "node app.js"
},
"dependencies": {
"express": "3.3.5",
"socket.io": "~0.9.16"
},
"author": "Alex Williams, Unscramble <license@unscramble.jp>",
"license": "MIT"
}

View File

@@ -0,0 +1,44 @@
<!doctype html>
<head>
<link type="text/css" rel="stylesheet" href="../src/css/graph.css">
<link type="text/css" rel="stylesheet" href="../examples/css/lines.css">
<script src="../vendor/d3.v2.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.1/jquery.min.js"></script>
<script src="/socket.io/socket.io.js"></script>
<script src="../rickshaw.js"></script>
</head>
<body>
<div id="chart_container">
<div id="chart"></div>
</div>
<script>
Rickshaw.Graph.Socketio.Static = Rickshaw.Class.create( Rickshaw.Graph.Socketio, {
request: function() {
var socket = io.connect(this.dataURL);
thisData = this;
socket.on('rickshaw', function (data) {
console.log("Got some fancy Websocket data: ");
console.log(data);
thisData.success(data);
});
}
} );
var socketioGraph = new Rickshaw.Graph.Socketio.Static( {
element: document.getElementById("chart"),
width: 400,
height: 200,
renderer: 'line',
dataURL: "http://localhost",
onData: function(d) { Rickshaw.Series.zeroFill(d); return d }
} );
</script>
</body>

View File

@@ -0,0 +1,58 @@
<!doctype>
<head>
<link type="text/css" rel="stylesheet" href="../src/css/graph.css">
<link type="text/css" rel="stylesheet" href="../src/css/detail.css">
<link type="text/css" rel="stylesheet" href="../src/css/legend.css">
<link type="text/css" rel="stylesheet" href="css/lines.css">
<script src="../vendor/d3.v3.js"></script>
<script src="../rickshaw.js"></script>
</head>
<body>
<div id="chart_container">
<div id="chart"></div>
<div id="legend_container">
<div id="smoother" title="Smoothing"></div>
<div id="legend"></div>
</div>
<div id="slider"></div>
</div>
<script>
// set up our data series with 50 random data points
var seriesData = [ [], [], [] ];
var random = new Rickshaw.Fixtures.RandomData(150);
for (var i = 0; i < 150; i++) {
random.addData(seriesData);
}
// instantiate our graph!
var graph = new Rickshaw.Graph( {
element: document.getElementById("chart"),
width: 960,
height: 500,
renderer: 'line',
series: [
{
color: "steelblue",
name: 'New York',
data: [ { x: 0, y: 15 }, { x: 100, y: 20 }, { x: 200, y: 22 }, { x: 300, y: 25 }, { x: 380, y: 24 }, { x: 400, y: 22 }, { x: 420, y: 25 } ],
}
]
} );
graph.render();
var hoverDetail = new Rickshaw.Graph.HoverDetail( {
graph: graph
} );
</script>
</body>

View File

@@ -0,0 +1,26 @@
<!doctype html>
<script src="../vendor/d3.v3.js"></script>
<script src="../rickshaw.min.js"></script>
<div id="chart"></div>
<script>
var graph = new Rickshaw.Graph( {
element: document.querySelector("#chart"),
width: 500,
height: 200,
series: [{
color: 'steelblue',
data: [
{ x: 0, y: 40 },
{ x: 1, y: 49 },
{ x: 2, y: 38 },
{ x: 3, y: 30 },
{ x: 4, y: 32 } ]
}]
});
graph.render();
</script>

View File

@@ -0,0 +1,58 @@
<!doctype>
<link type="text/css" rel="stylesheet" href="../src/css/graph.css">
<link type="text/css" rel="stylesheet" href="../src/css/legend.css">
<link type="text/css" rel="stylesheet" href="css/extensions.css">
<script src="../vendor/d3.v3.js"></script>
<script src="../rickshaw.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.15/jquery-ui.min.js"></script>
<div id="chart"></div>
<div id="legend"></div>
<script>
var palette = new Rickshaw.Color.Palette( { scheme: 'httpStatus' } );
var wrapper = new Rickshaw.Graph.Ajax( {
element: document.getElementById("chart"),
dataURL: 'data/status.json',
width: 960,
height: 500,
renderer: 'bar',
onData: function(d) { return transformData(d) },
onComplete: function(w) {
var legend = new Rickshaw.Graph.Legend( {
element: document.querySelector('#legend'),
graph: w.graph
} );
}
} );
function transformData(d) {
var data = [];
var statusCounts = {};
Rickshaw.keys(d).sort().forEach( function(t) {
Rickshaw.keys(d[t]).forEach( function(status) {
statusCounts[status] = statusCounts[status] || [];
statusCounts[status].push( { x: parseFloat(t), y: d[t][status] } );
} );
} );
Rickshaw.keys(statusCounts).sort().forEach( function(status) {
data.push( {
name: status,
data: statusCounts[status],
color: palette.color(status)
} );
} );
Rickshaw.Series.zeroFill(data);
return data;
}
</script>

View File

@@ -0,0 +1,90 @@
<!doctype>
<head>
<link type="text/css" rel="stylesheet" href="../src/css/graph.css">
<link type="text/css" rel="stylesheet" href="../src/css/detail.css">
<link type="text/css" rel="stylesheet" href="../src/css/legend.css">
<script src="../vendor/d3.v3.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js"></script>
<script src="../rickshaw.js"></script>
<style>
body {
font-family: Arial, sans-serif
}
#chart_container {
width: 960px;
}
.swatch {
display: inline-block;
width: 10px;
height: 10px;
margin: 0 8px 0 0;
}
.label {
display: inline-block;
}
.line {
display: inline-block;
margin: 0 0 0 30px;
}
#legend {
text-align: center;
}
.rickshaw_graph .detail {
background: none;
}
</style>
</head>
<body>
<div id="chart_container">
<div id="chart"></div><br>
<div id="legend"></div>
</div>
<script>
// set up our data series with 50 random data points
var seriesData = [];
for (i = 0; i < 50; i++) {
seriesData.push([]);
}
var random = new Rickshaw.Fixtures.RandomData(150);
for (var i = 0; i < 150; i++) {
random.addData(seriesData);
}
// instantiate our graph!
var palette = new Rickshaw.Color.Palette( { scheme: 'spectrum2001', interpolatedStopCount: 4 } );
var series = seriesData.map(function(s) {
return {
data: s,
color: palette.color()
}
});
var graph = new Rickshaw.Graph( {
element: document.getElementById("chart"),
width: 960,
height: 500,
stroke: true,
renderer: 'area',
series: series
} );
graph.render();
var legend = document.querySelector('#legend');
</script>
</body>

View File

@@ -0,0 +1,56 @@
<!doctype html>
<link type="text/css" rel="stylesheet" href="../src/css/graph.css">
<link type="text/css" rel="stylesheet" href="css/lines.css">
<script src="../vendor/d3.v3.js"></script>
<script src="../rickshaw.min.js"></script>
<div id="chart"></div>
<div id="slider"></div>
<script>
var seriesData = [ [], [] ];
var random = new Rickshaw.Fixtures.RandomData(1500000);
for (var i = 0; i < 900; i++) {
random.addData(seriesData);
}
var graph = new Rickshaw.Graph({
element: document.getElementById("chart"),
width: 960,
height: 500,
stroke: true,
strokeWidth: 0.5,
renderer: 'area',
xScale: d3.time.scale(),
yScale: d3.scale.sqrt(),
series:[
{ color: 'steelblue', data: seriesData[0] },
{ color: '#99d4ee', data: seriesData[1] }
]
});
graph.render();
var xAxis = new Rickshaw.Graph.Axis.X({
graph: graph,
tickFormat: graph.x.tickFormat()
});
xAxis.render();
var yAxis = new Rickshaw.Graph.Axis.Y({
graph: graph
});
yAxis.render();
var slider = new Rickshaw.Graph.RangeSlider.Preview({
graph: graph,
element: document.getElementById('slider')
});
</script>

View File

@@ -0,0 +1,80 @@
<!doctype html>
<link type="text/css" rel="stylesheet" href="../src/css/graph.css">
<link type="text/css" rel="stylesheet" href="css/lines.css">
<script src="../vendor/d3.v3.js"></script>
<script src="../rickshaw.js"></script>
<style>
#chart {
position: relative;
left: 40px;
display: block;
}
#y_axis {
position: absolute;
top: 0;
bottom: 0;
width: 40px;
}
#x_axis {
position: relative;
left: 40px;
height: 40px;
}
</style>
<div id="chart_container">
<div id="y_axis"></div>
<div id="chart"></div>
<div id="x_axis"></div>
</div>
<script>
// instantiate our graph!
var graph = new Rickshaw.Graph( {
element: document.getElementById("chart"),
renderer: 'line',
height: 300,
width: 800,
series: [
{
data: [ { x: 0, y: 120 }, { x: 1, y: 890 }, { x: 2, y: 38 }, { x: 3, y: 70 }, { x: 4, y: 32 } ],
color: "#c05020"
}, {
data: [ { x: 0, y: 80 }, { x: 1, y: 200 }, { x: 2, y: 100 }, { x: 3, y: 520 }, { x: 4, y: 133 } ],
color: "#30c020"
}, {
data: [ { x: 0, y: 200 }, { x: 1, y: 390 }, { x: 2, y: 1000 }, { x: 3, y: 200 }, { x: 4, y: 230 } ],
color: "#6060c0"
}
]
} );
var format = function(n) {
var map = {
0: 'zero',
1: 'first',
2: 'second',
3: 'third',
4: 'fourth'
};
return map[n];
}
var x_ticks = new Rickshaw.Graph.Axis.X( {
graph: graph,
orientation: 'bottom',
element: document.getElementById('x_axis'),
pixelsPerTick: 200,
tickFormat: format
} );
graph.render();
</script>

View File

@@ -0,0 +1,60 @@
<!doctype>
<link type="text/css" rel="stylesheet" href="../src/css/graph.css">
<link type="text/css" rel="stylesheet" href="css/lines.css">
<script src="../vendor/d3.v3.js"></script>
<script src="../rickshaw.js"></script>
<style>
#chart {
position: relative;
left: 40px;
}
#y_axis {
position: absolute;
top: 0;
bottom: 0;
width: 40px;
}
</style>
<div id="chart_container">
<div id="y_axis"></div>
<div id="chart"></div>
</div>
<script>
// instantiate our graph!
var graph = new Rickshaw.Graph( {
element: document.getElementById("chart"),
renderer: 'line',
height: 300,
width: 800,
series: [
{
data: [ { x: 0, y: 120 }, { x: 1, y: 890 }, { x: 2, y: 38 }, { x: 3, y: 70 }, { x: 4, y: 32 } ],
color: "#c05020"
}, {
data: [ { x: 0, y: 80 }, { x: 1, y: 200 }, { x: 2, y: 100 }, { x: 3, y: 520 }, { x: 4, y: 133 } ],
color: "#30c020"
}, {
data: [ { x: 0, y: 200 }, { x: 1, y: 390 }, { x: 2, y: 1000 }, { x: 3, y: 200 }, { x: 4, y: 230 } ],
color: "#6060c0"
}
]
} );
var y_ticks = new Rickshaw.Graph.Axis.Y( {
graph: graph,
orientation: 'left',
tickFormat: Rickshaw.Fixtures.Number.formatKMBT,
element: document.getElementById('y_axis'),
} );
graph.render();
</script>

View File

@@ -0,0 +1,351 @@
.rickshaw_graph .detail {
pointer-events: none;
position: absolute;
top: 0;
z-index: 2;
background: rgba(0, 0, 0, 0.1);
bottom: 0;
width: 1px;
transition: opacity 0.25s linear;
-moz-transition: opacity 0.25s linear;
-o-transition: opacity 0.25s linear;
-webkit-transition: opacity 0.25s linear;
}
.rickshaw_graph .detail.inactive {
opacity: 0;
}
.rickshaw_graph .detail .item.active {
opacity: 1;
}
.rickshaw_graph .detail .x_label {
font-family: Arial, sans-serif;
border-radius: 3px;
padding: 6px;
opacity: 0.5;
border: 1px solid #e0e0e0;
font-size: 12px;
position: absolute;
background: white;
white-space: nowrap;
}
.rickshaw_graph .detail .x_label.left {
left: 0;
}
.rickshaw_graph .detail .x_label.right {
right: 0;
}
.rickshaw_graph .detail .item {
position: absolute;
z-index: 2;
border-radius: 3px;
padding: 0.25em;
font-size: 12px;
opacity: 0;
background: rgba(0, 0, 0, 0.4);
color: white;
border: 1px solid rgba(0, 0, 0, 0.4);
margin-left: 1em;
margin-right: 1em;
margin-top: -1em;
white-space: nowrap;
}
.rickshaw_graph .detail .item.left {
left: 0;
}
.rickshaw_graph .detail .item.right {
right: 0;
}
.rickshaw_graph .detail .item.active {
opacity: 1;
background: rgba(0, 0, 0, 0.8);
}
.rickshaw_graph .detail .item:after {
position: absolute;
display: block;
width: 0;
height: 0;
content: "";
border: 5px solid transparent;
}
.rickshaw_graph .detail .item.left:after {
top: 1em;
left: -5px;
margin-top: -5px;
border-right-color: rgba(0, 0, 0, 0.8);
border-left-width: 0;
}
.rickshaw_graph .detail .item.right:after {
top: 1em;
right: -5px;
margin-top: -5px;
border-left-color: rgba(0, 0, 0, 0.8);
border-right-width: 0;
}
.rickshaw_graph .detail .dot {
width: 4px;
height: 4px;
margin-left: -2px;
margin-top: -2px;
border-radius: 5px;
position: absolute;
box-shadow: 0 0 2px rgba(0, 0, 0, 0.6);
background: white;
border-width: 2px;
border-style: solid;
display: none;
background-clip: padding-box;
}
.rickshaw_graph .detail .dot.active {
display: block;
}
/* graph */
.rickshaw_graph {
position: relative;
}
.rickshaw_graph svg {
display: block;
overflow: hidden;
}
/* ticks */
.rickshaw_graph .x_tick {
position: absolute;
top: 0;
bottom: 0;
width: 0px;
border-left: 1px dotted rgba(0, 0, 0, 0.2);
pointer-events: none;
}
.rickshaw_graph .x_tick .title {
position: absolute;
font-size: 12px;
font-family: Arial, sans-serif;
opacity: 0.5;
white-space: nowrap;
margin-left: 3px;
bottom: 1px;
}
/* annotations */
.rickshaw_annotation_timeline {
height: 1px;
border-top: 1px solid #e0e0e0;
margin-top: 10px;
position: relative;
}
.rickshaw_annotation_timeline .annotation {
position: absolute;
height: 6px;
width: 6px;
margin-left: -2px;
top: -3px;
border-radius: 5px;
background-color: rgba(0, 0, 0, 0.25);
}
.rickshaw_graph .annotation_line {
position: absolute;
top: 0;
bottom: -6px;
width: 0px;
border-left: 2px solid rgba(0, 0, 0, 0.3);
display: none;
}
.rickshaw_graph .annotation_line.active {
display: block;
}
.rickshaw_graph .annotation_range {
background: rgba(0, 0, 0, 0.1);
display: none;
position: absolute;
top: 0;
bottom: -6px;
}
.rickshaw_graph .annotation_range.active {
display: block;
}
.rickshaw_graph .annotation_range.active.offscreen {
display: none;
}
.rickshaw_annotation_timeline .annotation .content {
background: white;
color: black;
opacity: 0.9;
padding: 5px 5px;
box-shadow: 0 0 2px rgba(0, 0, 0, 0.8);
border-radius: 3px;
position: relative;
z-index: 20;
font-size: 12px;
padding: 6px 8px 8px;
top: 18px;
left: -11px;
width: 160px;
display: none;
cursor: pointer;
}
.rickshaw_annotation_timeline .annotation .content:before {
content: "\25b2";
position: absolute;
top: -11px;
color: white;
text-shadow: 0 -1px 1px rgba(0, 0, 0, 0.8);
}
.rickshaw_annotation_timeline .annotation.active,
.rickshaw_annotation_timeline .annotation:hover {
background-color: rgba(0, 0, 0, 0.8);
cursor: none;
}
.rickshaw_annotation_timeline .annotation .content:hover {
z-index: 50;
}
.rickshaw_annotation_timeline .annotation.active .content {
display: block;
}
.rickshaw_annotation_timeline .annotation:hover .content {
display: block;
z-index: 50;
}
.rickshaw_graph .y_axis,
.rickshaw_graph .x_axis_d3 {
fill: none;
}
.rickshaw_graph .y_ticks .tick,
.rickshaw_graph .x_ticks_d3 .tick {
stroke: rgba(0, 0, 0, 0.16);
stroke-width: 2px;
shape-rendering: crisp-edges;
pointer-events: none;
}
.rickshaw_graph .y_grid .tick,
.rickshaw_graph .x_grid_d3 .tick {
z-index: -1;
stroke: rgba(0, 0, 0, 0.20);
stroke-width: 1px;
stroke-dasharray: 1 1;
}
.rickshaw_graph .y_grid .tick[data-y-value="0"] {
stroke-dasharray: 1 0;
}
.rickshaw_graph .y_grid path,
.rickshaw_graph .x_grid_d3 path {
fill: none;
stroke: none;
}
.rickshaw_graph .y_ticks path,
.rickshaw_graph .x_ticks_d3 path {
fill: none;
stroke: #808080;
}
.rickshaw_graph .y_ticks text,
.rickshaw_graph .x_ticks_d3 text {
opacity: 0.5;
font-size: 12px;
pointer-events: none;
}
.rickshaw_graph .x_tick.glow .title,
.rickshaw_graph .y_ticks.glow text {
fill: black;
color: black;
text-shadow:
-1px 1px 0 rgba(255, 255, 255, 0.1),
1px -1px 0 rgba(255, 255, 255, 0.1),
1px 1px 0 rgba(255, 255, 255, 0.1),
0px 1px 0 rgba(255, 255, 255, 0.1),
0px -1px 0 rgba(255, 255, 255, 0.1),
1px 0px 0 rgba(255, 255, 255, 0.1),
-1px 0px 0 rgba(255, 255, 255, 0.1),
-1px -1px 0 rgba(255, 255, 255, 0.1);
}
.rickshaw_graph .x_tick.inverse .title,
.rickshaw_graph .y_ticks.inverse text {
fill: white;
color: white;
text-shadow:
-1px 1px 0 rgba(0, 0, 0, 0.8),
1px -1px 0 rgba(0, 0, 0, 0.8),
1px 1px 0 rgba(0, 0, 0, 0.8),
0px 1px 0 rgba(0, 0, 0, 0.8),
0px -1px 0 rgba(0, 0, 0, 0.8),
1px 0px 0 rgba(0, 0, 0, 0.8),
-1px 0px 0 rgba(0, 0, 0, 0.8),
-1px -1px 0 rgba(0, 0, 0, 0.8);
}
.rickshaw_legend {
font-size: 12px;
color: white;
background: #404040;
display: inline-block;
padding: 12px 5px;
border-radius: 2px;
position: relative;
}
.rickshaw_legend:hover {
z-index: 10;
}
.rickshaw_legend .swatch {
width: 10px;
height: 10px;
border: 1px solid rgba(0, 0, 0, 0.2);
}
.rickshaw_legend .line {
clear: both;
line-height: 140%;
padding-right: 15px;
}
.rickshaw_legend .line .swatch {
display: inline-block;
margin-right: 3px;
border-radius: 2px;
}
.rickshaw_legend .label {
margin: 0;
white-space: nowrap;
display: inline;
font-size: inherit;
background-color: transparent;
color: inherit;
font-weight: normal;
line-height: normal;
padding: 0px;
text-shadow: none;
}
.rickshaw_legend .action:hover {
opacity: 0.6;
}
.rickshaw_legend .action {
margin-right: 0.2em;
font-size: 10px;
opacity: 0.2;
cursor: pointer;
font-size: 14px;
}
.rickshaw_legend .line.disabled {
opacity: 0.4;
}
.rickshaw_legend ul {
list-style-type: none;
margin: 0;
padding: 0;
margin: 2px;
cursor: pointer;
}
.rickshaw_legend li {
padding: 0 0 0 2px;
min-width: 80px;
white-space: nowrap;
}
.rickshaw_legend li:hover {
background: rgba(255, 255, 255, 0.08);
border-radius: 3px;
}
.rickshaw_legend li:active {
background: rgba(255, 255, 255, 0.2);
border-radius: 3px;
}

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,103 @@
.rickshaw_graph .detail {
pointer-events: none;
position: absolute;
top: 0;
z-index: 2;
background: rgba(0, 0, 0, 0.1);
bottom: 0;
width: 1px;
transition: opacity 0.25s linear;
-moz-transition: opacity 0.25s linear;
-o-transition: opacity 0.25s linear;
-webkit-transition: opacity 0.25s linear;
}
.rickshaw_graph .detail.inactive {
opacity: 0;
}
.rickshaw_graph .detail .item.active {
opacity: 1;
}
.rickshaw_graph .detail .x_label {
font-family: Arial, sans-serif;
border-radius: 3px;
padding: 6px;
opacity: 0.5;
border: 1px solid #e0e0e0;
font-size: 12px;
position: absolute;
background: white;
white-space: nowrap;
}
.rickshaw_graph .detail .x_label.left {
left: 0;
}
.rickshaw_graph .detail .x_label.right {
right: 0;
}
.rickshaw_graph .detail .item {
position: absolute;
z-index: 2;
border-radius: 3px;
padding: 0.25em;
font-size: 12px;
font-family: Arial, sans-serif;
opacity: 0;
background: rgba(0, 0, 0, 0.4);
color: white;
border: 1px solid rgba(0, 0, 0, 0.4);
margin-left: 1em;
margin-right: 1em;
margin-top: -1em;
white-space: nowrap;
}
.rickshaw_graph .detail .item.left {
left: 0;
}
.rickshaw_graph .detail .item.right {
right: 0;
}
.rickshaw_graph .detail .item.active {
opacity: 1;
background: rgba(0, 0, 0, 0.8);
}
.rickshaw_graph .detail .item:after {
position: absolute;
display: block;
width: 0;
height: 0;
content: "";
border: 5px solid transparent;
}
.rickshaw_graph .detail .item.left:after {
top: 1em;
left: -5px;
margin-top: -5px;
border-right-color: rgba(0, 0, 0, 0.8);
border-left-width: 0;
}
.rickshaw_graph .detail .item.right:after {
top: 1em;
right: -5px;
margin-top: -5px;
border-left-color: rgba(0, 0, 0, 0.8);
border-right-width: 0;
}
.rickshaw_graph .detail .dot {
width: 4px;
height: 4px;
margin-left: -2px;
margin-top: -2px;
border-radius: 5px;
position: absolute;
box-shadow: 0 0 2px rgba(0, 0, 0, 0.6);
background: white;
border-width: 2px;
border-style: solid;
display: none;
background-clip: padding-box;
}
.rickshaw_graph .detail .dot.active {
display: block;
}

View File

@@ -0,0 +1,177 @@
/* graph */
.rickshaw_graph {
position: relative;
}
.rickshaw_graph svg {
display: block;
overflow: hidden;
}
/* ticks */
.rickshaw_graph .x_tick {
position: absolute;
top: 0;
bottom: 0;
width: 0px;
border-left: 1px dotted rgba(0, 0, 0, 0.2);
pointer-events: none;
}
.rickshaw_graph .x_tick .title {
position: absolute;
font-size: 12px;
font-family: Arial, sans-serif;
opacity: 0.5;
white-space: nowrap;
margin-left: 3px;
bottom: 1px;
}
/* annotations */
.rickshaw_annotation_timeline {
height: 1px;
border-top: 1px solid #e0e0e0;
margin-top: 10px;
position: relative;
}
.rickshaw_annotation_timeline .annotation {
position: absolute;
height: 6px;
width: 6px;
margin-left: -2px;
top: -3px;
border-radius: 5px;
background-color: rgba(0, 0, 0, 0.25);
}
.rickshaw_graph .annotation_line {
position: absolute;
top: 0;
bottom: -6px;
width: 0px;
border-left: 2px solid rgba(0, 0, 0, 0.3);
display: none;
}
.rickshaw_graph .annotation_line.active {
display: block;
}
.rickshaw_graph .annotation_range {
background: rgba(0, 0, 0, 0.1);
display: none;
position: absolute;
top: 0;
bottom: -6px;
}
.rickshaw_graph .annotation_range.active {
display: block;
}
.rickshaw_graph .annotation_range.active.offscreen {
display: none;
}
.rickshaw_annotation_timeline .annotation .content {
background: white;
color: black;
opacity: 0.9;
padding: 5px 5px;
box-shadow: 0 0 2px rgba(0, 0, 0, 0.8);
border-radius: 3px;
position: relative;
z-index: 20;
font-size: 12px;
padding: 6px 8px 8px;
top: 18px;
left: -11px;
width: 160px;
display: none;
cursor: pointer;
}
.rickshaw_annotation_timeline .annotation .content:before {
content: "\25b2";
position: absolute;
top: -11px;
color: white;
text-shadow: 0 -1px 1px rgba(0, 0, 0, 0.8);
}
.rickshaw_annotation_timeline .annotation.active,
.rickshaw_annotation_timeline .annotation:hover {
background-color: rgba(0, 0, 0, 0.8);
cursor: none;
}
.rickshaw_annotation_timeline .annotation .content:hover {
z-index: 50;
}
.rickshaw_annotation_timeline .annotation.active .content {
display: block;
}
.rickshaw_annotation_timeline .annotation:hover .content {
display: block;
z-index: 50;
}
.rickshaw_graph .y_axis,
.rickshaw_graph .x_axis_d3 {
fill: none;
}
.rickshaw_graph .y_ticks .tick line,
.rickshaw_graph .x_ticks_d3 .tick {
stroke: rgba(0, 0, 0, 0.16);
stroke-width: 2px;
shape-rendering: crisp-edges;
pointer-events: none;
}
.rickshaw_graph .y_grid .tick,
.rickshaw_graph .x_grid_d3 .tick {
z-index: -1;
stroke: rgba(0, 0, 0, 0.20);
stroke-width: 1px;
stroke-dasharray: 1 1;
}
.rickshaw_graph .y_grid .tick[data-y-value="0"] {
stroke-dasharray: 1 0;
}
.rickshaw_graph .y_grid path,
.rickshaw_graph .x_grid_d3 path {
fill: none;
stroke: none;
}
.rickshaw_graph .y_ticks path,
.rickshaw_graph .x_ticks_d3 path {
fill: none;
stroke: #808080;
}
.rickshaw_graph .y_ticks text,
.rickshaw_graph .x_ticks_d3 text {
opacity: 0.5;
font-size: 12px;
pointer-events: none;
}
.rickshaw_graph .x_tick.glow .title,
.rickshaw_graph .y_ticks.glow text {
fill: black;
color: black;
text-shadow:
-1px 1px 0 rgba(255, 255, 255, 0.1),
1px -1px 0 rgba(255, 255, 255, 0.1),
1px 1px 0 rgba(255, 255, 255, 0.1),
0px 1px 0 rgba(255, 255, 255, 0.1),
0px -1px 0 rgba(255, 255, 255, 0.1),
1px 0px 0 rgba(255, 255, 255, 0.1),
-1px 0px 0 rgba(255, 255, 255, 0.1),
-1px -1px 0 rgba(255, 255, 255, 0.1);
}
.rickshaw_graph .x_tick.inverse .title,
.rickshaw_graph .y_ticks.inverse text {
fill: white;
color: white;
text-shadow:
-1px 1px 0 rgba(0, 0, 0, 0.8),
1px -1px 0 rgba(0, 0, 0, 0.8),
1px 1px 0 rgba(0, 0, 0, 0.8),
0px 1px 0 rgba(0, 0, 0, 0.8),
0px -1px 0 rgba(0, 0, 0, 0.8),
1px 0px 0 rgba(0, 0, 0, 0.8),
-1px 0px 0 rgba(0, 0, 0, 0.8),
-1px -1px 0 rgba(0, 0, 0, 0.8);
}

View File

@@ -0,0 +1,73 @@
.rickshaw_legend {
font-family: Arial;
font-size: 12px;
color: white;
background: #404040;
display: inline-block;
padding: 12px 5px;
border-radius: 2px;
position: relative;
}
.rickshaw_legend:hover {
z-index: 10;
}
.rickshaw_legend .swatch {
width: 10px;
height: 10px;
border: 1px solid rgba(0, 0, 0, 0.2);
}
.rickshaw_legend .line {
clear: both;
line-height: 140%;
padding-right: 15px;
}
.rickshaw_legend .line .swatch {
display: inline-block;
margin-right: 3px;
border-radius: 2px;
}
.rickshaw_legend .label {
margin: 0;
white-space: nowrap;
display: inline;
font-size: inherit;
background-color: transparent;
color: inherit;
font-weight: normal;
line-height: normal;
padding: 0px;
text-shadow: none;
}
.rickshaw_legend .action:hover {
opacity: 0.6;
}
.rickshaw_legend .action {
margin-right: 0.2em;
font-size: 10px;
opacity: 0.2;
cursor: pointer;
font-size: 14px;
}
.rickshaw_legend .line.disabled {
opacity: 0.4;
}
.rickshaw_legend ul {
list-style-type: none;
margin: 0;
padding: 0;
margin: 2px;
cursor: pointer;
}
.rickshaw_legend li {
padding: 0 0 0 2px;
min-width: 80px;
white-space: nowrap;
}
.rickshaw_legend li:hover {
background: rgba(255, 255, 255, 0.08);
border-radius: 3px;
}
.rickshaw_legend li:active {
background: rgba(255, 255, 255, 0.2);
border-radius: 3px;
}

View File

@@ -0,0 +1,204 @@
/* Adapted from https://github.com/Jakobo/PTClass */
/*
Copyright (c) 2005-2010 Sam Stephenson
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 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.
*/
/* Based on Alex Arnell's inheritance implementation. */
/** section: Language
* class Class
*
* Manages Prototype's class-based OOP system.
*
* Refer to Prototype's web site for a [tutorial on classes and
* inheritance](http://prototypejs.org/learn/class-inheritance).
**/
(function(globalContext) {
/* ------------------------------------ */
/* Import from object.js */
/* ------------------------------------ */
var _toString = Object.prototype.toString,
NULL_TYPE = 'Null',
UNDEFINED_TYPE = 'Undefined',
BOOLEAN_TYPE = 'Boolean',
NUMBER_TYPE = 'Number',
STRING_TYPE = 'String',
OBJECT_TYPE = 'Object',
FUNCTION_CLASS = '[object Function]';
function isFunction(object) {
return _toString.call(object) === FUNCTION_CLASS;
}
function extend(destination, source) {
for (var property in source) if (source.hasOwnProperty(property)) // modify protect primitive slaughter
destination[property] = source[property];
return destination;
}
function keys(object) {
if (Type(object) !== OBJECT_TYPE) { throw new TypeError(); }
var results = [];
for (var property in object) {
if (object.hasOwnProperty(property)) {
results.push(property);
}
}
return results;
}
function Type(o) {
switch(o) {
case null: return NULL_TYPE;
case (void 0): return UNDEFINED_TYPE;
}
var type = typeof o;
switch(type) {
case 'boolean': return BOOLEAN_TYPE;
case 'number': return NUMBER_TYPE;
case 'string': return STRING_TYPE;
}
return OBJECT_TYPE;
}
function isUndefined(object) {
return typeof object === "undefined";
}
/* ------------------------------------ */
/* Import from Function.js */
/* ------------------------------------ */
var slice = Array.prototype.slice;
function argumentNames(fn) {
var names = fn.toString().match(/^[\s\(]*function[^(]*\(([^)]*)\)/)[1]
.replace(/\/\/.*?[\r\n]|\/\*(?:.|[\r\n])*?\*\//g, '')
.replace(/\s+/g, '').split(',');
return names.length == 1 && !names[0] ? [] : names;
}
function wrap(fn, wrapper) {
var __method = fn;
return function() {
var a = update([bind(__method, this)], arguments);
return wrapper.apply(this, a);
}
}
function update(array, args) {
var arrayLength = array.length, length = args.length;
while (length--) array[arrayLength + length] = args[length];
return array;
}
function merge(array, args) {
array = slice.call(array, 0);
return update(array, args);
}
function bind(fn, context) {
if (arguments.length < 2 && isUndefined(arguments[0])) return this;
var __method = fn, args = slice.call(arguments, 2);
return function() {
var a = merge(args, arguments);
return __method.apply(context, a);
}
}
/* ------------------------------------ */
/* Import from Prototype.js */
/* ------------------------------------ */
var emptyFunction = function(){};
var Class = (function() {
// Some versions of JScript fail to enumerate over properties, names of which
// correspond to non-enumerable properties in the prototype chain
var IS_DONTENUM_BUGGY = (function(){
for (var p in { toString: 1 }) {
// check actual property name, so that it works with augmented Object.prototype
if (p === 'toString') return false;
}
return true;
})();
function subclass() {};
function create() {
var parent = null, properties = [].slice.apply(arguments);
if (isFunction(properties[0]))
parent = properties.shift();
function klass() {
this.initialize.apply(this, arguments);
}
extend(klass, Class.Methods);
klass.superclass = parent;
klass.subclasses = [];
if (parent) {
subclass.prototype = parent.prototype;
klass.prototype = new subclass;
try { parent.subclasses.push(klass) } catch(e) {}
}
for (var i = 0, length = properties.length; i < length; i++)
klass.addMethods(properties[i]);
if (!klass.prototype.initialize)
klass.prototype.initialize = emptyFunction;
klass.prototype.constructor = klass;
return klass;
}
function addMethods(source) {
var ancestor = this.superclass && this.superclass.prototype,
properties = keys(source);
// IE6 doesn't enumerate `toString` and `valueOf` (among other built-in `Object.prototype`) properties,
// Force copy if they're not Object.prototype ones.
// Do not copy other Object.prototype.* for performance reasons
if (IS_DONTENUM_BUGGY) {
if (source.toString != Object.prototype.toString)
properties.push("toString");
if (source.valueOf != Object.prototype.valueOf)
properties.push("valueOf");
}
for (var i = 0, length = properties.length; i < length; i++) {
var property = properties[i], value = source[property];
if (ancestor && isFunction(value) &&
argumentNames(value)[0] == "$super") {
var method = value;
value = wrap((function(m) {
return function() { return ancestor[m].apply(this, arguments); };
})(property), method);
value.valueOf = bind(method.valueOf, method);
value.toString = bind(method.toString, method);
}
this.prototype[property] = value;
}
return this;
}
return {
create: create,
Methods: {
addMethods: addMethods
}
};
})();
if (globalContext.exports) {
globalContext.exports.Class = Class;
}
else {
globalContext.Class = Class;
}
})(Rickshaw);

View File

@@ -0,0 +1,48 @@
Rickshaw.namespace("Rickshaw.Color.Palette");
Rickshaw.Color.Palette = function(args) {
var color = new Rickshaw.Fixtures.Color();
args = args || {};
this.schemes = {};
this.scheme = color.schemes[args.scheme] || args.scheme || color.schemes.colorwheel;
this.runningIndex = 0;
this.generatorIndex = 0;
if (args.interpolatedStopCount) {
var schemeCount = this.scheme.length - 1;
var i, j, scheme = [];
for (i = 0; i < schemeCount; i++) {
scheme.push(this.scheme[i]);
var generator = d3.interpolateHsl(this.scheme[i], this.scheme[i + 1]);
for (j = 1; j < args.interpolatedStopCount; j++) {
scheme.push(generator((1 / args.interpolatedStopCount) * j));
}
}
scheme.push(this.scheme[this.scheme.length - 1]);
this.scheme = scheme;
}
this.rotateCount = this.scheme.length;
this.color = function(key) {
return this.scheme[key] || this.scheme[this.runningIndex++] || this.interpolateColor() || '#808080';
};
this.interpolateColor = function() {
if (!Array.isArray(this.scheme)) return;
var color;
if (this.generatorIndex == this.rotateCount * 2 - 1) {
color = d3.interpolateHsl(this.scheme[this.generatorIndex], this.scheme[0])(0.5);
this.generatorIndex = 0;
this.rotateCount *= 2;
} else {
color = d3.interpolateHsl(this.scheme[this.generatorIndex], this.scheme[this.generatorIndex + 1])(0.5);
this.generatorIndex++;
}
this.scheme.push(color);
return color;
};
};

View File

@@ -0,0 +1,135 @@
Rickshaw.namespace('Rickshaw.Compat.ClassList');
Rickshaw.Compat.ClassList = function() {
/* adapted from http://purl.eligrey.com/github/classList.js/blob/master/classList.js */
if (typeof document !== "undefined" && !("classList" in document.createElement("a"))) {
(function (view) {
"use strict";
var
classListProp = "classList"
, protoProp = "prototype"
, elemCtrProto = (view.HTMLElement || view.Element)[protoProp]
, objCtr = Object
, strTrim = String[protoProp].trim || function () {
return this.replace(/^\s+|\s+$/g, "");
}
, arrIndexOf = Array[protoProp].indexOf || function (item) {
var
i = 0
, len = this.length
;
for (; i < len; i++) {
if (i in this && this[i] === item) {
return i;
}
}
return -1;
}
// Vendors: please allow content code to instantiate DOMExceptions
, DOMEx = function (type, message) {
this.name = type;
this.code = DOMException[type];
this.message = message;
}
, checkTokenAndGetIndex = function (classList, token) {
if (token === "") {
throw new DOMEx(
"SYNTAX_ERR"
, "An invalid or illegal string was specified"
);
}
if (/\s/.test(token)) {
throw new DOMEx(
"INVALID_CHARACTER_ERR"
, "String contains an invalid character"
);
}
return arrIndexOf.call(classList, token);
}
, ClassList = function (elem) {
var
trimmedClasses = strTrim.call(elem.className)
, classes = trimmedClasses ? trimmedClasses.split(/\s+/) : []
, i = 0
, len = classes.length
;
for (; i < len; i++) {
this.push(classes[i]);
}
this._updateClassName = function () {
elem.className = this.toString();
};
}
, classListProto = ClassList[protoProp] = []
, classListGetter = function () {
return new ClassList(this);
}
;
// Most DOMException implementations don't allow calling DOMException's toString()
// on non-DOMExceptions. Error's toString() is sufficient here.
DOMEx[protoProp] = Error[protoProp];
classListProto.item = function (i) {
return this[i] || null;
};
classListProto.contains = function (token) {
token += "";
return checkTokenAndGetIndex(this, token) !== -1;
};
classListProto.add = function (token) {
token += "";
if (checkTokenAndGetIndex(this, token) === -1) {
this.push(token);
this._updateClassName();
}
};
classListProto.remove = function (token) {
token += "";
var index = checkTokenAndGetIndex(this, token);
if (index !== -1) {
this.splice(index, 1);
this._updateClassName();
}
};
classListProto.toggle = function (token) {
token += "";
if (checkTokenAndGetIndex(this, token) === -1) {
this.add(token);
} else {
this.remove(token);
}
};
classListProto.toString = function () {
return this.join(" ");
};
if (objCtr.defineProperty) {
var classListPropDesc = {
get: classListGetter
, enumerable: true
, configurable: true
};
try {
objCtr.defineProperty(elemCtrProto, classListProp, classListPropDesc);
} catch (ex) { // IE 8 doesn't support enumerable:true
if (ex.number === -0x7FF5EC54) {
classListPropDesc.enumerable = false;
objCtr.defineProperty(elemCtrProto, classListProp, classListPropDesc);
}
}
} else if (objCtr[protoProp].__defineGetter__) {
elemCtrProto.__defineGetter__(classListProp, classListGetter);
}
}(window));
}
};
if ( (typeof RICKSHAW_NO_COMPAT !== "undefined" && !RICKSHAW_NO_COMPAT) || typeof RICKSHAW_NO_COMPAT === "undefined") {
new Rickshaw.Compat.ClassList();
}

View File

@@ -0,0 +1,159 @@
Rickshaw.namespace('Rickshaw.Fixtures.Color');
Rickshaw.Fixtures.Color = function() {
this.schemes = {};
this.schemes.spectrum14 = [
'#ecb796',
'#dc8f70',
'#b2a470',
'#92875a',
'#716c49',
'#d2ed82',
'#bbe468',
'#a1d05d',
'#e7cbe6',
'#d8aad6',
'#a888c2',
'#9dc2d3',
'#649eb9',
'#387aa3'
].reverse();
this.schemes.spectrum2000 = [
'#57306f',
'#514c76',
'#646583',
'#738394',
'#6b9c7d',
'#84b665',
'#a7ca50',
'#bfe746',
'#e2f528',
'#fff726',
'#ecdd00',
'#d4b11d',
'#de8800',
'#de4800',
'#c91515',
'#9a0000',
'#7b0429',
'#580839',
'#31082b'
];
this.schemes.spectrum2001 = [
'#2f243f',
'#3c2c55',
'#4a3768',
'#565270',
'#6b6b7c',
'#72957f',
'#86ad6e',
'#a1bc5e',
'#b8d954',
'#d3e04e',
'#ccad2a',
'#cc8412',
'#c1521d',
'#ad3821',
'#8a1010',
'#681717',
'#531e1e',
'#3d1818',
'#320a1b'
];
this.schemes.classic9 = [
'#423d4f',
'#4a6860',
'#848f39',
'#a2b73c',
'#ddcb53',
'#c5a32f',
'#7d5836',
'#963b20',
'#7c2626',
'#491d37',
'#2f254a'
].reverse();
this.schemes.httpStatus = {
503: '#ea5029',
502: '#d23f14',
500: '#bf3613',
410: '#efacea',
409: '#e291dc',
403: '#f457e8',
408: '#e121d2',
401: '#b92dae',
405: '#f47ceb',
404: '#a82a9f',
400: '#b263c6',
301: '#6fa024',
302: '#87c32b',
307: '#a0d84c',
304: '#28b55c',
200: '#1a4f74',
206: '#27839f',
201: '#52adc9',
202: '#7c979f',
203: '#a5b8bd',
204: '#c1cdd1'
};
this.schemes.colorwheel = [
'#b5b6a9',
'#858772',
'#785f43',
'#96557e',
'#4682b4',
'#65b9ac',
'#73c03a',
'#cb513a'
].reverse();
this.schemes.cool = [
'#5e9d2f',
'#73c03a',
'#4682b4',
'#7bc3b8',
'#a9884e',
'#c1b266',
'#a47493',
'#c09fb5'
];
this.schemes.munin = [
'#00cc00',
'#0066b3',
'#ff8000',
'#ffcc00',
'#330099',
'#990099',
'#ccff00',
'#ff0000',
'#808080',
'#008f00',
'#00487d',
'#b35a00',
'#b38f00',
'#6b006b',
'#8fb300',
'#b30000',
'#bebebe',
'#80ff80',
'#80c9ff',
'#ffc080',
'#ffe680',
'#aa80ff',
'#ee00cc',
'#ff8080',
'#666600',
'#ffbfff',
'#00ffcc',
'#cc6699',
'#999900'
];
};

View File

@@ -0,0 +1,24 @@
Rickshaw.namespace('Rickshaw.Fixtures.Number');
Rickshaw.Fixtures.Number.formatKMBT = function(y) {
var abs_y = Math.abs(y);
if (abs_y >= 1000000000000) { return y / 1000000000000 + "T" }
else if (abs_y >= 1000000000) { return y / 1000000000 + "B" }
else if (abs_y >= 1000000) { return y / 1000000 + "M" }
else if (abs_y >= 1000) { return y / 1000 + "K" }
else if (abs_y < 1 && y > 0) { return y.toFixed(2) }
else if (abs_y === 0) { return '' }
else { return y }
};
Rickshaw.Fixtures.Number.formatBase1024KMGTP = function(y) {
var abs_y = Math.abs(y);
if (abs_y >= 1125899906842624) { return y / 1125899906842624 + "P" }
else if (abs_y >= 1099511627776){ return y / 1099511627776 + "T" }
else if (abs_y >= 1073741824) { return y / 1073741824 + "G" }
else if (abs_y >= 1048576) { return y / 1048576 + "M" }
else if (abs_y >= 1024) { return y / 1024 + "K" }
else if (abs_y < 1 && y > 0) { return y.toFixed(2) }
else if (abs_y === 0) { return '' }
else { return y }
};

View File

@@ -0,0 +1,39 @@
Rickshaw.namespace('Rickshaw.Fixtures.RandomData');
Rickshaw.Fixtures.RandomData = function(timeInterval) {
var addData;
timeInterval = timeInterval || 1;
var lastRandomValue = 200;
var timeBase = Math.floor(new Date().getTime() / 1000);
this.addData = function(data) {
var randomValue = Math.random() * 100 + 15 + lastRandomValue;
var index = data[0].length;
var counter = 1;
data.forEach( function(series) {
var randomVariance = Math.random() * 20;
var v = randomValue / 25 + counter++ +
(Math.cos((index * counter * 11) / 960) + 2) * 15 +
(Math.cos(index / 7) + 2) * 7 +
(Math.cos(index / 17) + 2) * 1;
series.push( { x: (index * timeInterval) + timeBase, y: v + randomVariance } );
} );
lastRandomValue = randomValue * 0.85;
};
this.removeData = function(data) {
data.forEach( function(series) {
series.shift();
} );
timeBase += timeInterval;
};
};

View File

@@ -0,0 +1,131 @@
Rickshaw.namespace('Rickshaw.Fixtures.Time.Local');
Rickshaw.Fixtures.Time.Local = function() {
var self = this;
this.months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
this.units = [
{
name: 'decade',
seconds: 86400 * 365.25 * 10,
formatter: function(d) { return (parseInt(d.getFullYear() / 10, 10) * 10) }
}, {
name: 'year',
seconds: 86400 * 365.25,
formatter: function(d) { return d.getFullYear() }
}, {
name: 'month',
seconds: 86400 * 30.5,
formatter: function(d) { return self.months[d.getMonth()] }
}, {
name: 'week',
seconds: 86400 * 7,
formatter: function(d) { return self.formatDate(d) }
}, {
name: 'day',
seconds: 86400,
formatter: function(d) { return d.getDate() }
}, {
name: '6 hour',
seconds: 3600 * 6,
formatter: function(d) { return self.formatTime(d) }
}, {
name: 'hour',
seconds: 3600,
formatter: function(d) { return self.formatTime(d) }
}, {
name: '15 minute',
seconds: 60 * 15,
formatter: function(d) { return self.formatTime(d) }
}, {
name: 'minute',
seconds: 60,
formatter: function(d) { return d.getMinutes() }
}, {
name: '15 second',
seconds: 15,
formatter: function(d) { return d.getSeconds() + 's' }
}, {
name: 'second',
seconds: 1,
formatter: function(d) { return d.getSeconds() + 's' }
}, {
name: 'decisecond',
seconds: 1/10,
formatter: function(d) { return d.getMilliseconds() + 'ms' }
}, {
name: 'centisecond',
seconds: 1/100,
formatter: function(d) { return d.getMilliseconds() + 'ms' }
}
];
this.unit = function(unitName) {
return this.units.filter( function(unit) { return unitName == unit.name } ).shift();
};
this.formatDate = function(d) {
return d3.time.format('%b %e')(d);
};
this.formatTime = function(d) {
return d.toString().match(/(\d+:\d+):/)[1];
};
this.ceil = function(time, unit) {
var date, floor, year;
if (unit.name == 'day') {
var nearFuture = new Date((time + unit.seconds - 1) * 1000);
var rounded = new Date(0);
rounded.setMilliseconds(0);
rounded.setSeconds(0);
rounded.setMinutes(0);
rounded.setHours(0);
rounded.setDate(nearFuture.getDate());
rounded.setMonth(nearFuture.getMonth());
rounded.setFullYear(nearFuture.getFullYear());
return rounded.getTime() / 1000;
}
if (unit.name == 'month') {
date = new Date(time * 1000);
floor = new Date(date.getFullYear(), date.getMonth()).getTime() / 1000;
if (floor == time) return time;
year = date.getFullYear();
var month = date.getMonth();
if (month == 11) {
month = 0;
year = year + 1;
} else {
month += 1;
}
return new Date(year, month).getTime() / 1000;
}
if (unit.name == 'year') {
date = new Date(time * 1000);
floor = new Date(date.getUTCFullYear(), 0).getTime() / 1000;
if (floor == time) return time;
year = date.getFullYear() + 1;
return new Date(year, 0).getTime() / 1000;
}
return Math.ceil(time / unit.seconds) * unit.seconds;
};
};

View File

@@ -0,0 +1,115 @@
Rickshaw.namespace('Rickshaw.Fixtures.Time');
Rickshaw.Fixtures.Time = function() {
var self = this;
this.months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
this.units = [
{
name: 'decade',
seconds: 86400 * 365.25 * 10,
formatter: function(d) { return (parseInt(d.getUTCFullYear() / 10, 10) * 10) }
}, {
name: 'year',
seconds: 86400 * 365.25,
formatter: function(d) { return d.getUTCFullYear() }
}, {
name: 'month',
seconds: 86400 * 30.5,
formatter: function(d) { return self.months[d.getUTCMonth()] }
}, {
name: 'week',
seconds: 86400 * 7,
formatter: function(d) { return self.formatDate(d) }
}, {
name: 'day',
seconds: 86400,
formatter: function(d) { return d.getUTCDate() }
}, {
name: '6 hour',
seconds: 3600 * 6,
formatter: function(d) { return self.formatTime(d) }
}, {
name: 'hour',
seconds: 3600,
formatter: function(d) { return self.formatTime(d) }
}, {
name: '15 minute',
seconds: 60 * 15,
formatter: function(d) { return self.formatTime(d) }
}, {
name: 'minute',
seconds: 60,
formatter: function(d) { return d.getUTCMinutes() }
}, {
name: '15 second',
seconds: 15,
formatter: function(d) { return d.getUTCSeconds() + 's' }
}, {
name: 'second',
seconds: 1,
formatter: function(d) { return d.getUTCSeconds() + 's' }
}, {
name: 'decisecond',
seconds: 1/10,
formatter: function(d) { return d.getUTCMilliseconds() + 'ms' }
}, {
name: 'centisecond',
seconds: 1/100,
formatter: function(d) { return d.getUTCMilliseconds() + 'ms' }
}
];
this.unit = function(unitName) {
return this.units.filter( function(unit) { return unitName == unit.name } ).shift();
};
this.formatDate = function(d) {
return d3.time.format('%b %e')(d);
};
this.formatTime = function(d) {
return d.toUTCString().match(/(\d+:\d+):/)[1];
};
this.ceil = function(time, unit) {
var date, floor, year;
if (unit.name == 'month') {
date = new Date(time * 1000);
floor = Date.UTC(date.getUTCFullYear(), date.getUTCMonth()) / 1000;
if (floor == time) return time;
year = date.getUTCFullYear();
var month = date.getUTCMonth();
if (month == 11) {
month = 0;
year = year + 1;
} else {
month += 1;
}
return Date.UTC(year, month) / 1000;
}
if (unit.name == 'year') {
date = new Date(time * 1000);
floor = Date.UTC(date.getUTCFullYear(), 0) / 1000;
if (floor == time) return time;
year = date.getUTCFullYear() + 1;
return Date.UTC(year, 0) / 1000;
}
return Math.ceil(time / unit.seconds) * unit.seconds;
};
};

View File

@@ -0,0 +1,74 @@
Rickshaw.namespace('Rickshaw.Graph.Ajax');
Rickshaw.Graph.Ajax = Rickshaw.Class.create( {
initialize: function(args) {
this.dataURL = args.dataURL;
this.onData = args.onData || function(d) { return d };
this.onComplete = args.onComplete || function() {};
this.onError = args.onError || function() {};
this.args = args; // pass through to Rickshaw.Graph
this.request();
},
request: function() {
jQuery.ajax( {
url: this.dataURL,
dataType: 'json',
success: this.success.bind(this),
error: this.error.bind(this)
} );
},
error: function() {
console.log("error loading dataURL: " + this.dataURL);
this.onError(this);
},
success: function(data, status) {
data = this.onData(data);
this.args.series = this._splice({ data: data, series: this.args.series });
this.graph = this.graph || new Rickshaw.Graph(this.args);
this.graph.render();
this.onComplete(this);
},
_splice: function(args) {
var data = args.data;
var series = args.series;
if (!args.series) return data;
series.forEach( function(s) {
var seriesKey = s.key || s.name;
if (!seriesKey) throw "series needs a key or a name";
data.forEach( function(d) {
var dataKey = d.key || d.name;
if (!dataKey) throw "data needs a key or a name";
if (seriesKey == dataKey) {
var properties = ['color', 'name', 'data'];
properties.forEach( function(p) {
if (d[p]) s[p] = d[p];
} );
}
} );
} );
return series;
}
} );

View File

@@ -0,0 +1,105 @@
Rickshaw.namespace('Rickshaw.Graph.Annotate');
Rickshaw.Graph.Annotate = function(args) {
var graph = this.graph = args.graph;
this.elements = { timeline: args.element };
var self = this;
this.data = {};
this.elements.timeline.classList.add('rickshaw_annotation_timeline');
this.add = function(time, content, end_time) {
self.data[time] = self.data[time] || {'boxes': []};
self.data[time].boxes.push({content: content, end: end_time});
};
this.update = function() {
Rickshaw.keys(self.data).forEach( function(time) {
var annotation = self.data[time];
var left = self.graph.x(time);
if (left < 0 || left > self.graph.x.range()[1]) {
if (annotation.element) {
annotation.line.classList.add('offscreen');
annotation.element.style.display = 'none';
}
annotation.boxes.forEach( function(box) {
if ( box.rangeElement ) box.rangeElement.classList.add('offscreen');
});
return;
}
if (!annotation.element) {
var element = annotation.element = document.createElement('div');
element.classList.add('annotation');
this.elements.timeline.appendChild(element);
element.addEventListener('click', function(e) {
element.classList.toggle('active');
annotation.line.classList.toggle('active');
annotation.boxes.forEach( function(box) {
if ( box.rangeElement ) box.rangeElement.classList.toggle('active');
});
}, false);
}
annotation.element.style.left = left + 'px';
annotation.element.style.display = 'block';
annotation.boxes.forEach( function(box) {
var element = box.element;
if (!element) {
element = box.element = document.createElement('div');
element.classList.add('content');
element.innerHTML = box.content;
annotation.element.appendChild(element);
annotation.line = document.createElement('div');
annotation.line.classList.add('annotation_line');
self.graph.element.appendChild(annotation.line);
if ( box.end ) {
box.rangeElement = document.createElement('div');
box.rangeElement.classList.add('annotation_range');
self.graph.element.appendChild(box.rangeElement);
}
}
if ( box.end ) {
var annotationRangeStart = left;
var annotationRangeEnd = Math.min( self.graph.x(box.end), self.graph.x.range()[1] );
// annotation makes more sense at end
if ( annotationRangeStart > annotationRangeEnd ) {
annotationRangeEnd = left;
annotationRangeStart = Math.max( self.graph.x(box.end), self.graph.x.range()[0] );
}
var annotationRangeWidth = annotationRangeEnd - annotationRangeStart;
box.rangeElement.style.left = annotationRangeStart + 'px';
box.rangeElement.style.width = annotationRangeWidth + 'px';
box.rangeElement.classList.remove('offscreen');
}
annotation.line.classList.remove('offscreen');
annotation.line.style.left = left + 'px';
} );
}, this );
};
this.graph.onUpdate( function() { self.update() } );
};

View File

@@ -0,0 +1,85 @@
Rickshaw.namespace('Rickshaw.Graph.Axis.Time');
Rickshaw.Graph.Axis.Time = function(args) {
var self = this;
this.graph = args.graph;
this.elements = [];
this.ticksTreatment = args.ticksTreatment || 'plain';
this.fixedTimeUnit = args.timeUnit;
var time = args.timeFixture || new Rickshaw.Fixtures.Time();
this.appropriateTimeUnit = function() {
var unit;
var units = time.units;
var domain = this.graph.x.domain();
var rangeSeconds = domain[1] - domain[0];
units.forEach( function(u) {
if (Math.floor(rangeSeconds / u.seconds) >= 2) {
unit = unit || u;
}
} );
return (unit || time.units[time.units.length - 1]);
};
this.tickOffsets = function() {
var domain = this.graph.x.domain();
var unit = this.fixedTimeUnit || this.appropriateTimeUnit();
var count = Math.ceil((domain[1] - domain[0]) / unit.seconds);
var runningTick = domain[0];
var offsets = [];
for (var i = 0; i < count; i++) {
var tickValue = time.ceil(runningTick, unit);
runningTick = tickValue + unit.seconds / 2;
offsets.push( { value: tickValue, unit: unit } );
}
return offsets;
};
this.render = function() {
this.elements.forEach( function(e) {
e.parentNode.removeChild(e);
} );
this.elements = [];
var offsets = this.tickOffsets();
offsets.forEach( function(o) {
if (self.graph.x(o.value) > self.graph.x.range()[1]) return;
var element = document.createElement('div');
element.style.left = self.graph.x(o.value) + 'px';
element.classList.add('x_tick');
element.classList.add(self.ticksTreatment);
var title = document.createElement('div');
title.classList.add('title');
title.innerHTML = o.unit.formatter(new Date(o.value * 1000));
element.appendChild(title);
self.graph.element.appendChild(element);
self.elements.push(element);
} );
};
this.graph.onUpdate( function() { self.render() } );
};

View File

@@ -0,0 +1,118 @@
Rickshaw.namespace('Rickshaw.Graph.Axis.X');
Rickshaw.Graph.Axis.X = function(args) {
var self = this;
var berthRate = 0.10;
this.initialize = function(args) {
this.graph = args.graph;
this.orientation = args.orientation || 'top';
this.pixelsPerTick = args.pixelsPerTick || 75;
if (args.ticks) this.staticTicks = args.ticks;
if (args.tickValues) this.tickValues = args.tickValues;
this.tickSize = args.tickSize || 4;
this.ticksTreatment = args.ticksTreatment || 'plain';
if (args.element) {
this.element = args.element;
this._discoverSize(args.element, args);
this.vis = d3.select(args.element)
.append("svg:svg")
.attr('height', this.height)
.attr('width', this.width)
.attr('class', 'rickshaw_graph x_axis_d3');
this.element = this.vis[0][0];
this.element.style.position = 'relative';
this.setSize({ width: args.width, height: args.height });
} else {
this.vis = this.graph.vis;
}
this.graph.onUpdate( function() { self.render() } );
};
this.setSize = function(args) {
args = args || {};
if (!this.element) return;
this._discoverSize(this.element.parentNode, args);
this.vis
.attr('height', this.height)
.attr('width', this.width * (1 + berthRate));
var berth = Math.floor(this.width * berthRate / 2);
this.element.style.left = -1 * berth + 'px';
};
this.render = function() {
if (this._renderWidth !== undefined && this.graph.width !== this._renderWidth) this.setSize({ auto: true });
var axis = d3.svg.axis().scale(this.graph.x).orient(this.orientation);
axis.tickFormat( args.tickFormat || function(x) { return x } );
if (this.tickValues) axis.tickValues(this.tickValues);
this.ticks = this.staticTicks || Math.floor(this.graph.width / this.pixelsPerTick);
var berth = Math.floor(this.width * berthRate / 2) || 0;
var transform;
if (this.orientation == 'top') {
var yOffset = this.height || this.graph.height;
transform = 'translate(' + berth + ',' + yOffset + ')';
} else {
transform = 'translate(' + berth + ', 0)';
}
if (this.element) {
this.vis.selectAll('*').remove();
}
this.vis
.append("svg:g")
.attr("class", ["x_ticks_d3", this.ticksTreatment].join(" "))
.attr("transform", transform)
.call(axis.ticks(this.ticks).tickSubdivide(0).tickSize(this.tickSize));
var gridSize = (this.orientation == 'bottom' ? 1 : -1) * this.graph.height;
this.graph.vis
.append("svg:g")
.attr("class", "x_grid_d3")
.call(axis.ticks(this.ticks).tickSubdivide(0).tickSize(gridSize))
.selectAll('text')
.each(function() { this.parentNode.setAttribute('data-x-value', this.textContent) });
this._renderHeight = this.graph.height;
};
this._discoverSize = function(element, args) {
if (typeof window !== 'undefined') {
var style = window.getComputedStyle(element, null);
var elementHeight = parseInt(style.getPropertyValue('height'), 10);
if (!args.auto) {
var elementWidth = parseInt(style.getPropertyValue('width'), 10);
}
}
this.width = (args.width || elementWidth || this.graph.width) * (1 + berthRate);
this.height = args.height || elementHeight || 40;
};
this.initialize(args);
};

View File

@@ -0,0 +1,60 @@
Rickshaw.namespace('Rickshaw.Graph.Axis.Y.Scaled');
Rickshaw.Graph.Axis.Y.Scaled = Rickshaw.Class.create( Rickshaw.Graph.Axis.Y, {
initialize: function($super, args) {
if (typeof(args.scale) === 'undefined') {
throw new Error('Scaled requires scale');
}
this.scale = args.scale;
if (typeof(args.grid) === 'undefined') {
this.grid = true;
} else {
this.grid = args.grid;
}
$super(args);
},
_drawAxis: function($super, scale) {
// Adjust scale's domain to compensate for adjustments to the
// renderer's domain (e.g. padding).
var domain = this.scale.domain();
var renderDomain = this.graph.renderer.domain().y;
var extents = [
Math.min.apply(Math, domain),
Math.max.apply(Math, domain)];
// A mapping from the ideal render domain [0, 1] to the extent
// of the original scale's domain. This is used to calculate
// the extents of the adjusted domain.
var extentMap = d3.scale.linear().domain([0, 1]).range(extents);
var adjExtents = [
extentMap(renderDomain[0]),
extentMap(renderDomain[1])];
// A mapping from the original domain to the adjusted domain.
var adjustment = d3.scale.linear().domain(extents).range(adjExtents);
// Make a copy of the custom scale, apply the adjusted domain, and
// copy the range to match the graph's scale.
var adjustedScale = this.scale.copy()
.domain(domain.map(adjustment))
.range(scale.range());
return $super(adjustedScale);
},
_drawGrid: function($super, axis) {
if (this.grid) {
// only draw the axis if the grid option is true
$super(axis);
}
}
} );

View File

@@ -0,0 +1,117 @@
Rickshaw.namespace('Rickshaw.Graph.Axis.Y');
Rickshaw.Graph.Axis.Y = Rickshaw.Class.create( {
initialize: function(args) {
this.graph = args.graph;
this.orientation = args.orientation || 'right';
this.pixelsPerTick = args.pixelsPerTick || 75;
if (args.ticks) this.staticTicks = args.ticks;
if (args.tickValues) this.tickValues = args.tickValues;
this.tickSize = args.tickSize || 4;
this.ticksTreatment = args.ticksTreatment || 'plain';
this.tickFormat = args.tickFormat || function(y) { return y };
this.berthRate = 0.10;
if (args.element) {
this.element = args.element;
this.vis = d3.select(args.element)
.append("svg:svg")
.attr('class', 'rickshaw_graph y_axis');
this.element = this.vis[0][0];
this.element.style.position = 'relative';
this.setSize({ width: args.width, height: args.height });
} else {
this.vis = this.graph.vis;
}
var self = this;
this.graph.onUpdate( function() { self.render() } );
},
setSize: function(args) {
args = args || {};
if (!this.element) return;
if (typeof window !== 'undefined') {
var style = window.getComputedStyle(this.element.parentNode, null);
var elementWidth = parseInt(style.getPropertyValue('width'), 10);
if (!args.auto) {
var elementHeight = parseInt(style.getPropertyValue('height'), 10);
}
}
this.width = args.width || elementWidth || this.graph.width * this.berthRate;
this.height = args.height || elementHeight || this.graph.height;
this.vis
.attr('width', this.width)
.attr('height', this.height * (1 + this.berthRate));
var berth = this.height * this.berthRate;
if (this.orientation == 'left') {
this.element.style.top = -1 * berth + 'px';
}
},
render: function() {
if (this._renderHeight !== undefined && this.graph.height !== this._renderHeight) this.setSize({ auto: true });
this.ticks = this.staticTicks || Math.floor(this.graph.height / this.pixelsPerTick);
var axis = this._drawAxis(this.graph.y);
this._drawGrid(axis);
this._renderHeight = this.graph.height;
},
_drawAxis: function(scale) {
var axis = d3.svg.axis().scale(scale).orient(this.orientation);
axis.tickFormat(this.tickFormat);
if (this.tickValues) axis.tickValues(this.tickValues);
if (this.orientation == 'left') {
var berth = this.height * this.berthRate;
var transform = 'translate(' + this.width + ', ' + berth + ')';
}
if (this.element) {
this.vis.selectAll('*').remove();
}
this.vis
.append("svg:g")
.attr("class", ["y_ticks", this.ticksTreatment].join(" "))
.attr("transform", transform)
.call(axis.ticks(this.ticks).tickSubdivide(0).tickSize(this.tickSize));
return axis;
},
_drawGrid: function(axis) {
var gridSize = (this.orientation == 'right' ? 1 : -1) * this.graph.width;
this.graph.vis
.append("svg:g")
.attr("class", "y_grid")
.call(axis.ticks(this.ticks).tickSubdivide(0).tickSize(gridSize))
.selectAll('text')
.each(function() { this.parentNode.setAttribute('data-y-value', this.textContent) });
}
} );

View File

@@ -0,0 +1,80 @@
Rickshaw.namespace('Rickshaw.Graph.Behavior.Series.Highlight');
Rickshaw.Graph.Behavior.Series.Highlight = function(args) {
this.graph = args.graph;
this.legend = args.legend;
var self = this;
var colorSafe = {};
var activeLine = null;
var disabledColor = args.disabledColor || function(seriesColor) {
return d3.interpolateRgb(seriesColor, d3.rgb('#d8d8d8'))(0.8).toString();
};
this.addHighlightEvents = function (l) {
l.element.addEventListener( 'mouseover', function(e) {
if (activeLine) return;
else activeLine = l;
self.legend.lines.forEach( function(line) {
if (l === line) {
// if we're not in a stacked renderer bring active line to the top
if (self.graph.renderer.unstack && (line.series.renderer ? line.series.renderer.unstack : true)) {
var seriesIndex = self.graph.series.indexOf(line.series);
line.originalIndex = seriesIndex;
var series = self.graph.series.splice(seriesIndex, 1)[0];
self.graph.series.push(series);
}
return;
}
colorSafe[line.series.name] = colorSafe[line.series.name] || line.series.color;
line.series.color = disabledColor(line.series.color);
} );
self.graph.update();
}, false );
l.element.addEventListener( 'mouseout', function(e) {
if (!activeLine) return;
else activeLine = null;
self.legend.lines.forEach( function(line) {
// return reordered series to its original place
if (l === line && line.hasOwnProperty('originalIndex')) {
var series = self.graph.series.pop();
self.graph.series.splice(line.originalIndex, 0, series);
delete line.originalIndex;
}
if (colorSafe[line.series.name]) {
line.series.color = colorSafe[line.series.name];
}
} );
self.graph.update();
}, false );
};
if (this.legend) {
this.legend.lines.forEach( function(l) {
self.addHighlightEvents(l);
} );
}
};

View File

@@ -0,0 +1,44 @@
Rickshaw.namespace('Rickshaw.Graph.Behavior.Series.Order');
Rickshaw.Graph.Behavior.Series.Order = function(args) {
this.graph = args.graph;
this.legend = args.legend;
var self = this;
if (typeof window.jQuery == 'undefined') {
throw "couldn't find jQuery at window.jQuery";
}
if (typeof window.jQuery.ui == 'undefined') {
throw "couldn't find jQuery UI at window.jQuery.ui";
}
jQuery(function() {
jQuery(self.legend.list).sortable( {
containment: 'parent',
tolerance: 'pointer',
update: function( event, ui ) {
var series = [];
jQuery(self.legend.list).find('li').each( function(index, item) {
if (!item.series) return;
series.push(item.series);
} );
for (var i = self.graph.series.length - 1; i >= 0; i--) {
self.graph.series[i] = series.shift();
}
self.graph.update();
}
} );
jQuery(self.legend.list).disableSelection();
});
//hack to make jquery-ui sortable behave
this.graph.onUpdate( function() {
var h = window.getComputedStyle(self.legend.element).height;
self.legend.element.style.height = h;
} );
};

View File

@@ -0,0 +1,126 @@
Rickshaw.namespace('Rickshaw.Graph.Behavior.Series.Toggle');
Rickshaw.Graph.Behavior.Series.Toggle = function(args) {
this.graph = args.graph;
this.legend = args.legend;
var self = this;
this.addAnchor = function(line) {
var anchor = document.createElement('a');
anchor.innerHTML = '&#10004;';
anchor.classList.add('action');
line.element.insertBefore(anchor, line.element.firstChild);
anchor.onclick = function(e) {
if (line.series.disabled) {
line.series.enable();
line.element.classList.remove('disabled');
} else {
if (this.graph.series.filter(function(s) { return !s.disabled }).length <= 1) return;
line.series.disable();
line.element.classList.add('disabled');
}
}.bind(this);
var label = line.element.getElementsByTagName('span')[0];
label.onclick = function(e){
var disableAllOtherLines = line.series.disabled;
if ( ! disableAllOtherLines ) {
for ( var i = 0; i < self.legend.lines.length; i++ ) {
var l = self.legend.lines[i];
if ( line.series === l.series ) {
// noop
} else if ( l.series.disabled ) {
// noop
} else {
disableAllOtherLines = true;
break;
}
}
}
// show all or none
if ( disableAllOtherLines ) {
// these must happen first or else we try ( and probably fail ) to make a no line graph
line.series.enable();
line.element.classList.remove('disabled');
self.legend.lines.forEach(function(l){
if ( line.series === l.series ) {
// noop
} else {
l.series.disable();
l.element.classList.add('disabled');
}
});
} else {
self.legend.lines.forEach(function(l){
l.series.enable();
l.element.classList.remove('disabled');
});
}
};
};
if (this.legend) {
var $ = jQuery;
if (typeof $ != 'undefined' && $(this.legend.list).sortable) {
$(this.legend.list).sortable( {
start: function(event, ui) {
ui.item.bind('no.onclick',
function(event) {
event.preventDefault();
}
);
},
stop: function(event, ui) {
setTimeout(function(){
ui.item.unbind('no.onclick');
}, 250);
}
});
}
this.legend.lines.forEach( function(l) {
self.addAnchor(l);
} );
}
this._addBehavior = function() {
this.graph.series.forEach( function(s) {
s.disable = function() {
if (self.graph.series.length <= 1) {
throw('only one series left');
}
s.disabled = true;
self.graph.update();
};
s.enable = function() {
s.disabled = false;
self.graph.update();
};
} );
};
this._addBehavior();
this.updateBehaviour = function () { this._addBehavior() };
};

View File

@@ -0,0 +1,277 @@
Rickshaw.namespace('Rickshaw.Graph.HoverDetail');
Rickshaw.Graph.HoverDetail = Rickshaw.Class.create({
initialize: function(args) {
var graph = this.graph = args.graph;
this.xFormatter = args.xFormatter || function(x) {
return new Date( x * 1000 ).toUTCString();
};
this.yFormatter = args.yFormatter || function(y) {
return y === null ? y : y.toFixed(2);
};
var element = this.element = document.createElement('div');
element.className = 'detail';
this.visible = true;
graph.element.appendChild(element);
this.lastEvent = null;
this._addListeners();
this.onShow = args.onShow;
this.onHide = args.onHide;
this.onRender = args.onRender;
this.formatter = args.formatter || this.formatter;
},
formatter: function(series, x, y, formattedX, formattedY, d) {
return series.name + ':&nbsp;' + formattedY;
},
update: function(e) {
e = e || this.lastEvent;
if (!e) return;
this.lastEvent = e;
if (!e.target.nodeName.match(/^(path|svg|rect|circle)$/)) return;
var graph = this.graph;
var eventX = e.offsetX || e.layerX;
var eventY = e.offsetY || e.layerY;
var j = 0;
var points = [];
var nearestPoint;
this.graph.series.active().forEach( function(series) {
var data = this.graph.stackedData[j++];
if (!data.length)
return;
var domainX = graph.x.invert(eventX);
var domainIndexScale = d3.scale.linear()
.domain([data[0].x, data.slice(-1)[0].x])
.range([0, data.length - 1]);
var approximateIndex = Math.round(domainIndexScale(domainX));
if (approximateIndex == data.length - 1) approximateIndex--;
var dataIndex = Math.min(approximateIndex || 0, data.length - 1);
for (var i = approximateIndex; i < data.length - 1;) {
if (!data[i] || !data[i + 1]) break;
if (data[i].x <= domainX && data[i + 1].x > domainX) {
dataIndex = Math.abs(domainX - data[i].x) < Math.abs(domainX - data[i + 1].x) ? i : i + 1;
break;
}
if (data[i + 1].x <= domainX) { i++ } else { i-- }
}
if (dataIndex < 0) dataIndex = 0;
var value = data[dataIndex];
var distance = Math.sqrt(
Math.pow(Math.abs(graph.x(value.x) - eventX), 2) +
Math.pow(Math.abs(graph.y(value.y + value.y0) - eventY), 2)
);
var xFormatter = series.xFormatter || this.xFormatter;
var yFormatter = series.yFormatter || this.yFormatter;
var point = {
formattedXValue: xFormatter(value.x),
formattedYValue: yFormatter(series.scale ? series.scale.invert(value.y) : value.y),
series: series,
value: value,
distance: distance,
order: j,
name: series.name
};
if (!nearestPoint || distance < nearestPoint.distance) {
nearestPoint = point;
}
points.push(point);
}, this );
if (!nearestPoint)
return;
nearestPoint.active = true;
var domainX = nearestPoint.value.x;
var formattedXValue = nearestPoint.formattedXValue;
this.element.innerHTML = '';
this.element.style.left = graph.x(domainX) + 'px';
this.visible && this.render( {
points: points,
detail: points, // for backwards compatibility
mouseX: eventX,
mouseY: eventY,
formattedXValue: formattedXValue,
domainX: domainX
} );
},
hide: function() {
this.visible = false;
this.element.classList.add('inactive');
if (typeof this.onHide == 'function') {
this.onHide();
}
},
show: function() {
this.visible = true;
this.element.classList.remove('inactive');
if (typeof this.onShow == 'function') {
this.onShow();
}
},
render: function(args) {
var graph = this.graph;
var points = args.points;
var point = points.filter( function(p) { return p.active } ).shift();
if (point.value.y === null) return;
var formattedXValue = point.formattedXValue;
var formattedYValue = point.formattedYValue;
this.element.innerHTML = '';
this.element.style.left = graph.x(point.value.x) + 'px';
var xLabel = document.createElement('div');
xLabel.className = 'x_label';
xLabel.innerHTML = formattedXValue;
this.element.appendChild(xLabel);
var item = document.createElement('div');
item.className = 'item';
// invert the scale if this series displays using a scale
var series = point.series;
var actualY = series.scale ? series.scale.invert(point.value.y) : point.value.y;
item.innerHTML = this.formatter(series, point.value.x, actualY, formattedXValue, formattedYValue, point);
item.style.top = this.graph.y(point.value.y0 + point.value.y) + 'px';
this.element.appendChild(item);
var dot = document.createElement('div');
dot.className = 'dot';
dot.style.top = item.style.top;
dot.style.borderColor = series.color;
this.element.appendChild(dot);
if (point.active) {
item.classList.add('active');
dot.classList.add('active');
}
// Assume left alignment until the element has been displayed and
// bounding box calculations are possible.
var alignables = [xLabel, item];
alignables.forEach(function(el) {
el.classList.add('left');
});
this.show();
// If left-alignment results in any error, try right-alignment.
var leftAlignError = this._calcLayoutError(alignables);
if (leftAlignError > 0) {
alignables.forEach(function(el) {
el.classList.remove('left');
el.classList.add('right');
});
// If right-alignment is worse than left alignment, switch back.
var rightAlignError = this._calcLayoutError(alignables);
if (rightAlignError > leftAlignError) {
alignables.forEach(function(el) {
el.classList.remove('right');
el.classList.add('left');
});
}
}
if (typeof this.onRender == 'function') {
this.onRender(args);
}
},
_calcLayoutError: function(alignables) {
// Layout error is calculated as the number of linear pixels by which
// an alignable extends past the left or right edge of the parent.
var parentRect = this.element.parentNode.getBoundingClientRect();
var error = 0;
var alignRight = alignables.forEach(function(el) {
var rect = el.getBoundingClientRect();
if (!rect.width) {
return;
}
if (rect.right > parentRect.right) {
error += rect.right - parentRect.right;
}
if (rect.left < parentRect.left) {
error += parentRect.left - rect.left;
}
});
return error;
},
_addListeners: function() {
this.graph.element.addEventListener(
'mousemove',
function(e) {
this.visible = true;
this.update(e);
}.bind(this),
false
);
this.graph.onUpdate( function() { this.update() }.bind(this) );
this.graph.element.addEventListener(
'mouseout',
function(e) {
if (e.relatedTarget && !(e.relatedTarget.compareDocumentPosition(this.graph.element) & Node.DOCUMENT_POSITION_CONTAINS)) {
this.hide();
}
}.bind(this),
false
);
}
});

View File

@@ -0,0 +1,14 @@
Rickshaw.namespace('Rickshaw.Graph.JSONP');
Rickshaw.Graph.JSONP = Rickshaw.Class.create( Rickshaw.Graph.Ajax, {
request: function() {
jQuery.ajax( {
url: this.dataURL,
dataType: 'jsonp',
success: this.success.bind(this),
error: this.error.bind(this)
} );
}
} );

View File

@@ -0,0 +1,87 @@
Rickshaw.namespace('Rickshaw.Graph.Legend');
Rickshaw.Graph.Legend = Rickshaw.Class.create( {
className: 'rickshaw_legend',
initialize: function(args) {
this.element = args.element;
this.graph = args.graph;
this.naturalOrder = args.naturalOrder;
this.element.classList.add(this.className);
this.list = document.createElement('ul');
this.element.appendChild(this.list);
this.render();
// we could bind this.render.bind(this) here
// but triggering the re-render would lose the added
// behavior of the series toggle
this.graph.onUpdate( function() {} );
},
render: function() {
var self = this;
while ( this.list.firstChild ) {
this.list.removeChild( this.list.firstChild );
}
this.lines = [];
var series = this.graph.series
.map( function(s) { return s } );
if (!this.naturalOrder) {
series = series.reverse();
}
series.forEach( function(s) {
self.addLine(s);
} );
},
addLine: function (series) {
var line = document.createElement('li');
line.className = 'line';
if (series.disabled) {
line.className += ' disabled';
}
if (series.className) {
d3.select(line).classed(series.className, true);
}
var swatch = document.createElement('div');
swatch.className = 'swatch';
swatch.style.backgroundColor = series.color;
line.appendChild(swatch);
var label = document.createElement('span');
label.className = 'label';
label.innerHTML = series.name;
line.appendChild(label);
this.list.appendChild(line);
line.series = series;
if (series.noLegend) {
line.style.display = 'none';
}
var _line = { element: line, series: series };
if (this.shelving) {
this.shelving.addAnchor(_line);
this.shelving.updateBehaviour();
}
if (this.highlighter) {
this.highlighter.addHighlightEvents(_line);
}
this.lines.push(_line);
return line;
}
} );

View File

@@ -0,0 +1,452 @@
Rickshaw.namespace('Rickshaw.Graph.RangeSlider.Preview');
Rickshaw.Graph.RangeSlider.Preview = Rickshaw.Class.create({
initialize: function(args) {
if (!args.element) throw "Rickshaw.Graph.RangeSlider.Preview needs a reference to an element";
if (!args.graph && !args.graphs) throw "Rickshaw.Graph.RangeSlider.Preview needs a reference to an graph or an array of graphs";
this.element = args.element;
this.graphs = args.graph ? [ args.graph ] : args.graphs;
this.defaults = {
height: 75,
width: 400,
gripperColor: undefined,
frameTopThickness: 3,
frameHandleThickness: 10,
frameColor: "#d4d4d4",
frameOpacity: 1,
minimumFrameWidth: 0
};
this.defaults.gripperColor = d3.rgb(this.defaults.frameColor).darker().toString();
this.configureCallbacks = [];
this.slideCallbacks = [];
this.previews = [];
args.width = args.width || this.graphs[0].width || this.defaults.width;
args.height = args.height || this.graphs[0].height / 5 || this.defaults.height;
this.configure(args);
this.render();
},
onSlide: function(callback) {
this.slideCallbacks.push(callback);
},
onConfigure: function(callback) {
this.configureCallbacks.push(callback);
},
configure: function(args) {
this.config = {};
this.configureCallbacks.forEach(function(callback) {
callback(args);
});
Rickshaw.keys(this.defaults).forEach(function(k) {
this.config[k] = k in args ? args[k]
: k in this.config ? this.config[k]
: this.defaults[k];
}, this);
if (args.width) {
this.previews.forEach(function(preview) {
var width = args.width - this.config.frameHandleThickness * 2;
preview.setSize({ width: width });
}, this);
}
if (args.height) {
this.previews.forEach(function(preview) {
var height = this.previewHeight / this.graphs.length;
preview.setSize({ height: height });
}, this);
}
},
render: function() {
var self = this;
this.svg = d3.select(this.element)
.selectAll("svg.rickshaw_range_slider_preview")
.data([null]);
this.previewHeight = this.config.height - (this.config.frameTopThickness * 2);
this.previewWidth = this.config.width - (this.config.frameHandleThickness * 2);
this.currentFrame = [0, this.previewWidth];
var buildGraph = function(parent, index) {
var graphArgs = Rickshaw.extend({}, parent.config);
var height = self.previewHeight / self.graphs.length;
var renderer = parent.renderer.name;
Rickshaw.extend(graphArgs, {
element: this.appendChild(document.createElement("div")),
height: height,
width: self.previewWidth,
series: parent.series,
renderer: renderer
});
var graph = new Rickshaw.Graph(graphArgs);
self.previews.push(graph);
parent.onUpdate(function() { graph.render(); self.render() });
parent.onConfigure(function(args) {
// don't propagate height
delete args.height;
graph.configure(args);
graph.render();
});
graph.render();
};
var graphContainer = d3.select(this.element)
.selectAll("div.rickshaw_range_slider_preview_container")
.data(this.graphs);
var translateCommand = "translate(" +
this.config.frameHandleThickness + "px, " +
this.config.frameTopThickness + "px)";
graphContainer.enter()
.append("div")
.classed("rickshaw_range_slider_preview_container", true)
.style("-webkit-transform", translateCommand)
.style("-moz-transform", translateCommand)
.style("-ms-transform", translateCommand)
.style("transform", translateCommand)
.each(buildGraph);
graphContainer.exit()
.remove();
// Use the first graph as the "master" for the frame state
var masterGraph = this.graphs[0];
var domainScale = d3.scale.linear()
.domain([0, this.previewWidth])
.range(masterGraph.dataDomain());
var currentWindow = [masterGraph.window.xMin, masterGraph.window.xMax];
this.currentFrame[0] = currentWindow[0] === undefined ?
0 : Math.round(domainScale.invert(currentWindow[0]));
if (this.currentFrame[0] < 0) this.currentFrame[0] = 0;
this.currentFrame[1] = currentWindow[1] === undefined ?
this.previewWidth : domainScale.invert(currentWindow[1]);
if (this.currentFrame[1] - this.currentFrame[0] < self.config.minimumFrameWidth) {
this.currentFrame[1] = (this.currentFrame[0] || 0) + self.config.minimumFrameWidth;
}
this.svg.enter()
.append("svg")
.classed("rickshaw_range_slider_preview", true)
.style("height", this.config.height + "px")
.style("width", this.config.width + "px")
.style("position", "relative")
.style("top", -this.previewHeight + "px");
this._renderDimming();
this._renderFrame();
this._renderGrippers();
this._renderHandles();
this._renderMiddle();
this._registerMouseEvents();
},
_renderDimming: function() {
var element = this.svg
.selectAll("path.dimming")
.data([null]);
element.enter()
.append("path")
.attr("fill", "white")
.attr("fill-opacity", "0.7")
.attr("fill-rule", "evenodd")
.classed("dimming", true);
var path = "";
path += " M " + this.config.frameHandleThickness + " " + this.config.frameTopThickness;
path += " h " + this.previewWidth;
path += " v " + this.previewHeight;
path += " h " + -this.previewWidth;
path += " z ";
path += " M " + Math.max(this.currentFrame[0], this.config.frameHandleThickness) + " " + this.config.frameTopThickness;
path += " H " + Math.min(this.currentFrame[1] + this.config.frameHandleThickness * 2, this.previewWidth + this.config.frameHandleThickness);
path += " v " + this.previewHeight;
path += " H " + Math.max(this.currentFrame[0], this.config.frameHandleThickness);
path += " z";
element.attr("d", path);
},
_renderFrame: function() {
var element = this.svg
.selectAll("path.frame")
.data([null]);
element.enter()
.append("path")
.attr("stroke", "white")
.attr("stroke-width", "1px")
.attr("stroke-linejoin", "round")
.attr("fill", this.config.frameColor)
.attr("fill-opacity", this.config.frameOpacity)
.attr("fill-rule", "evenodd")
.classed("frame", true);
var path = "";
path += " M " + this.currentFrame[0] + " 0";
path += " H " + (this.currentFrame[1] + (this.config.frameHandleThickness * 2));
path += " V " + this.config.height;
path += " H " + (this.currentFrame[0]);
path += " z";
path += " M " + (this.currentFrame[0] + this.config.frameHandleThickness) + " " + this.config.frameTopThickness;
path += " H " + (this.currentFrame[1] + this.config.frameHandleThickness);
path += " v " + this.previewHeight;
path += " H " + (this.currentFrame[0] + this.config.frameHandleThickness);
path += " z";
element.attr("d", path);
},
_renderGrippers: function() {
var gripper = this.svg.selectAll("path.gripper")
.data([null]);
gripper.enter()
.append("path")
.attr("stroke", this.config.gripperColor)
.classed("gripper", true);
var path = "";
[0.4, 0.6].forEach(function(spacing) {
path += " M " + Math.round((this.currentFrame[0] + (this.config.frameHandleThickness * spacing))) + " " + Math.round(this.config.height * 0.3);
path += " V " + Math.round(this.config.height * 0.7);
path += " M " + Math.round((this.currentFrame[1] + (this.config.frameHandleThickness * (1 + spacing)))) + " " + Math.round(this.config.height * 0.3);
path += " V " + Math.round(this.config.height * 0.7);
}.bind(this));
gripper.attr("d", path);
},
_renderHandles: function() {
var leftHandle = this.svg.selectAll("rect.left_handle")
.data([null]);
leftHandle.enter()
.append("rect")
.attr('width', this.config.frameHandleThickness)
.attr('height', this.config.height)
.style("cursor", "ew-resize")
.style("fill-opacity", "0")
.classed("left_handle", true);
leftHandle.attr('x', this.currentFrame[0]);
var rightHandle = this.svg.selectAll("rect.right_handle")
.data([null]);
rightHandle.enter()
.append("rect")
.attr('width', this.config.frameHandleThickness)
.attr('height', this.config.height)
.style("cursor", "ew-resize")
.style("fill-opacity", "0")
.classed("right_handle", true);
rightHandle.attr('x', this.currentFrame[1] + this.config.frameHandleThickness);
},
_renderMiddle: function() {
var middleHandle = this.svg.selectAll("rect.middle_handle")
.data([null]);
middleHandle.enter()
.append("rect")
.attr('height', this.config.height)
.style("cursor", "move")
.style("fill-opacity", "0")
.classed("middle_handle", true);
middleHandle
.attr('width', Math.max(0, this.currentFrame[1] - this.currentFrame[0]))
.attr('x', this.currentFrame[0] + this.config.frameHandleThickness);
},
_registerMouseEvents: function() {
var element = d3.select(this.element);
var drag = {
target: null,
start: null,
stop: null,
left: false,
right: false,
rigid: false
};
var self = this;
function onMousemove(datum, index) {
drag.stop = self._getClientXFromEvent(d3.event, drag);
var distanceTraveled = drag.stop - drag.start;
var frameAfterDrag = self.frameBeforeDrag.slice(0);
var minimumFrameWidth = self.config.minimumFrameWidth;
if (drag.rigid) {
minimumFrameWidth = self.frameBeforeDrag[1] - self.frameBeforeDrag[0];
}
if (drag.left) {
frameAfterDrag[0] = Math.max(frameAfterDrag[0] + distanceTraveled, 0);
}
if (drag.right) {
frameAfterDrag[1] = Math.min(frameAfterDrag[1] + distanceTraveled, self.previewWidth);
}
var currentFrameWidth = frameAfterDrag[1] - frameAfterDrag[0];
if (currentFrameWidth <= minimumFrameWidth) {
if (drag.left) {
frameAfterDrag[0] = frameAfterDrag[1] - minimumFrameWidth;
}
if (drag.right) {
frameAfterDrag[1] = frameAfterDrag[0] + minimumFrameWidth;
}
if (frameAfterDrag[0] <= 0) {
frameAfterDrag[1] -= frameAfterDrag[0];
frameAfterDrag[0] = 0;
}
if (frameAfterDrag[1] >= self.previewWidth) {
frameAfterDrag[0] -= (frameAfterDrag[1] - self.previewWidth);
frameAfterDrag[1] = self.previewWidth;
}
}
self.graphs.forEach(function(graph) {
var domainScale = d3.scale.linear()
.interpolate(d3.interpolateNumber)
.domain([0, self.previewWidth])
.range(graph.dataDomain());
var windowAfterDrag = [
domainScale(frameAfterDrag[0]),
domainScale(frameAfterDrag[1])
];
self.slideCallbacks.forEach(function(callback) {
callback(graph, windowAfterDrag[0], windowAfterDrag[1]);
});
if (frameAfterDrag[0] === 0) {
windowAfterDrag[0] = undefined;
}
if (frameAfterDrag[1] === self.previewWidth) {
windowAfterDrag[1] = undefined;
}
graph.window.xMin = windowAfterDrag[0];
graph.window.xMax = windowAfterDrag[1];
graph.update();
});
}
function onMousedown() {
drag.target = d3.event.target;
drag.start = self._getClientXFromEvent(d3.event, drag);
self.frameBeforeDrag = self.currentFrame.slice();
d3.event.preventDefault ? d3.event.preventDefault() : d3.event.returnValue = false;
d3.select(document).on("mousemove.rickshaw_range_slider_preview", onMousemove);
d3.select(document).on("mouseup.rickshaw_range_slider_preview", onMouseup);
d3.select(document).on("touchmove.rickshaw_range_slider_preview", onMousemove);
d3.select(document).on("touchend.rickshaw_range_slider_preview", onMouseup);
d3.select(document).on("touchcancel.rickshaw_range_slider_preview", onMouseup);
}
function onMousedownLeftHandle(datum, index) {
drag.left = true;
onMousedown();
}
function onMousedownRightHandle(datum, index) {
drag.right = true;
onMousedown();
}
function onMousedownMiddleHandle(datum, index) {
drag.left = true;
drag.right = true;
drag.rigid = true;
onMousedown();
}
function onMouseup(datum, index) {
d3.select(document).on("mousemove.rickshaw_range_slider_preview", null);
d3.select(document).on("mouseup.rickshaw_range_slider_preview", null);
d3.select(document).on("touchmove.rickshaw_range_slider_preview", null);
d3.select(document).on("touchend.rickshaw_range_slider_preview", null);
d3.select(document).on("touchcancel.rickshaw_range_slider_preview", null);
delete self.frameBeforeDrag;
drag.left = false;
drag.right = false;
drag.rigid = false;
}
element.select("rect.left_handle").on("mousedown", onMousedownLeftHandle);
element.select("rect.right_handle").on("mousedown", onMousedownRightHandle);
element.select("rect.middle_handle").on("mousedown", onMousedownMiddleHandle);
element.select("rect.left_handle").on("touchstart", onMousedownLeftHandle);
element.select("rect.right_handle").on("touchstart", onMousedownRightHandle);
element.select("rect.middle_handle").on("touchstart", onMousedownMiddleHandle);
},
_getClientXFromEvent: function(event, drag) {
switch (event.type) {
case 'touchstart':
case 'touchmove':
var touchList = event.changedTouches;
var touch = null;
for (var touchIndex = 0; touchIndex < touchList.length; touchIndex++) {
if (touchList[touchIndex].target === drag.target) {
touch = touchList[touchIndex];
break;
}
}
return touch !== null ? touch.clientX : undefined;
default:
return event.clientX;
}
}
});

View File

@@ -0,0 +1,92 @@
Rickshaw.namespace('Rickshaw.Graph.RangeSlider');
Rickshaw.Graph.RangeSlider = Rickshaw.Class.create({
initialize: function(args) {
var element = this.element = args.element;
var graph = this.graph = args.graph;
this.slideCallbacks = [];
this.build();
graph.onUpdate( function() { this.update() }.bind(this) );
},
build: function() {
var element = this.element;
var graph = this.graph;
var $ = jQuery;
var domain = graph.dataDomain();
var self = this;
$( function() {
$(element).slider( {
range: true,
min: domain[0],
max: domain[1],
values: [
domain[0],
domain[1]
],
slide: function( event, ui ) {
if (ui.values[1] <= ui.values[0]) return;
graph.window.xMin = ui.values[0];
graph.window.xMax = ui.values[1];
graph.update();
var domain = graph.dataDomain();
// if we're at an extreme, stick there
if (domain[0] == ui.values[0]) {
graph.window.xMin = undefined;
}
if (domain[1] == ui.values[1]) {
graph.window.xMax = undefined;
}
self.slideCallbacks.forEach(function(callback) {
callback(graph, graph.window.xMin, graph.window.xMax);
});
}
} );
} );
$(element)[0].style.width = graph.width + 'px';
},
update: function() {
var element = this.element;
var graph = this.graph;
var $ = jQuery;
var values = $(element).slider('option', 'values');
var domain = graph.dataDomain();
$(element).slider('option', 'min', domain[0]);
$(element).slider('option', 'max', domain[1]);
if (graph.window.xMin == null) {
values[0] = domain[0];
}
if (graph.window.xMax == null) {
values[1] = domain[1];
}
$(element).slider('option', 'values', values);
},
onSlide: function(callback) {
this.slideCallbacks.push(callback);
}
});

View File

@@ -0,0 +1,101 @@
Rickshaw.namespace('Rickshaw.Graph.Renderer.Area');
Rickshaw.Graph.Renderer.Area = Rickshaw.Class.create( Rickshaw.Graph.Renderer, {
name: 'area',
defaults: function($super) {
return Rickshaw.extend( $super(), {
unstack: false,
fill: false,
stroke: false
} );
},
seriesPathFactory: function() {
var graph = this.graph;
var factory = d3.svg.area()
.x( function(d) { return graph.x(d.x) } )
.y0( function(d) { return graph.y(d.y0) } )
.y1( function(d) { return graph.y(d.y + d.y0) } )
.interpolate(graph.interpolation).tension(this.tension);
factory.defined && factory.defined( function(d) { return d.y !== null } );
return factory;
},
seriesStrokeFactory: function() {
var graph = this.graph;
var factory = d3.svg.line()
.x( function(d) { return graph.x(d.x) } )
.y( function(d) { return graph.y(d.y + d.y0) } )
.interpolate(graph.interpolation).tension(this.tension);
factory.defined && factory.defined( function(d) { return d.y !== null } );
return factory;
},
render: function(args) {
args = args || {};
var graph = this.graph;
var series = args.series || graph.series;
var vis = args.vis || graph.vis;
vis.selectAll('*').remove();
// insert or stacked areas so strokes lay on top of areas
var method = this.unstack ? 'append' : 'insert';
var data = series
.filter(function(s) { return !s.disabled })
.map(function(s) { return s.stack });
var nodes = vis.selectAll("path")
.data(data)
.enter()[method]("svg:g", 'g');
nodes.append("svg:path")
.attr("d", this.seriesPathFactory())
.attr("class", 'area');
if (this.stroke) {
nodes.append("svg:path")
.attr("d", this.seriesStrokeFactory())
.attr("class", 'line');
}
var i = 0;
series.forEach( function(series) {
if (series.disabled) return;
series.path = nodes[0][i++];
this._styleSeries(series);
}, this );
},
_styleSeries: function(series) {
if (!series.path) return;
d3.select(series.path).select('.area')
.attr('fill', series.color);
if (this.stroke) {
d3.select(series.path).select('.line')
.attr('fill', 'none')
.attr('stroke', series.stroke || d3.interpolateRgb(series.color, 'black')(0.125))
.attr('stroke-width', this.strokeWidth);
}
if (series.className) {
series.path.setAttribute('class', series.className);
}
}
} );

View File

@@ -0,0 +1,112 @@
Rickshaw.namespace('Rickshaw.Graph.Renderer.Bar');
Rickshaw.Graph.Renderer.Bar = Rickshaw.Class.create( Rickshaw.Graph.Renderer, {
name: 'bar',
defaults: function($super) {
var defaults = Rickshaw.extend( $super(), {
gapSize: 0.05,
unstack: false
} );
delete defaults.tension;
return defaults;
},
initialize: function($super, args) {
args = args || {};
this.gapSize = args.gapSize || this.gapSize;
$super(args);
},
domain: function($super) {
var domain = $super();
var frequentInterval = this._frequentInterval(this.graph.stackedData.slice(-1).shift());
domain.x[1] += Number(frequentInterval.magnitude);
return domain;
},
barWidth: function(series) {
var frequentInterval = this._frequentInterval(series.stack);
var barWidth = this.graph.x(series.stack[0].x + frequentInterval.magnitude * (1 - this.gapSize));
return barWidth;
},
render: function(args) {
args = args || {};
var graph = this.graph;
var series = args.series || graph.series;
var vis = args.vis || graph.vis;
vis.selectAll('*').remove();
var barWidth = this.barWidth(series.active()[0]);
var barXOffset = 0;
var activeSeriesCount = series.filter( function(s) { return !s.disabled; } ).length;
var seriesBarWidth = this.unstack ? barWidth / activeSeriesCount : barWidth;
var transform = function(d) {
// add a matrix transform for negative values
var matrix = [ 1, 0, 0, (d.y < 0 ? -1 : 1), 0, (d.y < 0 ? graph.y.magnitude(Math.abs(d.y)) * 2 : 0) ];
return "matrix(" + matrix.join(',') + ")";
};
series.forEach( function(series) {
if (series.disabled) return;
var barWidth = this.barWidth(series);
var nodes = vis.selectAll("path")
.data(series.stack.filter( function(d) { return d.y !== null } ))
.enter().append("svg:rect")
.attr("x", function(d) { return graph.x(d.x) + barXOffset })
.attr("y", function(d) { return (graph.y(d.y0 + Math.abs(d.y))) * (d.y < 0 ? -1 : 1 ) })
.attr("width", seriesBarWidth)
.attr("height", function(d) { return graph.y.magnitude(Math.abs(d.y)) })
.attr("transform", transform);
Array.prototype.forEach.call(nodes[0], function(n) {
n.setAttribute('fill', series.color);
} );
if (this.unstack) barXOffset += seriesBarWidth;
}, this );
},
_frequentInterval: function(data) {
var intervalCounts = {};
for (var i = 0; i < data.length - 1; i++) {
var interval = data[i + 1].x - data[i].x;
intervalCounts[interval] = intervalCounts[interval] || 0;
intervalCounts[interval]++;
}
var frequentInterval = { count: 0, magnitude: 1 };
Rickshaw.keys(intervalCounts).forEach( function(i) {
if (frequentInterval.count < intervalCounts[i]) {
frequentInterval = {
count: intervalCounts[i],
magnitude: i
};
}
} );
return frequentInterval;
}
} );

Some files were not shown because too many files have changed in this diff Show More