diff --git a/highcharts/highstock/highstock.py b/highcharts/highstock/highstock.py index 0b5c4c0..7f9513d 100644 --- a/highcharts/highstock/highstock.py +++ b/highcharts/highstock/highstock.py @@ -7,7 +7,8 @@ from jinja2 import Environment, PackageLoader -import json, uuid +import json +import uuid import re import datetime import html @@ -31,7 +32,7 @@ template_content = jinja2_env.get_template(CONTENT_FILENAME) template_page = jinja2_env.get_template(PAGE_FILENAME) - + class Highstock(object): """ @@ -59,20 +60,20 @@ def __init__(self, **kwargs): # an Instance of Jinja2 template self.template_page_highcharts = template_page self.template_content_highcharts = template_content - + # set Javascript src, Highcharts lib needs to make sure it's up to date self.JSsource = [ - 'https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js', - 'https://code.highcharts.com/stock/highstock.js', - 'https://code.highcharts.com/stock/modules/exporting.js', - 'https://code.highcharts.com/highcharts-more.js', - ] + 'https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js', + 'https://code.highcharts.com/stock/highstock.js', + 'https://code.highcharts.com/stock/modules/exporting.js', + 'https://code.highcharts.com/highcharts-more.js', + ] # set CSS src self.CSSsource = [ - 'https://www.highcharts.com/highslide/highslide.css', + 'https://www.highcharts.com/highslide/highslide.css', - ] + ] # set data self.data = [] self.data_temp = [] @@ -84,8 +85,8 @@ def __init__(self, **kwargs): # Data from jsonp self.jsonp_data_flag = False - self.jsonp_data_url_list = [] # DEM 2017/04/25: List of JSON data sources - + self.jsonp_data_url_list = [] # DEM 2017/04/25: List of JSON data sources + # javascript self.jscript_head_flag = False self.jscript_head = kwargs.get('jscript_head', None) @@ -155,18 +156,16 @@ def __init__(self, **kwargs): for keyword in allowed_kwargs: if keyword in kwargs: - self.options['chart'].update_dict(**{keyword:kwargs[keyword]}) + self.options['chart'].update_dict(**{keyword: kwargs[keyword]}) # Some Extra Vals to store: self.data_set_count = 0 self.drilldown_data_set_count = 0 - def __load_defaults__(self): self.options["chart"].update_dict(renderTo='container') self.options["title"].update_dict(text='A New Highchart') self.options["credits"].update_dict(enabled=False) - def add_JSsource(self, new_src): """add additional js script source(s)""" if isinstance(new_src, list): @@ -177,7 +176,6 @@ def add_JSsource(self, new_src): else: raise OptionTypeError("Option: %s Not Allowed For Series Type: %s" % type(new_src)) - def add_CSSsource(self, new_src): """add additional css source(s)""" if isinstance(new_src, list): @@ -188,44 +186,37 @@ def add_CSSsource(self, new_src): else: raise OptionTypeError("Option: %s Not Allowed For Series Type: %s" % type(new_src)) - def add_data_set(self, data, series_type="line", name=None, **kwargs): """set data for series option in highstocks""" self.data_set_count += 1 if not name: name = "Series %d" % self.data_set_count - kwargs.update({'name':name}) + kwargs.update({'name': name}) series_data = Series(data, series_type=series_type, **kwargs) series_data.__options__().update(SeriesOptions(series_type=series_type, **kwargs).__options__()) self.data_temp.append(series_data) - - def add_data_from_jsonp(self, data_src, data_name='json_data', series_type="line", name=None, **kwargs): + def add_data_from_jsonp(self, data_src, series_type="line", name=None, **kwargs): """set map data directly from a https source the data_src is the https link for data and it must be in jsonp format """ if not self.jsonp_data_flag: self.jsonp_data_flag = True - - if data_name == 'data': - data_name = 'json_'+ data_name - - self.jsonp_data = data_name - self.add_data_set(RawJavaScriptText(self.jsonp_data), series_type, name=name, **kwargs) + + self.add_data_set(None, series_type, name=name, **kwargs) # DEM 2017/04/25: Append new JSON data source to a list instead of # replacing whatever already exists self.jsonp_data_url_list.append(json.dumps(data_src)) - def add_navi_series(self, data, series_type="line", **kwargs): """set series for navigator option in highstocks""" self.navi_seri_flag = True series_data = Series(data, series_type=series_type, **kwargs) - series_data.__options__().update(SeriesOptions(series_type=series_type, **kwargs).__options__()) + series_data.__options__().update(SeriesOptions(series_type=series_type, **kwargs).__options__()) self.navi_seri_temp = series_data def add_navi_series_from_jsonp(self, data_src=None, data_name='json_data', series_type="line", **kwargs): @@ -233,15 +224,12 @@ def add_navi_series_from_jsonp(self, data_src=None, data_name='json_data', serie if not self.jsonp_data_flag: self.jsonp_data_flag = True - self.jsonp_data_url = json.dumps(data_src) - + self.jsonp_data_url = json.dumps(data_src) + if data_name == 'data': - data_name = 'json_'+ data_name - - self.jsonp_data = data_name - - self.add_navi_series(RawJavaScriptText(self.jsonp_data), series_type, **kwargs) + data_name = 'json_' + data_name + self.add_navi_series(RawJavaScriptText(self.jsonp_data), series_type, **kwargs) def add_JSscript(self, js_script, js_loc): """add (highcharts) javascript in the beginning or at the end of script @@ -250,19 +238,18 @@ def add_JSscript(self, js_script, js_loc): if js_loc == 'head': self.jscript_head_flag = True if self.jscript_head: - self.jscript_head = self.jscript_head + '\n' + js_script + self.jscript_head = self.jscript_head + '\n' + js_script else: self.jscript_head = js_script elif js_loc == 'end': self.jscript_end_flag = True if self.jscript_end: - self.jscript_end = self.jscript_end + '\n' + js_script + self.jscript_end = self.jscript_end + '\n' + js_script else: self.jscript_end = js_script else: - raise OptionTypeError("Not An Accepted script location: %s, either 'head' or 'end'" - % js_loc) - + raise OptionTypeError("Not An Accepted script location: %s, either 'head' or 'end'" + % js_loc) def set_options(self, option_type, option_dict, force_options=False): """set plot options """ @@ -274,13 +261,12 @@ def set_options(self, option_type, option_dict, force_options=False): for each_dict in option_dict: self.options[option_type].update(**each_dict) elif option_type == 'colors': - self.options["colors"].set_colors(option_dict) # option_dict should be a list - elif option_type in ["global" , "lang"]: #Highcharts.setOptions: + self.options["colors"].set_colors(option_dict) # option_dict should be a list + elif option_type in ["global", "lang"]: # Highcharts.setOptions: self.setOptions[option_type].update_dict(**option_dict) else: self.options[option_type].update_dict(**option_dict) - def set_dict_options(self, options): """for dictionary-like inputs (as object in Javascript) options must be in python dictionary format @@ -289,27 +275,25 @@ def set_dict_options(self, options): for key, option_data in options.items(): self.set_options(key, option_data) else: - raise OptionTypeError("Not An Accepted Input Format: %s. Must be Dictionary" %type(options)) - + raise OptionTypeError("Not An Accepted Input Format: %s. Must be Dictionary" % type(options)) def buildcontent(self): """build HTML content only, no header or body tags""" self.buildcontainer() - self.option = json.dumps(self.options, cls = HighchartsEncoder) - self.setoption = json.dumps(self.setOptions, cls = HighchartsEncoder) - self.data = json.dumps(self.data_temp, cls = HighchartsEncoder) + self.option = json.dumps(self.options, cls=HighchartsEncoder) + self.setoption = json.dumps(self.setOptions, cls=HighchartsEncoder) + self.data = json.dumps(self.data_temp, cls=HighchartsEncoder) # DEM 2017/04/25: Make 'data' available as an array # ... this permits jinja2 array access to each data definition # ... which is useful for looping over multiple data sources - self.data_list = [json.dumps(x, cls = HighchartsEncoder) for x in self.data_temp] - - if self.navi_seri_flag: - self.navi_seri = json.dumps(self.navi_seri_temp, cls = HighchartsEncoder) + self.data_list = [json.dumps(x, cls=HighchartsEncoder) for x in self.data_temp] - self._htmlcontent = self.template_content_highcharts.render(chart=self).encode('utf-8') + if self.navi_seri_flag: + self.navi_seri = json.dumps(self.navi_seri_temp, cls=HighchartsEncoder) + self._htmlcontent = self.template_content_highcharts.render(chart=self).encode('utf-8') def buildhtml(self): """build the HTML page @@ -318,10 +302,9 @@ def buildhtml(self): """ self.buildcontent() self.buildhtmlheader() - self.content = self._htmlcontent.decode('utf-8') # need to ensure unicode + self.content = self._htmlcontent.decode('utf-8') # need to ensure unicode self._htmlcontent = self.template_page_highcharts.render(chart=self) return self._htmlcontent - def buildhtmlheader(self): """generate HTML header content""" @@ -340,7 +323,6 @@ def buildhtmlheader(self): for js in self.header_js: self.htmlheader += js - def buildcontainer(self): """generate HTML div""" if self.container: @@ -357,7 +339,7 @@ def buildcontainer(self): else: self.div_style += 'height:%s;' % self.options['chart'].height - self.div_name = self.options['chart'].__dict__['renderTo'] # recheck div name + self.div_name = self.options['chart'].__dict__['renderTo'] # recheck div name self.container = self.containerheader + \ '