├── .gitignore ├── Gemfile ├── Gemfile.lock ├── LICENSE ├── README.md ├── assets ├── fonts │ ├── fontawesome-webfont.eot │ ├── fontawesome-webfont.svg │ ├── fontawesome-webfont.ttf │ └── fontawesome-webfont.woff ├── images │ └── logo.png ├── javascripts │ ├── application.coffee │ ├── d3-3.2.8.js │ ├── dashing.gridster.coffee │ ├── gridster │ │ ├── jquery.gridster.js │ │ └── jquery.leanModal.min.js │ ├── jquery.knob.js │ └── rickshaw-1.4.3.min.js └── stylesheets │ ├── application.scss │ ├── font-awesome.css │ └── jquery.gridster.css ├── config.ru ├── dashboards ├── layout.erb ├── sample.erb └── sampletv.erb ├── doc ├── nginx.conf ├── one.sh ├── screenshot.png └── unicorn.rb ├── jobs ├── buzzwords.rb ├── convergence.rb └── sample.rb ├── public ├── 404.html └── favicon.ico └── widgets ├── clock ├── clock.coffee ├── clock.html └── clock.scss ├── comments ├── comments.coffee ├── comments.html └── comments.scss ├── graph ├── graph.coffee ├── graph.html └── graph.scss ├── iframe ├── iframe.coffee ├── iframe.html └── iframe.scss ├── image ├── image.coffee ├── image.html └── image.scss ├── list ├── list.coffee ├── list.html └── list.scss ├── meter ├── meter.coffee ├── meter.html └── meter.scss ├── number ├── number.coffee ├── number.html └── number.scss └── text ├── text.coffee ├── text.html └── text.scss /.gitignore: -------------------------------------------------------------------------------- 1 | *DS_STORE 2 | history.yml 3 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | 3 | gem 'dashing' 4 | gem 'unicorn' 5 | ## Remove this if you don't need a twitter widget. 6 | gem 'twitter' 7 | -------------------------------------------------------------------------------- /Gemfile.lock: -------------------------------------------------------------------------------- 1 | GEM 2 | remote: https://rubygems.org/ 3 | specs: 4 | addressable (2.3.5) 5 | atomic (1.1.14) 6 | backports (3.5.0) 7 | buftok (0.2.0) 8 | coffee-script (2.2.0) 9 | coffee-script-source 10 | execjs 11 | coffee-script-source (1.7.0) 12 | daemons (1.1.9) 13 | dashing (1.3.2) 14 | coffee-script (>= 1.6.2) 15 | execjs (>= 2.0.0) 16 | rack 17 | rufus-scheduler (~> 2.0) 18 | sass 19 | sinatra 20 | sinatra-contrib 21 | sprockets 22 | thin 23 | thor 24 | equalizer (0.0.9) 25 | eventmachine (1.0.3) 26 | execjs (2.0.2) 27 | faraday (0.9.0) 28 | multipart-post (>= 1.2, < 3) 29 | hike (1.2.3) 30 | http (0.5.0) 31 | http_parser.rb 32 | http_parser.rb (0.6.0) 33 | json (1.8.1) 34 | kgio (2.9.1) 35 | memoizable (0.4.0) 36 | thread_safe (~> 0.1.3) 37 | multi_json (1.8.4) 38 | multipart-post (2.0.0) 39 | naught (1.0.0) 40 | rack (1.5.2) 41 | rack-protection (1.5.2) 42 | rack 43 | rack-test (0.6.2) 44 | rack (>= 1.0) 45 | raindrops (0.12.0) 46 | rufus-scheduler (2.0.24) 47 | tzinfo (>= 0.3.22) 48 | sass (3.2.14) 49 | simple_oauth (0.2.0) 50 | sinatra (1.4.4) 51 | rack (~> 1.4) 52 | rack-protection (~> 1.4) 53 | tilt (~> 1.3, >= 1.3.4) 54 | sinatra-contrib (1.4.2) 55 | backports (>= 2.0) 56 | multi_json 57 | rack-protection 58 | rack-test 59 | sinatra (~> 1.4.0) 60 | tilt (~> 1.3) 61 | sprockets (2.10.1) 62 | hike (~> 1.2) 63 | multi_json (~> 1.0) 64 | rack (~> 1.0) 65 | tilt (~> 1.1, != 1.3.0) 66 | thin (1.6.1) 67 | daemons (>= 1.0.9) 68 | eventmachine (>= 1.0.0) 69 | rack (>= 1.0.0) 70 | thor (0.18.1) 71 | thread_safe (0.1.3) 72 | atomic 73 | tilt (1.4.1) 74 | twitter (5.7.0) 75 | addressable (~> 2.3) 76 | buftok (~> 0.2.0) 77 | equalizer (~> 0.0.9) 78 | faraday (~> 0.9.0) 79 | http (~> 0.5.0) 80 | http_parser.rb (~> 0.6.0) 81 | json (~> 1.8) 82 | memoizable (~> 0.4.0) 83 | naught (~> 1.0) 84 | simple_oauth (~> 0.2.0) 85 | tzinfo (1.1.0) 86 | thread_safe (~> 0.1) 87 | unicorn (4.8.2) 88 | kgio (~> 2.6) 89 | rack 90 | raindrops (~> 0.7) 91 | 92 | PLATFORMS 93 | ruby 94 | 95 | DEPENDENCIES 96 | dashing 97 | twitter 98 | unicorn 99 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 2, June 1991 3 | 4 | Copyright (C) 1989, 1991 Free Software Foundation, Inc., 5 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 6 | Everyone is permitted to copy and distribute verbatim copies 7 | of this license document, but changing it is not allowed. 8 | 9 | Preamble 10 | 11 | The licenses for most software are designed to take away your 12 | freedom to share and change it. By contrast, the GNU General Public 13 | License is intended to guarantee your freedom to share and change free 14 | software--to make sure the software is free for all its users. This 15 | General Public License applies to most of the Free Software 16 | Foundation's software and to any other program whose authors commit to 17 | using it. (Some other Free Software Foundation software is covered by 18 | the GNU Lesser General Public License instead.) You can apply it to 19 | your programs, too. 20 | 21 | When we speak of free software, we are referring to freedom, not 22 | price. Our General Public Licenses are designed to make sure that you 23 | have the freedom to distribute copies of free software (and charge for 24 | this service if you wish), that you receive source code or can get it 25 | if you want it, that you can change the software or use pieces of it 26 | in new free programs; and that you know you can do these things. 27 | 28 | To protect your rights, we need to make restrictions that forbid 29 | anyone to deny you these rights or to ask you to surrender the rights. 30 | These restrictions translate to certain responsibilities for you if you 31 | distribute copies of the software, or if you modify it. 32 | 33 | For example, if you distribute copies of such a program, whether 34 | gratis or for a fee, you must give the recipients all the rights that 35 | you have. You must make sure that they, too, receive or can get the 36 | source code. And you must show them these terms so they know their 37 | rights. 38 | 39 | We protect your rights with two steps: (1) copyright the software, and 40 | (2) offer you this license which gives you legal permission to copy, 41 | distribute and/or modify the software. 42 | 43 | Also, for each author's protection and ours, we want to make certain 44 | that everyone understands that there is no warranty for this free 45 | software. If the software is modified by someone else and passed on, we 46 | want its recipients to know that what they have is not the original, so 47 | that any problems introduced by others will not reflect on the original 48 | authors' reputations. 49 | 50 | Finally, any free program is threatened constantly by software 51 | patents. We wish to avoid the danger that redistributors of a free 52 | program will individually obtain patent licenses, in effect making the 53 | program proprietary. To prevent this, we have made it clear that any 54 | patent must be licensed for everyone's free use or not licensed at all. 55 | 56 | The precise terms and conditions for copying, distribution and 57 | modification follow. 58 | 59 | GNU GENERAL PUBLIC LICENSE 60 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 61 | 62 | 0. This License applies to any program or other work which contains 63 | a notice placed by the copyright holder saying it may be distributed 64 | under the terms of this General Public License. The "Program", below, 65 | refers to any such program or work, and a "work based on the Program" 66 | means either the Program or any derivative work under copyright law: 67 | that is to say, a work containing the Program or a portion of it, 68 | either verbatim or with modifications and/or translated into another 69 | language. (Hereinafter, translation is included without limitation in 70 | the term "modification".) Each licensee is addressed as "you". 71 | 72 | Activities other than copying, distribution and modification are not 73 | covered by this License; they are outside its scope. The act of 74 | running the Program is not restricted, and the output from the Program 75 | is covered only if its contents constitute a work based on the 76 | Program (independent of having been made by running the Program). 77 | Whether that is true depends on what the Program does. 78 | 79 | 1. You may copy and distribute verbatim copies of the Program's 80 | source code as you receive it, in any medium, provided that you 81 | conspicuously and appropriately publish on each copy an appropriate 82 | copyright notice and disclaimer of warranty; keep intact all the 83 | notices that refer to this License and to the absence of any warranty; 84 | and give any other recipients of the Program a copy of this License 85 | along with the Program. 86 | 87 | You may charge a fee for the physical act of transferring a copy, and 88 | you may at your option offer warranty protection in exchange for a fee. 89 | 90 | 2. You may modify your copy or copies of the Program or any portion 91 | of it, thus forming a work based on the Program, and copy and 92 | distribute such modifications or work under the terms of Section 1 93 | above, provided that you also meet all of these conditions: 94 | 95 | a) You must cause the modified files to carry prominent notices 96 | stating that you changed the files and the date of any change. 97 | 98 | b) You must cause any work that you distribute or publish, that in 99 | whole or in part contains or is derived from the Program or any 100 | part thereof, to be licensed as a whole at no charge to all third 101 | parties under the terms of this License. 102 | 103 | c) If the modified program normally reads commands interactively 104 | when run, you must cause it, when started running for such 105 | interactive use in the most ordinary way, to print or display an 106 | announcement including an appropriate copyright notice and a 107 | notice that there is no warranty (or else, saying that you provide 108 | a warranty) and that users may redistribute the program under 109 | these conditions, and telling the user how to view a copy of this 110 | License. (Exception: if the Program itself is interactive but 111 | does not normally print such an announcement, your work based on 112 | the Program is not required to print an announcement.) 113 | 114 | These requirements apply to the modified work as a whole. If 115 | identifiable sections of that work are not derived from the Program, 116 | and can be reasonably considered independent and separate works in 117 | themselves, then this License, and its terms, do not apply to those 118 | sections when you distribute them as separate works. But when you 119 | distribute the same sections as part of a whole which is a work based 120 | on the Program, the distribution of the whole must be on the terms of 121 | this License, whose permissions for other licensees extend to the 122 | entire whole, and thus to each and every part regardless of who wrote it. 123 | 124 | Thus, it is not the intent of this section to claim rights or contest 125 | your rights to work written entirely by you; rather, the intent is to 126 | exercise the right to control the distribution of derivative or 127 | collective works based on the Program. 128 | 129 | In addition, mere aggregation of another work not based on the Program 130 | with the Program (or with a work based on the Program) on a volume of 131 | a storage or distribution medium does not bring the other work under 132 | the scope of this License. 133 | 134 | 3. You may copy and distribute the Program (or a work based on it, 135 | under Section 2) in object code or executable form under the terms of 136 | Sections 1 and 2 above provided that you also do one of the following: 137 | 138 | a) Accompany it with the complete corresponding machine-readable 139 | source code, which must be distributed under the terms of Sections 140 | 1 and 2 above on a medium customarily used for software interchange; or, 141 | 142 | b) Accompany it with a written offer, valid for at least three 143 | years, to give any third party, for a charge no more than your 144 | cost of physically performing source distribution, a complete 145 | machine-readable copy of the corresponding source code, to be 146 | distributed under the terms of Sections 1 and 2 above on a medium 147 | customarily used for software interchange; or, 148 | 149 | c) Accompany it with the information you received as to the offer 150 | to distribute corresponding source code. (This alternative is 151 | allowed only for noncommercial distribution and only if you 152 | received the program in object code or executable form with such 153 | an offer, in accord with Subsection b above.) 154 | 155 | The source code for a work means the preferred form of the work for 156 | making modifications to it. For an executable work, complete source 157 | code means all the source code for all modules it contains, plus any 158 | associated interface definition files, plus the scripts used to 159 | control compilation and installation of the executable. However, as a 160 | special exception, the source code distributed need not include 161 | anything that is normally distributed (in either source or binary 162 | form) with the major components (compiler, kernel, and so on) of the 163 | operating system on which the executable runs, unless that component 164 | itself accompanies the executable. 165 | 166 | If distribution of executable or object code is made by offering 167 | access to copy from a designated place, then offering equivalent 168 | access to copy the source code from the same place counts as 169 | distribution of the source code, even though third parties are not 170 | compelled to copy the source along with the object code. 171 | 172 | 4. You may not copy, modify, sublicense, or distribute the Program 173 | except as expressly provided under this License. Any attempt 174 | otherwise to copy, modify, sublicense or distribute the Program is 175 | void, and will automatically terminate your rights under this License. 176 | However, parties who have received copies, or rights, from you under 177 | this License will not have their licenses terminated so long as such 178 | parties remain in full compliance. 179 | 180 | 5. You are not required to accept this License, since you have not 181 | signed it. However, nothing else grants you permission to modify or 182 | distribute the Program or its derivative works. These actions are 183 | prohibited by law if you do not accept this License. Therefore, by 184 | modifying or distributing the Program (or any work based on the 185 | Program), you indicate your acceptance of this License to do so, and 186 | all its terms and conditions for copying, distributing or modifying 187 | the Program or works based on it. 188 | 189 | 6. Each time you redistribute the Program (or any work based on the 190 | Program), the recipient automatically receives a license from the 191 | original licensor to copy, distribute or modify the Program subject to 192 | these terms and conditions. You may not impose any further 193 | restrictions on the recipients' exercise of the rights granted herein. 194 | You are not responsible for enforcing compliance by third parties to 195 | this License. 196 | 197 | 7. If, as a consequence of a court judgment or allegation of patent 198 | infringement or for any other reason (not limited to patent issues), 199 | conditions are imposed on you (whether by court order, agreement or 200 | otherwise) that contradict the conditions of this License, they do not 201 | excuse you from the conditions of this License. If you cannot 202 | distribute so as to satisfy simultaneously your obligations under this 203 | License and any other pertinent obligations, then as a consequence you 204 | may not distribute the Program at all. For example, if a patent 205 | license would not permit royalty-free redistribution of the Program by 206 | all those who receive copies directly or indirectly through you, then 207 | the only way you could satisfy both it and this License would be to 208 | refrain entirely from distribution of the Program. 209 | 210 | If any portion of this section is held invalid or unenforceable under 211 | any particular circumstance, the balance of the section is intended to 212 | apply and the section as a whole is intended to apply in other 213 | circumstances. 214 | 215 | It is not the purpose of this section to induce you to infringe any 216 | patents or other property right claims or to contest validity of any 217 | such claims; this section has the sole purpose of protecting the 218 | integrity of the free software distribution system, which is 219 | implemented by public license practices. Many people have made 220 | generous contributions to the wide range of software distributed 221 | through that system in reliance on consistent application of that 222 | system; it is up to the author/donor to decide if he or she is willing 223 | to distribute software through any other system and a licensee cannot 224 | impose that choice. 225 | 226 | This section is intended to make thoroughly clear what is believed to 227 | be a consequence of the rest of this License. 228 | 229 | 8. If the distribution and/or use of the Program is restricted in 230 | certain countries either by patents or by copyrighted interfaces, the 231 | original copyright holder who places the Program under this License 232 | may add an explicit geographical distribution limitation excluding 233 | those countries, so that distribution is permitted only in or among 234 | countries not thus excluded. In such case, this License incorporates 235 | the limitation as if written in the body of this License. 236 | 237 | 9. The Free Software Foundation may publish revised and/or new versions 238 | of the General Public License from time to time. Such new versions will 239 | be similar in spirit to the present version, but may differ in detail to 240 | address new problems or concerns. 241 | 242 | Each version is given a distinguishing version number. If the Program 243 | specifies a version number of this License which applies to it and "any 244 | later version", you have the option of following the terms and conditions 245 | either of that version or of any later version published by the Free 246 | Software Foundation. If the Program does not specify a version number of 247 | this License, you may choose any version ever published by the Free Software 248 | Foundation. 249 | 250 | 10. If you wish to incorporate parts of the Program into other free 251 | programs whose distribution conditions are different, write to the author 252 | to ask for permission. For software which is copyrighted by the Free 253 | Software Foundation, write to the Free Software Foundation; we sometimes 254 | make exceptions for this. Our decision will be guided by the two goals 255 | of preserving the free status of all derivatives of our free software and 256 | of promoting the sharing and reuse of software generally. 257 | 258 | NO WARRANTY 259 | 260 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY 261 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN 262 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES 263 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED 264 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 265 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS 266 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE 267 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, 268 | REPAIR OR CORRECTION. 269 | 270 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 271 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR 272 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, 273 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING 274 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED 275 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY 276 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER 277 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE 278 | POSSIBILITY OF SUCH DAMAGES. 279 | 280 | END OF TERMS AND CONDITIONS 281 | 282 | How to Apply These Terms to Your New Programs 283 | 284 | If you develop a new program, and you want it to be of the greatest 285 | possible use to the public, the best way to achieve this is to make it 286 | free software which everyone can redistribute and change under these terms. 287 | 288 | To do so, attach the following notices to the program. It is safest 289 | to attach them to the start of each source file to most effectively 290 | convey the exclusion of warranty; and each file should have at least 291 | the "copyright" line and a pointer to where the full notice is found. 292 | 293 | {description} 294 | Copyright (C) {year} {fullname} 295 | 296 | This program is free software; you can redistribute it and/or modify 297 | it under the terms of the GNU General Public License as published by 298 | the Free Software Foundation; either version 2 of the License, or 299 | (at your option) any later version. 300 | 301 | This program is distributed in the hope that it will be useful, 302 | but WITHOUT ANY WARRANTY; without even the implied warranty of 303 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 304 | GNU General Public License for more details. 305 | 306 | You should have received a copy of the GNU General Public License along 307 | with this program; if not, write to the Free Software Foundation, Inc., 308 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 309 | 310 | Also add information on how to contact you by electronic and paper mail. 311 | 312 | If the program is interactive, make it output a short notice like this 313 | when it starts in an interactive mode: 314 | 315 | Gnomovision version 69, Copyright (C) year name of author 316 | Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 317 | This is free software, and you are welcome to redistribute it 318 | under certain conditions; type `show c' for details. 319 | 320 | The hypothetical commands `show w' and `show c' should show the appropriate 321 | parts of the General Public License. Of course, the commands you use may 322 | be called something other than `show w' and `show c'; they could even be 323 | mouse-clicks or menu items--whatever suits your program. 324 | 325 | You should also get your employer (if you work as a programmer) or your 326 | school, if any, to sign a "copyright disclaimer" for the program, if 327 | necessary. Here is a sample; alter the names: 328 | 329 | Yoyodyne, Inc., hereby disclaims all copyright interest in the program 330 | `Gnomovision' (which makes passes at compilers) written by James Hacker. 331 | 332 | {signature of Ty Coon}, 1 April 1989 333 | Ty Coon, President of Vice 334 | 335 | This General Public License does not permit incorporating your program into 336 | proprietary programs. If your program is a subroutine library, you may 337 | consider it more useful to permit linking proprietary applications with the 338 | library. If this is what you want to do, use the GNU Lesser General 339 | Public License instead of this License. 340 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ============= 2 | iot-dashboard 3 | ============= 4 | 5 | - Language : Ruby 6 | - Framework: Dashboard 7 | 8 | ![](https://raw.github.com/gmszone/iot-dashboard/master/doc/screenshot.png) 9 | 10 | ##How to Run## 11 | 12 | 1.安装依赖 13 | 14 | bundle install 15 | 16 | 2.启动 17 | 18 | dashing start 19 | -------------------------------------------------------------------------------- /assets/fonts/fontawesome-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iot-works/iot-dashboard/da9574ed6dd8143d987c5f1aa6204fdb6c5c4c9b/assets/fonts/fontawesome-webfont.eot -------------------------------------------------------------------------------- /assets/fonts/fontawesome-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iot-works/iot-dashboard/da9574ed6dd8143d987c5f1aa6204fdb6c5c4c9b/assets/fonts/fontawesome-webfont.ttf -------------------------------------------------------------------------------- /assets/fonts/fontawesome-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iot-works/iot-dashboard/da9574ed6dd8143d987c5f1aa6204fdb6c5c4c9b/assets/fonts/fontawesome-webfont.woff -------------------------------------------------------------------------------- /assets/images/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iot-works/iot-dashboard/da9574ed6dd8143d987c5f1aa6204fdb6c5c4c9b/assets/images/logo.png -------------------------------------------------------------------------------- /assets/javascripts/application.coffee: -------------------------------------------------------------------------------- 1 | # dashing.js is located in the dashing framework 2 | # It includes jquery & batman for you. 3 | #= require dashing.js 4 | 5 | #= require_directory . 6 | #= require_tree ../../widgets 7 | 8 | console.log("Yeah! The dashboard has started!") 9 | 10 | Dashing.on 'ready', -> 11 | Dashing.widget_margins ||= [5, 5] 12 | Dashing.widget_base_dimensions ||= [300, 360] 13 | Dashing.numColumns ||= 4 14 | 15 | contentWidth = (Dashing.widget_base_dimensions[0] + Dashing.widget_margins[0] * 2) * Dashing.numColumns 16 | 17 | Batman.setImmediate -> 18 | $('.gridster').width(contentWidth) 19 | $('.gridster ul:first').gridster 20 | widget_margins: Dashing.widget_margins 21 | widget_base_dimensions: Dashing.widget_base_dimensions 22 | avoid_overlapped_widgets: !Dashing.customGridsterLayout 23 | draggable: 24 | stop: Dashing.showGridsterInstructions 25 | start: -> Dashing.currentWidgetPositions = Dashing.getWidgetPositions() 26 | -------------------------------------------------------------------------------- /assets/javascripts/dashing.gridster.coffee: -------------------------------------------------------------------------------- 1 | #= require_directory ./gridster 2 | 3 | # This file enables gridster integration (http://gridster.net/) 4 | # Delete it if you'd rather handle the layout yourself. 5 | # You'll miss out on a lot if you do, but we won't hold it against you. 6 | 7 | Dashing.gridsterLayout = (positions) -> 8 | Dashing.customGridsterLayout = true 9 | positions = positions.replace(/^"|"$/g, '') 10 | positions = $.parseJSON(positions) 11 | widgets = $("[data-row^=]") 12 | for widget, index in widgets 13 | $(widget).attr('data-row', positions[index].row) 14 | $(widget).attr('data-col', positions[index].col) 15 | 16 | Dashing.getWidgetPositions = -> 17 | $(".gridster ul:first").gridster().data('gridster').serialize() 18 | 19 | Dashing.showGridsterInstructions = -> 20 | newWidgetPositions = Dashing.getWidgetPositions() 21 | 22 | unless JSON.stringify(newWidgetPositions) == JSON.stringify(Dashing.currentWidgetPositions) 23 | Dashing.currentWidgetPositions = newWidgetPositions 24 | $('#save-gridster').slideDown() 25 | $('#gridster-code').text(" 26 | 31 | ") 32 | 33 | $ -> 34 | $('#save-gridster').leanModal() 35 | 36 | $('#save-gridster').click -> 37 | $('#save-gridster').slideUp() 38 | -------------------------------------------------------------------------------- /assets/javascripts/gridster/jquery.leanModal.min.js: -------------------------------------------------------------------------------- 1 | // leanModal v1.1 by Ray Stone - http://finelysliced.com.au 2 | // Dual licensed under the MIT and GPL 3 | 4 | (function($){$.fn.extend({leanModal:function(options){var defaults={top:100,overlay:0.5,closeButton:null};var overlay=$("
");$("body").append(overlay);options=$.extend(defaults,options);return this.each(function(){var o=options;$(this).click(function(e){var modal_id=$(this).attr("href");$("#lean_overlay").click(function(){close_modal(modal_id)});$(o.closeButton).click(function(){close_modal(modal_id)});var modal_height=$(modal_id).outerHeight();var modal_width=$(modal_id).outerWidth(); 5 | $("#lean_overlay").css({"display":"block",opacity:0});$("#lean_overlay").fadeTo(200,o.overlay);$(modal_id).css({"display":"block","position":"fixed","opacity":0,"z-index":11000,"left":50+"%","margin-left":-(modal_width/2)+"px","top":o.top+"px"});$(modal_id).fadeTo(200,1);e.preventDefault()})});function close_modal(modal_id){$("#lean_overlay").fadeOut(200);$(modal_id).css({"display":"none"})}}})})(jQuery); 6 | -------------------------------------------------------------------------------- /assets/javascripts/jquery.knob.js: -------------------------------------------------------------------------------- 1 | /*!jQuery Knob*/ 2 | /** 3 | * Downward compatible, touchable dial 4 | * 5 | * Version: 1.2.0 (15/07/2012) 6 | * Requires: jQuery v1.7+ 7 | * 8 | * Copyright (c) 2012 Anthony Terrien 9 | * Under MIT and GPL licenses: 10 | * http://www.opensource.org/licenses/mit-license.php 11 | * http://www.gnu.org/licenses/gpl.html 12 | * 13 | * Thanks to vor, eskimoblood, spiffistan, FabrizioC 14 | */ 15 | $(function () { 16 | 17 | /** 18 | * Kontrol library 19 | */ 20 | "use strict"; 21 | 22 | /** 23 | * Definition of globals and core 24 | */ 25 | var k = {}, // kontrol 26 | max = Math.max, 27 | min = Math.min; 28 | 29 | k.c = {}; 30 | k.c.d = $(document); 31 | k.c.t = function (e) { 32 | return e.originalEvent.touches.length - 1; 33 | }; 34 | 35 | /** 36 | * Kontrol Object 37 | * 38 | * Definition of an abstract UI control 39 | * 40 | * Each concrete component must call this one. 41 | * 42 | * k.o.call(this); 43 | * 44 | */ 45 | k.o = function () { 46 | var s = this; 47 | 48 | this.o = null; // array of options 49 | this.$ = null; // jQuery wrapped element 50 | this.i = null; // mixed HTMLInputElement or array of HTMLInputElement 51 | this.g = null; // 2D graphics context for 'pre-rendering' 52 | this.v = null; // value ; mixed array or integer 53 | this.cv = null; // change value ; not commited value 54 | this.x = 0; // canvas x position 55 | this.y = 0; // canvas y position 56 | this.$c = null; // jQuery canvas element 57 | this.c = null; // rendered canvas context 58 | this.t = 0; // touches index 59 | this.isInit = false; 60 | this.fgColor = null; // main color 61 | this.pColor = null; // previous color 62 | this.dH = null; // draw hook 63 | this.cH = null; // change hook 64 | this.eH = null; // cancel hook 65 | this.rH = null; // release hook 66 | 67 | this.run = function () { 68 | var cf = function (e, conf) { 69 | var k; 70 | for (k in conf) { 71 | s.o[k] = conf[k]; 72 | } 73 | s.init(); 74 | s._configure() 75 | ._draw(); 76 | }; 77 | 78 | if(this.$.data('kontroled')) return; 79 | this.$.data('kontroled', true); 80 | 81 | this.extend(); 82 | this.o = $.extend( 83 | { 84 | // Config 85 | min : this.$.data('min') || 0, 86 | max : this.$.data('max') || 100, 87 | stopper : true, 88 | readOnly : this.$.data('readonly'), 89 | 90 | // UI 91 | cursor : (this.$.data('cursor') === true && 30) 92 | || this.$.data('cursor') 93 | || 0, 94 | thickness : this.$.data('thickness') || 0.35, 95 | width : this.$.data('width') || 200, 96 | height : this.$.data('height') || 200, 97 | displayInput : this.$.data('displayinput') == null || this.$.data('displayinput'), 98 | displayPrevious : this.$.data('displayprevious'), 99 | fgColor : this.$.data('fgcolor') || '#87CEEB', 100 | inline : false, 101 | 102 | // Hooks 103 | draw : null, // function () {} 104 | change : null, // function (value) {} 105 | cancel : null, // function () {} 106 | release : null // function (value) {} 107 | }, this.o 108 | ); 109 | 110 | // routing value 111 | if(this.$.is('fieldset')) { 112 | 113 | // fieldset = array of integer 114 | this.v = {}; 115 | this.i = this.$.find('input') 116 | this.i.each(function(k) { 117 | var $this = $(this); 118 | s.i[k] = $this; 119 | s.v[k] = $this.val(); 120 | 121 | $this.bind( 122 | 'change' 123 | , function () { 124 | var val = {}; 125 | val[k] = $this.val(); 126 | s.val(val); 127 | } 128 | ); 129 | }); 130 | this.$.find('legend').remove(); 131 | 132 | } else { 133 | // input = integer 134 | this.i = this.$; 135 | this.v = this.$.val(); 136 | (this.v == '') && (this.v = this.o.min); 137 | 138 | this.$.bind( 139 | 'change' 140 | , function () { 141 | s.val(s.$.val()); 142 | } 143 | ); 144 | } 145 | 146 | (!this.o.displayInput) && this.$.hide(); 147 | 148 | this.$c = $(''); 151 | this.c = this.$c[0].getContext("2d"); 152 | 153 | this.$ 154 | .wrap($('
')) 157 | .before(this.$c); 158 | 159 | if (this.v instanceof Object) { 160 | this.cv = {}; 161 | this.copy(this.v, this.cv); 162 | } else { 163 | this.cv = this.v; 164 | } 165 | 166 | this.$ 167 | .bind("configure", cf) 168 | .parent() 169 | .bind("configure", cf); 170 | 171 | this._listen() 172 | ._configure() 173 | ._xy() 174 | .init(); 175 | 176 | this.isInit = true; 177 | 178 | this._draw(); 179 | 180 | return this; 181 | }; 182 | 183 | this._draw = function () { 184 | 185 | // canvas pre-rendering 186 | var d = true, 187 | c = document.createElement('canvas'); 188 | 189 | c.width = s.o.width; 190 | c.height = s.o.height; 191 | s.g = c.getContext('2d'); 192 | 193 | s.clear(); 194 | 195 | s.dH 196 | && (d = s.dH()); 197 | 198 | (d !== false) && s.draw(); 199 | 200 | s.c.drawImage(c, 0, 0); 201 | c = null; 202 | }; 203 | 204 | this._touch = function (e) { 205 | 206 | var touchMove = function (e) { 207 | 208 | var v = s.xy2val( 209 | e.originalEvent.touches[s.t].pageX, 210 | e.originalEvent.touches[s.t].pageY 211 | ); 212 | 213 | if (v == s.cv) return; 214 | 215 | if ( 216 | s.cH 217 | && (s.cH(v) === false) 218 | ) return; 219 | 220 | 221 | s.change(v); 222 | s._draw(); 223 | }; 224 | 225 | // get touches index 226 | this.t = k.c.t(e); 227 | 228 | // First touch 229 | touchMove(e); 230 | 231 | // Touch events listeners 232 | k.c.d 233 | .bind("touchmove.k", touchMove) 234 | .bind( 235 | "touchend.k" 236 | , function () { 237 | k.c.d.unbind('touchmove.k touchend.k'); 238 | 239 | if ( 240 | s.rH 241 | && (s.rH(s.cv) === false) 242 | ) return; 243 | 244 | s.val(s.cv); 245 | } 246 | ); 247 | 248 | return this; 249 | }; 250 | 251 | this._mouse = function (e) { 252 | 253 | var mouseMove = function (e) { 254 | var v = s.xy2val(e.pageX, e.pageY); 255 | if (v == s.cv) return; 256 | 257 | if ( 258 | s.cH 259 | && (s.cH(v) === false) 260 | ) return; 261 | 262 | s.change(v); 263 | s._draw(); 264 | }; 265 | 266 | // First click 267 | mouseMove(e); 268 | 269 | // Mouse events listeners 270 | k.c.d 271 | .bind("mousemove.k", mouseMove) 272 | .bind( 273 | // Escape key cancel current change 274 | "keyup.k" 275 | , function (e) { 276 | if (e.keyCode === 27) { 277 | k.c.d.unbind("mouseup.k mousemove.k keyup.k"); 278 | 279 | if ( 280 | s.eH 281 | && (s.eH() === false) 282 | ) return; 283 | 284 | s.cancel(); 285 | } 286 | } 287 | ) 288 | .bind( 289 | "mouseup.k" 290 | , function (e) { 291 | k.c.d.unbind('mousemove.k mouseup.k keyup.k'); 292 | 293 | if ( 294 | s.rH 295 | && (s.rH(s.cv) === false) 296 | ) return; 297 | 298 | s.val(s.cv); 299 | } 300 | ); 301 | 302 | return this; 303 | }; 304 | 305 | this._xy = function () { 306 | var o = this.$c.offset(); 307 | this.x = o.left; 308 | this.y = o.top; 309 | return this; 310 | }; 311 | 312 | this._listen = function () { 313 | 314 | if (!this.o.readOnly) { 315 | this.$c 316 | .bind( 317 | "mousedown" 318 | , function (e) { 319 | e.preventDefault(); 320 | s._xy()._mouse(e); 321 | } 322 | ) 323 | .bind( 324 | "touchstart" 325 | , function (e) { 326 | e.preventDefault(); 327 | s._xy()._touch(e); 328 | } 329 | ); 330 | this.listen(); 331 | } else { 332 | this.$.attr('readonly', 'readonly'); 333 | } 334 | 335 | return this; 336 | }; 337 | 338 | this._configure = function () { 339 | 340 | // Hooks 341 | if (this.o.draw) this.dH = this.o.draw; 342 | if (this.o.change) this.cH = this.o.change; 343 | if (this.o.cancel) this.eH = this.o.cancel; 344 | if (this.o.release) this.rH = this.o.release; 345 | 346 | if (this.o.displayPrevious) { 347 | this.pColor = this.h2rgba(this.o.fgColor, "0.4"); 348 | this.fgColor = this.h2rgba(this.o.fgColor, "0.6"); 349 | } else { 350 | this.fgColor = this.o.fgColor; 351 | } 352 | 353 | return this; 354 | }; 355 | 356 | this._clear = function () { 357 | this.$c[0].width = this.$c[0].width; 358 | }; 359 | 360 | // Abstract methods 361 | this.listen = function () {}; // on start, one time 362 | this.extend = function () {}; // each time configure triggered 363 | this.init = function () {}; // each time configure triggered 364 | this.change = function (v) {}; // on change 365 | this.val = function (v) {}; // on release 366 | this.xy2val = function (x, y) {}; // 367 | this.draw = function () {}; // on change / on release 368 | this.clear = function () { this._clear(); }; 369 | 370 | // Utils 371 | this.h2rgba = function (h, a) { 372 | var rgb; 373 | h = h.substring(1,7) 374 | rgb = [parseInt(h.substring(0,2),16) 375 | ,parseInt(h.substring(2,4),16) 376 | ,parseInt(h.substring(4,6),16)]; 377 | return "rgba(" + rgb[0] + "," + rgb[1] + "," + rgb[2] + "," + a + ")"; 378 | }; 379 | 380 | this.copy = function (f, t) { 381 | for (var i in f) { t[i] = f[i]; } 382 | }; 383 | }; 384 | 385 | 386 | /** 387 | * k.Dial 388 | */ 389 | k.Dial = function () { 390 | k.o.call(this); 391 | 392 | this.startAngle = null; 393 | this.xy = null; 394 | this.radius = null; 395 | this.lineWidth = null; 396 | this.cursorExt = null; 397 | this.w2 = null; 398 | this.PI2 = 2*Math.PI; 399 | 400 | this.extend = function () { 401 | this.o = $.extend( 402 | { 403 | bgColor : this.$.data('bgcolor') || '#EEEEEE', 404 | angleOffset : this.$.data('angleoffset') || 0, 405 | angleArc : this.$.data('anglearc') || 360, 406 | inline : true 407 | }, this.o 408 | ); 409 | }; 410 | 411 | this.val = function (v) { 412 | if (null != v) { 413 | this.cv = this.o.stopper ? max(min(v, this.o.max), this.o.min) : v; 414 | this.v = this.cv; 415 | this.$.val(this.v); 416 | this._draw(); 417 | } else { 418 | return this.v; 419 | } 420 | }; 421 | 422 | this.xy2val = function (x, y) { 423 | var a, ret; 424 | 425 | a = Math.atan2( 426 | x - (this.x + this.w2) 427 | , - (y - this.y - this.w2) 428 | ) - this.angleOffset; 429 | 430 | if(this.angleArc != this.PI2 && (a < 0) && (a > -0.5)) { 431 | // if isset angleArc option, set to min if .5 under min 432 | a = 0; 433 | } else if (a < 0) { 434 | a += this.PI2; 435 | } 436 | 437 | ret = ~~ (0.5 + (a * (this.o.max - this.o.min) / this.angleArc)) 438 | + this.o.min; 439 | 440 | this.o.stopper 441 | && (ret = max(min(ret, this.o.max), this.o.min)); 442 | 443 | return ret; 444 | }; 445 | 446 | this.listen = function () { 447 | // bind MouseWheel 448 | var s = this, 449 | mw = function (e) { 450 | e.preventDefault(); 451 | 452 | var ori = e.originalEvent 453 | ,deltaX = ori.detail || ori.wheelDeltaX 454 | ,deltaY = ori.detail || ori.wheelDeltaY 455 | ,v = parseInt(s.$.val()) + (deltaX>0 || deltaY>0 ? 1 : deltaX<0 || deltaY<0 ? -1 : 0); 456 | 457 | if ( 458 | s.cH 459 | && (s.cH(v) === false) 460 | ) return; 461 | 462 | s.val(v); 463 | } 464 | , kval, to, m = 1, kv = {37:-1, 38:1, 39:1, 40:-1}; 465 | 466 | this.$ 467 | .bind( 468 | "keydown" 469 | ,function (e) { 470 | var kc = e.keyCode; 471 | kval = parseInt(String.fromCharCode(kc)); 472 | 473 | if (isNaN(kval)) { 474 | 475 | (kc !== 13) // enter 476 | && (kc !== 8) // bs 477 | && (kc !== 9) // tab 478 | && (kc !== 189) // - 479 | && e.preventDefault(); 480 | 481 | // arrows 482 | if ($.inArray(kc,[37,38,39,40]) > -1) { 483 | e.preventDefault(); 484 | 485 | var v = parseInt(s.$.val()) + kv[kc] * m; 486 | 487 | s.o.stopper 488 | && (v = max(min(v, s.o.max), s.o.min)); 489 | 490 | s.change(v); 491 | s._draw(); 492 | 493 | // long time keydown speed-up 494 | to = window.setTimeout( 495 | function () { m*=2; } 496 | ,30 497 | ); 498 | } 499 | } 500 | } 501 | ) 502 | .bind( 503 | "keyup" 504 | ,function (e) { 505 | if (isNaN(kval)) { 506 | if (to) { 507 | window.clearTimeout(to); 508 | to = null; 509 | m = 1; 510 | s.val(s.$.val()); 511 | } 512 | } else { 513 | // kval postcond 514 | (s.$.val() > s.o.max && s.$.val(s.o.max)) 515 | || (s.$.val() < s.o.min && s.$.val(s.o.min)); 516 | } 517 | 518 | } 519 | ); 520 | 521 | this.$c.bind("mousewheel DOMMouseScroll", mw); 522 | this.$.bind("mousewheel DOMMouseScroll", mw) 523 | }; 524 | 525 | this.init = function () { 526 | 527 | if ( 528 | this.v < this.o.min 529 | || this.v > this.o.max 530 | ) this.v = this.o.min; 531 | 532 | this.$.val(this.v); 533 | this.w2 = this.o.width / 2; 534 | this.cursorExt = this.o.cursor / 100; 535 | this.xy = this.w2; 536 | this.lineWidth = this.xy * this.o.thickness; 537 | this.radius = this.xy - this.lineWidth / 2; 538 | 539 | this.o.angleOffset 540 | && (this.o.angleOffset = isNaN(this.o.angleOffset) ? 0 : this.o.angleOffset); 541 | 542 | this.o.angleArc 543 | && (this.o.angleArc = isNaN(this.o.angleArc) ? this.PI2 : this.o.angleArc); 544 | 545 | // deg to rad 546 | this.angleOffset = this.o.angleOffset * Math.PI / 180; 547 | this.angleArc = this.o.angleArc * Math.PI / 180; 548 | 549 | // compute start and end angles 550 | this.startAngle = 1.5 * Math.PI + this.angleOffset; 551 | this.endAngle = 1.5 * Math.PI + this.angleOffset + this.angleArc; 552 | 553 | var s = max( 554 | String(Math.abs(this.o.max)).length 555 | , String(Math.abs(this.o.min)).length 556 | , 2 557 | ) + 2; 558 | 559 | this.o.displayInput 560 | && this.i.css({ 561 | 'width' : ((this.o.width / 2 + 4) >> 0) + 'px' 562 | ,'height' : ((this.o.width / 3) >> 0) + 'px' 563 | ,'position' : 'absolute' 564 | ,'vertical-align' : 'middle' 565 | ,'margin-top' : ((this.o.width / 3) >> 0) + 'px' 566 | ,'margin-left' : '-' + ((this.o.width * 3 / 4 + 2) >> 0) + 'px' 567 | ,'border' : 0 568 | ,'background' : 'none' 569 | ,'font' : 'bold ' + ((this.o.width / s) >> 0) + 'px Arial' 570 | ,'text-align' : 'center' 571 | ,'color' : this.o.fgColor 572 | ,'padding' : '0px' 573 | ,'-webkit-appearance': 'none' 574 | }) 575 | || this.i.css({ 576 | 'width' : '0px' 577 | ,'visibility' : 'hidden' 578 | }); 579 | }; 580 | 581 | this.change = function (v) { 582 | this.cv = v; 583 | this.$.val(v); 584 | }; 585 | 586 | this.angle = function (v) { 587 | return (v - this.o.min) * this.angleArc / (this.o.max - this.o.min); 588 | }; 589 | 590 | this.draw = function () { 591 | 592 | var c = this.g, // context 593 | a = this.angle(this.cv) // Angle 594 | , sat = this.startAngle // Start angle 595 | , eat = sat + a // End angle 596 | , sa, ea // Previous angles 597 | , r = 1; 598 | 599 | c.lineWidth = this.lineWidth; 600 | 601 | this.o.cursor 602 | && (sat = eat - this.cursorExt) 603 | && (eat = eat + this.cursorExt); 604 | 605 | c.beginPath(); 606 | c.strokeStyle = this.o.bgColor; 607 | c.arc(this.xy, this.xy, this.radius, this.endAngle, this.startAngle, true); 608 | c.stroke(); 609 | 610 | if (this.o.displayPrevious) { 611 | ea = this.startAngle + this.angle(this.v); 612 | sa = this.startAngle; 613 | this.o.cursor 614 | && (sa = ea - this.cursorExt) 615 | && (ea = ea + this.cursorExt); 616 | 617 | c.beginPath(); 618 | c.strokeStyle = this.pColor; 619 | c.arc(this.xy, this.xy, this.radius, sa, ea, false); 620 | c.stroke(); 621 | r = (this.cv == this.v); 622 | } 623 | 624 | c.beginPath(); 625 | c.strokeStyle = r ? this.o.fgColor : this.fgColor ; 626 | c.arc(this.xy, this.xy, this.radius, sat, eat, false); 627 | c.stroke(); 628 | }; 629 | 630 | this.cancel = function () { 631 | this.val(this.v); 632 | }; 633 | }; 634 | 635 | $.fn.dial = $.fn.knob = function (o) { 636 | return this.each( 637 | function () { 638 | var d = new k.Dial(); 639 | d.o = o; 640 | d.$ = $(this); 641 | d.run(); 642 | } 643 | ).parent(); 644 | }; 645 | 646 | }); -------------------------------------------------------------------------------- /assets/javascripts/rickshaw-1.4.3.min.js: -------------------------------------------------------------------------------- 1 | var Rickshaw={namespace:function(namespace,obj){var parts=namespace.split(".");var parent=Rickshaw;for(var i=1,length=parts.length;i=3){if(s.data[2].xthis.window.xMax)isInRange=false;return isInRange}return true};this.onUpdate=function(callback){this.updateCallbacks.push(callback)};this.registerRenderer=function(renderer){this._renderers=this._renderers||{};this._renderers[renderer.name]=renderer};this.configure=function(args){if(args.width||args.height){this.setSize(args)}Rickshaw.keys(this.defaults).forEach(function(k){this[k]=k in args?args[k]:k in this?this[k]:this.defaults[k]},this);this.setRenderer(args.renderer||this.renderer.name,args)};this.setRenderer=function(r,args){if(typeof r=="function"){this.renderer=new r({graph:self});this.registerRenderer(this.renderer)}else{if(!this._renderers[r]){throw"couldn't find renderer "+r}this.renderer=this._renderers[r]}if(typeof args=="object"){this.renderer.configure(args)}};this.setSize=function(args){args=args||{};if(typeof window!==undefined){var style=window.getComputedStyle(this.element,null);var elementWidth=parseInt(style.getPropertyValue("width"),10);var elementHeight=parseInt(style.getPropertyValue("height"),10)}this.width=args.width||elementWidth||400;this.height=args.height||elementHeight||250;this.vis&&this.vis.attr("width",this.width).attr("height",this.height)};this.initialize(args)};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"]};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()/1e3);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*.85};this.removeData=function(data){data.forEach(function(series){series.shift()});timeBase+=timeInterval}};Rickshaw.namespace("Rickshaw.Fixtures.Time");Rickshaw.Fixtures.Time=function(){var tzOffset=(new Date).getTimezoneOffset()*60;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"}}];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 nearFuture;var rounded;if(unit.name=="month"){nearFuture=new Date((time+unit.seconds-1)*1e3);rounded=new Date(0);rounded.setUTCFullYear(nearFuture.getUTCFullYear());rounded.setUTCMonth(nearFuture.getUTCMonth());rounded.setUTCDate(1);rounded.setUTCHours(0);rounded.setUTCMinutes(0);rounded.setUTCSeconds(0);rounded.setUTCMilliseconds(0);return rounded.getTime()/1e3}if(unit.name=="year"){nearFuture=new Date((time+unit.seconds-1)*1e3);rounded=new Date(0);rounded.setUTCFullYear(nearFuture.getUTCFullYear());rounded.setUTCMonth(0);rounded.setUTCDate(1);rounded.setUTCHours(0);rounded.setUTCMinutes(0);rounded.setUTCSeconds(0);rounded.setUTCMilliseconds(0);return rounded.getTime()/1e3}return Math.ceil(time/unit.seconds)*unit.seconds}};Rickshaw.namespace("Rickshaw.Fixtures.Time.Local");Rickshaw.Fixtures.Time.Local=function(){var tzOffset=(new Date).getTimezoneOffset()*60;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"}}];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 nearFuture;var rounded;if(unit.name=="day"){nearFuture=new Date((time+unit.seconds-1)*1e3);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()/1e3}if(unit.name=="month"){nearFuture=new Date((time+unit.seconds-1)*1e3);rounded=new Date(0);rounded.setMilliseconds(0);rounded.setSeconds(0);rounded.setMinutes(0);rounded.setHours(0);rounded.setDate(1);rounded.setMonth(nearFuture.getMonth());rounded.setFullYear(nearFuture.getFullYear());return rounded.getTime()/1e3}if(unit.name=="year"){nearFuture=new Date((time+unit.seconds-1)*1e3);rounded=new Date(0);rounded.setFullYear(nearFuture.getFullYear());rounded.setMilliseconds(0);rounded.setSeconds(0);rounded.setMinutes(0);rounded.setHours(0);rounded.setDate(1);rounded.setMonth(0);return rounded.getTime()/1e3}return Math.ceil(time/unit.seconds)*unit.seconds}};Rickshaw.namespace("Rickshaw.Fixtures.Number");Rickshaw.Fixtures.Number.formatKMBT=function(y){var abs_y=Math.abs(y);if(abs_y>=1e12){return y/1e12+"T"}else if(abs_y>=1e9){return y/1e9+"B"}else if(abs_y>=1e6){return y/1e6+"M"}else if(abs_y>=1e3){return y/1e3+"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>=0x4000000000000){return y/0x4000000000000+"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}};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;iself.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]);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()})};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;iself.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*1e3));element.appendChild(title);self.graph.element.appendChild(element);self.elements.push(element)})};this.graph.onUpdate(function(){self.render()})};Rickshaw.namespace("Rickshaw.Graph.Axis.X");Rickshaw.Graph.Axis.X=function(args){var self=this;var berthRate=.1;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.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));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)};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=.1;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.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))}});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){var adjustedScale=this.scale.copy().range(scale.range());return $super(adjustedScale)},_drawGrid:function($super,axis){if(this.grid){$super(axis)}}});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"))(.8).toString()};this.addHighlightEvents=function(l){l.element.addEventListener("mouseover",function(e){if(activeLine)return;else activeLine=l;self.legend.lines.forEach(function(line,index){if(l===line){if(index>0&&self.graph.renderer.unstack&&(line.series.renderer?line.series.renderer.unstack:true)){var seriesIndex=self.graph.series.length-index-1; 2 | 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){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)})}};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.$=="undefined"){throw"couldn't find jQuery at window.$"}if(typeof window.$.ui=="undefined"){throw"couldn't find jQuery UI at window.$.ui"}$(function(){$(self.legend.list).sortable({containment:"parent",tolerance:"pointer",update:function(event,ui){var series=[];$(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()}});$(self.legend.list).disableSelection()});this.graph.onUpdate(function(){var h=window.getComputedStyle(self.legend.element).height;self.legend.element.style.height=h})};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="✔";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;idomainX){dataIndex=Math.abs(domainX-data[i].x)yMax)yMax=y});if(series[0].xxMax)xMax=series[series.length-1].x});xMin-=(xMax-xMin)*this.padding.left;xMax+=(xMax-xMin)*this.padding.right;yMin=this.graph.min==="auto"?yMin:this.graph.min||0;yMax=this.graph.max===undefined?yMax:this.graph.max;if(this.graph.min==="auto"||yMin<0){yMin-=(yMax-yMin)*this.padding.bottom}if(this.graph.max===undefined){yMax+=(yMax-yMin)*this.padding.top}return{x:[xMin,xMax],y:[yMin,yMax]}},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 data=series.filter(function(s){return!s.disabled}).map(function(s){return s.stack});var nodes=vis.selectAll("path").data(data).enter().append("svg:path").attr("d",this.seriesPathFactory());var i=0;series.forEach(function(series){if(series.disabled)return;series.path=nodes[0][i++];this._styleSeries(series)},this)},_styleSeries:function(series){var fill=this.fill?series.color:"none";var stroke=this.stroke?series.color:"none";series.path.setAttribute("fill",fill);series.path.setAttribute("stroke",stroke);series.path.setAttribute("stroke-width",this.strokeWidth);series.path.setAttribute("class",series.className)},configure:function(args){args=args||{};Rickshaw.keys(this.defaults()).forEach(function(key){if(!args.hasOwnProperty(key)){this[key]=this[key]||this.graph[key]||this.defaults()[key];return}if(typeof this.defaults()[key]=="object"){Rickshaw.keys(this.defaults()[key]).forEach(function(k){this[key][k]=args[key][k]!==undefined?args[key][k]:this[key][k]!==undefined?this[key][k]:this.defaults()[key][k]},this)}else{this[key]=args[key]!==undefined?args[key]:this[key]!==undefined?this[key]:this.graph[key]!==undefined?this.graph[key]:this.defaults()[key]}},this)},setStrokeWidth:function(strokeWidth){if(strokeWidth!==undefined){this.strokeWidth=strokeWidth}},setTension:function(tension){if(tension!==undefined){this.tension=tension}}});Rickshaw.namespace("Rickshaw.Graph.Renderer.Line");Rickshaw.Graph.Renderer.Line=Rickshaw.Class.create(Rickshaw.Graph.Renderer,{name:"line",defaults:function($super){return Rickshaw.extend($super(),{unstack:true,fill:false,stroke:true})},seriesPathFactory: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)}).interpolate(this.graph.interpolation).tension(this.tension);factory.defined&&factory.defined(function(d){return d.y!==null});return factory}});Rickshaw.namespace("Rickshaw.Graph.Renderer.Stack");Rickshaw.Graph.Renderer.Stack=Rickshaw.Class.create(Rickshaw.Graph.Renderer,{name:"stack",defaults:function($super){return Rickshaw.extend($super(),{fill:true,stroke:false,unstack: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(this.graph.interpolation).tension(this.tension);factory.defined&&factory.defined(function(d){return d.y!==null});return factory}});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:.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){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;i0){this[0].data.forEach(function(plot){item.data.push({x:plot.x,y:0})})}else if(item.data.length===0){item.data.push({x:this.timeBase-(this.timeInterval||0),y:0})}this.push(item);if(this.legend){this.legend.addLine(this.itemByName(item.name))}},addData:function(data,x){var index=this.getIndex();Rickshaw.keys(data).forEach(function(name){if(!this.itemByName(name)){this.addItem({name:name})}},this);this.forEach(function(item){item.data.push({x:x||(index*this.timeInterval||1)+this.timeBase,y:data[item.name]||0})},this)},getIndex:function(){return this[0]&&this[0].data&&this[0].data.length?this[0].data.length:0},itemByName:function(name){for(var i=0;i1;i--){this.currentSize+=1;this.currentIndex+=1;this.forEach(function(item){item.data.unshift({x:((i-1)*this.timeInterval||1)+this.timeBase,y:0,i:i})},this)}}},addData:function($super,data,x){$super(data,x);this.currentSize+=1;this.currentIndex+=1;if(this.maxDataPoints!==undefined){while(this.currentSize>this.maxDataPoints){this.dropData()}}},dropData:function(){this.forEach(function(item){item.data.splice(0,1)});this.currentSize-=1},getIndex:function(){return this.currentIndex}}); -------------------------------------------------------------------------------- /assets/stylesheets/application.scss: -------------------------------------------------------------------------------- 1 | /* 2 | //=require_directory . 3 | //=require_tree ../../widgets 4 | */ 5 | // ---------------------------------------------------------------------------- 6 | // Sass declarations 7 | // ---------------------------------------------------------------------------- 8 | $background-color: #222; 9 | $text-color: #fff; 10 | 11 | $background-warning-color-1: #e82711; 12 | $background-warning-color-2: #9b2d23; 13 | $text-warning-color: #fff; 14 | 15 | $background-danger-color-1: #eeae32; 16 | $background-danger-color-2: #ff9618; 17 | $text-danger-color: #fff; 18 | 19 | @-webkit-keyframes status-warning-background { 20 | 0% { background-color: $background-warning-color-1; } 21 | 50% { background-color: $background-warning-color-2; } 22 | 100% { background-color: $background-warning-color-1; } 23 | } 24 | @-webkit-keyframes status-danger-background { 25 | 0% { background-color: $background-danger-color-1; } 26 | 50% { background-color: $background-danger-color-2; } 27 | 100% { background-color: $background-danger-color-1; } 28 | } 29 | @mixin animation($animation-name, $duration, $function, $animation-iteration-count:""){ 30 | -webkit-animation: $animation-name $duration $function #{$animation-iteration-count}; 31 | -moz-animation: $animation-name $duration $function #{$animation-iteration-count}; 32 | -ms-animation: $animation-name $duration $function #{$animation-iteration-count}; 33 | } 34 | 35 | // ---------------------------------------------------------------------------- 36 | // Base styles 37 | // ---------------------------------------------------------------------------- 38 | html { 39 | font-size: 100%; 40 | -webkit-text-size-adjust: 100%; 41 | -ms-text-size-adjust: 100%; 42 | } 43 | 44 | body { 45 | margin: 0; 46 | background-color: $background-color; 47 | font-size: 20px; 48 | color: $text-color; 49 | font-family: 'Open Sans', "Helvetica Neue", Helvetica, Arial, sans-serif; 50 | } 51 | 52 | b, strong { 53 | font-weight: bold; 54 | } 55 | 56 | a { 57 | text-decoration: none; 58 | color: inherit; 59 | } 60 | 61 | img { 62 | border: 0; 63 | -ms-interpolation-mode: bicubic; 64 | vertical-align: middle; 65 | } 66 | 67 | img, object { 68 | max-width: 100%; 69 | } 70 | 71 | iframe { 72 | max-width: 100%; 73 | } 74 | 75 | table { 76 | border-collapse: collapse; 77 | border-spacing: 0; 78 | width: 100%; 79 | } 80 | 81 | td { 82 | vertical-align: middle; 83 | } 84 | 85 | ul, ol { 86 | padding: 0; 87 | margin: 0; 88 | } 89 | 90 | h1, h2, h3, h4, h5, p { 91 | padding: 0; 92 | margin: 0; 93 | } 94 | h1 { 95 | margin-bottom: 12px; 96 | text-align: center; 97 | font-size: 30px; 98 | font-weight: 400; 99 | } 100 | h2 { 101 | text-transform: uppercase; 102 | font-size: 76px; 103 | font-weight: 700; 104 | color: $text-color; 105 | } 106 | h3 { 107 | font-size: 25px; 108 | font-weight: 600; 109 | color: $text-color; 110 | } 111 | 112 | // ---------------------------------------------------------------------------- 113 | // Base widget styles 114 | // ---------------------------------------------------------------------------- 115 | .gridster { 116 | margin: 0px auto; 117 | } 118 | 119 | .icon-background { 120 | width: 100%!important; 121 | height: 100%; 122 | position: absolute; 123 | left: 0; 124 | top: 0; 125 | opacity: 0.1; 126 | font-size: 275px; 127 | text-align: center; 128 | margin-top: 82px; 129 | } 130 | 131 | .list-nostyle { 132 | list-style: none; 133 | } 134 | 135 | .gridster ul { 136 | list-style: none; 137 | } 138 | 139 | .gs_w { 140 | width: 100%; 141 | display: table; 142 | cursor: pointer; 143 | } 144 | 145 | .widget { 146 | padding: 25px 12px; 147 | text-align: center; 148 | width: 100%; 149 | display: table-cell; 150 | vertical-align: middle; 151 | } 152 | 153 | .widget.status-warning { 154 | background-color: $background-warning-color-1; 155 | @include animation(status-warning-background, 2s, ease, infinite); 156 | 157 | .icon-warning-sign { 158 | display: inline-block; 159 | } 160 | 161 | .title, .more-info { 162 | color: $text-warning-color; 163 | } 164 | } 165 | 166 | .widget.status-danger { 167 | color: $text-danger-color; 168 | background-color: $background-danger-color-1; 169 | @include animation(status-danger-background, 2s, ease, infinite); 170 | 171 | .icon-warning-sign { 172 | display: inline-block; 173 | } 174 | 175 | .title, .more-info { 176 | color: $text-danger-color; 177 | } 178 | } 179 | 180 | .more-info { 181 | font-size: 15px; 182 | position: absolute; 183 | bottom: 32px; 184 | left: 0; 185 | right: 0; 186 | } 187 | 188 | .updated-at { 189 | font-size: 15px; 190 | position: absolute; 191 | bottom: 12px; 192 | left: 0; 193 | right: 0; 194 | } 195 | 196 | #save-gridster { 197 | display: none; 198 | position: fixed; 199 | top: 0; 200 | margin: 0px auto; 201 | left: 50%; 202 | z-index: 1000; 203 | background: black; 204 | width: 190px; 205 | text-align: center; 206 | border: 1px solid white; 207 | border-top: 0px; 208 | margin-left: -95px; 209 | padding: 15px; 210 | } 211 | 212 | #save-gridster:hover { 213 | padding-top: 25px; 214 | } 215 | 216 | #saving-instructions { 217 | display: none; 218 | padding: 10px; 219 | width: 500px; 220 | height: 122px; 221 | z-index: 1000; 222 | background: white; 223 | top: 100px; 224 | color: black; 225 | font-size: 15px; 226 | padding-bottom: 4px; 227 | 228 | textarea { 229 | white-space: nowrap; 230 | width: 494px; 231 | height: 80px; 232 | } 233 | } 234 | 235 | #lean_overlay { 236 | position: fixed; 237 | z-index:100; 238 | top: 0px; 239 | left: 0px; 240 | height:100%; 241 | width:100%; 242 | background: #000; 243 | display: none; 244 | } 245 | 246 | #container { 247 | padding-top: 5px; 248 | } 249 | 250 | 251 | // ---------------------------------------------------------------------------- 252 | // Clearfix 253 | // ---------------------------------------------------------------------------- 254 | .clearfix:before, .clearfix:after { content: "\0020"; display: block; height: 0; overflow: hidden; } 255 | .clearfix:after { clear: both; } 256 | .clearfix { zoom: 1; } 257 | 258 | -------------------------------------------------------------------------------- /assets/stylesheets/font-awesome.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Font Awesome 3.2.1 3 | * the iconic font designed for Bootstrap 4 | * ------------------------------------------------------------------------------ 5 | * The full suite of pictographic icons, examples, and documentation can be 6 | * found at http://fontawesome.io. Stay up to date on Twitter at 7 | * http://twitter.com/fontawesome. 8 | * 9 | * License 10 | * ------------------------------------------------------------------------------ 11 | * - The Font Awesome font is licensed under SIL OFL 1.1 - 12 | * http://scripts.sil.org/OFL 13 | * - Font Awesome CSS, LESS, and SASS files are licensed under MIT License - 14 | * http://opensource.org/licenses/mit-license.html 15 | * - Font Awesome documentation licensed under CC BY 3.0 - 16 | * http://creativecommons.org/licenses/by/3.0/ 17 | * - Attribution is no longer required in Font Awesome 3.0, but much appreciated: 18 | * "Font Awesome by Dave Gandy - http://fontawesome.io" 19 | * 20 | * Author - Dave Gandy 21 | * ------------------------------------------------------------------------------ 22 | * Email: dave@fontawesome.io 23 | * Twitter: http://twitter.com/davegandy 24 | * Work: Lead Product Designer @ Kyruus - http://kyruus.com 25 | */ 26 | /* FONT PATH 27 | * -------------------------- */ 28 | @font-face { 29 | font-family: 'FontAwesome'; 30 | src: url('../assets/fontawesome-webfont.eot?v=3.2.1'); 31 | src: url('../assets/fontawesome-webfont.eot?#iefix&v=3.2.1') format('embedded-opentype'), url('../assets/fontawesome-webfont.woff?v=3.2.1') format('woff'), url('../assets/fontawesome-webfont.ttf?v=3.2.1') format('truetype'), url('../assets/fontawesome-webfont.svg#fontawesomeregular?v=3.2.1') format('svg'); 32 | font-weight: normal; 33 | font-style: normal; 34 | } 35 | /* FONT AWESOME CORE 36 | * -------------------------- */ 37 | [class^="icon-"], 38 | [class*=" icon-"] { 39 | font-family: FontAwesome; 40 | font-weight: normal; 41 | font-style: normal; 42 | text-decoration: inherit; 43 | -webkit-font-smoothing: antialiased; 44 | *margin-right: .3em; 45 | } 46 | [class^="icon-"]:before, 47 | [class*=" icon-"]:before { 48 | text-decoration: inherit; 49 | display: inline-block; 50 | speak: none; 51 | } 52 | /* makes the font 33% larger relative to the icon container */ 53 | .icon-large:before { 54 | vertical-align: -10%; 55 | font-size: 1.3333333333333333em; 56 | } 57 | /* makes sure icons active on rollover in links */ 58 | a [class^="icon-"], 59 | a [class*=" icon-"] { 60 | display: inline; 61 | } 62 | /* increased font size for icon-large */ 63 | [class^="icon-"].icon-fixed-width, 64 | [class*=" icon-"].icon-fixed-width { 65 | display: inline-block; 66 | width: 1.1428571428571428em; 67 | text-align: right; 68 | padding-right: 0.2857142857142857em; 69 | } 70 | [class^="icon-"].icon-fixed-width.icon-large, 71 | [class*=" icon-"].icon-fixed-width.icon-large { 72 | width: 1.4285714285714286em; 73 | } 74 | .icons-ul { 75 | margin-left: 2.142857142857143em; 76 | list-style-type: none; 77 | } 78 | .icons-ul > li { 79 | position: relative; 80 | } 81 | .icons-ul .icon-li { 82 | position: absolute; 83 | left: -2.142857142857143em; 84 | width: 2.142857142857143em; 85 | text-align: center; 86 | line-height: inherit; 87 | } 88 | [class^="icon-"].hide, 89 | [class*=" icon-"].hide { 90 | display: none; 91 | } 92 | .icon-muted { 93 | color: #eeeeee; 94 | } 95 | .icon-light { 96 | color: #ffffff; 97 | } 98 | .icon-dark { 99 | color: #333333; 100 | } 101 | .icon-border { 102 | border: solid 1px #eeeeee; 103 | padding: .2em .25em .15em; 104 | -webkit-border-radius: 3px; 105 | -moz-border-radius: 3px; 106 | border-radius: 3px; 107 | } 108 | .icon-2x { 109 | font-size: 2em; 110 | } 111 | .icon-2x.icon-border { 112 | border-width: 2px; 113 | -webkit-border-radius: 4px; 114 | -moz-border-radius: 4px; 115 | border-radius: 4px; 116 | } 117 | .icon-3x { 118 | font-size: 3em; 119 | } 120 | .icon-3x.icon-border { 121 | border-width: 3px; 122 | -webkit-border-radius: 5px; 123 | -moz-border-radius: 5px; 124 | border-radius: 5px; 125 | } 126 | .icon-4x { 127 | font-size: 4em; 128 | } 129 | .icon-4x.icon-border { 130 | border-width: 4px; 131 | -webkit-border-radius: 6px; 132 | -moz-border-radius: 6px; 133 | border-radius: 6px; 134 | } 135 | .icon-5x { 136 | font-size: 5em; 137 | } 138 | .icon-5x.icon-border { 139 | border-width: 5px; 140 | -webkit-border-radius: 7px; 141 | -moz-border-radius: 7px; 142 | border-radius: 7px; 143 | } 144 | .pull-right { 145 | float: right; 146 | } 147 | .pull-left { 148 | float: left; 149 | } 150 | [class^="icon-"].pull-left, 151 | [class*=" icon-"].pull-left { 152 | margin-right: .3em; 153 | } 154 | [class^="icon-"].pull-right, 155 | [class*=" icon-"].pull-right { 156 | margin-left: .3em; 157 | } 158 | /* BOOTSTRAP SPECIFIC CLASSES 159 | * -------------------------- */ 160 | /* Bootstrap 2.0 sprites.less reset */ 161 | [class^="icon-"], 162 | [class*=" icon-"] { 163 | display: inline; 164 | width: auto; 165 | height: auto; 166 | line-height: normal; 167 | vertical-align: baseline; 168 | background-image: none; 169 | background-position: 0% 0%; 170 | background-repeat: repeat; 171 | margin-top: 0; 172 | } 173 | /* more sprites.less reset */ 174 | .icon-white, 175 | .nav-pills > .active > a > [class^="icon-"], 176 | .nav-pills > .active > a > [class*=" icon-"], 177 | .nav-list > .active > a > [class^="icon-"], 178 | .nav-list > .active > a > [class*=" icon-"], 179 | .navbar-inverse .nav > .active > a > [class^="icon-"], 180 | .navbar-inverse .nav > .active > a > [class*=" icon-"], 181 | .dropdown-menu > li > a:hover > [class^="icon-"], 182 | .dropdown-menu > li > a:hover > [class*=" icon-"], 183 | .dropdown-menu > .active > a > [class^="icon-"], 184 | .dropdown-menu > .active > a > [class*=" icon-"], 185 | .dropdown-submenu:hover > a > [class^="icon-"], 186 | .dropdown-submenu:hover > a > [class*=" icon-"] { 187 | background-image: none; 188 | } 189 | /* keeps Bootstrap styles with and without icons the same */ 190 | .btn [class^="icon-"].icon-large, 191 | .nav [class^="icon-"].icon-large, 192 | .btn [class*=" icon-"].icon-large, 193 | .nav [class*=" icon-"].icon-large { 194 | line-height: .9em; 195 | } 196 | .btn [class^="icon-"].icon-spin, 197 | .nav [class^="icon-"].icon-spin, 198 | .btn [class*=" icon-"].icon-spin, 199 | .nav [class*=" icon-"].icon-spin { 200 | display: inline-block; 201 | } 202 | .nav-tabs [class^="icon-"], 203 | .nav-pills [class^="icon-"], 204 | .nav-tabs [class*=" icon-"], 205 | .nav-pills [class*=" icon-"], 206 | .nav-tabs [class^="icon-"].icon-large, 207 | .nav-pills [class^="icon-"].icon-large, 208 | .nav-tabs [class*=" icon-"].icon-large, 209 | .nav-pills [class*=" icon-"].icon-large { 210 | line-height: .9em; 211 | } 212 | .btn [class^="icon-"].pull-left.icon-2x, 213 | .btn [class*=" icon-"].pull-left.icon-2x, 214 | .btn [class^="icon-"].pull-right.icon-2x, 215 | .btn [class*=" icon-"].pull-right.icon-2x { 216 | margin-top: .18em; 217 | } 218 | .btn [class^="icon-"].icon-spin.icon-large, 219 | .btn [class*=" icon-"].icon-spin.icon-large { 220 | line-height: .8em; 221 | } 222 | .btn.btn-small [class^="icon-"].pull-left.icon-2x, 223 | .btn.btn-small [class*=" icon-"].pull-left.icon-2x, 224 | .btn.btn-small [class^="icon-"].pull-right.icon-2x, 225 | .btn.btn-small [class*=" icon-"].pull-right.icon-2x { 226 | margin-top: .25em; 227 | } 228 | .btn.btn-large [class^="icon-"], 229 | .btn.btn-large [class*=" icon-"] { 230 | margin-top: 0; 231 | } 232 | .btn.btn-large [class^="icon-"].pull-left.icon-2x, 233 | .btn.btn-large [class*=" icon-"].pull-left.icon-2x, 234 | .btn.btn-large [class^="icon-"].pull-right.icon-2x, 235 | .btn.btn-large [class*=" icon-"].pull-right.icon-2x { 236 | margin-top: .05em; 237 | } 238 | .btn.btn-large [class^="icon-"].pull-left.icon-2x, 239 | .btn.btn-large [class*=" icon-"].pull-left.icon-2x { 240 | margin-right: .2em; 241 | } 242 | .btn.btn-large [class^="icon-"].pull-right.icon-2x, 243 | .btn.btn-large [class*=" icon-"].pull-right.icon-2x { 244 | margin-left: .2em; 245 | } 246 | /* Fixes alignment in nav lists */ 247 | .nav-list [class^="icon-"], 248 | .nav-list [class*=" icon-"] { 249 | line-height: inherit; 250 | } 251 | /* EXTRAS 252 | * -------------------------- */ 253 | /* Stacked and layered icon */ 254 | .icon-stack { 255 | position: relative; 256 | display: inline-block; 257 | width: 2em; 258 | height: 2em; 259 | line-height: 2em; 260 | vertical-align: -35%; 261 | } 262 | .icon-stack [class^="icon-"], 263 | .icon-stack [class*=" icon-"] { 264 | display: block; 265 | text-align: center; 266 | position: absolute; 267 | width: 100%; 268 | height: 100%; 269 | font-size: 1em; 270 | line-height: inherit; 271 | *line-height: 2em; 272 | } 273 | .icon-stack .icon-stack-base { 274 | font-size: 2em; 275 | *line-height: 1em; 276 | } 277 | /* Animated rotating icon */ 278 | .icon-spin { 279 | display: inline-block; 280 | -moz-animation: spin 2s infinite linear; 281 | -o-animation: spin 2s infinite linear; 282 | -webkit-animation: spin 2s infinite linear; 283 | animation: spin 2s infinite linear; 284 | } 285 | /* Prevent stack and spinners from being taken inline when inside a link */ 286 | a .icon-stack, 287 | a .icon-spin { 288 | display: inline-block; 289 | text-decoration: none; 290 | } 291 | @-moz-keyframes spin { 292 | 0% { 293 | -moz-transform: rotate(0deg); 294 | } 295 | 100% { 296 | -moz-transform: rotate(359deg); 297 | } 298 | } 299 | @-webkit-keyframes spin { 300 | 0% { 301 | -webkit-transform: rotate(0deg); 302 | } 303 | 100% { 304 | -webkit-transform: rotate(359deg); 305 | } 306 | } 307 | @-o-keyframes spin { 308 | 0% { 309 | -o-transform: rotate(0deg); 310 | } 311 | 100% { 312 | -o-transform: rotate(359deg); 313 | } 314 | } 315 | @-ms-keyframes spin { 316 | 0% { 317 | -ms-transform: rotate(0deg); 318 | } 319 | 100% { 320 | -ms-transform: rotate(359deg); 321 | } 322 | } 323 | @keyframes spin { 324 | 0% { 325 | transform: rotate(0deg); 326 | } 327 | 100% { 328 | transform: rotate(359deg); 329 | } 330 | } 331 | /* Icon rotations and mirroring */ 332 | .icon-rotate-90:before { 333 | -webkit-transform: rotate(90deg); 334 | -moz-transform: rotate(90deg); 335 | -ms-transform: rotate(90deg); 336 | -o-transform: rotate(90deg); 337 | transform: rotate(90deg); 338 | filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=1); 339 | } 340 | .icon-rotate-180:before { 341 | -webkit-transform: rotate(180deg); 342 | -moz-transform: rotate(180deg); 343 | -ms-transform: rotate(180deg); 344 | -o-transform: rotate(180deg); 345 | transform: rotate(180deg); 346 | filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=2); 347 | } 348 | .icon-rotate-270:before { 349 | -webkit-transform: rotate(270deg); 350 | -moz-transform: rotate(270deg); 351 | -ms-transform: rotate(270deg); 352 | -o-transform: rotate(270deg); 353 | transform: rotate(270deg); 354 | filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=3); 355 | } 356 | .icon-flip-horizontal:before { 357 | -webkit-transform: scale(-1, 1); 358 | -moz-transform: scale(-1, 1); 359 | -ms-transform: scale(-1, 1); 360 | -o-transform: scale(-1, 1); 361 | transform: scale(-1, 1); 362 | } 363 | .icon-flip-vertical:before { 364 | -webkit-transform: scale(1, -1); 365 | -moz-transform: scale(1, -1); 366 | -ms-transform: scale(1, -1); 367 | -o-transform: scale(1, -1); 368 | transform: scale(1, -1); 369 | } 370 | /* ensure rotation occurs inside anchor tags */ 371 | a .icon-rotate-90:before, 372 | a .icon-rotate-180:before, 373 | a .icon-rotate-270:before, 374 | a .icon-flip-horizontal:before, 375 | a .icon-flip-vertical:before { 376 | display: inline-block; 377 | } 378 | /* Font Awesome uses the Unicode Private Use Area (PUA) to ensure screen 379 | readers do not read off random characters that represent icons */ 380 | .icon-glass:before { 381 | content: "\f000"; 382 | } 383 | .icon-music:before { 384 | content: "\f001"; 385 | } 386 | .icon-search:before { 387 | content: "\f002"; 388 | } 389 | .icon-envelope-alt:before { 390 | content: "\f003"; 391 | } 392 | .icon-heart:before { 393 | content: "\f004"; 394 | } 395 | .icon-star:before { 396 | content: "\f005"; 397 | } 398 | .icon-star-empty:before { 399 | content: "\f006"; 400 | } 401 | .icon-user:before { 402 | content: "\f007"; 403 | } 404 | .icon-film:before { 405 | content: "\f008"; 406 | } 407 | .icon-th-large:before { 408 | content: "\f009"; 409 | } 410 | .icon-th:before { 411 | content: "\f00a"; 412 | } 413 | .icon-th-list:before { 414 | content: "\f00b"; 415 | } 416 | .icon-ok:before { 417 | content: "\f00c"; 418 | } 419 | .icon-remove:before { 420 | content: "\f00d"; 421 | } 422 | .icon-zoom-in:before { 423 | content: "\f00e"; 424 | } 425 | .icon-zoom-out:before { 426 | content: "\f010"; 427 | } 428 | .icon-power-off:before, 429 | .icon-off:before { 430 | content: "\f011"; 431 | } 432 | .icon-signal:before { 433 | content: "\f012"; 434 | } 435 | .icon-gear:before, 436 | .icon-cog:before { 437 | content: "\f013"; 438 | } 439 | .icon-trash:before { 440 | content: "\f014"; 441 | } 442 | .icon-home:before { 443 | content: "\f015"; 444 | } 445 | .icon-file-alt:before { 446 | content: "\f016"; 447 | } 448 | .icon-time:before { 449 | content: "\f017"; 450 | } 451 | .icon-road:before { 452 | content: "\f018"; 453 | } 454 | .icon-download-alt:before { 455 | content: "\f019"; 456 | } 457 | .icon-download:before { 458 | content: "\f01a"; 459 | } 460 | .icon-upload:before { 461 | content: "\f01b"; 462 | } 463 | .icon-inbox:before { 464 | content: "\f01c"; 465 | } 466 | .icon-play-circle:before { 467 | content: "\f01d"; 468 | } 469 | .icon-rotate-right:before, 470 | .icon-repeat:before { 471 | content: "\f01e"; 472 | } 473 | .icon-refresh:before { 474 | content: "\f021"; 475 | } 476 | .icon-list-alt:before { 477 | content: "\f022"; 478 | } 479 | .icon-lock:before { 480 | content: "\f023"; 481 | } 482 | .icon-flag:before { 483 | content: "\f024"; 484 | } 485 | .icon-headphones:before { 486 | content: "\f025"; 487 | } 488 | .icon-volume-off:before { 489 | content: "\f026"; 490 | } 491 | .icon-volume-down:before { 492 | content: "\f027"; 493 | } 494 | .icon-volume-up:before { 495 | content: "\f028"; 496 | } 497 | .icon-qrcode:before { 498 | content: "\f029"; 499 | } 500 | .icon-barcode:before { 501 | content: "\f02a"; 502 | } 503 | .icon-tag:before { 504 | content: "\f02b"; 505 | } 506 | .icon-tags:before { 507 | content: "\f02c"; 508 | } 509 | .icon-book:before { 510 | content: "\f02d"; 511 | } 512 | .icon-bookmark:before { 513 | content: "\f02e"; 514 | } 515 | .icon-print:before { 516 | content: "\f02f"; 517 | } 518 | .icon-camera:before { 519 | content: "\f030"; 520 | } 521 | .icon-font:before { 522 | content: "\f031"; 523 | } 524 | .icon-bold:before { 525 | content: "\f032"; 526 | } 527 | .icon-italic:before { 528 | content: "\f033"; 529 | } 530 | .icon-text-height:before { 531 | content: "\f034"; 532 | } 533 | .icon-text-width:before { 534 | content: "\f035"; 535 | } 536 | .icon-align-left:before { 537 | content: "\f036"; 538 | } 539 | .icon-align-center:before { 540 | content: "\f037"; 541 | } 542 | .icon-align-right:before { 543 | content: "\f038"; 544 | } 545 | .icon-align-justify:before { 546 | content: "\f039"; 547 | } 548 | .icon-list:before { 549 | content: "\f03a"; 550 | } 551 | .icon-indent-left:before { 552 | content: "\f03b"; 553 | } 554 | .icon-indent-right:before { 555 | content: "\f03c"; 556 | } 557 | .icon-facetime-video:before { 558 | content: "\f03d"; 559 | } 560 | .icon-picture:before { 561 | content: "\f03e"; 562 | } 563 | .icon-pencil:before { 564 | content: "\f040"; 565 | } 566 | .icon-map-marker:before { 567 | content: "\f041"; 568 | } 569 | .icon-adjust:before { 570 | content: "\f042"; 571 | } 572 | .icon-tint:before { 573 | content: "\f043"; 574 | } 575 | .icon-edit:before { 576 | content: "\f044"; 577 | } 578 | .icon-share:before { 579 | content: "\f045"; 580 | } 581 | .icon-check:before { 582 | content: "\f046"; 583 | } 584 | .icon-move:before { 585 | content: "\f047"; 586 | } 587 | .icon-step-backward:before { 588 | content: "\f048"; 589 | } 590 | .icon-fast-backward:before { 591 | content: "\f049"; 592 | } 593 | .icon-backward:before { 594 | content: "\f04a"; 595 | } 596 | .icon-play:before { 597 | content: "\f04b"; 598 | } 599 | .icon-pause:before { 600 | content: "\f04c"; 601 | } 602 | .icon-stop:before { 603 | content: "\f04d"; 604 | } 605 | .icon-forward:before { 606 | content: "\f04e"; 607 | } 608 | .icon-fast-forward:before { 609 | content: "\f050"; 610 | } 611 | .icon-step-forward:before { 612 | content: "\f051"; 613 | } 614 | .icon-eject:before { 615 | content: "\f052"; 616 | } 617 | .icon-chevron-left:before { 618 | content: "\f053"; 619 | } 620 | .icon-chevron-right:before { 621 | content: "\f054"; 622 | } 623 | .icon-plus-sign:before { 624 | content: "\f055"; 625 | } 626 | .icon-minus-sign:before { 627 | content: "\f056"; 628 | } 629 | .icon-remove-sign:before { 630 | content: "\f057"; 631 | } 632 | .icon-ok-sign:before { 633 | content: "\f058"; 634 | } 635 | .icon-question-sign:before { 636 | content: "\f059"; 637 | } 638 | .icon-info-sign:before { 639 | content: "\f05a"; 640 | } 641 | .icon-screenshot:before { 642 | content: "\f05b"; 643 | } 644 | .icon-remove-circle:before { 645 | content: "\f05c"; 646 | } 647 | .icon-ok-circle:before { 648 | content: "\f05d"; 649 | } 650 | .icon-ban-circle:before { 651 | content: "\f05e"; 652 | } 653 | .icon-arrow-left:before { 654 | content: "\f060"; 655 | } 656 | .icon-arrow-right:before { 657 | content: "\f061"; 658 | } 659 | .icon-arrow-up:before { 660 | content: "\f062"; 661 | } 662 | .icon-arrow-down:before { 663 | content: "\f063"; 664 | } 665 | .icon-mail-forward:before, 666 | .icon-share-alt:before { 667 | content: "\f064"; 668 | } 669 | .icon-resize-full:before { 670 | content: "\f065"; 671 | } 672 | .icon-resize-small:before { 673 | content: "\f066"; 674 | } 675 | .icon-plus:before { 676 | content: "\f067"; 677 | } 678 | .icon-minus:before { 679 | content: "\f068"; 680 | } 681 | .icon-asterisk:before { 682 | content: "\f069"; 683 | } 684 | .icon-exclamation-sign:before { 685 | content: "\f06a"; 686 | } 687 | .icon-gift:before { 688 | content: "\f06b"; 689 | } 690 | .icon-leaf:before { 691 | content: "\f06c"; 692 | } 693 | .icon-fire:before { 694 | content: "\f06d"; 695 | } 696 | .icon-eye-open:before { 697 | content: "\f06e"; 698 | } 699 | .icon-eye-close:before { 700 | content: "\f070"; 701 | } 702 | .icon-warning-sign:before { 703 | content: "\f071"; 704 | } 705 | .icon-plane:before { 706 | content: "\f072"; 707 | } 708 | .icon-calendar:before { 709 | content: "\f073"; 710 | } 711 | .icon-random:before { 712 | content: "\f074"; 713 | } 714 | .icon-comment:before { 715 | content: "\f075"; 716 | } 717 | .icon-magnet:before { 718 | content: "\f076"; 719 | } 720 | .icon-chevron-up:before { 721 | content: "\f077"; 722 | } 723 | .icon-chevron-down:before { 724 | content: "\f078"; 725 | } 726 | .icon-retweet:before { 727 | content: "\f079"; 728 | } 729 | .icon-shopping-cart:before { 730 | content: "\f07a"; 731 | } 732 | .icon-folder-close:before { 733 | content: "\f07b"; 734 | } 735 | .icon-folder-open:before { 736 | content: "\f07c"; 737 | } 738 | .icon-resize-vertical:before { 739 | content: "\f07d"; 740 | } 741 | .icon-resize-horizontal:before { 742 | content: "\f07e"; 743 | } 744 | .icon-bar-chart:before { 745 | content: "\f080"; 746 | } 747 | .icon-twitter-sign:before { 748 | content: "\f081"; 749 | } 750 | .icon-facebook-sign:before { 751 | content: "\f082"; 752 | } 753 | .icon-camera-retro:before { 754 | content: "\f083"; 755 | } 756 | .icon-key:before { 757 | content: "\f084"; 758 | } 759 | .icon-gears:before, 760 | .icon-cogs:before { 761 | content: "\f085"; 762 | } 763 | .icon-comments:before { 764 | content: "\f086"; 765 | } 766 | .icon-thumbs-up-alt:before { 767 | content: "\f087"; 768 | } 769 | .icon-thumbs-down-alt:before { 770 | content: "\f088"; 771 | } 772 | .icon-star-half:before { 773 | content: "\f089"; 774 | } 775 | .icon-heart-empty:before { 776 | content: "\f08a"; 777 | } 778 | .icon-signout:before { 779 | content: "\f08b"; 780 | } 781 | .icon-linkedin-sign:before { 782 | content: "\f08c"; 783 | } 784 | .icon-pushpin:before { 785 | content: "\f08d"; 786 | } 787 | .icon-external-link:before { 788 | content: "\f08e"; 789 | } 790 | .icon-signin:before { 791 | content: "\f090"; 792 | } 793 | .icon-trophy:before { 794 | content: "\f091"; 795 | } 796 | .icon-github-sign:before { 797 | content: "\f092"; 798 | } 799 | .icon-upload-alt:before { 800 | content: "\f093"; 801 | } 802 | .icon-lemon:before { 803 | content: "\f094"; 804 | } 805 | .icon-phone:before { 806 | content: "\f095"; 807 | } 808 | .icon-unchecked:before, 809 | .icon-check-empty:before { 810 | content: "\f096"; 811 | } 812 | .icon-bookmark-empty:before { 813 | content: "\f097"; 814 | } 815 | .icon-phone-sign:before { 816 | content: "\f098"; 817 | } 818 | .icon-twitter:before { 819 | content: "\f099"; 820 | } 821 | .icon-facebook:before { 822 | content: "\f09a"; 823 | } 824 | .icon-github:before { 825 | content: "\f09b"; 826 | } 827 | .icon-unlock:before { 828 | content: "\f09c"; 829 | } 830 | .icon-credit-card:before { 831 | content: "\f09d"; 832 | } 833 | .icon-rss:before { 834 | content: "\f09e"; 835 | } 836 | .icon-hdd:before { 837 | content: "\f0a0"; 838 | } 839 | .icon-bullhorn:before { 840 | content: "\f0a1"; 841 | } 842 | .icon-bell:before { 843 | content: "\f0a2"; 844 | } 845 | .icon-certificate:before { 846 | content: "\f0a3"; 847 | } 848 | .icon-hand-right:before { 849 | content: "\f0a4"; 850 | } 851 | .icon-hand-left:before { 852 | content: "\f0a5"; 853 | } 854 | .icon-hand-up:before { 855 | content: "\f0a6"; 856 | } 857 | .icon-hand-down:before { 858 | content: "\f0a7"; 859 | } 860 | .icon-circle-arrow-left:before { 861 | content: "\f0a8"; 862 | } 863 | .icon-circle-arrow-right:before { 864 | content: "\f0a9"; 865 | } 866 | .icon-circle-arrow-up:before { 867 | content: "\f0aa"; 868 | } 869 | .icon-circle-arrow-down:before { 870 | content: "\f0ab"; 871 | } 872 | .icon-globe:before { 873 | content: "\f0ac"; 874 | } 875 | .icon-wrench:before { 876 | content: "\f0ad"; 877 | } 878 | .icon-tasks:before { 879 | content: "\f0ae"; 880 | } 881 | .icon-filter:before { 882 | content: "\f0b0"; 883 | } 884 | .icon-briefcase:before { 885 | content: "\f0b1"; 886 | } 887 | .icon-fullscreen:before { 888 | content: "\f0b2"; 889 | } 890 | .icon-group:before { 891 | content: "\f0c0"; 892 | } 893 | .icon-link:before { 894 | content: "\f0c1"; 895 | } 896 | .icon-cloud:before { 897 | content: "\f0c2"; 898 | } 899 | .icon-beaker:before { 900 | content: "\f0c3"; 901 | } 902 | .icon-cut:before { 903 | content: "\f0c4"; 904 | } 905 | .icon-copy:before { 906 | content: "\f0c5"; 907 | } 908 | .icon-paperclip:before, 909 | .icon-paper-clip:before { 910 | content: "\f0c6"; 911 | } 912 | .icon-save:before { 913 | content: "\f0c7"; 914 | } 915 | .icon-sign-blank:before { 916 | content: "\f0c8"; 917 | } 918 | .icon-reorder:before { 919 | content: "\f0c9"; 920 | } 921 | .icon-list-ul:before { 922 | content: "\f0ca"; 923 | } 924 | .icon-list-ol:before { 925 | content: "\f0cb"; 926 | } 927 | .icon-strikethrough:before { 928 | content: "\f0cc"; 929 | } 930 | .icon-underline:before { 931 | content: "\f0cd"; 932 | } 933 | .icon-table:before { 934 | content: "\f0ce"; 935 | } 936 | .icon-magic:before { 937 | content: "\f0d0"; 938 | } 939 | .icon-truck:before { 940 | content: "\f0d1"; 941 | } 942 | .icon-pinterest:before { 943 | content: "\f0d2"; 944 | } 945 | .icon-pinterest-sign:before { 946 | content: "\f0d3"; 947 | } 948 | .icon-google-plus-sign:before { 949 | content: "\f0d4"; 950 | } 951 | .icon-google-plus:before { 952 | content: "\f0d5"; 953 | } 954 | .icon-money:before { 955 | content: "\f0d6"; 956 | } 957 | .icon-caret-down:before { 958 | content: "\f0d7"; 959 | } 960 | .icon-caret-up:before { 961 | content: "\f0d8"; 962 | } 963 | .icon-caret-left:before { 964 | content: "\f0d9"; 965 | } 966 | .icon-caret-right:before { 967 | content: "\f0da"; 968 | } 969 | .icon-columns:before { 970 | content: "\f0db"; 971 | } 972 | .icon-sort:before { 973 | content: "\f0dc"; 974 | } 975 | .icon-sort-down:before { 976 | content: "\f0dd"; 977 | } 978 | .icon-sort-up:before { 979 | content: "\f0de"; 980 | } 981 | .icon-envelope:before { 982 | content: "\f0e0"; 983 | } 984 | .icon-linkedin:before { 985 | content: "\f0e1"; 986 | } 987 | .icon-rotate-left:before, 988 | .icon-undo:before { 989 | content: "\f0e2"; 990 | } 991 | .icon-legal:before { 992 | content: "\f0e3"; 993 | } 994 | .icon-dashboard:before { 995 | content: "\f0e4"; 996 | } 997 | .icon-comment-alt:before { 998 | content: "\f0e5"; 999 | } 1000 | .icon-comments-alt:before { 1001 | content: "\f0e6"; 1002 | } 1003 | .icon-bolt:before { 1004 | content: "\f0e7"; 1005 | } 1006 | .icon-sitemap:before { 1007 | content: "\f0e8"; 1008 | } 1009 | .icon-umbrella:before { 1010 | content: "\f0e9"; 1011 | } 1012 | .icon-paste:before { 1013 | content: "\f0ea"; 1014 | } 1015 | .icon-lightbulb:before { 1016 | content: "\f0eb"; 1017 | } 1018 | .icon-exchange:before { 1019 | content: "\f0ec"; 1020 | } 1021 | .icon-cloud-download:before { 1022 | content: "\f0ed"; 1023 | } 1024 | .icon-cloud-upload:before { 1025 | content: "\f0ee"; 1026 | } 1027 | .icon-user-md:before { 1028 | content: "\f0f0"; 1029 | } 1030 | .icon-stethoscope:before { 1031 | content: "\f0f1"; 1032 | } 1033 | .icon-suitcase:before { 1034 | content: "\f0f2"; 1035 | } 1036 | .icon-bell-alt:before { 1037 | content: "\f0f3"; 1038 | } 1039 | .icon-coffee:before { 1040 | content: "\f0f4"; 1041 | } 1042 | .icon-food:before { 1043 | content: "\f0f5"; 1044 | } 1045 | .icon-file-text-alt:before { 1046 | content: "\f0f6"; 1047 | } 1048 | .icon-building:before { 1049 | content: "\f0f7"; 1050 | } 1051 | .icon-hospital:before { 1052 | content: "\f0f8"; 1053 | } 1054 | .icon-ambulance:before { 1055 | content: "\f0f9"; 1056 | } 1057 | .icon-medkit:before { 1058 | content: "\f0fa"; 1059 | } 1060 | .icon-fighter-jet:before { 1061 | content: "\f0fb"; 1062 | } 1063 | .icon-beer:before { 1064 | content: "\f0fc"; 1065 | } 1066 | .icon-h-sign:before { 1067 | content: "\f0fd"; 1068 | } 1069 | .icon-plus-sign-alt:before { 1070 | content: "\f0fe"; 1071 | } 1072 | .icon-double-angle-left:before { 1073 | content: "\f100"; 1074 | } 1075 | .icon-double-angle-right:before { 1076 | content: "\f101"; 1077 | } 1078 | .icon-double-angle-up:before { 1079 | content: "\f102"; 1080 | } 1081 | .icon-double-angle-down:before { 1082 | content: "\f103"; 1083 | } 1084 | .icon-angle-left:before { 1085 | content: "\f104"; 1086 | } 1087 | .icon-angle-right:before { 1088 | content: "\f105"; 1089 | } 1090 | .icon-angle-up:before { 1091 | content: "\f106"; 1092 | } 1093 | .icon-angle-down:before { 1094 | content: "\f107"; 1095 | } 1096 | .icon-desktop:before { 1097 | content: "\f108"; 1098 | } 1099 | .icon-laptop:before { 1100 | content: "\f109"; 1101 | } 1102 | .icon-tablet:before { 1103 | content: "\f10a"; 1104 | } 1105 | .icon-mobile-phone:before { 1106 | content: "\f10b"; 1107 | } 1108 | .icon-circle-blank:before { 1109 | content: "\f10c"; 1110 | } 1111 | .icon-quote-left:before { 1112 | content: "\f10d"; 1113 | } 1114 | .icon-quote-right:before { 1115 | content: "\f10e"; 1116 | } 1117 | .icon-spinner:before { 1118 | content: "\f110"; 1119 | } 1120 | .icon-circle:before { 1121 | content: "\f111"; 1122 | } 1123 | .icon-mail-reply:before, 1124 | .icon-reply:before { 1125 | content: "\f112"; 1126 | } 1127 | .icon-github-alt:before { 1128 | content: "\f113"; 1129 | } 1130 | .icon-folder-close-alt:before { 1131 | content: "\f114"; 1132 | } 1133 | .icon-folder-open-alt:before { 1134 | content: "\f115"; 1135 | } 1136 | .icon-expand-alt:before { 1137 | content: "\f116"; 1138 | } 1139 | .icon-collapse-alt:before { 1140 | content: "\f117"; 1141 | } 1142 | .icon-smile:before { 1143 | content: "\f118"; 1144 | } 1145 | .icon-frown:before { 1146 | content: "\f119"; 1147 | } 1148 | .icon-meh:before { 1149 | content: "\f11a"; 1150 | } 1151 | .icon-gamepad:before { 1152 | content: "\f11b"; 1153 | } 1154 | .icon-keyboard:before { 1155 | content: "\f11c"; 1156 | } 1157 | .icon-flag-alt:before { 1158 | content: "\f11d"; 1159 | } 1160 | .icon-flag-checkered:before { 1161 | content: "\f11e"; 1162 | } 1163 | .icon-terminal:before { 1164 | content: "\f120"; 1165 | } 1166 | .icon-code:before { 1167 | content: "\f121"; 1168 | } 1169 | .icon-reply-all:before { 1170 | content: "\f122"; 1171 | } 1172 | .icon-mail-reply-all:before { 1173 | content: "\f122"; 1174 | } 1175 | .icon-star-half-full:before, 1176 | .icon-star-half-empty:before { 1177 | content: "\f123"; 1178 | } 1179 | .icon-location-arrow:before { 1180 | content: "\f124"; 1181 | } 1182 | .icon-crop:before { 1183 | content: "\f125"; 1184 | } 1185 | .icon-code-fork:before { 1186 | content: "\f126"; 1187 | } 1188 | .icon-unlink:before { 1189 | content: "\f127"; 1190 | } 1191 | .icon-question:before { 1192 | content: "\f128"; 1193 | } 1194 | .icon-info:before { 1195 | content: "\f129"; 1196 | } 1197 | .icon-exclamation:before { 1198 | content: "\f12a"; 1199 | } 1200 | .icon-superscript:before { 1201 | content: "\f12b"; 1202 | } 1203 | .icon-subscript:before { 1204 | content: "\f12c"; 1205 | } 1206 | .icon-eraser:before { 1207 | content: "\f12d"; 1208 | } 1209 | .icon-puzzle-piece:before { 1210 | content: "\f12e"; 1211 | } 1212 | .icon-microphone:before { 1213 | content: "\f130"; 1214 | } 1215 | .icon-microphone-off:before { 1216 | content: "\f131"; 1217 | } 1218 | .icon-shield:before { 1219 | content: "\f132"; 1220 | } 1221 | .icon-calendar-empty:before { 1222 | content: "\f133"; 1223 | } 1224 | .icon-fire-extinguisher:before { 1225 | content: "\f134"; 1226 | } 1227 | .icon-rocket:before { 1228 | content: "\f135"; 1229 | } 1230 | .icon-maxcdn:before { 1231 | content: "\f136"; 1232 | } 1233 | .icon-chevron-sign-left:before { 1234 | content: "\f137"; 1235 | } 1236 | .icon-chevron-sign-right:before { 1237 | content: "\f138"; 1238 | } 1239 | .icon-chevron-sign-up:before { 1240 | content: "\f139"; 1241 | } 1242 | .icon-chevron-sign-down:before { 1243 | content: "\f13a"; 1244 | } 1245 | .icon-html5:before { 1246 | content: "\f13b"; 1247 | } 1248 | .icon-css3:before { 1249 | content: "\f13c"; 1250 | } 1251 | .icon-anchor:before { 1252 | content: "\f13d"; 1253 | } 1254 | .icon-unlock-alt:before { 1255 | content: "\f13e"; 1256 | } 1257 | .icon-bullseye:before { 1258 | content: "\f140"; 1259 | } 1260 | .icon-ellipsis-horizontal:before { 1261 | content: "\f141"; 1262 | } 1263 | .icon-ellipsis-vertical:before { 1264 | content: "\f142"; 1265 | } 1266 | .icon-rss-sign:before { 1267 | content: "\f143"; 1268 | } 1269 | .icon-play-sign:before { 1270 | content: "\f144"; 1271 | } 1272 | .icon-ticket:before { 1273 | content: "\f145"; 1274 | } 1275 | .icon-minus-sign-alt:before { 1276 | content: "\f146"; 1277 | } 1278 | .icon-check-minus:before { 1279 | content: "\f147"; 1280 | } 1281 | .icon-level-up:before { 1282 | content: "\f148"; 1283 | } 1284 | .icon-level-down:before { 1285 | content: "\f149"; 1286 | } 1287 | .icon-check-sign:before { 1288 | content: "\f14a"; 1289 | } 1290 | .icon-edit-sign:before { 1291 | content: "\f14b"; 1292 | } 1293 | .icon-external-link-sign:before { 1294 | content: "\f14c"; 1295 | } 1296 | .icon-share-sign:before { 1297 | content: "\f14d"; 1298 | } 1299 | .icon-compass:before { 1300 | content: "\f14e"; 1301 | } 1302 | .icon-collapse:before { 1303 | content: "\f150"; 1304 | } 1305 | .icon-collapse-top:before { 1306 | content: "\f151"; 1307 | } 1308 | .icon-expand:before { 1309 | content: "\f152"; 1310 | } 1311 | .icon-euro:before, 1312 | .icon-eur:before { 1313 | content: "\f153"; 1314 | } 1315 | .icon-gbp:before { 1316 | content: "\f154"; 1317 | } 1318 | .icon-dollar:before, 1319 | .icon-usd:before { 1320 | content: "\f155"; 1321 | } 1322 | .icon-rupee:before, 1323 | .icon-inr:before { 1324 | content: "\f156"; 1325 | } 1326 | .icon-yen:before, 1327 | .icon-jpy:before { 1328 | content: "\f157"; 1329 | } 1330 | .icon-renminbi:before, 1331 | .icon-cny:before { 1332 | content: "\f158"; 1333 | } 1334 | .icon-won:before, 1335 | .icon-krw:before { 1336 | content: "\f159"; 1337 | } 1338 | .icon-bitcoin:before, 1339 | .icon-btc:before { 1340 | content: "\f15a"; 1341 | } 1342 | .icon-file:before { 1343 | content: "\f15b"; 1344 | } 1345 | .icon-file-text:before { 1346 | content: "\f15c"; 1347 | } 1348 | .icon-sort-by-alphabet:before { 1349 | content: "\f15d"; 1350 | } 1351 | .icon-sort-by-alphabet-alt:before { 1352 | content: "\f15e"; 1353 | } 1354 | .icon-sort-by-attributes:before { 1355 | content: "\f160"; 1356 | } 1357 | .icon-sort-by-attributes-alt:before { 1358 | content: "\f161"; 1359 | } 1360 | .icon-sort-by-order:before { 1361 | content: "\f162"; 1362 | } 1363 | .icon-sort-by-order-alt:before { 1364 | content: "\f163"; 1365 | } 1366 | .icon-thumbs-up:before { 1367 | content: "\f164"; 1368 | } 1369 | .icon-thumbs-down:before { 1370 | content: "\f165"; 1371 | } 1372 | .icon-youtube-sign:before { 1373 | content: "\f166"; 1374 | } 1375 | .icon-youtube:before { 1376 | content: "\f167"; 1377 | } 1378 | .icon-xing:before { 1379 | content: "\f168"; 1380 | } 1381 | .icon-xing-sign:before { 1382 | content: "\f169"; 1383 | } 1384 | .icon-youtube-play:before { 1385 | content: "\f16a"; 1386 | } 1387 | .icon-dropbox:before { 1388 | content: "\f16b"; 1389 | } 1390 | .icon-stackexchange:before { 1391 | content: "\f16c"; 1392 | } 1393 | .icon-instagram:before { 1394 | content: "\f16d"; 1395 | } 1396 | .icon-flickr:before { 1397 | content: "\f16e"; 1398 | } 1399 | .icon-adn:before { 1400 | content: "\f170"; 1401 | } 1402 | .icon-bitbucket:before { 1403 | content: "\f171"; 1404 | } 1405 | .icon-bitbucket-sign:before { 1406 | content: "\f172"; 1407 | } 1408 | .icon-tumblr:before { 1409 | content: "\f173"; 1410 | } 1411 | .icon-tumblr-sign:before { 1412 | content: "\f174"; 1413 | } 1414 | .icon-long-arrow-down:before { 1415 | content: "\f175"; 1416 | } 1417 | .icon-long-arrow-up:before { 1418 | content: "\f176"; 1419 | } 1420 | .icon-long-arrow-left:before { 1421 | content: "\f177"; 1422 | } 1423 | .icon-long-arrow-right:before { 1424 | content: "\f178"; 1425 | } 1426 | .icon-apple:before { 1427 | content: "\f179"; 1428 | } 1429 | .icon-windows:before { 1430 | content: "\f17a"; 1431 | } 1432 | .icon-android:before { 1433 | content: "\f17b"; 1434 | } 1435 | .icon-linux:before { 1436 | content: "\f17c"; 1437 | } 1438 | .icon-dribbble:before { 1439 | content: "\f17d"; 1440 | } 1441 | .icon-skype:before { 1442 | content: "\f17e"; 1443 | } 1444 | .icon-foursquare:before { 1445 | content: "\f180"; 1446 | } 1447 | .icon-trello:before { 1448 | content: "\f181"; 1449 | } 1450 | .icon-female:before { 1451 | content: "\f182"; 1452 | } 1453 | .icon-male:before { 1454 | content: "\f183"; 1455 | } 1456 | .icon-gittip:before { 1457 | content: "\f184"; 1458 | } 1459 | .icon-sun:before { 1460 | content: "\f185"; 1461 | } 1462 | .icon-moon:before { 1463 | content: "\f186"; 1464 | } 1465 | .icon-archive:before { 1466 | content: "\f187"; 1467 | } 1468 | .icon-bug:before { 1469 | content: "\f188"; 1470 | } 1471 | .icon-vk:before { 1472 | content: "\f189"; 1473 | } 1474 | .icon-weibo:before { 1475 | content: "\f18a"; 1476 | } 1477 | .icon-renren:before { 1478 | content: "\f18b"; 1479 | } 1480 | -------------------------------------------------------------------------------- /assets/stylesheets/jquery.gridster.css: -------------------------------------------------------------------------------- 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 | }*/ -------------------------------------------------------------------------------- /config.ru: -------------------------------------------------------------------------------- 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 -------------------------------------------------------------------------------- /dashboards/layout.erb: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | <%= yield_content(:title) %> 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 |
21 | <%= yield %> 22 |
23 | 24 | <% if development? %> 25 |
26 |

Paste the following at the top of <%= params[:dashboard] %>.erb

27 | 28 |
29 | Save this layout 30 | <% end %> 31 | 32 | -------------------------------------------------------------------------------- /dashboards/sample.erb: -------------------------------------------------------------------------------- 1 | <% content_for :title do %>IOT Dashboard<% end %> 2 |
3 |
    4 |
  • 5 |
    6 |
  • 7 | 8 |
  • 9 |
    10 |
  • 11 | 16 |
  • 17 |
    18 |
  • 19 | 20 |
  • 21 |
    22 |
  • 23 |
24 |
Try this: curl -d '{ "auth_token": "YOUR_AUTH_TOKEN", "text": "Hey, Look what I can do!" }' \http://<%=request.host%>:<%=request.port%>/widgets/welcome
25 |
26 | -------------------------------------------------------------------------------- /dashboards/sampletv.erb: -------------------------------------------------------------------------------- 1 | 9 | 10 | 11 | <% content_for :title do %>1080p dashboard<% end %> 12 | 13 |
14 |
    15 |
  • 16 |
    17 | 18 |
  • 19 | 20 |
  • 21 |
    22 |
  • 23 | 24 |
  • 25 |
    26 |
  • 27 | 28 |
  • 29 |
    30 |
  • 31 | 32 |
  • 33 |
    34 |
  • 35 | 36 |
  • 37 |
    38 |
  • 39 | 40 |
  • 41 |
    42 | 43 |
  • 44 | 45 |
  • 46 |
    47 |
  • 48 | 49 |
  • 50 |
    51 | 52 |
  • 53 | 54 |
55 |
Try this: curl -d '{ "auth_token": "YOUR_AUTH_TOKEN", "text": "Hey, Look what I can do!" }' \http://<%=request.host%>:<%=request.port%>/widgets/welcome
56 |
-------------------------------------------------------------------------------- /doc/nginx.conf: -------------------------------------------------------------------------------- 1 | # sudo ln -s ~/nginx.conf unicorn.conf 2 | upstream app_server { 3 | server unix:/tmp/unicorn_padrino.sock fail_timeout=0; 4 | } 5 | 6 | server { 7 | listen 80; 8 | charset utf-8; 9 | server_name db.innshine.com; 10 | 11 | keepalive_timeout 5; 12 | 13 | root /home/innshine/one/public; 14 | access_log /home/innshine/one/log/nginx_access.log; 15 | error_log /home/innshine/one/log/nginx_error.log; 16 | rewrite_log on; 17 | 18 | location ~* ^/(images|javascripts|stylesheets|img)/ { 19 | access_log off; 20 | log_not_found off; 21 | expires max; 22 | break; 23 | } 24 | 25 | location / { 26 | proxy_set_header Host $host; 27 | proxy_set_header X-Forwarded-Host $host; 28 | proxy_set_header X-Forwarded-Server $host; 29 | proxy_set_header X-Real-IP $remote_addr; 30 | proxy_set_header X-Forward-For $proxy_add_x_forwarded_for; 31 | proxy_buffering on; 32 | proxy_redirect off; 33 | 34 | if (!-f $request_filename) { 35 | proxy_pass http://app_server; 36 | break; 37 | } 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /doc/one.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # rvm wrapper ruby-1.9.3-p194 bootup 3 | UNICORN=/home/innshine/.rvm/bin/bootup_unicorn 4 | CONFIG_FILE=/home/innshine/one/config/unicorn.rb 5 | APP_HOME=/home/innshine/one 6 | 7 | case "$1" in 8 | start) 9 | $UNICORN -c $CONFIG_FILE -E production -D 10 | ;; 11 | stop) 12 | kill -QUIT `cat /tmp/unicorn_padrino.pid` 13 | ;; 14 | restart|force-reload) 15 | kill -USR2 `cat /tmp/unicorn_padrino.pid` 16 | ;; 17 | *) 18 | echo "Usage: $SCRIPTNAME {start|stop|restart|force-reload}" >&2 19 | exit 3 20 | ;; 21 | esac 22 | 23 | : 24 | -------------------------------------------------------------------------------- /doc/screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iot-works/iot-dashboard/da9574ed6dd8143d987c5f1aa6204fdb6c5c4c9b/doc/screenshot.png -------------------------------------------------------------------------------- /doc/unicorn.rb: -------------------------------------------------------------------------------- 1 | # -*- encoding: utf-8 -*- 2 | 3 | root_path = File.expand_path '../', File.dirname(__FILE__) 4 | # 日志 5 | log_file = root_path + '/log/unicorn.log' 6 | err_log = root_path + '/log/unicorn_error.log' 7 | # 进程标识 8 | pid_file = '/tmp/unicorn_padrino.pid' 9 | old_pid = pid_file + '.oldbin' 10 | # 通道 11 | socket_file = '/tmp/unicorn_padrino.sock' 12 | 13 | worker_processes 6 14 | working_directory root_path 15 | timeout 30 16 | # 侦听 17 | listen 8080, tcp_nopush: false 18 | listen socket_file, backlog: 1024 19 | 20 | pid pid_file 21 | stderr_path err_log 22 | stdout_path log_file 23 | 24 | preload_app true 25 | 26 | before_exec do |server| 27 | ENV['BUNDLE_GEMFILE'] = root_path + '/Gemfile' 28 | end 29 | 30 | before_fork do |server, worker| 31 | if File.exists?(old_pid) && server.pid != old_pid 32 | begin 33 | Process.kill('QUIT', File.read(old_pid).to_i) 34 | rescue Errno::ENOENT, Errno::ESRCH 35 | puts "Send 'QUIT' signal to unicorn error!" 36 | end 37 | end 38 | end 39 | -------------------------------------------------------------------------------- /jobs/buzzwords.rb: -------------------------------------------------------------------------------- 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) % 30 } 7 | 8 | send_event('buzzwords', { items: buzzword_counts.values }) 9 | end -------------------------------------------------------------------------------- /jobs/convergence.rb: -------------------------------------------------------------------------------- 1 | # Populate the graph with some random points 2 | 3 | require "rubygems" 4 | require "json" 5 | require "net/http" 6 | require "uri" 7 | 8 | def get_data 9 | uri = URI.parse("http://b.phodal.com/athome") 10 | 11 | http = Net::HTTP.new(uri.host,uri.port) 12 | request = Net::HTTP::Get.new(uri.request_uri) 13 | 14 | response=http.request(request) 15 | result=JSON.parse(response.body) 16 | 17 | result.map do |data| 18 | {x: data["id"].to_i, y: data["temperature"].to_i} 19 | end 20 | end 21 | 22 | points=get_data 23 | 24 | SCHEDULER.every '2s' do 25 | send_event('tempdata', points: points) 26 | end 27 | -------------------------------------------------------------------------------- /jobs/sample.rb: -------------------------------------------------------------------------------- 1 | require "rubygems" 2 | require "json" 3 | require "net/http" 4 | require "uri" 5 | 6 | def get_data(num) 7 | uri = URI.parse("http://b.phodal.com/athome/"+num.to_s) 8 | 9 | http = Net::HTTP.new(uri.host, uri.port) 10 | request = Net::HTTP::Get.new(uri.request_uri) 11 | 12 | response = http.request(request) 13 | 14 | result=JSON.parse(response.body) 15 | result 16 | end 17 | 18 | current_valuation = 0 19 | current_karma = 0 20 | 21 | SCHEDULER.every '2s' do 22 | last_valuation = current_valuation 23 | current_valuation = rand(100) 24 | current_temperature = get_data(2)[0]["temperature"].to_i 25 | last_temperature = get_data(1)[0]["temperature"].to_i 26 | 27 | sensors1 = get_data(2)[0]["sensors1"].to_i 28 | send_event('karma', { current: current_valuation, last: last_valuation }) 29 | send_event('temperature', { current: current_temperature, last: last_temperature }) 30 | send_event('sensors1', { value: sensors1}) 31 | end 32 | -------------------------------------------------------------------------------- /public/404.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | This Dashboard doesn't exist. 5 | 17 | 18 | 19 | 20 | 21 |
22 |

Drats! That Dashboard doesn't exist.

23 |

You may have mistyped the address or the page may have moved.

24 |
25 | 26 | -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iot-works/iot-dashboard/da9574ed6dd8143d987c5f1aa6204fdb6c5c4c9b/public/favicon.ico -------------------------------------------------------------------------------- /widgets/clock/clock.coffee: -------------------------------------------------------------------------------- 1 | class Dashing.Clock extends Dashing.Widget 2 | 3 | ready: -> 4 | setInterval(@startTime, 500) 5 | 6 | startTime: => 7 | today = new Date() 8 | 9 | h = today.getHours() 10 | m = today.getMinutes() 11 | s = today.getSeconds() 12 | m = @formatTime(m) 13 | s = @formatTime(s) 14 | @set('time', h + ":" + m + ":" + s) 15 | @set('date', today.toDateString()) 16 | 17 | formatTime: (i) -> 18 | if i < 10 then "0" + i else i -------------------------------------------------------------------------------- /widgets/clock/clock.html: -------------------------------------------------------------------------------- 1 |

2 |

-------------------------------------------------------------------------------- /widgets/clock/clock.scss: -------------------------------------------------------------------------------- 1 | // ---------------------------------------------------------------------------- 2 | // Sass declarations 3 | // ---------------------------------------------------------------------------- 4 | $background-color: #dc5945; 5 | 6 | // ---------------------------------------------------------------------------- 7 | // Widget-clock styles 8 | // ---------------------------------------------------------------------------- 9 | .widget-clock { 10 | 11 | background-color: $background-color; 12 | 13 | } 14 | -------------------------------------------------------------------------------- /widgets/comments/comments.coffee: -------------------------------------------------------------------------------- 1 | class Dashing.Comments extends Dashing.Widget 2 | 3 | @accessor 'quote', -> 4 | "“#{@get('current_comment')?.body}”" 5 | 6 | ready: -> 7 | @currentIndex = 0 8 | @commentElem = $(@node).find('.comment-container') 9 | @nextComment() 10 | @startCarousel() 11 | 12 | onData: (data) -> 13 | @currentIndex = 0 14 | 15 | startCarousel: -> 16 | setInterval(@nextComment, 8000) 17 | 18 | nextComment: => 19 | comments = @get('comments') 20 | if comments 21 | @commentElem.fadeOut => 22 | @currentIndex = (@currentIndex + 1) % comments.length 23 | @set 'current_comment', comments[@currentIndex] 24 | @commentElem.fadeIn() 25 | -------------------------------------------------------------------------------- /widgets/comments/comments.html: -------------------------------------------------------------------------------- 1 |

2 |
3 |

4 |

5 |
6 | 7 |

8 | -------------------------------------------------------------------------------- /widgets/comments/comments.scss: -------------------------------------------------------------------------------- 1 | // ---------------------------------------------------------------------------- 2 | // Sass declarations 3 | // ---------------------------------------------------------------------------- 4 | $background-color: #eb9c3c; 5 | 6 | $title-color: rgba(255, 255, 255, 0.7); 7 | $moreinfo-color: rgba(255, 255, 255, 0.7); 8 | 9 | // ---------------------------------------------------------------------------- 10 | // Widget-comment styles 11 | // ---------------------------------------------------------------------------- 12 | .widget-comments { 13 | 14 | background-color: $background-color; 15 | 16 | .title { 17 | color: $title-color; 18 | margin-bottom: 15px; 19 | } 20 | 21 | .name { 22 | padding-left: 5px; 23 | } 24 | 25 | .comment-container { 26 | display: none; 27 | } 28 | 29 | .more-info { 30 | color: $moreinfo-color; 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /widgets/graph/graph.coffee: -------------------------------------------------------------------------------- 1 | class Dashing.Graph extends Dashing.Widget 2 | 3 | @accessor 'current', -> 4 | return @get('displayedValue') if @get('displayedValue') 5 | points = @get('points') 6 | if points 7 | points[points.length - 1].y 8 | 9 | ready: -> 10 | container = $(@node).parent() 11 | # Gross hacks. Let's fix this. 12 | width = (Dashing.widget_base_dimensions[0] * container.data("sizex")) + Dashing.widget_margins[0] * 2 * (container.data("sizex") - 1) 13 | height = (Dashing.widget_base_dimensions[1] * container.data("sizey")) 14 | @graph = new Rickshaw.Graph( 15 | element: @node 16 | width: width 17 | height: height 18 | renderer: @get("graphtype") 19 | series: [ 20 | { 21 | color: "#fff", 22 | data: [{x:0, y:0}] 23 | } 24 | ] 25 | ) 26 | 27 | @graph.series[0].data = @get('points') if @get('points') 28 | 29 | x_axis = new Rickshaw.Graph.Axis.Time(graph: @graph) 30 | y_axis = new Rickshaw.Graph.Axis.Y(graph: @graph, tickFormat: Rickshaw.Fixtures.Number.formatKMBT) 31 | @graph.render() 32 | 33 | onData: (data) -> 34 | if @graph 35 | @graph.series[0].data = data.points 36 | @graph.render() 37 | -------------------------------------------------------------------------------- /widgets/graph/graph.html: -------------------------------------------------------------------------------- 1 |

2 | 3 |

4 | 5 |

6 | -------------------------------------------------------------------------------- /widgets/graph/graph.scss: -------------------------------------------------------------------------------- 1 | // ---------------------------------------------------------------------------- 2 | // Sass declarations 3 | // ---------------------------------------------------------------------------- 4 | $background-color: #dc5945; 5 | 6 | $title-color: rgba(255, 255, 255, 0.7); 7 | $moreinfo-color: rgba(255, 255, 255, 0.3); 8 | $tick-color: rgba(0, 0, 0, 0.4); 9 | 10 | 11 | // ---------------------------------------------------------------------------- 12 | // Widget-graph styles 13 | // ---------------------------------------------------------------------------- 14 | .widget-graph { 15 | 16 | background-color: $background-color; 17 | position: relative; 18 | 19 | 20 | svg { 21 | position: absolute; 22 | opacity: 0.4; 23 | fill-opacity: 0.4; 24 | left: 0px; 25 | top: 0px; 26 | } 27 | 28 | .title, .value { 29 | position: relative; 30 | z-index: 99; 31 | } 32 | 33 | .title { 34 | color: $title-color; 35 | } 36 | 37 | .more-info { 38 | color: $moreinfo-color; 39 | font-weight: 600; 40 | font-size: 20px; 41 | margin-top: 0; 42 | } 43 | 44 | .x_tick { 45 | position: absolute; 46 | bottom: 0; 47 | .title { 48 | font-size: 20px; 49 | color: $tick-color; 50 | opacity: 0.5; 51 | padding-bottom: 3px; 52 | } 53 | } 54 | 55 | .y_ticks { 56 | font-size: 20px; 57 | fill: $tick-color; 58 | fill-opacity: 1; 59 | } 60 | 61 | .domain { 62 | display: none; 63 | } 64 | 65 | } 66 | -------------------------------------------------------------------------------- /widgets/iframe/iframe.coffee: -------------------------------------------------------------------------------- 1 | class Dashing.Iframe extends Dashing.Widget 2 | 3 | ready: -> 4 | # This is fired when the widget is done being rendered 5 | 6 | onData: (data) -> 7 | # Handle incoming data 8 | # You can access the html node of this widget with `@node` 9 | # Example: $(@node).fadeOut().fadeIn() will make the node flash each time data comes in. 10 | -------------------------------------------------------------------------------- /widgets/iframe/iframe.html: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /widgets/iframe/iframe.scss: -------------------------------------------------------------------------------- 1 | .widget-iframe { 2 | padding: 3px 0px 0px 0px !important; 3 | 4 | iframe { 5 | width: 100%; 6 | height: 100%; 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /widgets/image/image.coffee: -------------------------------------------------------------------------------- 1 | class Dashing.Image extends Dashing.Widget 2 | 3 | ready: -> 4 | # This is fired when the widget is done being rendered 5 | 6 | onData: (data) -> 7 | # Handle incoming data 8 | # You can access the html node of this widget with `@node` 9 | # Example: $(@node).fadeOut().fadeIn() will make the node flash each time data comes in. 10 | -------------------------------------------------------------------------------- /widgets/image/image.html: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /widgets/image/image.scss: -------------------------------------------------------------------------------- 1 | // ---------------------------------------------------------------------------- 2 | // Sass declarations 3 | // ---------------------------------------------------------------------------- 4 | $background-color: #4b4b4b; 5 | 6 | // ---------------------------------------------------------------------------- 7 | // Widget-image styles 8 | // ---------------------------------------------------------------------------- 9 | .widget-image { 10 | 11 | background-color: $background-color; 12 | 13 | } 14 | -------------------------------------------------------------------------------- /widgets/list/list.coffee: -------------------------------------------------------------------------------- 1 | class Dashing.List extends Dashing.Widget 2 | ready: -> 3 | if @get('unordered') 4 | $(@node).find('ol').remove() 5 | else 6 | $(@node).find('ul').remove() 7 | -------------------------------------------------------------------------------- /widgets/list/list.html: -------------------------------------------------------------------------------- 1 |

2 | 3 |
    4 |
  1. 5 | 6 | 7 |
  2. 8 |
9 | 10 |
    11 |
  • 12 | 13 | 14 |
  • 15 |
16 | 17 |

18 |

19 | -------------------------------------------------------------------------------- /widgets/list/list.scss: -------------------------------------------------------------------------------- 1 | // ---------------------------------------------------------------------------- 2 | // Sass declarations 3 | // ---------------------------------------------------------------------------- 4 | $background-color: #12b0c5; 5 | $value-color: #fff; 6 | 7 | $title-color: rgba(255, 255, 255, 0.7); 8 | $label-color: rgba(255, 255, 255, 0.7); 9 | $moreinfo-color: rgba(255, 255, 255, 0.7); 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 | .updated-at { 53 | color: rgba(0, 0, 0, 0.3); 54 | } 55 | 56 | .more-info { 57 | color: $moreinfo-color; 58 | } 59 | 60 | } 61 | -------------------------------------------------------------------------------- /widgets/meter/meter.coffee: -------------------------------------------------------------------------------- 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() 15 | -------------------------------------------------------------------------------- /widgets/meter/meter.html: -------------------------------------------------------------------------------- 1 |

2 | 3 | 4 | 5 |

6 | 7 |

8 | -------------------------------------------------------------------------------- /widgets/meter/meter.scss: -------------------------------------------------------------------------------- 1 | // ---------------------------------------------------------------------------- 2 | // Sass declarations 3 | // ---------------------------------------------------------------------------- 4 | $background-color: #9c4274; 5 | 6 | $title-color: rgba(255, 255, 255, 0.7); 7 | $moreinfo-color: rgba(255, 255, 255, 0.3); 8 | 9 | $meter-background: darken($background-color, 15%); 10 | 11 | // ---------------------------------------------------------------------------- 12 | // Widget-meter styles 13 | // ---------------------------------------------------------------------------- 14 | .widget-meter { 15 | 16 | background-color: $background-color; 17 | 18 | input.meter { 19 | background-color: $meter-background; 20 | color: #fff; 21 | } 22 | 23 | .title { 24 | color: $title-color; 25 | } 26 | 27 | .more-info { 28 | color: $moreinfo-color; 29 | } 30 | 31 | .updated-at { 32 | color: rgba(0, 0, 0, 0.3); 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /widgets/number/number.coffee: -------------------------------------------------------------------------------- 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 | else 12 | "" 13 | 14 | @accessor 'arrow', -> 15 | if @get('last') 16 | if parseInt(@get('current')) > parseInt(@get('last')) then 'icon-arrow-up' else 'icon-arrow-down' 17 | 18 | onData: (data) -> 19 | if data.status 20 | # clear existing "status-*" classes 21 | $(@get('node')).attr 'class', (i,c) -> 22 | c.replace /\bstatus-\S+/g, '' 23 | # add new class 24 | $(@get('node')).addClass "status-#{data.status}" 25 | -------------------------------------------------------------------------------- /widgets/number/number.html: -------------------------------------------------------------------------------- 1 |

2 | 3 |

4 | 5 |

6 | 7 |

8 | 9 |

10 | 11 |

12 | -------------------------------------------------------------------------------- /widgets/number/number.scss: -------------------------------------------------------------------------------- 1 | // ---------------------------------------------------------------------------- 2 | // Sass declarations 3 | // ---------------------------------------------------------------------------- 4 | $background-color: #47bbb3; 5 | $value-color: #fff; 6 | 7 | $title-color: rgba(255, 255, 255, 0.7); 8 | $moreinfo-color: rgba(255, 255, 255, 0.7); 9 | 10 | // ---------------------------------------------------------------------------- 11 | // Widget-number styles 12 | // ---------------------------------------------------------------------------- 13 | .widget-number { 14 | 15 | background-color: $background-color; 16 | 17 | .title { 18 | color: $title-color; 19 | } 20 | 21 | .value { 22 | color: $value-color; 23 | } 24 | 25 | .change-rate { 26 | font-weight: 500; 27 | font-size: 30px; 28 | color: $value-color; 29 | } 30 | 31 | .more-info { 32 | color: $moreinfo-color; 33 | } 34 | 35 | .updated-at { 36 | color: rgba(0, 0, 0, 0.3); 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /widgets/text/text.coffee: -------------------------------------------------------------------------------- 1 | class Dashing.Text extends Dashing.Widget 2 | -------------------------------------------------------------------------------- /widgets/text/text.html: -------------------------------------------------------------------------------- 1 |

2 | 3 |

4 | 5 |

6 | 7 |

8 | -------------------------------------------------------------------------------- /widgets/text/text.scss: -------------------------------------------------------------------------------- 1 | // ---------------------------------------------------------------------------- 2 | // Sass declarations 3 | // ---------------------------------------------------------------------------- 4 | $background-color: #ec663c; 5 | 6 | $title-color: rgba(255, 255, 255, 0.7); 7 | $moreinfo-color: rgba(255, 255, 255, 0.7); 8 | 9 | // ---------------------------------------------------------------------------- 10 | // Widget-text styles 11 | // ---------------------------------------------------------------------------- 12 | .widget-text { 13 | 14 | background-color: $background-color; 15 | 16 | .title { 17 | color: $title-color; 18 | } 19 | 20 | .more-info { 21 | color: $moreinfo-color; 22 | } 23 | 24 | .updated-at { 25 | color: rgba(255, 255, 255, 0.7); 26 | } 27 | 28 | 29 | &.large h3 { 30 | font-size: 65px; 31 | } 32 | } 33 | --------------------------------------------------------------------------------