├── .gitignore ├── LICENSE ├── MANIFEST.in ├── README.md ├── demo_ezhc.ipynb ├── demo_ezhc_themes_and_global_options.ipynb ├── ezhc ├── __init__.py ├── __meta__.py ├── _clock.py ├── _config.py ├── _global_options.py ├── _hc_versions.py ├── _highcharts.py ├── _highstock.py ├── _img.py ├── _plot.py ├── _proxy.py ├── _state.py ├── _theme.py ├── _wrapper.py ├── api │ ├── hc_object.json │ ├── hc_option.json │ ├── hs_object.json │ └── hs_option.json ├── build.py ├── sample.py ├── samples │ ├── build_data_world_population.py │ ├── build_samples.py │ ├── data_population.py │ ├── df_bubble.csv │ ├── df_heatmap.csv │ ├── df_one_idx_one_col.csv │ ├── df_one_idx_several_col.csv │ ├── df_one_idx_several_col_2.csv │ ├── df_one_idx_two_col.csv │ ├── df_scatter.csv │ ├── df_several_idx_one_col.csv │ ├── df_several_idx_one_col_2.csv │ ├── df_two_idx_one_col.csv │ └── df_two_idx_several_col.csv ├── script │ ├── Jupyter_logo.png │ ├── SG_logo.png │ ├── financial_time_series_0.js │ ├── financial_time_series_table.html │ ├── financial_time_series_table_1.js │ ├── financial_time_series_table_2.js │ ├── financial_time_series_table_options_1.js │ ├── financial_time_series_table_options_2.js │ ├── formatter_basic.js │ ├── formatter_percent.js │ ├── formatter_quantile.js │ ├── json_parse.js │ ├── template_disclaimer.html │ ├── themes │ │ ├── avocado.js │ │ ├── avocado.json │ │ ├── build_theme_json.ipynb │ │ ├── dark-blue.js │ │ ├── dark-blue.json │ │ ├── dark-green.js │ │ ├── dark-green.json │ │ ├── dark-unica.js │ │ ├── dark-unica.json │ │ ├── gray.js │ │ ├── gray.json │ │ ├── grid-light.js │ │ ├── grid-light.json │ │ ├── grid.js │ │ ├── grid.json │ │ ├── sand-signika.js │ │ ├── sand-signika.json │ │ ├── skies.js │ │ ├── skies.json │ │ ├── sunset.js │ │ └── sunset.json │ ├── tooltip_positioner_center_top.js │ ├── tooltip_positioner_left_top.js │ └── tooltip_positioner_right_top.js ├── scripts.py └── series.py ├── requirements.txt ├── setup.cfg └── setup.py /.gitignore: -------------------------------------------------------------------------------- 1 | .idea/ 2 | 3 | *.py[cod] 4 | saved/ 5 | .vscode/ 6 | *.ipynb_checkpoints/ 7 | 8 | dist 9 | build 10 | *.egg-info 11 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2017 Olivier Borderies 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 13 | all 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 21 | THE SOFTWARE. -------------------------------------------------------------------------------- /MANIFEST.in: -------------------------------------------------------------------------------- 1 | # necessary to push to PyPI 2 | # cf. https://tom-christie.github.io/articles/pypi/ 3 | 4 | # subfolders 5 | recursive-include ezhc/api *.json 6 | recursive-include ezhc/samples df_*.csv 7 | recursive-include ezhc/script * 8 | recursive-exclude ezhc/script/themes/.ipynb_checkpoints * 9 | 10 | global-exclude *.py[co] 11 | 12 | # Misc 13 | include LICENSE 14 | include requirements.txt 15 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ezhc 2 | 3 | ## 1 - Introduction 4 | 5 | **ezhc** stands for easy Highcharts. 6 | [Highcharts](http://www.highcharts.com/) is a popular, flexible, versatile, user friendly visualisation javascript library. 7 | Currently only [Highcharts](http://www.highcharts.com/demo) and [Highstock](http://www.highcharts.com/stock/demo), not [Highmap](http://www.highcharts.com/maps/demo). 8 | 9 | **ezhc** is a wrapper that lets you transparently access the full configuration options of the library as described in their APIs, directly from the [Jupyter notebook](http://jupyter.org/): 10 | + [Highcharts](http://api.highcharts.com/highcharts) 11 | + [Highstock](http://api.highcharts.com/highstock) 12 | 13 | You need bring the data in a [pandas](http://pandas.pydata.org/) dataframe as shown in the many examples in the [demo notebook](http://nbviewer.ipython.org/github/oscar6echo/ezhc/blob/master/demo_ezhc.ipynb). 14 | 15 | To update global options and apply themes see the [demo notebook for global options and styles](http://nbviewer.ipython.org/github/oscar6echo/ezhc/blob/master/demo_ezhc_themes_and_global_options.ipynb). 16 | The highcharts [official themes](https://github.com/highcharts/highcharts/tree/master/js/themes) are available in **ezhc**. 17 | 18 | ## 2 - Install 19 | 20 | To install run from command line: 21 | ``` 22 | pip install ezhc 23 | ``` 24 | 25 | ## 3 - Exceptions 26 | 27 | There are exceptions to the transparent wrapping approach: 28 | I added 2 datatables ([datatables.net](http://datatables.net/)) linked to the Highstock call. 29 | A footer (described in HTML) can be added below a plot. If the footer contains an image, it will be burned into the standalone file upon save. 30 | Cf. examples in the [demo notebook](http://nbviewer.ipython.org/github/oscar6echo/ezhc/blob/master/demo_ezhc.ipynb). 31 | 32 | 33 | -------------------------------------------------------------------------------- /ezhc/__init__.py: -------------------------------------------------------------------------------- 1 | 2 | 3 | # from ._config import load_js_libs 4 | from ._proxy import Proxy 5 | 6 | from ._highcharts import Highcharts 7 | from ._highstock import Highstock 8 | from ._global_options import GlobalOptions 9 | from ._theme import Theme 10 | from . import sample 11 | from . import build 12 | from ._clock import Clock 13 | 14 | 15 | __all__ = ['Highcharts', 16 | 'Highstock', 17 | 'GlobalOptions', 18 | 'Theme', 19 | 'sample', 20 | 'build', 21 | 'Clock', 22 | ] 23 | 24 | 25 | # load_js_libs() 26 | -------------------------------------------------------------------------------- /ezhc/__meta__.py: -------------------------------------------------------------------------------- 1 | 2 | __name__ = 'ezhc' 3 | name_url = __name__.replace('_', '-') 4 | 5 | __packages__ = [__name__] 6 | __version__ = '0.7.12' 7 | __description__ = 'easy Highcharts & Highstock, dynamic plots from pandas dataframes in the Jupyter notebook' 8 | __author__ = 'oscar6echo' 9 | __author_email__ = 'olivier.borderies@gmail.com' 10 | __url__ = 'https://github.com/{}/{}'.format(__author__, 11 | name_url) 12 | __download_url__ = 'https://github.com/{}/{}/tarball/{}'.format(__author__, 13 | name_url, 14 | __version__) 15 | __keywords__ = ['Highcharts', 'Highstock', 'pandas', 'notebook', 'javascript'] 16 | __license__ = 'MIT' 17 | __classifiers__ = ['Development Status :: 4 - Beta', 18 | 'License :: OSI Approved :: MIT License', 19 | 'Programming Language :: Python :: 2.7', 20 | 'Programming Language :: Python :: 3.5', 21 | 'Programming Language :: Python :: 3.6', 22 | 'Programming Language :: Python :: 3.7', 23 | 'Programming Language :: Python :: 3.8', 24 | ] 25 | __include_package_data__ = True 26 | __package_data__ = {} 27 | 28 | __zip_safe__ = False 29 | __entry_points__ = {} 30 | -------------------------------------------------------------------------------- /ezhc/_clock.py: -------------------------------------------------------------------------------- 1 | 2 | from ._highcharts import Highcharts 3 | 4 | 5 | 6 | class Clock(Highcharts): 7 | """ 8 | Highcharts Clock 9 | https://jsfiddle.net/gh/get/jquery/1.9.1/highslide-software/highcharts.com/tree/master/samples/highcharts/demo/gauge-clock/ 10 | """ 11 | 12 | def __init__(self): 13 | 14 | Highcharts.__init__(self) 15 | 16 | self.js_extra = """ 17 | function getNow() { 18 | var now = new Date(); 19 | 20 | return { 21 | hours: now.getHours() + now.getMinutes() / 60, 22 | minutes: now.getMinutes() * 12 / 60 + now.getSeconds() * 12 / 3600, 23 | seconds: now.getSeconds() * 12 / 60 24 | }; 25 | } 26 | 27 | var now = getNow(); 28 | 29 | function pad(number, length) { 30 | // Create an array of the remaining length + 1 and join it with 0's 31 | return new Array((length || 2) + 1 - String(number).length).join(0) + number; 32 | } 33 | 34 | 35 | // Extend jQuery with some easing (copied from jQuery UI) 36 | $.extend($.easing, { 37 | easeOutElastic: function (x, t, b, c, d) { 38 | var s=1.70158;var p=0;var a=c; 39 | if (t==0) return b; if ((t/=d)==1) return b+c; if (!p) p=d*.3; 40 | if (a < Math.abs(c)) { a=c; var s=p/4; } 41 | else var s = p/(2*Math.PI) * Math.asin (c/a); 42 | return a*Math.pow(2,-10*t) * Math.sin( (t*d-s)*(2*Math.PI)/p ) + c + b; 43 | } 44 | }); 45 | """ 46 | 47 | self.callback = """ 48 | function (chart) { 49 | setInterval(function () { 50 | 51 | now = getNow(); 52 | 53 | var hour = chart.get('hour'), 54 | minute = chart.get('minute'), 55 | second = chart.get('second'), 56 | // run animation unless we're wrapping around from 59 to 0 57 | animation = now.seconds === 0 ? false : { easing: 'easeOutElastic' }; 58 | 59 | // Cache the tooltip text 60 | chart.tooltipText = 61 | pad(Math.floor(now.hours), 2) + ':' + 62 | pad(Math.floor(now.minutes * 5), 2) + ':' + 63 | pad(now.seconds * 5, 2); 64 | 65 | hour.update(now.hours, true, animation); 66 | minute.update(now.minutes, true, animation); 67 | second.update(now.seconds, true, animation); 68 | 69 | }, 1000); 70 | } 71 | """ 72 | 73 | self.g = Highcharts() 74 | 75 | self.g.chart = { 76 | 'type': 'gauge', 77 | 'plotBackgroundColor': None, 78 | 'plotBackgroundImage': None, 79 | 'plotBorderWidth': 0, 80 | 'plotShadow': False, 81 | 'height': 250 82 | } 83 | 84 | self.g.title.text = 'The Highcharts Clock' 85 | 86 | self.g.pane.background = [ 87 | # default background 88 | {}, 89 | # reflex for supported browsers 90 | {'backgroundColor': { 91 | 'radialGradient': { 92 | 'cx': 0.5, 93 | 'cy': -0.4, 94 | 'r': 1.9 95 | }, 96 | 'stops': [ 97 | [0.5, 'rgba(255, 255, 255, 0.2)'], 98 | [0.5, 'rgba(200, 200, 200, 0.2)'] 99 | ] 100 | }} 101 | ] 102 | 103 | self.g.yAxis = { 104 | 'labels': { 'distance': -20 }, 105 | 'min': 0, 106 | 'max': 12, 107 | 'lineWidth': 0, 108 | 'showFirstLabel': False, 109 | 110 | 'minorTickInterval': 'auto', 111 | 'minorTickWidth': 1, 112 | 'minorTickLength': 5, 113 | 'minorTickPosition': 'inside', 114 | 'minorGridLineWidth': 0, 115 | 'minorTickColor': '#666', 116 | 117 | 'tickInterval': 1, 118 | 'tickWidth': 2, 119 | 'tickPosition': 'inside', 120 | 'tickLength': 10, 121 | 'tickColor': '#666', 122 | } 123 | 124 | self.g.tooltip.formatter = 'function() { return this.series.chart.tooltipText; }' 125 | 126 | self.g.exporting.enabled = False 127 | 128 | self.g.series = [{ 129 | 'data': [{ 130 | 'id': 'hour', 131 | 'y': '(function() { var now = new Date(); return now.getHours() + now.getMinutes() / 60; })()', 132 | 'dial': { 133 | 'radius': '60%', 134 | 'baseWidth': 4, 135 | 'baseLength': '95%', 136 | 'rearLength': 0 137 | } 138 | }, { 139 | 'id': 'minute', 140 | 'y': '(function() { var now = new Date(); return now.getMinutes() * 12 / 60 + now.getSeconds() * 12 / 3600; })()', 141 | 'dial': { 142 | 'baseLength': '95%', 143 | 'rearLength': 0 144 | } 145 | }, { 146 | 'id': 'second', 147 | 'y': '(function() { var now = new Date(); return now.getSeconds() * 12 / 60; })()', 148 | 'dial': { 149 | 'radius': '100%', 150 | 'baseWidth': 1, 151 | 'rearLength': '20%' 152 | } 153 | }], 154 | 'animation': False, 155 | 'dataLabels': { 156 | 'enabled': False 157 | } 158 | }] 159 | 160 | 161 | 162 | def _repr_html_(self): 163 | return self.g.html(js_extra=self.js_extra, callback=self.callback) 164 | 165 | 166 | 167 | -------------------------------------------------------------------------------- /ezhc/_config.py: -------------------------------------------------------------------------------- 1 | 2 | import json 3 | from IPython.display import display, HTML, Javascript 4 | 5 | 6 | JS_SAVE = [ 7 | 'https://cdnjs.cloudflare.com/ajax/libs/require.js/2.1.17/require.js', 8 | 'https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.4/jquery.min.js', 9 | ] 10 | 11 | # JS_LIBS_ONE = json.dumps([ 12 | JS_LIBS_ONE = [ 13 | 'jquery', 14 | 'https://code.highcharts.com/stock/{}highstock.js', 15 | 'https://d3js.org/d3.v3.min.js', 16 | ] 17 | # ]) 18 | 19 | # JS_LIBS_ONE_sep = ';'.join(map(lambda x: 'console.log("'+x+'")', json.loads(JS_LIBS_ONE)))+';' 20 | 21 | # See CDN https://code.highcharts.com/ 22 | 23 | # JS_LIBS_TWO = json.dumps([ 24 | JS_LIBS_TWO = [ 25 | 'https://code.highcharts.com/stock/{}highcharts-more.js', 26 | 'https://code.highcharts.com/stock/{}modules/exporting.js', 27 | 'https://code.highcharts.com/stock/{}modules/offline-exporting.js', 28 | 'https://code.highcharts.com/stock/{}modules/export-data.js', 29 | 'https://code.highcharts.com/stock/{}modules/drilldown.js', 30 | 'https://code.highcharts.com/stock/{}modules/heatmap.js', 31 | 'https://code.highcharts.com/stock/{}modules/treemap.js', 32 | 'https://code.highcharts.com/stock/{}modules/sunburst.js', 33 | 'https://cdn.datatables.net/1.10.10/js/jquery.dataTables.min.js', 34 | ] 35 | # ]) 36 | 37 | # JS_LIBS_TWO_sep = ';'.join(map(lambda x: 'console.log("'+x+'")', json.loads(JS_LIBS_TWO)))+';' 38 | 39 | 40 | # JS_LOAD = """ 41 | # require(%s, function() { 42 | # require(%s, function() { 43 | # console.log("The following js libs loaded:"); 44 | # console.log("First:"); 45 | # %s 46 | # console.log("Then:"); 47 | # %s 48 | # }); 49 | # });""" % (JS_LIBS_ONE, JS_LIBS_TWO, JS_LIBS_ONE_sep, JS_LIBS_TWO_sep) 50 | 51 | 52 | def load_js_libs(): 53 | display(Javascript(JS_LOAD)) 54 | 55 | 56 | API_DIR = 'api' 57 | SCRIPT_DIR = 'script' 58 | SAMPLES_DIR = 'samples' 59 | 60 | HC_OBJECT_FILE = 'hc_object.json' 61 | HC_OPTION_FILE = 'hc_option.json' 62 | 63 | HS_OBJECT_FILE = 'hs_object.json' 64 | HS_OPTION_FILE = 'hs_option.json' 65 | 66 | FULLNAME = 'fullname' 67 | DESCRIPTION = 'description' 68 | DEMO = 'demo' 69 | 70 | 71 | DF_ONE_IDX_SEVERAL_COL = 'df_one_idx_several_col.csv' 72 | DF_ONE_IDX_SEVERAL_COL_2 = 'df_one_idx_several_col_2.csv' 73 | DF_ONE_IDX_ONE_COL = 'df_one_idx_one_col.csv' 74 | DF_ONE_IDX_TWO_COL = 'df_one_idx_two_col.csv' 75 | DF_TWO_IDX_ONE_COL = 'df_two_idx_one_col.csv' 76 | DF_SCATTER = 'df_scatter.csv' 77 | DF_BUBBLE = 'df_bubble.csv' 78 | DF_HEATMAP = 'df_heatmap.csv' 79 | DF_SEVERAL_IDX_ONE_COL = 'df_several_idx_one_col.csv' 80 | DF_SEVERAL_IDX_ONE_COL_2 = 'df_several_idx_one_col_2.csv' 81 | DF_TWO_IDX_SEVERAL_COL = 'df_two_idx_several_col.csv' 82 | -------------------------------------------------------------------------------- /ezhc/_global_options.py: -------------------------------------------------------------------------------- 1 | 2 | import json 3 | import pandas as pd 4 | 5 | from IPython.display import display, Javascript, Markdown 6 | 7 | from ._config import JS_LIBS_ONE, JS_LIBS_TWO, JS_SAVE 8 | from .scripts import JS_JSON_PARSE 9 | 10 | 11 | class GlobalOptions: 12 | """ 13 | Used to pass global options to Highcharts object 14 | 15 | API: https://api.highcharts.com/highcharts 16 | Demos: https://www.highcharts.com/demo 17 | """ 18 | 19 | def __init__(self, data): 20 | self.options = data 21 | self.js = None 22 | 23 | def _json_dumps(self, obj): 24 | return pd.io.json.dumps(obj) 25 | 26 | def create(self): 27 | 28 | if isinstance(self.options, dict): 29 | json_options = self._json_dumps(self.options) 30 | else: 31 | json_options = self.options 32 | 33 | js_default = """ 34 | if (window.HCDefaults == undefined) { 35 | window.HCDefaults = $.extend(true, {}, Highcharts.getOptions(), {}); 36 | console.log('Highcharts global default options accessible as HCDefaults'); 37 | } 38 | """ 39 | 40 | js_option = """ 41 | var options = %s; 42 | %s 43 | window.globalOptions = $.extend(true, {}, options); 44 | console.log(globalOptions); 45 | if (window.globalOptions == undefined) { 46 | window.globalOptions = {}; 47 | } 48 | 49 | console.log('Highcharts global options accessible as globalOptions'); 50 | """ % (json_options, JS_JSON_PARSE) 51 | 52 | js_call = 'Highcharts.setOptions(options);' 53 | 54 | js = """ 55 | // the Jupyter notebook loads jquery.min.js and require.js and at the top of the page 56 | // then to make jquery available inside a require module 57 | // the trick is http://www.manuel-strehl.de/dev/load_jquery_before_requirejs.en.html 58 | define('jquery', [], function() { 59 | return jQuery; 60 | }); 61 | 62 | require(%s, function() { 63 | require(%s, function() { 64 | %s 65 | %s 66 | %s 67 | }); 68 | }); 69 | """ % (JS_LIBS_ONE, JS_LIBS_TWO, js_default, js_option, js_call) 70 | 71 | return js 72 | 73 | def inject(self, verbose=False): 74 | if not self.js: 75 | self.js = self.create() 76 | if verbose: 77 | md = """ 78 | Highcharts **global options** set in this cell: 79 | ```json 80 | {} 81 | ``` 82 | """.format(self._json_dumps(self.options)) 83 | display(Markdown(md)) 84 | display(Javascript(self.js)) 85 | 86 | def reset(self, verbose=False): 87 | js_reset = """ 88 | let ResetOptions = function() { 89 | if (window.HCDefaults){ 90 | var defaultOptions = Highcharts.getOptions(); 91 | for (var prop in defaultOptions) { 92 | if (typeof defaultOptions[prop] !== 'function') { 93 | delete defaultOptions[prop] 94 | } 95 | else { 96 | console.log(prop); 97 | }; 98 | } 99 | Highcharts.setOptions(window.HCDefaults); 100 | console.log('Highcharts global options reset to default ie HCDefaults'); 101 | } 102 | } 103 | ResetOptions(); 104 | """ 105 | 106 | if verbose: 107 | md = """ 108 | Highcharts **global options** reset to default. 109 | """ 110 | display(Markdown(md)) 111 | display(Javascript(js_reset)) 112 | -------------------------------------------------------------------------------- /ezhc/_hc_versions.py: -------------------------------------------------------------------------------- 1 | 2 | import json 3 | import requests as rq 4 | from ._proxy import Proxy 5 | 6 | 7 | def get_hc_versions(proxy=None): 8 | """ 9 | retrieve highcharts versions 10 | """ 11 | 12 | proxies = {} 13 | if proxy: 14 | assert isinstance(proxy, Proxy) 15 | proxies = proxy.proxies 16 | 17 | url = 'https://registry.npmjs.org/highcharts' 18 | headers = {'Accept': 'application/vnd.npm.install-v1+json'} 19 | 20 | try: 21 | r = rq.get(url, headers=headers) 22 | res = json.loads(r.content.decode('utf-8')) 23 | versions = list(res['versions'].keys()) 24 | 25 | except: 26 | # to be updated from time to time 27 | versions = [ 28 | '0.0.1', '0.0.2', '0.0.3', '0.0.4', '0.0.5', '0.0.6', '0.0.8', '0.0.9', '0.0.10', 29 | '0.0.11', '4.1.10', '4.2.0', '4.2.1', '4.2.2', '4.2.3', '4.2.4', '4.2.5', '4.2.6', 30 | '4.2.7', '5.0.0', '5.0.1', '5.0.2', '5.0.3', '5.0.4', '5.0.5', '5.0.6', '5.0.7', 31 | '5.0.8', '5.0.9', '5.0.10', '5.0.11', '5.0.12', '5.0.13', '5.0.14', '6.0.0', '6.0.1', 32 | '6.0.2', '6.0.3', '6.0.4', '6.0.5', '6.0.6', '6.0.7', '5.0.15', '6.1.0', '6.1.1', 33 | '6.1.2'] 34 | 35 | return versions 36 | -------------------------------------------------------------------------------- /ezhc/_highcharts.py: -------------------------------------------------------------------------------- 1 | 2 | from ._wrapper import Wrapper 3 | from ._plot import plot, html, opt_to_dict, opt_to_json 4 | 5 | 6 | class Highcharts(Wrapper): 7 | """ 8 | Main Highcharts Object 9 | 10 | API: https://api.highcharts.com/highcharts 11 | Demos: https://www.highcharts.com/demo 12 | """ 13 | 14 | def __init__(self): 15 | Wrapper.__init__(self, lib='highcharts') 16 | 17 | # default config 18 | self.credits.enabled = False 19 | self.exporting.enabled = True 20 | self.chart.animation = False 21 | self.series.animation = False 22 | 23 | self.plotOptions.series.animation = False 24 | self.plotOptions.line.animation = False 25 | self.plotOptions.column.animation = False 26 | self.plotOptions.bar.animation = False 27 | self.plotOptions.pie.animation = False 28 | self.plotOptions.scatter.animation = False 29 | self.plotOptions.bubble.animation = False 30 | self.plotOptions.treemap.animation = False 31 | 32 | def options_as_dict(self, chart_id='chart_id'): 33 | opt = self.to_dict() 34 | return opt_to_dict(opt, chart_id=chart_id) 35 | 36 | def options_as_json(self, chart_id='chart_id', save=False, save_name=None, save_path='saved'): 37 | opt = self.to_dict() 38 | return opt_to_json(opt, chart_id=chart_id, save=save, save_name=save_name, 39 | save_path=save_path) 40 | 41 | def plot(self, dated=True, save=False, save_name=None, save_path='saved', notebook=True, 42 | html_init=None, js_option_postprocess=None, js_extra=None, callback=None, 43 | version='latest', proxy=None, center=False): 44 | opt = self.to_dict() 45 | return plot(opt, lib='highcharts', dated=dated, save=save, save_name=save_name, 46 | save_path=save_path, notebook=notebook, 47 | html_init=html_init, js_option_postprocess=js_option_postprocess, 48 | js_extra=js_extra, callback=callback, version=version, proxy=proxy, 49 | center=center) 50 | 51 | def html(self, dated=True, save=False, save_name=None, save_path='saved', notebook=True, 52 | html_init=None, js_option_postprocess=None, js_extra=None, callback=None, 53 | version='latest', proxy=None, center=False): 54 | opt = self.to_dict() 55 | return html(opt, lib='highcharts', dated=dated, save=save, save_name=save_name, 56 | save_path=save_path, notebook=notebook, 57 | html_init=html_init, js_option_postprocess=js_option_postprocess, 58 | js_extra=js_extra, callback=callback, version=version, proxy=proxy, 59 | center=center) 60 | -------------------------------------------------------------------------------- /ezhc/_highstock.py: -------------------------------------------------------------------------------- 1 | 2 | from ._wrapper import Wrapper 3 | from ._plot import plot, html, opt_to_dict, opt_to_json 4 | from .scripts import JS_FINANCIAL_TIME_SERIES_0, \ 5 | JS_FINANCIAL_TIME_SERIES_TABLE_1, \ 6 | JS_FINANCIAL_TIME_SERIES_TABLE_2, \ 7 | JS_FINANCIAL_TIME_SERIES_TABLE_OPTIONS_1, \ 8 | JS_FINANCIAL_TIME_SERIES_TABLE_OPTIONS_2, \ 9 | HTML_FINANCIAL_TIME_SERIES_TABLE, \ 10 | JS_FINANCIAL_TIME_SERIES_TABLE_CALLBACK_0, \ 11 | JS_FINANCIAL_TIME_SERIES_TABLE_CALLBACK_1, \ 12 | JS_FINANCIAL_TIME_SERIES_TABLE_CALLBACK_2 13 | 14 | 15 | class Highstock(Wrapper): 16 | """ 17 | Main Highstock Object 18 | 19 | API: https://api.highcharts.com/highstock 20 | Demos: https://www.highcharts.com/stock/demo 21 | """ 22 | 23 | def __init__(self): 24 | Wrapper.__init__(self, lib='highstock') 25 | 26 | # default config 27 | self.credits.enabled = False 28 | self.exporting.enabled = True 29 | self.chart.animation = False 30 | 31 | self.plotOptions.series.animation = False 32 | self.plotOptions.line.animation = False 33 | self.plotOptions.column.animation = False 34 | 35 | def options_as_dict(self, chart_id='chart_id'): 36 | opt = self.to_dict() 37 | return opt_to_dict(opt, chart_id=chart_id) 38 | 39 | def options_as_json(self, chart_id='chart_id', save=False, save_name=None, save_path='saved'): 40 | opt = self.to_dict() 41 | return opt_to_json(opt, chart_id=chart_id, save=save, save_name=save_name, 42 | save_path=save_path) 43 | 44 | def html(self, dated=True, save=False, save_name=None, save_path='saved', notebook=True, 45 | html_init=None, js_option_postprocess=None, js_extra=None, callback=None, 46 | version='latest', proxy=None, center=False): 47 | opt = self.to_dict() 48 | return html(opt, lib='highstock', dated=dated, save=save, save_name=save_name, 49 | save_path=save_path, notebook=notebook, 50 | html_init=html_init, js_option_postprocess=js_option_postprocess, 51 | js_extra=js_extra, callback=callback, version=version, proxy=proxy, 52 | center=center) 53 | 54 | def plot(self, dated=True, save=False, save_name=None, save_path='saved', notebook=True, 55 | html_init=None, js_option_postprocess=None, js_extra=None, callback=None, footer=None, 56 | version='latest', proxy=None, center=False): 57 | """Only Highstock. No add-on.""" 58 | opt = self.to_dict() 59 | js_extra = JS_FINANCIAL_TIME_SERIES_0 60 | callback = JS_FINANCIAL_TIME_SERIES_TABLE_CALLBACK_0 61 | 62 | return plot(opt, lib='highstock', dated=dated, save=save, save_name=save_name, 63 | save_path=save_path, notebook=notebook, 64 | html_init=html_init, js_option_postprocess=js_option_postprocess, 65 | js_extra=js_extra, callback=callback, footer=footer, version=version, 66 | proxy=proxy, center=center) 67 | 68 | def plot_with_table_1( 69 | self, dated=True, save=False, save_name=None, save_path='saved', notebook=True, 70 | footer=None, version='latest', proxy=None): 71 | """ 72 | Table with Perf, IRR, Vol, Sharpe Ratio, Max Drawdown 73 | Sharpe ratio is based on time series 'Cash' meaning cash compounded 74 | If no Cash colmun rates are assumed zero. 75 | """ 76 | opt = self.to_dict() 77 | html_init = HTML_FINANCIAL_TIME_SERIES_TABLE 78 | js_option_postprocess = JS_FINANCIAL_TIME_SERIES_TABLE_OPTIONS_1 79 | js_extra = JS_FINANCIAL_TIME_SERIES_TABLE_1 80 | callback = JS_FINANCIAL_TIME_SERIES_TABLE_CALLBACK_1 81 | 82 | return plot(opt, lib='highstock', dated=dated, save=save, save_name=save_name, 83 | save_path=save_path, notebook=notebook, 84 | html_init=html_init, js_option_postprocess=js_option_postprocess, 85 | js_extra=js_extra, callback=callback, footer=footer, 86 | version='latest', proxy=None) 87 | 88 | def plot_with_table_2( 89 | self, dated=True, save=False, save_name=None, save_path='saved', notebook=True, 90 | footer=None, version='latest', proxy=None): 91 | """ 92 | Table with Min, Max, Average, Max Drawdown 93 | """ 94 | opt = self.to_dict() 95 | html_init = HTML_FINANCIAL_TIME_SERIES_TABLE 96 | js_option_postprocess = JS_FINANCIAL_TIME_SERIES_TABLE_OPTIONS_2 97 | js_extra = JS_FINANCIAL_TIME_SERIES_TABLE_2 98 | callback = JS_FINANCIAL_TIME_SERIES_TABLE_CALLBACK_2 99 | 100 | return plot(opt, lib='highstock', dated=dated, save=save, save_name=save_name, 101 | save_path=save_path, notebook=notebook, 102 | html_init=html_init, js_option_postprocess=js_option_postprocess, 103 | js_extra=js_extra, callback=callback, footer=footer, 104 | version=version, proxy=proxy) 105 | -------------------------------------------------------------------------------- /ezhc/_img.py: -------------------------------------------------------------------------------- 1 | 2 | import requests 3 | import base64 4 | 5 | requests.packages.urllib3.disable_warnings() 6 | 7 | 8 | def is_http_url(img_path): 9 | img_path = img_path.lower() 10 | return (img_path.startswith("http://") or 11 | img_path.startswith("https://")) 12 | 13 | 14 | def image_base64(imgpath): 15 | with open(imgpath, 'rb') as obj: 16 | return base64.b64encode(obj.read()).decode('utf-8') 17 | 18 | 19 | def image_content(img_path): 20 | """Get the image content according to its path 21 | Different case: 22 | - PNG,JPEG: convert it to base64 23 | - SVG: open it and read it 24 | - HTTP URL: get the content via requests.get 25 | """ 26 | if is_http_url(img_path): 27 | content = requests.get(img_path, verify=False).content 28 | if img_path.endswith(".svg"): 29 | return content 30 | return base64.b64encode(content).decode('utf-8') 31 | if img_path.endswith(".svg"): 32 | return open(img_path).read() 33 | return image_base64(img_path) 34 | 35 | 36 | def image_src(img_path): 37 | content = image_content(img_path) 38 | if img_path.endswith('.svg'): 39 | return '{}'.format(content) 40 | else: 41 | return 'data:image/png;base64,{}'.format(content) 42 | -------------------------------------------------------------------------------- /ezhc/_plot.py: -------------------------------------------------------------------------------- 1 | 2 | import os 3 | import uuid 4 | import pandas as pd 5 | import datetime as dt 6 | from IPython.display import HTML 7 | from copy import deepcopy as copy 8 | 9 | from ._config import JS_LIBS_ONE, JS_LIBS_TWO, JS_SAVE 10 | from ._hc_versions import get_hc_versions 11 | from .scripts import JS_JSON_PARSE 12 | 13 | 14 | def opt_to_dict(options, chart_id='chart_id'): 15 | """ 16 | returns dictionary of options for highcharts/highstocks object 17 | with field chart:renderTo set to arg chart_id 18 | """ 19 | 20 | _options = dict(options) 21 | _options['chart']['renderTo'] = chart_id 22 | return _options 23 | 24 | 25 | def opt_to_json(options, chart_id='chart_id', save=False, save_name=None, save_path='saved'): 26 | """ 27 | returns json of options for highcharts/highstocks object 28 | """ 29 | def json_dumps(obj): 30 | return pd.io.json.ujson_dumps(obj) 31 | 32 | _options = opt_to_dict(options, chart_id) 33 | json_options = json_dumps(_options) 34 | 35 | # save 36 | if save == True: 37 | if not os.path.exists(save_path): 38 | os.makedirs(save_path) 39 | tag = save_name if save_name else 'plot' 40 | with open(os.path.join(save_path, tag + '.json'), 'w') as f: 41 | f.write(json_options) 42 | 43 | return json_options 44 | 45 | 46 | def html( 47 | options, lib='highcharts', dated=True, save=False, save_name=None, save_path='saved', 48 | notebook=True, html_init=None, js_option_postprocess=None, js_extra=None, callback=None, 49 | footer=None, version='latest', proxy=None, center=False): 50 | """ 51 | save=True will create a standalone HTML doc under save_path directory (after creating folder if necessary) 52 | """ 53 | 54 | def json_dumps(obj): 55 | return pd.io.json.dumps(obj) 56 | 57 | chart_id = str(uuid.uuid4()).replace('-', '_') 58 | 59 | _options = dict(options) 60 | _options['chart']['renderTo'] = chart_id + 'container_chart' 61 | json_options = json_dumps(_options).replace('__uuid__', chart_id) 62 | 63 | # HIGHCHARTS VERSION 64 | hc_versions = get_hc_versions(proxy) 65 | if version is None: 66 | v = '' 67 | elif version == 'latest': 68 | v = hc_versions[-1] + '/' 69 | else: 70 | msg = 'version must be a valid highcharts version - see https://github.com/highcharts/highcharts/releases' 71 | assert version in hc_versions, msg 72 | v = version + '/' 73 | 74 | JS_LIBS_ONE_version = copy(JS_LIBS_ONE) 75 | for k, e in enumerate(JS_LIBS_ONE_version): 76 | if 'highcharts.com' in e: 77 | JS_LIBS_ONE_version[k] = e.format(v) 78 | 79 | JS_LIBS_TWO_version = copy(JS_LIBS_TWO) 80 | for k, e in enumerate(JS_LIBS_TWO_version): 81 | if 'highcharts.com' in e: 82 | JS_LIBS_TWO_version[k] = e.format(v) 83 | 84 | # HTML 85 | if center: 86 | html = '
' 87 | else: 88 | html = '
' 89 | 90 | html_init = html_init if html_init else '' 91 | if html_init: 92 | html = html_init + html 93 | 94 | footer = footer if footer else '' 95 | html = html + footer 96 | html = html.replace('__uuid__', chart_id) 97 | 98 | # JS 99 | js_option_postprocess = js_option_postprocess.replace( 100 | '__uuid__', chart_id) if js_option_postprocess else '' 101 | js_extra = js_extra if js_extra else '' 102 | callback = ', ' + \ 103 | callback.replace('__uuid__', chart_id) if callback else '' 104 | 105 | js_option = """ 106 | var options = %s; 107 | %s 108 | %s 109 | 110 | var opt = $.extend(true, {}, options); 111 | if (window.opts==undefined) { 112 | window.opts = {}; 113 | } 114 | window.opts['__uuid__'] = opt; 115 | 116 | console.log('Highcharts/Highstock options accessible as opts["__uuid__"]'); 117 | """.replace('__uuid__', chart_id) % (json_options, JS_JSON_PARSE, js_option_postprocess) 118 | 119 | if lib == 'highcharts': 120 | js_call = 'window.chart = new Highcharts.Chart(options%s);' % ( 121 | callback) 122 | elif lib == 'highstock': 123 | js_call = 'window.chart = new Highcharts.StockChart(options%s);' % ( 124 | callback) 125 | 126 | js_debug = """ 127 | console.log('Highcharts/Highstock chart accessible as charts["__uuid__"]'); 128 | """.replace('__uuid__', chart_id) 129 | 130 | js = """""" % (JS_LIBS_ONE_version, JS_LIBS_TWO_version, 169 | js_option, js_extra, js_call, js_debug) 170 | 171 | # save 172 | js_load = ''.join(['' % e for e in JS_SAVE]) 173 | if save == True: 174 | if not os.path.exists(save_path): 175 | os.makedirs(save_path) 176 | tag = save_name if save_name else 'plot' 177 | dated = dt.datetime.now().strftime('_%Y%m%d_%H%M%S') if dated else '' 178 | 179 | with open(os.path.join(save_path, tag + dated + '.html'), 'w') as f: 180 | f.write(js_load + html + js) 181 | 182 | with open(os.path.join(save_path, tag + dated + '-for-ezdashboard.html'), 'w') as f: 183 | f.write(html + js) 184 | 185 | 186 | if notebook: 187 | return html + js 188 | else: 189 | return js_load + html + js 190 | 191 | 192 | def plot( 193 | options, lib='highcharts', dated=True, save=False, save_name=None, save_path='saved', 194 | notebook=True, html_init=None, js_option_postprocess=None, js_extra=None, callback=None, 195 | footer=None, version='latest', proxy=None, center=False): 196 | contents = html(options, lib, dated, save, save_name, save_path, notebook, 197 | html_init, js_option_postprocess, js_extra, callback, footer, 198 | version, proxy, center) 199 | return HTML(contents) 200 | -------------------------------------------------------------------------------- /ezhc/_proxy.py: -------------------------------------------------------------------------------- 1 | 2 | 3 | import requests as rq 4 | import urllib 5 | 6 | from requests.packages.urllib3.exceptions import InsecureRequestWarning 7 | rq.packages.urllib3.disable_warnings(InsecureRequestWarning) 8 | 9 | 10 | class Proxy: 11 | """ 12 | proxy object 13 | """ 14 | 15 | def __init__(self, 16 | login=None, 17 | pwd=None, 18 | proxy_host=None, 19 | proxy_port=None): 20 | """ 21 | """ 22 | self.login = login 23 | self.pwd = pwd 24 | self.proxy_host = proxy_host 25 | self.proxy_port = proxy_port 26 | self.proxies = None 27 | 28 | if self.pwd: 29 | self.pwd = urllib.parse.quote(self.pwd) 30 | 31 | if self.login: 32 | dic = {'login': self.login, 33 | 'pwd': self.pwd, 34 | 'proxy_host': self.proxy_host, 35 | 'proxy_port': self.proxy_port} 36 | self.proxies = { 37 | 'http': 'http://{login}:{pwd}@{proxy_host}:{proxy_port}'.format(**dic), 38 | 'https': 'https://{login}:{pwd}@{proxy_host}:{proxy_port}'.format(**dic) 39 | } 40 | 41 | -------------------------------------------------------------------------------- /ezhc/_state.py: -------------------------------------------------------------------------------- 1 | 2 | import sys 3 | import os 4 | import json 5 | from ._config import HC_OPTION_FILE, HC_OBJECT_FILE, \ 6 | HS_OPTION_FILE, HS_OBJECT_FILE, \ 7 | API_DIR 8 | 9 | 10 | def load_resource(src): 11 | _dir = os.path.dirname(__file__) 12 | object_builder_file = os.path.join(_dir, API_DIR, src) 13 | if sys.version_info.major == 3: 14 | with open(object_builder_file, encoding='UTF-8') as obj_build: 15 | return json.load(obj_build) 16 | else: 17 | with open(object_builder_file) as obj_build: 18 | return json.load(obj_build) 19 | 20 | 21 | class State(object): 22 | """ 23 | Contains all 'highcharts' or 'highstock' API 24 | Select lib='highcharts' or lib='highstock' 25 | """ 26 | 27 | def __init__(self, lib='highcharts'): 28 | if lib == 'highcharts': 29 | self._OBJECT = load_resource(HC_OBJECT_FILE) 30 | self._OPTION = load_resource(HC_OPTION_FILE) 31 | elif lib == 'highstock': 32 | self._OBJECT = load_resource(HS_OBJECT_FILE) 33 | self._OPTION = load_resource(HS_OPTION_FILE) 34 | else: 35 | raise ValueError("Wrong lib, 'highcharts' or 'highstock' expected") 36 | 37 | state_HC = State(lib='highcharts') 38 | state_HS = State(lib='highstock') 39 | -------------------------------------------------------------------------------- /ezhc/_theme.py: -------------------------------------------------------------------------------- 1 | 2 | import os 3 | import json 4 | import glob 5 | 6 | from IPython.display import Markdown 7 | 8 | 9 | class Theme: 10 | """ 11 | Easy access to Highcharts themes 12 | See https://github.com/highcharts/highcharts/tree/master/js/themes 13 | """ 14 | 15 | def __init__(self): 16 | here = os.path.dirname(os.path.realpath(__file__)) 17 | paths = glob.glob(os.path.join(here, 'script/themes/*.json')) 18 | themes = {} 19 | for path in paths: 20 | filename = os.path.basename(path).split('.json')[0] 21 | with open(path, 'r') as f: 22 | content = f.read() 23 | dic = json.loads(content) 24 | themes[filename] = dic 25 | self.themes = themes 26 | 27 | def info(self): 28 | li_theme = list(self.themes.keys()) 29 | md = """ 30 | Theme contains predtermined [Highcharts themes](https://github.com/highcharts/highcharts/tree/master/js/themes) available as properties 31 | ```json 32 | {} 33 | ```""".format(li_theme) 34 | return Markdown(md) 35 | -------------------------------------------------------------------------------- /ezhc/_wrapper.py: -------------------------------------------------------------------------------- 1 | 2 | from IPython.display import HTML, display 3 | 4 | from ._config import DEMO, DESCRIPTION, FULLNAME 5 | from ._state import State, state_HC, state_HS 6 | 7 | 8 | class Wrapper(object): 9 | 10 | def __init__(self, lib, path=''): 11 | self.path = path 12 | self.lib = lib 13 | if lib == 'highcharts': 14 | self.state = state_HC 15 | if lib == 'highstock': 16 | self.state = state_HS 17 | 18 | def __getattr__(self, item): 19 | _path = item if not self.path else self.path+'.'+item 20 | for attr in self.state._OPTION: 21 | if _path == attr.get(FULLNAME): 22 | var = Wrapper(self.lib, _path) 23 | if len(dir(var)): 24 | setattr(self, item, var) 25 | # setattr(self, item, var if len(dir(var)) else '') 26 | return var 27 | 28 | def __dir__(self): 29 | _dir = [] 30 | _path = self.path.split('.') 31 | if len(_path) == 1 and self.path == '': 32 | for attr in self.state._OPTION: 33 | if len(attr.get(FULLNAME).split('.')) == 1: 34 | _dir.append(attr.get(FULLNAME)) 35 | else: 36 | for attr in self.state._OPTION: 37 | _attr_path = attr.get(FULLNAME).split('.') 38 | if len(_path) < len(_attr_path): 39 | if _path[len(_path)-1] == _attr_path[len(_path)-1] \ 40 | and len(_attr_path) == len(_path)+1: 41 | _dir.append(_attr_path[len(_path)]) 42 | return _dir 43 | 44 | def to_dict(self): 45 | _dic = dict(self.__dict__) 46 | _dic.pop('path') 47 | _dic.pop('lib') 48 | 49 | for k in list(_dic.keys()): 50 | if isinstance(_dic[k], list): 51 | for i, e in enumerate(_dic[k]): 52 | if isinstance(e, Wrapper): 53 | _dic[k][i] = _dic[k][i].to_dict() 54 | elif isinstance(e, dict): 55 | pass 56 | elif _dic[k][i] == {} or _dic[k][i] is None or isinstance(_dic[k][i], State): 57 | _dic[k].pop(i) 58 | else: 59 | if isinstance(_dic[k], Wrapper): 60 | _dic[k] = _dic[k].to_dict() 61 | elif isinstance(_dic[k], dict): 62 | pass 63 | elif _dic[k] == {} or _dic[k] is None or isinstance(_dic[k], State): 64 | _dic.pop(k) 65 | 66 | return _dic 67 | 68 | @property 69 | def __doc__(self): 70 | for attr in self.state._OPTION: 71 | if self.path == attr.get(FULLNAME): 72 | _desc = attr.get(DESCRIPTION) 73 | _demo = attr.get(DEMO) 74 | break 75 | 76 | doc = "Documentation for '%s'\n\n" % self.path + \ 77 | "Description\n%s\n\n" % _desc 78 | if _demo: 79 | doc += "Demo\n%s\n" % _demo 80 | 81 | return doc 82 | 83 | def info(self): 84 | def correct_url(s): 85 | url = 'href=\"#' 86 | url_highcharts = 'href=\"https://api.highcharts.com/highcharts#' 87 | url_highstock = 'href=\"https://api.highcharts.com/highstock#' 88 | li = s.split(url) 89 | if len(li) == 1: 90 | return s 91 | else: 92 | if self.lib == 'highcharts': 93 | return url_highcharts.join(li) 94 | if self.lib == 'highstock': 95 | return url_highstock.join(li) 96 | 97 | if self.path != '': 98 | for attr in self.state._OPTION: 99 | if self.path == attr.get(FULLNAME): 100 | _desc = attr.get(DESCRIPTION) 101 | _demo = attr.get(DEMO) 102 | break 103 | 104 | doc = "

Documentation for '%s'


" % self.path 105 | if _desc: 106 | _desc = correct_url(_desc) 107 | doc += "
  • Description
  • %s

    " % _desc 108 | if _demo: 109 | _demo = correct_url(_demo) 110 | doc += "
  • Demo
  • %s
    " % _demo 111 | 112 | display(HTML(doc)) 113 | -------------------------------------------------------------------------------- /ezhc/build.py: -------------------------------------------------------------------------------- 1 | 2 | import pandas as pd 3 | 4 | DEFAULT_COLORS = ["#7cb5ec", "#434348", "#90ed7d", "#f7a35c", "#8085e9", 5 | "#f15c80", "#e4d354", "#2b908f", "#f45b5b", "#91e8e1"] 6 | 7 | 8 | def series(df, *args, **kwargs): 9 | idx = df.index 10 | col = df.columns 11 | data = df.values 12 | assert(isinstance(idx, pd.Index)) 13 | 14 | series = [] 15 | for k, c in enumerate(col): 16 | if df[c].dtype.kind in 'fib': 17 | v = data[:, k] 18 | sec = c in kwargs.get('secondary_y', []) 19 | d = { 20 | 'name': c if not sec else c + ' (right)', 21 | 'yAxis': int(sec), 22 | 'data': [[idx[q], v[q]] for q in range(len(v))], 23 | } 24 | for key in kwargs.keys(): 25 | if key == 'fillColor': 26 | d['type'] = 'area' 27 | d['fillColor'] = kwargs['fillColor'].get(c) 28 | elif c in kwargs.get(key, []): 29 | d[key] = kwargs[key].get(c) 30 | series.append(d) 31 | return series 32 | 33 | 34 | def series_range(df, *args, **kwargs): 35 | idx = df.index 36 | col = df.columns 37 | data = df.values 38 | assert(isinstance(idx, pd.Index)) 39 | assert(len(col) == 2) 40 | assert(df[col[0]].dtype.kind in 'if') 41 | assert(df[col[1]].dtype.kind in 'if') 42 | 43 | series = [{ 44 | 'data': [[data[q, 0], data[q, 1]] for q in range(data.shape[0])], 45 | }] 46 | if 'color' in kwargs: 47 | series['color'] = kwargs['color'] 48 | axis_categories = list(idx) 49 | 50 | return axis_categories, series 51 | 52 | 53 | def series_drilldown_orig(df, colorByPoint=True, pointPlacement='on', *args, **kwargs): 54 | idx = df.index 55 | col = df.columns 56 | assert(isinstance(idx, pd.MultiIndex)) 57 | assert(len(idx.levshape) == 2) 58 | for c in col: 59 | assert df[c].dtype.kind in 'if' 60 | 61 | levone = list(idx.levels[0]) 62 | data = [] 63 | series = [] 64 | drilldownSeries = [] 65 | for co in col: 66 | data = [] 67 | for c in levone: 68 | dfs = df.xs(c) 69 | ii = dfs[[co]].index.values.flatten() 70 | vv = dfs[[co]].values.flatten() 71 | 72 | d1 = { 73 | 'name': c, 74 | 'y': dfs[[co]].sum().values[0], 75 | 'drilldown': c + ' - ' + co if len(dfs) > 1 else None, 76 | 'pointPlacement': pointPlacement 77 | } 78 | if co in kwargs.get('color', []): 79 | d1['color'] = kwargs['color'].get(co) 80 | data.append(d1) 81 | 82 | if len(dfs) > 1: 83 | d2 = { 84 | 'name': c + ' - ' + co, 85 | 'data': [[str(ii[q]), vv[q]] for q in range(len(ii))], 86 | 'id': c + ' - ' + co, 87 | 'pointPlacement': pointPlacement 88 | } 89 | drilldownSeries.append(d2) 90 | 91 | s = {'name': co, 'data': data, 'colorByPoint': colorByPoint} 92 | if co in kwargs.get('color', []): 93 | s['color'] = kwargs['color'].get(co) 94 | series.append(s) 95 | 96 | return series, drilldownSeries 97 | 98 | 99 | def series_drilldown(df, 100 | top_name='Top', 101 | colorByPoint=True, 102 | pointPlacement='on', 103 | set_color=False, 104 | colors=None, 105 | set_precision=False, 106 | precision=None, 107 | *args, 108 | **kwargs): 109 | idx = df.index 110 | col = df.columns 111 | assert(isinstance(idx, pd.MultiIndex)) 112 | for c in col: 113 | assert df[c].dtype.kind in 'if' 114 | 115 | class DrillDownBuilder: 116 | """ 117 | Recursive build of drilldown structure 118 | """ 119 | 120 | def __init__(self, 121 | df, 122 | top_name='Top', 123 | colorByPoint=True, 124 | pointPlacement='on', 125 | set_color=False, 126 | colors=None, 127 | set_precision=False, 128 | precision=None): 129 | 130 | self.top_name = top_name 131 | self.colorByPoint = colorByPoint 132 | self.pointPlacement = pointPlacement 133 | self.df = df 134 | self.set_color = set_color 135 | self.colors = colors 136 | self.set_precision = set_precision 137 | self.precision = precision 138 | 139 | self.items = [] 140 | self.top_item = self.build(df) 141 | 142 | def build(self, dfxs, parent=None, name=None): 143 | top_items = [] 144 | for col in dfxs.columns: 145 | dfc = dfxs[[col]] 146 | item = { 147 | 'id': col + '-toplevel', 148 | 'name': dfc.columns[0] 149 | } 150 | if len(dfxs.columns) == 1: 151 | item['name'] = self.top_name 152 | if parent: 153 | item['id'] = str(parent) + '-' + name 154 | item['name'] = name 155 | if self.colorByPoint: 156 | item['colorByPoint'] = self.colorByPoint 157 | 158 | data = [] 159 | 160 | idx = dfc.index 161 | if isinstance(idx, pd.MultiIndex): 162 | 163 | for k, idx0 in enumerate(idx.levels[0]): 164 | df_sub = dfc.xs(idx0) 165 | total = df_sub.sum().iloc[0] 166 | d = { 167 | 'name': str(idx0), 168 | 'y': total, 169 | 'drilldown': item['id'] + '-' + str(idx0) 170 | } 171 | if self.pointPlacement: 172 | d['pointPlacement'] = self.pointPlacement 173 | if self.set_precision: 174 | d['y'] = round(total, self.precision) 175 | if self.set_color: 176 | d['color'] = self.colors[k % len(self.colors)] 177 | data.append(d) 178 | 179 | self.build(df_sub, 180 | parent=item['id'], 181 | name=str(idx0)) 182 | 183 | elif isinstance(idx, pd.Index): 184 | 185 | for k, idx0 in enumerate(idx): 186 | df_sub = dfc.xs(idx0) 187 | total = df_sub.sum() 188 | d = { 189 | 'name': str(idx0), 190 | 'y': total, 191 | } 192 | if self.set_precision: 193 | d['y'] = round(total, self.precision) 194 | if self.set_color: 195 | d['color'] = self.colors[k % len(self.colors)] 196 | data.append(d) 197 | 198 | else: 199 | raise Exception('Pandas Index Unknown Problem') 200 | 201 | item['data'] = data 202 | self.items.append(item) 203 | top_items.append(item) 204 | 205 | return top_items 206 | 207 | def series(self): 208 | return self.top_item 209 | 210 | def drilldown_series(self): 211 | return self.items 212 | 213 | dd = DrillDownBuilder(df, 214 | top_name=top_name, 215 | colorByPoint=colorByPoint, 216 | pointPlacement=pointPlacement, 217 | set_color=set_color, 218 | colors=colors, 219 | set_precision=set_precision, 220 | precision=precision) 221 | 222 | return dd.series(), dd.drilldown_series() 223 | 224 | 225 | # def series_drilldown_orig(df, colorByPoint=True, pointPlacement='on', *args, **kwargs): 226 | # idx = df.index 227 | # col = df.columns 228 | # assert(isinstance(idx, pd.MultiIndex)) 229 | # assert(len(idx.levshape) == 2) 230 | # for c in col: 231 | # assert df[c].dtype.kind in 'if' 232 | 233 | # levone = list(idx.levels[0]) 234 | # data = [] 235 | # series = [] 236 | # drilldownSeries = [] 237 | # for co in col: 238 | # data = [] 239 | # for c in levone: 240 | # dfs = df.xs(c) 241 | # ii = dfs[[co]].index.values.flatten() 242 | # vv = dfs[[co]].values.flatten() 243 | 244 | # d1 = { 245 | # 'name': c, 246 | # 'y': dfs[[co]].sum().values[0], 247 | # 'drilldown': c + ' - ' + co if len(dfs) > 1 else None, 248 | # 'pointPlacement': pointPlacement 249 | # } 250 | # if co in kwargs.get('color', []): 251 | # d1['color'] = kwargs['color'].get(co) 252 | # data.append(d1) 253 | 254 | # if len(dfs) > 1: 255 | # d2 = { 256 | # 'name': c + ' - ' + co, 257 | # 'data': [[str(ii[q]), vv[q]] for q in range(len(ii))], 258 | # 'id': c + ' - ' + co, 259 | # 'pointPlacement': pointPlacement 260 | # } 261 | # drilldownSeries.append(d2) 262 | 263 | # s = {'name': co, 'data': data, 'colorByPoint': colorByPoint} 264 | # if co in kwargs.get('color', []): 265 | # s['color'] = kwargs['color'].get(co) 266 | # series.append(s) 267 | 268 | # return series, drilldownSeries 269 | 270 | 271 | def series_scatter(df, color_column=None, title_column=None, *args, **kwargs): 272 | idx = df.index 273 | col = df.columns 274 | assert(isinstance(idx, pd.MultiIndex)) 275 | assert(len(idx.levshape) == 2) 276 | assert(len(col) <= 2) 277 | assert(df[color_column].dtype.kind in 'iO') 278 | 279 | if color_column == None: 280 | assert(len(col) == 1) 281 | color_column = col[0] 282 | if title_column == None: 283 | title_column = color_column 284 | 285 | data = df[[color_column]].values.flatten() 286 | elmt = list(set(data)) 287 | color = kwargs.get('color', {}) 288 | series = [] 289 | 290 | for e in elmt: 291 | dfs = df[df[color_column] == e] 292 | idx = dfs.index 293 | names = list(dfs[title_column]) 294 | series.append({'animation': False, 295 | 'name': e, 296 | 'turboThreshold': 0, 297 | 'color': color.get(e, None), 298 | 'data': [{'x': idx[k][0], 'y': idx[k][1], 'name': str(names[k])} 299 | for k in range(len(dfs))], 300 | }) 301 | return series 302 | 303 | 304 | def series_bubble(df, *args, **kwargs): 305 | idx = df.index 306 | col = df.columns 307 | assert(isinstance(idx, pd.MultiIndex)) 308 | assert(len(idx.levshape) == 3) 309 | assert(len(col) == 1) 310 | assert(df[col[0]].dtype.kind in 'fib') 311 | 312 | names = list(idx.levels[0]) 313 | series = [] 314 | for s in names: 315 | dfs = df.xs(s) 316 | v = dfs.values.flatten() 317 | idxs = dfs.index 318 | d = { 319 | 'name': s, 320 | 'data': [[idxs[q][0], idxs[q][1], v[q]] for q in range(len(v))], 321 | } 322 | if s in kwargs.get('color', []): 323 | d['color'] = kwargs['color'].get(s) 324 | 325 | series.append(d) 326 | 327 | return series 328 | 329 | 330 | def series_heatmap(df, *args, **kwargs): 331 | idx = df.index 332 | col = df.columns 333 | assert(isinstance(idx, pd.Index)) 334 | for c in col: 335 | assert(df[c].dtype.kind in 'if') 336 | 337 | dft = df.copy() 338 | dft.index = range(len(df.index)) 339 | dft.columns = range(len(df.columns)) 340 | res_data = list(dft.stack().swaplevel(0, 1).reset_index().values) 341 | res_idx = list(df.columns) 342 | res_col = list(df.index) 343 | 344 | return res_idx, res_col, res_data 345 | 346 | 347 | def series_tree(df, 348 | set_total=False, 349 | name_total='All', 350 | set_color=False, 351 | colors=DEFAULT_COLORS, 352 | set_value=True, 353 | precision=2): 354 | 355 | class TreeBuilder: 356 | """ 357 | Recursive build of tree data structure 358 | """ 359 | 360 | def __init__(self, 361 | df, 362 | set_total, 363 | name_total, 364 | set_color, 365 | colors, 366 | set_value, 367 | precision): 368 | self.df = df 369 | self.set_color = set_color 370 | self.colors = colors 371 | self.set_value = set_value 372 | self.precision = precision 373 | 374 | self.points = [] 375 | if set_total: 376 | point = {'id': '0', 377 | 'name': name_total, 378 | } 379 | if set_value: 380 | point['value'] = round(df.sum().sum(), precision) 381 | self.points.append(point) 382 | total = self.build(df, parent='0') 383 | else: 384 | total = self.build(df) 385 | 386 | def build(self, dfxs, parent=None): 387 | idx = dfxs.index 388 | sum_value = 0 389 | 390 | if isinstance(idx, pd.MultiIndex): 391 | for k, name in enumerate(idx.levels[0]): 392 | point = { 393 | 'name': name, 394 | } 395 | if parent: 396 | point['id'] = parent + '.' + str(k) 397 | point['parent'] = parent 398 | else: 399 | point['id'] = '0.' + str(k) 400 | if self.set_color: 401 | point['color'] = self.colors[k % len(self.colors)] 402 | 403 | df_sub = dfxs.xs(name) 404 | df_sub = df_sub.reset_index().set_index(df_sub.index.names) 405 | 406 | value = self.build(df_sub, 407 | parent=point.get('id')) 408 | sum_value += value 409 | if self.set_value: 410 | point['value'] = round(value, self.precision) 411 | self.points.append(point) 412 | 413 | elif isinstance(idx, pd.Index): 414 | 415 | for k, name in enumerate(idx): 416 | value = dfxs.loc[name][0] 417 | sum_value += value 418 | 419 | point = { 420 | 'name': name, 421 | 'value': round(value, self.precision) 422 | } 423 | if parent: 424 | point['id'] = parent + '.' + str(k) 425 | point['parent'] = parent 426 | else: 427 | point['id'] = 'id_' + str(k) 428 | point['color'] = self.colors[k % len(self.colors)] 429 | 430 | self.points.append(point) 431 | 432 | else: 433 | raise Exception('Pandas Index Unknown Problem') 434 | 435 | return sum_value 436 | 437 | col = df.columns 438 | assert(len(col) == 1) 439 | tb = TreeBuilder(df, 440 | set_total, 441 | name_total, 442 | set_color, 443 | colors, 444 | set_value, 445 | precision) 446 | return tb.points 447 | -------------------------------------------------------------------------------- /ezhc/sample.py: -------------------------------------------------------------------------------- 1 | 2 | import os 3 | import numpy as np 4 | import pandas as pd 5 | 6 | from ._config import SAMPLES_DIR, DF_ONE_IDX_SEVERAL_COL, DF_ONE_IDX_SEVERAL_COL_2, \ 7 | DF_ONE_IDX_ONE_COL, DF_ONE_IDX_TWO_COL, DF_TWO_IDX_ONE_COL, DF_SCATTER, \ 8 | DF_BUBBLE, DF_HEATMAP, DF_SEVERAL_IDX_ONE_COL, DF_SEVERAL_IDX_ONE_COL_2, \ 9 | DF_TWO_IDX_SEVERAL_COL 10 | 11 | 12 | def load_df(src): 13 | _dir = os.path.dirname(__file__) 14 | df_file = os.path.join(_dir, SAMPLES_DIR, src) 15 | df = pd.read_csv(df_file) 16 | return df 17 | 18 | 19 | def df_timeseries(N=3, Nb_bd=500, seed=123456): 20 | np.random.seed(seed) 21 | 22 | rate = 0.02 23 | vol = 0.25 24 | dt = 1.0/260 25 | tracks = np.zeros([Nb_bd, N], dtype=np.float) 26 | 27 | for k in range(N): 28 | ln_returns = (rate-vol**2/2)*dt+vol*np.sqrt(dt)*np.random.normal(size=Nb_bd) 29 | ln_returns[0] = 0.0 30 | tracks[:, k] = np.exp(ln_returns).cumprod() 31 | 32 | dates = pd.date_range(start=pd.datetime(2015, 1, 1), periods=Nb_bd, freq='B') 33 | df = pd.DataFrame(data=tracks, index=dates, columns=['Track'+str(1+i) for i in range(N)]) 34 | 35 | return df 36 | 37 | 38 | def df_one_idx_several_col(): 39 | df = load_df(DF_ONE_IDX_SEVERAL_COL) 40 | df = df.set_index('Fruit') 41 | return df 42 | 43 | 44 | def df_one_idx_several_col_2(): 45 | df = load_df(DF_ONE_IDX_SEVERAL_COL_2) 46 | df = df.set_index('WeekDay') 47 | return df 48 | 49 | 50 | def df_one_idx_one_col(): 51 | df = load_df(DF_ONE_IDX_ONE_COL) 52 | df = df.set_index('Brand') 53 | return df 54 | 55 | 56 | def df_one_idx_two_col(): 57 | df = load_df(DF_ONE_IDX_TWO_COL) 58 | df = df.set_index('Month') 59 | return df 60 | 61 | 62 | def df_two_idx_one_col(): 63 | df = load_df(DF_TWO_IDX_ONE_COL) 64 | df = df.set_index(['Brand', 'Version']) 65 | return df 66 | 67 | 68 | def df_scatter(): 69 | df = load_df(DF_SCATTER) 70 | df = df.set_index(['Height', 'Weight']) 71 | return df 72 | 73 | 74 | def df_bubble(): 75 | df = load_df(DF_BUBBLE) 76 | df = df.set_index(['Cat', 'x', 'y']) 77 | return df 78 | 79 | 80 | def df_heatmap(): 81 | df = load_df(DF_HEATMAP) 82 | df = df.set_index(['Name', 'Day']) 83 | return df 84 | 85 | 86 | def df_several_idx_one_col(): 87 | df = load_df(DF_SEVERAL_IDX_ONE_COL) 88 | df = df.set_index(['Region', 'Country', 'Cause']) 89 | df = df.sort_index() 90 | return df 91 | 92 | def df_several_idx_one_col_2(): 93 | df = load_df(DF_SEVERAL_IDX_ONE_COL_2) 94 | df = df.set_index(['Continent', 'Region', 'Country']) 95 | df = df.sort_index() 96 | return df 97 | 98 | 99 | def df_two_idx_several_col(): 100 | df = load_df(DF_TWO_IDX_SEVERAL_COL) 101 | df = df.set_index(['Strategy', 'Ticker']) 102 | df = df.sort_index() 103 | return df 104 | -------------------------------------------------------------------------------- /ezhc/samples/build_data_world_population.py: -------------------------------------------------------------------------------- 1 | import os 2 | import pandas as pd 3 | 4 | from data_population import data 5 | 6 | 7 | dfd = pd.DataFrame(data) 8 | 9 | dic_1 = dfd[dfd['id'].str.startswith( 10 | '1')][['id', 'name']].set_index('id').to_dict()['name'] 11 | dic_2 = dfd[dfd['id'].str.startswith( 12 | '2')][['id', 'name']].set_index('id').to_dict()['name'] 13 | dic_3 = dfd[dfd['id'].str.startswith( 14 | '3')][['id', 'name']].set_index('id').to_dict()['name'] 15 | 16 | g = dfd.groupby('parent') 17 | 18 | dic_tree_1 = {} 19 | dic_tree_2 = {} 20 | for k, v in g.groups.items(): 21 | if k.startswith('1'): 22 | df = g.get_group(k) 23 | dic_tree_1[dic_1[k]] = list(df['name']) 24 | if k.startswith('2'): 25 | df = g.get_group(k) 26 | dic_tree_2[dic_2[k]] = list(df['name']) 27 | 28 | g = dfd.groupby('id') 29 | dic_val = {} 30 | for k, v in g.groups.items(): 31 | if k.startswith('3'): 32 | df = g.get_group(k) 33 | dic_val[dic_3[k]] = df['value'].iloc[0] 34 | 35 | data = [] 36 | for continent, li_reg in dic_tree_1.items(): 37 | for reg in li_reg: 38 | li_country = dic_tree_2[reg] 39 | for country in li_country: 40 | v = dic_val[country] 41 | data.append([continent, reg, country, v]) 42 | 43 | dfs = pd.DataFrame(data=data, 44 | columns=['Continent', 'Region', 'Country', 'Population']) 45 | dfs = dfs.set_index(['Continent', 'Region', 'Country']) 46 | 47 | path = 'df_several_idx_one_col_2.csv' 48 | dfs.to_csv(path) 49 | -------------------------------------------------------------------------------- /ezhc/samples/df_bubble.csv: -------------------------------------------------------------------------------- 1 | Cat,x,y,Size 2 | Cat1,97,36,79 3 | Cat1,94,74,60 4 | Cat1,68,76,58 5 | Cat1,64,87,56 6 | Cat1,68,27,73 7 | Cat1,74,99,42 8 | Cat1,7,93,87 9 | Cat1,51,69,40 10 | Cat1,38,23,33 11 | Cat1,57,86,31 12 | Cat2,25,10,87 13 | Cat2,2,75,59 14 | Cat2,11,54,8 15 | Cat2,86,55,93 16 | Cat2,5,3,58 17 | Cat2,90,63,44 18 | Cat2,91,33,17 19 | Cat2,97,3,56 20 | Cat2,15,67,48 21 | Cat2,54,25,81 22 | Cat3,47,47,21 23 | Cat3,20,12,4 24 | Cat3,6,76,91 25 | Cat3,38,30,60 26 | Cat3,57,98,64 27 | Cat3,61,17,80 28 | Cat3,83,60,13 29 | Cat3,67,78,75 30 | Cat3,64,12,10 31 | Cat3,30,77,82 32 | -------------------------------------------------------------------------------- /ezhc/samples/df_heatmap.csv: -------------------------------------------------------------------------------- 1 | Name,Day,Sales 2 | Alexander,Monday,10 3 | Alexander,Tuesday,19 4 | Alexander,Wednesday,8 5 | Alexander,Thursday,24 6 | Alexander,Friday,67 7 | Marie,Monday,92 8 | Marie,Tuesday,58 9 | Marie,Wednesday,78 10 | Marie,Thursday,117 11 | Marie,Friday,48 12 | Maximilian,Monday,35 13 | Maximilian,Tuesday,15 14 | Maximilian,Wednesday,123 15 | Maximilian,Thursday,64 16 | Maximilian,Friday,52 17 | Sophia,Monday,72 18 | Sophia,Tuesday,132 19 | Sophia,Wednesday,114 20 | Sophia,Thursday,19 21 | Sophia,Friday,16 22 | Lukas,Monday,38 23 | Lukas,Tuesday,5 24 | Lukas,Wednesday,8 25 | Lukas,Thursday,117 26 | Lukas,Friday,115 27 | Maria,Monday,88 28 | Maria,Tuesday,32 29 | Maria,Wednesday,12 30 | Maria,Thursday,6 31 | Maria,Friday,120 32 | Leon,Monday,13 33 | Leon,Tuesday,44 34 | Leon,Wednesday,88 35 | Leon,Thursday,98 36 | Leon,Friday,96 37 | Anna,Monday,31 38 | Anna,Tuesday,1 39 | Anna,Wednesday,82 40 | Anna,Thursday,32 41 | Anna,Friday,30 42 | Tim,Monday,85 43 | Tim,Tuesday,97 44 | Tim,Wednesday,123 45 | Tim,Thursday,64 46 | Tim,Friday,84 47 | Laura,Monday,47 48 | Laura,Tuesday,114 49 | Laura,Wednesday,31 50 | Laura,Thursday,48 51 | Laura,Friday,91 52 | -------------------------------------------------------------------------------- /ezhc/samples/df_one_idx_one_col.csv: -------------------------------------------------------------------------------- 1 | Brand,MktShare 2 | Firefox,45.0 3 | IE,26.8 4 | Chrome,12.8 5 | Safari,8.5 6 | Opera,6.2 7 | Others,0.7 8 | -------------------------------------------------------------------------------- /ezhc/samples/df_one_idx_several_col.csv: -------------------------------------------------------------------------------- 1 | Fruit,Jane,Joe,John 2 | Apples,2,3,5 3 | Oranges,2,4,3 4 | Pears,3,4,4 5 | Grapes,2,2,7 6 | Bananas,1,5,2 7 | -------------------------------------------------------------------------------- /ezhc/samples/df_one_idx_several_col_2.csv: -------------------------------------------------------------------------------- 1 | WeekDay,Alexander,Marie,Maximilian,Sophia,Lukas,Maria,Leon,Anna,Tim,Laura 2 | Monday,10,92,35,72,38,88,13,31,85,47 3 | Tuesday,19,58,15,132,5,32,44,1,97,114 4 | Wednesday,8,78,123,114,8,12,88,82,123,31 5 | Thursday,24,117,64,19,117,6,98,32,64,48 6 | Friday,67,48,52,16,115,120,96,30,84,91 7 | -------------------------------------------------------------------------------- /ezhc/samples/df_one_idx_two_col.csv: -------------------------------------------------------------------------------- 1 | Month,Min,Max 2 | Jan,-9.7,9.4 3 | Feb,-8.7,6.5 4 | Mar,-3.5,9.4 5 | Apr,-1.4,19.9 6 | May,0.0,22.6 7 | Jun,2.9,29.5 8 | Jul,9.2,30.7 9 | Aug,7.3,26.5 10 | Sep,4.4,18.0 11 | Oct,-3.1,11.4 12 | Nov,-5.2,10.4 13 | Dec,-13.5,9.8 14 | -------------------------------------------------------------------------------- /ezhc/samples/df_scatter.csv: -------------------------------------------------------------------------------- 1 | Height,Weight,Sex 2 | 161.2,51.6,Female 3 | 167.5,59.0,Female 4 | 159.5,49.2,Female 5 | 157.0,63.0,Female 6 | 155.8,53.6,Female 7 | 170.0,59.0,Female 8 | 159.1,47.6,Female 9 | 166.0,69.8,Female 10 | 176.2,66.8,Female 11 | 160.2,75.2,Female 12 | 172.5,55.2,Female 13 | 170.9,54.2,Female 14 | 172.9,62.5,Female 15 | 153.4,42.0,Female 16 | 160.0,50.0,Female 17 | 147.2,49.8,Female 18 | 168.2,49.2,Female 19 | 175.0,73.2,Female 20 | 157.0,47.8,Female 21 | 167.6,68.8,Female 22 | 159.5,50.6,Female 23 | 175.0,82.5,Female 24 | 166.8,57.2,Female 25 | 176.5,87.8,Female 26 | 170.2,72.8,Female 27 | 174.0,54.5,Female 28 | 173.0,59.8,Female 29 | 179.9,67.3,Female 30 | 170.5,67.8,Female 31 | 160.0,47.0,Female 32 | 154.4,46.2,Female 33 | 162.0,55.0,Female 34 | 176.5,83.0,Female 35 | 160.0,54.4,Female 36 | 152.0,45.8,Female 37 | 162.1,53.6,Female 38 | 170.0,73.2,Female 39 | 160.2,52.1,Female 40 | 161.3,67.9,Female 41 | 166.4,56.6,Female 42 | 168.9,62.3,Female 43 | 163.8,58.5,Female 44 | 167.6,54.5,Female 45 | 160.0,50.2,Female 46 | 161.3,60.3,Female 47 | 167.6,58.3,Female 48 | 165.1,56.2,Female 49 | 160.0,50.2,Female 50 | 170.0,72.9,Female 51 | 157.5,59.8,Female 52 | 167.6,61.0,Female 53 | 160.7,69.1,Female 54 | 163.2,55.9,Female 55 | 152.4,46.5,Female 56 | 157.5,54.3,Female 57 | 168.3,54.8,Female 58 | 180.3,60.7,Female 59 | 165.5,60.0,Female 60 | 165.0,62.0,Female 61 | 164.5,60.3,Female 62 | 156.0,52.7,Female 63 | 160.0,74.3,Female 64 | 163.0,62.0,Female 65 | 165.7,73.1,Female 66 | 161.0,80.0,Female 67 | 162.0,54.7,Female 68 | 166.0,53.2,Female 69 | 174.0,75.7,Female 70 | 172.7,61.1,Female 71 | 167.6,55.7,Female 72 | 151.1,48.7,Female 73 | 164.5,52.3,Female 74 | 163.5,50.0,Female 75 | 152.0,59.3,Female 76 | 169.0,62.5,Female 77 | 164.0,55.7,Female 78 | 161.2,54.8,Female 79 | 155.0,45.9,Female 80 | 170.0,70.6,Female 81 | 176.2,67.2,Female 82 | 170.0,69.4,Female 83 | 162.5,58.2,Female 84 | 170.3,64.8,Female 85 | 164.1,71.6,Female 86 | 169.5,52.8,Female 87 | 163.2,59.8,Female 88 | 154.5,49.0,Female 89 | 159.8,50.0,Female 90 | 173.2,69.2,Female 91 | 170.0,55.9,Female 92 | 161.4,63.4,Female 93 | 169.0,58.2,Female 94 | 166.2,58.6,Female 95 | 159.4,45.7,Female 96 | 162.5,52.2,Female 97 | 159.0,48.6,Female 98 | 162.8,57.8,Female 99 | 159.0,55.6,Female 100 | 179.8,66.8,Female 101 | 162.9,59.4,Female 102 | 161.0,53.6,Female 103 | 151.1,73.2,Female 104 | 168.2,53.4,Female 105 | 168.9,69.0,Female 106 | 173.2,58.4,Female 107 | 171.8,56.2,Female 108 | 178.0,70.6,Female 109 | 164.3,59.8,Female 110 | 163.0,72.0,Female 111 | 168.5,65.2,Female 112 | 166.8,56.6,Female 113 | 172.7,105.2,Female 114 | 163.5,51.8,Female 115 | 169.4,63.4,Female 116 | 167.8,59.0,Female 117 | 159.5,47.6,Female 118 | 167.6,63.0,Female 119 | 161.2,55.2,Female 120 | 160.0,45.0,Female 121 | 163.2,54.0,Female 122 | 162.2,50.2,Female 123 | 161.3,60.2,Female 124 | 149.5,44.8,Female 125 | 157.5,58.8,Female 126 | 163.2,56.4,Female 127 | 172.7,62.0,Female 128 | 155.0,49.2,Female 129 | 156.5,67.2,Female 130 | 164.0,53.8,Female 131 | 160.9,54.4,Female 132 | 162.8,58.0,Female 133 | 167.0,59.8,Female 134 | 160.0,54.8,Female 135 | 160.0,43.2,Female 136 | 168.9,60.5,Female 137 | 158.2,46.4,Female 138 | 156.0,64.4,Female 139 | 160.0,48.8,Female 140 | 167.1,62.2,Female 141 | 158.0,55.5,Female 142 | 167.6,57.8,Female 143 | 156.0,54.6,Female 144 | 162.1,59.2,Female 145 | 173.4,52.7,Female 146 | 159.8,53.2,Female 147 | 170.5,64.5,Female 148 | 159.2,51.8,Female 149 | 157.5,56.0,Female 150 | 161.3,63.6,Female 151 | 162.6,63.2,Female 152 | 160.0,59.5,Female 153 | 168.9,56.8,Female 154 | 165.1,64.1,Female 155 | 162.6,50.0,Female 156 | 165.1,72.3,Female 157 | 166.4,55.0,Female 158 | 160.0,55.9,Female 159 | 152.4,60.4,Female 160 | 170.2,69.1,Female 161 | 162.6,84.5,Female 162 | 170.2,55.9,Female 163 | 158.8,55.5,Female 164 | 172.7,69.5,Female 165 | 167.6,76.4,Female 166 | 162.6,61.4,Female 167 | 167.6,65.9,Female 168 | 156.2,58.6,Female 169 | 175.2,66.8,Female 170 | 172.1,56.6,Female 171 | 162.6,58.6,Female 172 | 160.0,55.9,Female 173 | 165.1,59.1,Female 174 | 182.9,81.8,Female 175 | 166.4,70.7,Female 176 | 165.1,56.8,Female 177 | 177.8,60.0,Female 178 | 165.1,58.2,Female 179 | 175.3,72.7,Female 180 | 154.9,54.1,Female 181 | 158.8,49.1,Female 182 | 172.7,75.9,Female 183 | 168.9,55.0,Female 184 | 161.3,57.3,Female 185 | 167.6,55.0,Female 186 | 165.1,65.5,Female 187 | 175.3,65.5,Female 188 | 157.5,48.6,Female 189 | 163.8,58.6,Female 190 | 167.6,63.6,Female 191 | 165.1,55.2,Female 192 | 165.1,62.7,Female 193 | 168.9,56.6,Female 194 | 162.6,53.9,Female 195 | 164.5,63.2,Female 196 | 176.5,73.6,Female 197 | 168.9,62.0,Female 198 | 175.3,63.6,Female 199 | 159.4,53.2,Female 200 | 160.0,53.4,Female 201 | 170.2,55.0,Female 202 | 162.6,70.5,Female 203 | 167.6,54.5,Female 204 | 162.6,54.5,Female 205 | 160.7,55.9,Female 206 | 160.0,59.0,Female 207 | 157.5,63.6,Female 208 | 162.6,54.5,Female 209 | 152.4,47.3,Female 210 | 170.2,67.7,Female 211 | 165.1,80.9,Female 212 | 172.7,70.5,Female 213 | 165.1,60.9,Female 214 | 170.2,63.6,Female 215 | 170.2,54.5,Female 216 | 170.2,59.1,Female 217 | 161.3,70.5,Female 218 | 167.6,52.7,Female 219 | 167.6,62.7,Female 220 | 165.1,86.3,Female 221 | 162.6,66.4,Female 222 | 152.4,67.3,Female 223 | 168.9,63.0,Female 224 | 170.2,73.6,Female 225 | 175.2,62.3,Female 226 | 175.2,57.7,Female 227 | 160.0,55.4,Female 228 | 165.1,104.1,Female 229 | 174.0,55.5,Female 230 | 170.2,77.3,Female 231 | 160.0,80.5,Female 232 | 167.6,64.5,Female 233 | 167.6,72.3,Female 234 | 167.6,61.4,Female 235 | 154.9,58.2,Female 236 | 162.6,81.8,Female 237 | 175.3,63.6,Female 238 | 171.4,53.4,Female 239 | 157.5,54.5,Female 240 | 165.1,53.6,Female 241 | 160.0,60.0,Female 242 | 174.0,73.6,Female 243 | 162.6,61.4,Female 244 | 174.0,55.5,Female 245 | 162.6,63.6,Female 246 | 161.3,60.9,Female 247 | 156.2,60.0,Female 248 | 149.9,46.8,Female 249 | 169.5,57.3,Female 250 | 160.0,64.1,Female 251 | 175.3,63.6,Female 252 | 169.5,67.3,Female 253 | 160.0,75.5,Female 254 | 172.7,68.2,Female 255 | 162.6,61.4,Female 256 | 157.5,76.8,Female 257 | 176.5,71.8,Female 258 | 164.4,55.5,Female 259 | 160.7,48.6,Female 260 | 174.0,66.4,Female 261 | 163.8,67.3,Female 262 | 174.0,65.6,Male 263 | 175.3,71.8,Male 264 | 193.5,80.7,Male 265 | 186.5,72.6,Male 266 | 187.2,78.8,Male 267 | 181.5,74.8,Male 268 | 184.0,86.4,Male 269 | 184.5,78.4,Male 270 | 175.0,62.0,Male 271 | 184.0,81.6,Male 272 | 180.0,76.6,Male 273 | 177.8,83.6,Male 274 | 192.0,90.0,Male 275 | 176.0,74.6,Male 276 | 174.0,71.0,Male 277 | 184.0,79.6,Male 278 | 192.7,93.8,Male 279 | 171.5,70.0,Male 280 | 173.0,72.4,Male 281 | 176.0,85.9,Male 282 | 176.0,78.8,Male 283 | 180.5,77.8,Male 284 | 172.7,66.2,Male 285 | 176.0,86.4,Male 286 | 173.5,81.8,Male 287 | 178.0,89.6,Male 288 | 180.3,82.8,Male 289 | 180.3,76.4,Male 290 | 164.5,63.2,Male 291 | 173.0,60.9,Male 292 | 183.5,74.8,Male 293 | 175.5,70.0,Male 294 | 188.0,72.4,Male 295 | 189.2,84.1,Male 296 | 172.8,69.1,Male 297 | 170.0,59.5,Male 298 | 182.0,67.2,Male 299 | 170.0,61.3,Male 300 | 177.8,68.6,Male 301 | 184.2,80.1,Male 302 | 186.7,87.8,Male 303 | 171.4,84.7,Male 304 | 172.7,73.4,Male 305 | 175.3,72.1,Male 306 | 180.3,82.6,Male 307 | 182.9,88.7,Male 308 | 188.0,84.1,Male 309 | 177.2,94.1,Male 310 | 172.1,74.9,Male 311 | 167.0,59.1,Male 312 | 169.5,75.6,Male 313 | 174.0,86.2,Male 314 | 172.7,75.3,Male 315 | 182.2,87.1,Male 316 | 164.1,55.2,Male 317 | 163.0,57.0,Male 318 | 171.5,61.4,Male 319 | 184.2,76.8,Male 320 | 174.0,86.8,Male 321 | 174.0,72.2,Male 322 | 177.0,71.6,Male 323 | 186.0,84.8,Male 324 | 167.0,68.2,Male 325 | 171.8,66.1,Male 326 | 182.0,72.0,Male 327 | 167.0,64.6,Male 328 | 177.8,74.8,Male 329 | 164.5,70.0,Male 330 | 192.0,101.6,Male 331 | 175.5,63.2,Male 332 | 171.2,79.1,Male 333 | 181.6,78.9,Male 334 | 167.4,67.7,Male 335 | 181.1,66.0,Male 336 | 177.0,68.2,Male 337 | 174.5,63.9,Male 338 | 177.5,72.0,Male 339 | 170.5,56.8,Male 340 | 182.4,74.5,Male 341 | 197.1,90.9,Male 342 | 180.1,93.0,Male 343 | 175.5,80.9,Male 344 | 180.6,72.7,Male 345 | 184.4,68.0,Male 346 | 175.5,70.9,Male 347 | 180.6,72.5,Male 348 | 177.0,72.5,Male 349 | 177.1,83.4,Male 350 | 181.6,75.5,Male 351 | 176.5,73.0,Male 352 | 175.0,70.2,Male 353 | 174.0,73.4,Male 354 | 165.1,70.5,Male 355 | 177.0,68.9,Male 356 | 192.0,102.3,Male 357 | 176.5,68.4,Male 358 | 169.4,65.9,Male 359 | 182.1,75.7,Male 360 | 179.8,84.5,Male 361 | 175.3,87.7,Male 362 | 184.9,86.4,Male 363 | 177.3,73.2,Male 364 | 167.4,53.9,Male 365 | 178.1,72.0,Male 366 | 168.9,55.5,Male 367 | 157.2,58.4,Male 368 | 180.3,83.2,Male 369 | 170.2,72.7,Male 370 | 177.8,64.1,Male 371 | 172.7,72.3,Male 372 | 165.1,65.0,Male 373 | 186.7,86.4,Male 374 | 165.1,65.0,Male 375 | 174.0,88.6,Male 376 | 175.3,84.1,Male 377 | 185.4,66.8,Male 378 | 177.8,75.5,Male 379 | 180.3,93.2,Male 380 | 180.3,82.7,Male 381 | 177.8,58.0,Male 382 | 177.8,79.5,Male 383 | 177.8,78.6,Male 384 | 177.8,71.8,Male 385 | 177.8,116.4,Male 386 | 163.8,72.2,Male 387 | 188.0,83.6,Male 388 | 198.1,85.5,Male 389 | 175.3,90.9,Male 390 | 166.4,85.9,Male 391 | 190.5,89.1,Male 392 | 166.4,75.0,Male 393 | 177.8,77.7,Male 394 | 179.7,86.4,Male 395 | 172.7,90.9,Male 396 | 190.5,73.6,Male 397 | 185.4,76.4,Male 398 | 168.9,69.1,Male 399 | 167.6,84.5,Male 400 | 175.3,64.5,Male 401 | 170.2,69.1,Male 402 | 190.5,108.6,Male 403 | 177.8,86.4,Male 404 | 190.5,80.9,Male 405 | 177.8,87.7,Male 406 | 184.2,94.5,Male 407 | 176.5,80.2,Male 408 | 177.8,72.0,Male 409 | 180.3,71.4,Male 410 | 171.4,72.7,Male 411 | 172.7,84.1,Male 412 | 172.7,76.8,Male 413 | 177.8,63.6,Male 414 | 177.8,80.9,Male 415 | 182.9,80.9,Male 416 | 170.2,85.5,Male 417 | 167.6,68.6,Male 418 | 175.3,67.7,Male 419 | 165.1,66.4,Male 420 | 185.4,102.3,Male 421 | 181.6,70.5,Male 422 | 172.7,95.9,Male 423 | 190.5,84.1,Male 424 | 179.1,87.3,Male 425 | 175.3,71.8,Male 426 | 170.2,65.9,Male 427 | 193.0,95.9,Male 428 | 171.4,91.4,Male 429 | 177.8,81.8,Male 430 | 177.8,96.8,Male 431 | 167.6,69.1,Male 432 | 167.6,82.7,Male 433 | 180.3,75.5,Male 434 | 182.9,79.5,Male 435 | 176.5,73.6,Male 436 | 186.7,91.8,Male 437 | 188.0,84.1,Male 438 | 188.0,85.9,Male 439 | 177.8,81.8,Male 440 | 174.0,82.5,Male 441 | 177.8,80.5,Male 442 | 171.4,70.0,Male 443 | 185.4,81.8,Male 444 | 185.4,84.1,Male 445 | 188.0,90.5,Male 446 | 188.0,91.4,Male 447 | 182.9,89.1,Male 448 | 176.5,85.0,Male 449 | 175.3,69.1,Male 450 | 175.3,73.6,Male 451 | 188.0,80.5,Male 452 | 188.0,82.7,Male 453 | 175.3,86.4,Male 454 | 170.5,67.7,Male 455 | 179.1,92.7,Male 456 | 177.8,93.6,Male 457 | 175.3,70.9,Male 458 | 182.9,75.0,Male 459 | 170.8,93.2,Male 460 | 188.0,93.2,Male 461 | 180.3,77.7,Male 462 | 177.8,61.4,Male 463 | 185.4,94.1,Male 464 | 168.9,75.0,Male 465 | 185.4,83.6,Male 466 | 180.3,85.5,Male 467 | 174.0,73.9,Male 468 | 167.6,66.8,Male 469 | 182.9,87.3,Male 470 | 160.0,72.3,Male 471 | 180.3,88.6,Male 472 | 167.6,75.5,Male 473 | 186.7,101.4,Male 474 | 175.3,91.1,Male 475 | 175.3,67.3,Male 476 | 175.9,77.7,Male 477 | 175.3,81.8,Male 478 | 179.1,75.5,Male 479 | 181.6,84.5,Male 480 | 177.8,76.6,Male 481 | 182.9,85.0,Male 482 | 177.8,102.5,Male 483 | 184.2,77.3,Male 484 | 179.1,71.8,Male 485 | 176.5,87.9,Male 486 | 188.0,94.3,Male 487 | 174.0,70.9,Male 488 | 167.6,64.5,Male 489 | 170.2,77.3,Male 490 | 167.6,72.3,Male 491 | 188.0,87.3,Male 492 | 174.0,80.0,Male 493 | 176.5,82.3,Male 494 | 180.3,73.6,Male 495 | 167.6,74.1,Male 496 | 188.0,85.9,Male 497 | 180.3,73.2,Male 498 | 167.6,76.3,Male 499 | 183.0,65.9,Male 500 | 183.0,90.9,Male 501 | 179.1,89.1,Male 502 | 170.2,62.3,Male 503 | 177.8,82.7,Male 504 | 179.1,79.1,Male 505 | 190.5,98.2,Male 506 | 177.8,84.1,Male 507 | 180.3,83.2,Male 508 | 180.3,83.2,Male 509 | -------------------------------------------------------------------------------- /ezhc/samples/df_several_idx_one_col_2.csv: -------------------------------------------------------------------------------- 1 | Continent,Region,Country,Population 2 | Africa,Eastern Africa,Ethiopia,104957438.0 3 | Africa,Eastern Africa,Tanzania,57310019.0 4 | Africa,Eastern Africa,Kenya,49699862.0 5 | Africa,Eastern Africa,Uganda,42862958.0 6 | Africa,Eastern Africa,Mozambique,29668834.0 7 | Africa,Eastern Africa,Madagascar,25570895.0 8 | Africa,Eastern Africa,Malawi,18622104.0 9 | Africa,Eastern Africa,Zambia,17094130.0 10 | Africa,Eastern Africa,Zimbabwe,16529904.0 11 | Africa,Eastern Africa,Somalia,14742523.0 12 | Africa,Eastern Africa,South Sudan,12575714.0 13 | Africa,Eastern Africa,Rwanda,12208407.0 14 | Africa,Eastern Africa,Burundi,10864245.0 15 | Africa,Eastern Africa,Eritrea,5068831.0 16 | Africa,Eastern Africa,Mauritius,1265138.0 17 | Africa,Eastern Africa,Djibouti,956985.0 18 | Africa,Eastern Africa,Réunion,876562.0 19 | Africa,Eastern Africa,Comoros,813912.0 20 | Africa,Eastern Africa,Mayotte,253045.0 21 | Africa,Eastern Africa,Seychelles,94737.0 22 | Africa,Western Africa,Nigeria,190886311.0 23 | Africa,Western Africa,Ghana,28833629.0 24 | Africa,Western Africa,Côte Ivoire,24294750.0 25 | Africa,Western Africa,Niger,21477348.0 26 | Africa,Western Africa,Burkina Faso,19193382.0 27 | Africa,Western Africa,Mali,18541980.0 28 | Africa,Western Africa,Senegal,15850567.0 29 | Africa,Western Africa,Guinea,12717176.0 30 | Africa,Western Africa,Benin,11175692.0 31 | Africa,Western Africa,Togo,7797694.0 32 | Africa,Western Africa,Sierra Leone,7557212.0 33 | Africa,Western Africa,Liberia,4731906.0 34 | Africa,Western Africa,Mauritania,4420184.0 35 | Africa,Western Africa,The Gambia,2100568.0 36 | Africa,Western Africa,Guinea-Bissau,1861283.0 37 | Africa,Western Africa,Cabo Verde,546388.0 38 | Africa,Western Africa,"Saint Helena, Ascension and Tristan da Cunha",4049.0 39 | Africa,North Africa,Egypt,97553151.0 40 | Africa,North Africa,Algeria,41318142.0 41 | Africa,North Africa,Sudan,40533330.0 42 | Africa,North Africa,Morocco,35739580.0 43 | Africa,North Africa,Tunisia,11532127.0 44 | Africa,North Africa,Libya,6374616.0 45 | Africa,North Africa,Western Sahara,552628.0 46 | Africa,Central Africa,Democratic Republic of the Congo,81339988.0 47 | Africa,Central Africa,Angola,29784193.0 48 | Africa,Central Africa,Cameroon,24053727.0 49 | Africa,Central Africa,Chad,14899994.0 50 | Africa,Central Africa,Congo,5260750.0 51 | Africa,Central Africa,Central African Republic,4659080.0 52 | Africa,Central Africa,Gabon,2025137.0 53 | Africa,Central Africa,Equatorial Guinea,1267689.0 54 | Africa,Central Africa,Sao Tome and Principe,204327.0 55 | Africa,South America,Brazil,209288278.0 56 | Africa,South America,Colombia,49065615.0 57 | Africa,South America,Argentina,44271041.0 58 | Africa,South America,Peru,32165485.0 59 | Africa,South America,Venezuela,31977065.0 60 | Africa,South America,Chile,18054726.0 61 | Africa,South America,Ecuador,16624858.0 62 | Africa,South America,Bolivia,11051600.0 63 | Africa,South America,Paraguay,6811297.0 64 | Africa,South America,Uruguay,3456750.0 65 | Africa,South America,Guyana,777859.0 66 | Africa,South America,Suriname,563402.0 67 | Africa,South America,French Guiana,282731.0 68 | Africa,South America,Falkland Islands,2910.0 69 | America,South America,Brazil,209288278.0 70 | America,South America,Colombia,49065615.0 71 | America,South America,Argentina,44271041.0 72 | America,South America,Peru,32165485.0 73 | America,South America,Venezuela,31977065.0 74 | America,South America,Chile,18054726.0 75 | America,South America,Ecuador,16624858.0 76 | America,South America,Bolivia,11051600.0 77 | America,South America,Paraguay,6811297.0 78 | America,South America,Uruguay,3456750.0 79 | America,South America,Guyana,777859.0 80 | America,South America,Suriname,563402.0 81 | America,South America,French Guiana,282731.0 82 | America,South America,Falkland Islands,2910.0 83 | America,Northern America,United States,324459463.0 84 | America,Northern America,Canada,36624199.0 85 | America,Northern America,Bermuda,61349.0 86 | America,Northern America,Greenland,56480.0 87 | America,Northern America,Saint Pierre and Miquelon,6320.0 88 | America,Central America,Mexico,129163276.0 89 | America,Central America,Guatemala,16913503.0 90 | America,Central America,Honduras,9265067.0 91 | America,Central America,El Salvador,6377853.0 92 | America,Central America,Nicaragua,6217581.0 93 | America,Central America,Costa Rica,4905769.0 94 | America,Central America,Panama,4098587.0 95 | America,Central America,Belize,374681.0 96 | America,Caribbean,Cuba,11484636.0 97 | America,Caribbean,Haiti,10981229.0 98 | America,Caribbean,Dominican Republic,10766998.0 99 | America,Caribbean,Puerto Rico,3663131.0 100 | America,Caribbean,Jamaica,2890299.0 101 | America,Caribbean,Trinidad and Tobago,1369125.0 102 | America,Caribbean,Guadeloupe,449568.0 103 | America,Caribbean,Bahamas,395361.0 104 | America,Caribbean,Martinique,384896.0 105 | America,Caribbean,Barbados,285719.0 106 | America,Caribbean,Saint Lucia,178844.0 107 | America,Caribbean,Curaçao,160539.0 108 | America,Caribbean,Saint Vincent and the Grenadines,109897.0 109 | America,Caribbean,Grenada,107825.0 110 | America,Caribbean,Aruba,105264.0 111 | America,Caribbean,United States Virgin Islands,104901.0 112 | America,Caribbean,Antigua and Barbuda,102012.0 113 | America,Caribbean,Dominica,73925.0 114 | America,Caribbean,Cayman Islands,61559.0 115 | America,Caribbean,Saint Kitts and Nevis,55345.0 116 | America,Caribbean,Sint Maarten,40120.0 117 | America,Caribbean,Turks and Caicos Islands,35446.0 118 | America,Caribbean,British Virgin Islands,31196.0 119 | America,Caribbean,Caribbean Netherlands,25398.0 120 | America,Caribbean,Anguilla,14909.0 121 | America,Caribbean,Montserrat,5177.0 122 | Asia,Southern Asia,India,1339180127.0 123 | Asia,Southern Asia,Pakistan,197015955.0 124 | Asia,Southern Asia,Bangladesh,164669751.0 125 | Asia,Southern Asia,Iran,81162788.0 126 | Asia,Southern Asia,Afghanistan,35530081.0 127 | Asia,Southern Asia,Nepal,29304998.0 128 | Asia,Southern Asia,Sri Lanka,20876917.0 129 | Asia,Southern Asia,Bhutan,807610.0 130 | Asia,Southern Asia,Maldives,436330.0 131 | Asia,Eastern Asia,China,1409517397.0 132 | Asia,Eastern Asia,Japan,127484450.0 133 | Asia,Eastern Asia,South Korea,50982212.0 134 | Asia,Eastern Asia,North Korea,25490965.0 135 | Asia,Eastern Asia,Taiwan,23626456.0 136 | Asia,Eastern Asia,Hong Kong,7364883.0 137 | Asia,Eastern Asia,Mongolia,3075647.0 138 | Asia,Eastern Asia,Macau,622567.0 139 | Asia,South-Eastern Asia,Indonesia,263991379.0 140 | Asia,South-Eastern Asia,Philippines,104918090.0 141 | Asia,South-Eastern Asia,Vietnam,95540800.0 142 | Asia,South-Eastern Asia,Thailand,69037513.0 143 | Asia,South-Eastern Asia,Myanmar,53370609.0 144 | Asia,South-Eastern Asia,Malaysia,31624264.0 145 | Asia,South-Eastern Asia,Cambodia,16005373.0 146 | Asia,South-Eastern Asia,Laos,6858160.0 147 | Asia,South-Eastern Asia,Singapore,5708844.0 148 | Asia,South-Eastern Asia,Timor-Leste,1296311.0 149 | Asia,South-Eastern Asia,Brunei,428697.0 150 | Asia,Western Asia,Turkey,80745020.0 151 | Asia,Western Asia,Iraq,38274618.0 152 | Asia,Western Asia,Saudi Arabia,32938213.0 153 | Asia,Western Asia,Yemen,28250420.0 154 | Asia,Western Asia,Syria,18269868.0 155 | Asia,Western Asia,Azerbaijan,9827589.0 156 | Asia,Western Asia,Jordan,9702353.0 157 | Asia,Western Asia,United Arab Emirates,9400145.0 158 | Asia,Western Asia,Israel,8321570.0 159 | Asia,Western Asia,Lebanon,6082357.0 160 | Asia,Western Asia,Palestine,4920724.0 161 | Asia,Western Asia,Oman,4636262.0 162 | Asia,Western Asia,Kuwait,4136528.0 163 | Asia,Western Asia,Georgia,3912061.0 164 | Asia,Western Asia,Armenia,2930450.0 165 | Asia,Western Asia,Qatar,2639211.0 166 | Asia,Western Asia,Bahrain,1492584.0 167 | Asia,Central Asia,Uzbekistan,31910641.0 168 | Asia,Central Asia,Kazakhstan,18204499.0 169 | Asia,Central Asia,Tajikistan,8921343.0 170 | Asia,Central Asia,Kyrgyzstan,6045117.0 171 | Asia,Central Asia,Turkmenistan,5758075.0 172 | Europe,Eastern Europe,Russia,143989754.0 173 | Europe,Eastern Europe,Ukraine,44222947.0 174 | Europe,Eastern Europe,Poland,38170712.0 175 | Europe,Eastern Europe,Romania,19679306.0 176 | Europe,Eastern Europe,Czechia,10618303.0 177 | Europe,Eastern Europe,Hungary,9721559.0 178 | Europe,Eastern Europe,Belarus,9468338.0 179 | Europe,Eastern Europe,Bulgaria,7084571.0 180 | Europe,Eastern Europe,Slovakia,5447662.0 181 | Europe,Eastern Europe,Moldova,4051212.0 182 | Europe,Eastern Europe,Cyprus,1179551.0 183 | Europe,Northern Europe,United Kingdom,66181585.0 184 | Europe,Northern Europe,Sweden,9910701.0 185 | Europe,Northern Europe,Denmark,5733551.0 186 | Europe,Northern Europe,Finland,5523231.0 187 | Europe,Northern Europe,Norway,5305383.0 188 | Europe,Northern Europe,Ireland,4761657.0 189 | Europe,Northern Europe,Lithuania,2890297.0 190 | Europe,Northern Europe,Latvia,1949670.0 191 | Europe,Northern Europe,Estonia,1309632.0 192 | Europe,Northern Europe,Iceland,335025.0 193 | Europe,Northern Europe,Guernsey and Jersey,165314.0 194 | Europe,Northern Europe,Isle of Man,84287.0 195 | Europe,Northern Europe,Faroe Islands,49290.0 196 | Europe,Southern Europe,Italy,59359900.0 197 | Europe,Southern Europe,Spain,46354321.0 198 | Europe,Southern Europe,Greece,11159773.0 199 | Europe,Southern Europe,Portugal,10329506.0 200 | Europe,Southern Europe,Serbia,8790574.0 201 | Europe,Southern Europe,Croatia,4189353.0 202 | Europe,Southern Europe,Bosnia and Herzegovina,3507017.0 203 | Europe,Southern Europe,Albania,2930187.0 204 | Europe,Southern Europe,Republic of Macedonia,2083160.0 205 | Europe,Southern Europe,Slovenia,2079976.0 206 | Europe,Southern Europe,Montenegro,628960.0 207 | Europe,Southern Europe,Malta,430835.0 208 | Europe,Southern Europe,Andorra,76965.0 209 | Europe,Southern Europe,Gibraltar,34571.0 210 | Europe,Southern Europe,San Marino,33400.0 211 | Europe,Southern Europe,Vatican City,792.0 212 | Europe,Western Europe,Germany,82114224.0 213 | Europe,Western Europe,France,64979548.0 214 | Europe,Western Europe,Netherlands,17035938.0 215 | Europe,Western Europe,Belgium,11429336.0 216 | Europe,Western Europe,Austria,8735453.0 217 | Europe,Western Europe,Switzerland,8476005.0 218 | Europe,Western Europe,Luxembourg,583455.0 219 | Europe,Western Europe,Monaco,38695.0 220 | Europe,Western Europe,Liechtenstein,37922.0 221 | Oceanic,Australia and New Zealand,Australia,24450561.0 222 | Oceanic,Australia and New Zealand,New Zealand,4705818.0 223 | Oceanic,Melanesia,Papua New Guinea, 224 | Oceanic,Melanesia,Fiji,905502.0 225 | Oceanic,Melanesia,Solomon Islands,611343.0 226 | Oceanic,Melanesia,New Caledonia,276255.0 227 | Oceanic,Melanesia,Vanuatu,276244.0 228 | Oceanic,Micronesia,Guam,164229.0 229 | Oceanic,Micronesia,Kiribati,116398.0 230 | Oceanic,Micronesia,Federated States of Micronesia,105544.0 231 | Oceanic,Micronesia,Northern Mariana Islands,55144.0 232 | Oceanic,Micronesia,Marshall Islands,53127.0 233 | Oceanic,Micronesia,Palau,21729.0 234 | Oceanic,Micronesia,Nauru,11359.0 235 | Oceanic,Polynesia,French Polynesia,283007.0 236 | Oceanic,Polynesia,Samoa,196440.0 237 | Oceanic,Polynesia,Tonga,108020.0 238 | Oceanic,Polynesia,American Samoa,55641.0 239 | Oceanic,Polynesia,Cook Islands,17380.0 240 | Oceanic,Polynesia,Wallis and Futuna,11773.0 241 | Oceanic,Polynesia,Tuvalu,11192.0 242 | Oceanic,Polynesia,Niue,1618.0 243 | Oceanic,Polynesia,Tokelau,1300.0 244 | -------------------------------------------------------------------------------- /ezhc/samples/df_two_idx_one_col.csv: -------------------------------------------------------------------------------- 1 | Brand,Version,Market Share 2 | Internet Explorer,6.0,6.4 3 | Internet Explorer,7.0,3.55 4 | Internet Explorer,8.0,26.7 5 | Internet Explorer,9.0,16.96 6 | Firefox,2.0,0.09 7 | Firefox,3.0,0.36 8 | Firefox,3.5,0.36 9 | Firefox,3.6,1.87 10 | Firefox,4.0,0.5 11 | Firefox,5.0,0.31 12 | Firefox,6.0,0.32 13 | Firefox,7.0,0.29 14 | Firefox,8.0,0.55 15 | Firefox,9.0,0.65 16 | Firefox,10,0.9 17 | Firefox,11,4.72 18 | Firefox,12,6.72 19 | Firefox,13,2.16 20 | Firefox,14.0,0.1 21 | Chrome,10,0.09 22 | Chrome,11,0.1 23 | Chrome,12,0.16 24 | Chrome,13,0.13 25 | Chrome,14.0,0.25 26 | Chrome,15.0,0.18 27 | Chrome,16.0,0.45 28 | Chrome,17.0,1.13 29 | Chrome,18.0,8.27 30 | Chrome,19.0,7.73 31 | Chrome,20.0,0.24 32 | Safari,4.0,0.14 33 | Safari,4.1,0.12 34 | Safari,5.0,0.85 35 | Safari,5.1,3.53 36 | Opera,10.x,0.09 37 | Opera,11.x,1.3 38 | Opera,12.x,0.15 39 | Unknown,Unknown,0.29 40 | -------------------------------------------------------------------------------- /ezhc/samples/df_two_idx_several_col.csv: -------------------------------------------------------------------------------- 1 | Strategy,Ticker,5Y,1Y 2 | Commo Roll-yield,SGICLMFV,0.5370451,0.7333421971495934 3 | Commo Trend,SGIXTFCY,-0.3293532,0.048283030173804975 4 | Credit Short vol,SGIMCESP,-0.308817,-0.3777033687131688 5 | Credit Trend,SGIXGCM,-0.3090037,-0.36475371724201167 6 | Defensive,SGBVPHLE,0.013125,0.3612929384992754 7 | Defensive,SGBVPHQE,0.1705903,0.5452781879645822 8 | Defensive,SGSLQAE,-0.22688560000000002,-0.34620407420579297 9 | Defensive,SGSLQAU,-0.1699097,-0.2037813431398829 10 | Defensive,SGSLQAW,-0.1768096,-0.3587694109556843 11 | Div Roll yield,SGBVDRY,0.323195,0.3149040612388768 12 | EU MR,SGIXEUGR,0.09506260000000001,0.1651109187969738 13 | EU MR,SGIXMTE,0.0859626,-0.2376601076535272 14 | EU MR,SGIXTNE,0.1755753,-0.526895841719151 15 | Eqy Short vol,SGIXVP3,0.17562350000000002,-0.03664742371905219 16 | Eqy Trend,SGIXTFEQ,-0.13122589999999998,-0.4070213231937968 17 | FX Carry,SGIFXH10,-0.09989210000000001,-0.3335265292448509 18 | FX MR,SGIFXM10,0.0341679,-0.3489653407465959 19 | FX Short vol,SGIFXG4,-0.7086976,-0.5702311313763152 20 | FX Trend,SGIXTFFX,-0.23866450000000003,-0.8060459798961913 21 | IR Trend,SGIXTFIR,0.3485816,0.2513637051958637 22 | Momentum,SGBVPMEU,-0.349043,-0.048290195729987495 23 | Momentum,SGSLMAE,0.34813330000000003,0.39265367410141855 24 | Momentum,SGSLMAU,-0.1774919,-0.4276787764161665 25 | Momentum,SGSLMAW,0.0011804,-0.3420532439258364 26 | Profitability,SGBVPHPE,0.1358282,0.26022327414502755 27 | Profitability,SGSLPAE,-0.31085329999999994,-0.6609708639165219 28 | Profitability,SGSLPAU,-0.2137515,-0.17324869554595207 29 | Profitability,SGSLPAW,-0.13678959999999998,-0.15367813958971197 30 | Rates Carry,SGIXBE3E,-0.20452720000000002,-0.5184559549532537 31 | Rates Carry,SGIXBHE5,-0.172627,-0.45488627634771583 32 | Rates FRB,SGIXMOE2,-0.000157684,-0.5000695344888871 33 | Rates FRB,SGIXMOGS,-0.39852719999999997,-0.3235294014315888 34 | Rates FRB,SGIXMOUS,-0.626708,-0.6119790731474299 35 | Rates Roll-yield,SGIXCCSE,-0.3453906,-0.06174266600269507 36 | Rates Roll-yield,SGIXCCSU,-0.5587850999999999,-1.1568995121001788 37 | Rates Short vol,SGIXIRSP,0.2607208,0.1907465954125647 38 | US MR,SGIXUSGR,0.0933473,0.0997387522777567 39 | US MR,SGIXVIGR,-0.39749870000000004,-0.7428363157414595 40 | VIX Roll yield,DSVIX,0.3345415,0.5497900901107085 41 | VIX Roll yield,SGIXVIDC,0.2011225,0.2640229455196267 42 | Value,SGBVPHVE,0.22574410000000003,0.5996090629342496 43 | Value,SGSLVAE,0.1507235,0.41312730521126 44 | Value,SGSLVAU,0.1717714,-0.4108860980792959 45 | Value,SGSLVAW,0.031459,-0.06179194546727261 46 | Value/Defensive,SGSLVQAE,-0.2039749,-0.7919550708161043 47 | Value/Defensive,SGSLVQAU,0.004480060000000001,-0.28400559637526723 48 | Value/Defensive,SGSLVQAW,-0.1434506,-0.28094695248654367 49 | XA7 Dual Mom,SGBVCADM,0.0820668,0.4788789030742203 50 | XA7 Trend,SGIXTFXA,-0.10739130000000001,0.2811105580797879 51 | -------------------------------------------------------------------------------- /ezhc/script/Jupyter_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oscar6echo/ezhc/aea6225990d0ff6818dd642c7668cb6b9666f131/ezhc/script/Jupyter_logo.png -------------------------------------------------------------------------------- /ezhc/script/SG_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/oscar6echo/ezhc/aea6225990d0ff6818dd642c7668cb6b9666f131/ezhc/script/SG_logo.png -------------------------------------------------------------------------------- /ezhc/script/financial_time_series_0.js: -------------------------------------------------------------------------------- 1 | 2 | function create_table_0(uuid, chart) { 3 | if (typeof window.charts == "undefined") { 4 | window.charts = {}; 5 | } 6 | window.charts[uuid] = chart; 7 | console.log('create_table_0 '+uuid); 8 | } 9 | -------------------------------------------------------------------------------- /ezhc/script/financial_time_series_table.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 20 | 21 |
    22 |
    23 |
    24 |
    25 |
    26 |
    27 |
    28 |
    29 |
    30 | Drawdown Number of bdays 31 | 32 | 33 |
    34 |
    35 |
    36 | 37 | -------------------------------------------------------------------------------- /ezhc/script/financial_time_series_table_1.js: -------------------------------------------------------------------------------- 1 | 2 | var isNumber = function(n) { return !isNaN(parseFloat(n)) && isFinite(n); }; 3 | 4 | var fmt_nb_pct = function(d) { if (isNumber(d)) { var f = d3.format("+,.1%"); return f(d) } 5 | else { return d; } 6 | } 7 | var fmt_nb_flo = function(d) { if (isNumber(d)) { var f = d3.format("+,.2f"); return f(d) } 8 | else { return d; } 9 | } 10 | 11 | 12 | function cash_idx_in_series(uuid) { 13 | var t = -1, 14 | opt = window.opts[uuid]; 15 | 16 | for (var i=1; i=mint & t<=maxt) { 37 | ts.data.push({t: t, v: data[i][1]}) 38 | } 39 | } 40 | return ts; 41 | } 42 | 43 | 44 | function get_perf(ts) { 45 | var n = ts.data.length, 46 | first_val = ts.data[0].v, 47 | last_val = ts.data[n-1].v; 48 | perf = last_val/first_val-1.0; 49 | return perf; 50 | } 51 | 52 | 53 | function get_irr(ts) { 54 | var n = ts.data.length, 55 | first_date = new Date(ts.data[0].t), 56 | last_date = new Date(ts.data[n-1].t), 57 | first_val = ts.data[0].v, 58 | last_val = ts.data[n-1].v, 59 | dt, irr; 60 | dt = parseInt((last_date - first_date) / (1000 * 60 * 60 * 24)); 61 | irr = Math.pow((last_val/first_val), 365/dt)-1.0; 62 | return irr; 63 | } 64 | 65 | 66 | function get_vol(ts) { 67 | var sum = 0, 68 | date, prev_date = new Date(ts.data[0].t), 69 | val, prev_val = ts.data[0].v, 70 | dt, vol; 71 | for (var i=1; i' ); 117 | 118 | var data = update_table_data_1(uuid, chart); 119 | var dtable = init_table_1(uuid, chart, data); 120 | 121 | window.data = data; 122 | window.dtable = dtable; 123 | console.log('create_table_1 '+uuid); 124 | } 125 | 126 | 127 | function init_table_1(uuid, chart, data) { 128 | var dtable = $('#'+uuid+' .dtable').DataTable( { 129 | data: data.arr, 130 | columns: data.col, 131 | // dom: "CTftip", 132 | dom: "tB", 133 | order: [], 134 | lengthMenu: [[-1], ["All"]], 135 | columnDefs: [ 136 | { "width": "35%", "targets": 0 }, 137 | { "width": "13%", "targets": [1, 2, 3, 4, 5] } 138 | ], 139 | } ); 140 | var dtablejq = $('#'+uuid+' .dtable').dataTable(); 141 | color_dtable_series_name_1(uuid, chart, dtablejq); 142 | 143 | window.dtable = dtable; 144 | window.dtablejq = dtablejq; 145 | 146 | console.log('init_table_1 '+uuid); 147 | return dtable; 148 | } 149 | 150 | 151 | function color_dtable_series_name_1(uuid, chart, dtablejq) { 152 | window.toto = chart; 153 | 154 | var color_series = chart.series.map(function(d) { return d.color; }); 155 | $('#'+uuid+' td:first-child').each(function(i, d) { $(this).css('color', color_series[i]); }) 156 | } 157 | 158 | 159 | function update_table_1(uuid) { 160 | var chart = window.charts[uuid], 161 | data = update_table_data_1(uuid, chart), 162 | dtable = $('#'+uuid+' .dtable').DataTable() 163 | dtable.clear(); 164 | dtable.rows.add(data.arr); 165 | dtable.draw(); 166 | color_dtable_series_name_1(uuid, chart, dtablejq) 167 | 168 | window.data = data; 169 | console.log('update_table_1 '+uuid); 170 | } 171 | 172 | 173 | function update_table_data_1(uuid, chart) { 174 | var extremes = chart.xAxis[0].getExtremes(), 175 | results = [], 176 | ts, perf, irr, vol, irr_cash, sharpe, max_dd; 177 | 178 | window.extremes = extremes; 179 | 180 | var c = cash_idx_in_series(uuid); 181 | if (c>0) { 182 | cash_ts = get_timeseries(uuid, c, extremes); 183 | irr_cash = get_irr(cash_ts); 184 | } 185 | else { 186 | irr_cash = 0; 187 | } 188 | 189 | for (var k=0; k=mint & t<=maxt) { 23 | ts.data.push({t: t, v: data[i][1]}) 24 | } 25 | } 26 | return ts; 27 | } 28 | 29 | 30 | function get_min(ts) { 31 | var arr = ts.data.map(function(d){ return d.v; }); 32 | return Math.min(...arr); 33 | } 34 | 35 | 36 | function get_max(ts) { 37 | var arr = ts.data.map(function(d){ return d.v; }); 38 | return Math.max(...arr); 39 | } 40 | 41 | 42 | function get_avg(ts) { 43 | var arr = ts.data.map(function(d){ return d.v; }); 44 | var s = arr.reduce(function(a, b){ return a+b; }); 45 | return s/arr.length; 46 | } 47 | 48 | 49 | function get_max_drawdown(ts, nb_bd) { 50 | var dd = Number.POSITIVE_INFINITY, 51 | val, ref_val; 52 | 53 | for (var i=nb_bd; i' ); 82 | 83 | var data = update_table_data_2(uuid, chart); 84 | var dtable = init_table_2(uuid, chart, data); 85 | 86 | window.data = data; 87 | window.dtable = dtable; 88 | console.log('create_table_2 '+uuid); 89 | } 90 | 91 | 92 | function init_table_2(uuid, chart, data) { 93 | var dtable = $('#'+uuid+' .dtable').DataTable( { 94 | data: data.arr, 95 | columns: data.col, 96 | // dom: "CTftip", 97 | dom: "tB", 98 | order: [], 99 | lengthMenu: [[-1], ["All"]], 100 | columnDefs: [ 101 | { "width": "40%", "targets": 0 }, 102 | { "width": "13%", "targets": [1, 2, 3, 4] } 103 | ], 104 | } ); 105 | var dtablejq = $('#'+uuid+' .dtable').dataTable(); 106 | color_dtable_series_name_2(uuid, chart, dtablejq); 107 | 108 | window.dtable = dtable; 109 | window.dtablejq = dtablejq; 110 | 111 | console.log('init_table_2 '+uuid); 112 | return dtable; 113 | } 114 | 115 | 116 | function color_dtable_series_name_2(uuid, chart, dtablejq) { 117 | var color_series = chart.series.map(function(d) { return d.color; }); 118 | $('#'+uuid+' td:first-child').each(function(i, d) { $(this).css('color', color_series[i]); }) 119 | } 120 | 121 | 122 | function update_table_2(uuid) { 123 | var chart = window.charts[uuid], 124 | data = update_table_data_2(uuid, chart), 125 | dtable = $('#'+uuid+' .dtable').DataTable() 126 | dtable.clear(); 127 | dtable.rows.add(data.arr); 128 | dtable.draw(); 129 | color_dtable_series_name_2(uuid, chart, dtablejq) 130 | 131 | window.data = data; 132 | console.log('update_table_2 '+uuid); 133 | } 134 | 135 | 136 | function update_table_data_2(uuid, chart) { 137 | var extremes = chart.xAxis[0].getExtremes(), 138 | results = [], 139 | ts, min, max, avf, max_dd; 140 | 141 | window.extremes = extremes; 142 | 143 | for (var k=0; k 0 ? ' + ' : '') + this.value; } 2 | -------------------------------------------------------------------------------- /ezhc/script/formatter_percent.js: -------------------------------------------------------------------------------- 1 | function() { return (this.value > 0 ? ' + ' : '') + this.value + '%'; } 2 | -------------------------------------------------------------------------------- /ezhc/script/formatter_quantile.js: -------------------------------------------------------------------------------- 1 | function() { 2 | 3 | var fmt_val = d3.format(',.2f'); 4 | var fmt_qtile = d3.format('.1%'); 5 | 6 | var percentile = function(v, arr){ 7 | var c = 0; 8 | for (var i=0; i'; 21 | 22 | for (point of this.points) { 23 | window.ppoint = point; 24 | s += `${point.series.name}: ${fmt_val(point.y)} (percentile: ${fmt_qtile(get_percentile(point))})
    `; 25 | } 26 | 27 | return s; 28 | 29 | } 30 | 31 | -------------------------------------------------------------------------------- /ezhc/script/json_parse.js: -------------------------------------------------------------------------------- 1 | 2 | options = JSON.stringify(options); 3 | 4 | options = JSON.parse(options, function (key, value) { 5 | 6 | if (value && (typeof value === "string")) { 7 | 8 | // replace spaces then newline characters 9 | var check1 = (value.replace(/\s+/g, '').replace(/\r?\n|\r/g, '').substr(0, 8) == "function"), 10 | check2 = (value.replace(/\s+/g, '').replace(/\r?\n|\r/g, '').substr(0, 9) == "(function"); 11 | 12 | 13 | if (check1) { 14 | var startBody = value.indexOf('{') + 1; 15 | var endBody = value.lastIndexOf('}'); 16 | var startArgs = value.indexOf('(') + 1; 17 | var endArgs = value.indexOf(')'); 18 | 19 | return new Function(value.substring(startArgs, endArgs), 20 | value.substring(startBody, endBody)); 21 | } 22 | if (check2) { 23 | return eval(value); 24 | } 25 | 26 | } 27 | 28 | return value; 29 | 30 | }); -------------------------------------------------------------------------------- /ezhc/script/template_disclaimer.html: -------------------------------------------------------------------------------- 1 | 22 | 23 |
    24 |
    25 |
    26 |
    27 | 28 |
    29 |
    30 | {{ comment }} 31 |
    32 |
    33 | -------------------------------------------------------------------------------- /ezhc/script/themes/avocado.js: -------------------------------------------------------------------------------- 1 | var theme = { 2 | colors: ['#F3E796', '#95C471', '#35729E', '#251735'], 3 | 4 | colorAxis: { 5 | maxColor: '#05426E', 6 | minColor: '#F3E796' 7 | }, 8 | 9 | plotOptions: { 10 | map: { 11 | nullColor: '#fcfefe' 12 | } 13 | }, 14 | 15 | navigator: { 16 | maskFill: 'rgba(170, 205, 170, 0.5)', 17 | series: { 18 | color: '#95C471', 19 | lineColor: '#35729E' 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /ezhc/script/themes/avocado.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors": [ 3 | "#F3E796", 4 | "#95C471", 5 | "#35729E", 6 | "#251735" 7 | ], 8 | "colorAxis": { 9 | "maxColor": "#05426E", 10 | "minColor": "#F3E796" 11 | }, 12 | "plotOptions": { 13 | "map": { 14 | "nullColor": "#fcfefe" 15 | } 16 | }, 17 | "navigator": { 18 | "maskFill": "rgba(170, 205, 170, 0.5)", 19 | "series": { 20 | "color": "#95C471", 21 | "lineColor": "#35729E" 22 | } 23 | } 24 | } -------------------------------------------------------------------------------- /ezhc/script/themes/build_theme_json.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 1, 6 | "metadata": {}, 7 | "outputs": [], 8 | "source": [ 9 | "import os\n", 10 | "from IPython.display import display, Javascript" 11 | ] 12 | }, 13 | { 14 | "cell_type": "code", 15 | "execution_count": 69, 16 | "metadata": {}, 17 | "outputs": [ 18 | { 19 | "data": { 20 | "application/javascript": [ 21 | "var theme = {\n", 22 | "\tcolors: ['#FDD089', '#FF7F79', '#A0446E', '#251535'],\n", 23 | "\n", 24 | "\tcolorAxis: {\n", 25 | "\t\tmaxColor: '#60042E',\n", 26 | "\t\tminColor: '#FDD089'\n", 27 | "\t},\n", 28 | "\n", 29 | "\tplotOptions: {\n", 30 | "\t\tmap: {\n", 31 | "\t\t\tnullColor: '#fefefc'\n", 32 | "\t\t}\n", 33 | "\t},\n", 34 | "\n", 35 | "\tnavigator: {\n", 36 | "\t\tseries: {\n", 37 | "\t\t\tcolor: '#FF7F79',\n", 38 | "\t\t\tlineColor: '#A0446E'\n", 39 | "\t\t}\n", 40 | "\t}\n", 41 | "};window.theme = theme; console.log(\"sunset.js:\"); console.log(theme);" 42 | ], 43 | "text/plain": [ 44 | "" 45 | ] 46 | }, 47 | "metadata": {}, 48 | "output_type": "display_data" 49 | } 50 | ], 51 | "source": [ 52 | "filename = 'sunset.js'\n", 53 | "with open(filename, 'r') as f:\n", 54 | " content = f.read()\n", 55 | " js_theme = content + 'window.theme = theme; console.log(\"{}:\"); console.log(theme);'.format(filename)\n", 56 | " #print(js_theme)\n", 57 | " display(Javascript(js_theme))" 58 | ] 59 | }, 60 | { 61 | "cell_type": "code", 62 | "execution_count": 70, 63 | "metadata": {}, 64 | "outputs": [ 65 | { 66 | "data": { 67 | "application/javascript": [ 68 | "\n", 69 | "window.json_theme = JSON.stringify(window.theme);\n", 70 | "console.log(json_theme);\n" 71 | ], 72 | "text/plain": [ 73 | "" 74 | ] 75 | }, 76 | "execution_count": 70, 77 | "metadata": {}, 78 | "output_type": "execute_result" 79 | } 80 | ], 81 | "source": [ 82 | "js_transform = \"\"\"\n", 83 | "window.json_theme = JSON.stringify(window.theme);\n", 84 | "console.log(json_theme);\n", 85 | "\"\"\"\n", 86 | "Javascript(js_transform)" 87 | ] 88 | }, 89 | { 90 | "cell_type": "code", 91 | "execution_count": null, 92 | "metadata": {}, 93 | "outputs": [], 94 | "source": [] 95 | } 96 | ], 97 | "metadata": { 98 | "kernelspec": { 99 | "display_name": "Python 3", 100 | "language": "python", 101 | "name": "python3" 102 | }, 103 | "language_info": { 104 | "codemirror_mode": { 105 | "name": "ipython", 106 | "version": 3 107 | }, 108 | "file_extension": ".py", 109 | "mimetype": "text/x-python", 110 | "name": "python", 111 | "nbconvert_exporter": "python", 112 | "pygments_lexer": "ipython3", 113 | "version": "3.6.3" 114 | } 115 | }, 116 | "nbformat": 4, 117 | "nbformat_minor": 2 118 | } 119 | -------------------------------------------------------------------------------- /ezhc/script/themes/dark-blue.js: -------------------------------------------------------------------------------- 1 | var theme = { 2 | colors: ['#DDDF0D', '#55BF3B', '#DF5353', '#7798BF', '#aaeeee', 3 | '#ff0066', '#eeaaee', '#55BF3B', '#DF5353', '#7798BF', '#aaeeee'], 4 | chart: { 5 | backgroundColor: { 6 | linearGradient: { x1: 0, y1: 0, x2: 1, y2: 1 }, 7 | stops: [ 8 | [0, 'rgb(48, 48, 96)'], 9 | [1, 'rgb(0, 0, 0)'] 10 | ] 11 | }, 12 | borderColor: '#000000', 13 | borderWidth: 2, 14 | className: 'dark-container', 15 | plotBackgroundColor: 'rgba(255, 255, 255, .1)', 16 | plotBorderColor: '#CCCCCC', 17 | plotBorderWidth: 1 18 | }, 19 | title: { 20 | style: { 21 | color: '#C0C0C0', 22 | font: 'bold 16px "Trebuchet MS", Verdana, sans-serif' 23 | } 24 | }, 25 | subtitle: { 26 | style: { 27 | color: '#666666', 28 | font: 'bold 12px "Trebuchet MS", Verdana, sans-serif' 29 | } 30 | }, 31 | xAxis: { 32 | gridLineColor: '#333333', 33 | gridLineWidth: 1, 34 | labels: { 35 | style: { 36 | color: '#A0A0A0' 37 | } 38 | }, 39 | lineColor: '#A0A0A0', 40 | tickColor: '#A0A0A0', 41 | title: { 42 | style: { 43 | color: '#CCC', 44 | fontWeight: 'bold', 45 | fontSize: '12px', 46 | fontFamily: 'Trebuchet MS, Verdana, sans-serif' 47 | 48 | } 49 | } 50 | }, 51 | yAxis: { 52 | gridLineColor: '#333333', 53 | labels: { 54 | style: { 55 | color: '#A0A0A0' 56 | } 57 | }, 58 | lineColor: '#A0A0A0', 59 | minorTickInterval: null, 60 | tickColor: '#A0A0A0', 61 | tickWidth: 1, 62 | title: { 63 | style: { 64 | color: '#CCC', 65 | fontWeight: 'bold', 66 | fontSize: '12px', 67 | fontFamily: 'Trebuchet MS, Verdana, sans-serif' 68 | } 69 | } 70 | }, 71 | tooltip: { 72 | backgroundColor: 'rgba(0, 0, 0, 0.75)', 73 | style: { 74 | color: '#F0F0F0' 75 | } 76 | }, 77 | toolbar: { 78 | itemStyle: { 79 | color: 'silver' 80 | } 81 | }, 82 | plotOptions: { 83 | line: { 84 | dataLabels: { 85 | color: '#CCC' 86 | }, 87 | marker: { 88 | lineColor: '#333' 89 | } 90 | }, 91 | spline: { 92 | marker: { 93 | lineColor: '#333' 94 | } 95 | }, 96 | scatter: { 97 | marker: { 98 | lineColor: '#333' 99 | } 100 | }, 101 | candlestick: { 102 | lineColor: 'white' 103 | } 104 | }, 105 | legend: { 106 | itemStyle: { 107 | font: '9pt Trebuchet MS, Verdana, sans-serif', 108 | color: '#A0A0A0' 109 | }, 110 | itemHoverStyle: { 111 | color: '#FFF' 112 | }, 113 | itemHiddenStyle: { 114 | color: '#444' 115 | } 116 | }, 117 | credits: { 118 | style: { 119 | color: '#666' 120 | } 121 | }, 122 | labels: { 123 | style: { 124 | color: '#CCC' 125 | } 126 | }, 127 | 128 | navigation: { 129 | buttonOptions: { 130 | symbolStroke: '#DDDDDD', 131 | hoverSymbolStroke: '#FFFFFF', 132 | theme: { 133 | fill: { 134 | linearGradient: { x1: 0, y1: 0, x2: 0, y2: 1 }, 135 | stops: [ 136 | [0.4, '#606060'], 137 | [0.6, '#333333'] 138 | ] 139 | }, 140 | stroke: '#000000' 141 | } 142 | } 143 | }, 144 | 145 | // scroll charts 146 | rangeSelector: { 147 | buttonTheme: { 148 | fill: { 149 | linearGradient: { x1: 0, y1: 0, x2: 0, y2: 1 }, 150 | stops: [ 151 | [0.4, '#888'], 152 | [0.6, '#555'] 153 | ] 154 | }, 155 | stroke: '#000000', 156 | style: { 157 | color: '#CCC', 158 | fontWeight: 'bold' 159 | }, 160 | states: { 161 | hover: { 162 | fill: { 163 | linearGradient: { x1: 0, y1: 0, x2: 0, y2: 1 }, 164 | stops: [ 165 | [0.4, '#BBB'], 166 | [0.6, '#888'] 167 | ] 168 | }, 169 | stroke: '#000000', 170 | style: { 171 | color: 'white' 172 | } 173 | }, 174 | select: { 175 | fill: { 176 | linearGradient: { x1: 0, y1: 0, x2: 0, y2: 1 }, 177 | stops: [ 178 | [0.1, '#000'], 179 | [0.3, '#333'] 180 | ] 181 | }, 182 | stroke: '#000000', 183 | style: { 184 | color: 'yellow' 185 | } 186 | } 187 | } 188 | }, 189 | inputStyle: { 190 | backgroundColor: '#333', 191 | color: 'silver' 192 | }, 193 | labelStyle: { 194 | color: 'silver' 195 | } 196 | }, 197 | 198 | navigator: { 199 | handles: { 200 | backgroundColor: '#666', 201 | borderColor: '#AAA' 202 | }, 203 | outlineColor: '#CCC', 204 | maskFill: 'rgba(16, 16, 16, 0.5)', 205 | series: { 206 | color: '#7798BF', 207 | lineColor: '#A6C7ED' 208 | } 209 | }, 210 | 211 | scrollbar: { 212 | barBackgroundColor: { 213 | linearGradient: { x1: 0, y1: 0, x2: 0, y2: 1 }, 214 | stops: [ 215 | [0.4, '#888'], 216 | [0.6, '#555'] 217 | ] 218 | }, 219 | barBorderColor: '#CCC', 220 | buttonArrowColor: '#CCC', 221 | buttonBackgroundColor: { 222 | linearGradient: { x1: 0, y1: 0, x2: 0, y2: 1 }, 223 | stops: [ 224 | [0.4, '#888'], 225 | [0.6, '#555'] 226 | ] 227 | }, 228 | buttonBorderColor: '#CCC', 229 | rifleColor: '#FFF', 230 | trackBackgroundColor: { 231 | linearGradient: { x1: 0, y1: 0, x2: 0, y2: 1 }, 232 | stops: [ 233 | [0, '#000'], 234 | [1, '#333'] 235 | ] 236 | }, 237 | trackBorderColor: '#666' 238 | }, 239 | 240 | // special colors for some of the 241 | legendBackgroundColor: 'rgba(0, 0, 0, 0.5)', 242 | background2: 'rgb(35, 35, 70)', 243 | dataLabelsColor: '#444', 244 | textColor: '#C0C0C0', 245 | maskColor: 'rgba(255,255,255,0.3)' 246 | }; -------------------------------------------------------------------------------- /ezhc/script/themes/dark-blue.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors": [ 3 | "#DDDF0D", 4 | "#55BF3B", 5 | "#DF5353", 6 | "#7798BF", 7 | "#aaeeee", 8 | "#ff0066", 9 | "#eeaaee", 10 | "#55BF3B", 11 | "#DF5353", 12 | "#7798BF", 13 | "#aaeeee" 14 | ], 15 | "chart": { 16 | "backgroundColor": { 17 | "linearGradient": { 18 | "x1": 0, 19 | "y1": 0, 20 | "x2": 1, 21 | "y2": 1 22 | }, 23 | "stops": [ 24 | [ 25 | 0, 26 | "rgb(48, 48, 96)" 27 | ], 28 | [ 29 | 1, 30 | "rgb(0, 0, 0)" 31 | ] 32 | ] 33 | }, 34 | "borderColor": "#000000", 35 | "borderWidth": 2, 36 | "className": "dark-container", 37 | "plotBackgroundColor": "rgba(255, 255, 255, .1)", 38 | "plotBorderColor": "#CCCCCC", 39 | "plotBorderWidth": 1 40 | }, 41 | "title": { 42 | "style": { 43 | "color": "#C0C0C0", 44 | "font": "bold 16px \"Trebuchet MS\", Verdana, sans-serif" 45 | } 46 | }, 47 | "subtitle": { 48 | "style": { 49 | "color": "#666666", 50 | "font": "bold 12px \"Trebuchet MS\", Verdana, sans-serif" 51 | } 52 | }, 53 | "xAxis": { 54 | "gridLineColor": "#333333", 55 | "gridLineWidth": 1, 56 | "labels": { 57 | "style": { 58 | "color": "#A0A0A0" 59 | } 60 | }, 61 | "lineColor": "#A0A0A0", 62 | "tickColor": "#A0A0A0", 63 | "title": { 64 | "style": { 65 | "color": "#CCC", 66 | "fontWeight": "bold", 67 | "fontSize": "12px", 68 | "fontFamily": "Trebuchet MS, Verdana, sans-serif" 69 | } 70 | } 71 | }, 72 | "yAxis": { 73 | "gridLineColor": "#333333", 74 | "labels": { 75 | "style": { 76 | "color": "#A0A0A0" 77 | } 78 | }, 79 | "lineColor": "#A0A0A0", 80 | "minorTickInterval": null, 81 | "tickColor": "#A0A0A0", 82 | "tickWidth": 1, 83 | "title": { 84 | "style": { 85 | "color": "#CCC", 86 | "fontWeight": "bold", 87 | "fontSize": "12px", 88 | "fontFamily": "Trebuchet MS, Verdana, sans-serif" 89 | } 90 | } 91 | }, 92 | "tooltip": { 93 | "backgroundColor": "rgba(0, 0, 0, 0.75)", 94 | "style": { 95 | "color": "#F0F0F0" 96 | } 97 | }, 98 | "toolbar": { 99 | "itemStyle": { 100 | "color": "silver" 101 | } 102 | }, 103 | "plotOptions": { 104 | "line": { 105 | "dataLabels": { 106 | "color": "#CCC" 107 | }, 108 | "marker": { 109 | "lineColor": "#333" 110 | } 111 | }, 112 | "spline": { 113 | "marker": { 114 | "lineColor": "#333" 115 | } 116 | }, 117 | "scatter": { 118 | "marker": { 119 | "lineColor": "#333" 120 | } 121 | }, 122 | "candlestick": { 123 | "lineColor": "white" 124 | } 125 | }, 126 | "legend": { 127 | "itemStyle": { 128 | "font": "9pt Trebuchet MS, Verdana, sans-serif", 129 | "color": "#A0A0A0" 130 | }, 131 | "itemHoverStyle": { 132 | "color": "#FFF" 133 | }, 134 | "itemHiddenStyle": { 135 | "color": "#444" 136 | } 137 | }, 138 | "credits": { 139 | "style": { 140 | "color": "#666" 141 | } 142 | }, 143 | "labels": { 144 | "style": { 145 | "color": "#CCC" 146 | } 147 | }, 148 | "navigation": { 149 | "buttonOptions": { 150 | "symbolStroke": "#DDDDDD", 151 | "hoverSymbolStroke": "#FFFFFF", 152 | "theme": { 153 | "fill": { 154 | "linearGradient": { 155 | "x1": 0, 156 | "y1": 0, 157 | "x2": 0, 158 | "y2": 1 159 | }, 160 | "stops": [ 161 | [ 162 | 0.4, 163 | "#606060" 164 | ], 165 | [ 166 | 0.6, 167 | "#333333" 168 | ] 169 | ] 170 | }, 171 | "stroke": "#000000" 172 | } 173 | } 174 | }, 175 | "rangeSelector": { 176 | "buttonTheme": { 177 | "fill": { 178 | "linearGradient": { 179 | "x1": 0, 180 | "y1": 0, 181 | "x2": 0, 182 | "y2": 1 183 | }, 184 | "stops": [ 185 | [ 186 | 0.4, 187 | "#888" 188 | ], 189 | [ 190 | 0.6, 191 | "#555" 192 | ] 193 | ] 194 | }, 195 | "stroke": "#000000", 196 | "style": { 197 | "color": "#CCC", 198 | "fontWeight": "bold" 199 | }, 200 | "states": { 201 | "hover": { 202 | "fill": { 203 | "linearGradient": { 204 | "x1": 0, 205 | "y1": 0, 206 | "x2": 0, 207 | "y2": 1 208 | }, 209 | "stops": [ 210 | [ 211 | 0.4, 212 | "#BBB" 213 | ], 214 | [ 215 | 0.6, 216 | "#888" 217 | ] 218 | ] 219 | }, 220 | "stroke": "#000000", 221 | "style": { 222 | "color": "white" 223 | } 224 | }, 225 | "select": { 226 | "fill": { 227 | "linearGradient": { 228 | "x1": 0, 229 | "y1": 0, 230 | "x2": 0, 231 | "y2": 1 232 | }, 233 | "stops": [ 234 | [ 235 | 0.1, 236 | "#000" 237 | ], 238 | [ 239 | 0.3, 240 | "#333" 241 | ] 242 | ] 243 | }, 244 | "stroke": "#000000", 245 | "style": { 246 | "color": "yellow" 247 | } 248 | } 249 | } 250 | }, 251 | "inputStyle": { 252 | "backgroundColor": "#333", 253 | "color": "silver" 254 | }, 255 | "labelStyle": { 256 | "color": "silver" 257 | } 258 | }, 259 | "navigator": { 260 | "handles": { 261 | "backgroundColor": "#666", 262 | "borderColor": "#AAA" 263 | }, 264 | "outlineColor": "#CCC", 265 | "maskFill": "rgba(16, 16, 16, 0.5)", 266 | "series": { 267 | "color": "#7798BF", 268 | "lineColor": "#A6C7ED" 269 | } 270 | }, 271 | "scrollbar": { 272 | "barBackgroundColor": { 273 | "linearGradient": { 274 | "x1": 0, 275 | "y1": 0, 276 | "x2": 0, 277 | "y2": 1 278 | }, 279 | "stops": [ 280 | [ 281 | 0.4, 282 | "#888" 283 | ], 284 | [ 285 | 0.6, 286 | "#555" 287 | ] 288 | ] 289 | }, 290 | "barBorderColor": "#CCC", 291 | "buttonArrowColor": "#CCC", 292 | "buttonBackgroundColor": { 293 | "linearGradient": { 294 | "x1": 0, 295 | "y1": 0, 296 | "x2": 0, 297 | "y2": 1 298 | }, 299 | "stops": [ 300 | [ 301 | 0.4, 302 | "#888" 303 | ], 304 | [ 305 | 0.6, 306 | "#555" 307 | ] 308 | ] 309 | }, 310 | "buttonBorderColor": "#CCC", 311 | "rifleColor": "#FFF", 312 | "trackBackgroundColor": { 313 | "linearGradient": { 314 | "x1": 0, 315 | "y1": 0, 316 | "x2": 0, 317 | "y2": 1 318 | }, 319 | "stops": [ 320 | [ 321 | 0, 322 | "#000" 323 | ], 324 | [ 325 | 1, 326 | "#333" 327 | ] 328 | ] 329 | }, 330 | "trackBorderColor": "#666" 331 | }, 332 | "legendBackgroundColor": "rgba(0, 0, 0, 0.5)", 333 | "background2": "rgb(35, 35, 70)", 334 | "dataLabelsColor": "#444", 335 | "textColor": "#C0C0C0", 336 | "maskColor": "rgba(255,255,255,0.3)" 337 | } -------------------------------------------------------------------------------- /ezhc/script/themes/dark-green.js: -------------------------------------------------------------------------------- 1 | var theme = { 2 | colors: ['#DDDF0D', '#55BF3B', '#DF5353', '#7798BF', '#aaeeee', 3 | '#ff0066', '#eeaaee', '#55BF3B', '#DF5353', '#7798BF', '#aaeeee'], 4 | chart: { 5 | backgroundColor: { 6 | linearGradient: [0, 0, 250, 500], 7 | stops: [ 8 | [0, 'rgb(48, 96, 48)'], 9 | [1, 'rgb(0, 0, 0)'] 10 | ] 11 | }, 12 | borderColor: '#000000', 13 | borderWidth: 2, 14 | className: 'dark-container', 15 | plotBackgroundColor: 'rgba(255, 255, 255, .1)', 16 | plotBorderColor: '#CCCCCC', 17 | plotBorderWidth: 1 18 | }, 19 | title: { 20 | style: { 21 | color: '#C0C0C0', 22 | font: 'bold 16px "Trebuchet MS", Verdana, sans-serif' 23 | } 24 | }, 25 | subtitle: { 26 | style: { 27 | color: '#666666', 28 | font: 'bold 12px "Trebuchet MS", Verdana, sans-serif' 29 | } 30 | }, 31 | xAxis: { 32 | gridLineColor: '#333333', 33 | gridLineWidth: 1, 34 | labels: { 35 | style: { 36 | color: '#A0A0A0' 37 | } 38 | }, 39 | lineColor: '#A0A0A0', 40 | tickColor: '#A0A0A0', 41 | title: { 42 | style: { 43 | color: '#CCC', 44 | fontWeight: 'bold', 45 | fontSize: '12px', 46 | fontFamily: 'Trebuchet MS, Verdana, sans-serif' 47 | 48 | } 49 | } 50 | }, 51 | yAxis: { 52 | gridLineColor: '#333333', 53 | labels: { 54 | style: { 55 | color: '#A0A0A0' 56 | } 57 | }, 58 | lineColor: '#A0A0A0', 59 | minorTickInterval: null, 60 | tickColor: '#A0A0A0', 61 | tickWidth: 1, 62 | title: { 63 | style: { 64 | color: '#CCC', 65 | fontWeight: 'bold', 66 | fontSize: '12px', 67 | fontFamily: 'Trebuchet MS, Verdana, sans-serif' 68 | } 69 | } 70 | }, 71 | tooltip: { 72 | backgroundColor: 'rgba(0, 0, 0, 0.75)', 73 | style: { 74 | color: '#F0F0F0' 75 | } 76 | }, 77 | toolbar: { 78 | itemStyle: { 79 | color: 'silver' 80 | } 81 | }, 82 | plotOptions: { 83 | line: { 84 | dataLabels: { 85 | color: '#CCC' 86 | }, 87 | marker: { 88 | lineColor: '#333' 89 | } 90 | }, 91 | spline: { 92 | marker: { 93 | lineColor: '#333' 94 | } 95 | }, 96 | scatter: { 97 | marker: { 98 | lineColor: '#333' 99 | } 100 | }, 101 | candlestick: { 102 | lineColor: 'white' 103 | } 104 | }, 105 | legend: { 106 | itemStyle: { 107 | font: '9pt Trebuchet MS, Verdana, sans-serif', 108 | color: '#A0A0A0' 109 | }, 110 | itemHoverStyle: { 111 | color: '#FFF' 112 | }, 113 | itemHiddenStyle: { 114 | color: '#444' 115 | } 116 | }, 117 | credits: { 118 | style: { 119 | color: '#666' 120 | } 121 | }, 122 | labels: { 123 | style: { 124 | color: '#CCC' 125 | } 126 | }, 127 | 128 | 129 | navigation: { 130 | buttonOptions: { 131 | symbolStroke: '#DDDDDD', 132 | hoverSymbolStroke: '#FFFFFF', 133 | theme: { 134 | fill: { 135 | linearGradient: { x1: 0, y1: 0, x2: 0, y2: 1 }, 136 | stops: [ 137 | [0.4, '#606060'], 138 | [0.6, '#333333'] 139 | ] 140 | }, 141 | stroke: '#000000' 142 | } 143 | } 144 | }, 145 | 146 | // scroll charts 147 | rangeSelector: { 148 | buttonTheme: { 149 | fill: { 150 | linearGradient: { x1: 0, y1: 0, x2: 0, y2: 1 }, 151 | stops: [ 152 | [0.4, '#888'], 153 | [0.6, '#555'] 154 | ] 155 | }, 156 | stroke: '#000000', 157 | style: { 158 | color: '#CCC', 159 | fontWeight: 'bold' 160 | }, 161 | states: { 162 | hover: { 163 | fill: { 164 | linearGradient: { x1: 0, y1: 0, x2: 0, y2: 1 }, 165 | stops: [ 166 | [0.4, '#BBB'], 167 | [0.6, '#888'] 168 | ] 169 | }, 170 | stroke: '#000000', 171 | style: { 172 | color: 'white' 173 | } 174 | }, 175 | select: { 176 | fill: { 177 | linearGradient: { x1: 0, y1: 0, x2: 0, y2: 1 }, 178 | stops: [ 179 | [0.1, '#000'], 180 | [0.3, '#333'] 181 | ] 182 | }, 183 | stroke: '#000000', 184 | style: { 185 | color: 'yellow' 186 | } 187 | } 188 | } 189 | }, 190 | inputStyle: { 191 | backgroundColor: '#333', 192 | color: 'silver' 193 | }, 194 | labelStyle: { 195 | color: 'silver' 196 | } 197 | }, 198 | 199 | navigator: { 200 | handles: { 201 | backgroundColor: '#666', 202 | borderColor: '#AAA' 203 | }, 204 | outlineColor: '#CCC', 205 | maskFill: 'rgba(16, 16, 16, 0.5)', 206 | series: { 207 | color: '#7798BF', 208 | lineColor: '#A6C7ED' 209 | } 210 | }, 211 | 212 | scrollbar: { 213 | barBackgroundColor: { 214 | linearGradient: { x1: 0, y1: 0, x2: 0, y2: 1 }, 215 | stops: [ 216 | [0.4, '#888'], 217 | [0.6, '#555'] 218 | ] 219 | }, 220 | barBorderColor: '#CCC', 221 | buttonArrowColor: '#CCC', 222 | buttonBackgroundColor: { 223 | linearGradient: { x1: 0, y1: 0, x2: 0, y2: 1 }, 224 | stops: [ 225 | [0.4, '#888'], 226 | [0.6, '#555'] 227 | ] 228 | }, 229 | buttonBorderColor: '#CCC', 230 | rifleColor: '#FFF', 231 | trackBackgroundColor: { 232 | linearGradient: { x1: 0, y1: 0, x2: 0, y2: 1 }, 233 | stops: [ 234 | [0, '#000'], 235 | [1, '#333'] 236 | ] 237 | }, 238 | trackBorderColor: '#666' 239 | }, 240 | 241 | // special colors for some of the 242 | legendBackgroundColor: 'rgba(0, 0, 0, 0.5)', 243 | background2: 'rgb(35, 35, 70)', 244 | dataLabelsColor: '#444', 245 | textColor: '#C0C0C0', 246 | maskColor: 'rgba(255,255,255,0.3)' 247 | }; -------------------------------------------------------------------------------- /ezhc/script/themes/dark-green.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors": [ 3 | "#DDDF0D", 4 | "#55BF3B", 5 | "#DF5353", 6 | "#7798BF", 7 | "#aaeeee", 8 | "#ff0066", 9 | "#eeaaee", 10 | "#55BF3B", 11 | "#DF5353", 12 | "#7798BF", 13 | "#aaeeee" 14 | ], 15 | "chart": { 16 | "backgroundColor": { 17 | "linearGradient": [ 18 | 0, 19 | 0, 20 | 250, 21 | 500 22 | ], 23 | "stops": [ 24 | [ 25 | 0, 26 | "rgb(48, 96, 48)" 27 | ], 28 | [ 29 | 1, 30 | "rgb(0, 0, 0)" 31 | ] 32 | ] 33 | }, 34 | "borderColor": "#000000", 35 | "borderWidth": 2, 36 | "className": "dark-container", 37 | "plotBackgroundColor": "rgba(255, 255, 255, .1)", 38 | "plotBorderColor": "#CCCCCC", 39 | "plotBorderWidth": 1 40 | }, 41 | "title": { 42 | "style": { 43 | "color": "#C0C0C0", 44 | "font": "bold 16px \"Trebuchet MS\", Verdana, sans-serif" 45 | } 46 | }, 47 | "subtitle": { 48 | "style": { 49 | "color": "#666666", 50 | "font": "bold 12px \"Trebuchet MS\", Verdana, sans-serif" 51 | } 52 | }, 53 | "xAxis": { 54 | "gridLineColor": "#333333", 55 | "gridLineWidth": 1, 56 | "labels": { 57 | "style": { 58 | "color": "#A0A0A0" 59 | } 60 | }, 61 | "lineColor": "#A0A0A0", 62 | "tickColor": "#A0A0A0", 63 | "title": { 64 | "style": { 65 | "color": "#CCC", 66 | "fontWeight": "bold", 67 | "fontSize": "12px", 68 | "fontFamily": "Trebuchet MS, Verdana, sans-serif" 69 | } 70 | } 71 | }, 72 | "yAxis": { 73 | "gridLineColor": "#333333", 74 | "labels": { 75 | "style": { 76 | "color": "#A0A0A0" 77 | } 78 | }, 79 | "lineColor": "#A0A0A0", 80 | "minorTickInterval": null, 81 | "tickColor": "#A0A0A0", 82 | "tickWidth": 1, 83 | "title": { 84 | "style": { 85 | "color": "#CCC", 86 | "fontWeight": "bold", 87 | "fontSize": "12px", 88 | "fontFamily": "Trebuchet MS, Verdana, sans-serif" 89 | } 90 | } 91 | }, 92 | "tooltip": { 93 | "backgroundColor": "rgba(0, 0, 0, 0.75)", 94 | "style": { 95 | "color": "#F0F0F0" 96 | } 97 | }, 98 | "toolbar": { 99 | "itemStyle": { 100 | "color": "silver" 101 | } 102 | }, 103 | "plotOptions": { 104 | "line": { 105 | "dataLabels": { 106 | "color": "#CCC" 107 | }, 108 | "marker": { 109 | "lineColor": "#333" 110 | } 111 | }, 112 | "spline": { 113 | "marker": { 114 | "lineColor": "#333" 115 | } 116 | }, 117 | "scatter": { 118 | "marker": { 119 | "lineColor": "#333" 120 | } 121 | }, 122 | "candlestick": { 123 | "lineColor": "white" 124 | } 125 | }, 126 | "legend": { 127 | "itemStyle": { 128 | "font": "9pt Trebuchet MS, Verdana, sans-serif", 129 | "color": "#A0A0A0" 130 | }, 131 | "itemHoverStyle": { 132 | "color": "#FFF" 133 | }, 134 | "itemHiddenStyle": { 135 | "color": "#444" 136 | } 137 | }, 138 | "credits": { 139 | "style": { 140 | "color": "#666" 141 | } 142 | }, 143 | "labels": { 144 | "style": { 145 | "color": "#CCC" 146 | } 147 | }, 148 | "navigation": { 149 | "buttonOptions": { 150 | "symbolStroke": "#DDDDDD", 151 | "hoverSymbolStroke": "#FFFFFF", 152 | "theme": { 153 | "fill": { 154 | "linearGradient": { 155 | "x1": 0, 156 | "y1": 0, 157 | "x2": 0, 158 | "y2": 1 159 | }, 160 | "stops": [ 161 | [ 162 | 0.4, 163 | "#606060" 164 | ], 165 | [ 166 | 0.6, 167 | "#333333" 168 | ] 169 | ] 170 | }, 171 | "stroke": "#000000" 172 | } 173 | } 174 | }, 175 | "rangeSelector": { 176 | "buttonTheme": { 177 | "fill": { 178 | "linearGradient": { 179 | "x1": 0, 180 | "y1": 0, 181 | "x2": 0, 182 | "y2": 1 183 | }, 184 | "stops": [ 185 | [ 186 | 0.4, 187 | "#888" 188 | ], 189 | [ 190 | 0.6, 191 | "#555" 192 | ] 193 | ] 194 | }, 195 | "stroke": "#000000", 196 | "style": { 197 | "color": "#CCC", 198 | "fontWeight": "bold" 199 | }, 200 | "states": { 201 | "hover": { 202 | "fill": { 203 | "linearGradient": { 204 | "x1": 0, 205 | "y1": 0, 206 | "x2": 0, 207 | "y2": 1 208 | }, 209 | "stops": [ 210 | [ 211 | 0.4, 212 | "#BBB" 213 | ], 214 | [ 215 | 0.6, 216 | "#888" 217 | ] 218 | ] 219 | }, 220 | "stroke": "#000000", 221 | "style": { 222 | "color": "white" 223 | } 224 | }, 225 | "select": { 226 | "fill": { 227 | "linearGradient": { 228 | "x1": 0, 229 | "y1": 0, 230 | "x2": 0, 231 | "y2": 1 232 | }, 233 | "stops": [ 234 | [ 235 | 0.1, 236 | "#000" 237 | ], 238 | [ 239 | 0.3, 240 | "#333" 241 | ] 242 | ] 243 | }, 244 | "stroke": "#000000", 245 | "style": { 246 | "color": "yellow" 247 | } 248 | } 249 | } 250 | }, 251 | "inputStyle": { 252 | "backgroundColor": "#333", 253 | "color": "silver" 254 | }, 255 | "labelStyle": { 256 | "color": "silver" 257 | } 258 | }, 259 | "navigator": { 260 | "handles": { 261 | "backgroundColor": "#666", 262 | "borderColor": "#AAA" 263 | }, 264 | "outlineColor": "#CCC", 265 | "maskFill": "rgba(16, 16, 16, 0.5)", 266 | "series": { 267 | "color": "#7798BF", 268 | "lineColor": "#A6C7ED" 269 | } 270 | }, 271 | "scrollbar": { 272 | "barBackgroundColor": { 273 | "linearGradient": { 274 | "x1": 0, 275 | "y1": 0, 276 | "x2": 0, 277 | "y2": 1 278 | }, 279 | "stops": [ 280 | [ 281 | 0.4, 282 | "#888" 283 | ], 284 | [ 285 | 0.6, 286 | "#555" 287 | ] 288 | ] 289 | }, 290 | "barBorderColor": "#CCC", 291 | "buttonArrowColor": "#CCC", 292 | "buttonBackgroundColor": { 293 | "linearGradient": { 294 | "x1": 0, 295 | "y1": 0, 296 | "x2": 0, 297 | "y2": 1 298 | }, 299 | "stops": [ 300 | [ 301 | 0.4, 302 | "#888" 303 | ], 304 | [ 305 | 0.6, 306 | "#555" 307 | ] 308 | ] 309 | }, 310 | "buttonBorderColor": "#CCC", 311 | "rifleColor": "#FFF", 312 | "trackBackgroundColor": { 313 | "linearGradient": { 314 | "x1": 0, 315 | "y1": 0, 316 | "x2": 0, 317 | "y2": 1 318 | }, 319 | "stops": [ 320 | [ 321 | 0, 322 | "#000" 323 | ], 324 | [ 325 | 1, 326 | "#333" 327 | ] 328 | ] 329 | }, 330 | "trackBorderColor": "#666" 331 | }, 332 | "legendBackgroundColor": "rgba(0, 0, 0, 0.5)", 333 | "background2": "rgb(35, 35, 70)", 334 | "dataLabelsColor": "#444", 335 | "textColor": "#C0C0C0", 336 | "maskColor": "rgba(255,255,255,0.3)" 337 | } -------------------------------------------------------------------------------- /ezhc/script/themes/dark-unica.js: -------------------------------------------------------------------------------- 1 | var theme = { 2 | colors: ['#2b908f', '#90ee7e', '#f45b5b', '#7798BF', '#aaeeee', '#ff0066', 3 | '#eeaaee', '#55BF3B', '#DF5353', '#7798BF', '#aaeeee'], 4 | chart: { 5 | backgroundColor: { 6 | linearGradient: { x1: 0, y1: 0, x2: 1, y2: 1 }, 7 | stops: [ 8 | [0, '#2a2a2b'], 9 | [1, '#3e3e40'] 10 | ] 11 | }, 12 | style: { 13 | fontFamily: '\'Unica One\', sans-serif' 14 | }, 15 | plotBorderColor: '#606063' 16 | }, 17 | title: { 18 | style: { 19 | color: '#E0E0E3', 20 | textTransform: 'uppercase', 21 | fontSize: '20px' 22 | } 23 | }, 24 | subtitle: { 25 | style: { 26 | color: '#E0E0E3', 27 | textTransform: 'uppercase' 28 | } 29 | }, 30 | xAxis: { 31 | gridLineColor: '#707073', 32 | labels: { 33 | style: { 34 | color: '#E0E0E3' 35 | } 36 | }, 37 | lineColor: '#707073', 38 | minorGridLineColor: '#505053', 39 | tickColor: '#707073', 40 | title: { 41 | style: { 42 | color: '#A0A0A3' 43 | 44 | } 45 | } 46 | }, 47 | yAxis: { 48 | gridLineColor: '#707073', 49 | labels: { 50 | style: { 51 | color: '#E0E0E3' 52 | } 53 | }, 54 | lineColor: '#707073', 55 | minorGridLineColor: '#505053', 56 | tickColor: '#707073', 57 | tickWidth: 1, 58 | title: { 59 | style: { 60 | color: '#A0A0A3' 61 | } 62 | } 63 | }, 64 | tooltip: { 65 | backgroundColor: 'rgba(0, 0, 0, 0.85)', 66 | style: { 67 | color: '#F0F0F0' 68 | } 69 | }, 70 | plotOptions: { 71 | series: { 72 | dataLabels: { 73 | color: '#B0B0B3' 74 | }, 75 | marker: { 76 | lineColor: '#333' 77 | } 78 | }, 79 | boxplot: { 80 | fillColor: '#505053' 81 | }, 82 | candlestick: { 83 | lineColor: 'white' 84 | }, 85 | errorbar: { 86 | color: 'white' 87 | } 88 | }, 89 | legend: { 90 | itemStyle: { 91 | color: '#E0E0E3' 92 | }, 93 | itemHoverStyle: { 94 | color: '#FFF' 95 | }, 96 | itemHiddenStyle: { 97 | color: '#606063' 98 | } 99 | }, 100 | credits: { 101 | style: { 102 | color: '#666' 103 | } 104 | }, 105 | labels: { 106 | style: { 107 | color: '#707073' 108 | } 109 | }, 110 | 111 | drilldown: { 112 | activeAxisLabelStyle: { 113 | color: '#F0F0F3' 114 | }, 115 | activeDataLabelStyle: { 116 | color: '#F0F0F3' 117 | } 118 | }, 119 | 120 | navigation: { 121 | buttonOptions: { 122 | symbolStroke: '#DDDDDD', 123 | theme: { 124 | fill: '#505053' 125 | } 126 | } 127 | }, 128 | 129 | // scroll charts 130 | rangeSelector: { 131 | buttonTheme: { 132 | fill: '#505053', 133 | stroke: '#000000', 134 | style: { 135 | color: '#CCC' 136 | }, 137 | states: { 138 | hover: { 139 | fill: '#707073', 140 | stroke: '#000000', 141 | style: { 142 | color: 'white' 143 | } 144 | }, 145 | select: { 146 | fill: '#000003', 147 | stroke: '#000000', 148 | style: { 149 | color: 'white' 150 | } 151 | } 152 | } 153 | }, 154 | inputBoxBorderColor: '#505053', 155 | inputStyle: { 156 | backgroundColor: '#333', 157 | color: 'silver' 158 | }, 159 | labelStyle: { 160 | color: 'silver' 161 | } 162 | }, 163 | 164 | navigator: { 165 | handles: { 166 | backgroundColor: '#666', 167 | borderColor: '#AAA' 168 | }, 169 | outlineColor: '#CCC', 170 | maskFill: 'rgba(255,255,255,0.1)', 171 | series: { 172 | color: '#7798BF', 173 | lineColor: '#A6C7ED' 174 | }, 175 | xAxis: { 176 | gridLineColor: '#505053' 177 | } 178 | }, 179 | 180 | scrollbar: { 181 | barBackgroundColor: '#808083', 182 | barBorderColor: '#808083', 183 | buttonArrowColor: '#CCC', 184 | buttonBackgroundColor: '#606063', 185 | buttonBorderColor: '#606063', 186 | rifleColor: '#FFF', 187 | trackBackgroundColor: '#404043', 188 | trackBorderColor: '#404043' 189 | }, 190 | 191 | // special colors for some of the 192 | legendBackgroundColor: 'rgba(0, 0, 0, 0.5)', 193 | background2: '#505053', 194 | dataLabelsColor: '#B0B0B3', 195 | textColor: '#C0C0C0', 196 | contrastTextColor: '#F0F0F3', 197 | maskColor: 'rgba(255,255,255,0.3)' 198 | }; -------------------------------------------------------------------------------- /ezhc/script/themes/dark-unica.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors": [ 3 | "#2b908f", 4 | "#90ee7e", 5 | "#f45b5b", 6 | "#7798BF", 7 | "#aaeeee", 8 | "#ff0066", 9 | "#eeaaee", 10 | "#55BF3B", 11 | "#DF5353", 12 | "#7798BF", 13 | "#aaeeee" 14 | ], 15 | "chart": { 16 | "backgroundColor": { 17 | "linearGradient": { 18 | "x1": 0, 19 | "y1": 0, 20 | "x2": 1, 21 | "y2": 1 22 | }, 23 | "stops": [ 24 | [ 25 | 0, 26 | "#2a2a2b" 27 | ], 28 | [ 29 | 1, 30 | "#3e3e40" 31 | ] 32 | ] 33 | }, 34 | "style": { 35 | "fontFamily": "'Unica One', sans-serif" 36 | }, 37 | "plotBorderColor": "#606063" 38 | }, 39 | "title": { 40 | "style": { 41 | "color": "#E0E0E3", 42 | "textTransform": "uppercase", 43 | "fontSize": "20px" 44 | } 45 | }, 46 | "subtitle": { 47 | "style": { 48 | "color": "#E0E0E3", 49 | "textTransform": "uppercase" 50 | } 51 | }, 52 | "xAxis": { 53 | "gridLineColor": "#707073", 54 | "labels": { 55 | "style": { 56 | "color": "#E0E0E3" 57 | } 58 | }, 59 | "lineColor": "#707073", 60 | "minorGridLineColor": "#505053", 61 | "tickColor": "#707073", 62 | "title": { 63 | "style": { 64 | "color": "#A0A0A3" 65 | } 66 | } 67 | }, 68 | "yAxis": { 69 | "gridLineColor": "#707073", 70 | "labels": { 71 | "style": { 72 | "color": "#E0E0E3" 73 | } 74 | }, 75 | "lineColor": "#707073", 76 | "minorGridLineColor": "#505053", 77 | "tickColor": "#707073", 78 | "tickWidth": 1, 79 | "title": { 80 | "style": { 81 | "color": "#A0A0A3" 82 | } 83 | } 84 | }, 85 | "tooltip": { 86 | "backgroundColor": "rgba(0, 0, 0, 0.85)", 87 | "style": { 88 | "color": "#F0F0F0" 89 | } 90 | }, 91 | "plotOptions": { 92 | "series": { 93 | "dataLabels": { 94 | "color": "#B0B0B3" 95 | }, 96 | "marker": { 97 | "lineColor": "#333" 98 | } 99 | }, 100 | "boxplot": { 101 | "fillColor": "#505053" 102 | }, 103 | "candlestick": { 104 | "lineColor": "white" 105 | }, 106 | "errorbar": { 107 | "color": "white" 108 | } 109 | }, 110 | "legend": { 111 | "itemStyle": { 112 | "color": "#E0E0E3" 113 | }, 114 | "itemHoverStyle": { 115 | "color": "#FFF" 116 | }, 117 | "itemHiddenStyle": { 118 | "color": "#606063" 119 | } 120 | }, 121 | "credits": { 122 | "style": { 123 | "color": "#666" 124 | } 125 | }, 126 | "labels": { 127 | "style": { 128 | "color": "#707073" 129 | } 130 | }, 131 | "drilldown": { 132 | "activeAxisLabelStyle": { 133 | "color": "#F0F0F3" 134 | }, 135 | "activeDataLabelStyle": { 136 | "color": "#F0F0F3" 137 | } 138 | }, 139 | "navigation": { 140 | "buttonOptions": { 141 | "symbolStroke": "#DDDDDD", 142 | "theme": { 143 | "fill": "#505053" 144 | } 145 | } 146 | }, 147 | "rangeSelector": { 148 | "buttonTheme": { 149 | "fill": "#505053", 150 | "stroke": "#000000", 151 | "style": { 152 | "color": "#CCC" 153 | }, 154 | "states": { 155 | "hover": { 156 | "fill": "#707073", 157 | "stroke": "#000000", 158 | "style": { 159 | "color": "white" 160 | } 161 | }, 162 | "select": { 163 | "fill": "#000003", 164 | "stroke": "#000000", 165 | "style": { 166 | "color": "white" 167 | } 168 | } 169 | } 170 | }, 171 | "inputBoxBorderColor": "#505053", 172 | "inputStyle": { 173 | "backgroundColor": "#333", 174 | "color": "silver" 175 | }, 176 | "labelStyle": { 177 | "color": "silver" 178 | } 179 | }, 180 | "navigator": { 181 | "handles": { 182 | "backgroundColor": "#666", 183 | "borderColor": "#AAA" 184 | }, 185 | "outlineColor": "#CCC", 186 | "maskFill": "rgba(255,255,255,0.1)", 187 | "series": { 188 | "color": "#7798BF", 189 | "lineColor": "#A6C7ED" 190 | }, 191 | "xAxis": { 192 | "gridLineColor": "#505053" 193 | } 194 | }, 195 | "scrollbar": { 196 | "barBackgroundColor": "#808083", 197 | "barBorderColor": "#808083", 198 | "buttonArrowColor": "#CCC", 199 | "buttonBackgroundColor": "#606063", 200 | "buttonBorderColor": "#606063", 201 | "rifleColor": "#FFF", 202 | "trackBackgroundColor": "#404043", 203 | "trackBorderColor": "#404043" 204 | }, 205 | "legendBackgroundColor": "rgba(0, 0, 0, 0.5)", 206 | "background2": "#505053", 207 | "dataLabelsColor": "#B0B0B3", 208 | "textColor": "#C0C0C0", 209 | "contrastTextColor": "#F0F0F3", 210 | "maskColor": "rgba(255,255,255,0.3)" 211 | } -------------------------------------------------------------------------------- /ezhc/script/themes/gray.js: -------------------------------------------------------------------------------- 1 | var theme = { 2 | colors: ['#DDDF0D', '#7798BF', '#55BF3B', '#DF5353', '#aaeeee', 3 | '#ff0066', '#eeaaee', '#55BF3B', '#DF5353', '#7798BF', '#aaeeee'], 4 | chart: { 5 | backgroundColor: { 6 | linearGradient: { x1: 0, y1: 0, x2: 0, y2: 1 }, 7 | stops: [ 8 | [0, 'rgb(96, 96, 96)'], 9 | [1, 'rgb(16, 16, 16)'] 10 | ] 11 | }, 12 | borderWidth: 0, 13 | borderRadius: 0, 14 | plotBackgroundColor: null, 15 | plotShadow: false, 16 | plotBorderWidth: 0 17 | }, 18 | title: { 19 | style: { 20 | color: '#FFF', 21 | font: '16px Lucida Grande, Lucida Sans Unicode,' + 22 | ' Verdana, Arial, Helvetica, sans-serif' 23 | } 24 | }, 25 | subtitle: { 26 | style: { 27 | color: '#DDD', 28 | font: '12px Lucida Grande, Lucida Sans Unicode,' + 29 | ' Verdana, Arial, Helvetica, sans-serif' 30 | } 31 | }, 32 | xAxis: { 33 | gridLineWidth: 0, 34 | lineColor: '#999', 35 | tickColor: '#999', 36 | labels: { 37 | style: { 38 | color: '#999', 39 | fontWeight: 'bold' 40 | } 41 | }, 42 | title: { 43 | style: { 44 | color: '#AAA', 45 | font: 'bold 12px Lucida Grande, Lucida Sans Unicode,' + 46 | ' Verdana, Arial, Helvetica, sans-serif' 47 | } 48 | } 49 | }, 50 | yAxis: { 51 | alternateGridColor: null, 52 | minorTickInterval: null, 53 | gridLineColor: 'rgba(255, 255, 255, .1)', 54 | minorGridLineColor: 'rgba(255,255,255,0.07)', 55 | lineWidth: 0, 56 | tickWidth: 0, 57 | labels: { 58 | style: { 59 | color: '#999', 60 | fontWeight: 'bold' 61 | } 62 | }, 63 | title: { 64 | style: { 65 | color: '#AAA', 66 | font: 'bold 12px Lucida Grande, Lucida Sans Unicode,' + 67 | ' Verdana, Arial, Helvetica, sans-serif' 68 | } 69 | } 70 | }, 71 | legend: { 72 | itemStyle: { 73 | color: '#CCC' 74 | }, 75 | itemHoverStyle: { 76 | color: '#FFF' 77 | }, 78 | itemHiddenStyle: { 79 | color: '#333' 80 | } 81 | }, 82 | labels: { 83 | style: { 84 | color: '#CCC' 85 | } 86 | }, 87 | tooltip: { 88 | backgroundColor: { 89 | linearGradient: { x1: 0, y1: 0, x2: 0, y2: 1 }, 90 | stops: [ 91 | [0, 'rgba(96, 96, 96, .8)'], 92 | [1, 'rgba(16, 16, 16, .8)'] 93 | ] 94 | }, 95 | borderWidth: 0, 96 | style: { 97 | color: '#FFF' 98 | } 99 | }, 100 | 101 | 102 | plotOptions: { 103 | series: { 104 | nullColor: '#444444' 105 | }, 106 | line: { 107 | dataLabels: { 108 | color: '#CCC' 109 | }, 110 | marker: { 111 | lineColor: '#333' 112 | } 113 | }, 114 | spline: { 115 | marker: { 116 | lineColor: '#333' 117 | } 118 | }, 119 | scatter: { 120 | marker: { 121 | lineColor: '#333' 122 | } 123 | }, 124 | candlestick: { 125 | lineColor: 'white' 126 | } 127 | }, 128 | 129 | toolbar: { 130 | itemStyle: { 131 | color: '#CCC' 132 | } 133 | }, 134 | 135 | navigation: { 136 | buttonOptions: { 137 | symbolStroke: '#DDDDDD', 138 | hoverSymbolStroke: '#FFFFFF', 139 | theme: { 140 | fill: { 141 | linearGradient: { x1: 0, y1: 0, x2: 0, y2: 1 }, 142 | stops: [ 143 | [0.4, '#606060'], 144 | [0.6, '#333333'] 145 | ] 146 | }, 147 | stroke: '#000000' 148 | } 149 | } 150 | }, 151 | 152 | // scroll charts 153 | rangeSelector: { 154 | buttonTheme: { 155 | fill: { 156 | linearGradient: { x1: 0, y1: 0, x2: 0, y2: 1 }, 157 | stops: [ 158 | [0.4, '#888'], 159 | [0.6, '#555'] 160 | ] 161 | }, 162 | stroke: '#000000', 163 | style: { 164 | color: '#CCC', 165 | fontWeight: 'bold' 166 | }, 167 | states: { 168 | hover: { 169 | fill: { 170 | linearGradient: { x1: 0, y1: 0, x2: 0, y2: 1 }, 171 | stops: [ 172 | [0.4, '#BBB'], 173 | [0.6, '#888'] 174 | ] 175 | }, 176 | stroke: '#000000', 177 | style: { 178 | color: 'white' 179 | } 180 | }, 181 | select: { 182 | fill: { 183 | linearGradient: { x1: 0, y1: 0, x2: 0, y2: 1 }, 184 | stops: [ 185 | [0.1, '#000'], 186 | [0.3, '#333'] 187 | ] 188 | }, 189 | stroke: '#000000', 190 | style: { 191 | color: 'yellow' 192 | } 193 | } 194 | } 195 | }, 196 | inputStyle: { 197 | backgroundColor: '#333', 198 | color: 'silver' 199 | }, 200 | labelStyle: { 201 | color: 'silver' 202 | } 203 | }, 204 | 205 | navigator: { 206 | handles: { 207 | backgroundColor: '#666', 208 | borderColor: '#AAA' 209 | }, 210 | outlineColor: '#CCC', 211 | maskFill: 'rgba(16, 16, 16, 0.5)', 212 | series: { 213 | color: '#7798BF', 214 | lineColor: '#A6C7ED' 215 | } 216 | }, 217 | 218 | scrollbar: { 219 | barBackgroundColor: { 220 | linearGradient: { x1: 0, y1: 0, x2: 0, y2: 1 }, 221 | stops: [ 222 | [0.4, '#888'], 223 | [0.6, '#555'] 224 | ] 225 | }, 226 | barBorderColor: '#CCC', 227 | buttonArrowColor: '#CCC', 228 | buttonBackgroundColor: { 229 | linearGradient: { x1: 0, y1: 0, x2: 0, y2: 1 }, 230 | stops: [ 231 | [0.4, '#888'], 232 | [0.6, '#555'] 233 | ] 234 | }, 235 | buttonBorderColor: '#CCC', 236 | rifleColor: '#FFF', 237 | trackBackgroundColor: { 238 | linearGradient: { x1: 0, y1: 0, x2: 0, y2: 1 }, 239 | stops: [ 240 | [0, '#000'], 241 | [1, '#333'] 242 | ] 243 | }, 244 | trackBorderColor: '#666' 245 | }, 246 | 247 | // special colors for some of the demo examples 248 | legendBackgroundColor: 'rgba(48, 48, 48, 0.8)', 249 | background2: 'rgb(70, 70, 70)', 250 | dataLabelsColor: '#444', 251 | textColor: '#E0E0E0', 252 | maskColor: 'rgba(255,255,255,0.3)' 253 | }; -------------------------------------------------------------------------------- /ezhc/script/themes/gray.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors": [ 3 | "#DDDF0D", 4 | "#7798BF", 5 | "#55BF3B", 6 | "#DF5353", 7 | "#aaeeee", 8 | "#ff0066", 9 | "#eeaaee", 10 | "#55BF3B", 11 | "#DF5353", 12 | "#7798BF", 13 | "#aaeeee" 14 | ], 15 | "chart": { 16 | "backgroundColor": { 17 | "linearGradient": { 18 | "x1": 0, 19 | "y1": 0, 20 | "x2": 0, 21 | "y2": 1 22 | }, 23 | "stops": [ 24 | [ 25 | 0, 26 | "rgb(96, 96, 96)" 27 | ], 28 | [ 29 | 1, 30 | "rgb(16, 16, 16)" 31 | ] 32 | ] 33 | }, 34 | "borderWidth": 0, 35 | "borderRadius": 0, 36 | "plotBackgroundColor": null, 37 | "plotShadow": false, 38 | "plotBorderWidth": 0 39 | }, 40 | "title": { 41 | "style": { 42 | "color": "#FFF", 43 | "font": "16px Lucida Grande, Lucida Sans Unicode, Verdana, Arial, Helvetica, sans-serif" 44 | } 45 | }, 46 | "subtitle": { 47 | "style": { 48 | "color": "#DDD", 49 | "font": "12px Lucida Grande, Lucida Sans Unicode, Verdana, Arial, Helvetica, sans-serif" 50 | } 51 | }, 52 | "xAxis": { 53 | "gridLineWidth": 0, 54 | "lineColor": "#999", 55 | "tickColor": "#999", 56 | "labels": { 57 | "style": { 58 | "color": "#999", 59 | "fontWeight": "bold" 60 | } 61 | }, 62 | "title": { 63 | "style": { 64 | "color": "#AAA", 65 | "font": "bold 12px Lucida Grande, Lucida Sans Unicode, Verdana, Arial, Helvetica, sans-serif" 66 | } 67 | } 68 | }, 69 | "yAxis": { 70 | "alternateGridColor": null, 71 | "minorTickInterval": null, 72 | "gridLineColor": "rgba(255, 255, 255, .1)", 73 | "minorGridLineColor": "rgba(255,255,255,0.07)", 74 | "lineWidth": 0, 75 | "tickWidth": 0, 76 | "labels": { 77 | "style": { 78 | "color": "#999", 79 | "fontWeight": "bold" 80 | } 81 | }, 82 | "title": { 83 | "style": { 84 | "color": "#AAA", 85 | "font": "bold 12px Lucida Grande, Lucida Sans Unicode, Verdana, Arial, Helvetica, sans-serif" 86 | } 87 | } 88 | }, 89 | "legend": { 90 | "itemStyle": { 91 | "color": "#CCC" 92 | }, 93 | "itemHoverStyle": { 94 | "color": "#FFF" 95 | }, 96 | "itemHiddenStyle": { 97 | "color": "#333" 98 | } 99 | }, 100 | "labels": { 101 | "style": { 102 | "color": "#CCC" 103 | } 104 | }, 105 | "tooltip": { 106 | "backgroundColor": { 107 | "linearGradient": { 108 | "x1": 0, 109 | "y1": 0, 110 | "x2": 0, 111 | "y2": 1 112 | }, 113 | "stops": [ 114 | [ 115 | 0, 116 | "rgba(96, 96, 96, .8)" 117 | ], 118 | [ 119 | 1, 120 | "rgba(16, 16, 16, .8)" 121 | ] 122 | ] 123 | }, 124 | "borderWidth": 0, 125 | "style": { 126 | "color": "#FFF" 127 | } 128 | }, 129 | "plotOptions": { 130 | "series": { 131 | "nullColor": "#444444" 132 | }, 133 | "line": { 134 | "dataLabels": { 135 | "color": "#CCC" 136 | }, 137 | "marker": { 138 | "lineColor": "#333" 139 | } 140 | }, 141 | "spline": { 142 | "marker": { 143 | "lineColor": "#333" 144 | } 145 | }, 146 | "scatter": { 147 | "marker": { 148 | "lineColor": "#333" 149 | } 150 | }, 151 | "candlestick": { 152 | "lineColor": "white" 153 | } 154 | }, 155 | "toolbar": { 156 | "itemStyle": { 157 | "color": "#CCC" 158 | } 159 | }, 160 | "navigation": { 161 | "buttonOptions": { 162 | "symbolStroke": "#DDDDDD", 163 | "hoverSymbolStroke": "#FFFFFF", 164 | "theme": { 165 | "fill": { 166 | "linearGradient": { 167 | "x1": 0, 168 | "y1": 0, 169 | "x2": 0, 170 | "y2": 1 171 | }, 172 | "stops": [ 173 | [ 174 | 0.4, 175 | "#606060" 176 | ], 177 | [ 178 | 0.6, 179 | "#333333" 180 | ] 181 | ] 182 | }, 183 | "stroke": "#000000" 184 | } 185 | } 186 | }, 187 | "rangeSelector": { 188 | "buttonTheme": { 189 | "fill": { 190 | "linearGradient": { 191 | "x1": 0, 192 | "y1": 0, 193 | "x2": 0, 194 | "y2": 1 195 | }, 196 | "stops": [ 197 | [ 198 | 0.4, 199 | "#888" 200 | ], 201 | [ 202 | 0.6, 203 | "#555" 204 | ] 205 | ] 206 | }, 207 | "stroke": "#000000", 208 | "style": { 209 | "color": "#CCC", 210 | "fontWeight": "bold" 211 | }, 212 | "states": { 213 | "hover": { 214 | "fill": { 215 | "linearGradient": { 216 | "x1": 0, 217 | "y1": 0, 218 | "x2": 0, 219 | "y2": 1 220 | }, 221 | "stops": [ 222 | [ 223 | 0.4, 224 | "#BBB" 225 | ], 226 | [ 227 | 0.6, 228 | "#888" 229 | ] 230 | ] 231 | }, 232 | "stroke": "#000000", 233 | "style": { 234 | "color": "white" 235 | } 236 | }, 237 | "select": { 238 | "fill": { 239 | "linearGradient": { 240 | "x1": 0, 241 | "y1": 0, 242 | "x2": 0, 243 | "y2": 1 244 | }, 245 | "stops": [ 246 | [ 247 | 0.1, 248 | "#000" 249 | ], 250 | [ 251 | 0.3, 252 | "#333" 253 | ] 254 | ] 255 | }, 256 | "stroke": "#000000", 257 | "style": { 258 | "color": "yellow" 259 | } 260 | } 261 | } 262 | }, 263 | "inputStyle": { 264 | "backgroundColor": "#333", 265 | "color": "silver" 266 | }, 267 | "labelStyle": { 268 | "color": "silver" 269 | } 270 | }, 271 | "navigator": { 272 | "handles": { 273 | "backgroundColor": "#666", 274 | "borderColor": "#AAA" 275 | }, 276 | "outlineColor": "#CCC", 277 | "maskFill": "rgba(16, 16, 16, 0.5)", 278 | "series": { 279 | "color": "#7798BF", 280 | "lineColor": "#A6C7ED" 281 | } 282 | }, 283 | "scrollbar": { 284 | "barBackgroundColor": { 285 | "linearGradient": { 286 | "x1": 0, 287 | "y1": 0, 288 | "x2": 0, 289 | "y2": 1 290 | }, 291 | "stops": [ 292 | [ 293 | 0.4, 294 | "#888" 295 | ], 296 | [ 297 | 0.6, 298 | "#555" 299 | ] 300 | ] 301 | }, 302 | "barBorderColor": "#CCC", 303 | "buttonArrowColor": "#CCC", 304 | "buttonBackgroundColor": { 305 | "linearGradient": { 306 | "x1": 0, 307 | "y1": 0, 308 | "x2": 0, 309 | "y2": 1 310 | }, 311 | "stops": [ 312 | [ 313 | 0.4, 314 | "#888" 315 | ], 316 | [ 317 | 0.6, 318 | "#555" 319 | ] 320 | ] 321 | }, 322 | "buttonBorderColor": "#CCC", 323 | "rifleColor": "#FFF", 324 | "trackBackgroundColor": { 325 | "linearGradient": { 326 | "x1": 0, 327 | "y1": 0, 328 | "x2": 0, 329 | "y2": 1 330 | }, 331 | "stops": [ 332 | [ 333 | 0, 334 | "#000" 335 | ], 336 | [ 337 | 1, 338 | "#333" 339 | ] 340 | ] 341 | }, 342 | "trackBorderColor": "#666" 343 | }, 344 | "legendBackgroundColor": "rgba(48, 48, 48, 0.8)", 345 | "background2": "rgb(70, 70, 70)", 346 | "dataLabelsColor": "#444", 347 | "textColor": "#E0E0E0", 348 | "maskColor": "rgba(255,255,255,0.3)" 349 | } -------------------------------------------------------------------------------- /ezhc/script/themes/grid-light.js: -------------------------------------------------------------------------------- 1 | var theme = { 2 | colors: ['#7cb5ec', '#f7a35c', '#90ee7e', '#7798BF', '#aaeeee', '#ff0066', 3 | '#eeaaee', '#55BF3B', '#DF5353', '#7798BF', '#aaeeee'], 4 | chart: { 5 | backgroundColor: null, 6 | style: { 7 | fontFamily: 'Dosis, sans-serif' 8 | } 9 | }, 10 | title: { 11 | style: { 12 | fontSize: '16px', 13 | fontWeight: 'bold', 14 | textTransform: 'uppercase' 15 | } 16 | }, 17 | tooltip: { 18 | borderWidth: 0, 19 | backgroundColor: 'rgba(219,219,216,0.8)', 20 | shadow: false 21 | }, 22 | legend: { 23 | itemStyle: { 24 | fontWeight: 'bold', 25 | fontSize: '13px' 26 | } 27 | }, 28 | xAxis: { 29 | gridLineWidth: 1, 30 | labels: { 31 | style: { 32 | fontSize: '12px' 33 | } 34 | } 35 | }, 36 | yAxis: { 37 | minorTickInterval: 'auto', 38 | title: { 39 | style: { 40 | textTransform: 'uppercase' 41 | } 42 | }, 43 | labels: { 44 | style: { 45 | fontSize: '12px' 46 | } 47 | } 48 | }, 49 | plotOptions: { 50 | candlestick: { 51 | lineColor: '#404048' 52 | } 53 | }, 54 | 55 | 56 | // General 57 | background2: '#F0F0EA' 58 | 59 | }; -------------------------------------------------------------------------------- /ezhc/script/themes/grid-light.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors": [ 3 | "#7cb5ec", 4 | "#f7a35c", 5 | "#90ee7e", 6 | "#7798BF", 7 | "#aaeeee", 8 | "#ff0066", 9 | "#eeaaee", 10 | "#55BF3B", 11 | "#DF5353", 12 | "#7798BF", 13 | "#aaeeee" 14 | ], 15 | "chart": { 16 | "backgroundColor": null, 17 | "style": { 18 | "fontFamily": "Dosis, sans-serif" 19 | } 20 | }, 21 | "title": { 22 | "style": { 23 | "fontSize": "16px", 24 | "fontWeight": "bold", 25 | "textTransform": "uppercase" 26 | } 27 | }, 28 | "tooltip": { 29 | "borderWidth": 0, 30 | "backgroundColor": "rgba(219,219,216,0.8)", 31 | "shadow": false 32 | }, 33 | "legend": { 34 | "itemStyle": { 35 | "fontWeight": "bold", 36 | "fontSize": "13px" 37 | } 38 | }, 39 | "xAxis": { 40 | "gridLineWidth": 1, 41 | "labels": { 42 | "style": { 43 | "fontSize": "12px" 44 | } 45 | } 46 | }, 47 | "yAxis": { 48 | "minorTickInterval": "auto", 49 | "title": { 50 | "style": { 51 | "textTransform": "uppercase" 52 | } 53 | }, 54 | "labels": { 55 | "style": { 56 | "fontSize": "12px" 57 | } 58 | } 59 | }, 60 | "plotOptions": { 61 | "candlestick": { 62 | "lineColor": "#404048" 63 | } 64 | }, 65 | "background2": "#F0F0EA" 66 | } -------------------------------------------------------------------------------- /ezhc/script/themes/grid.js: -------------------------------------------------------------------------------- 1 | var theme = { 2 | colors: ['#058DC7', '#50B432', '#ED561B', '#DDDF00', '#24CBE5', '#64E572', 3 | '#FF9655', '#FFF263', '#6AF9C4'], 4 | chart: { 5 | backgroundColor: { 6 | linearGradient: { x1: 0, y1: 0, x2: 1, y2: 1 }, 7 | stops: [ 8 | [0, 'rgb(255, 255, 255)'], 9 | [1, 'rgb(240, 240, 255)'] 10 | ] 11 | }, 12 | borderWidth: 2, 13 | plotBackgroundColor: 'rgba(255, 255, 255, .9)', 14 | plotShadow: true, 15 | plotBorderWidth: 1 16 | }, 17 | title: { 18 | style: { 19 | color: '#000', 20 | font: 'bold 16px "Trebuchet MS", Verdana, sans-serif' 21 | } 22 | }, 23 | subtitle: { 24 | style: { 25 | color: '#666666', 26 | font: 'bold 12px "Trebuchet MS", Verdana, sans-serif' 27 | } 28 | }, 29 | xAxis: { 30 | gridLineWidth: 1, 31 | lineColor: '#000', 32 | tickColor: '#000', 33 | labels: { 34 | style: { 35 | color: '#000', 36 | font: '11px Trebuchet MS, Verdana, sans-serif' 37 | } 38 | }, 39 | title: { 40 | style: { 41 | color: '#333', 42 | fontWeight: 'bold', 43 | fontSize: '12px', 44 | fontFamily: 'Trebuchet MS, Verdana, sans-serif' 45 | 46 | } 47 | } 48 | }, 49 | yAxis: { 50 | minorTickInterval: 'auto', 51 | lineColor: '#000', 52 | lineWidth: 1, 53 | tickWidth: 1, 54 | tickColor: '#000', 55 | labels: { 56 | style: { 57 | color: '#000', 58 | font: '11px Trebuchet MS, Verdana, sans-serif' 59 | } 60 | }, 61 | title: { 62 | style: { 63 | color: '#333', 64 | fontWeight: 'bold', 65 | fontSize: '12px', 66 | fontFamily: 'Trebuchet MS, Verdana, sans-serif' 67 | } 68 | } 69 | }, 70 | legend: { 71 | itemStyle: { 72 | font: '9pt Trebuchet MS, Verdana, sans-serif', 73 | color: 'black' 74 | 75 | }, 76 | itemHoverStyle: { 77 | color: '#039' 78 | }, 79 | itemHiddenStyle: { 80 | color: 'gray' 81 | } 82 | }, 83 | labels: { 84 | style: { 85 | color: '#99b' 86 | } 87 | }, 88 | 89 | navigation: { 90 | buttonOptions: { 91 | theme: { 92 | stroke: '#CCCCCC' 93 | } 94 | } 95 | } 96 | }; -------------------------------------------------------------------------------- /ezhc/script/themes/grid.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors": [ 3 | "#058DC7", 4 | "#50B432", 5 | "#ED561B", 6 | "#DDDF00", 7 | "#24CBE5", 8 | "#64E572", 9 | "#FF9655", 10 | "#FFF263", 11 | "#6AF9C4" 12 | ], 13 | "chart": { 14 | "backgroundColor": { 15 | "linearGradient": { 16 | "x1": 0, 17 | "y1": 0, 18 | "x2": 1, 19 | "y2": 1 20 | }, 21 | "stops": [ 22 | [ 23 | 0, 24 | "rgb(255, 255, 255)" 25 | ], 26 | [ 27 | 1, 28 | "rgb(240, 240, 255)" 29 | ] 30 | ] 31 | }, 32 | "borderWidth": 2, 33 | "plotBackgroundColor": "rgba(255, 255, 255, .9)", 34 | "plotShadow": true, 35 | "plotBorderWidth": 1 36 | }, 37 | "title": { 38 | "style": { 39 | "color": "#000", 40 | "font": "bold 16px \"Trebuchet MS\", Verdana, sans-serif" 41 | } 42 | }, 43 | "subtitle": { 44 | "style": { 45 | "color": "#666666", 46 | "font": "bold 12px \"Trebuchet MS\", Verdana, sans-serif" 47 | } 48 | }, 49 | "xAxis": { 50 | "gridLineWidth": 1, 51 | "lineColor": "#000", 52 | "tickColor": "#000", 53 | "labels": { 54 | "style": { 55 | "color": "#000", 56 | "font": "11px Trebuchet MS, Verdana, sans-serif" 57 | } 58 | }, 59 | "title": { 60 | "style": { 61 | "color": "#333", 62 | "fontWeight": "bold", 63 | "fontSize": "12px", 64 | "fontFamily": "Trebuchet MS, Verdana, sans-serif" 65 | } 66 | } 67 | }, 68 | "yAxis": { 69 | "minorTickInterval": "auto", 70 | "lineColor": "#000", 71 | "lineWidth": 1, 72 | "tickWidth": 1, 73 | "tickColor": "#000", 74 | "labels": { 75 | "style": { 76 | "color": "#000", 77 | "font": "11px Trebuchet MS, Verdana, sans-serif" 78 | } 79 | }, 80 | "title": { 81 | "style": { 82 | "color": "#333", 83 | "fontWeight": "bold", 84 | "fontSize": "12px", 85 | "fontFamily": "Trebuchet MS, Verdana, sans-serif" 86 | } 87 | } 88 | }, 89 | "legend": { 90 | "itemStyle": { 91 | "font": "9pt Trebuchet MS, Verdana, sans-serif", 92 | "color": "black" 93 | }, 94 | "itemHoverStyle": { 95 | "color": "#039" 96 | }, 97 | "itemHiddenStyle": { 98 | "color": "gray" 99 | } 100 | }, 101 | "labels": { 102 | "style": { 103 | "color": "#99b" 104 | } 105 | }, 106 | "navigation": { 107 | "buttonOptions": { 108 | "theme": { 109 | "stroke": "#CCCCCC" 110 | } 111 | } 112 | } 113 | } -------------------------------------------------------------------------------- /ezhc/script/themes/sand-signika.js: -------------------------------------------------------------------------------- 1 | var theme = { 2 | colors: ['#f45b5b', '#8085e9', '#8d4654', '#7798BF', '#aaeeee', 3 | '#ff0066', '#eeaaee', '#55BF3B', '#DF5353', '#7798BF', '#aaeeee'], 4 | chart: { 5 | backgroundColor: null, 6 | style: { 7 | fontFamily: 'Signika, serif' 8 | } 9 | }, 10 | title: { 11 | style: { 12 | color: 'black', 13 | fontSize: '16px', 14 | fontWeight: 'bold' 15 | } 16 | }, 17 | subtitle: { 18 | style: { 19 | color: 'black' 20 | } 21 | }, 22 | tooltip: { 23 | borderWidth: 0 24 | }, 25 | legend: { 26 | itemStyle: { 27 | fontWeight: 'bold', 28 | fontSize: '13px' 29 | } 30 | }, 31 | xAxis: { 32 | labels: { 33 | style: { 34 | color: '#6e6e70' 35 | } 36 | } 37 | }, 38 | yAxis: { 39 | labels: { 40 | style: { 41 | color: '#6e6e70' 42 | } 43 | } 44 | }, 45 | plotOptions: { 46 | series: { 47 | shadow: true 48 | }, 49 | candlestick: { 50 | lineColor: '#404048' 51 | }, 52 | map: { 53 | shadow: false 54 | } 55 | }, 56 | 57 | // Highstock specific 58 | navigator: { 59 | xAxis: { 60 | gridLineColor: '#D0D0D8' 61 | } 62 | }, 63 | rangeSelector: { 64 | buttonTheme: { 65 | fill: 'white', 66 | stroke: '#C0C0C8', 67 | 'stroke-width': 1, 68 | states: { 69 | select: { 70 | fill: '#D0D0D8' 71 | } 72 | } 73 | } 74 | }, 75 | scrollbar: { 76 | trackBorderColor: '#C0C0C8' 77 | }, 78 | 79 | // General 80 | background2: '#E0E0E8' 81 | 82 | }; -------------------------------------------------------------------------------- /ezhc/script/themes/sand-signika.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors": [ 3 | "#f45b5b", 4 | "#8085e9", 5 | "#8d4654", 6 | "#7798BF", 7 | "#aaeeee", 8 | "#ff0066", 9 | "#eeaaee", 10 | "#55BF3B", 11 | "#DF5353", 12 | "#7798BF", 13 | "#aaeeee" 14 | ], 15 | "chart": { 16 | "backgroundColor": null, 17 | "style": { 18 | "fontFamily": "Signika, serif" 19 | } 20 | }, 21 | "title": { 22 | "style": { 23 | "color": "black", 24 | "fontSize": "16px", 25 | "fontWeight": "bold" 26 | } 27 | }, 28 | "subtitle": { 29 | "style": { 30 | "color": "black" 31 | } 32 | }, 33 | "tooltip": { 34 | "borderWidth": 0 35 | }, 36 | "legend": { 37 | "itemStyle": { 38 | "fontWeight": "bold", 39 | "fontSize": "13px" 40 | } 41 | }, 42 | "xAxis": { 43 | "labels": { 44 | "style": { 45 | "color": "#6e6e70" 46 | } 47 | } 48 | }, 49 | "yAxis": { 50 | "labels": { 51 | "style": { 52 | "color": "#6e6e70" 53 | } 54 | } 55 | }, 56 | "plotOptions": { 57 | "series": { 58 | "shadow": true 59 | }, 60 | "candlestick": { 61 | "lineColor": "#404048" 62 | }, 63 | "map": { 64 | "shadow": false 65 | } 66 | }, 67 | "navigator": { 68 | "xAxis": { 69 | "gridLineColor": "#D0D0D8" 70 | } 71 | }, 72 | "rangeSelector": { 73 | "buttonTheme": { 74 | "fill": "white", 75 | "stroke": "#C0C0C8", 76 | "stroke-width": 1, 77 | "states": { 78 | "select": { 79 | "fill": "#D0D0D8" 80 | } 81 | } 82 | } 83 | }, 84 | "scrollbar": { 85 | "trackBorderColor": "#C0C0C8" 86 | }, 87 | "background2": "#E0E0E8" 88 | } -------------------------------------------------------------------------------- /ezhc/script/themes/skies.js: -------------------------------------------------------------------------------- 1 | var theme = { 2 | colors: ['#514F78', '#42A07B', '#9B5E4A', '#72727F', '#1F949A', 3 | '#82914E', '#86777F', '#42A07B'], 4 | chart: { 5 | className: 'skies', 6 | borderWidth: 0, 7 | plotShadow: true, 8 | plotBackgroundImage: 'http://www.highcharts.com/demo/gfx/skies.jpg', 9 | plotBackgroundColor: { 10 | linearGradient: [0, 0, 250, 500], 11 | stops: [ 12 | [0, 'rgba(255, 255, 255, 1)'], 13 | [1, 'rgba(255, 255, 255, 0)'] 14 | ] 15 | }, 16 | plotBorderWidth: 1 17 | }, 18 | title: { 19 | style: { 20 | color: '#3E576F', 21 | font: '16px Lucida Grande, Lucida Sans Unicode,' + 22 | ' Verdana, Arial, Helvetica, sans-serif' 23 | } 24 | }, 25 | subtitle: { 26 | style: { 27 | color: '#6D869F', 28 | font: '12px Lucida Grande, Lucida Sans Unicode,' + 29 | ' Verdana, Arial, Helvetica, sans-serif' 30 | } 31 | }, 32 | xAxis: { 33 | gridLineWidth: 0, 34 | lineColor: '#C0D0E0', 35 | tickColor: '#C0D0E0', 36 | labels: { 37 | style: { 38 | color: '#666', 39 | fontWeight: 'bold' 40 | } 41 | }, 42 | title: { 43 | style: { 44 | color: '#666', 45 | font: '12px Lucida Grande, Lucida Sans Unicode,' + 46 | ' Verdana, Arial, Helvetica, sans-serif' 47 | } 48 | } 49 | }, 50 | yAxis: { 51 | alternateGridColor: 'rgba(255, 255, 255, .5)', 52 | lineColor: '#C0D0E0', 53 | tickColor: '#C0D0E0', 54 | tickWidth: 1, 55 | labels: { 56 | style: { 57 | color: '#666', 58 | fontWeight: 'bold' 59 | } 60 | }, 61 | title: { 62 | style: { 63 | color: '#666', 64 | font: '12px Lucida Grande, Lucida Sans Unicode,' + 65 | ' Verdana, Arial, Helvetica, sans-serif' 66 | } 67 | } 68 | }, 69 | legend: { 70 | itemStyle: { 71 | font: '9pt Trebuchet MS, Verdana, sans-serif', 72 | color: '#3E576F' 73 | }, 74 | itemHoverStyle: { 75 | color: 'black' 76 | }, 77 | itemHiddenStyle: { 78 | color: 'silver' 79 | } 80 | }, 81 | labels: { 82 | style: { 83 | color: '#3E576F' 84 | } 85 | } 86 | }; -------------------------------------------------------------------------------- /ezhc/script/themes/skies.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors": [ 3 | "#514F78", 4 | "#42A07B", 5 | "#9B5E4A", 6 | "#72727F", 7 | "#1F949A", 8 | "#82914E", 9 | "#86777F", 10 | "#42A07B" 11 | ], 12 | "chart": { 13 | "className": "skies", 14 | "borderWidth": 0, 15 | "plotShadow": true, 16 | "plotBackgroundImage": "http://www.highcharts.com/demo/gfx/skies.jpg", 17 | "plotBackgroundColor": { 18 | "linearGradient": [ 19 | 0, 20 | 0, 21 | 250, 22 | 500 23 | ], 24 | "stops": [ 25 | [ 26 | 0, 27 | "rgba(255, 255, 255, 1)" 28 | ], 29 | [ 30 | 1, 31 | "rgba(255, 255, 255, 0)" 32 | ] 33 | ] 34 | }, 35 | "plotBorderWidth": 1 36 | }, 37 | "title": { 38 | "style": { 39 | "color": "#3E576F", 40 | "font": "16px Lucida Grande, Lucida Sans Unicode, Verdana, Arial, Helvetica, sans-serif" 41 | } 42 | }, 43 | "subtitle": { 44 | "style": { 45 | "color": "#6D869F", 46 | "font": "12px Lucida Grande, Lucida Sans Unicode, Verdana, Arial, Helvetica, sans-serif" 47 | } 48 | }, 49 | "xAxis": { 50 | "gridLineWidth": 0, 51 | "lineColor": "#C0D0E0", 52 | "tickColor": "#C0D0E0", 53 | "labels": { 54 | "style": { 55 | "color": "#666", 56 | "fontWeight": "bold" 57 | } 58 | }, 59 | "title": { 60 | "style": { 61 | "color": "#666", 62 | "font": "12px Lucida Grande, Lucida Sans Unicode, Verdana, Arial, Helvetica, sans-serif" 63 | } 64 | } 65 | }, 66 | "yAxis": { 67 | "alternateGridColor": "rgba(255, 255, 255, .5)", 68 | "lineColor": "#C0D0E0", 69 | "tickColor": "#C0D0E0", 70 | "tickWidth": 1, 71 | "labels": { 72 | "style": { 73 | "color": "#666", 74 | "fontWeight": "bold" 75 | } 76 | }, 77 | "title": { 78 | "style": { 79 | "color": "#666", 80 | "font": "12px Lucida Grande, Lucida Sans Unicode, Verdana, Arial, Helvetica, sans-serif" 81 | } 82 | } 83 | }, 84 | "legend": { 85 | "itemStyle": { 86 | "font": "9pt Trebuchet MS, Verdana, sans-serif", 87 | "color": "#3E576F" 88 | }, 89 | "itemHoverStyle": { 90 | "color": "black" 91 | }, 92 | "itemHiddenStyle": { 93 | "color": "silver" 94 | } 95 | }, 96 | "labels": { 97 | "style": { 98 | "color": "#3E576F" 99 | } 100 | } 101 | } -------------------------------------------------------------------------------- /ezhc/script/themes/sunset.js: -------------------------------------------------------------------------------- 1 | var theme = { 2 | colors: ['#FDD089', '#FF7F79', '#A0446E', '#251535'], 3 | 4 | colorAxis: { 5 | maxColor: '#60042E', 6 | minColor: '#FDD089' 7 | }, 8 | 9 | plotOptions: { 10 | map: { 11 | nullColor: '#fefefc' 12 | } 13 | }, 14 | 15 | navigator: { 16 | series: { 17 | color: '#FF7F79', 18 | lineColor: '#A0446E' 19 | } 20 | } 21 | }; -------------------------------------------------------------------------------- /ezhc/script/themes/sunset.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors": [ 3 | "#FDD089", 4 | "#FF7F79", 5 | "#A0446E", 6 | "#251535" 7 | ], 8 | "colorAxis": { 9 | "maxColor": "#60042E", 10 | "minColor": "#FDD089" 11 | }, 12 | "plotOptions": { 13 | "map": { 14 | "nullColor": "#fefefc" 15 | } 16 | }, 17 | "navigator": { 18 | "series": { 19 | "color": "#FF7F79", 20 | "lineColor": "#A0446E" 21 | } 22 | } 23 | } -------------------------------------------------------------------------------- /ezhc/script/tooltip_positioner_center_top.js: -------------------------------------------------------------------------------- 1 | function (labelWidth, labelHeight, point) { 2 | var roundUp100 = function(d) { return 100*Math.floor(d/100); }, 3 | labelWidth = roundUp100(labelWidth), 4 | chart = window.charts['__uuid__']; 5 | 6 | var tooltipX, tooltipY; 7 | // test X: point.plotX in center 8 | var testX = (point.plotX + labelWidth * 0.7 > chart.plotWidth / 2) && (point.plotX - labelWidth * 0.7 < chart.plotWidth / 2); 9 | // test Y: point.plotY in top 10 | var testY = point.plotY < labelHeight * 0.7; 11 | 12 | if (testX && testY) { 13 | // put tooltip at center bottom 14 | tooltipX = chart.plotLeft + (chart.plotWidth - labelWidth) / 2; 15 | tooltipY = chart.plotTop + chart.plotHeight - labelHeight; 16 | } else { 17 | // put tooltip at center top 18 | tooltipX = chart.plotLeft + (chart.plotWidth - labelWidth) / 2; 19 | tooltipY = chart.plotTop; 20 | } 21 | 22 | return { 23 | x: tooltipX, 24 | y: tooltipY 25 | }; 26 | } 27 | 28 | -------------------------------------------------------------------------------- /ezhc/script/tooltip_positioner_left_top.js: -------------------------------------------------------------------------------- 1 | //function() { return { x: 400, y: 1 }; } 2 | 3 | function (labelWidth, labelHeight, point) { 4 | var roundUp100 = function(d) { return 100*Math.floor(d/100); }, 5 | labelWidth = roundUp100(labelWidth), 6 | chart = window.charts['__uuid__']; 7 | 8 | var tooltipX, tooltipY; 9 | // test X: point.plotX in left 10 | var testX = point.plotX < labelWidth * 0.7; 11 | // test Y: point.plotY in top 12 | var testY = point.plotY < labelHeight * 0.7; 13 | 14 | if (testX && testY) { 15 | // put tooltip at left bottom 16 | tooltipX = chart.plotLeft; 17 | tooltipY = chart.plotTop + chart.plotHeight - labelHeight; 18 | } else { 19 | // put tooltip at left top 20 | tooltipX = chart.plotLeft; 21 | tooltipY = chart.plotTop; 22 | } 23 | 24 | return { 25 | x: tooltipX, 26 | y: tooltipY 27 | }; 28 | } 29 | -------------------------------------------------------------------------------- /ezhc/script/tooltip_positioner_right_top.js: -------------------------------------------------------------------------------- 1 | //function() { return { x: 400, y: 1 }; } 2 | 3 | function (labelWidth, labelHeight, point) { 4 | var roundUp100 = function(d) { return 100*Math.floor(d/100); }, 5 | labelWidth = roundUp100(labelWidth), 6 | chart = window.charts['__uuid__']; 7 | 8 | var tooltipX, tooltipY; 9 | // test X: point.plotX in right 10 | var testX = point.plotX + labelWidth * 0.7 > chart.plotWidth; 11 | // test Y: point.plotY in top 12 | var testY = point.plotY < labelHeight * 0.7; 13 | 14 | if (testX && testY) { 15 | // put tooltip at right bottom 16 | tooltipX = chart.plotLeft + chart.plotWidth - labelWidth; 17 | tooltipY = chart.plotTop + chart.plotHeight - labelHeight; 18 | } else { 19 | // put tooltip at right top 20 | tooltipX = chart.plotLeft + chart.plotWidth - labelWidth; 21 | tooltipY = chart.plotTop; 22 | } 23 | 24 | return { 25 | x: tooltipX, 26 | y: tooltipY 27 | }; 28 | } 29 | -------------------------------------------------------------------------------- /ezhc/scripts.py: -------------------------------------------------------------------------------- 1 | 2 | import os 3 | import re 4 | from jinja2 import Environment 5 | 6 | from ._config import SCRIPT_DIR 7 | from ._img import image_src 8 | 9 | 10 | def get_path(filename): 11 | _dir = os.path.dirname(__file__) 12 | path = os.path.join(_dir, SCRIPT_DIR, filename) 13 | return path 14 | 15 | 16 | def remove_comments_js(string): 17 | # remove all streamed comments (/*COMMENT */) from string 18 | string = re.sub(re.compile("/\*.*?\*/", re.DOTALL), "", string) 19 | # remove all singleline comments (//COMMENT\n ) from string 20 | string = re.sub(re.compile("//.*?\n"), "", string) 21 | return string 22 | 23 | 24 | def load_script(filename, js=True): 25 | path = get_path(filename) 26 | with open(path) as f: 27 | contents = f.read() 28 | if js: 29 | contents = remove_comments_js(contents) 30 | return contents # .replace('\n', '') 31 | 32 | 33 | def from_template(contents, **kwargs): 34 | contents = Environment().from_string(contents).render(**kwargs) 35 | return contents 36 | 37 | 38 | TOOLTIP_HEADER_FORMAT = '{series.name}
    ' 39 | TOOLTIP_POINT_FORMAT_PERCENT = '{series.name}: {point.y} ({point.change}%)
    ' 40 | TOOLTIP_POINT_FORMAT_BASIC = '{series.name}: {point.y}
    ' 41 | 42 | 43 | TOOLTIP_POSITIONER_CENTER_TOP = load_script('tooltip_positioner_center_top.js') 44 | TOOLTIP_POSITIONER_LEFT_TOP = load_script('tooltip_positioner_left_top.js') 45 | TOOLTIP_POSITIONER_RIGHT_TOP = load_script('tooltip_positioner_right_top.js') 46 | 47 | FORMATTER_PERCENT = load_script('formatter_percent.js') 48 | FORMATTER_BASIC = load_script('formatter_basic.js') 49 | FORMATTER_QUANTILE = load_script('formatter_quantile.js') 50 | 51 | 52 | JS_JSON_PARSE = load_script('json_parse.js') 53 | 54 | JS_FINANCIAL_TIME_SERIES_0 = load_script('financial_time_series_0.js') 55 | JS_FINANCIAL_TIME_SERIES_TABLE_1 = load_script('financial_time_series_table_1.js') 56 | JS_FINANCIAL_TIME_SERIES_TABLE_2 = load_script('financial_time_series_table_2.js') 57 | HTML_FINANCIAL_TIME_SERIES_TABLE = load_script('financial_time_series_table.html', js=False) 58 | JS_FINANCIAL_TIME_SERIES_TABLE_OPTIONS_1 = load_script('financial_time_series_table_options_1.js') 59 | JS_FINANCIAL_TIME_SERIES_TABLE_OPTIONS_2 = load_script('financial_time_series_table_options_2.js') 60 | JS_FINANCIAL_TIME_SERIES_TABLE_CALLBACK_0 = 'function(chart) { create_table_0("__uuid__", chart); }' 61 | JS_FINANCIAL_TIME_SERIES_TABLE_CALLBACK_1 = 'function(chart) { console.log("callback_1 beg "+"__uuid__"); create_table_1("__uuid__", chart); }' 62 | JS_FINANCIAL_TIME_SERIES_TABLE_CALLBACK_2 = 'function(chart) { create_table_2("__uuid__", chart); }' 63 | 64 | TEMPLATE_DISCLAIMER = load_script('template_disclaimer.html', js=False) 65 | 66 | PATH_TO_LOGO_JUPYTER = image_src(get_path('Jupyter_logo.png')) 67 | PATH_TO_LOGO_SG = image_src(get_path('SG_logo.png')) 68 | -------------------------------------------------------------------------------- /ezhc/series.py: -------------------------------------------------------------------------------- 1 | 2 | import pandas as pd 3 | 4 | 5 | 6 | def series(df, options, *args, **kwargs): 7 | idx = df.index 8 | col = df.columns 9 | data = df.values 10 | assert(isinstance(idx, pd.core.index.Index)) 11 | 12 | series = [] 13 | for k, c in enumerate(col): 14 | if df[c].dtype.kind in 'fib': 15 | v = data[:, k] 16 | sec = c in kwargs.get('secondary_y', []) 17 | d = { 18 | 'name': c if not sec else c + ' (right)', 19 | 'yAxis': int(sec), 20 | 'data': [[idx[q], v[q]] for q in range(len(v))], 21 | } 22 | if c in kwargs.get('color', []): 23 | d['color'] = kwargs['color'].get(c) 24 | if kwargs.get('dashStyle', []): 25 | d['dashStyle'] = kwargs['dashStyle'].get(c, 'Solid') 26 | series.append(d) 27 | return series 28 | 29 | 30 | 31 | 32 | def series_drilldown(df, options, *args, **kwargs): 33 | idx = df.index 34 | col = df.columns 35 | assert(isinstance(idx, pd.core.index.MultiIndex)) 36 | assert(len(idx.levshape)==2) 37 | assert(len(col)==1) 38 | assert(df[col[0]].dtype.kind in 'if') 39 | 40 | levone = list(idx.levels[0]) 41 | data = [] 42 | drilldownSeries = [] 43 | for c in levone: 44 | dfs = df.xs(c) 45 | ii = dfs.index.values.flatten() 46 | vv = dfs.values.flatten() 47 | 48 | d1 = { 49 | 'name': c, 50 | 'y': dfs.sum().values[0], 51 | 'drilldown': c if len(dfs)>1 else None, 52 | } 53 | data.append(d1) 54 | 55 | if len(dfs)>1: 56 | d2 = { 57 | 'name': c, 58 | 'data': [[str(ii[q]), vv[q]] for q in range(len(ii))], 59 | 'id': c, 60 | } 61 | drilldownSeries.append(d2) 62 | 63 | series = [{'name': col[0],'data': data, 'colorByPoint': True}] 64 | return series, drilldownSeries 65 | 66 | 67 | 68 | 69 | 70 | 71 | def series_scatter(df, options, *args, **kwargs): 72 | idx = df.index 73 | col = df.columns 74 | assert(isinstance(idx, pd.core.index.MultiIndex)) 75 | assert(len(idx.levshape)==2) 76 | assert(len(col)==1) 77 | assert(df[col[0]].dtype.kind in 'iO') 78 | 79 | data = df.values.flatten() 80 | elmt = list(set(data)) 81 | color = kwargs.get('color', {}) 82 | series = [] 83 | 84 | for e in elmt: 85 | dfs = df[df.iloc[:, 0]==e] 86 | idx = dfs.index 87 | series.append({'animation': False, 88 | 'name': e, 89 | 'color': color.get(e, None), 90 | 'data': [[idx[k][0], idx[k][1]] for k in range(len(dfs))], 91 | }) 92 | return series 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | def series_bubble(df, options, *args, **kwargs): 101 | idx = df.index 102 | col = df.columns 103 | assert(isinstance(idx, pd.core.index.MultiIndex)) 104 | assert(len(idx.levshape)==3) 105 | assert(len(col)==1) 106 | assert(df[col[0]].dtype.kind in 'fib') 107 | 108 | names = list(idx.levels[0]) 109 | color = kwargs.get('color', {}) 110 | series = [] 111 | for s in names: 112 | dfs = df.xs(s) 113 | v = dfs.values.flatten() 114 | idxs = dfs.index 115 | d = { 116 | 'name': s, 117 | 'data': [[idxs[q][0], idxs[q][1], v[q]] for q in range(len(v))], 118 | } 119 | if s in kwargs.get('color', []): 120 | d['color'] = kwargs['color'].get(s) 121 | 122 | series.append(d) 123 | 124 | return series 125 | 126 | 127 | 128 | 129 | def series_treemap(df, options, *args, **kwargs): 130 | idx = df.index 131 | col = df.columns 132 | assert(isinstance(idx, pd.core.index.MultiIndex)) 133 | assert(df[col[0]].dtype.kind in 'fi') 134 | 135 | data = df.values 136 | elmt = list(set(data)) 137 | color = kwargs.get('color', {}) 138 | series = [] 139 | 140 | for e in elmt: 141 | dfs = df[df.iloc[:, 0]==e] 142 | idx = dfs.index 143 | series.append({'animation': False, 144 | 'name': e, 145 | 'color': color.get(e, None), 146 | 'data': [[idx[k][0], idx[k][1]] for k in range(len(dfs))], 147 | }) 148 | return series 149 | 150 | 151 | 152 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | pandas>=0.17 2 | jinja2>=2.8 3 | ipython>=3.0 4 | requests>=2.9 5 | -------------------------------------------------------------------------------- /setup.cfg: -------------------------------------------------------------------------------- 1 | # necessary to push to PyPI 2 | 3 | [metadata] 4 | description-file = README.rst -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | # necessary to push to PyPI 2 | # cf. http://peterdowns.com/posts/first-time-with-pypi.html 3 | # cf. https://tom-christie.github.io/articles/pypi/ 4 | # cf. https://pythonhosted.org/setuptools/setuptools.html 5 | 6 | # commands: 7 | # one liner 8 | # python setup.py sdist upload -r pypi 9 | # 2 steps 10 | # python setup.py sdist bdist_wheel 11 | # twine upload dist/* -r ezhc 12 | 13 | 14 | from distutils.util import convert_path 15 | 16 | from setuptools import find_packages, setup 17 | 18 | packages = find_packages() 19 | module = packages[0] 20 | 21 | meta_ns = {} 22 | ver_path = convert_path(module + '/__meta__.py') 23 | with open(ver_path) as ver_file: 24 | exec(ver_file.read(), meta_ns) 25 | 26 | name = meta_ns['__name__'] 27 | packages = packages 28 | version = meta_ns['__version__'] 29 | description = meta_ns['__description__'] 30 | author = meta_ns['__author__'] 31 | author_email = meta_ns['__author_email__'] 32 | url = meta_ns['__url__'] 33 | download_url = meta_ns['__download_url__'] 34 | keywords = meta_ns['__keywords__'] 35 | license = meta_ns['__license__'] 36 | classifiers = meta_ns['__classifiers__'] 37 | include_package_data = meta_ns['__include_package_data__'] 38 | package_data = meta_ns['__package_data__'] 39 | zip_safe = meta_ns['__zip_safe__'] 40 | entry_points = meta_ns['__entry_points__'] 41 | 42 | 43 | # read requirements.txt 44 | with open('requirements.txt', 'r') as f: 45 | content = f.read() 46 | li_req = content.split('\n') 47 | install_requires = [e.strip() for e in li_req if len(e)] 48 | 49 | # with open('README.rst') as f: 50 | # long_description = f.read() 51 | 52 | setup( 53 | name=name, 54 | version=version, 55 | description=description, 56 | # long_description=long_description, 57 | author=author, 58 | author_email=author_email, 59 | url=url, 60 | download_url=download_url, 61 | keywords=keywords, 62 | license=license, 63 | classifiers=classifiers, 64 | packages=packages, 65 | install_requires=install_requires, 66 | include_package_data=include_package_data, 67 | package_data=package_data, 68 | zip_safe=zip_safe, 69 | entry_points=entry_points 70 | ) 71 | --------------------------------------------------------------------------------