dashing 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +202 -0
- data/bin/dashing +82 -0
- data/javascripts/batman.jquery.js +109 -0
- data/javascripts/batman.js +11811 -0
- data/javascripts/dashing.coffee +96 -0
- data/javascripts/es5-shim.js +1021 -0
- data/javascripts/jquery.js +4 -0
- data/lib/dashing.rb +109 -0
- data/templates/dashboard/%name%.erb.tt +7 -0
- data/templates/job/%name%.rb +4 -0
- data/templates/project/Gemfile +3 -0
- data/templates/project/README.md +0 -0
- data/templates/project/assets/fonts/fontawesome-webfont.eot +0 -0
- data/templates/project/assets/fonts/fontawesome-webfont.svg +255 -0
- data/templates/project/assets/fonts/fontawesome-webfont.ttf +0 -0
- data/templates/project/assets/fonts/fontawesome-webfont.woff +0 -0
- data/templates/project/assets/images/favicon.ico +0 -0
- data/templates/project/assets/javascripts/application.coffee +24 -0
- data/templates/project/assets/javascripts/d3.v2.min.js +4 -0
- data/templates/project/assets/javascripts/dashing.gridster.coffee +32 -0
- data/templates/project/assets/javascripts/gridster/jquery.gridster.js +2890 -0
- data/templates/project/assets/javascripts/gridster/jquery.leanModal.min.js +5 -0
- data/templates/project/assets/javascripts/jquery.knob.js +646 -0
- data/templates/project/assets/javascripts/rickshaw.min.js +2 -0
- data/templates/project/assets/stylesheets/application.scss +229 -0
- data/templates/project/assets/stylesheets/font-awesome.css +303 -0
- data/templates/project/assets/stylesheets/jquery.gridster.css +57 -0
- data/templates/project/config.ru +18 -0
- data/templates/project/dashboards/layout.erb +32 -0
- data/templates/project/dashboards/sample.erb +25 -0
- data/templates/project/jobs/buzzwords.rb +9 -0
- data/templates/project/jobs/convergence.rb +13 -0
- data/templates/project/jobs/sample.rb +9 -0
- data/templates/project/lib/.empty_directory +1 -0
- data/templates/project/public/.empty_directory +1 -0
- data/templates/project/widgets/graph/graph.coffee +26 -0
- data/templates/project/widgets/graph/graph.html +5 -0
- data/templates/project/widgets/graph/graph.scss +51 -0
- data/templates/project/widgets/list/list.coffee +13 -0
- data/templates/project/widgets/list/list.html +15 -0
- data/templates/project/widgets/list/list.scss +52 -0
- data/templates/project/widgets/meter/meter.coffee +14 -0
- data/templates/project/widgets/meter/meter.html +5 -0
- data/templates/project/widgets/meter/meter.scss +37 -0
- data/templates/project/widgets/number/number.coffee +25 -0
- data/templates/project/widgets/number/number.html +9 -0
- data/templates/project/widgets/number/number.scss +35 -0
- data/templates/project/widgets/text/text.coffee +1 -0
- data/templates/project/widgets/text/text.html +5 -0
- data/templates/project/widgets/text/text.scss +25 -0
- data/templates/widget/%name%/%name%.coffee.tt +10 -0
- data/templates/widget/%name%/%name%.html +1 -0
- data/templates/widget/%name%/%name%.scss.tt +3 -0
- metadata +187 -0
@@ -0,0 +1,57 @@
|
|
1
|
+
/*! gridster.js - v0.1.0 - 2012-08-14
|
2
|
+
* http://gridster.net/
|
3
|
+
* Copyright (c) 2012 ducksboard; Licensed MIT */
|
4
|
+
|
5
|
+
.gridster {
|
6
|
+
position:relative;
|
7
|
+
}
|
8
|
+
|
9
|
+
.gridster > * {
|
10
|
+
margin: 0 auto;
|
11
|
+
-webkit-transition: height .4s;
|
12
|
+
-moz-transition: height .4s;
|
13
|
+
-o-transition: height .4s;
|
14
|
+
-ms-transition: height .4s;
|
15
|
+
transition: height .4s;
|
16
|
+
}
|
17
|
+
|
18
|
+
.gridster .gs_w{
|
19
|
+
z-index: 2;
|
20
|
+
position: absolute;
|
21
|
+
}
|
22
|
+
|
23
|
+
.ready .gs_w:not(.preview-holder) {
|
24
|
+
-webkit-transition: opacity .3s, left .3s, top .3s;
|
25
|
+
-moz-transition: opacity .3s, left .3s, top .3s;
|
26
|
+
-o-transition: opacity .3s, left .3s, top .3s;
|
27
|
+
transition: opacity .3s, left .3s, top .3s;
|
28
|
+
}
|
29
|
+
|
30
|
+
.gridster .preview-holder {
|
31
|
+
z-index: 1;
|
32
|
+
position: absolute;
|
33
|
+
background-color: #fff;
|
34
|
+
border-color: #fff;
|
35
|
+
opacity: 0.3;
|
36
|
+
}
|
37
|
+
|
38
|
+
.gridster .player-revert {
|
39
|
+
z-index: 10!important;
|
40
|
+
-webkit-transition: left .3s, top .3s!important;
|
41
|
+
-moz-transition: left .3s, top .3s!important;
|
42
|
+
-o-transition: left .3s, top .3s!important;
|
43
|
+
transition: left .3s, top .3s!important;
|
44
|
+
}
|
45
|
+
|
46
|
+
.gridster .dragging {
|
47
|
+
z-index: 10!important;
|
48
|
+
-webkit-transition: all 0s !important;
|
49
|
+
-moz-transition: all 0s !important;
|
50
|
+
-o-transition: all 0s !important;
|
51
|
+
transition: all 0s !important;
|
52
|
+
}
|
53
|
+
|
54
|
+
/* Uncomment this if you set helper : "clone" in draggable options */
|
55
|
+
/*.gridster .player {
|
56
|
+
opacity:0;
|
57
|
+
}*/
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'dashing'
|
2
|
+
|
3
|
+
configure do
|
4
|
+
set :auth_token, 'YOUR_AUTH_TOKEN'
|
5
|
+
|
6
|
+
helpers do
|
7
|
+
def protected!
|
8
|
+
# Put any authentication code you want in here.
|
9
|
+
# This method is run before accessing any resource.
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
map Sinatra::Application.assets_prefix do
|
15
|
+
run Sinatra::Application.sprockets
|
16
|
+
end
|
17
|
+
|
18
|
+
run Sinatra::Application
|
@@ -0,0 +1,32 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html lang="en">
|
3
|
+
<head>
|
4
|
+
<meta charset="utf-8"/>
|
5
|
+
<meta name="description" content="">
|
6
|
+
<meta name="viewport" content="width=device-width">
|
7
|
+
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
|
8
|
+
|
9
|
+
<title><%= yield_content(:title) %></title>
|
10
|
+
|
11
|
+
<!-- The javascript and css are managed by sprockets. The files can be found in the /assets folder-->
|
12
|
+
<script type="text/javascript" src="/assets/application.js"></script>
|
13
|
+
<link rel="stylesheet" href="/assets/application.css">
|
14
|
+
|
15
|
+
<link href='http://fonts.googleapis.com/css?family=Open+Sans:300,400,600,700' rel='stylesheet' type='text/css'>
|
16
|
+
<link rel="icon" href="/assets/favicon.ico">
|
17
|
+
|
18
|
+
</head>
|
19
|
+
<body>
|
20
|
+
<div id="container">
|
21
|
+
<%= yield %>
|
22
|
+
</div>
|
23
|
+
|
24
|
+
<% if development? %>
|
25
|
+
<div id="saving-instructions">
|
26
|
+
<p>Paste the following at the top of <i><%= params[:dashboard] %>.erb</i></p>
|
27
|
+
<textarea id="gridster-code"></textarea>
|
28
|
+
</div>
|
29
|
+
<a href="#saving-instructions" id="save-gridster">Save this layout</a>
|
30
|
+
<% end %>
|
31
|
+
</body>
|
32
|
+
</html>
|
@@ -0,0 +1,25 @@
|
|
1
|
+
<% content_for(:title) { "My super sweet dashboard" } %>
|
2
|
+
<div class="gridster">
|
3
|
+
<ul>
|
4
|
+
<li data-row="1" data-col="1" data-sizex="2" data-sizey="1">
|
5
|
+
<div data-id="welcome" data-view="Text" data-title="Hello" data-text="This is your shiny new dashboard." data-moreinfo="Protip: You can drag the widgets around!"></div>
|
6
|
+
</li>
|
7
|
+
|
8
|
+
<li data-row="1" data-col="1" data-sizex="1" data-sizey="1">
|
9
|
+
<div data-id="synergy" data-view="Meter" data-title="Synergy" data-min="0" data-max="100"></div>
|
10
|
+
</li>
|
11
|
+
|
12
|
+
<li data-row="1" data-col="1" data-sizex="1" data-sizey="2">
|
13
|
+
<div data-id="buzzwords" data-view="List" data-unordered="true" data-title="Buzzwords"></div>
|
14
|
+
</li>
|
15
|
+
|
16
|
+
<li data-row="1" data-col="1" data-sizex="1" data-sizey="1">
|
17
|
+
<div data-id="valuation" data-view="Number" data-title="Current Valuation" data-moreinfo="In billions"></div>
|
18
|
+
</li>
|
19
|
+
|
20
|
+
<li data-row="1" data-col="1" data-sizex="2" data-sizey="1">
|
21
|
+
<div data-id="convergence" data-view="Graph" data-title="Convergence" style="background-color:#ff9618;"></div>
|
22
|
+
</li>
|
23
|
+
</ul>
|
24
|
+
<center><div style="font-size: 12px">Try this: curl -d '{ "auth_token": "YOUR_AUTH_TOKEN", "text": "Hey, Look what I can do!" }' \http://localhost:3000/widgets/welcome</div></center>
|
25
|
+
</div>
|
@@ -0,0 +1,9 @@
|
|
1
|
+
buzzwords = ['Paradigm shift', 'Leverage', 'Pivoting', 'Turn-key', 'Streamlininess', 'Exit strategy', 'Synergy', 'Enterprise', 'Web 2.0']
|
2
|
+
buzzword_counts = Hash.new({ value: 0 })
|
3
|
+
|
4
|
+
SCHEDULER.every '2s' do
|
5
|
+
random_buzzword = buzzwords.sample
|
6
|
+
buzzword_counts[random_buzzword] = { label: random_buzzword, value: buzzword_counts[random_buzzword][:value] + 1 }
|
7
|
+
|
8
|
+
send_event('buzzwords', { items: buzzword_counts.values })
|
9
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
.empty_directory
|
@@ -0,0 +1 @@
|
|
1
|
+
.empty_directory
|
@@ -0,0 +1,26 @@
|
|
1
|
+
class Dashing.Graph extends Dashing.Widget
|
2
|
+
|
3
|
+
@accessor 'current', ->
|
4
|
+
points = @get('points')
|
5
|
+
if points
|
6
|
+
points[points.length - 1].y
|
7
|
+
|
8
|
+
ready: ->
|
9
|
+
@graph = new Rickshaw.Graph(
|
10
|
+
element: @node
|
11
|
+
width: $(@node).parent().width()
|
12
|
+
series: [
|
13
|
+
{
|
14
|
+
color: "#fff",
|
15
|
+
data: [{ x: 0, y: 0}]
|
16
|
+
}
|
17
|
+
]
|
18
|
+
)
|
19
|
+
x_axis = new Rickshaw.Graph.Axis.Time(graph: @graph)
|
20
|
+
@graph.render()
|
21
|
+
|
22
|
+
onData: (data) ->
|
23
|
+
super
|
24
|
+
if @graph
|
25
|
+
@graph.series[0].data = data.points
|
26
|
+
@graph.render()
|
@@ -0,0 +1,51 @@
|
|
1
|
+
// ----------------------------------------------------------------------------
|
2
|
+
// Sass declarations
|
3
|
+
// ----------------------------------------------------------------------------
|
4
|
+
$background-color: #2e864f;
|
5
|
+
$value-color: #fff;
|
6
|
+
|
7
|
+
$title-color: lighten($background-color, 75%);
|
8
|
+
$moreinfo-color: lighten($background-color, 45%);
|
9
|
+
|
10
|
+
$graph_color: lighten($background-color, 75%);
|
11
|
+
|
12
|
+
// ----------------------------------------------------------------------------
|
13
|
+
// Widget-graph styles
|
14
|
+
// ----------------------------------------------------------------------------
|
15
|
+
.widget-graph {
|
16
|
+
|
17
|
+
background-color: $background-color;
|
18
|
+
position: relative;
|
19
|
+
|
20
|
+
svg {
|
21
|
+
color: $graph_color;
|
22
|
+
opacity: 0.4;
|
23
|
+
fill-opacity: 0.4;
|
24
|
+
position: absolute;
|
25
|
+
bottom: 0;
|
26
|
+
left: 0;
|
27
|
+
right: 0;
|
28
|
+
}
|
29
|
+
|
30
|
+
.title, .value {
|
31
|
+
position: relative;
|
32
|
+
z-index: 99;
|
33
|
+
}
|
34
|
+
|
35
|
+
.title {
|
36
|
+
color: $title-color;
|
37
|
+
}
|
38
|
+
|
39
|
+
.text-moreinfo {
|
40
|
+
color: $moreinfo-color;
|
41
|
+
font-weight: 600;
|
42
|
+
font-size: 20px;
|
43
|
+
margin-top: 0;
|
44
|
+
}
|
45
|
+
|
46
|
+
.x_tick {
|
47
|
+
position: absolute;
|
48
|
+
bottom: 0;
|
49
|
+
}
|
50
|
+
|
51
|
+
}
|
@@ -0,0 +1,13 @@
|
|
1
|
+
class Dashing.List extends Dashing.Widget
|
2
|
+
@accessor 'current', Dashing.AnimatedValue
|
3
|
+
|
4
|
+
@accessor 'arrow', ->
|
5
|
+
if @get('last')
|
6
|
+
if parseInt(@get('current')) > parseInt(@get('last')) then 'arrow-up' else 'arrow-down'
|
7
|
+
|
8
|
+
ready: ->
|
9
|
+
Batman.setImmediate =>
|
10
|
+
if @get('unordered')
|
11
|
+
$(@node).find('ol').remove()
|
12
|
+
else
|
13
|
+
$(@node).find('ul').remove()
|
@@ -0,0 +1,15 @@
|
|
1
|
+
<h1 class="title" data-bind="title"></h1>
|
2
|
+
|
3
|
+
<ol>
|
4
|
+
<li data-foreach-item="items">
|
5
|
+
<span class="label" data-bind="item.label"></span>
|
6
|
+
<span class="value" data-bind="item.value"></span>
|
7
|
+
</li>
|
8
|
+
</ol>
|
9
|
+
|
10
|
+
<ul class="list-nostyle">
|
11
|
+
<li data-foreach-item="items">
|
12
|
+
<span class="label" data-bind="item.label"></span>
|
13
|
+
<span class="value" data-bind="item.value"></span>
|
14
|
+
</li>
|
15
|
+
</ul>
|
@@ -0,0 +1,52 @@
|
|
1
|
+
// ----------------------------------------------------------------------------
|
2
|
+
// Sass declarations
|
3
|
+
// ----------------------------------------------------------------------------
|
4
|
+
|
5
|
+
$background-color: #12b0c5;
|
6
|
+
$value-color: #fff;
|
7
|
+
|
8
|
+
$title-color: lighten($background-color, 45%);
|
9
|
+
$label-color: lighten($background-color, 45%);
|
10
|
+
|
11
|
+
// ----------------------------------------------------------------------------
|
12
|
+
// Widget-list styles
|
13
|
+
// ----------------------------------------------------------------------------
|
14
|
+
.widget-list {
|
15
|
+
|
16
|
+
background-color: $background-color;
|
17
|
+
vertical-align: top;
|
18
|
+
|
19
|
+
.title {
|
20
|
+
color: $title-color;
|
21
|
+
}
|
22
|
+
|
23
|
+
ol, ul {
|
24
|
+
margin: 0 15px;
|
25
|
+
text-align: left;
|
26
|
+
color: $label-color;
|
27
|
+
}
|
28
|
+
|
29
|
+
ol {
|
30
|
+
list-style-position: inside;
|
31
|
+
}
|
32
|
+
|
33
|
+
li {
|
34
|
+
margin-bottom: 5px;
|
35
|
+
}
|
36
|
+
|
37
|
+
.list-nostyle {
|
38
|
+
list-style: none;
|
39
|
+
}
|
40
|
+
|
41
|
+
.label {
|
42
|
+
color: $label-color;
|
43
|
+
}
|
44
|
+
|
45
|
+
.value {
|
46
|
+
float: right;
|
47
|
+
margin-left: 12px;
|
48
|
+
font-weight: 600;
|
49
|
+
color: $value-color;
|
50
|
+
}
|
51
|
+
|
52
|
+
}
|
@@ -0,0 +1,14 @@
|
|
1
|
+
class Dashing.Meter extends Dashing.Widget
|
2
|
+
|
3
|
+
@accessor 'value', Dashing.AnimatedValue
|
4
|
+
|
5
|
+
constructor: ->
|
6
|
+
super
|
7
|
+
@observe 'value', (value) ->
|
8
|
+
$(@node).find(".meter").val(value).trigger('change')
|
9
|
+
|
10
|
+
ready: ->
|
11
|
+
meter = $(@node).find(".meter")
|
12
|
+
meter.attr("data-bgcolor", meter.css("background-color"))
|
13
|
+
meter.attr("data-fgcolor", meter.css("color"))
|
14
|
+
meter.knob()
|
@@ -0,0 +1,5 @@
|
|
1
|
+
<h1 class="title" data-bind="title"></h1>
|
2
|
+
|
3
|
+
<input class="meter" data-angleOffset=-125 data-angleArc=250 data-width=200 data-readOnly=true data-bind-value="value | shortenedNumber" data-bind-data-min="min" data-bind-data-max="max">
|
4
|
+
|
5
|
+
<p class="text-moreinfo" data-bind="moreinfo"></p>
|
@@ -0,0 +1,37 @@
|
|
1
|
+
// ----------------------------------------------------------------------------
|
2
|
+
// Sass declarations
|
3
|
+
// ----------------------------------------------------------------------------
|
4
|
+
|
5
|
+
$background-color: #9c4274;
|
6
|
+
$value-color: #fff;
|
7
|
+
|
8
|
+
$title-color: lighten($background-color, 75%);
|
9
|
+
$moreinfo-color: lighten($background-color, 45%);
|
10
|
+
|
11
|
+
$meter-background: darken($background-color, 10%);
|
12
|
+
$meter-foreground: lighten($background-color, 75%);
|
13
|
+
|
14
|
+
// ----------------------------------------------------------------------------
|
15
|
+
// Widget-meter styles
|
16
|
+
// ----------------------------------------------------------------------------
|
17
|
+
.widget-meter {
|
18
|
+
|
19
|
+
background-color: $background-color;
|
20
|
+
|
21
|
+
input.meter {
|
22
|
+
background-color: $meter-background;
|
23
|
+
color: $meter-foreground;
|
24
|
+
}
|
25
|
+
|
26
|
+
.title {
|
27
|
+
color: $title-color;
|
28
|
+
}
|
29
|
+
|
30
|
+
.text-moreinfo {
|
31
|
+
color: $moreinfo-color;
|
32
|
+
font-weight: 600;
|
33
|
+
font-size: 20px;
|
34
|
+
margin-top: 0;
|
35
|
+
}
|
36
|
+
|
37
|
+
}
|
@@ -0,0 +1,25 @@
|
|
1
|
+
class Dashing.Number extends Dashing.Widget
|
2
|
+
@accessor 'current', Dashing.AnimatedValue
|
3
|
+
|
4
|
+
@accessor 'difference', ->
|
5
|
+
if @get('last')
|
6
|
+
last = parseInt(@get('last'))
|
7
|
+
current = parseInt(@get('current'))
|
8
|
+
if last != 0
|
9
|
+
diff = Math.abs(Math.round((current - last) / last * 100))
|
10
|
+
"#{diff}%"
|
11
|
+
|
12
|
+
@accessor 'arrow', ->
|
13
|
+
if @get('last')
|
14
|
+
if parseInt(@get('current')) > parseInt(@get('last')) then 'icon-arrow-up' else 'icon-arrow-down'
|
15
|
+
|
16
|
+
@accessor 'statusStyle', ->
|
17
|
+
"status-#{@get('status')}"
|
18
|
+
|
19
|
+
@accessor 'needsAttention', ->
|
20
|
+
@get('status') == 'warning' || @get('status') == 'danger'
|
21
|
+
|
22
|
+
onData: (data) ->
|
23
|
+
super
|
24
|
+
if data.status
|
25
|
+
$(@get('node')).addClass("status-#{data.status}")
|
@@ -0,0 +1,9 @@
|
|
1
|
+
<h1 class="title"><i data-showif="needsAttention" class="icon-warning-sign"></i><span data-bind="title"></span></h1>
|
2
|
+
|
3
|
+
<h2 class="value" data-bind="current | prettyNumber"></h2>
|
4
|
+
|
5
|
+
<p class="change-rate">
|
6
|
+
<i data-bind-class="arrow"></i><span data-bind="difference">50%</span>
|
7
|
+
</p>
|
8
|
+
|
9
|
+
<p class="text-moreinfo" data-bind="moreinfo">2012-07-26 10:59AM</p>
|