├── .DS_Store
├── .bowerrc
├── .editorconfig
├── .gitignore
├── .jshintrc
├── .sass-cache
└── d092eda4ac72474b686870cd866fbade096fa91f
│ └── main.scssc
├── Async plotting.ipynb
├── Different series formats.ipynb
├── Javascript functions in options.ipynb
├── LICENSE.md
├── MANIFEST.in
├── Quickstart-nbv4.ipynb
├── README.md
├── README.rst
├── Tutorial.ipynb
├── app
├── chart.svg
├── favicon.ico
├── index.html
├── robots.txt
├── scripts
│ ├── app.js
│ └── ui
│ │ └── Timer.js
└── styles
│ └── main.scss
├── bower.json
├── chart.svg
├── charts
├── .DS_Store
├── __init__.py
├── app.css
├── async.js
├── chart.py
├── core.py
├── data.py
├── fonts
│ ├── Post-Creator-Icons.eot
│ ├── Post-Creator-Icons.svg
│ ├── Post-Creator-Icons.ttf
│ └── Post-Creator-Icons.woff
├── images
│ ├── gulp.png
│ └── jsoneditor-icons.png
├── index-async.html
├── index.html
├── jsonencoder.py
├── lib.js
├── page.js
├── plot.py
├── require.js
├── server.py
└── settings.py
├── gulpfile.js
├── index.html
├── log.txt
├── my-settings.json
├── package.json
├── preprocessor.js
├── scripts
├── app.js
└── require-config.js
├── settings.json
├── setup.cfg
├── setup.py
├── small
├── AAPL.json
├── MSFT.json
├── OHLC.json
├── index.html
└── keys.json
├── style.css
└── view
├── .gitignore
├── LICENSE.md
├── README.md
├── gulp
├── config.js
├── tasks
│ ├── browserSync.js
│ ├── browserify.js
│ ├── default.js
│ ├── iconFont
│ │ ├── generateIconSass.js
│ │ └── index.js
│ ├── images.js
│ ├── inline.js
│ ├── karma.js
│ ├── markup.js
│ ├── minifyCss.js
│ ├── production.js
│ ├── removedep.js
│ ├── replace.js
│ ├── sass.js
│ ├── test.js
│ ├── uglifyJs.js
│ ├── watch.js
│ └── watchify.js
└── util
│ ├── bundleLogger.js
│ └── handleErrors.js
├── gulpfile.js
├── karma.conf.js
├── package.json
└── src
├── htdocs
├── index-async.html
└── index.html
├── icons
├── uE001-facebook.svg
├── uE002-linkedin.svg
├── uE003-pinterest.svg
└── uE004-twitter.svg
├── images
├── gulp.png
└── jsoneditor-icons.png
├── javascript
├── __tests__
│ └── page-test.coffee
├── async.js
├── lib.js
├── page.js
├── require.js
└── vendor
│ └── jquery-plugin.js
└── sass
├── _icons.sass
├── _scss-mixins.scss
├── _typography.sass
├── app.sass
├── bootstrap
├── _bootstrap.custom.min.scss
├── bootstrap-theme.css
├── bootstrap-theme.css.map
├── bootstrap-theme.min.css
├── bootstrap.css
└── bootstrap.css.map
├── jsoneditor
└── _jsoneditor.min.scss
└── selectize
├── _selectize.bootstrap3.scss
├── _selectize.default.scss
├── selectize.bootstrap2.css
├── selectize.css
└── selectize.legacy.css
/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/arnoutaertgeerts/python-highcharts/6bd433cf53e851e9697639e88fcec453b7b63076/.DS_Store
--------------------------------------------------------------------------------
/.bowerrc:
--------------------------------------------------------------------------------
1 | {
2 | "directory": "app/bower_components"
3 | }
4 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | # http://editorconfig.org
2 | root = true
3 |
4 | [*]
5 | indent_style = space
6 | indent_size = 4
7 | end_of_line = lf
8 | charset = utf-8
9 | trim_trailing_whitespace = true
10 | insert_final_newline = true
11 |
12 | [*.md]
13 | trim_trailing_whitespace = false
14 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | ## Other
2 | temp.*
3 | temp*
4 | chart
5 |
6 | *.mat
7 | node_modules
8 | bower_components
9 |
10 | # Created by .ignore support plugin (hsz.mobi)
11 | ### JetBrains template
12 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm
13 |
14 | *.iml
15 |
16 | ## Directory-based project format:
17 | .idea/
18 | # if you remove the above rule, at least ignore the following:
19 |
20 | # User-specific stuff:
21 | # .idea/workspace.xml
22 | # .idea/tasks.xml
23 | # .idea/dictionaries
24 |
25 | # Sensitive or high-churn files:
26 | # .idea/dataSources.ids
27 | # .idea/dataSources.xml
28 | # .idea/sqlDataSources.xml
29 | # .idea/dynamic.xml
30 | # .idea/uiDesigner.xml
31 |
32 | # Gradle:
33 | # .idea/gradle.xml
34 | # .idea/libraries
35 |
36 | # Mongo Explorer plugin:
37 | # .idea/mongoSettings.xml
38 |
39 | ## File-based project format:
40 | *.ipr
41 | *.iws
42 |
43 | ## Plugin-specific files:
44 |
45 | # IntelliJ
46 | out/
47 |
48 | # mpeltonen/sbt-idea plugin
49 | .idea_modules/
50 |
51 | # JIRA plugin
52 | atlassian-ide-plugin.xml
53 |
54 | # Crashlytics plugin (for Android Studio and IntelliJ)
55 | com_crashlytics_export_strings.xml
56 | crashlytics.properties
57 | crashlytics-build.properties
58 |
59 |
60 | ### IPythonNotebook template
61 | # Temporary data
62 | .ipynb_checkpoints/
63 |
64 |
65 | ### Python template
66 | # Byte-compiled / optimized / DLL files
67 | __pycache__/
68 | *.py[cod]
69 |
70 | # C extensions
71 | *.so
72 |
73 | # Distribution / packaging
74 | .Python
75 | env/
76 | build/
77 | develop-eggs/
78 | dist/
79 | downloads/
80 | eggs/
81 | .eggs/
82 | lib/
83 | lib64/
84 | parts/
85 | sdist/
86 | var/
87 | *.egg-info/
88 | .installed.cfg
89 | *.egg
90 |
91 | # PyInstaller
92 | # Usually these files are written by a python script from a template
93 | # before PyInstaller builds the exe, so as to inject date/other infos into it.
94 | *.manifest
95 | *.spec
96 |
97 | # Installer logs
98 | pip-log.txt
99 | pip-delete-this-directory.txt
100 |
101 | # Unit test / coverage reports
102 | htmlcov/
103 | .tox/
104 | .coverage
105 | .coverage.*
106 | .cache
107 | nosetests.xml
108 | coverage.xml
109 |
110 | # Translations
111 | *.mo
112 | *.pot
113 |
114 | # Django stuff:
115 | *.log
116 |
117 | # Sphinx documentation
118 | docs/_build/
119 |
120 | # PyBuilder
121 | target/
122 |
123 | large
124 | .pypirc
--------------------------------------------------------------------------------
/.jshintrc:
--------------------------------------------------------------------------------
1 | {
2 | "node": true,
3 | "esnext": true,
4 | "bitwise": true,
5 | "camelcase": true,
6 | "curly": true,
7 | "eqeqeq": true,
8 | "immed": true,
9 | "indent": 2,
10 | "latedef": true,
11 | "newcap": true,
12 | "noarg": true,
13 | "quotmark": "single",
14 | "regexp": true,
15 | "undef": true,
16 | "unused": true,
17 | "strict": true,
18 | "trailing": true,
19 | "smarttabs": true,
20 | "white": true
21 | }
22 |
--------------------------------------------------------------------------------
/.sass-cache/d092eda4ac72474b686870cd866fbade096fa91f/main.scssc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/arnoutaertgeerts/python-highcharts/6bd433cf53e851e9697639e88fcec453b7b63076/.sass-cache/d092eda4ac72474b686870cd866fbade096fa91f/main.scssc
--------------------------------------------------------------------------------
/MANIFEST.in:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/arnoutaertgeerts/python-highcharts/6bd433cf53e851e9697639e88fcec453b7b63076/MANIFEST.in
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Python-highcharts
2 | Use the excellent [highcharts/highstock](http://www.highcharts.com/stock/demo) library in Python or even in an IPython notebook as an interactive alternative to maplotlib.
3 |
4 | ## Install
5 | ```shell
6 | pip install charts
7 | ```
8 |
9 | ## Quick start
10 |
11 | First import the library:
12 | ```python
13 | import charts
14 | ```
15 |
16 | Second load some example data from the `data` module and some default options from the `options` module:
17 | ```python
18 | aapl = charts.data.aapl()
19 | msft = charts.data.msft()
20 | ohlc = charts.data.ohlc()
21 |
22 | ohlc['display'] = False
23 |
24 | series = [
25 | aapl,
26 | msft,
27 | ohlc
28 | ]
29 | ```
30 |
31 | And finally plot the chart! Use `show='inline'` if you are in an IPython notebook and `show='tab'` otherwise.
32 | ```python
33 | charts.plot(series, options, height=500, stock=True, show='inline')
34 | ```
35 |
36 | Don't be affraid to play with the chart, it's interactive :) Try typing in `OHLC` in the variable selector or viewing a different time period by squeezing the bottom scroll bar!
37 |
38 | For more, checkout this [notebook](http://nbviewer.ipython.org/github/arnoutaertgeerts/python-highcharts/blob/master/Tutorial.ipynb)!
39 |
40 | ## Use javascript functions in your option dictionary
41 |
42 | If you want to use a javascript function in your python option dictionary to for example dynamically update a tooltip, you should pre and affix your function statements with `@#`. The procedure is explained in [this notebook](http://nbviewer.ipython.org/github/arnoutaertgeerts/python-highcharts/blob/master/Javascript%20functions%20in%20options.ipynb).
43 |
--------------------------------------------------------------------------------
/README.rst:
--------------------------------------------------------------------------------
1 | Python-Highcharts
2 | =================
3 |
4 | A python module that allows you to use the highchart javascript library in python or inline in IPython notebooks.
--------------------------------------------------------------------------------
/app/chart.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/app/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/arnoutaertgeerts/python-highcharts/6bd433cf53e851e9697639e88fcec453b7b63076/app/favicon.ico
--------------------------------------------------------------------------------
/app/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | python highcharts
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
24 |
25 |
26 |
27 |
28 |
'Allo, 'Allo!
29 |
You now have
30 |
31 | - HTML5 Boilerplate
32 |
33 | - Modernizr
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
53 |
54 |
55 |
--------------------------------------------------------------------------------
/app/robots.txt:
--------------------------------------------------------------------------------
1 | # robotstxt.org/
2 |
3 | User-agent: *
4 |
--------------------------------------------------------------------------------
/app/scripts/app.js:
--------------------------------------------------------------------------------
1 |
2 | var React = window.React = require('react'),
3 | Timer = require("./ui/Timer"),
4 | mountNode = document.getElementById("app");
5 |
6 | var TodoList = React.createClass({
7 | render: function() {
8 | var createItem = function(itemText) {
9 | return {itemText};
10 | };
11 | return {this.props.items.map(createItem)}
;
12 | }
13 | });
14 | var TodoApp = React.createClass({
15 | getInitialState: function() {
16 | return {items: [], text: ''};
17 | },
18 | onChange: function(e) {
19 | this.setState({text: e.target.value});
20 | },
21 | handleSubmit: function(e) {
22 | e.preventDefault();
23 | var nextItems = this.state.items.concat([this.state.text]);
24 | var nextText = '';
25 | this.setState({items: nextItems, text: nextText});
26 | },
27 | render: function() {
28 | return (
29 |
30 |
TODO
31 |
32 |
36 |
37 |
38 | );
39 | }
40 | });
41 |
42 |
43 | React.render(, mountNode);
44 |
45 |
--------------------------------------------------------------------------------
/app/scripts/ui/Timer.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var React = require('react');
4 |
5 | var Timer = React.createClass({
6 | getInitialState: function() {
7 | return {secondsElapsed: 0};
8 | },
9 | tick: function() {
10 | this.setState({secondsElapsed: this.state.secondsElapsed + 1});
11 | },
12 | componentDidMount: function() {
13 | this.interval = setInterval(this.tick, 1000);
14 | },
15 | componentWillUnmount: function() {
16 | clearInterval(this.interval);
17 | },
18 | render: function() {
19 | return (
20 | Seconds Elapsed: {this.state.secondsElapsed}
21 | );
22 | }
23 | });
24 |
25 |
26 | module.exports = Timer;
27 |
--------------------------------------------------------------------------------
/app/styles/main.scss:
--------------------------------------------------------------------------------
1 | body {
2 | background: #fafafa;
3 | font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
4 | color: #333;
5 | }
6 |
7 | .hero-unit {
8 | margin: 50px auto 0 auto;
9 | width: 300px;
10 | font-size: 18px;
11 | font-weight: 200;
12 | line-height: 30px;
13 | background-color: #eee;
14 | border-radius: 6px;
15 | padding: 60px;
16 | h1 {
17 | font-size: 60px;
18 | line-height: 1;
19 | letter-spacing: -1px;
20 | }
21 | }
22 |
23 | .browsehappy {
24 | margin: 0.2em 0;
25 | background: #ccc;
26 | color: #000;
27 | padding: 0.2em 0;
28 | }
29 |
--------------------------------------------------------------------------------
/bower.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "charts",
3 | "version": "0.0.1",
4 | "dependencies": {
5 | "jquery": "~2.1.1",
6 | "bootstrap-sass-official": ">=3.3.0",
7 | "modernizr": "^2.8.3"
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/chart.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/charts/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/arnoutaertgeerts/python-highcharts/6bd433cf53e851e9697639e88fcec453b7b63076/charts/.DS_Store
--------------------------------------------------------------------------------
/charts/__init__.py:
--------------------------------------------------------------------------------
1 | __author__ = 'arnout'
2 |
3 | __version__ = '0.4.6'
4 |
5 | from plot import plot, plotasync, line, area, spline, pie
6 | from server import run_server
7 |
8 | from IPython.core import getipython
9 | from IPython.core.display import display, HTML
10 |
11 | from settings import default_settings, default_options, load_options
12 | import data
13 | import jsonencoder
14 |
--------------------------------------------------------------------------------
/charts/app.css:
--------------------------------------------------------------------------------
1 | body{-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;color:#555;font-family:sans-serif}
2 | small{font-weight:400;display:block;font-size:14px}
3 | code{background-color:#d3d3d3;border-radius:3px;font-family:monospace;padding:0 .5em}
4 | .icon.-facebook:before,.icon.-linkedin:before,.icon.-pinterest:before,.icon.-twitter:before{-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;font-family:Post-Creator-Icons;font-style:normal;font-variant:normal;font-weight:400;line-height:1;speak:none;text-transform:none}
5 | @font-face{font-family:Post-Creator-Icons;src:url(fonts/Post-Creator-Icons.eot);src:url(fonts/Post-Creator-Icons.eot?#iefix) format('embedded-opentype'),url(fonts/Post-Creator-Icons.woff) format('woff'),url(fonts/Post-Creator-Icons.ttf) format('truetype'),url(fonts/Post-Creator-Icons.svg#Post-Creator-Icons) format('svg');font-weight:400;font-style:normal}
6 | .icon.-facebook:before{content:"\e001"}
7 | .icon.-linkedin:before{content:"\e002"}
8 | .icon.-pinterest:before{content:"\e003"}
9 | .icon.-twitter:before{content:"\e004"}
10 | .social-icons h4{display:inline-block;margin:20px 10px 0 0}
11 | .social-icons .icon{display:inline-block;margin:0 5px}
12 | body.modal-open{overflow:hidden}
13 | .jsoneditor table,.jsoneditor td,.jsoneditor td.tree,.jsoneditor tr{border:none;margin:0}
--------------------------------------------------------------------------------
/charts/async.js:
--------------------------------------------------------------------------------
1 | (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o -1) {
227 | var newSeries = cachedSeries[index];
228 | renderedSeries.push(newSeries);
229 | return $.when()
230 | } else {
231 | return $.get(path + '/' + key + '.json').done(function (data) {
232 | if (key.color) {
233 | data['color'] = key.color
234 | } else {
235 | data['color'] = colors[colorIndex % 10];
236 | colorIndex = colorIndex + 1;
237 | }
238 |
239 | renderedSeries.push(data);
240 | cachedSeries.push(data);
241 | return null;
242 | });
243 | }
244 | }
245 |
246 | function deleteSeries(key) {
247 | var index = findSeries(renderedSeries, key);
248 | renderedSeries.splice(index, 1)
249 | }
250 |
251 | function saveSVG(url, name) {
252 | $.ajax({
253 | type: "POST",
254 | url: url,
255 | data: JSON.stringify({
256 | svg: chart.getSVG(),
257 | name: name
258 | })
259 | });
260 | }
261 | }
262 | });
263 |
264 | },{}]},{},[1]);
265 |
--------------------------------------------------------------------------------
/charts/chart.py:
--------------------------------------------------------------------------------
1 | __author__ = 'arnoutaertgeerts'
2 |
3 |
4 | from core import to_series, to_json_files, show_plot, set_display
5 |
6 |
7 | class Chart():
8 | def __init__(self, inline, html, path, show):
9 | self.inline = inline
10 | self.html = html
11 | self.path = path
12 | self.show_property = show
13 |
14 | def plot(self, *args, **kwargs):
15 | if len(args) == 2:
16 | self._plot_single(*args, **kwargs)
17 | else:
18 | self._plot_multi(*args, **kwargs)
19 |
20 | def _plot_multi(self, series, display):
21 | series = to_series(series)
22 | series = set_display(series, display)
23 |
24 | to_json_files(series, self.path)
25 |
26 | def _plot_single(self, data, name, display):
27 | series = to_series(dict(data=data, name=name))
28 | series = set_display(series, display)
29 |
30 | to_json_files(series, self.path, )
31 |
32 | def show(self):
33 | return show_plot(self.inline, self.html, self.show_property, async=self.path)
--------------------------------------------------------------------------------
/charts/core.py:
--------------------------------------------------------------------------------
1 | __author__ = 'arnoutaertgeerts'
2 |
3 | from string import Template
4 | from jsonencoder import ChartsJSONEncoder
5 | from server import url
6 |
7 | import os
8 | import json
9 | import shutil
10 | import webbrowser
11 | import re
12 |
13 |
14 | class MyTemplate(Template):
15 | delimiter = '$#'
16 | idpattern = r'[a-z][_a-z0-9]*'
17 |
18 |
19 | def show_plot(html, saveHTML, show, async=False):
20 | if show == 'inline':
21 | from IPython.display import HTML
22 | return HTML(html)
23 |
24 | elif show == 'tab':
25 | print 'Opening new tab...'
26 | if async:
27 | address = url(async)
28 | webbrowser.open_new_tab(address)
29 | else:
30 | webbrowser.open_new_tab('file://' + os.path.realpath(saveHTML))
31 |
32 | elif show == 'window':
33 | print 'Trying to open a window. If this fails we will open a tab...'
34 | if async:
35 | address = url(async)
36 | webbrowser.open_new(address)
37 | else:
38 | webbrowser.open_new('file://' + os.path.realpath(saveHTML))
39 |
40 | elif show == 'string':
41 | return html
42 |
43 |
44 | def clean_dir(path):
45 | if os.path.exists(path):
46 | shutil.rmtree(path)
47 | os.makedirs(path)
48 |
49 |
50 | def make_dir(path):
51 | if not os.path.exists(path):
52 | os.makedirs(path)
53 |
54 |
55 | def to_json_files(series, path):
56 | try:
57 | with open(os.path.join(path, 'keys.json'), "r") as keys_file:
58 | keys = json.loads(keys_file.read())
59 | except IOError:
60 | keys = []
61 |
62 | for k in keys:
63 | k["display"] = False
64 |
65 | for s in series:
66 | if s["name"] not in map(lambda x: x["name"], keys):
67 | keys.append(dict(name=s["name"], display=s["display"], value=s["name"], text=s["name"]))
68 | with open(os.path.join(path, s["name"] + ".json"), "w") as json_file:
69 | json_file.write(json.dumps(s, cls=ChartsJSONEncoder))
70 | else:
71 | i = find(keys, "name", s["name"])
72 | keys[i] = dict(name=s["name"], display=s["display"], value=s["name"], text=s["name"])
73 |
74 | with open(os.path.join(path, 'keys.json'), "w") as keys_file:
75 | keys_file.write(json.dumps(keys))
76 |
77 |
78 | def find(col, key, value):
79 | for i, c in enumerate(col):
80 | if c[key] == value:
81 | return i
82 |
83 |
84 | def set_display(series, display):
85 | if display is True:
86 | for s in series:
87 | s['display'] = True
88 |
89 | elif display is False:
90 | for s in series:
91 | s['display'] = False
92 |
93 | else:
94 | for s in series:
95 | if s['name'] in display:
96 | s['display'] = True
97 | else:
98 | s['display'] = False
99 |
100 | return series
101 |
102 |
103 | def df_to_series(df):
104 | """Prepare data from dataframe for plotting with python-highcharts.
105 | all columns in df are entries in the returned series.
106 |
107 | The returned series is in the format suitable for python-highcharts: list of dicts with:
108 | data:list of [index, value]-lists.
109 | name:name of variable.
110 | """
111 |
112 | import pandas as pd
113 | import numpy as np
114 |
115 | df = df.where((pd.notnull(df)), None)
116 |
117 | if isinstance(df.index, pd.DatetimeIndex):
118 | index = df.index.asi8 / (1e6)
119 | else:
120 | index = df.index
121 |
122 | series = []
123 | for col in df:
124 | series.append(
125 | dict(name=col,
126 | data=np.array([index, df[col].values]).T,
127 | display=False)
128 | )
129 |
130 | return series
131 |
132 |
133 | def list_to_series(array):
134 | return dict(
135 | data=array
136 | )
137 |
138 |
139 | def to_series(series, name=False):
140 | # Dictionary?
141 | if isinstance(series, dict):
142 | return [series]
143 |
144 | # List of dictionaries?:
145 | try:
146 | if isinstance(series[0], dict):
147 | return series
148 | except KeyError:
149 | pass
150 |
151 | # List?
152 | try:
153 | if isinstance(series, list):
154 | return [dict(data=series, name=name)]
155 | except KeyError:
156 | pass
157 |
158 | # Numpy array?
159 | try:
160 | import numpy as np
161 | if isinstance(series, np.ndarray):
162 | return [dict(data=series, name=name)]
163 | except ImportError:
164 | pass
165 |
166 | # pandas DataFrame or series?
167 | try:
168 | import pandas as pd
169 | if isinstance(series, pd.DataFrame):
170 | return df_to_series(series)
171 | if isinstance(series, pd.Series):
172 | return df_to_series(pd.DataFrame(series))
173 | except ImportError:
174 | pass
175 |
176 | raise ValueError('Your data is not in the right format!')
177 |
178 | def remove_quotes(options):
179 |
180 | options = json.dumps(options)
181 |
182 | ix = [m.start() for m in re.finditer('@#', options)]
183 |
184 | for j, i in enumerate(ix):
185 | k = i-3*j
186 | if options[k-1] == '"':
187 | options = options[:k-1] + options[k+2:]
188 | else:
189 | options = options[:k] + options[k+3:]
190 |
191 | return options
192 |
--------------------------------------------------------------------------------
/charts/fonts/Post-Creator-Icons.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/arnoutaertgeerts/python-highcharts/6bd433cf53e851e9697639e88fcec453b7b63076/charts/fonts/Post-Creator-Icons.eot
--------------------------------------------------------------------------------
/charts/fonts/Post-Creator-Icons.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
25 |
--------------------------------------------------------------------------------
/charts/fonts/Post-Creator-Icons.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/arnoutaertgeerts/python-highcharts/6bd433cf53e851e9697639e88fcec453b7b63076/charts/fonts/Post-Creator-Icons.ttf
--------------------------------------------------------------------------------
/charts/fonts/Post-Creator-Icons.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/arnoutaertgeerts/python-highcharts/6bd433cf53e851e9697639e88fcec453b7b63076/charts/fonts/Post-Creator-Icons.woff
--------------------------------------------------------------------------------
/charts/images/gulp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/arnoutaertgeerts/python-highcharts/6bd433cf53e851e9697639e88fcec453b7b63076/charts/images/gulp.png
--------------------------------------------------------------------------------
/charts/images/jsoneditor-icons.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/arnoutaertgeerts/python-highcharts/6bd433cf53e851e9697639e88fcec453b7b63076/charts/images/jsoneditor-icons.png
--------------------------------------------------------------------------------
/charts/jsonencoder.py:
--------------------------------------------------------------------------------
1 | __author__ = 'Arnout Aertgeerts'
2 |
3 | import json
4 |
5 |
6 | class ChartsJSONEncoder(json.JSONEncoder):
7 | def default(self, obj):
8 | try:
9 | import numpy
10 | if isinstance(obj, numpy.ndarray):
11 | if obj.ndim == 1:
12 | return obj.tolist()
13 | else:
14 | return [self.default(obj[i]) for i in range(obj.shape[0])]
15 | elif isinstance(obj, numpy.generic):
16 | return obj.item()
17 | except ImportError:
18 | pass
19 |
20 | return json.JSONEncoder.default(self, obj)
21 |
--------------------------------------------------------------------------------
/charts/lib.js:
--------------------------------------------------------------------------------
1 | (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o>> 0;
13 | var thisArg = arguments[1];
14 | var value;
15 |
16 | for (var i = 0; i < length; i++) {
17 | value = list[i];
18 | if (predicate.call(thisArg, value, i, list)) {
19 | return i;
20 | }
21 | }
22 | return -1;
23 | };
24 | }
25 |
26 | if (!Array.prototype.filter) {
27 | Array.prototype.filter = function(fun/*, thisArg*/) {
28 | 'use strict';
29 |
30 | if (this === void 0 || this === null) {
31 | throw new TypeError();
32 | }
33 |
34 | var t = Object(this);
35 | var len = t.length >>> 0;
36 | if (typeof fun !== 'function') {
37 | throw new TypeError();
38 | }
39 |
40 | var res = [];
41 | var thisArg = arguments.length >= 2 ? arguments[1] : void 0;
42 | for (var i = 0; i < len; i++) {
43 | if (i in t) {
44 | var val = t[i];
45 |
46 | // NOTE: Technically this should Object.defineProperty at
47 | // the next index, as push can be affected by
48 | // properties on Object.prototype and Array.prototype.
49 | // But that method's new, and collisions should be
50 | // rare, so use the more-compatible alternative.
51 | if (fun.call(thisArg, val, i, t)) {
52 | res.push(val);
53 | }
54 | }
55 | }
56 |
57 | return res;
58 | };
59 | }
60 |
61 | function guid() {
62 | function s4() {
63 | return Math.floor((1 + Math.random()) * 0x10000)
64 | .toString(16)
65 | .substring(1);
66 | }
67 | return s4() + s4() + '-' + s4() + '-' + s4() + '-' +
68 | s4() + '-' + s4() + s4() + s4();
69 | }
70 |
71 | Array.prototype.equals = function (array) {
72 | // if the other array is a false value, return
73 | if (!array)
74 | return false;
75 |
76 | // compare lengths - can save a lot of time
77 | if (this.length != array.length)
78 | return false;
79 |
80 | for (var i = 0, l = this.length; i < l; i++) {
81 | // Check if we have nested arrays
82 | if (this[i] instanceof Array && array[i] instanceof Array) {
83 | // recurse into the nested arrays
84 | if (!this[i].equals(array[i]))
85 | return false;
86 | }
87 | else if (this[i] != array[i]) {
88 | // Warning - two different object instances will never be equal: {x:20} != {x:20}
89 | return false;
90 | }
91 | }
92 | return true;
93 | };
94 |
95 | },{}]},{},[1]);
96 |
--------------------------------------------------------------------------------
/charts/page.js:
--------------------------------------------------------------------------------
1 | (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o
16 |
17 | """
18 |
19 |
20 | def line(*args, **kwargs):
21 | return plot(*args, type='line', **kwargs)
22 |
23 |
24 | def area(*args, **kwargs):
25 | return plot(*args, type='area', **kwargs)
26 |
27 |
28 | def spline(*args, **kwargs):
29 | return plot(*args, type='spline', **kwargs)
30 |
31 |
32 | def pie(*args, **kwargs):
33 | return plot(*args, type='pie', **kwargs)
34 |
35 |
36 | def stock(*args, **kwargs):
37 | return plot(*args, stock=True, **kwargs)
38 |
39 |
40 | def plot(series, options=dict(), **kwargs):
41 | """
42 | Make a highchart plot with all data embedded in the HTML
43 | :param type: Type of the chart (will overwrite options['chart']['type'] if specified).
44 | :param series: The necessary data, can be a list of dictionaries or a dataframe
45 | :param options: Options for the chart. This can one of the following:
46 | - A Dictionary
47 | - The path to a json file
48 | - A json string
49 | :param height: Chart height
50 | :param save: Specify a filename to save the HTML file if wanted.
51 | :param stock: Set to False to use Highcharts instead of highstock
52 | :param show: Determines how the chart is shown. Can be one of the following options:
53 | - 'tab': Show the chart in a new tab of the default browser
54 | - 'window': Show the chart in a new window of the default browser
55 | - 'inline': Show the chart inline (only works in IPython notebook)
56 | :param display: A list containing the keys of the variables you want to show initially in the plot
57 | :return: The chart to display
58 | """
59 |
60 | # Check if options is a json string or file
61 | if isinstance(options, str):
62 | if '.json' in options:
63 | options = load_options(options)
64 | else:
65 | try:
66 | options = json.loads(options)
67 | except ValueError:
68 | raise ValueError('Your options string is not valid JSON!')
69 |
70 | chart_settings = default_settings.copy()
71 | chart_options = default_options.copy()
72 |
73 | chart_settings.update(kwargs)
74 | chart_options.update(options)
75 |
76 | keys = chart_settings.keys()
77 |
78 | for key in keys:
79 | if key not in ['options', 'name', 'display', 'save', 'show', 'height', 'type', 'stock', 'width']:
80 | raise AttributeError(key + ' is not a valid option!')
81 |
82 | options = chart_options
83 | name = chart_settings['name']
84 | display = chart_settings['display']
85 | save = chart_settings['save']
86 | show = chart_settings['show']
87 | type = chart_settings['type']
88 | stock = chart_settings['stock']
89 |
90 | try:
91 | if options['chart']:
92 | options['chart'].update(dict(type=type))
93 | except KeyError:
94 | options['chart'] = dict(type=type)
95 |
96 | try:
97 | if not options['height']:
98 | options['chart'].update(dict(type=type))
99 | except KeyError:
100 | options['chart'] = dict(type=type)
101 |
102 | # Convert to a legitimate series object
103 | series = to_series(series, name)
104 |
105 | # Set the display option
106 | series = set_display(series, display)
107 |
108 | # Get the save extension
109 | if save:
110 | extension = os.path.splitext(save)[1]
111 | else:
112 | extension = False
113 |
114 | saveSVG = False
115 | saveHTML = False
116 |
117 | if extension == '.svg':
118 | saveSVG = save
119 | if show != 'inline':
120 | saveHTML = 'index.html'
121 | if extension == '.html':
122 | saveHTML = save
123 |
124 | if 'settingsFile' in options:
125 | settings_file = options['settingsFile'][:-5]
126 | else:
127 | settings_file = 'settings'
128 |
129 | with open(os.path.join(package_directory, "index.html"), "r") as html:
130 | html = MyTemplate(html.read()).substitute(
131 | path=package_directory,
132 | series=json.dumps(series, cls=ChartsJSONEncoder),
133 | options=remove_quotes(options),
134 | highstock=json.dumps(stock),
135 | url=json.dumps(address),
136 | save=json.dumps(saveSVG),
137 | settingsFile=json.dumps(settings_file)
138 | )
139 |
140 | if saveHTML:
141 | with open(saveHTML, "w") as text_file:
142 | text_file.write(html + TABDEPS)
143 |
144 | return show_plot(html, saveHTML, show)
145 |
146 |
147 | def plotasync(
148 | series=None, options=dict(), type='line',
149 | height=400, save="temp", stock=False, show='tab', display=False, purge=False, live=False):
150 | """
151 | :param type: Type of the chart. Can be line, area, spline, pie, bar, ...
152 | :param display: Set to true to display all, False to display none or an array of names for a specific selection
153 | :param purge: Set to true to clean the directory
154 | :param live: Set to true to keep the chart in sync with data in the directory. Currently only works for show='tab'
155 | :param series: The series object which contains the data. If this is not specified, the plot will look for json
156 | files in the save directory.
157 | :param options: The chart display options
158 | :param height: Height of the chart
159 | :param save: Name of the directory to store the data
160 | :param stock: Set to true to use highstock
161 | :param show: Determines how the chart is shown. Can be one of the following options:
162 | - 'tab': Show the chart in a new tab of the default browser
163 | - 'window': Show the chart in a new window of the default browser
164 | - 'inline': Show the chart inline (only works in IPython notebook)
165 | :return: A chart object
166 | """
167 |
168 | try:
169 | if not options['chart']:
170 | options['chart'] = dict(type=type)
171 | except KeyError:
172 | options['chart'] = dict(type=type)
173 |
174 | if 'height' not in options:
175 | options['height'] = 400
176 |
177 | # Clean the directory
178 | if purge:
179 | clean_dir(save)
180 | else:
181 | make_dir(save)
182 |
183 | if series is not None:
184 | # Convert to a legitimate series object
185 | series = to_series(series)
186 | series = set_display(series, display)
187 |
188 | # Convert to json files
189 | to_json_files(series, save)
190 |
191 | if show == 'inline':
192 | live = False
193 |
194 | with open(os.path.join(package_directory, "index-async.html"), "r") as index:
195 | read = index.read()
196 |
197 | html = MyTemplate(read).substitute(
198 | path=json.dumps('/' + save),
199 | options=json.dumps(options),
200 | highstock=json.dumps(stock),
201 | height=str(height) + "px",
202 | live=json.dumps(live),
203 | url=json.dumps(address),
204 | save=json.dumps(False)
205 | )
206 |
207 | inline = MyTemplate(read).substitute(
208 | path=json.dumps(save),
209 | options=json.dumps(options),
210 | highstock=json.dumps(stock),
211 | height=str(height) + "px",
212 | live=json.dumps(live),
213 | url=json.dumps(address),
214 | save=json.dumps(False)
215 | )
216 |
217 | html_path = os.path.join(save, 'index.html')
218 | with open(html_path, "w") as html_file:
219 | html_file.write(html + TABDEPS)
220 |
221 | return Chart(inline, html_path, save, show)
222 |
--------------------------------------------------------------------------------
/charts/require.js:
--------------------------------------------------------------------------------
1 | (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;oCreated with Highstock 2.1.5ValuesChart titletemperature 1temperature 200.511.522.530246810Highcharts.com
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "charts",
3 | "version": "0.0.0",
4 | "dependencies": {},
5 | "devDependencies": {
6 | "del": "~0.1.3",
7 | "gulp": "~3.8.8",
8 | "gulp-autoprefixer": "~1.0.1",
9 | "gulp-bower": "0.0.6",
10 | "gulp-cache": "~0.2.4",
11 | "gulp-imagemin": "latest",
12 | "gulp-jshint": "~1.8.5",
13 | "gulp-load-plugins": "~0.7.0",
14 | "gulp-ruby-sass": "~0.7.1",
15 | "browser-sync": "latest",
16 | "gulp-size": "~1.1.0",
17 | "gulp-useref": "~0.4.4",
18 | "gulp-util": "~3.0.1",
19 | "gulp-webserver": "latest",
20 | "react": "latest",
21 | "react-tools": "latest",
22 | "reactify": "latest",
23 | "watchify": "~2.1",
24 | "browserify-shim": "^3.8.0",
25 | "gulp-uglify": "^1.0.2",
26 | "strip-debug": "^1.0.1",
27 | "gulp-strip-debug": "^1.0.2",
28 | "vinyl-source-stream": "^1.0.0",
29 | "main-bower-files":"~2.6.2"
30 | },
31 | "engines": {
32 | "node": ">=0.10.0"
33 | },
34 | "scripts": {
35 | "test": "jest"
36 | },
37 | "jest": {
38 | "scriptPreprocessor": "/preprocessor.js",
39 | "unmockedModulePathPatterns": [
40 | "/node_modules/react"
41 | ]
42 | },
43 | "browserify": {
44 | "transform": [
45 | "browserify-shim",
46 | [
47 | "reactify",
48 | {
49 | "es6": true
50 | }
51 | ]
52 | ]
53 | },
54 | "browser": {
55 | "jquery": "./app/bower_components/jquery/dist/jquery.js"
56 | },
57 | "browserify-shim": {
58 | "jquery": "$"
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/preprocessor.js:
--------------------------------------------------------------------------------
1 | var ReactTools = require('react-tools');
2 | module.exports = {
3 | process: function(src) {
4 | return ReactTools.transform(src, {
5 | harmony: true
6 | });
7 | }
8 | };
9 |
--------------------------------------------------------------------------------
/scripts/app.js:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/scripts/require-config.js:
--------------------------------------------------------------------------------
1 | requirejs.config({
2 | paths: {
3 | 'highstock': "http://code.highcharts.com/stock/highstock",
4 | 'standalone': "http://code.highcharts.com/adapters/standalone-framework",
5 | 'export': "http://code.highcharts.com/stock/modules/exporting",
6 | 'angular': "https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.3.15/angular"
7 | },
8 |
9 | shim: {
10 | 'highstock': {
11 | deps: ['standalone'],
12 | exports: 'Highcharts'
13 | }
14 | }
15 | });
16 |
--------------------------------------------------------------------------------
/setup.cfg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/arnoutaertgeerts/python-highcharts/6bd433cf53e851e9697639e88fcec453b7b63076/setup.cfg
--------------------------------------------------------------------------------
/setup.py:
--------------------------------------------------------------------------------
1 | __author__ = 'arnout'
2 |
3 | from setuptools import setup, find_packages
4 |
5 | setup(
6 | name='charts',
7 | version='0.4.6',
8 | description='Use the highcharts js library in Python',
9 | url='https://github.com/arnoutaertgeerts/python-highcharts',
10 | author='Arnout Aertgeerts',
11 | author_email='arnoutaertgeerts@gmail.com',
12 | license='MIT',
13 | keywords='highcharts highstock plotting',
14 | packages=find_packages(),
15 | install_requires=[],
16 | package_data={
17 | 'charts': ['*.html']
18 | }
19 | )
20 |
--------------------------------------------------------------------------------
/small/keys.json:
--------------------------------------------------------------------------------
1 | [{
2 | "name": "AAPL",
3 | "display": true
4 | }, {
5 | "name": "MSFT",
6 | "display": true
7 | }, {
8 | "name": "OHLC",
9 | "display": false
10 | }
11 | ]
12 |
--------------------------------------------------------------------------------
/style.css:
--------------------------------------------------------------------------------
1 | .md-chips .md-chip-input-container input:focus {
2 | outline: none;
3 | border: none;
4 | box-shadow: none;
5 | }
6 |
7 |
8 | .chipsdemoContactChips .md-item-text.compact {
9 | padding-top: 8px;
10 | padding-bottom: 8px; }
11 | .chipsdemoContactChips .contact-item {
12 | box-sizing: border-box; }
13 | .chipsdemoContactChips .contact-item.selected {
14 | opacity: 0.5; }
15 | .chipsdemoContactChips .contact-item.selected h3 {
16 | opacity: 0.5; }
17 | .chipsdemoContactChips .contact-item .md-list-item-text {
18 | padding: 14px 0; }
19 | .chipsdemoContactChips .contact-item .md-list-item-text h3 {
20 | margin: 0 !important;
21 | padding: 0;
22 | line-height: 1.2em !important; }
23 | .chipsdemoContactChips .contact-item .md-list-item-text h3, .chipsdemoContactChips .contact-item .md-list-item-text p {
24 | text-overflow: ellipsis;
25 | white-space: nowrap;
26 | overflow: hidden; }
27 | @media (min-width: 900px) {
28 | .chipsdemoContactChips .contact-item {
29 | float: left;
30 | width: 33%; } }
31 | .chipsdemoContactChips md-contact-chips {
32 | margin-bottom: 10px; }
33 | .chipsdemoContactChips .md-chips {
34 | padding: 5px 0 8px; }
35 | .chipsdemoContactChips .fixedRows {
36 | height: 250px;
37 | overflow: hidden; }
--------------------------------------------------------------------------------
/view/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | build
3 | Desktop.ini
4 | node_modules
5 |
--------------------------------------------------------------------------------
/view/LICENSE.md:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2014 Daniel Tello
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/view/README.md:
--------------------------------------------------------------------------------
1 | **Lots of new stuff happening in the [2.0 branch](https://github.com/greypants/gulp-starter/tree/2.0)**
2 |
3 | **Use Rails?** Check out http://viget.com/extend/gulp-rails-asset-pipeline and https://github.com/vigetlabs/gulp-rails-pipeline
4 |
5 | gulp-starter
6 | ============
7 |
8 | Starter Gulp + Browserify project with examples of how to accomplish some common tasks and workflows. Read the [blog post](http://viget.com/extend/gulp-browserify-starter-faq) for more context, and check out the [Wiki](https://github.com/greypants/gulp-starter/wiki) for some good background knowledge.
9 |
10 | Includes the following tools, tasks, and workflows:
11 |
12 | - [Browserify](http://browserify.org/) (with [browserify-shim](https://github.com/thlorenz/browserify-shim))
13 | - [Watchify](https://github.com/substack/watchify) (caching version of browserify for super fast rebuilds)
14 | - [SASS](http://sass-lang.com/) (super fast libsass with [source maps](https://github.com/sindresorhus/gulp-ruby-sass#sourcemap), and [autoprefixer](https://github.com/sindresorhus/gulp-autoprefixer))
15 | - [CoffeeScript](http://coffeescript.org/) (with source maps!)
16 | - [BrowserSync](http://browsersync.io) for live reloading and a static server
17 | - [Image optimization](https://www.npmjs.com/package/gulp-imagemin)
18 | - Error handling in the console [and in Notification Center](https://github.com/mikaelbr/gulp-notify)
19 | - Shimming non common-js vendor code with other dependencies (like a jQuery plugin)
20 | - **New** Multiple bundles with shared dependencies
21 | - **New** Separate compression task for production builds
22 | - **New** Icon Font generation
23 |
24 | If you've never used Node or npm before, you'll need to install Node.
25 | If you use homebrew, do:
26 |
27 | ```
28 | brew install node
29 | ```
30 |
31 | Otherwise, you can download and install from [here](http://nodejs.org/download/).
32 |
33 | ### Install npm dependencies
34 | ```
35 | npm install
36 | ```
37 |
38 | This runs through all dependencies listed in `package.json` and downloads them to a `node_modules` folder in your project directory.
39 |
40 | ### The `gulp` command
41 | To run the version of gulp installed local to the project, in the root of your this project, you'd run
42 |
43 | ```
44 | ./node_modules/.bin/gulp
45 | ```
46 |
47 | **WAT.** Why can't I just run `gulp`? Well, you could install gulp globally with `npm install -g gulp`, which will add the gulp script to your global bin folder, but it's always better to use the version that's specified in your project's package.json. My solution to this is to simply alias `./node_modules/.bin/gulp` to `gulp`. Open up `~/.zshrc` or `~./bashrc` and add the following line:
48 |
49 | ```
50 | alias gulp='node_modules/.bin/gulp'
51 | ```
52 | Now, running `gulp` in the project directory will use the version specified and installed from the `package.json` file.
53 |
54 | ### Run gulp and be amazed.
55 | The first time you run the app, you'll also need to generate the iconFont, since this is not something we want to run every time with our `default` task.
56 | ```
57 | gulp iconFont
58 | ```
59 |
60 | After that, just run the `default` gulp task with:
61 | ```
62 | gulp
63 | ```
64 |
65 | This will run the `default` gulp task defined in `gulp/tasks/default.js`, which has the following task dependencies: `['sass', 'images', 'markup', 'watch']`
66 | - The `sass` task compiles your css files.
67 | - `images` moves images copies images from a source folder, performs optimizations, the outputs them into the build folder
68 | - `markup` doesn't do anything but copy an html file over from src to build, but here is where you could do additional templating work.
69 | - `watch` has `watchify` as a dependency, which will run the browserifyTask with a `devMode` flag that enables sourcemaps and watchify, a browserify add-on that enables caching for super fast recompiling. The task itself starts watching source files and will re-run the appropriate tasks when those files change.
70 |
71 | ### Configuration
72 | All paths and plugin settings have been abstracted into a centralized config object in `gulp/config.js`. Adapt the paths and settings to the structure and needs of your project.
73 |
74 | ### Additional Features and Tasks
75 |
76 | #### Icon Fonts
77 |
78 | ```
79 | gulp iconFont
80 | ```
81 |
82 | Generating and re-generating icon fonts is an every once and a while task, so it's not included in `tasks/default.js`. Run the task separately any time you add an svg to your icons folder. This task has a couple of parts.
83 |
84 | ##### The task
85 | The task calls `gulp-iconfont` and passes the options we've configured in [`gulp/config.js`](https://github.com/greypants/gulp-starter/blob/icon-font/gulp/config.js#L27). Then it listens for a `codepoints` that triggers the generation of the sass file you'll be importing into your stylesheets. [`gulp/iconFont/generateIconSass`](./gulp/tasks/iconFont/generateIconSass.js) passes the icon data to [a template](./gulp/tasks/iconFont/template.sass.swig), then outputs the resulting file to your sass directory. See the [gulp-iconFont docs](https://github.com/nfroidure/gulp-iconfont) for more config details. You may reconfigure the template to output whatever you'd like. The way it's currently set up will make icons usable as both class names and mixins.
86 |
87 | ```sass
88 | .twitter-button
89 | +icon--twitter // (@include in .scss syntax)
90 | ```
91 |
92 | or
93 |
94 | ```html
95 |
96 | ```
97 |
98 | #### Production files
99 |
100 | There is also a `production` task you can run:
101 | ```
102 | gulp production
103 | ```
104 | This will run JavaScript tests, then re-build optimized, compressed css and js files to the build folder, as well as output their file sizes to the console. It's a shortcut for running the following tasks: `karma`, `images`, `iconFont` `minifyCss`, `uglifyJs`.
105 |
106 | #### JavaScript Tests with Karma
107 | This repo includes a basic js testing setup with the following: [Karma](http://karma-runner.github.io/0.12/index.html), [Mocha](http://mochajs.org/), [Chai](http://chaijs.com/), and [Sinon](http://sinonjs.org/). There is `karma` gulp task, which the `production` task uses to run the tests before compiling. If any tests fail, the `production` task will abort.
108 |
109 | To run the tests and start monitoring files:
110 | ```
111 | ./node_modules/karma/bin/karma start
112 | ```
113 |
114 | Want to just run `karma start`? Either add `alias karma="./node_modules/karma/bin/karma"` to your shell config or install the karma command line interface globally with `npm install -g karma-cli`.
115 |
116 |
117 | --
118 |
119 | Social icons courtesy of [icomoon.io](https://icomoon.io/#icons-icomoon)
120 |
121 | Made with ♥ at [Viget](http://viget.com)!
122 |
--------------------------------------------------------------------------------
/view/gulp/config.js:
--------------------------------------------------------------------------------
1 | var dest = "../charts";
2 | //var dest = "./build";
3 | var src = './src';
4 |
5 | module.exports = {
6 | browserSync: {
7 | server: {
8 | // Serve up our build folder
9 | baseDir: dest
10 | }
11 | },
12 | sass: {
13 | src: src + "/sass/**/*.{sass,scss}",
14 | dest: dest,
15 | settings: {
16 | indentedSyntax: true, // Enable .sass syntax!
17 | imagePath: 'images' // Used by the image-url helper
18 | }
19 | },
20 | images: {
21 | src: src + "/images/**",
22 | dest: dest + "/images"
23 | },
24 | markup: {
25 | src: src + "/htdocs/**",
26 | dest: dest
27 | },
28 | iconFonts: {
29 | name: 'Gulp Starter Icons',
30 | src: src + '/icons/*.svg',
31 | dest: dest + '/fonts',
32 | sassDest: src + '/sass',
33 | template: './gulp/tasks/iconFont/template.sass.swig',
34 | sassOutputName: '_icons.sass',
35 | fontPath: 'fonts',
36 | className: 'icon',
37 | options: {
38 | fontName: 'Post-Creator-Icons',
39 | appendCodepoints: true,
40 | normalize: false
41 | }
42 | },
43 | browserify: {
44 | // A separate bundle will be generated for each
45 | // bundle config in the list below
46 | bundleConfigs: [
47 | {
48 | entries: src + '/javascript/page.js',
49 | dest: dest,
50 | outputName: 'page.js'
51 | // list of externally available modules to exclude from the bundle
52 | //external: ['jquery']
53 | },
54 | {
55 | entries: src + '/javascript/async.js',
56 | dest: dest,
57 | outputName: 'async.js'
58 | // list of externally available modules to exclude from the bundle
59 | //external: ['jquery']
60 | },
61 | {
62 | entries: src + '/javascript/require.js',
63 | dest: dest,
64 | outputName: 'require.js'
65 | },
66 | {
67 | entries: src + '/javascript/lib.js',
68 | dest: dest,
69 | outputName: 'lib.js'
70 | }
71 | ]
72 | },
73 | production: {
74 | cssSrc: dest + '/*.css',
75 | jsSrc: dest + '/*.js',
76 | htmlSrc: dest + '/*.html',
77 | dest: dest
78 | }
79 | };
80 |
--------------------------------------------------------------------------------
/view/gulp/tasks/browserSync.js:
--------------------------------------------------------------------------------
1 | var browserSync = require('browser-sync');
2 | var gulp = require('gulp');
3 | var config = require('../config').browserSync;
4 |
5 | gulp.task('browserSync', function() {
6 | browserSync(config);
7 | });
8 |
--------------------------------------------------------------------------------
/view/gulp/tasks/browserify.js:
--------------------------------------------------------------------------------
1 | /* browserify task
2 | ---------------
3 | Bundle javascripty things with browserify!
4 |
5 | This task is set up to generate multiple separate bundles, from
6 | different sources, and to use Watchify when run from the default task.
7 |
8 | See browserify.bundleConfigs in gulp/config.js
9 | */
10 |
11 | var browserify = require('browserify');
12 | var browserSync = require('browser-sync');
13 | var watchify = require('watchify');
14 | var mergeStream = require('merge-stream');
15 | var bundleLogger = require('../util/bundleLogger');
16 | var gulp = require('gulp');
17 | var handleErrors = require('../util/handleErrors');
18 | var source = require('vinyl-source-stream');
19 | var config = require('../config').browserify;
20 | var _ = require('lodash');
21 |
22 | var browserifyTask = function(devMode) {
23 |
24 | var browserifyThis = function(bundleConfig) {
25 |
26 | if(devMode) {
27 | // Add watchify args and debug (sourcemaps) option
28 | _.extend(bundleConfig, watchify.args, { debug: true });
29 | // A watchify require/external bug that prevents proper recompiling,
30 | // so (for now) we'll ignore these options during development. Running
31 | // `gulp browserify` directly will properly require and externalize.
32 | bundleConfig = _.omit(bundleConfig, ['external', 'require']);
33 | }
34 |
35 | var b = browserify(bundleConfig);
36 |
37 | var bundle = function() {
38 | // Log when bundling starts
39 | bundleLogger.start(bundleConfig.outputName);
40 |
41 | return b
42 | .bundle()
43 | // Report compile errors
44 | .on('error', handleErrors)
45 | // Use vinyl-source-stream to make the
46 | // stream gulp compatible. Specify the
47 | // desired output filename here.
48 | .pipe(source(bundleConfig.outputName))
49 | // Specify the output destination
50 | .pipe(gulp.dest(bundleConfig.dest))
51 | .pipe(browserSync.reload({
52 | stream: true
53 | }));
54 | };
55 |
56 | if(devMode) {
57 | // Wrap with watchify and rebundle on changes
58 | b = watchify(b);
59 | // Rebundle on update
60 | b.on('update', bundle);
61 | bundleLogger.watch(bundleConfig.outputName);
62 | } else {
63 | // Sort out shared dependencies.
64 | // b.require exposes modules externally
65 | if(bundleConfig.require) b.require(bundleConfig.require);
66 | // b.external excludes modules from the bundle, and expects
67 | // they'll be available externally
68 | if(bundleConfig.external) b.external(bundleConfig.external);
69 | }
70 |
71 | return bundle();
72 | };
73 |
74 | // Start bundling with Browserify for each bundleConfig specified
75 | return mergeStream.apply(gulp, _.map(config.bundleConfigs, browserifyThis));
76 |
77 | };
78 |
79 | gulp.task('browserify', function() {
80 | return browserifyTask()
81 | });
82 |
83 | // Exporting the task so we can call it directly in our watch task, with the 'devMode' option
84 | module.exports = browserifyTask;
85 |
--------------------------------------------------------------------------------
/view/gulp/tasks/default.js:
--------------------------------------------------------------------------------
1 | var gulp = require('gulp');
2 |
3 | gulp.task('default', ['sass', 'images', 'markup', 'watch']);
4 |
--------------------------------------------------------------------------------
/view/gulp/tasks/iconFont/generateIconSass.js:
--------------------------------------------------------------------------------
1 | var gulp = require('gulp');
2 | var config = require('../../config').iconFonts;
3 | var swig = require('gulp-swig');
4 | var rename = require('gulp-rename');
5 |
6 | module.exports = function(codepoints, options) {
7 | gulp.src(config.template)
8 | .pipe(swig({
9 | data: {
10 | icons: codepoints.map(function(icon) {
11 | return {
12 | name: icon.name,
13 | code: icon.codepoint.toString(16)
14 | }
15 | }),
16 |
17 | fontName: config.options.fontName,
18 | fontPath: config.fontPath,
19 | className: config.className,
20 | comment: 'DO NOT EDIT DIRECTLY!\n Generated by gulp/tasks/iconFont.js\n from ' + config.template
21 | }
22 | }))
23 | .pipe(rename(config.sassOutputName))
24 | .pipe(gulp.dest(config.sassDest));
25 | };
26 |
--------------------------------------------------------------------------------
/view/gulp/tasks/iconFont/index.js:
--------------------------------------------------------------------------------
1 | var gulp = require('gulp');
2 | var iconfont = require('gulp-iconfont');
3 | var config = require('../../config').iconFonts;
4 | var generateIconSass = require('./generateIconSass');
5 |
6 | gulp.task('iconFont', function() {
7 | return gulp.src(config.src)
8 | .pipe(iconfont(config.options))
9 | .on('codepoints', generateIconSass)
10 | .pipe(gulp.dest(config.dest));
11 | });
12 |
--------------------------------------------------------------------------------
/view/gulp/tasks/images.js:
--------------------------------------------------------------------------------
1 | var changed = require('gulp-changed');
2 | var gulp = require('gulp');
3 | var imagemin = require('gulp-imagemin');
4 | var config = require('../config').images;
5 | var browserSync = require('browser-sync');
6 |
7 | gulp.task('images', function() {
8 | return gulp.src(config.src)
9 | .pipe(changed(config.dest)) // Ignore unchanged files
10 | .pipe(imagemin()) // Optimize
11 | .pipe(gulp.dest(config.dest))
12 | .pipe(browserSync.reload({stream:true}));
13 | });
14 |
--------------------------------------------------------------------------------
/view/gulp/tasks/inline.js:
--------------------------------------------------------------------------------
1 | var gulp = require('gulp');
2 | var config = require('../config').production;
3 | var inline = require('gulp-inline-source');
4 | var size = require('gulp-filesize');
5 |
6 | gulp.task('inline', ['markup', 'images', 'iconFont', 'minifyCss', 'replace-pre'], function() {
7 | var options = {
8 | 'compress' : false
9 | };
10 |
11 | return gulp.src(config.htmlSrc)
12 | .pipe(inline(options))
13 | .pipe(gulp.dest(config.dest))
14 | .pipe(size());
15 | });
16 |
--------------------------------------------------------------------------------
/view/gulp/tasks/karma.js:
--------------------------------------------------------------------------------
1 | var gulp = require('gulp');
2 | var karma = require('karma');
3 |
4 | var karmaTask = function(done) {
5 | karma.server.start({
6 | configFile: process.cwd() + '/karma.conf.js',
7 | singleRun: true
8 | }, done);
9 | };
10 |
11 | gulp.task('karma', karmaTask);
12 |
13 | module.exports = karmaTask;
14 |
--------------------------------------------------------------------------------
/view/gulp/tasks/markup.js:
--------------------------------------------------------------------------------
1 | var gulp = require('gulp');
2 | var config = require('../config').markup;
3 | var browserSync = require('browser-sync');
4 |
5 | gulp.task('markup', function() {
6 | return gulp.src(config.src)
7 | .pipe(gulp.dest(config.dest))
8 | .pipe(browserSync.reload({stream:true}));
9 | });
10 |
--------------------------------------------------------------------------------
/view/gulp/tasks/minifyCss.js:
--------------------------------------------------------------------------------
1 | var gulp = require('gulp');
2 | var config = require('../config').production;
3 | var minifyCSS = require('gulp-minify-css');
4 | var size = require('gulp-filesize');
5 |
6 | gulp.task('minifyCss', ['sass'], function() {
7 | return gulp.src(config.cssSrc)
8 | .pipe(minifyCSS({keepBreaks:true}))
9 | .pipe(gulp.dest(config.dest))
10 | .pipe(size());
11 | });
--------------------------------------------------------------------------------
/view/gulp/tasks/production.js:
--------------------------------------------------------------------------------
1 | var gulp = require('gulp');
2 |
3 | // Run this to compress all the things!
4 | gulp.task('production', ['replace-post']);
5 |
--------------------------------------------------------------------------------
/view/gulp/tasks/removedep.js:
--------------------------------------------------------------------------------
1 | var gulp = require('gulp');
2 | var config = require('../config').production;
3 | var size = require('gulp-filesize');
4 | var replace = require('gulp-html-replace');
5 |
6 | gulp.task('removedep', ['replace-post'], function() {
7 | return gulp.src(config.htmlSrc)
8 | .pipe(replace({bootstrap: ''}))
9 | .pipe(gulp.dest(config.dest))
10 | .pipe(size());
11 | });
12 |
--------------------------------------------------------------------------------
/view/gulp/tasks/replace.js:
--------------------------------------------------------------------------------
1 | var gulp = require('gulp');
2 | var config = require('../config').production;
3 | var size = require('gulp-filesize');
4 | var replace = require('gulp-replace');
5 |
6 | gulp.task('replace-pre', ['browserify'], function() {
7 | return gulp.src(config.jsSrc)
8 | .pipe(replace('//replace-series', "var series = '$#series'"))
9 | .pipe(replace('//replace-options', "var options = '$#options'"))
10 | .pipe(replace('//replace-save', "var save = '$#save'"))
11 | .pipe(replace('//replace-url', "var url = '$#url'"))
12 | .pipe(replace('//replace-highstock', "var useHighStock = '$#highstock'"))
13 | .pipe(replace('//replace-path', "var path = '$#path'"))
14 | .pipe(replace('//replace-height', "var height = '$#height'"))
15 | .pipe(replace('//replace-width', "var width = '$#width'"))
16 | .pipe(replace('//replace-settings', "var settingsFile = '$#settingsFile'"))
17 | .pipe(gulp.dest(config.dest))
18 | .pipe(size());
19 | });
20 |
21 | gulp.task('replace-post', ['inline'], function() {
22 | return gulp.src(config.htmlSrc)
23 | .pipe(replace("'$#series'", "$#series"))
24 | .pipe(replace("'$#options'", "$#options"))
25 | .pipe(replace("'$#highstock'", "$#highstock"))
26 | .pipe(replace("'$#save'", "$#save"))
27 | .pipe(replace("'$#height'", "$#height"))
28 | .pipe(replace("'$#width'", "$#width"))
29 | .pipe(replace("'$#url'", "$#url"))
30 | .pipe(replace("'$#path'", "$#path"))
31 | .pipe(replace("'$#settingsFile'", "$#settingsFile"))
32 | .pipe(gulp.dest(config.dest))
33 | .pipe(size());
34 | });
35 |
--------------------------------------------------------------------------------
/view/gulp/tasks/sass.js:
--------------------------------------------------------------------------------
1 | var gulp = require('gulp');
2 | var browserSync = require('browser-sync');
3 | var sass = require('gulp-sass');
4 | var sourcemaps = require('gulp-sourcemaps');
5 | var handleErrors = require('../util/handleErrors');
6 | var config = require('../config').sass;
7 | var autoprefixer = require('gulp-autoprefixer');
8 |
9 | gulp.task('sass', function () {
10 | return gulp.src(config.src)
11 | .pipe(sourcemaps.init())
12 | .pipe(sass(config.settings))
13 | .on('error', handleErrors)
14 | .pipe(sourcemaps.write())
15 | .pipe(autoprefixer({ browsers: ['last 2 version'] }))
16 | .pipe(gulp.dest(config.dest))
17 | .pipe(browserSync.reload({stream:true}));
18 | });
19 |
--------------------------------------------------------------------------------
/view/gulp/tasks/test.js:
--------------------------------------------------------------------------------
1 | var gulp = require('gulp');
2 |
3 | // Run this to compress all the things!
4 | gulp.task('production', ['inline']);
5 |
--------------------------------------------------------------------------------
/view/gulp/tasks/uglifyJs.js:
--------------------------------------------------------------------------------
1 | var gulp = require('gulp');
2 | var config = require('../config').production;
3 | var size = require('gulp-filesize');
4 | var uglify = require('gulp-uglify');
5 |
6 | gulp.task('uglifyJs', ['browserify', 'replace'], function() {
7 | return gulp.src(config.jsSrc)
8 | .pipe(uglify())
9 | .pipe(gulp.dest(config.dest))
10 | .pipe(size());
11 | });
12 |
--------------------------------------------------------------------------------
/view/gulp/tasks/watch.js:
--------------------------------------------------------------------------------
1 | /* Notes:
2 | - gulp/tasks/browserify.js handles js recompiling with watchify
3 | - gulp/tasks/browserSync.js watches and reloads compiled files
4 | */
5 |
6 | var gulp = require('gulp');
7 | var config = require('../config');
8 |
9 | gulp.task('watch', ['watchify','browserSync'], function() {
10 | gulp.watch(config.sass.src, ['sass']);
11 | gulp.watch(config.images.src, ['images']);
12 | gulp.watch(config.markup.src, ['markup']);
13 | // Watchify will watch and recompile our JS, so no need to gulp.watch it
14 | });
15 |
--------------------------------------------------------------------------------
/view/gulp/tasks/watchify.js:
--------------------------------------------------------------------------------
1 | var gulp = require('gulp');
2 | var browserifyTask = require('./browserify');
3 |
4 | gulp.task('watchify', function() {
5 | // Start browserify task with devMode === true
6 | return browserifyTask(true);
7 | });
8 |
--------------------------------------------------------------------------------
/view/gulp/util/bundleLogger.js:
--------------------------------------------------------------------------------
1 | /* bundleLogger
2 | ------------
3 | Provides gulp style logs to the bundle method in browserify.js
4 | */
5 |
6 | var gutil = require('gulp-util');
7 | var prettyHrtime = require('pretty-hrtime');
8 | var startTime;
9 |
10 | module.exports = {
11 | start: function(filepath) {
12 | startTime = process.hrtime();
13 | gutil.log('Bundling', gutil.colors.green(filepath) + '...');
14 | },
15 |
16 | watch: function(bundleName) {
17 | gutil.log('Watching files required by', gutil.colors.yellow(bundleName));
18 | },
19 |
20 | end: function(filepath) {
21 | var taskTime = process.hrtime(startTime);
22 | var prettyTime = prettyHrtime(taskTime);
23 | gutil.log('Bundled', gutil.colors.green(filepath), 'in', gutil.colors.magenta(prettyTime));
24 | }
25 | };
26 |
--------------------------------------------------------------------------------
/view/gulp/util/handleErrors.js:
--------------------------------------------------------------------------------
1 | var notify = require("gulp-notify");
2 |
3 | module.exports = function() {
4 |
5 | var args = Array.prototype.slice.call(arguments);
6 |
7 | // Send error to notification center with gulp-notify
8 | notify.onError({
9 | title: "Compile Error",
10 | message: "<%= error %>"
11 | }).apply(this, args);
12 |
13 | // Keep gulp from hanging on this task
14 | this.emit('end');
15 | };
--------------------------------------------------------------------------------
/view/gulpfile.js:
--------------------------------------------------------------------------------
1 | /*
2 | gulpfile.js
3 | ===========
4 | Rather than manage one giant configuration file responsible
5 | for creating multiple tasks, each task has been broken out into
6 | its own file in gulp/tasks. Any files in that directory get
7 | automatically required below.
8 |
9 | To add a new task, simply add a new task file that directory.
10 | gulp/tasks/default.js specifies the default set of tasks to run
11 | when you run `gulp`.
12 | */
13 |
14 | var requireDir = require('require-dir');
15 |
16 | // Require all tasks in gulp/tasks, including subfolders
17 | requireDir('./gulp/tasks', { recurse: true });
18 |
--------------------------------------------------------------------------------
/view/karma.conf.js:
--------------------------------------------------------------------------------
1 | // Karma configuration
2 | // Generated on Fri Jan 23 2015 17:22:58 GMT-0500 (EST)
3 |
4 | module.exports = function(config) {
5 | config.set({
6 |
7 | // base path that will be used to resolve all patterns (eg. files, exclude)
8 | basePath: '',
9 |
10 | // frameworks to use
11 | // available frameworks: https://npmjs.org/browse/keyword/karma-adapter
12 | frameworks: ['mocha', 'sinon-chai', 'browserify'],
13 |
14 | // list of files / patterns to load in the browser
15 | files: [
16 | 'src/javascript/**/__tests__/*'
17 | ],
18 |
19 | // list of files to exclude
20 | exclude: [
21 | ],
22 |
23 | // preprocess matching files before serving them to the browser
24 | // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
25 | preprocessors: {
26 | 'src/javascript/**/__tests__/*': ['browserify']
27 | },
28 |
29 | browserify: {
30 | debug: true,
31 | extensions: ['.js', '.coffee', '.hbs']
32 | },
33 |
34 | // test results reporter to use
35 | // possible values: 'dots', 'progress'
36 | // available reporters: https://npmjs.org/browse/keyword/karma-reporter
37 | reporters: ['nyan'],
38 |
39 | // web server port
40 | port: 9876,
41 |
42 | // enable / disable colors in the output (reporters and logs)
43 | colors: true,
44 |
45 | // level of logging
46 | // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
47 | logLevel: config.LOG_INFO,
48 |
49 | // enable / disable watching file and executing tests whenever any file changes
50 | autoWatch: true,
51 |
52 | // start these browsers
53 | // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
54 | browsers: ['Chrome'],
55 |
56 | // Continuous Integration mode
57 | // if true, Karma captures browsers, runs the tests and exits
58 | singleRun: false,
59 |
60 | // Helps to address an issue on TravisCI where activity can time out
61 | browserNoActivityTimeout: 30000
62 |
63 | });
64 | };
65 |
--------------------------------------------------------------------------------
/view/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "gulp-starter",
3 | "version": "0.1.1",
4 | "description": "Gulp starter with common tasks and scenarios",
5 | "repository": {
6 | "type": "git",
7 | "url": "git://github.com/greypants/gulp-starter.git"
8 | },
9 | "//": [
10 | "The following 'underscore' example demonstrates exposing a module included ",
11 | "by another module. If you were to npm install underscore separately and ",
12 | "require('underscore'), you'd end up with two copies in your bundle. The one",
13 | "you installed, and the one that shipped with another package (backbone in ",
14 | "this example). This is an edge case and should rarely happen.",
15 | "",
16 | "The 'plugin' example makes that file requireable with `require('plugin')`,",
17 | "and available to browserify-shim as 'plugin' on line 30."
18 | ],
19 | "browserify": {
20 | "transform": [
21 | "browserify-shim",
22 | "coffeeify",
23 | "hbsfy"
24 | ]
25 | },
26 | "browserify-shim": {
27 | "plugin": {
28 | "exports": "plugin",
29 | "depends": [
30 | "jquery:$"
31 | ]
32 | },
33 | "bootstrap": {
34 | "depends": [
35 | "jquery:jQuery"
36 | ]
37 | }
38 | },
39 | "devDependencies": {
40 | "browser-sync": "~2.2.2",
41 | "browserify": "^9.0.3",
42 | "browserify-shim": "^3.8.2",
43 | "coffeeify": "~1.0.0",
44 | "gulp": "^3.8.11",
45 | "gulp-autoprefixer": "^2.1.0",
46 | "gulp-changed": "^1.1.1",
47 | "gulp-filesize": "0.0.6",
48 | "gulp-html-replace": "^1.5.0",
49 | "gulp-iconfont": "^1.0.0",
50 | "gulp-imagemin": "^2.2.1",
51 | "gulp-minify-css": "~0.5.1",
52 | "gulp-notify": "^2.2.0",
53 | "gulp-rename": "^1.2.0",
54 | "gulp-sass": "~1.3.3",
55 | "gulp-sourcemaps": "^1.5.0",
56 | "gulp-swig": "^0.7.4",
57 | "gulp-uglify": "^1.1.0",
58 | "gulp-util": "^3.0.4",
59 | "handlebars": "^3.0.0",
60 | "hbsfy": "~2.2.1",
61 | "karma": "^0.12.31",
62 | "karma-browserify": "^4.0.0",
63 | "karma-chrome-launcher": "^0.1.7",
64 | "karma-coffee-preprocessor": "^0.2.1",
65 | "karma-mocha": "^0.1.10",
66 | "karma-nyan-reporter": "0.0.51",
67 | "karma-sinon-chai": "^0.3.0",
68 | "lodash": "^3.3.1",
69 | "merge-stream": "^0.1.7",
70 | "pretty-hrtime": "~1.0.0",
71 | "require-dir": "^0.1.0",
72 | "vinyl-source-stream": "~1.0.0",
73 | "watchify": "^2.4.0"
74 | },
75 | "dependencies": {
76 | "backbone": "~1.1.2",
77 | "bootstrap": "^3.3.4",
78 | "gulp-inline-source": "^1.3.0",
79 | "gulp-replace": "^0.5.3",
80 | "highstock-browserify": "^1.0.1",
81 | "jquery": "^2.1.4",
82 | "jsoneditor": "^4.2.0",
83 | "selectize": "^0.12.1",
84 | "underscore": "^1.8.3"
85 | }
86 | }
87 |
--------------------------------------------------------------------------------
/view/src/htdocs/index-async.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
Adjust chart settings
23 |
24 |
27 |
28 |
29 |
32 |
33 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
--------------------------------------------------------------------------------
/view/src/htdocs/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
Adjust chart settings
19 |
20 |
23 |
24 |
25 |
28 |
29 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
--------------------------------------------------------------------------------
/view/src/icons/uE001-facebook.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
7 |
--------------------------------------------------------------------------------
/view/src/icons/uE002-linkedin.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
7 |
--------------------------------------------------------------------------------
/view/src/icons/uE003-pinterest.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
7 |
--------------------------------------------------------------------------------
/view/src/icons/uE004-twitter.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
7 |
--------------------------------------------------------------------------------
/view/src/images/gulp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/arnoutaertgeerts/python-highcharts/6bd433cf53e851e9697639e88fcec453b7b63076/view/src/images/gulp.png
--------------------------------------------------------------------------------
/view/src/images/jsoneditor-icons.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/arnoutaertgeerts/python-highcharts/6bd433cf53e851e9697639e88fcec453b7b63076/view/src/images/jsoneditor-icons.png
--------------------------------------------------------------------------------
/view/src/javascript/__tests__/page-test.coffee:
--------------------------------------------------------------------------------
1 | require '../page'
2 | $ = require 'jquery'
3 |
4 | describe 'page.js', ->
5 | it 'contains a love letter', ->
6 | loveLetter = $('.love-letter').length
7 | loveLetter.should.equal 1
8 |
--------------------------------------------------------------------------------
/view/src/javascript/async.js:
--------------------------------------------------------------------------------
1 |
2 | requirejs([
3 | 'jquery',
4 | 'selectize',
5 | 'jsoneditor',
6 | 'highstock',
7 | 'export'
8 | ], function($, selectize, JSONEditor) {
9 |
10 | function guid() {
11 | function s4() {
12 | return Math.floor((1 + Math.random()) * 0x10000)
13 | .toString(16)
14 | .substring(1);
15 | }
16 | return s4() + s4() + '-' + s4() + '-' + s4() + '-' +
17 | s4() + '-' + s4() + s4() + s4();
18 | }
19 |
20 | var id = guid();
21 | plot(id);
22 |
23 | function plot(id) {
24 | var options = {};
25 | //replace-options
26 | var useHighStock = true;
27 | //replace-highstock
28 | var save = 'app/chart.svg';
29 | //replace-save
30 | var url = 'http://127.0.0.1:37759';
31 | //replace-url
32 | var path = 'small';
33 | //replace-path
34 | var settingsFile = 'settings';
35 | //replace-settings
36 |
37 | //Create different containers for the charts
38 | var chartContainer = document.getElementById("chart-container");
39 | chartContainer.id = "chart-container" + id;
40 | chartContainer.style.height = options.height.toString() + 'px';
41 |
42 | var selectorContainer = $("#variable-selector");
43 | selectorContainer.attr('id', "variable-selector" + id);
44 |
45 | var settings = $("#settings-collapse");
46 | settings.attr('id', "settings-collapse" + id);
47 |
48 | var button = $("#settings-button");
49 | button.attr('id', "settings-button" + id);
50 |
51 | var saveButton = $("#save-settings");
52 | saveButton.attr('id', "save-settings" + id);
53 |
54 | var optionsInput = $("#options-input");
55 | optionsInput.attr('id', "options-input" + id);
56 | optionsInput.val(settingsFile);
57 |
58 | var optionsButton = $("#options-button");
59 | optionsButton.attr('id', "options-button" + id);
60 |
61 | var updateButton = $("#update-button");
62 | updateButton.attr('id', "update-button" + id);
63 |
64 | var liveToggle = $("#live-toggle");
65 | liveToggle.attr('id', "live-toggle" + id);
66 |
67 | // create the editor
68 | var editorContainer = document.getElementById("jsoneditor");
69 | editorContainer.id = "jsoneditor" + id;
70 | var editor = new JSONEditor(editorContainer);
71 |
72 | updateButton.on('click', update);
73 | button.on('click', showSettings);
74 | saveButton.on('click', applyOptions);
75 | optionsButton.on('click', saveOptions);
76 |
77 | function applyOptions() {
78 | var newOptions = editor.get();
79 | setOptions(newOptions);
80 | settings.collapse('hide');
81 | }
82 |
83 | function saveOptions(event) {
84 | event.preventDefault();
85 |
86 | applyOptions();
87 |
88 | var options = chart.options;
89 | delete options.exporting;
90 |
91 | var name = optionsInput.val() ? optionsInput.val() + '.json' : 'settings.json';
92 |
93 | options['settingsFile'] = name;
94 |
95 | $.ajax({
96 | type: "POST",
97 | url: url,
98 | data: JSON.stringify({
99 | options: options,
100 | name: name
101 | })
102 | });
103 | }
104 |
105 | function showSettings() {
106 | settings.collapse('toggle');
107 | }
108 |
109 | //Choose a chart type
110 | var ChartType = useHighStock ? Highcharts.StockChart : Highcharts.Chart;
111 |
112 | //Default highchart colors
113 | var colors = ['#7cb5ec', '#434348', '#90ed7d', '#f7a35c', '#8085e9',
114 | '#f15c80', '#e4d354', '#2b908f', '#f45b5b', '#91e8e1'];
115 | var colorIndex = 0;
116 |
117 | var keys = [];
118 |
119 | //Set initial chart options
120 | var chartOptions;
121 | if (typeof options.chart === "undefined") {
122 | chartOptions = {renderTo: chartContainer.id};
123 | } else {
124 | chartOptions = $.extend(options["chart"], {renderTo: chartContainer.id});
125 | }
126 |
127 | //Initial rendered series
128 | var renderedSeries = [];
129 | var cachedSeries = [];
130 | options = $.extend(options, {chart: chartOptions}, {series: renderedSeries});
131 | var chart = new ChartType(options);
132 | editor.set(chart.options);
133 |
134 | selectorContainer.selectize({
135 | plugins: ['remove_button', 'restore_on_backspace'],
136 | delimiter: ',',
137 | options: [],
138 | onItemAdd: function (key) {
139 | console.log('series added');
140 | addSeries(key).done(function() {
141 | newChart(chart.options, renderedSeries)
142 | });
143 | },
144 | onItemRemove: function (key) {
145 | console.log('series removed');
146 | deleteSeries(key);
147 | newChart(chart.options, renderedSeries);
148 | },
149 | onInitialize: update
150 | });
151 |
152 | var selector = selectorContainer[0].selectize;
153 |
154 | //Check for new keys
155 | function update() {
156 | $.get(path + '/keys.json').done(function (data) {
157 | //Get the new keys
158 | var oldKeys = keys.map(function (element) {
159 | return element.name
160 | });
161 |
162 | //Get the new key objects
163 | var newKeys = data.filter(function (element) {
164 | return oldKeys.indexOf(element.name) == -1
165 | });
166 |
167 | //Set the keys equal to all keys and update the selector
168 | keys = data;
169 |
170 | var showNewKeys = newKeys.filter(function(obj) {
171 | return obj.display == true;
172 | });
173 |
174 | selector.addOption(keys);
175 |
176 | $.each(showNewKeys, function(index, obj) {
177 | selector.addItem(obj.value)
178 | })
179 | })
180 | }
181 |
182 | function setOptions(options) {
183 | //Prevent export from breaking
184 | delete options.exporting;
185 | options['exporting'] = {scale: options.scale};
186 |
187 | chartContainer.style.height = options.height.toString() + 'px';
188 |
189 | if (options.width != 'auto') {
190 | chartContainer.style.width = options.width.toString() + 'px';
191 | }
192 |
193 | newChart(options, renderedSeries);
194 |
195 | }
196 |
197 | function findSeries(series, key) {
198 | return series.findIndex(function (obj) {
199 | return obj.name == key;
200 | })
201 | }
202 |
203 | function newChart(options, series) {
204 | //Disable animation
205 | var newOptions = $.extend(options, {series: series});
206 | newOptions.plotOptions['series'] = {animation: false};
207 |
208 | //Get zoom
209 | var xExtremes = chart.xAxis[0].getExtremes();
210 |
211 | //Re-plot the chart
212 | chart.destroy();
213 | chart = new ChartType(newOptions);
214 |
215 | //Reset the zoom
216 | chart.xAxis[0].setExtremes(xExtremes.min, xExtremes.max, false, false);
217 |
218 | //Re-draw chart
219 | chart.redraw();
220 | }
221 |
222 | function addSeries(key) {
223 |
224 | var index = findSeries(cachedSeries, key);
225 | if (index > -1) {
226 | var newSeries = cachedSeries[index];
227 | renderedSeries.push(newSeries);
228 | return $.when()
229 | } else {
230 | return $.get(path + '/' + key + '.json').done(function (data) {
231 | if (key.color) {
232 | data['color'] = key.color
233 | } else {
234 | data['color'] = colors[colorIndex % 10];
235 | colorIndex = colorIndex + 1;
236 | }
237 |
238 | renderedSeries.push(data);
239 | cachedSeries.push(data);
240 | return null;
241 | });
242 | }
243 | }
244 |
245 | function deleteSeries(key) {
246 | var index = findSeries(renderedSeries, key);
247 | renderedSeries.splice(index, 1)
248 | }
249 |
250 | function saveSVG(url, name) {
251 | $.ajax({
252 | type: "POST",
253 | url: url,
254 | data: JSON.stringify({
255 | svg: chart.getSVG(),
256 | name: name
257 | })
258 | });
259 | }
260 | }
261 | });
262 |
--------------------------------------------------------------------------------
/view/src/javascript/lib.js:
--------------------------------------------------------------------------------
1 | //findIndex polyfill
2 | if (!Array.prototype.findIndex) {
3 | Array.prototype.findIndex = function(predicate) {
4 | if (this == null) {
5 | throw new TypeError('Array.prototype.findIndex called on null or undefined');
6 | }
7 | if (typeof predicate !== 'function') {
8 | throw new TypeError('predicate must be a function');
9 | }
10 | var list = Object(this);
11 | var length = list.length >>> 0;
12 | var thisArg = arguments[1];
13 | var value;
14 |
15 | for (var i = 0; i < length; i++) {
16 | value = list[i];
17 | if (predicate.call(thisArg, value, i, list)) {
18 | return i;
19 | }
20 | }
21 | return -1;
22 | };
23 | }
24 |
25 | if (!Array.prototype.filter) {
26 | Array.prototype.filter = function(fun/*, thisArg*/) {
27 | 'use strict';
28 |
29 | if (this === void 0 || this === null) {
30 | throw new TypeError();
31 | }
32 |
33 | var t = Object(this);
34 | var len = t.length >>> 0;
35 | if (typeof fun !== 'function') {
36 | throw new TypeError();
37 | }
38 |
39 | var res = [];
40 | var thisArg = arguments.length >= 2 ? arguments[1] : void 0;
41 | for (var i = 0; i < len; i++) {
42 | if (i in t) {
43 | var val = t[i];
44 |
45 | // NOTE: Technically this should Object.defineProperty at
46 | // the next index, as push can be affected by
47 | // properties on Object.prototype and Array.prototype.
48 | // But that method's new, and collisions should be
49 | // rare, so use the more-compatible alternative.
50 | if (fun.call(thisArg, val, i, t)) {
51 | res.push(val);
52 | }
53 | }
54 | }
55 |
56 | return res;
57 | };
58 | }
59 |
60 | function guid() {
61 | function s4() {
62 | return Math.floor((1 + Math.random()) * 0x10000)
63 | .toString(16)
64 | .substring(1);
65 | }
66 | return s4() + s4() + '-' + s4() + '-' + s4() + '-' +
67 | s4() + '-' + s4() + s4() + s4();
68 | }
69 |
70 | Array.prototype.equals = function (array) {
71 | // if the other array is a false value, return
72 | if (!array)
73 | return false;
74 |
75 | // compare lengths - can save a lot of time
76 | if (this.length != array.length)
77 | return false;
78 |
79 | for (var i = 0, l = this.length; i < l; i++) {
80 | // Check if we have nested arrays
81 | if (this[i] instanceof Array && array[i] instanceof Array) {
82 | // recurse into the nested arrays
83 | if (!this[i].equals(array[i]))
84 | return false;
85 | }
86 | else if (this[i] != array[i]) {
87 | // Warning - two different object instances will never be equal: {x:20} != {x:20}
88 | return false;
89 | }
90 | }
91 | return true;
92 | };
93 |
--------------------------------------------------------------------------------
/view/src/javascript/page.js:
--------------------------------------------------------------------------------
1 | //Count the number of charts on the page
2 | if (window.counter == undefined) {
3 | window.counter = 0;
4 | } else {
5 | window.counter++;
6 | }
7 |
8 | requirejs([
9 | 'jquery',
10 | 'selectize',
11 | 'jsoneditor',
12 | 'highstock',
13 | 'export',
14 | 'more'
15 | ], function ($, selectize, JSONEditor) {
16 |
17 | function guid() {
18 | function s4() {
19 | return Math.floor((1 + Math.random()) * 0x10000)
20 | .toString(16)
21 | .substring(1);
22 | }
23 |
24 | return s4() + s4() + '-' + s4() + '-' + s4() + '-' +
25 | s4() + '-' + s4() + s4() + s4();
26 | }
27 |
28 | var id = guid();
29 | plot(id);
30 |
31 | function plot(id) {
32 | var series = [
33 | {data: [1, 2, 4, 9], name: "temperature 1", display: true, color: '#2b908f'},
34 | {data: [9, 4, 2, 1], name: "temperature 2", display: true},
35 | {data: [0, 3, 5, 6], name: "temperature 3", display: false}
36 | ];
37 | //replace-series
38 | var options = {};
39 | //replace-options
40 | var useHighStock = false;
41 | //replace-highstock
42 | var save = 'app/chart.svg';
43 | //replace-save
44 | var url = 'http://127.0.0.1:65079';
45 | //replace-url
46 | var settingsFile = 'settings';
47 | //replace-settings
48 | var scale = options.scale;
49 |
50 | //Create different containers for the charts
51 | var chartContainer = document.getElementById("chart-container");
52 | chartContainer.id = "chart-container" + id;
53 | chartContainer.style.height = options.height.toString() + 'px';
54 |
55 | if (options.width != 'auto') {
56 | chartContainer.style.width = options.width.toString() + 'px';
57 | }
58 |
59 | var selector = $("#variable-selector");
60 | selector.attr('id', "variable-selector" + id);
61 |
62 | var settings = $("#settings-collapse");
63 | settings.attr('id', "settings-collapse" + id);
64 |
65 | var button = $("#settings-button");
66 | button.attr('id', "settings-button" + id);
67 |
68 | var saveButton = $("#save-settings");
69 | saveButton.attr('id', "save-settings" + id);
70 |
71 | var optionsInput = $("#options-input");
72 | optionsInput.attr('id', "options-input" + id);
73 | optionsInput.val(settingsFile);
74 |
75 | var optionsButton = $("#options-button");
76 | optionsButton.attr('id', "options-button" + id);
77 |
78 | // create the editor
79 | var editorContainer = document.getElementById("jsoneditor");
80 | editorContainer.id = "jsoneditor" + id;
81 | var editor = new JSONEditor(editorContainer);
82 |
83 | button.on('click', showSettings);
84 | saveButton.on('click', applyOptions);
85 | optionsButton.on('click', saveOptions);
86 |
87 | function applyOptions() {
88 | var newOptions = editor.get();
89 | setOptions(newOptions);
90 | settings.collapse('hide');
91 | }
92 |
93 | function saveOptions(event) {
94 | event.preventDefault();
95 |
96 | applyOptions();
97 |
98 | var options = chart.options;
99 | delete options.exporting;
100 |
101 | var name = optionsInput.val() ? optionsInput.val() + '.json' : 'settings.json';
102 |
103 | options['settingsFile'] = name;
104 |
105 | $.ajax({
106 | type: "POST",
107 | url: url,
108 | data: JSON.stringify({
109 | options: options,
110 | name: name
111 | })
112 | });
113 | }
114 |
115 | function showSettings() {
116 | settings.collapse('toggle');
117 | }
118 |
119 | //Choose a chart type
120 | var ChartType = useHighStock ? Highcharts.StockChart : Highcharts.Chart;
121 |
122 | //Default highchart colors
123 | var colors = ['#7cb5ec', '#434348', '#90ed7d', '#f7a35c', '#8085e9',
124 | '#f15c80', '#e4d354', '#2b908f', '#f45b5b', '#91e8e1'];
125 |
126 | series.map(function (serie, index) {
127 | if (!serie.color) {
128 | serie['color'] = colors[index % 10];
129 | }
130 |
131 | return serie;
132 | });
133 |
134 | //Get all the keys
135 | var keys = [];
136 | var initialKeys = [];
137 | $.each(series, function (index, serie) {
138 | keys.push({
139 | display: serie.display,
140 | value: serie.name,
141 | text: serie.name
142 | });
143 |
144 | if (serie.display) {
145 | initialKeys.push(serie.name)
146 | }
147 | });
148 |
149 | selector.selectize({
150 | plugins: ['remove_button', 'restore_on_backspace'],
151 | delimiter: ',',
152 | options: keys,
153 | items: initialKeys,
154 | onItemAdd: function (key) {
155 | console.log('series added');
156 | addSeries(key);
157 | newChart(chart.options, renderedSeries);
158 | },
159 | onItemRemove: function (key) {
160 | console.log('series removed');
161 | deleteSeries(key);
162 | newChart(chart.options, renderedSeries);
163 | }
164 | });
165 |
166 | //Set initial chart options
167 | var chartOptions;
168 | if (typeof options.chart === "undefined") {
169 | chartOptions = {renderTo: chartContainer.id};
170 | } else {
171 | chartOptions = $.extend(options["chart"], {renderTo: chartContainer.id});
172 | }
173 |
174 | //Initial rendered series
175 | var renderedSeries = [];
176 | options = $.extend(options, {chart: chartOptions}, {series: renderedSeries});
177 | var chart = new ChartType(options);
178 |
179 | $.each(initialKeys, function (index, key) {
180 | addSeries(key);
181 | });
182 |
183 | newChart(chart.options, renderedSeries);
184 | editor.set(chart.options);
185 |
186 | if (save) {
187 | saveSVG(url, save)
188 | }
189 |
190 | function setOptions(options) {
191 | //Prevent export from breaking
192 | delete options.exporting;
193 | options['exporting'] = {scale: options.scale};
194 |
195 | chartContainer.style.height = options.height.toString() + 'px';
196 |
197 | if (options.width != 'auto') {
198 | chartContainer.style.width = options.width.toString() + 'px';
199 | }
200 |
201 | newChart(options, renderedSeries);
202 |
203 | }
204 |
205 | function findSeries(series, key) {
206 | return series.findIndex(function (obj) {
207 | return obj.name == key;
208 | })
209 | }
210 |
211 | function newChart(options, series) {
212 | //Disable animation
213 | var newOptions = $.extend(options, {series: series});
214 | newOptions.plotOptions['series'] = {animation: false};
215 |
216 | //Get zoom
217 | var xExtremes = chart.xAxis[0].getExtremes();
218 |
219 | //Re-plot the chart
220 | chart.destroy();
221 | chart = new ChartType(newOptions);
222 |
223 | //Reset the zoom
224 | chart.xAxis[0].setExtremes(xExtremes.min, xExtremes.max, false, false);
225 |
226 | //Re-draw chart
227 | chart.redraw();
228 | }
229 |
230 | function addSeries(key) {
231 | var index = findSeries(series, key);
232 | var newSeries = series[index];
233 | renderedSeries.push(newSeries)
234 | }
235 |
236 | function deleteSeries(key) {
237 | var index = findSeries(renderedSeries, key);
238 | renderedSeries.splice(index, 1)
239 | }
240 |
241 | function saveSVG(url, name) {
242 | $.ajax({
243 | type: "POST",
244 | url: url,
245 | data: JSON.stringify({
246 | svg: chart.getSVG(),
247 | name: name
248 | })
249 | });
250 | }
251 |
252 | console.log('loaded!', Date());
253 | }
254 |
255 | });
256 |
--------------------------------------------------------------------------------
/view/src/javascript/require.js:
--------------------------------------------------------------------------------
1 |
2 |
3 | requirejs.config({
4 | "paths": {
5 | "highstock": "https://cdnjs.cloudflare.com/ajax/libs/highstock/2.1.5/highstock",
6 | "export": "https://cdnjs.cloudflare.com/ajax/libs/highstock/2.1.5/modules/exporting",
7 | "more": "https://cdnjs.cloudflare.com/ajax/libs/highstock/2.1.7/highcharts-more",
8 | "jsoneditor": "https://cdnjs.cloudflare.com/ajax/libs/jsoneditor/4.2.0/jsoneditor.min",
9 | "selectize": "https://cdnjs.cloudflare.com/ajax/libs/selectize.js/0.12.1/js/standalone/selectize.min",
10 | "jquery": "https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.4/jquery.min"
11 | },
12 | "shim": {
13 | "export": ["highstock"],
14 | "more": ["highstock"]
15 | }
16 | });
17 |
18 | //Define jquery here to use the pre-loaded version
19 | define('jquery', [], function() {
20 | return jQuery;
21 | });
22 |
--------------------------------------------------------------------------------
/view/src/javascript/vendor/jquery-plugin.js:
--------------------------------------------------------------------------------
1 | window.plugin = function() {
2 | $('body').append('This line was generated by a non common-js plugin that depends on jQuery!
');
3 | };
4 |
--------------------------------------------------------------------------------
/view/src/sass/_icons.sass:
--------------------------------------------------------------------------------
1 | // DO NOT EDIT DIRECTLY!
2 | Generated by gulp/tasks/iconFont.js
3 | from ./gulp/tasks/iconFont/template.sass.swig
4 |
5 | @font-face
6 | font-family: Post-Creator-Icons
7 | src: url("fonts/Post-Creator-Icons.eot")
8 | src: url("fonts/Post-Creator-Icons.eot?#iefix") format('embedded-opentype'), url("fonts/Post-Creator-Icons.woff") format('woff'), url("fonts/Post-Creator-Icons.ttf") format('truetype'), url("fonts/Post-Creator-Icons.svg#Post-Creator-Icons") format('svg')
9 | font-weight: normal
10 | font-style: normal
11 |
12 | =icon($content)
13 | &:before
14 | -moz-osx-font-smoothing: grayscale
15 | -webkit-font-smoothing: antialiased
16 | content: $content
17 | font-family: 'Post-Creator-Icons'
18 | font-style: normal
19 | font-variant: normal
20 | font-weight: normal
21 | line-height: 1
22 | speak: none
23 | text-transform: none
24 | @content
25 |
26 | =icon--facebook
27 | +icon("\e001")
28 | @content
29 |
30 | .icon
31 | &.-facebook
32 | +icon--facebook
33 |
34 | =icon--linkedin
35 | +icon("\e002")
36 | @content
37 |
38 | .icon
39 | &.-linkedin
40 | +icon--linkedin
41 |
42 | =icon--pinterest
43 | +icon("\e003")
44 | @content
45 |
46 | .icon
47 | &.-pinterest
48 | +icon--pinterest
49 |
50 | =icon--twitter
51 | +icon("\e004")
52 | @content
53 |
54 | .icon
55 | &.-twitter
56 | +icon--twitter
57 |
58 |
59 |
--------------------------------------------------------------------------------
/view/src/sass/_scss-mixins.scss:
--------------------------------------------------------------------------------
1 | @mixin font-smoothing {
2 | -moz-osx-font-smoothing: grayscale;
3 | -webkit-font-smoothing: antialiased;
4 | }
5 |
--------------------------------------------------------------------------------
/view/src/sass/_typography.sass:
--------------------------------------------------------------------------------
1 | body
2 | +font-smoothing // <- _mixins.scss
3 | color: #555
4 | font-family: sans-serif
5 |
6 | small
7 | font-weight: normal
8 | display: block
9 | font-size: 14px
10 |
11 | code
12 | background-color: lightgrey
13 | border-radius: 3px
14 | font-family: monospace
15 | padding: 0 .5em
16 |
--------------------------------------------------------------------------------
/view/src/sass/app.sass:
--------------------------------------------------------------------------------
1 | @import scss-mixins
2 | @import typography
3 | @import icons
4 |
5 | //@import selectize/selectize.default
6 | //@import jsoneditor/jsoneditor.min
7 |
8 | .social-icons
9 | h4
10 | display: inline-block
11 | margin: 20px 10px 0 0
12 |
13 | .icon
14 | display: inline-block
15 | margin: 0 5px
16 |
17 | body.modal-open
18 | overflow: hidden
19 |
20 | .jsoneditor td.tree, .jsoneditor td, .jsoneditor tr, .jsoneditor table
21 | border: none
22 | margin: 0
23 |
--------------------------------------------------------------------------------
/view/src/sass/jsoneditor/_jsoneditor.min.scss:
--------------------------------------------------------------------------------
1 | .jsoneditor .field,.jsoneditor .readonly,.jsoneditor .value{border:1px solid transparent;min-height:16px;min-width:32px;padding:2px;margin:1px;word-wrap:break-word;float:left}.jsoneditor .field p,.jsoneditor .value p{margin:0}.jsoneditor .value{word-break:break-word}.jsoneditor .readonly{min-width:16px;color:gray}.jsoneditor .empty{border-color:#d3d3d3;border-style:dashed;border-radius:2px}.jsoneditor .field.empty{background-image:url(images/jsoneditor-icons.png);background-position:0 -144px}.jsoneditor .value.empty{background-image:url(images/jsoneditor-icons.png);background-position:-48px -144px}.jsoneditor .value.url{color:green;text-decoration:underline}.jsoneditor a.value.url:focus,.jsoneditor a.value.url:hover{color:red}.jsoneditor .separator{padding:3px 0;vertical-align:top;color:gray}.jsoneditor .field.highlight,.jsoneditor .field[contenteditable=true]:focus,.jsoneditor .field[contenteditable=true]:hover,.jsoneditor .value.highlight,.jsoneditor .value[contenteditable=true]:focus,.jsoneditor .value[contenteditable=true]:hover{background-color:#FFFFAB;border:1px solid #ff0;border-radius:2px}.jsoneditor .field.highlight-active,.jsoneditor .field.highlight-active:focus,.jsoneditor .field.highlight-active:hover,.jsoneditor .value.highlight-active,.jsoneditor .value.highlight-active:focus,.jsoneditor .value.highlight-active:hover{background-color:#fe0;border:1px solid #ffc700;border-radius:2px}.jsoneditor div.tree button{width:24px;height:24px;padding:0;margin:0;border:none;cursor:pointer;background:url(images/jsoneditor-icons.png)}.jsoneditor div.tree button.collapsed{background-position:0 -48px}.jsoneditor div.tree button.expanded{background-position:0 -72px}.jsoneditor div.tree button.contextmenu{background-position:-48px -72px}.jsoneditor div.tree button.contextmenu.selected,.jsoneditor div.tree button.contextmenu:focus,.jsoneditor div.tree button.contextmenu:hover{background-position:-48px -48px}.jsoneditor div.tree :focus{outline:0}.jsoneditor div.tree button:focus{background-color:#f5f5f5;outline:#e5e5e5 solid 1px}.jsoneditor div.tree button.invisible{visibility:hidden;background:0 0}.jsoneditor{color:#1A1A1A;border:1px solid #97B0F8;box-sizing:border-box;width:100%;height:100%;overflow:auto;position:relative;padding:0;line-height:100%}.jsoneditor,.jsoneditor div.outer{-moz-box-sizing:border-box;-webkit-box-sizing:border-box}.jsoneditor div.tree table.tree{border-collapse:collapse;border-spacing:0;width:100%;margin:0}.jsoneditor div.outer{width:100%;height:100%;margin:-35px 0 0;padding:35px 0 0;box-sizing:border-box;overflow:hidden}.jsoneditor div.tree{width:100%;height:100%;position:relative;overflow:auto}.jsoneditor textarea.text{width:100%;height:100%;margin:0;box-sizing:border-box;border:none;background-color:#fff;resize:none}.jsoneditor .menu,.jsoneditor textarea.text{-moz-box-sizing:border-box;-webkit-box-sizing:border-box}.jsoneditor tr.highlight{background-color:#FFFFAB}.jsoneditor div.tree button.dragarea{background:url(images/jsoneditor-icons.png)-72px -72px;cursor:move}.jsoneditor div.tree button.dragarea:focus,.jsoneditor div.tree button.dragarea:hover{background-position:-72px -48px}.jsoneditor td,.jsoneditor th,.jsoneditor tr{padding:0;margin:0}.jsoneditor td,.jsoneditor td.tree{vertical-align:top}.jsoneditor .field,.jsoneditor .value,.jsoneditor td,.jsoneditor textarea,.jsoneditor th{font-family:droid sans mono,monospace,courier new,courier,sans-serif;font-size:10pt;color:#1A1A1A}.jsoneditor-contextmenu{position:absolute;z-index:99999}.jsoneditor-contextmenu ul{position:relative;left:0;top:0;width:124px;background:#fff;border:1px solid #d3d3d3;box-shadow:2px 2px 12px rgba(128,128,128,.3);list-style:none;margin:0;padding:0}.jsoneditor-contextmenu ul li button{padding:0;margin:0;width:124px;height:24px;border:none;cursor:pointer;color:#4d4d4d;background:0 0;line-height:26px;text-align:left}.jsoneditor-contextmenu ul li button::-moz-focus-inner{padding:0;border:0}.jsoneditor-contextmenu ul li button:focus,.jsoneditor-contextmenu ul li button:hover{color:#1a1a1a;background-color:#f5f5f5;outline:0}.jsoneditor-contextmenu ul li button.default{width:92px}.jsoneditor-contextmenu ul li button.expand{float:right;width:32px;height:24px;border-left:1px solid #e5e5e5}.jsoneditor-contextmenu div.icon{float:left;width:24px;height:24px;border:none;padding:0;margin:0;background-image:url(images/jsoneditor-icons.png)}.jsoneditor-contextmenu ul li button div.expand{float:right;width:24px;height:24px;padding:0;margin:0 4px 0 0;background:url(images/jsoneditor-icons.png)0 -72px;opacity:.4}.jsoneditor-contextmenu ul li button.expand:focus div.expand,.jsoneditor-contextmenu ul li button.expand:hover div.expand,.jsoneditor-contextmenu ul li button:focus div.expand,.jsoneditor-contextmenu ul li button:hover div.expand,.jsoneditor-contextmenu ul li.selected div.expand{opacity:1}.jsoneditor-contextmenu .separator{height:0;border-top:1px solid #e5e5e5;padding-top:5px;margin-top:5px}.jsoneditor-contextmenu button.remove>.icon{background-position:-24px -24px}.jsoneditor-contextmenu button.remove:focus>.icon,.jsoneditor-contextmenu button.remove:hover>.icon{background-position:-24px 0}.jsoneditor-contextmenu button.append>.icon{background-position:0 -24px}.jsoneditor-contextmenu button.append:focus>.icon,.jsoneditor-contextmenu button.append:hover>.icon{background-position:0 0}.jsoneditor-contextmenu button.insert>.icon{background-position:0 -24px}.jsoneditor-contextmenu button.insert:focus>.icon,.jsoneditor-contextmenu button.insert:hover>.icon{background-position:0 0}.jsoneditor-contextmenu button.duplicate>.icon{background-position:-48px -24px}.jsoneditor-contextmenu button.duplicate:focus>.icon,.jsoneditor-contextmenu button.duplicate:hover>.icon{background-position:-48px 0}.jsoneditor-contextmenu button.sort-asc>.icon{background-position:-168px -24px}.jsoneditor-contextmenu button.sort-asc:focus>.icon,.jsoneditor-contextmenu button.sort-asc:hover>.icon{background-position:-168px 0}.jsoneditor-contextmenu button.sort-desc>.icon{background-position:-192px -24px}.jsoneditor-contextmenu button.sort-desc:focus>.icon,.jsoneditor-contextmenu button.sort-desc:hover>.icon{background-position:-192px 0}.jsoneditor-contextmenu ul li .selected{background-color:#D5DDF6}.jsoneditor-contextmenu ul li{overflow:hidden}.jsoneditor-contextmenu ul li ul{display:none;position:relative;left:-10px;top:0;border:none;box-shadow:inset 0 0 10px rgba(128,128,128,.5);padding:0 10px;-webkit-transition:all .3s ease-out;-moz-transition:all .3s ease-out;-o-transition:all .3s ease-out;transition:all .3s ease-out}.jsoneditor-contextmenu ul li ul li button{padding-left:24px}.jsoneditor-contextmenu ul li ul li button:focus,.jsoneditor-contextmenu ul li ul li button:hover{background-color:#f5f5f5}.jsoneditor-contextmenu button.type-string>.icon{background-position:-144px -24px}.jsoneditor-contextmenu button.type-string.selected>.icon,.jsoneditor-contextmenu button.type-string:focus>.icon,.jsoneditor-contextmenu button.type-string:hover>.icon{background-position:-144px 0}.jsoneditor-contextmenu button.type-auto>.icon{background-position:-120px -24px}.jsoneditor-contextmenu button.type-auto.selected>.icon,.jsoneditor-contextmenu button.type-auto:focus>.icon,.jsoneditor-contextmenu button.type-auto:hover>.icon{background-position:-120px 0}.jsoneditor-contextmenu button.type-object>.icon{background-position:-72px -24px}.jsoneditor-contextmenu button.type-object.selected>.icon,.jsoneditor-contextmenu button.type-object:focus>.icon,.jsoneditor-contextmenu button.type-object:hover>.icon{background-position:-72px 0}.jsoneditor-contextmenu button.type-array>.icon{background-position:-96px -24px}.jsoneditor-contextmenu button.type-array.selected>.icon,.jsoneditor-contextmenu button.type-array:focus>.icon,.jsoneditor-contextmenu button.type-array:hover>.icon{background-position:-96px 0}.jsoneditor-contextmenu button.type-modes>.icon{background-image:none;width:6px}.jsoneditor .menu{width:100%;height:35px;padding:2px;margin:0;overflow:hidden;box-sizing:border-box;color:#1A1A1A;background-color:#D5DDF6;border-bottom:1px solid #97B0F8}.jsoneditor .menu button{width:26px;height:26px;margin:2px;padding:0;border-radius:2px;border:1px solid #aec0f8;background:url(images/jsoneditor-icons.png)#e3eaf6;color:#4D4D4D;opacity:.8;font-family:arial,sans-serif;font-size:10pt;float:left}.jsoneditor .menu button:hover{background-color:#f0f2f5}.jsoneditor .menu button:active,.jsoneditor .menu button:focus{background-color:#fff}.jsoneditor .menu button:disabled{background-color:#e3eaf6}.jsoneditor .menu button.collapse-all{background-position:0 -96px}.jsoneditor .menu button.expand-all{background-position:0 -120px}.jsoneditor .menu button.undo{background-position:-24px -96px}.jsoneditor .menu button.undo:disabled{background-position:-24px -120px}.jsoneditor .menu button.redo{background-position:-48px -96px}.jsoneditor .menu button.redo:disabled{background-position:-48px -120px}.jsoneditor .menu button.compact{background-position:-72px -96px}.jsoneditor .menu button.format{background-position:-72px -120px}.jsoneditor .menu button.modes{background-image:none;width:auto;padding-left:6px;padding-right:6px}.jsoneditor .menu button.separator{margin-left:10px}.jsoneditor .menu a{font-family:arial,sans-serif;font-size:10pt;color:#97B0F8;vertical-align:middle}.jsoneditor .menu a:hover{color:red}.jsoneditor .menu a.poweredBy{font-size:8pt;position:absolute;right:0;top:0;padding:10px}.jsoneditor .search .results,.jsoneditor .search input{font-family:arial,sans-serif;font-size:10pt;color:#1A1A1A;background:0 0}.jsoneditor .search{position:absolute;right:2px;top:2px}.jsoneditor .search .frame{border:1px solid #97B0F8;background-color:#fff;padding:0 2px;margin:0}.jsoneditor .search .frame table{border-collapse:collapse}.jsoneditor .search input{width:120px;border:none;outline:0;margin:1px}.jsoneditor .search .results{color:#4d4d4d;padding-right:5px;line-height:24px}.jsoneditor .search button{width:16px;height:24px;padding:0;margin:0;border:none;background:url(images/jsoneditor-icons.png);vertical-align:top}.jsoneditor .search button:hover{background-color:transparent}.jsoneditor .search button.refresh{width:18px;background-position:-99px -73px}.jsoneditor .search button.next{cursor:pointer;background-position:-124px -73px}.jsoneditor .search button.next:hover{background-position:-124px -49px}.jsoneditor .search button.previous{cursor:pointer;background-position:-148px -73px;margin-right:2px}.jsoneditor .search button.previous:hover{background-position:-148px -49px}
--------------------------------------------------------------------------------
/view/src/sass/selectize/_selectize.bootstrap3.scss:
--------------------------------------------------------------------------------
1 | /**
2 | * selectize.bootstrap3.css (v0.12.1) - Bootstrap 3 Theme
3 | * Copyright (c) 2013–2015 Brian Reavis & contributors
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this
6 | * file except in compliance with the License. You may obtain a copy of the License at:
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software distributed under
10 | * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
11 | * ANY KIND, either express or implied. See the License for the specific language
12 | * governing permissions and limitations under the License.
13 | *
14 | * @author Brian Reavis
15 | */
16 | .selectize-control.plugin-drag_drop.multi > .selectize-input > div.ui-sortable-placeholder {
17 | visibility: visible !important;
18 | background: #f2f2f2 !important;
19 | background: rgba(0, 0, 0, 0.06) !important;
20 | border: 0 none !important;
21 | -webkit-box-shadow: inset 0 0 12px 4px #ffffff;
22 | box-shadow: inset 0 0 12px 4px #ffffff;
23 | }
24 | .selectize-control.plugin-drag_drop .ui-sortable-placeholder::after {
25 | content: '!';
26 | visibility: hidden;
27 | }
28 | .selectize-control.plugin-drag_drop .ui-sortable-helper {
29 | -webkit-box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2);
30 | box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2);
31 | }
32 | .selectize-dropdown-header {
33 | position: relative;
34 | padding: 3px 12px;
35 | border-bottom: 1px solid #d0d0d0;
36 | background: #f8f8f8;
37 | -webkit-border-radius: 4px 4px 0 0;
38 | -moz-border-radius: 4px 4px 0 0;
39 | border-radius: 4px 4px 0 0;
40 | }
41 | .selectize-dropdown-header-close {
42 | position: absolute;
43 | right: 12px;
44 | top: 50%;
45 | color: #333333;
46 | opacity: 0.4;
47 | margin-top: -12px;
48 | line-height: 20px;
49 | font-size: 20px !important;
50 | }
51 | .selectize-dropdown-header-close:hover {
52 | color: #000000;
53 | }
54 | .selectize-dropdown.plugin-optgroup_columns .optgroup {
55 | border-right: 1px solid #f2f2f2;
56 | border-top: 0 none;
57 | float: left;
58 | -webkit-box-sizing: border-box;
59 | -moz-box-sizing: border-box;
60 | box-sizing: border-box;
61 | }
62 | .selectize-dropdown.plugin-optgroup_columns .optgroup:last-child {
63 | border-right: 0 none;
64 | }
65 | .selectize-dropdown.plugin-optgroup_columns .optgroup:before {
66 | display: none;
67 | }
68 | .selectize-dropdown.plugin-optgroup_columns .optgroup-header {
69 | border-top: 0 none;
70 | }
71 | .selectize-control.plugin-remove_button [data-value] {
72 | position: relative;
73 | padding-right: 24px !important;
74 | }
75 | .selectize-control.plugin-remove_button [data-value] .remove {
76 | z-index: 1;
77 | /* fixes ie bug (see #392) */
78 | position: absolute;
79 | top: 0;
80 | right: 0;
81 | bottom: 0;
82 | width: 17px;
83 | text-align: center;
84 | font-weight: bold;
85 | font-size: 12px;
86 | color: inherit;
87 | text-decoration: none;
88 | vertical-align: middle;
89 | display: inline-block;
90 | padding: 1px 0 0 0;
91 | border-left: 1px solid rgba(0, 0, 0, 0);
92 | -webkit-border-radius: 0 2px 2px 0;
93 | -moz-border-radius: 0 2px 2px 0;
94 | border-radius: 0 2px 2px 0;
95 | -webkit-box-sizing: border-box;
96 | -moz-box-sizing: border-box;
97 | box-sizing: border-box;
98 | }
99 | .selectize-control.plugin-remove_button [data-value] .remove:hover {
100 | background: rgba(0, 0, 0, 0.05);
101 | }
102 | .selectize-control.plugin-remove_button [data-value].active .remove {
103 | border-left-color: rgba(0, 0, 0, 0);
104 | }
105 | .selectize-control.plugin-remove_button .disabled [data-value] .remove:hover {
106 | background: none;
107 | }
108 | .selectize-control.plugin-remove_button .disabled [data-value] .remove {
109 | border-left-color: rgba(77, 77, 77, 0);
110 | }
111 | .selectize-control {
112 | position: relative;
113 | }
114 | .selectize-dropdown,
115 | .selectize-input,
116 | .selectize-input input {
117 | color: #333333;
118 | font-family: inherit;
119 | font-size: inherit;
120 | line-height: 20px;
121 | -webkit-font-smoothing: inherit;
122 | }
123 | .selectize-input,
124 | .selectize-control.single .selectize-input.input-active {
125 | background: #ffffff;
126 | cursor: text;
127 | display: inline-block;
128 | }
129 | .selectize-input {
130 | border: 1px solid #cccccc;
131 | padding: 6px 12px;
132 | display: inline-block;
133 | width: 100%;
134 | overflow: hidden;
135 | position: relative;
136 | z-index: 1;
137 | -webkit-box-sizing: border-box;
138 | -moz-box-sizing: border-box;
139 | box-sizing: border-box;
140 | -webkit-box-shadow: none;
141 | box-shadow: none;
142 | -webkit-border-radius: 4px;
143 | -moz-border-radius: 4px;
144 | border-radius: 4px;
145 | }
146 | .selectize-control.multi .selectize-input.has-items {
147 | padding: 5px 12px 2px;
148 | }
149 | .selectize-input.full {
150 | background-color: #ffffff;
151 | }
152 | .selectize-input.disabled,
153 | .selectize-input.disabled * {
154 | cursor: default !important;
155 | }
156 | .selectize-input.focus {
157 | -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.15);
158 | box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.15);
159 | }
160 | .selectize-input.dropdown-active {
161 | -webkit-border-radius: 4px 4px 0 0;
162 | -moz-border-radius: 4px 4px 0 0;
163 | border-radius: 4px 4px 0 0;
164 | }
165 | .selectize-input > * {
166 | vertical-align: baseline;
167 | display: -moz-inline-stack;
168 | display: inline-block;
169 | zoom: 1;
170 | *display: inline;
171 | }
172 | .selectize-control.multi .selectize-input > div {
173 | cursor: pointer;
174 | margin: 0 3px 3px 0;
175 | padding: 1px 3px;
176 | background: #efefef;
177 | color: #333333;
178 | border: 0 solid rgba(0, 0, 0, 0);
179 | }
180 | .selectize-control.multi .selectize-input > div.active {
181 | background: #428bca;
182 | color: #ffffff;
183 | border: 0 solid rgba(0, 0, 0, 0);
184 | }
185 | .selectize-control.multi .selectize-input.disabled > div,
186 | .selectize-control.multi .selectize-input.disabled > div.active {
187 | color: #808080;
188 | background: #ffffff;
189 | border: 0 solid rgba(77, 77, 77, 0);
190 | }
191 | .selectize-input > input {
192 | display: inline-block !important;
193 | padding: 0 !important;
194 | min-height: 0 !important;
195 | max-height: none !important;
196 | max-width: 100% !important;
197 | margin: 0 !important;
198 | text-indent: 0 !important;
199 | border: 0 none !important;
200 | background: none !important;
201 | line-height: inherit !important;
202 | -webkit-user-select: auto !important;
203 | -webkit-box-shadow: none !important;
204 | box-shadow: none !important;
205 | }
206 | .selectize-input > input::-ms-clear {
207 | display: none;
208 | }
209 | .selectize-input > input:focus {
210 | outline: none !important;
211 | }
212 | .selectize-input::after {
213 | content: ' ';
214 | display: block;
215 | clear: left;
216 | }
217 | .selectize-input.dropdown-active::before {
218 | content: ' ';
219 | display: block;
220 | position: absolute;
221 | background: #ffffff;
222 | height: 1px;
223 | bottom: 0;
224 | left: 0;
225 | right: 0;
226 | }
227 | .selectize-dropdown {
228 | position: absolute;
229 | z-index: 10;
230 | border: 1px solid #d0d0d0;
231 | background: #ffffff;
232 | margin: -1px 0 0 0;
233 | border-top: 0 none;
234 | -webkit-box-sizing: border-box;
235 | -moz-box-sizing: border-box;
236 | box-sizing: border-box;
237 | -webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
238 | box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
239 | -webkit-border-radius: 0 0 4px 4px;
240 | -moz-border-radius: 0 0 4px 4px;
241 | border-radius: 0 0 4px 4px;
242 | }
243 | .selectize-dropdown [data-selectable] {
244 | cursor: pointer;
245 | overflow: hidden;
246 | }
247 | .selectize-dropdown [data-selectable] .highlight {
248 | background: rgba(255, 237, 40, 0.4);
249 | -webkit-border-radius: 1px;
250 | -moz-border-radius: 1px;
251 | border-radius: 1px;
252 | }
253 | .selectize-dropdown [data-selectable],
254 | .selectize-dropdown .optgroup-header {
255 | padding: 3px 12px;
256 | }
257 | .selectize-dropdown .optgroup:first-child .optgroup-header {
258 | border-top: 0 none;
259 | }
260 | .selectize-dropdown .optgroup-header {
261 | color: #777777;
262 | background: #ffffff;
263 | cursor: default;
264 | }
265 | .selectize-dropdown .active {
266 | background-color: #f5f5f5;
267 | color: #262626;
268 | }
269 | .selectize-dropdown .active.create {
270 | color: #262626;
271 | }
272 | .selectize-dropdown .create {
273 | color: rgba(51, 51, 51, 0.5);
274 | }
275 | .selectize-dropdown-content {
276 | overflow-y: auto;
277 | overflow-x: hidden;
278 | max-height: 200px;
279 | }
280 | .selectize-control.single .selectize-input,
281 | .selectize-control.single .selectize-input input {
282 | cursor: pointer;
283 | }
284 | .selectize-control.single .selectize-input.input-active,
285 | .selectize-control.single .selectize-input.input-active input {
286 | cursor: text;
287 | }
288 | .selectize-control.single .selectize-input:after {
289 | content: ' ';
290 | display: block;
291 | position: absolute;
292 | top: 50%;
293 | right: 17px;
294 | margin-top: -3px;
295 | width: 0;
296 | height: 0;
297 | border-style: solid;
298 | border-width: 5px 5px 0 5px;
299 | border-color: #333333 transparent transparent transparent;
300 | }
301 | .selectize-control.single .selectize-input.dropdown-active:after {
302 | margin-top: -4px;
303 | border-width: 0 5px 5px 5px;
304 | border-color: transparent transparent #333333 transparent;
305 | }
306 | .selectize-control.rtl.single .selectize-input:after {
307 | left: 17px;
308 | right: auto;
309 | }
310 | .selectize-control.rtl .selectize-input > input {
311 | margin: 0 4px 0 -2px !important;
312 | }
313 | .selectize-control .selectize-input.disabled {
314 | opacity: 0.5;
315 | background-color: #ffffff;
316 | }
317 | .selectize-dropdown,
318 | .selectize-dropdown.form-control {
319 | height: auto;
320 | padding: 0;
321 | margin: 2px 0 0 0;
322 | z-index: 1000;
323 | background: #ffffff;
324 | border: 1px solid #cccccc;
325 | border: 1px solid rgba(0, 0, 0, 0.15);
326 | -webkit-border-radius: 4px;
327 | -moz-border-radius: 4px;
328 | border-radius: 4px;
329 | -webkit-box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175);
330 | box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175);
331 | }
332 | .selectize-dropdown .optgroup-header {
333 | font-size: 12px;
334 | line-height: 1.42857143;
335 | }
336 | .selectize-dropdown .optgroup:first-child:before {
337 | display: none;
338 | }
339 | .selectize-dropdown .optgroup:before {
340 | content: ' ';
341 | display: block;
342 | height: 1px;
343 | margin: 9px 0;
344 | overflow: hidden;
345 | background-color: #e5e5e5;
346 | margin-left: -12px;
347 | margin-right: -12px;
348 | }
349 | .selectize-dropdown-content {
350 | padding: 5px 0;
351 | }
352 | .selectize-dropdown-header {
353 | padding: 6px 12px;
354 | }
355 | .selectize-input {
356 | min-height: 34px;
357 | }
358 | .selectize-input.dropdown-active {
359 | -webkit-border-radius: 4px;
360 | -moz-border-radius: 4px;
361 | border-radius: 4px;
362 | }
363 | .selectize-input.dropdown-active::before {
364 | display: none;
365 | }
366 | .selectize-input.focus {
367 | border-color: #66afe9;
368 | outline: 0;
369 | -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.6);
370 | box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.6);
371 | }
372 | .has-error .selectize-input {
373 | border-color: #a94442;
374 | -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
375 | box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
376 | }
377 | .has-error .selectize-input:focus {
378 | border-color: #843534;
379 | -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #ce8483;
380 | box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #ce8483;
381 | }
382 | .selectize-control.multi .selectize-input.has-items {
383 | padding-left: 9px;
384 | padding-right: 9px;
385 | }
386 | .selectize-control.multi .selectize-input > div {
387 | -webkit-border-radius: 3px;
388 | -moz-border-radius: 3px;
389 | border-radius: 3px;
390 | }
391 | .form-control.selectize-control {
392 | padding: 0;
393 | height: auto;
394 | border: none;
395 | background: none;
396 | -webkit-box-shadow: none;
397 | box-shadow: none;
398 | -webkit-border-radius: 0;
399 | -moz-border-radius: 0;
400 | border-radius: 0;
401 | }
402 |
--------------------------------------------------------------------------------
/view/src/sass/selectize/_selectize.default.scss:
--------------------------------------------------------------------------------
1 | /**
2 | * selectize.default.css (v0.12.1) - Default Theme
3 | * Copyright (c) 2013–2015 Brian Reavis & contributors
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this
6 | * file except in compliance with the License. You may obtain a copy of the License at:
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software distributed under
10 | * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
11 | * ANY KIND, either express or implied. See the License for the specific language
12 | * governing permissions and limitations under the License.
13 | *
14 | * @author Brian Reavis
15 | */
16 | .selectize-control.plugin-drag_drop.multi > .selectize-input > div.ui-sortable-placeholder {
17 | visibility: visible !important;
18 | background: #f2f2f2 !important;
19 | background: rgba(0, 0, 0, 0.06) !important;
20 | border: 0 none !important;
21 | -webkit-box-shadow: inset 0 0 12px 4px #ffffff;
22 | box-shadow: inset 0 0 12px 4px #ffffff;
23 | }
24 | .selectize-control.plugin-drag_drop .ui-sortable-placeholder::after {
25 | content: '!';
26 | visibility: hidden;
27 | }
28 | .selectize-control.plugin-drag_drop .ui-sortable-helper {
29 | -webkit-box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2);
30 | box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2);
31 | }
32 | .selectize-dropdown-header {
33 | position: relative;
34 | padding: 5px 8px;
35 | border-bottom: 1px solid #d0d0d0;
36 | background: #f8f8f8;
37 | -webkit-border-radius: 3px 3px 0 0;
38 | -moz-border-radius: 3px 3px 0 0;
39 | border-radius: 3px 3px 0 0;
40 | }
41 | .selectize-dropdown-header-close {
42 | position: absolute;
43 | right: 8px;
44 | top: 50%;
45 | color: #303030;
46 | opacity: 0.4;
47 | margin-top: -12px;
48 | line-height: 20px;
49 | font-size: 20px !important;
50 | }
51 | .selectize-dropdown-header-close:hover {
52 | color: #000000;
53 | }
54 | .selectize-dropdown.plugin-optgroup_columns .optgroup {
55 | border-right: 1px solid #f2f2f2;
56 | border-top: 0 none;
57 | float: left;
58 | -webkit-box-sizing: border-box;
59 | -moz-box-sizing: border-box;
60 | box-sizing: border-box;
61 | }
62 | .selectize-dropdown.plugin-optgroup_columns .optgroup:last-child {
63 | border-right: 0 none;
64 | }
65 | .selectize-dropdown.plugin-optgroup_columns .optgroup:before {
66 | display: none;
67 | }
68 | .selectize-dropdown.plugin-optgroup_columns .optgroup-header {
69 | border-top: 0 none;
70 | }
71 | .selectize-control.plugin-remove_button [data-value] {
72 | position: relative;
73 | padding-right: 24px !important;
74 | }
75 | .selectize-control.plugin-remove_button [data-value] .remove {
76 | z-index: 1;
77 | /* fixes ie bug (see #392) */
78 | position: absolute;
79 | top: 0;
80 | right: 0;
81 | bottom: 0;
82 | width: 17px;
83 | text-align: center;
84 | font-weight: bold;
85 | font-size: 12px;
86 | color: inherit;
87 | text-decoration: none;
88 | vertical-align: middle;
89 | display: inline-block;
90 | padding: 2px 0 0 0;
91 | border-left: 1px solid #0073bb;
92 | -webkit-border-radius: 0 2px 2px 0;
93 | -moz-border-radius: 0 2px 2px 0;
94 | border-radius: 0 2px 2px 0;
95 | -webkit-box-sizing: border-box;
96 | -moz-box-sizing: border-box;
97 | box-sizing: border-box;
98 | }
99 | .selectize-control.plugin-remove_button [data-value] .remove:hover {
100 | background: rgba(0, 0, 0, 0.05);
101 | }
102 | .selectize-control.plugin-remove_button [data-value].active .remove {
103 | border-left-color: #00578d;
104 | }
105 | .selectize-control.plugin-remove_button .disabled [data-value] .remove:hover {
106 | background: none;
107 | }
108 | .selectize-control.plugin-remove_button .disabled [data-value] .remove {
109 | border-left-color: #aaaaaa;
110 | }
111 | .selectize-control {
112 | position: relative;
113 | }
114 | .selectize-dropdown,
115 | .selectize-input,
116 | .selectize-input input {
117 | color: #303030;
118 | font-family: inherit;
119 | font-size: 13px;
120 | line-height: 18px;
121 | -webkit-font-smoothing: inherit;
122 | }
123 | .selectize-input,
124 | .selectize-control.single .selectize-input.input-active {
125 | background: #ffffff;
126 | cursor: text;
127 | display: inline-block;
128 | }
129 | .selectize-input {
130 | border: 1px solid #d0d0d0;
131 | padding: 8px 8px;
132 | display: inline-block;
133 | width: 100%;
134 | overflow: hidden;
135 | position: relative;
136 | z-index: 1;
137 | -webkit-box-sizing: border-box;
138 | -moz-box-sizing: border-box;
139 | box-sizing: border-box;
140 | -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.1);
141 | box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.1);
142 | -webkit-border-radius: 3px;
143 | -moz-border-radius: 3px;
144 | border-radius: 3px;
145 | }
146 | .selectize-control.multi .selectize-input.has-items {
147 | padding: 5px 8px 2px;
148 | }
149 | .selectize-input.full {
150 | background-color: #ffffff;
151 | }
152 | .selectize-input.disabled,
153 | .selectize-input.disabled * {
154 | cursor: default !important;
155 | }
156 | .selectize-input.focus {
157 | -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.15);
158 | box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.15);
159 | }
160 | .selectize-input.dropdown-active {
161 | -webkit-border-radius: 3px 3px 0 0;
162 | -moz-border-radius: 3px 3px 0 0;
163 | border-radius: 3px 3px 0 0;
164 | }
165 | .selectize-input > * {
166 | vertical-align: baseline;
167 | display: -moz-inline-stack;
168 | display: inline-block;
169 | zoom: 1;
170 | *display: inline;
171 | }
172 | .selectize-control.multi .selectize-input > div {
173 | cursor: pointer;
174 | margin: 0 3px 3px 0;
175 | padding: 2px 6px;
176 | background: #1da7ee;
177 | color: #ffffff;
178 | border: 1px solid #0073bb;
179 | }
180 | .selectize-control.multi .selectize-input > div.active {
181 | background: #92c836;
182 | color: #ffffff;
183 | border: 1px solid #00578d;
184 | }
185 | .selectize-control.multi .selectize-input.disabled > div,
186 | .selectize-control.multi .selectize-input.disabled > div.active {
187 | color: #ffffff;
188 | background: #d2d2d2;
189 | border: 1px solid #aaaaaa;
190 | }
191 | .selectize-input > input {
192 | display: inline-block !important;
193 | padding: 0 !important;
194 | min-height: 0 !important;
195 | max-height: none !important;
196 | max-width: 100% !important;
197 | margin: 0 1px !important;
198 | text-indent: 0 !important;
199 | border: 0 none !important;
200 | background: none !important;
201 | line-height: inherit !important;
202 | -webkit-user-select: auto !important;
203 | -webkit-box-shadow: none !important;
204 | box-shadow: none !important;
205 | }
206 | .selectize-input > input::-ms-clear {
207 | display: none;
208 | }
209 | .selectize-input > input:focus {
210 | outline: none !important;
211 | }
212 | .selectize-input::after {
213 | content: ' ';
214 | display: block;
215 | clear: left;
216 | }
217 | .selectize-input.dropdown-active::before {
218 | content: ' ';
219 | display: block;
220 | position: absolute;
221 | background: #f0f0f0;
222 | height: 1px;
223 | bottom: 0;
224 | left: 0;
225 | right: 0;
226 | }
227 | .selectize-dropdown {
228 | position: absolute;
229 | z-index: 10;
230 | border: 1px solid #d0d0d0;
231 | background: #ffffff;
232 | margin: -1px 0 0 0;
233 | border-top: 0 none;
234 | -webkit-box-sizing: border-box;
235 | -moz-box-sizing: border-box;
236 | box-sizing: border-box;
237 | -webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
238 | box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
239 | -webkit-border-radius: 0 0 3px 3px;
240 | -moz-border-radius: 0 0 3px 3px;
241 | border-radius: 0 0 3px 3px;
242 | }
243 | .selectize-dropdown [data-selectable] {
244 | cursor: pointer;
245 | overflow: hidden;
246 | }
247 | .selectize-dropdown [data-selectable] .highlight {
248 | background: rgba(125, 168, 208, 0.2);
249 | -webkit-border-radius: 1px;
250 | -moz-border-radius: 1px;
251 | border-radius: 1px;
252 | }
253 | .selectize-dropdown [data-selectable],
254 | .selectize-dropdown .optgroup-header {
255 | padding: 5px 8px;
256 | }
257 | .selectize-dropdown .optgroup:first-child .optgroup-header {
258 | border-top: 0 none;
259 | }
260 | .selectize-dropdown .optgroup-header {
261 | color: #303030;
262 | background: #ffffff;
263 | cursor: default;
264 | }
265 | .selectize-dropdown .active {
266 | background-color: #f5fafd;
267 | color: #495c68;
268 | }
269 | .selectize-dropdown .active.create {
270 | color: #495c68;
271 | }
272 | .selectize-dropdown .create {
273 | color: rgba(48, 48, 48, 0.5);
274 | }
275 | .selectize-dropdown-content {
276 | overflow-y: auto;
277 | overflow-x: hidden;
278 | max-height: 200px;
279 | }
280 | .selectize-control.single .selectize-input,
281 | .selectize-control.single .selectize-input input {
282 | cursor: pointer;
283 | }
284 | .selectize-control.single .selectize-input.input-active,
285 | .selectize-control.single .selectize-input.input-active input {
286 | cursor: text;
287 | }
288 | .selectize-control.single .selectize-input:after {
289 | content: ' ';
290 | display: block;
291 | position: absolute;
292 | top: 50%;
293 | right: 15px;
294 | margin-top: -3px;
295 | width: 0;
296 | height: 0;
297 | border-style: solid;
298 | border-width: 5px 5px 0 5px;
299 | border-color: #808080 transparent transparent transparent;
300 | }
301 | .selectize-control.single .selectize-input.dropdown-active:after {
302 | margin-top: -4px;
303 | border-width: 0 5px 5px 5px;
304 | border-color: transparent transparent #808080 transparent;
305 | }
306 | .selectize-control.rtl.single .selectize-input:after {
307 | left: 15px;
308 | right: auto;
309 | }
310 | .selectize-control.rtl .selectize-input > input {
311 | margin: 0 4px 0 -2px !important;
312 | }
313 | .selectize-control .selectize-input.disabled {
314 | opacity: 0.5;
315 | background-color: #fafafa;
316 | }
317 | .selectize-control.multi .selectize-input.has-items {
318 | padding-left: 5px;
319 | padding-right: 5px;
320 | }
321 | .selectize-control.multi .selectize-input.disabled [data-value] {
322 | color: #999;
323 | text-shadow: none;
324 | background: none;
325 | -webkit-box-shadow: none;
326 | box-shadow: none;
327 | }
328 | .selectize-control.multi .selectize-input.disabled [data-value],
329 | .selectize-control.multi .selectize-input.disabled [data-value] .remove {
330 | border-color: #e6e6e6;
331 | }
332 | .selectize-control.multi .selectize-input.disabled [data-value] .remove {
333 | background: none;
334 | }
335 | .selectize-control.multi .selectize-input [data-value] {
336 | text-shadow: 0 1px 0 rgba(0, 51, 83, 0.3);
337 | -webkit-border-radius: 3px;
338 | -moz-border-radius: 3px;
339 | border-radius: 3px;
340 | background-color: #1b9dec;
341 | background-image: -moz-linear-gradient(top, #1da7ee, #178ee9);
342 | background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#1da7ee), to(#178ee9));
343 | background-image: -webkit-linear-gradient(top, #1da7ee, #178ee9);
344 | background-image: -o-linear-gradient(top, #1da7ee, #178ee9);
345 | background-image: linear-gradient(to bottom, #1da7ee, #178ee9);
346 | background-repeat: repeat-x;
347 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff1da7ee', endColorstr='#ff178ee9', GradientType=0);
348 | -webkit-box-shadow: 0 1px 0 rgba(0,0,0,0.2),inset 0 1px rgba(255,255,255,0.03);
349 | box-shadow: 0 1px 0 rgba(0,0,0,0.2),inset 0 1px rgba(255,255,255,0.03);
350 | }
351 | .selectize-control.multi .selectize-input [data-value].active {
352 | background-color: #0085d4;
353 | background-image: -moz-linear-gradient(top, #008fd8, #0075cf);
354 | background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#008fd8), to(#0075cf));
355 | background-image: -webkit-linear-gradient(top, #008fd8, #0075cf);
356 | background-image: -o-linear-gradient(top, #008fd8, #0075cf);
357 | background-image: linear-gradient(to bottom, #008fd8, #0075cf);
358 | background-repeat: repeat-x;
359 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff008fd8', endColorstr='#ff0075cf', GradientType=0);
360 | }
361 | .selectize-control.single .selectize-input {
362 | -webkit-box-shadow: 0 1px 0 rgba(0,0,0,0.05), inset 0 1px 0 rgba(255,255,255,0.8);
363 | box-shadow: 0 1px 0 rgba(0,0,0,0.05), inset 0 1px 0 rgba(255,255,255,0.8);
364 | background-color: #f9f9f9;
365 | background-image: -moz-linear-gradient(top, #fefefe, #f2f2f2);
366 | background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#fefefe), to(#f2f2f2));
367 | background-image: -webkit-linear-gradient(top, #fefefe, #f2f2f2);
368 | background-image: -o-linear-gradient(top, #fefefe, #f2f2f2);
369 | background-image: linear-gradient(to bottom, #fefefe, #f2f2f2);
370 | background-repeat: repeat-x;
371 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffefefe', endColorstr='#fff2f2f2', GradientType=0);
372 | }
373 | .selectize-control.single .selectize-input,
374 | .selectize-dropdown.single {
375 | border-color: #b8b8b8;
376 | }
377 | .selectize-dropdown .optgroup-header {
378 | padding-top: 7px;
379 | font-weight: bold;
380 | font-size: 0.85em;
381 | }
382 | .selectize-dropdown .optgroup {
383 | border-top: 1px solid #f0f0f0;
384 | }
385 | .selectize-dropdown .optgroup:first-child {
386 | border-top: 0 none;
387 | }
388 |
--------------------------------------------------------------------------------
/view/src/sass/selectize/selectize.css:
--------------------------------------------------------------------------------
1 | /**
2 | * selectize.css (v0.12.1)
3 | * Copyright (c) 2013–2015 Brian Reavis & contributors
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this
6 | * file except in compliance with the License. You may obtain a copy of the License at:
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software distributed under
10 | * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
11 | * ANY KIND, either express or implied. See the License for the specific language
12 | * governing permissions and limitations under the License.
13 | *
14 | * @author Brian Reavis
15 | */
16 |
17 | .selectize-control.plugin-drag_drop.multi > .selectize-input > div.ui-sortable-placeholder {
18 | visibility: visible !important;
19 | background: #f2f2f2 !important;
20 | background: rgba(0, 0, 0, 0.06) !important;
21 | border: 0 none !important;
22 | -webkit-box-shadow: inset 0 0 12px 4px #ffffff;
23 | box-shadow: inset 0 0 12px 4px #ffffff;
24 | }
25 | .selectize-control.plugin-drag_drop .ui-sortable-placeholder::after {
26 | content: '!';
27 | visibility: hidden;
28 | }
29 | .selectize-control.plugin-drag_drop .ui-sortable-helper {
30 | -webkit-box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2);
31 | box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2);
32 | }
33 | .selectize-dropdown-header {
34 | position: relative;
35 | padding: 5px 8px;
36 | border-bottom: 1px solid #d0d0d0;
37 | background: #f8f8f8;
38 | -webkit-border-radius: 3px 3px 0 0;
39 | -moz-border-radius: 3px 3px 0 0;
40 | border-radius: 3px 3px 0 0;
41 | }
42 | .selectize-dropdown-header-close {
43 | position: absolute;
44 | right: 8px;
45 | top: 50%;
46 | color: #303030;
47 | opacity: 0.4;
48 | margin-top: -12px;
49 | line-height: 20px;
50 | font-size: 20px !important;
51 | }
52 | .selectize-dropdown-header-close:hover {
53 | color: #000000;
54 | }
55 | .selectize-dropdown.plugin-optgroup_columns .optgroup {
56 | border-right: 1px solid #f2f2f2;
57 | border-top: 0 none;
58 | float: left;
59 | -webkit-box-sizing: border-box;
60 | -moz-box-sizing: border-box;
61 | box-sizing: border-box;
62 | }
63 | .selectize-dropdown.plugin-optgroup_columns .optgroup:last-child {
64 | border-right: 0 none;
65 | }
66 | .selectize-dropdown.plugin-optgroup_columns .optgroup:before {
67 | display: none;
68 | }
69 | .selectize-dropdown.plugin-optgroup_columns .optgroup-header {
70 | border-top: 0 none;
71 | }
72 | .selectize-control.plugin-remove_button [data-value] {
73 | position: relative;
74 | padding-right: 24px !important;
75 | }
76 | .selectize-control.plugin-remove_button [data-value] .remove {
77 | z-index: 1;
78 | /* fixes ie bug (see #392) */
79 | position: absolute;
80 | top: 0;
81 | right: 0;
82 | bottom: 0;
83 | width: 17px;
84 | text-align: center;
85 | font-weight: bold;
86 | font-size: 12px;
87 | color: inherit;
88 | text-decoration: none;
89 | vertical-align: middle;
90 | display: inline-block;
91 | padding: 2px 0 0 0;
92 | border-left: 1px solid #d0d0d0;
93 | -webkit-border-radius: 0 2px 2px 0;
94 | -moz-border-radius: 0 2px 2px 0;
95 | border-radius: 0 2px 2px 0;
96 | -webkit-box-sizing: border-box;
97 | -moz-box-sizing: border-box;
98 | box-sizing: border-box;
99 | }
100 | .selectize-control.plugin-remove_button [data-value] .remove:hover {
101 | background: rgba(0, 0, 0, 0.05);
102 | }
103 | .selectize-control.plugin-remove_button [data-value].active .remove {
104 | border-left-color: #cacaca;
105 | }
106 | .selectize-control.plugin-remove_button .disabled [data-value] .remove:hover {
107 | background: none;
108 | }
109 | .selectize-control.plugin-remove_button .disabled [data-value] .remove {
110 | border-left-color: #ffffff;
111 | }
112 | .selectize-control {
113 | position: relative;
114 | }
115 | .selectize-dropdown,
116 | .selectize-input,
117 | .selectize-input input {
118 | color: #303030;
119 | font-family: inherit;
120 | font-size: 13px;
121 | line-height: 18px;
122 | -webkit-font-smoothing: inherit;
123 | }
124 | .selectize-input,
125 | .selectize-control.single .selectize-input.input-active {
126 | background: #ffffff;
127 | cursor: text;
128 | display: inline-block;
129 | }
130 | .selectize-input {
131 | border: 1px solid #d0d0d0;
132 | padding: 8px 8px;
133 | display: inline-block;
134 | width: 100%;
135 | overflow: hidden;
136 | position: relative;
137 | z-index: 1;
138 | -webkit-box-sizing: border-box;
139 | -moz-box-sizing: border-box;
140 | box-sizing: border-box;
141 | -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.1);
142 | box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.1);
143 | -webkit-border-radius: 3px;
144 | -moz-border-radius: 3px;
145 | border-radius: 3px;
146 | }
147 | .selectize-control.multi .selectize-input.has-items {
148 | padding: 6px 8px 3px;
149 | }
150 | .selectize-input.full {
151 | background-color: #ffffff;
152 | }
153 | .selectize-input.disabled,
154 | .selectize-input.disabled * {
155 | cursor: default !important;
156 | }
157 | .selectize-input.focus {
158 | -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.15);
159 | box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.15);
160 | }
161 | .selectize-input.dropdown-active {
162 | -webkit-border-radius: 3px 3px 0 0;
163 | -moz-border-radius: 3px 3px 0 0;
164 | border-radius: 3px 3px 0 0;
165 | }
166 | .selectize-input > * {
167 | vertical-align: baseline;
168 | display: -moz-inline-stack;
169 | display: inline-block;
170 | zoom: 1;
171 | *display: inline;
172 | }
173 | .selectize-control.multi .selectize-input > div {
174 | cursor: pointer;
175 | margin: 0 3px 3px 0;
176 | padding: 2px 6px;
177 | background: #f2f2f2;
178 | color: #303030;
179 | border: 0 solid #d0d0d0;
180 | }
181 | .selectize-control.multi .selectize-input > div.active {
182 | background: #e8e8e8;
183 | color: #303030;
184 | border: 0 solid #cacaca;
185 | }
186 | .selectize-control.multi .selectize-input.disabled > div,
187 | .selectize-control.multi .selectize-input.disabled > div.active {
188 | color: #7d7d7d;
189 | background: #ffffff;
190 | border: 0 solid #ffffff;
191 | }
192 | .selectize-input > input {
193 | display: inline-block !important;
194 | padding: 0 !important;
195 | min-height: 0 !important;
196 | max-height: none !important;
197 | max-width: 100% !important;
198 | margin: 0 2px 0 0 !important;
199 | text-indent: 0 !important;
200 | border: 0 none !important;
201 | background: none !important;
202 | line-height: inherit !important;
203 | -webkit-user-select: auto !important;
204 | -webkit-box-shadow: none !important;
205 | box-shadow: none !important;
206 | }
207 | .selectize-input > input::-ms-clear {
208 | display: none;
209 | }
210 | .selectize-input > input:focus {
211 | outline: none !important;
212 | }
213 | .selectize-input::after {
214 | content: ' ';
215 | display: block;
216 | clear: left;
217 | }
218 | .selectize-input.dropdown-active::before {
219 | content: ' ';
220 | display: block;
221 | position: absolute;
222 | background: #f0f0f0;
223 | height: 1px;
224 | bottom: 0;
225 | left: 0;
226 | right: 0;
227 | }
228 | .selectize-dropdown {
229 | position: absolute;
230 | z-index: 10;
231 | border: 1px solid #d0d0d0;
232 | background: #ffffff;
233 | margin: -1px 0 0 0;
234 | border-top: 0 none;
235 | -webkit-box-sizing: border-box;
236 | -moz-box-sizing: border-box;
237 | box-sizing: border-box;
238 | -webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
239 | box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
240 | -webkit-border-radius: 0 0 3px 3px;
241 | -moz-border-radius: 0 0 3px 3px;
242 | border-radius: 0 0 3px 3px;
243 | }
244 | .selectize-dropdown [data-selectable] {
245 | cursor: pointer;
246 | overflow: hidden;
247 | }
248 | .selectize-dropdown [data-selectable] .highlight {
249 | background: rgba(125, 168, 208, 0.2);
250 | -webkit-border-radius: 1px;
251 | -moz-border-radius: 1px;
252 | border-radius: 1px;
253 | }
254 | .selectize-dropdown [data-selectable],
255 | .selectize-dropdown .optgroup-header {
256 | padding: 5px 8px;
257 | }
258 | .selectize-dropdown .optgroup:first-child .optgroup-header {
259 | border-top: 0 none;
260 | }
261 | .selectize-dropdown .optgroup-header {
262 | color: #303030;
263 | background: #ffffff;
264 | cursor: default;
265 | }
266 | .selectize-dropdown .active {
267 | background-color: #f5fafd;
268 | color: #495c68;
269 | }
270 | .selectize-dropdown .active.create {
271 | color: #495c68;
272 | }
273 | .selectize-dropdown .create {
274 | color: rgba(48, 48, 48, 0.5);
275 | }
276 | .selectize-dropdown-content {
277 | overflow-y: auto;
278 | overflow-x: hidden;
279 | max-height: 200px;
280 | }
281 | .selectize-control.single .selectize-input,
282 | .selectize-control.single .selectize-input input {
283 | cursor: pointer;
284 | }
285 | .selectize-control.single .selectize-input.input-active,
286 | .selectize-control.single .selectize-input.input-active input {
287 | cursor: text;
288 | }
289 | .selectize-control.single .selectize-input:after {
290 | content: ' ';
291 | display: block;
292 | position: absolute;
293 | top: 50%;
294 | right: 15px;
295 | margin-top: -3px;
296 | width: 0;
297 | height: 0;
298 | border-style: solid;
299 | border-width: 5px 5px 0 5px;
300 | border-color: #808080 transparent transparent transparent;
301 | }
302 | .selectize-control.single .selectize-input.dropdown-active:after {
303 | margin-top: -4px;
304 | border-width: 0 5px 5px 5px;
305 | border-color: transparent transparent #808080 transparent;
306 | }
307 | .selectize-control.rtl.single .selectize-input:after {
308 | left: 15px;
309 | right: auto;
310 | }
311 | .selectize-control.rtl .selectize-input > input {
312 | margin: 0 4px 0 -2px !important;
313 | }
314 | .selectize-control .selectize-input.disabled {
315 | opacity: 0.5;
316 | background-color: #fafafa;
317 | }
318 |
--------------------------------------------------------------------------------
/view/src/sass/selectize/selectize.legacy.css:
--------------------------------------------------------------------------------
1 | /**
2 | * selectize.legacy.css (v0.12.1) - Default Theme
3 | * Copyright (c) 2013–2015 Brian Reavis & contributors
4 | *
5 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this
6 | * file except in compliance with the License. You may obtain a copy of the License at:
7 | * http://www.apache.org/licenses/LICENSE-2.0
8 | *
9 | * Unless required by applicable law or agreed to in writing, software distributed under
10 | * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
11 | * ANY KIND, either express or implied. See the License for the specific language
12 | * governing permissions and limitations under the License.
13 | *
14 | * @author Brian Reavis
15 | */
16 | .selectize-control.plugin-drag_drop.multi > .selectize-input > div.ui-sortable-placeholder {
17 | visibility: visible !important;
18 | background: #f2f2f2 !important;
19 | background: rgba(0, 0, 0, 0.06) !important;
20 | border: 0 none !important;
21 | -webkit-box-shadow: inset 0 0 12px 4px #ffffff;
22 | box-shadow: inset 0 0 12px 4px #ffffff;
23 | }
24 | .selectize-control.plugin-drag_drop .ui-sortable-placeholder::after {
25 | content: '!';
26 | visibility: hidden;
27 | }
28 | .selectize-control.plugin-drag_drop .ui-sortable-helper {
29 | -webkit-box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2);
30 | box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2);
31 | }
32 | .selectize-dropdown-header {
33 | position: relative;
34 | padding: 7px 10px;
35 | border-bottom: 1px solid #d0d0d0;
36 | background: #f8f8f8;
37 | -webkit-border-radius: 3px 3px 0 0;
38 | -moz-border-radius: 3px 3px 0 0;
39 | border-radius: 3px 3px 0 0;
40 | }
41 | .selectize-dropdown-header-close {
42 | position: absolute;
43 | right: 10px;
44 | top: 50%;
45 | color: #303030;
46 | opacity: 0.4;
47 | margin-top: -12px;
48 | line-height: 20px;
49 | font-size: 20px !important;
50 | }
51 | .selectize-dropdown-header-close:hover {
52 | color: #000000;
53 | }
54 | .selectize-dropdown.plugin-optgroup_columns .optgroup {
55 | border-right: 1px solid #f2f2f2;
56 | border-top: 0 none;
57 | float: left;
58 | -webkit-box-sizing: border-box;
59 | -moz-box-sizing: border-box;
60 | box-sizing: border-box;
61 | }
62 | .selectize-dropdown.plugin-optgroup_columns .optgroup:last-child {
63 | border-right: 0 none;
64 | }
65 | .selectize-dropdown.plugin-optgroup_columns .optgroup:before {
66 | display: none;
67 | }
68 | .selectize-dropdown.plugin-optgroup_columns .optgroup-header {
69 | border-top: 0 none;
70 | }
71 | .selectize-control.plugin-remove_button [data-value] {
72 | position: relative;
73 | padding-right: 24px !important;
74 | }
75 | .selectize-control.plugin-remove_button [data-value] .remove {
76 | z-index: 1;
77 | /* fixes ie bug (see #392) */
78 | position: absolute;
79 | top: 0;
80 | right: 0;
81 | bottom: 0;
82 | width: 17px;
83 | text-align: center;
84 | font-weight: bold;
85 | font-size: 12px;
86 | color: inherit;
87 | text-decoration: none;
88 | vertical-align: middle;
89 | display: inline-block;
90 | padding: 1px 0 0 0;
91 | border-left: 1px solid #74b21e;
92 | -webkit-border-radius: 0 2px 2px 0;
93 | -moz-border-radius: 0 2px 2px 0;
94 | border-radius: 0 2px 2px 0;
95 | -webkit-box-sizing: border-box;
96 | -moz-box-sizing: border-box;
97 | box-sizing: border-box;
98 | }
99 | .selectize-control.plugin-remove_button [data-value] .remove:hover {
100 | background: rgba(0, 0, 0, 0.05);
101 | }
102 | .selectize-control.plugin-remove_button [data-value].active .remove {
103 | border-left-color: #6f9839;
104 | }
105 | .selectize-control.plugin-remove_button .disabled [data-value] .remove:hover {
106 | background: none;
107 | }
108 | .selectize-control.plugin-remove_button .disabled [data-value] .remove {
109 | border-left-color: #b4b4b4;
110 | }
111 | .selectize-control {
112 | position: relative;
113 | }
114 | .selectize-dropdown,
115 | .selectize-input,
116 | .selectize-input input {
117 | color: #303030;
118 | font-family: inherit;
119 | font-size: 13px;
120 | line-height: 20px;
121 | -webkit-font-smoothing: inherit;
122 | }
123 | .selectize-input,
124 | .selectize-control.single .selectize-input.input-active {
125 | background: #ffffff;
126 | cursor: text;
127 | display: inline-block;
128 | }
129 | .selectize-input {
130 | border: 1px solid #d0d0d0;
131 | padding: 10px 10px;
132 | display: inline-block;
133 | width: 100%;
134 | overflow: hidden;
135 | position: relative;
136 | z-index: 1;
137 | -webkit-box-sizing: border-box;
138 | -moz-box-sizing: border-box;
139 | box-sizing: border-box;
140 | -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.1);
141 | box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.1);
142 | -webkit-border-radius: 3px;
143 | -moz-border-radius: 3px;
144 | border-radius: 3px;
145 | }
146 | .selectize-control.multi .selectize-input.has-items {
147 | padding: 8px 10px 4px;
148 | }
149 | .selectize-input.full {
150 | background-color: #f2f2f2;
151 | }
152 | .selectize-input.disabled,
153 | .selectize-input.disabled * {
154 | cursor: default !important;
155 | }
156 | .selectize-input.focus {
157 | -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.15);
158 | box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.15);
159 | }
160 | .selectize-input.dropdown-active {
161 | -webkit-border-radius: 3px 3px 0 0;
162 | -moz-border-radius: 3px 3px 0 0;
163 | border-radius: 3px 3px 0 0;
164 | }
165 | .selectize-input > * {
166 | vertical-align: baseline;
167 | display: -moz-inline-stack;
168 | display: inline-block;
169 | zoom: 1;
170 | *display: inline;
171 | }
172 | .selectize-control.multi .selectize-input > div {
173 | cursor: pointer;
174 | margin: 0 4px 4px 0;
175 | padding: 1px 5px;
176 | background: #b8e76f;
177 | color: #3d5d18;
178 | border: 1px solid #74b21e;
179 | }
180 | .selectize-control.multi .selectize-input > div.active {
181 | background: #92c836;
182 | color: #303030;
183 | border: 1px solid #6f9839;
184 | }
185 | .selectize-control.multi .selectize-input.disabled > div,
186 | .selectize-control.multi .selectize-input.disabled > div.active {
187 | color: #878787;
188 | background: #f8f8f8;
189 | border: 1px solid #b4b4b4;
190 | }
191 | .selectize-input > input {
192 | display: inline-block !important;
193 | padding: 0 !important;
194 | min-height: 0 !important;
195 | max-height: none !important;
196 | max-width: 100% !important;
197 | margin: 0 2px 0 0 !important;
198 | text-indent: 0 !important;
199 | border: 0 none !important;
200 | background: none !important;
201 | line-height: inherit !important;
202 | -webkit-user-select: auto !important;
203 | -webkit-box-shadow: none !important;
204 | box-shadow: none !important;
205 | }
206 | .selectize-input > input::-ms-clear {
207 | display: none;
208 | }
209 | .selectize-input > input:focus {
210 | outline: none !important;
211 | }
212 | .selectize-input::after {
213 | content: ' ';
214 | display: block;
215 | clear: left;
216 | }
217 | .selectize-input.dropdown-active::before {
218 | content: ' ';
219 | display: block;
220 | position: absolute;
221 | background: #f0f0f0;
222 | height: 1px;
223 | bottom: 0;
224 | left: 0;
225 | right: 0;
226 | }
227 | .selectize-dropdown {
228 | position: absolute;
229 | z-index: 10;
230 | border: 1px solid #d0d0d0;
231 | background: #ffffff;
232 | margin: -1px 0 0 0;
233 | border-top: 0 none;
234 | -webkit-box-sizing: border-box;
235 | -moz-box-sizing: border-box;
236 | box-sizing: border-box;
237 | -webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
238 | box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
239 | -webkit-border-radius: 0 0 3px 3px;
240 | -moz-border-radius: 0 0 3px 3px;
241 | border-radius: 0 0 3px 3px;
242 | }
243 | .selectize-dropdown [data-selectable] {
244 | cursor: pointer;
245 | overflow: hidden;
246 | }
247 | .selectize-dropdown [data-selectable] .highlight {
248 | background: rgba(255, 237, 40, 0.4);
249 | -webkit-border-radius: 1px;
250 | -moz-border-radius: 1px;
251 | border-radius: 1px;
252 | }
253 | .selectize-dropdown [data-selectable],
254 | .selectize-dropdown .optgroup-header {
255 | padding: 7px 10px;
256 | }
257 | .selectize-dropdown .optgroup:first-child .optgroup-header {
258 | border-top: 0 none;
259 | }
260 | .selectize-dropdown .optgroup-header {
261 | color: #303030;
262 | background: #f8f8f8;
263 | cursor: default;
264 | }
265 | .selectize-dropdown .active {
266 | background-color: #fffceb;
267 | color: #303030;
268 | }
269 | .selectize-dropdown .active.create {
270 | color: #303030;
271 | }
272 | .selectize-dropdown .create {
273 | color: rgba(48, 48, 48, 0.5);
274 | }
275 | .selectize-dropdown-content {
276 | overflow-y: auto;
277 | overflow-x: hidden;
278 | max-height: 200px;
279 | }
280 | .selectize-control.single .selectize-input,
281 | .selectize-control.single .selectize-input input {
282 | cursor: pointer;
283 | }
284 | .selectize-control.single .selectize-input.input-active,
285 | .selectize-control.single .selectize-input.input-active input {
286 | cursor: text;
287 | }
288 | .selectize-control.single .selectize-input:after {
289 | content: ' ';
290 | display: block;
291 | position: absolute;
292 | top: 50%;
293 | right: 15px;
294 | margin-top: -3px;
295 | width: 0;
296 | height: 0;
297 | border-style: solid;
298 | border-width: 5px 5px 0 5px;
299 | border-color: #808080 transparent transparent transparent;
300 | }
301 | .selectize-control.single .selectize-input.dropdown-active:after {
302 | margin-top: -4px;
303 | border-width: 0 5px 5px 5px;
304 | border-color: transparent transparent #808080 transparent;
305 | }
306 | .selectize-control.rtl.single .selectize-input:after {
307 | left: 15px;
308 | right: auto;
309 | }
310 | .selectize-control.rtl .selectize-input > input {
311 | margin: 0 4px 0 -2px !important;
312 | }
313 | .selectize-control .selectize-input.disabled {
314 | opacity: 0.5;
315 | background-color: #fafafa;
316 | }
317 | .selectize-control.multi .selectize-input [data-value] {
318 | text-shadow: 0 1px 0 rgba(255, 255, 255, 0.1);
319 | -webkit-border-radius: 3px;
320 | -moz-border-radius: 3px;
321 | border-radius: 3px;
322 | background-color: #b2e567;
323 | background-image: -moz-linear-gradient(top, #b8e76f, #a9e25c);
324 | background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#b8e76f), to(#a9e25c));
325 | background-image: -webkit-linear-gradient(top, #b8e76f, #a9e25c);
326 | background-image: -o-linear-gradient(top, #b8e76f, #a9e25c);
327 | background-image: linear-gradient(to bottom, #b8e76f, #a9e25c);
328 | background-repeat: repeat-x;
329 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffb8e76f', endColorstr='#ffa9e25c', GradientType=0);
330 | -webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, 0.1);
331 | box-shadow: 0 1px 1px rgba(0, 0, 0, 0.1);
332 | }
333 | .selectize-control.multi .selectize-input [data-value].active {
334 | background-color: #88c332;
335 | background-image: -moz-linear-gradient(top, #92c836, #7abc2c);
336 | background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#92c836), to(#7abc2c));
337 | background-image: -webkit-linear-gradient(top, #92c836, #7abc2c);
338 | background-image: -o-linear-gradient(top, #92c836, #7abc2c);
339 | background-image: linear-gradient(to bottom, #92c836, #7abc2c);
340 | background-repeat: repeat-x;
341 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff92c836', endColorstr='#ff7abc2c', GradientType=0);
342 | }
343 | .selectize-control.single .selectize-input {
344 | -webkit-box-shadow: inset 0 1px 0 rgba(255,255,255,0.8), 0 2px 0 #e0e0e0, 0 3px 0 #c8c8c8, 0 4px 1px rgba(0,0,0,0.1);
345 | box-shadow: inset 0 1px 0 rgba(255,255,255,0.8), 0 2px 0 #e0e0e0, 0 3px 0 #c8c8c8, 0 4px 1px rgba(0,0,0,0.1);
346 | background-color: #f3f3f3;
347 | background-image: -moz-linear-gradient(top, #f5f5f5, #efefef);
348 | background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#f5f5f5), to(#efefef));
349 | background-image: -webkit-linear-gradient(top, #f5f5f5, #efefef);
350 | background-image: -o-linear-gradient(top, #f5f5f5, #efefef);
351 | background-image: linear-gradient(to bottom, #f5f5f5, #efefef);
352 | background-repeat: repeat-x;
353 | filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffefefef', GradientType=0);
354 | }
355 | .selectize-control.single .selectize-input,
356 | .selectize-dropdown.single {
357 | border-color: #b8b8b8;
358 | }
359 | .selectize-dropdown .optgroup-header {
360 | font-weight: bold;
361 | font-size: 0.8em;
362 | border-bottom: 1px solid #f0f0f0;
363 | border-top: 1px solid #f0f0f0;
364 | }
365 |
--------------------------------------------------------------------------------