From fb5ca7d986b15a5c87c08ba10e0286becda917c6 Mon Sep 17 00:00:00 2001 From: Kyle Solan Date: Wed, 2 Sep 2015 03:10:17 +0000 Subject: [PATCH 01/35] added install instructions --- README.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 3a4aa28..95537ec 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,10 @@ The original framework was inspired by [python-nvd3](https://github.com/areski/p ## Installation --need to work on this- +python-highcharts supports Python 2.7/3.4 and is available on PyPI. To install: +``` +pip install python-highcharts +``` --------------------------------------------------------------------------------------------------------------- # Highcharts/Highstock @@ -581,4 +584,4 @@ chart.save_file() * More examples * Clean code and put more explanation -Reference: [Highcharts API](http://api.highcharts.com/highcharts) \ No newline at end of file +Reference: [Highcharts API](http://api.highcharts.com/highcharts) From a2cc7f41f7f9ad594c6c7a907a38b85a4a4b78c1 Mon Sep 17 00:00:00 2001 From: Kyle Solan Date: Wed, 2 Sep 2015 03:17:53 +0000 Subject: [PATCH 02/35] updated readme --- README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.md b/README.md index 95537ec..2e15f2e 100644 --- a/README.md +++ b/README.md @@ -196,6 +196,12 @@ chart.add_data_set(data, 'spline', 'Temperature', marker={'enabled': False}) chart ``` +# Example notebooks: + +* [Highcharts](http://nbviewer.ipython.org/github/kyper-data/python-highcharts/blob/master/examples/ipynb/highcharts/Example1.ipynb) +* [Highmaps](http://nbviewer.ipython.org/github/kyper-data/python-highcharts/blob/master/examples/ipynb/highmaps/Example1.ipynb) +* [Highstock](http://nbviewer.ipython.org/github/kyper-data/python-highcharts/blob/master/examples/ipynb/highstock/Example1-basic-line.ipynb) + ## Todo: * More charts support From 9884e6becc519ac8c86844b1fe5a9070ede79081 Mon Sep 17 00:00:00 2001 From: Kyle Solan Date: Wed, 2 Sep 2015 03:21:30 +0000 Subject: [PATCH 03/35] updated notebook --- README.md | 2 +- examples/ipynb/highcharts/3d-scatter-draggable.ipynb | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 2e15f2e..9e53f5a 100644 --- a/README.md +++ b/README.md @@ -196,7 +196,7 @@ chart.add_data_set(data, 'spline', 'Temperature', marker={'enabled': False}) chart ``` -# Example notebooks: +### Example notebooks: * [Highcharts](http://nbviewer.ipython.org/github/kyper-data/python-highcharts/blob/master/examples/ipynb/highcharts/Example1.ipynb) * [Highmaps](http://nbviewer.ipython.org/github/kyper-data/python-highcharts/blob/master/examples/ipynb/highmaps/Example1.ipynb) diff --git a/examples/ipynb/highcharts/3d-scatter-draggable.ipynb b/examples/ipynb/highcharts/3d-scatter-draggable.ipynb index 4f2c9de..cfd6205 100644 --- a/examples/ipynb/highcharts/3d-scatter-draggable.ipynb +++ b/examples/ipynb/highcharts/3d-scatter-draggable.ipynb @@ -12,7 +12,7 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 1, "metadata": { "collapsed": false, "scrolled": false @@ -21,7 +21,7 @@ { "data": { "text/html": [ - "" + "</html> \"height= 400 width =550>" ], "text/plain": [ - "" + "" ] }, - "execution_count": 8, + "execution_count": 1, "metadata": {}, "output_type": "execute_result" } From d8d90ccfe80e78317dc0f73e618c4f371a41e418 Mon Sep 17 00:00:00 2001 From: Kyle Solan Date: Fri, 18 Sep 2015 22:18:03 +0000 Subject: [PATCH 04/35] updated ipynb to be compatible with ipython 4.0 --- highcharts/ipynb.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/highcharts/ipynb.py b/highcharts/ipynb.py index 69a6cb4..648a2e9 100644 --- a/highcharts/ipynb.py +++ b/highcharts/ipynb.py @@ -10,7 +10,7 @@ _ip = get_ipython() except: _ip = None -if _ip and _ip.__module__.startswith('IPython'): +if _ip and (_ip.__module__.startswith('IPython') or _ip.__module__.startswith('ipykernel')): def _print_html(chart): '''Function to return the HTML code for the div container plus the javascript @@ -45,4 +45,4 @@ def _setup_ipython_formatter(ip): for chart_type in [Highchart, Highmap, Highstock]: html_formatter.for_type(chart_type, _print_html) - _setup_ipython_formatter(_ip) \ No newline at end of file + _setup_ipython_formatter(_ip) From 3e6e72f389dbcc07fef8e7a0fb9e6463ebfd8c38 Mon Sep 17 00:00:00 2001 From: Kyle Solan Date: Fri, 18 Sep 2015 22:19:24 +0000 Subject: [PATCH 05/35] v0.1.1 --- highcharts/version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/highcharts/version.py b/highcharts/version.py index c1ced06..df46fc8 100644 --- a/highcharts/version.py +++ b/highcharts/version.py @@ -1,7 +1,7 @@ version_info = ( "0", "1", - "0" + "1" ) __version__ = '.'.join(map(str, version_info)) From a164be4ee5392daf469681eb38911de3b7dd2c2f Mon Sep 17 00:00:00 2001 From: Kyle Solan Date: Sat, 17 Oct 2015 04:05:26 +0000 Subject: [PATCH 06/35] fixed ipython bug with python3 + highstock/highmaps --- highcharts/highmaps/highmaps.py | 2 +- highcharts/highstock/highstock.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/highcharts/highmaps/highmaps.py b/highcharts/highmaps/highmaps.py index 0fc67f3..7df1e11 100644 --- a/highcharts/highmaps/highmaps.py +++ b/highcharts/highmaps/highmaps.py @@ -369,7 +369,7 @@ def buildhtml(self): self.buildcontent() self.buildhtmlheader() self.content = self._htmlcontent.decode('utf-8') # need to ensure unicode - self._htmlcontent = self.template_page_highcharts.render(chart=self).encode('utf-8') + self._htmlcontent = self.template_page_highcharts.render(chart=self) return self._htmlcontent def buildhtmlheader(self): diff --git a/highcharts/highstock/highstock.py b/highcharts/highstock/highstock.py index 624c9fb..fe649ca 100644 --- a/highcharts/highstock/highstock.py +++ b/highcharts/highstock/highstock.py @@ -306,7 +306,7 @@ def buildhtml(self): self.buildcontent() self.buildhtmlheader() self.content = self._htmlcontent.decode('utf-8') # need to ensure unicode - self._htmlcontent = self.template_page_highcharts.render(chart=self).encode('utf-8') + self._htmlcontent = self.template_page_highcharts.render(chart=self) return self._htmlcontent From 42ce7cc4143b21b8da1e026f982e84727541474a Mon Sep 17 00:00:00 2001 From: Kyle Solan Date: Sat, 17 Oct 2015 04:06:08 +0000 Subject: [PATCH 07/35] v0.1.2 --- highcharts/version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/highcharts/version.py b/highcharts/version.py index df46fc8..cd1bcb8 100644 --- a/highcharts/version.py +++ b/highcharts/version.py @@ -1,7 +1,7 @@ version_info = ( "0", "1", - "1" + "2" ) __version__ = '.'.join(map(str, version_info)) From 3b3f0b4d61432142123138f1d23ae345e9814640 Mon Sep 17 00:00:00 2001 From: Kyle Solan Date: Tue, 20 Oct 2015 17:24:21 +0000 Subject: [PATCH 08/35] cleaned up imports and added .iframe property --- highcharts/highcharts/highcharts.py | 22 ++++++++++++++++++---- highcharts/highmaps/highmaps.py | 19 +++++++++++++++++-- highcharts/highstock/highstock.py | 19 +++++++++++++++++-- highcharts/ipynb.py | 15 +-------------- 4 files changed, 53 insertions(+), 22 deletions(-) diff --git a/highcharts/highcharts/highcharts.py b/highcharts/highcharts/highcharts.py index 86f38b1..714cbaa 100644 --- a/highcharts/highcharts/highcharts.py +++ b/highcharts/highcharts/highcharts.py @@ -6,12 +6,10 @@ from past.builtins import basestring from jinja2 import Environment, PackageLoader -# import sys -# reload(sys) -# sys.setdefaultencoding("utf-8") import json, uuid -import datetime, random, os, inspect +import datetime +import html from collections import Iterable from .options import BaseOptions, ChartOptions, \ ColorsOptions, CreditsOptions, DrilldownOptions, ExportingOptions, \ @@ -357,6 +355,22 @@ def buildcontainer(self): def htmlcontent(self): return self.buildhtml() + @property + def iframe(self): + htmlsrcdoc = html.escape(self.htmlcontent) + width = int(self.options['chart'].__dict__['width']) if self.options['chart'].__dict__.get('width') else 820 + height = int(self.options['chart'].__dict__['height']) if self.options['chart'].__dict__.get('height') else 520 + + if self.options['chart'].__dict__.get('options3d'): + if len(htmlsrcdoc) < 99965000 : + return '' + else: + return '' + else: + return '' + + def __str__(self): """return htmlcontent""" #self.buildhtml() diff --git a/highcharts/highmaps/highmaps.py b/highcharts/highmaps/highmaps.py index 7df1e11..0afe210 100644 --- a/highcharts/highmaps/highmaps.py +++ b/highcharts/highmaps/highmaps.py @@ -6,12 +6,12 @@ from past.builtins import basestring -from optparse import OptionParser from urllib.request import urlopen from jinja2 import Environment, PackageLoader import json, uuid -import datetime, random, os, inspect +import datetime +import html from collections import Iterable from .options import BaseOptions, ChartOptions, \ ColorsOptions, ColorAxisOptions, CreditsOptions, DrilldownOptions, ExportingOptions, \ @@ -418,6 +418,21 @@ def buildcontainer(self): def htmlcontent(self): return self.buildhtml() + @property + def iframe(self): + htmlsrcdoc = html.escape(self.htmlcontent) + width = int(self.options['chart'].__dict__['width']) if self.options['chart'].__dict__.get('width') else 820 + height = int(self.options['chart'].__dict__['height']) if self.options['chart'].__dict__.get('height') else 520 + + if self.options['chart'].__dict__.get('options3d'): + if len(htmlsrcdoc) < 99965000 : + return '' + else: + return '' + else: + return '' + def __str__(self): """return htmlcontent""" #self.buildhtml() diff --git a/highcharts/highstock/highstock.py b/highcharts/highstock/highstock.py index fe649ca..70401c5 100644 --- a/highcharts/highstock/highstock.py +++ b/highcharts/highstock/highstock.py @@ -4,11 +4,11 @@ from future.standard_library import install_aliases install_aliases() -from optparse import OptionParser from jinja2 import Environment, PackageLoader import json, uuid -import datetime, random, os, inspect +import datetime +import html from collections import Iterable from .options import BaseOptions, ChartOptions, \ ColorsOptions, CreditsOptions, ExportingOptions, \ @@ -352,6 +352,21 @@ def buildcontainer(self): def htmlcontent(self): return self.buildhtml() + @property + def iframe(self): + htmlsrcdoc = html.escape(self.htmlcontent) + width = int(self.options['chart'].__dict__['width']) if self.options['chart'].__dict__.get('width') else 820 + height = int(self.options['chart'].__dict__['height']) if self.options['chart'].__dict__.get('height') else 520 + + if self.options['chart'].__dict__.get('options3d'): + if len(htmlsrcdoc) < 99965000 : + return '' + else: + return '' + else: + return '' + def __str__(self): """return htmlcontent""" #self.buildhtml() diff --git a/highcharts/ipynb.py b/highcharts/ipynb.py index 648a2e9..20b4e3a 100644 --- a/highcharts/ipynb.py +++ b/highcharts/ipynb.py @@ -17,20 +17,7 @@ def _print_html(chart): to generate the chart. This function is bound to the ipython formatter so that charts are displayed inline.''' - import html - htmlsrcdoc = html.escape(chart.htmlcontent) - width = int(chart.options['chart'].__dict__['width']) if chart.options['chart'].__dict__.get('width') else 820 - height = int(chart.options['chart'].__dict__['height']) if chart.options['chart'].__dict__.get('height') else 520 - - if chart.options['chart'].__dict__.get('options3d'): - if len(htmlsrcdoc) < 99965000 : - return '' - else: - return '' - else: - return '' - + return chart.iframe def _setup_ipython_formatter(ip): ''' Set up the ipython formatter to display HTML formatted output inline''' From 8acab908748957eda84ca06757a421cf812da83c Mon Sep 17 00:00:00 2001 From: Kyle Solan Date: Tue, 20 Oct 2015 17:26:40 +0000 Subject: [PATCH 09/35] v0.2.0 --- highcharts/version.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/highcharts/version.py b/highcharts/version.py index cd1bcb8..05e0870 100644 --- a/highcharts/version.py +++ b/highcharts/version.py @@ -1,7 +1,7 @@ version_info = ( "0", - "1", - "2" + "2", + "0" ) __version__ = '.'.join(map(str, version_info)) From b35735849478203f65e22a4b666aee9f45b3cdc1 Mon Sep 17 00:00:00 2001 From: Kyle Solan Date: Tue, 20 Oct 2015 22:43:11 +0000 Subject: [PATCH 10/35] remove excess spacing in iframes --- highcharts/highcharts/highcharts.py | 11 +++++++---- highcharts/highmaps/highmaps.py | 13 ++++++++----- highcharts/highstock/highstock.py | 11 +++++++---- 3 files changed, 22 insertions(+), 13 deletions(-) diff --git a/highcharts/highcharts/highcharts.py b/highcharts/highcharts/highcharts.py index 714cbaa..e8ecbc0 100644 --- a/highcharts/highcharts/highcharts.py +++ b/highcharts/highcharts/highcharts.py @@ -8,6 +8,7 @@ from jinja2 import Environment, PackageLoader import json, uuid +import re import datetime import html from collections import Iterable @@ -358,17 +359,19 @@ def htmlcontent(self): @property def iframe(self): htmlsrcdoc = html.escape(self.htmlcontent) + htmlsrcdoc = re.sub('\\n', ' ', htmlsrcdoc) + htmlsrcdoc = re.sub(' +', ' ', htmlsrcdoc) width = int(self.options['chart'].__dict__['width']) if self.options['chart'].__dict__.get('width') else 820 height = int(self.options['chart'].__dict__['height']) if self.options['chart'].__dict__.get('height') else 520 if self.options['chart'].__dict__.get('options3d'): if len(htmlsrcdoc) < 99965000 : - return '' + return '' else: - return '' + return '' else: - return '' + return '' def __str__(self): diff --git a/highcharts/highmaps/highmaps.py b/highcharts/highmaps/highmaps.py index 0afe210..fce007d 100644 --- a/highcharts/highmaps/highmaps.py +++ b/highcharts/highmaps/highmaps.py @@ -10,6 +10,7 @@ from jinja2 import Environment, PackageLoader import json, uuid +import re import datetime import html from collections import Iterable @@ -421,18 +422,20 @@ def htmlcontent(self): @property def iframe(self): htmlsrcdoc = html.escape(self.htmlcontent) + htmlsrcdoc = re.sub('\\n', ' ', htmlsrcdoc) + htmlsrcdoc = re.sub(' +', ' ', htmlsrcdoc) width = int(self.options['chart'].__dict__['width']) if self.options['chart'].__dict__.get('width') else 820 height = int(self.options['chart'].__dict__['height']) if self.options['chart'].__dict__.get('height') else 520 if self.options['chart'].__dict__.get('options3d'): if len(htmlsrcdoc) < 99965000 : - return '' + return '' else: - return '' + return '' else: - return '' - + return '' + def __str__(self): """return htmlcontent""" #self.buildhtml() diff --git a/highcharts/highstock/highstock.py b/highcharts/highstock/highstock.py index 70401c5..6ad132b 100644 --- a/highcharts/highstock/highstock.py +++ b/highcharts/highstock/highstock.py @@ -7,6 +7,7 @@ from jinja2 import Environment, PackageLoader import json, uuid +import re import datetime import html from collections import Iterable @@ -355,17 +356,19 @@ def htmlcontent(self): @property def iframe(self): htmlsrcdoc = html.escape(self.htmlcontent) + htmlsrcdoc = re.sub('\\n', ' ', htmlsrcdoc) + htmlsrcdoc = re.sub(' +', ' ', htmlsrcdoc) width = int(self.options['chart'].__dict__['width']) if self.options['chart'].__dict__.get('width') else 820 height = int(self.options['chart'].__dict__['height']) if self.options['chart'].__dict__.get('height') else 520 if self.options['chart'].__dict__.get('options3d'): if len(htmlsrcdoc) < 99965000 : - return '' + return '' else: - return '' + return '' else: - return '' + return '' def __str__(self): """return htmlcontent""" From 005aba831e7e95e9bc1c0e4932e6809721bdc297 Mon Sep 17 00:00:00 2001 From: Hank Chu Date: Thu, 24 Mar 2016 16:33:41 +0800 Subject: [PATCH 11/35] add setOptions (lang and global options) capability --- examples/highmaps/Example1_geojson.py | 3 ++- highcharts/highcharts/highcharts.py | 4 ++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/examples/highmaps/Example1_geojson.py b/examples/highmaps/Example1_geojson.py index 75697b6..fe33e7c 100644 --- a/examples/highmaps/Example1_geojson.py +++ b/examples/highmaps/Example1_geojson.py @@ -129,4 +129,5 @@ H.set_map_source('http://www.highcharts.com/samples/data/jsonp.php?filename=germany.geo.json&callback=?', True) # set map data from the src (jsonp) -H.htmlcontent \ No newline at end of file +H.htmlcontent +H.save_file() \ No newline at end of file diff --git a/highcharts/highcharts/highcharts.py b/highcharts/highcharts/highcharts.py index e8ecbc0..55e3ebe 100644 --- a/highcharts/highcharts/highcharts.py +++ b/highcharts/highcharts/highcharts.py @@ -267,6 +267,10 @@ def set_options(self, option_type, option_dict, force_options=False): elif option_type == 'zAxis': self.options.update({'zAxis': zAxisOptions()}) self.options[option_type].update_dict(**option_dict) + + elif option_type in ["global" , "lang"]: + self.setOptions[option_type].update_dict(**option_dict) + else: self.options[option_type].update_dict(**option_dict) From 7e7925003ea518cf7c30b843bd7265a6426faa77 Mon Sep 17 00:00:00 2001 From: Hank Chu Date: Thu, 24 Mar 2016 16:35:48 +0800 Subject: [PATCH 12/35] add setOptions (lang and global options) capability --- highcharts/highcharts/highcharts.py | 5 +---- highcharts/highmaps/highmaps.py | 2 ++ highcharts/highstock/highstock.py | 2 ++ 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/highcharts/highcharts/highcharts.py b/highcharts/highcharts/highcharts.py index 55e3ebe..1748625 100644 --- a/highcharts/highcharts/highcharts.py +++ b/highcharts/highcharts/highcharts.py @@ -263,14 +263,11 @@ def set_options(self, option_type, option_dict, force_options=False): 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 == 'zAxis': self.options.update({'zAxis': zAxisOptions()}) self.options[option_type].update_dict(**option_dict) - - elif option_type in ["global" , "lang"]: + 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) diff --git a/highcharts/highmaps/highmaps.py b/highcharts/highmaps/highmaps.py index fce007d..f7a4ce9 100644 --- a/highcharts/highmaps/highmaps.py +++ b/highcharts/highmaps/highmaps.py @@ -328,6 +328,8 @@ def set_options(self, option_type, option_dict, force_options=False): elif option_type == 'colorAxis': self.options.update({'colorAxis': self.options.get('colorAxis', ColorAxisOptions())}) self.options[option_type].update_dict(**option_dict) + elif option_type in ["global" , "lang"]: + self.setOptions[option_type].update_dict(**option_dict) else: self.options[option_type].update_dict(**option_dict) diff --git a/highcharts/highstock/highstock.py b/highcharts/highstock/highstock.py index 6ad132b..589a929 100644 --- a/highcharts/highstock/highstock.py +++ b/highcharts/highstock/highstock.py @@ -270,6 +270,8 @@ def set_options(self, option_type, option_dict, force_options=False): 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.setOptions[option_type].update_dict(**option_dict) else: self.options[option_type].update_dict(**option_dict) From 75305605d7b91fa1ae5e7d89427c5ad93b32e61d Mon Sep 17 00:00:00 2001 From: Hank Chu Date: Thu, 24 Mar 2016 16:38:24 +0800 Subject: [PATCH 13/35] remove save_file in highmap example1 --- examples/highmaps/Example1_geojson.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/examples/highmaps/Example1_geojson.py b/examples/highmaps/Example1_geojson.py index fe33e7c..75697b6 100644 --- a/examples/highmaps/Example1_geojson.py +++ b/examples/highmaps/Example1_geojson.py @@ -129,5 +129,4 @@ H.set_map_source('http://www.highcharts.com/samples/data/jsonp.php?filename=germany.geo.json&callback=?', True) # set map data from the src (jsonp) -H.htmlcontent -H.save_file() \ No newline at end of file +H.htmlcontent \ No newline at end of file From ef0ba314c1338560b89add348037908a6e14d1c2 Mon Sep 17 00:00:00 2001 From: Hank Chu Date: Sat, 23 Apr 2016 19:32:52 -0400 Subject: [PATCH 14/35] update highcarts code to support highmaps and update jQuery to 1.9.1 for all modules --- highcharts/highcharts/common.py | 8 +++++ highcharts/highcharts/highcharts.py | 6 ++-- highcharts/highcharts/options.py | 48 ++++++++++++++++++++++++++++- highcharts/highmaps/highmaps.py | 2 +- highcharts/highstock/highstock.py | 2 +- 5 files changed, 61 insertions(+), 5 deletions(-) diff --git a/highcharts/highcharts/common.py b/highcharts/highcharts/common.py index fe780ba..611e00b 100644 --- a/highcharts/highcharts/common.py +++ b/highcharts/highcharts/common.py @@ -695,6 +695,14 @@ class Breaks(ArrayObject): "to": [int, float], } +class DataClasses(ArrayObject): + ALLOWED_OPTIONS = { + "color": (ColorObject, basestring, dict), + "from": [int, float], + "name": basestring, + "to": [int, float], + } + class Zones(ArrayObject): ALLOWED_OPTIONS = { "color": (ColorObject, basestring, dict), diff --git a/highcharts/highcharts/highcharts.py b/highcharts/highcharts/highcharts.py index 1748625..5d5ec2e 100644 --- a/highcharts/highcharts/highcharts.py +++ b/highcharts/highcharts/highcharts.py @@ -12,7 +12,7 @@ import datetime import html from collections import Iterable -from .options import BaseOptions, ChartOptions, \ +from .options import BaseOptions, ChartOptions, ColorAxisOptions, \ ColorsOptions, CreditsOptions, DrilldownOptions, ExportingOptions, \ GlobalOptions, LabelsOptions, LangOptions, \ LegendOptions, LoadingOptions, NavigationOptions, PaneOptions, \ @@ -62,9 +62,10 @@ def __init__(self, **kwargs): # set Javascript src, Highcharts lib needs to make sure it's up to date self.JSsource = [ - 'https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js', + 'https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js', 'https://code.highcharts.com/highcharts.js', 'https://code.highcharts.com/highcharts-more.js', + 'https://code.highcharts.com/modules/heatmap.js', 'https://code.highcharts.com/modules/exporting.js' ] @@ -109,6 +110,7 @@ def __init__(self, **kwargs): # Bind Base Classes to self self.options = { "chart": ChartOptions(), + "colorAxis" : ColorAxisOptions(), "colors": ColorsOptions(), "credits": CreditsOptions(), #"data": #NotImplemented diff --git a/highcharts/highcharts/options.py b/highcharts/highcharts/options.py index 85e7689..a5a86c1 100644 --- a/highcharts/highcharts/options.py +++ b/highcharts/highcharts/options.py @@ -4,7 +4,7 @@ from .highchart_types import OptionTypeError, Series, SeriesOptions from .common import Formatter, Events, Position, ContextButton, Options3d, ResetZoomButton, \ DrillUpButton, Labels, PlotBands, PlotLines, Title, Items, Navigation, Background, Breaks, \ - DateTimeLabelFormats, Zones, Levels, \ + DataClasses, DateTimeLabelFormats, Zones, Levels, Marker, \ JSfunction, ColorObject, CSSObject, SVGObject, CommonObject, ArrayObject import json, datetime @@ -153,6 +153,52 @@ class ChartOptions(BaseOptions): } +class ColorAxisOptions(BaseOptions): + ALLOWED_OPTIONS = { + "dataClassColor": basestring, + "dataClasses": (DataClasses, dict), + "endOnTick": bool, + "events": (Events, dict), + "gridLineColor": (ColorObject, basestring, dict), + "gridLineDashStyle": basestring, + "gridLineWidth": [float, int], + "id": basestring, + "labels": (Labels, dict), + "lineColor": (ColorObject, basestring, dict), + "lineWidth": [float, int], + "marker": (Marker, dict), + "max": [float, int], + "maxColor": (ColorObject, basestring, dict), + "maxPadding": [float, int], + "min": [float, int], + "minColor": (ColorObject, basestring, dict), + "minPadding": [float, int], + "minorGridLineColor": (ColorObject, basestring, dict), + "minorGridLineDashStyle": basestring, + "minorGridLineWidth": int, + "minorTickColor": (ColorObject, basestring, dict), + "minorTickInterval": int, + "minorTickLength": int, + "minorTickPosition": basestring, + "minorTickWidth": int, + "reversed": bool, + "showFirstLabel": bool, + "showLastLabel": bool, + "startOfWeek": int, + "startOnTick": bool, + "stops": list, + "tickColor": (ColorObject, basestring, dict), + "tickInterval": int, + "tickLength": int, + "tickPixelInterval": int, + "tickPosition": basestring, + "tickPositioner": JSfunction, + "tickPositions": list, + "tickWidth": int, + "type": basestring, +} + + class ColorsOptions(BaseOptions): """ Special Case, this is simply just an array of colours """ def __init__(self): diff --git a/highcharts/highmaps/highmaps.py b/highcharts/highmaps/highmaps.py index f7a4ce9..8ccfc36 100644 --- a/highcharts/highmaps/highmaps.py +++ b/highcharts/highmaps/highmaps.py @@ -65,7 +65,7 @@ def __init__(self, **kwargs): # Set Javascript src self.JSsource = [ - 'https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js', + 'https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js', 'https://code.highcharts.com/maps/highmaps.js', 'https://code.highcharts.com/highcharts.js', 'https://code.highcharts.com/maps/modules/map.js', diff --git a/highcharts/highstock/highstock.py b/highcharts/highstock/highstock.py index 589a929..9a04af2 100644 --- a/highcharts/highstock/highstock.py +++ b/highcharts/highstock/highstock.py @@ -61,7 +61,7 @@ def __init__(self, **kwargs): # set Javascript src, Highcharts lib needs to make sure it's up to date self.JSsource = [ - 'https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.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', From e8063e49c7418a5c8bd4200f1504acf7c041ca33 Mon Sep 17 00:00:00 2001 From: ayamahmod Date: Fri, 8 Jul 2016 23:09:03 +0200 Subject: [PATCH 15/35] Update highcharts.py --- highcharts/highcharts/highcharts.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/highcharts/highcharts/highcharts.py b/highcharts/highcharts/highcharts.py index 5d5ec2e..0b7a5a3 100644 --- a/highcharts/highcharts/highcharts.py +++ b/highcharts/highcharts/highcharts.py @@ -110,7 +110,7 @@ def __init__(self, **kwargs): # Bind Base Classes to self self.options = { "chart": ChartOptions(), - "colorAxis" : ColorAxisOptions(), + #"colorAxis" : ColorAxisOptions(), "colors": ColorsOptions(), "credits": CreditsOptions(), #"data": #NotImplemented @@ -270,6 +270,9 @@ def set_options(self, option_type, option_dict, force_options=False): self.options[option_type].update_dict(**option_dict) elif option_type in ["global" , "lang"]: #Highcharts.setOptions: self.setOptions[option_type].update_dict(**option_dict) + elif option_type == 'colorAxis': + self.options.update({'colorAxis': ColorAxisOptions()}) + self.options[option_type].update_dict(**option_dict) else: self.options[option_type].update_dict(**option_dict) From 14455310216546c17374cf5a53bce559f71d1bbe Mon Sep 17 00:00:00 2001 From: ayamahmod Date: Fri, 8 Jul 2016 23:24:38 +0200 Subject: [PATCH 16/35] Update common.py --- highcharts/highcharts/common.py | 1 + 1 file changed, 1 insertion(+) diff --git a/highcharts/highcharts/common.py b/highcharts/highcharts/common.py index 611e00b..0be82af 100644 --- a/highcharts/highcharts/common.py +++ b/highcharts/highcharts/common.py @@ -568,6 +568,7 @@ class Hover(CommonObject): "marker": (Marker, dict), "radius": int, "radiusPlus": int, + "color": (ColorObject, basestring, dict), } class States(CommonObject): From b10d90400cfb859d92c7419c86bd6b71b3f3cec0 Mon Sep 17 00:00:00 2001 From: Kyle Solan Date: Sun, 30 Oct 2016 19:58:27 -0700 Subject: [PATCH 17/35] incremented version to v0.3.0 --- highcharts/version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/highcharts/version.py b/highcharts/version.py index 05e0870..d5456c8 100644 --- a/highcharts/version.py +++ b/highcharts/version.py @@ -1,6 +1,6 @@ version_info = ( "0", - "2", + "3", "0" ) From bc8a112a605e57a40f74982cf7363da7962ef3b1 Mon Sep 17 00:00:00 2001 From: Kyle Solan Date: Sun, 30 Oct 2016 20:08:27 -0700 Subject: [PATCH 18/35] added manifest --- MANIFEST.in | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 MANIFEST.in diff --git a/MANIFEST.in b/MANIFEST.in new file mode 100644 index 0000000..a6b8dc8 --- /dev/null +++ b/MANIFEST.in @@ -0,0 +1,6 @@ +include MANIFEST.in +include LICENSE + +graft tests + +global-exclude *.py[co] From 39769b71918b0f510f3f9ad4c364d369c4a06089 Mon Sep 17 00:00:00 2001 From: Kyle Solan Date: Sun, 30 Oct 2016 20:24:41 -0700 Subject: [PATCH 19/35] fixed #17 --- highcharts/highcharts/highchart_types.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/highcharts/highcharts/highchart_types.py b/highcharts/highcharts/highchart_types.py index 09817af..4a255b1 100644 --- a/highcharts/highcharts/highchart_types.py +++ b/highcharts/highcharts/highchart_types.py @@ -479,6 +479,7 @@ "selected": bool, "sliced": bool, "showInLegend": bool, + "stack": basestring, "type": basestring, "visible": bool, "x": [int, float], @@ -617,7 +618,7 @@ def __getattr__(self,item): class Series(object): """Series class for input data """ - def __init__(self,data,series_type="line",supress_errors=False,**kwargs): + def __init__(self, data, series_type="line", supress_errors=False, **kwargs): # List of dictionaries. Each dict contains data and properties, # which need to handle before construct the object for series From c3dde65c8903db72d86e20832e110600745aa8f0 Mon Sep 17 00:00:00 2001 From: Kyle Solan Date: Sun, 30 Oct 2016 20:27:03 -0700 Subject: [PATCH 20/35] fixed #16 --- highcharts/highstock/options.py | 1 + 1 file changed, 1 insertion(+) diff --git a/highcharts/highstock/options.py b/highcharts/highstock/options.py index 18fa235..7b47e2a 100644 --- a/highcharts/highstock/options.py +++ b/highcharts/highstock/options.py @@ -301,6 +301,7 @@ class PlotOptions(BaseOptions): "arearange": (SeriesOptions, dict), "areaspline": (SeriesOptions, dict), "areasplinerange": (SeriesOptions, dict), + "candlestick": (SeriesOptions, dict), "column": (SeriesOptions, dict), "columnrange": (SeriesOptions, dict), "flags": (SeriesOptions, dict), From ec063f966bfe7c392190417bf399714bd75e1ba7 Mon Sep 17 00:00:00 2001 From: Kyle Solan Date: Tue, 1 Nov 2016 21:09:31 -0700 Subject: [PATCH 21/35] added heatmap example --- examples/highcharts/heatmap.py | 107 ++++++++++++++++ examples/ipynb/highcharts/heatmap.ipynb | 159 ++++++++++++++++++++++++ tests/test_highcharts.py | 5 +- 3 files changed, 270 insertions(+), 1 deletion(-) create mode 100644 examples/highcharts/heatmap.py create mode 100644 examples/ipynb/highcharts/heatmap.ipynb diff --git a/examples/highcharts/heatmap.py b/examples/highcharts/heatmap.py new file mode 100644 index 0000000..338134b --- /dev/null +++ b/examples/highcharts/heatmap.py @@ -0,0 +1,107 @@ +# -*- coding: utf-8 -*- +""" +Highcharts Demos +Heatmap: http://www.highcharts.com/demo/heatmap +""" +from highcharts import Highchart +H = Highchart() + +data = [ + [0, 0, 10], + [0, 1, 19], + [0, 2, 8], + [0, 3, 24], + [0, 4, 67], + [1, 0, 92], + [1, 1, 58], + [1, 2, 78], + [1, 3, 117], + [1, 4, 48], + [2, 0, 35], + [2, 1, 15], + [2, 2, 123], + [2, 3, 64], + [2, 4, 52], + [3, 0, 72], + [3, 1, 132], + [3, 2, 114], + [3, 3, 19], + [3, 4, 16], + [4, 0, 38], + [4, 1, 5], + [4, 2, 8], + [4, 3, 117], + [4, 4, 115], + [5, 0, 88], + [5, 1, 32], + [5, 2, 12], + [5, 3, 6], + [5, 4, 120], + [6, 0, 13], + [6, 1, 44], + [6, 2, 88], + [6, 3, 98], + [6, 4, 96], + [7, 0, 31], + [7, 1, 1], + [7, 2, 82], + [7, 3, 32], + [7, 4, 30], + [8, 0, 85], + [8, 1, 97], + [8, 2, 123], + [8, 3, 64], + [8, 4, 84], + [9, 0, 47], + [9, 1, 114], + [9, 2, 31], + [9, 3, 48], + [9, 4, 91] +] + +H.add_data_set(data, ) + +H.set_options('chart', { + 'type': 'heatmap', + 'marginTop': 40, + 'marginBottom': 80, + 'plotBorderWidth': 1 +}) + +H.set_options('xAxis', { + 'categories': + ['Alexander', 'Marie', 'Maximilian', 'Sophia', 'Lukas', 'Maria', 'Leon', 'Anna', 'Tim', 'Laura'] +}) + +H.set_options('yAxis', { + 'categories': ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday'], + 'title': None +}) + +H.set_options('title', { + 'text': "Sales per employee per weekday" +}) + +H.set_options('colorAxis', { + 'min': 0, + 'minColor': '#FFFFFF', + 'maxColor': '#7CB5EC' +}) + +H.set_options('legend', { + 'align': 'right', + 'layout': 'vertical', + 'margin': 0, + 'verticalAlign': 'top', + 'y': 25, + 'symbolHeight': 280 +}) + +H.set_options('tooltip', { + 'formatter': "function () {" + + "return '' + this.series.xAxis.categories[this.point.x] + ' sold
' +" + + "this.point.value + ' items on
' + this.series.yAxis.categories[this.point.y] + '';" + + "}" +}) + +H.htmlcontent \ No newline at end of file diff --git a/examples/ipynb/highcharts/heatmap.ipynb b/examples/ipynb/highcharts/heatmap.ipynb new file mode 100644 index 0000000..9fd0880 --- /dev/null +++ b/examples/ipynb/highcharts/heatmap.ipynb @@ -0,0 +1,159 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 8, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/html": [ + "" + ], + "text/plain": [ + "" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# -*- coding: utf-8 -*-\n", + "\"\"\"\n", + "Highcharts Demos\n", + "Heatmap: http://www.highcharts.com/demo/heatmap\n", + "\"\"\"\n", + "from highcharts import Highchart\n", + "H = Highchart()\n", + "\n", + "data = [\n", + " [0, 0, 10],\n", + " [0, 1, 19],\n", + " [0, 2, 8],\n", + " [0, 3, 24],\n", + " [0, 4, 67],\n", + " [1, 0, 92],\n", + " [1, 1, 58],\n", + " [1, 2, 78],\n", + " [1, 3, 117],\n", + " [1, 4, 48],\n", + " [2, 0, 35],\n", + " [2, 1, 15],\n", + " [2, 2, 123],\n", + " [2, 3, 64],\n", + " [2, 4, 52],\n", + " [3, 0, 72],\n", + " [3, 1, 132],\n", + " [3, 2, 114],\n", + " [3, 3, 19],\n", + " [3, 4, 16],\n", + " [4, 0, 38],\n", + " [4, 1, 5],\n", + " [4, 2, 8],\n", + " [4, 3, 117],\n", + " [4, 4, 115],\n", + " [5, 0, 88],\n", + " [5, 1, 32],\n", + " [5, 2, 12],\n", + " [5, 3, 6],\n", + " [5, 4, 120],\n", + " [6, 0, 13],\n", + " [6, 1, 44],\n", + " [6, 2, 88],\n", + " [6, 3, 98],\n", + " [6, 4, 96],\n", + " [7, 0, 31],\n", + " [7, 1, 1],\n", + " [7, 2, 82],\n", + " [7, 3, 32],\n", + " [7, 4, 30],\n", + " [8, 0, 85],\n", + " [8, 1, 97],\n", + " [8, 2, 123],\n", + " [8, 3, 64],\n", + " [8, 4, 84],\n", + " [9, 0, 47],\n", + " [9, 1, 114],\n", + " [9, 2, 31],\n", + " [9, 3, 48],\n", + " [9, 4, 91]\n", + "]\n", + "\n", + "H.add_data_set(data, series_type='heatmap', borderWidth=1, dataLabels={\n", + " 'enabled': True,\n", + " 'color': '#000000'\n", + "})\n", + "\n", + "H.set_options('chart', {\n", + " 'type': 'heatmap',\n", + " 'marginTop': 40,\n", + " 'marginBottom': 80,\n", + " 'plotBorderWidth': 1\n", + "})\n", + "\n", + "H.set_options('xAxis', {\n", + " 'categories': \n", + " ['Alexander', 'Marie', 'Maximilian', 'Sophia', 'Lukas', 'Maria', 'Leon', 'Anna', 'Tim', 'Laura']\n", + "})\n", + "\n", + "H.set_options('yAxis', {\n", + " 'categories': ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday'],\n", + " 'title': None\n", + "})\n", + "\n", + "H.set_options('title', {\n", + " 'text': \"Sales per employee per weekday\"\n", + "})\n", + "\n", + "H.set_options('colorAxis', {\n", + " 'min': 0,\n", + " 'minColor': '#FFFFFF',\n", + " 'maxColor': '#7CB5EC'\n", + "})\n", + "\n", + "H.set_options('legend', {\n", + " 'align': 'right',\n", + " 'layout': 'vertical',\n", + " 'margin': 0,\n", + " 'verticalAlign': 'top',\n", + " 'y': 25,\n", + " 'symbolHeight': 280\n", + "})\n", + "\n", + "H.set_options('tooltip', {\n", + " 'formatter': \"function () {\" + \n", + " \"return '' + this.series.xAxis.categories[this.point.x] + ' sold
' +\" +\n", + " \"this.point.value + ' items on
' + this.series.yAxis.categories[this.point.y] + '';\" +\n", + " \"}\"\n", + "})\n", + "\n", + "H" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.5.1" + } + }, + "nbformat": 4, + "nbformat_minor": 1 +} diff --git a/tests/test_highcharts.py b/tests/test_highcharts.py index 6d6628c..a3882e6 100644 --- a/tests/test_highcharts.py +++ b/tests/test_highcharts.py @@ -56,6 +56,9 @@ def test_Example1(self): execfile(os.path.join(self.PATH_ROOT, 'Example1.py')) os.remove("highcharts.html") + def test_error_bar(self): + execfile(os.path.join(self.PATH_ROOT, 'heatmap.py')) + def test_line_time_series(self): execfile(os.path.join(self.PATH_ROOT, 'line-time-series.py')) @@ -82,4 +85,4 @@ def test_spline_symbols(self): def test_treemap_levels(self): execfile(os.path.join(self.PATH_ROOT, 'treemap-levels.py')) - \ No newline at end of file + From f05885418b44b8e2302097ce21fb91d1572d0773 Mon Sep 17 00:00:00 2001 From: Kyle Solan Date: Tue, 1 Nov 2016 21:18:32 -0700 Subject: [PATCH 22/35] incremented version v0.3.1 --- highcharts/version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/highcharts/version.py b/highcharts/version.py index d5456c8..37fbd6a 100644 --- a/highcharts/version.py +++ b/highcharts/version.py @@ -1,7 +1,7 @@ version_info = ( "0", "3", - "0" + "1" ) __version__ = '.'.join(map(str, version_info)) From 6e49c80053accecd8b0878f6d3a819ff6cff0fef Mon Sep 17 00:00:00 2001 From: Kyle Solan Date: Tue, 1 Nov 2016 21:53:36 -0700 Subject: [PATCH 23/35] added spline-irregular-time example --- examples/highcharts/spline-irregular-time.py | 119 +++++++++++++ .../highcharts/spline-irregular-time.ipynb | 168 ++++++++++++++++++ tests/test_highcharts.py | 3 + 3 files changed, 290 insertions(+) create mode 100644 examples/highcharts/spline-irregular-time.py create mode 100644 examples/ipynb/highcharts/spline-irregular-time.ipynb diff --git a/examples/highcharts/spline-irregular-time.py b/examples/highcharts/spline-irregular-time.py new file mode 100644 index 0000000..7ad233f --- /dev/null +++ b/examples/highcharts/spline-irregular-time.py @@ -0,0 +1,119 @@ +# -*- coding: utf-8 -*- +""" +Highcharts Demos +Time data with irregular intervals: http://www.highcharts.com/demo/spline-irregular-time +""" +from datetime import datetime +from highcharts import Highchart +H = Highchart() + +winter_12_13_data = [ + [datetime(1970, 10, 21), 0], + [datetime(1970, 11, 4), 0.28], + [datetime(1970, 11, 9), 0.25], + [datetime(1970, 11, 27), 0.2], + [datetime(1970, 12, 2), 0.28], + [datetime(1970, 12, 26), 0.28], + [datetime(1970, 12, 29), 0.47], + [datetime(1971, 1, 11), 0.79], + [datetime(1971, 1, 26), 0.72], + [datetime(1971, 2, 3), 1.02], + [datetime(1971, 2, 11), 1.12], + [datetime(1971, 2, 25), 1.2], + [datetime(1971, 3, 11), 1.18], + [datetime(1971, 4, 11), 1.19], + [datetime(1971, 5, 1), 1.85], + [datetime(1971, 5, 5), 2.22], + [datetime(1971, 5, 19), 1.15], + [datetime(1971, 6, 3), 0] +] + +winter_13_14_data = [ + [datetime(1970, 10, 29), 0], + [datetime(1970, 11, 9), 0.4], + [datetime(1970, 12, 1), 0.25], + [datetime(1971, 1, 1), 1.66], + [datetime(1971, 1, 10), 1.8], + [datetime(1971, 2, 19), 1.76], + [datetime(1971, 3, 25), 2.62], + [datetime(1971, 4, 19), 2.41], + [datetime(1971, 4, 30), 2.05], + [datetime(1971, 5, 14), 1.7], + [datetime(1971, 5, 24), 1.1], + [datetime(1971, 6, 10), 0] +] + +winter_14_15_data = [ + [datetime(1970, 11, 25), 0], + [datetime(1970, 12, 6), 0.25], + [datetime(1970, 12, 20), 1.41], + [datetime(1970, 12, 25), 1.64], + [datetime(1971, 1, 4), 1.6], + [datetime(1971, 1, 17), 2.55], + [datetime(1971, 1, 24), 2.62], + [datetime(1971, 2, 4), 2.5], + [datetime(1971, 2, 14), 2.42], + [datetime(1971, 3, 6), 2.74], + [datetime(1971, 3, 14), 2.62], + [datetime(1971, 3, 24), 2.6], + [datetime(1971, 4, 2), 2.81], + [datetime(1971, 4, 12), 2.63], + [datetime(1971, 4, 28), 2.77], + [datetime(1971, 5, 5), 2.68], + [datetime(1971, 5, 10), 2.56], + [datetime(1971, 5, 15), 2.39], + [datetime(1971, 5, 20), 2.3], + [datetime(1971, 6, 5), 2], + [datetime(1971, 6, 10), 1.85], + [datetime(1971, 6, 15), 1.49], + [datetime(1971, 6, 23), 1.08] +] + +H.add_data_set(winter_12_13_data, series_type="spline", name="Winter 2012-2013") +H.add_data_set(winter_13_14_data, series_type="spline", name="Winter 2013-2014") +H.add_data_set(winter_14_15_data, series_type="spline", name="Winter 2014-2015") + +H.set_options('chart', { + 'type': 'spline' +}) + +H.set_options('xAxis', { + 'type': 'datetime', + 'dateTimeLabelFormats': { # don't display the dummy year + 'month': '%e. %b', + 'year': '%b' + }, + 'title': { + 'text': 'Date' + } +}) + +H.set_options('yAxis', { + 'title': { + 'text': 'Snow depth (m)' + }, + 'min': 0 +}) + +H.set_options('title', { + 'text': "Snow depth at Vikjafjellet, Norway" +}) + +H.set_options('subtitle', { + 'text': "Irregular time data in Highcharts JS" +}) + +H.set_options('tooltip', { + 'headerFormat': '{series.name}
', + 'pointFormat': '{point.x:%e. %b}: {point.y:.2f} m' +}) + +H.set_options('plotOptions', { + 'spline': { + 'marker': { + 'enabled': True + } + } +}) + +H.htmlcontent \ No newline at end of file diff --git a/examples/ipynb/highcharts/spline-irregular-time.ipynb b/examples/ipynb/highcharts/spline-irregular-time.ipynb new file mode 100644 index 0000000..0b1139a --- /dev/null +++ b/examples/ipynb/highcharts/spline-irregular-time.ipynb @@ -0,0 +1,168 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 4, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/html": [ + "" + ], + "text/plain": [ + "" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# -*- coding: utf-8 -*-\n", + "\"\"\"\n", + "Highcharts Demos\n", + "Time data with irregular intervals: http://www.highcharts.com/demo/spline-irregular-time\n", + "\"\"\"\n", + "from datetime import datetime\n", + "from highcharts import Highchart\n", + "H = Highchart()\n", + "\n", + "winter_12_13_data = [\n", + " [datetime(1970, 10, 21), 0],\n", + " [datetime(1970, 11, 4), 0.28],\n", + " [datetime(1970, 11, 9), 0.25],\n", + " [datetime(1970, 11, 27), 0.2],\n", + " [datetime(1970, 12, 2), 0.28],\n", + " [datetime(1970, 12, 26), 0.28],\n", + " [datetime(1970, 12, 29), 0.47],\n", + " [datetime(1971, 1, 11), 0.79],\n", + " [datetime(1971, 1, 26), 0.72],\n", + " [datetime(1971, 2, 3), 1.02],\n", + " [datetime(1971, 2, 11), 1.12],\n", + " [datetime(1971, 2, 25), 1.2],\n", + " [datetime(1971, 3, 11), 1.18],\n", + " [datetime(1971, 4, 11), 1.19],\n", + " [datetime(1971, 5, 1), 1.85],\n", + " [datetime(1971, 5, 5), 2.22],\n", + " [datetime(1971, 5, 19), 1.15],\n", + " [datetime(1971, 6, 3), 0]\n", + "]\n", + "\n", + "winter_13_14_data = [\n", + " [datetime(1970, 10, 29), 0],\n", + " [datetime(1970, 11, 9), 0.4],\n", + " [datetime(1970, 12, 1), 0.25],\n", + " [datetime(1971, 1, 1), 1.66],\n", + " [datetime(1971, 1, 10), 1.8],\n", + " [datetime(1971, 2, 19), 1.76],\n", + " [datetime(1971, 3, 25), 2.62],\n", + " [datetime(1971, 4, 19), 2.41],\n", + " [datetime(1971, 4, 30), 2.05],\n", + " [datetime(1971, 5, 14), 1.7],\n", + " [datetime(1971, 5, 24), 1.1],\n", + " [datetime(1971, 6, 10), 0]\n", + "]\n", + "\n", + "winter_14_15_data = [\n", + " [datetime(1970, 11, 25), 0],\n", + " [datetime(1970, 12, 6), 0.25],\n", + " [datetime(1970, 12, 20), 1.41],\n", + " [datetime(1970, 12, 25), 1.64],\n", + " [datetime(1971, 1, 4), 1.6],\n", + " [datetime(1971, 1, 17), 2.55],\n", + " [datetime(1971, 1, 24), 2.62],\n", + " [datetime(1971, 2, 4), 2.5],\n", + " [datetime(1971, 2, 14), 2.42],\n", + " [datetime(1971, 3, 6), 2.74],\n", + " [datetime(1971, 3, 14), 2.62],\n", + " [datetime(1971, 3, 24), 2.6],\n", + " [datetime(1971, 4, 2), 2.81],\n", + " [datetime(1971, 4, 12), 2.63],\n", + " [datetime(1971, 4, 28), 2.77],\n", + " [datetime(1971, 5, 5), 2.68],\n", + " [datetime(1971, 5, 10), 2.56],\n", + " [datetime(1971, 5, 15), 2.39],\n", + " [datetime(1971, 5, 20), 2.3],\n", + " [datetime(1971, 6, 5), 2],\n", + " [datetime(1971, 6, 10), 1.85],\n", + " [datetime(1971, 6, 15), 1.49],\n", + " [datetime(1971, 6, 23), 1.08]\n", + "]\n", + "\n", + "H.add_data_set(winter_12_13_data, series_type=\"spline\", name=\"Winter 2012-2013\")\n", + "H.add_data_set(winter_13_14_data, series_type=\"spline\", name=\"Winter 2013-2014\")\n", + "H.add_data_set(winter_14_15_data, series_type=\"spline\", name=\"Winter 2014-2015\")\n", + "\n", + "H.set_options('chart', {\n", + " 'type': 'spline'\n", + "})\n", + "\n", + "H.set_options('xAxis', {\n", + " 'type': 'datetime',\n", + " 'dateTimeLabelFormats': { # don't display the dummy year\n", + " 'month': '%e. %b',\n", + " 'year': '%b'\n", + " },\n", + " 'title': {\n", + " 'text': 'Date'\n", + " }\n", + "})\n", + "\n", + "H.set_options('yAxis', {\n", + " 'title': {\n", + " 'text': 'Snow depth (m)'\n", + " },\n", + " 'min': 0\n", + "})\n", + "\n", + "H.set_options('title', {\n", + " 'text': \"Snow depth at Vikjafjellet, Norway\"\n", + "})\n", + "\n", + "H.set_options('subtitle', {\n", + " 'text': \"Irregular time data in Highcharts JS\"\n", + "})\n", + "\n", + "H.set_options('tooltip', {\n", + " 'headerFormat': '{series.name}
',\n", + " 'pointFormat': '{point.x:%e. %b}: {point.y:.2f} m'\n", + "})\n", + "\n", + "H.set_options('plotOptions', {\n", + " 'spline': {\n", + " 'marker': {\n", + " 'enabled': True\n", + " }\n", + " }\n", + "})\n", + "\n", + "H" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.5.1" + } + }, + "nbformat": 4, + "nbformat_minor": 1 +} diff --git a/tests/test_highcharts.py b/tests/test_highcharts.py index a3882e6..bef8136 100644 --- a/tests/test_highcharts.py +++ b/tests/test_highcharts.py @@ -80,6 +80,9 @@ def test_scatter(self): def test_spline_inverted(self): execfile(os.path.join(self.PATH_ROOT, 'spline-inverted.py')) + def test_spline_irregular_time(self): + execfile(os.path.join(self.PATH_ROOT, 'spline-irregular-time.py')) + def test_spline_symbols(self): execfile(os.path.join(self.PATH_ROOT, 'spline-symbols.py')) From 8920a3bf4869ff27a91ca8eae8febf812b514dab Mon Sep 17 00:00:00 2001 From: Kyle Solan Date: Tue, 1 Nov 2016 22:08:21 -0700 Subject: [PATCH 24/35] added build badge --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 9e53f5a..c57b75b 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# python-highcharts +# python-highcharts [![CircleCI](https://circleci.com/gh/kyper-data/python-highcharts.svg?style=svg)](https://circleci.com/gh/kyper-data/python-highcharts) ## License @@ -10,13 +10,13 @@ However, please be aware that the Highcharts project itself, as well as Highmaps python-highcharts is a simple translation layer between Python and Javascript for Highcharts projects (highcharts, highmaps, and highstocks). -In addition, python-highcharts integrates with [Jupyter/IPython notebook](https://github.com/jupyter/notebook), which enables you to render Highcharts, Highmaps, and Highstock visualizations directly in notebooks. See examples [here](https://github.com/kyper-data/python-highcharts/tree/developer/examples/ipynb). +In addition, python-highcharts integrates with [Jupyter notebook](https://github.com/jupyter/notebook), which enables you to render Highcharts, Highmaps, and Highstock visualizations directly in notebooks. See examples [here](https://github.com/kyper-data/python-highcharts/tree/developer/examples/ipynb). The original framework was inspired by [python-nvd3](https://github.com/areski/python-nvd3) and [PyHighcharts](https://github.com/fidyeates/PyHighcharts). ## Installation -python-highcharts supports Python 2.7/3.4 and is available on PyPI. To install: +python-highcharts supports Python 2.7/3.4+ and is available on PyPI. To install: ``` pip install python-highcharts ``` From d261025c44136b64c5af682f9ccfe900ef103aea Mon Sep 17 00:00:00 2001 From: eglenfield Date: Wed, 26 Apr 2017 16:38:40 +0100 Subject: [PATCH 25/35] Point event fix --- highcharts/highcharts/common.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/highcharts/highcharts/common.py b/highcharts/highcharts/common.py index 0be82af..02168d5 100644 --- a/highcharts/highcharts/common.py +++ b/highcharts/highcharts/common.py @@ -371,7 +371,7 @@ class Events(CommonObject): class Point(CommonObject): ALLOWED_OPTIONS = { - "events": Events + "events": (Events, dict) } class Position(CommonObject): From 5a84c12c08664e4c47bceb58dc4db7a193c77c45 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Borchmann?= Date: Wed, 28 Jun 2017 23:33:40 +0200 Subject: [PATCH 26/35] Update options.py Support of pointFormatter introduced in 4.1.0. --- highcharts/highcharts/options.py | 1 + 1 file changed, 1 insertion(+) diff --git a/highcharts/highcharts/options.py b/highcharts/highcharts/options.py index a5a86c1..d91b827 100644 --- a/highcharts/highcharts/options.py +++ b/highcharts/highcharts/options.py @@ -435,6 +435,7 @@ class TooltipOptions(BaseOptions): "formatter": (Formatter, JSfunction), "headerFormat": basestring, "pointFormat": basestring, + "pointFormatter": (Formatter, JSfunction), "positioner": (JSfunction, basestring), "shadow": bool, "shared": bool, From b021c049f81b3af747d84224d75d1e049e153322 Mon Sep 17 00:00:00 2001 From: smalawi Date: Fri, 14 Jul 2017 12:02:27 +0300 Subject: [PATCH 27/35] Fixed #29 --- highcharts/highcharts/highchart_types.py | 1 + 1 file changed, 1 insertion(+) diff --git a/highcharts/highcharts/highchart_types.py b/highcharts/highcharts/highchart_types.py index 4a255b1..c4d9f32 100644 --- a/highcharts/highcharts/highchart_types.py +++ b/highcharts/highcharts/highchart_types.py @@ -429,6 +429,7 @@ "cropThreshold": int, "dashStyle": basestring, "lineWidth": int, + "linkedTo": basestring, "marker": (Marker, dict), "pointInterval": int, "pointPlacement": [basestring, int, float], From ef2e290cc3d525162557becfddf18d6ac3bcbea8 Mon Sep 17 00:00:00 2001 From: adhiraj Date: Sun, 23 Jul 2017 22:44:25 -0700 Subject: [PATCH 28/35] Correct dashStyle option type The dashStyle param to plotLines takes a string (see http://api.highcharts.com/highcharts/yAxis.plotLines.dashStyle). --- highcharts/highcharts/common.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/highcharts/highcharts/common.py b/highcharts/highcharts/common.py index 0be82af..c9cea7f 100644 --- a/highcharts/highcharts/common.py +++ b/highcharts/highcharts/common.py @@ -662,7 +662,7 @@ class PlotBands(ArrayObject): class PlotLines(ArrayObject): ALLOWED_OPTIONS = { "color": (ColorObject, basestring, dict), - "dashStyle": int, + "dashStyle": basestring, "events": (Events, dict), "id": basestring, "label": (Labels, dict), From f122e5240db2fc1f2efe444a36be03caba6877af Mon Sep 17 00:00:00 2001 From: Lukas Vacek Date: Tue, 1 Aug 2017 22:36:32 +0200 Subject: [PATCH 29/35] offline mode --- highcharts/highcharts/highcharts.py | 34 ++++++++++++++++++++++++----- 1 file changed, 28 insertions(+), 6 deletions(-) diff --git a/highcharts/highcharts/highcharts.py b/highcharts/highcharts/highcharts.py index 0b7a5a3..e7c1ef6 100644 --- a/highcharts/highcharts/highcharts.py +++ b/highcharts/highcharts/highcharts.py @@ -10,6 +10,7 @@ import json, uuid import re import datetime +import urllib2 import html from collections import Iterable from .options import BaseOptions, ChartOptions, ColorAxisOptions, \ @@ -51,6 +52,9 @@ def __init__(self, **kwargs): This is the base class for all the charts. The following keywords are accepted: :keyword: **display_container** - default: ``True`` + **offline - default: ``False`` + If True, download all .js and .css file and put them + into the generated .html so it can be viewed offline. """ # set the model self.model = self.__class__.__name__ #: The chart model, @@ -59,6 +63,7 @@ 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 = [ @@ -74,6 +79,9 @@ def __init__(self, **kwargs): 'https://www.highcharts.com/highslide/highslide.css', ] + + self.offline = kwargs.get("offline", False) + # set data self.data = [] self.data_temp = [] @@ -323,13 +331,27 @@ def buildhtmlheader(self): if self.drilldown_flag: self.add_JSsource('http://code.highcharts.com/modules/drilldown.js') - self.header_css = [ - '' % h for h in self.CSSsource - ] - self.header_js = [ - '' % h for h in self.JSsource - ] + + if self.offline: + opener = urllib2.build_opener() + opener.addheaders = [('User-Agent', 'Mozilla/5.0')] + + self.header_css = [ + '' % opener.open(h).read() for h in self.CSSsource + ] + + self.header_js = [ + '' % opener.open(h).read() for h in self.JSsource + ] + else: + self.header_css = [ + '' % h for h in self.CSSsource + ] + + self.header_js = [ + '' % h for h in self.JSsource + ] self.htmlheader = '' for css in self.header_css: From 354221ff2083dfa8848486b90c97ef3b4755f0ac Mon Sep 17 00:00:00 2001 From: othalan Date: Wed, 13 Dec 2017 11:43:48 -0700 Subject: [PATCH 30/35] Update urllib2 to python3 version, relying on the already available 'future' package to provide the appropriate alias for use in python2 (#41) --- highcharts/highcharts/highcharts.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/highcharts/highcharts/highcharts.py b/highcharts/highcharts/highcharts.py index e7c1ef6..e99df62 100644 --- a/highcharts/highcharts/highcharts.py +++ b/highcharts/highcharts/highcharts.py @@ -10,7 +10,7 @@ import json, uuid import re import datetime -import urllib2 +import urllib.request, urllib.error, urllib.parse import html from collections import Iterable from .options import BaseOptions, ChartOptions, ColorAxisOptions, \ @@ -334,7 +334,7 @@ def buildhtmlheader(self): if self.offline: - opener = urllib2.build_opener() + opener = urllib.request.build_opener() opener.addheaders = [('User-Agent', 'Mozilla/5.0')] self.header_css = [ From d59f9f8feb948a99415621ac43ff830ae03f39ab Mon Sep 17 00:00:00 2001 From: othalan Date: Wed, 13 Dec 2017 11:45:02 -0700 Subject: [PATCH 31/35] Stock logarithmic (#40) * Permit type yAxis option used for setting logarithmic scale * Add comment string noting the reason for adding an undocumented keyword. * Fix typo in 'type' datatype --- highcharts/highstock/options.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/highcharts/highstock/options.py b/highcharts/highstock/options.py index 7b47e2a..4a21318 100644 --- a/highcharts/highstock/options.py +++ b/highcharts/highstock/options.py @@ -542,6 +542,11 @@ class yAxisOptions(BaseOptions): "tickmarkPlacement": basestring, "title": (Title, dict), "top": [int, float, basestring], + # DEM 2017/11/16: Note that the 'type' keyword for highstock is + # undocumented yet appears to be supported, likely because of underlying + # shared code. This permits logarithmic Y-Axis scale which is + # frequently useful in stock charts. + "type": basestring, "units": list } From 64567828591a3d5786a23066d9f4bfc312bf9dd7 Mon Sep 17 00:00:00 2001 From: othalan Date: Tue, 19 Dec 2017 04:31:08 +0000 Subject: [PATCH 32/35] JSONP multisource support (#42) * Add multiple JSONP data sources, assuming all data comes from JSONP * Add array version of data definition for improving the jinja2 template * Fix bug in Highchart add jsonp url * Apply multi-source JSONP code to highcharts * Update inline comments for clarity and accuracy * Update variable name to 'data_list' as per request for style consistency --- highcharts/highcharts/highchart_types.py | 31 ++++++------- highcharts/highcharts/highcharts.py | 31 ++++++++----- highcharts/highcharts/templates/content.html | 40 ++++++++++------- highcharts/highstock/highstock.py | 10 ++++- highcharts/highstock/templates/content.html | 46 ++++++++++++-------- highcharts/highstock/templates/page.html | 1 + 6 files changed, 99 insertions(+), 60 deletions(-) diff --git a/highcharts/highcharts/highchart_types.py b/highcharts/highcharts/highchart_types.py index c4d9f32..c8c241d 100644 --- a/highcharts/highcharts/highchart_types.py +++ b/highcharts/highcharts/highchart_types.py @@ -623,22 +623,23 @@ def __init__(self, data, series_type="line", supress_errors=False, **kwargs): # List of dictionaries. Each dict contains data and properties, # which need to handle before construct the object for series - for item in data: - if isinstance(item, dict): - for k, v in item.items(): - if k in DATA_SERIES_ALLOWED_OPTIONS: - if SeriesOptions.__validate_options__(k,v,DATA_SERIES_ALLOWED_OPTIONS[k]): - if isinstance(DATA_SERIES_ALLOWED_OPTIONS[k], tuple): - if isinstance(v, dict): - item.update({k:DATA_SERIES_ALLOWED_OPTIONS[k][0](**v)}) - elif isinstance(v, CommonObject) or isinstance(v, ArrayObject) or \ - isinstance(v, CSSObject) or isinstance(v, SVGObject) or isinstance(v, ColorObject) or \ - isinstance(v, JSfunction) or isinstance(v, Formatter) or isinstance(v, datetime.datetime): - item.update({k:v}) + if isinstance(data, list): + for item in data: + if isinstance(item, dict): + for k, v in item.items(): + if k in DATA_SERIES_ALLOWED_OPTIONS: + if SeriesOptions.__validate_options__(k,v,DATA_SERIES_ALLOWED_OPTIONS[k]): + if isinstance(DATA_SERIES_ALLOWED_OPTIONS[k], tuple): + if isinstance(v, dict): + item.update({k:DATA_SERIES_ALLOWED_OPTIONS[k][0](**v)}) + elif isinstance(v, CommonObject) or isinstance(v, ArrayObject) or \ + isinstance(v, CSSObject) or isinstance(v, SVGObject) or isinstance(v, ColorObject) or \ + isinstance(v, JSfunction) or isinstance(v, Formatter) or isinstance(v, datetime.datetime): + item.update({k:v}) + else: + item.update({k:DATA_SERIES_ALLOWED_OPTIONS[k][0](v)}) else: - item.update({k:DATA_SERIES_ALLOWED_OPTIONS[k][0](v)}) - else: - item.update({k:v}) + item.update({k:v}) self.__dict__.update({ "data": data, diff --git a/highcharts/highcharts/highcharts.py b/highcharts/highcharts/highcharts.py index e99df62..7b5dde2 100644 --- a/highcharts/highcharts/highcharts.py +++ b/highcharts/highcharts/highcharts.py @@ -87,11 +87,12 @@ def __init__(self, **kwargs): self.data_temp = [] # Data from jsonp self.jsonp_data_flag = False + self.jsonp_data_url_list = [] # DEM 2017/07/27: List of JSON data sources # set drilldown data self.drilldown_data = [] self.drilldown_data_temp = [] - + # javascript self.jscript_head_flag = False self.jscript_head = kwargs.get('jscript_head', None) @@ -220,10 +221,10 @@ def add_drilldown_data_set(self, data, series_type, id, **kwargs): self.drilldown_data_set_count += 1 if self.drilldown_flag == False: self.drilldown_flag = True - + kwargs.update({'id':id}) series_data = Series(data, series_type=series_type, **kwargs) - + series_data.__options__().update(SeriesOptions(series_type=series_type, **kwargs).__options__()) self.drilldown_data_temp.append(series_data) @@ -233,12 +234,17 @@ def add_data_from_jsonp(self, data_src, data_name='json_data', series_type="line the data_src is the https link for data and it must be in jsonp format """ - self.jsonp_data_flag = True - self.jsonp_data_url = json.dumps(data_src) - if data_name == 'data': - data_name = 'json_'+ data_name - self.jsonp_data = data_name + 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(data_name), series_type, name=name, **kwargs) + # DEM 2017/07/27: 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_JSscript(self, js_script, js_loc): @@ -305,9 +311,14 @@ def buildcontent(self): self.buildcontainer() self.option = json.dumps(self.options, cls = HighchartsEncoder) - self.setoption = json.dumps(self.setOptions, 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.drilldown_flag: self.drilldown_data = json.dumps(self.drilldown_data_temp, cls = HighchartsEncoder) self._htmlcontent = self.template_content_highcharts.render(chart=self).encode('utf-8') diff --git a/highcharts/highcharts/templates/content.html b/highcharts/highcharts/templates/content.html index 64e3e86..b92181e 100644 --- a/highcharts/highcharts/templates/content.html +++ b/highcharts/highcharts/templates/content.html @@ -5,19 +5,14 @@ {% block body_head %} - {% if chart.jsonp_data_flag %} - $.getJSON({{chart.jsonp_data_url}}, function ({{chart.jsonp_data}}) - { - {% endif %} + {% if chart.jscript_head_flag %} + {{chart.jscript_head}} + {% endif %} {% endblock body_head %} {% block body_content %} - {% if chart.jscript_head_flag %} - {{chart.jscript_head}} - {% endif %} - Highcharts.setOptions({{chart.setoption}}); var option = {{chart.option}}; @@ -25,9 +20,6 @@ var geojson = {{chart.mapdata}} {% endif %} - var data = {{chart.data}}; - option.series = data; - {% if chart.drilldown_flag %} var drilldowndata = {{chart.drilldown_data}}; option.drilldown.series = drilldowndata; @@ -35,6 +27,26 @@ var chart = new Highcharts.Chart(option); + {# DEM 2017/07/27: Use a list of JSONP data sources + {# DEM 2017/07/27: This implementation is limited and could easily be improved! #} + {% if chart.jsonp_data_flag %} + {% for data_url in chart.jsonp_data_url_list %} + + $.getJSON({{data_url}}, function ({{chart.jsonp_data}}) + { + chart.addSeries({{chart.data_list[loop.index0]}}); + }); + + {% endfor %} + {% else %} + var data = {{chart.data}}; + var dataLen = data.length; + for (var ix = 0; ix < dataLen; ix++) { + chart.addSeries(data[ix]); + } + {% endif %} + + {% if chart.jscript_end_flag %} {{chart.jscript_end}} {% endif %} @@ -73,8 +85,4 @@ {% block body_end %} - {% if chart.jsonp_data_flag %} - }); - {% endif %} - -{% endblock body_end %} \ No newline at end of file +{% endblock body_end %} diff --git a/highcharts/highstock/highstock.py b/highcharts/highstock/highstock.py index 9a04af2..659d032 100644 --- a/highcharts/highstock/highstock.py +++ b/highcharts/highstock/highstock.py @@ -83,6 +83,7 @@ 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 # javascript self.jscript_head_flag = False @@ -206,13 +207,15 @@ def add_data_from_jsonp(self, data_src, data_name='json_data', series_type="line """ if not self.jsonp_data_flag: self.jsonp_data_flag = True - self.jsonp_data_url = json.dumps(data_src) 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) + # 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): @@ -294,6 +297,11 @@ def buildcontent(self): 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) diff --git a/highcharts/highstock/templates/content.html b/highcharts/highstock/templates/content.html index 4eade17..54615ba 100644 --- a/highcharts/highstock/templates/content.html +++ b/highcharts/highstock/templates/content.html @@ -5,25 +5,17 @@ {% block body_head %} - {% if chart.jsonp_data_flag %} - $.getJSON({{chart.jsonp_data_url}}, function ({{chart.jsonp_data}}) - { - {% endif %} + {% if chart.jscript_head_flag %} + {{chart.jscript_head}} + {% endif %} {% endblock body_head %} {% block body_content %} - {% if chart.jscript_head_flag %} - {{chart.jscript_head}} - {% endif %} - Highcharts.setOptions({{chart.setoption}}); var option = {{chart.option}}; - var data = {{chart.data}}; - option.series = data; - {% if chart.navi_seri_flag %} var navi_data = {{chart.navi_seri}} option.navigator.series = navi_data; @@ -31,16 +23,34 @@ var chart = new Highcharts.StockChart(option); - {% if chart.jscript_end_flag %} - {{chart.jscript_end}} - {% endif %} + + {# DEM 2017/04/25: Use a list of JSONP data sources + {# DEM 2017/07/27: This implementation is limited and could easily be improved! #} + {% if chart.jsonp_data_flag %} + {% for data_url in chart.jsonp_data_url_list %} + + $.getJSON({{data_url}}, function ({{chart.jsonp_data}}) + { + chart.addSeries({{chart.data_list[loop.index0]}}); + }); + + {% endfor %} + {% else %} + + var data = {{chart.data}}; + var dataLen = data.length; + for (var ix = 0; ix < dataLen; ix++) { + chart.addSeries(data[ix]); + } + + {% endif %} {% endblock body_content %} {% block body_end %} - {% if chart.jsonp_data_flag %} - }); - {% endif %} + {% if chart.jscript_end_flag %} + {{chart.jscript_end}} + {% endif %} -{% endblock body_end %} \ No newline at end of file +{% endblock body_end %} diff --git a/highcharts/highstock/templates/page.html b/highcharts/highstock/templates/page.html index 3559aaa..dd722fe 100644 --- a/highcharts/highstock/templates/page.html +++ b/highcharts/highstock/templates/page.html @@ -8,5 +8,6 @@ {{ chart.content }} + {{ chart.other }} From 0a8b0dbd2aaf05d163d9f4301465ebc54bc85e3e Mon Sep 17 00:00:00 2001 From: Kyle Solan Date: Mon, 18 Dec 2017 20:39:04 -0800 Subject: [PATCH 33/35] Ksolan/version bump (#43) * bumped to v0.4.0 * bumped to v0.4.1 --- highcharts/version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/highcharts/version.py b/highcharts/version.py index 37fbd6a..1b4d830 100644 --- a/highcharts/version.py +++ b/highcharts/version.py @@ -1,6 +1,6 @@ version_info = ( "0", - "3", + "4", "1" ) From af7e4f8183a6c2a82303876c97dcf4aab2186daf Mon Sep 17 00:00:00 2001 From: Daniel Bowring Date: Sat, 15 Dec 2018 08:38:34 +1100 Subject: [PATCH 34/35] Update JSsource urls to use Highcharts v6.x (#62) --- highcharts/highcharts/highcharts.py | 8 ++++---- highcharts/highmaps/highmaps.py | 10 +++++----- highcharts/highstock/highstock.py | 6 +++--- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/highcharts/highcharts/highcharts.py b/highcharts/highcharts/highcharts.py index 7b5dde2..59e093e 100644 --- a/highcharts/highcharts/highcharts.py +++ b/highcharts/highcharts/highcharts.py @@ -68,10 +68,10 @@ def __init__(self, **kwargs): # 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/highcharts.js', - 'https://code.highcharts.com/highcharts-more.js', - 'https://code.highcharts.com/modules/heatmap.js', - 'https://code.highcharts.com/modules/exporting.js' + 'https://code.highcharts.com/6/highcharts.js', + 'https://code.highcharts.com/6/highcharts-more.js', + 'https://code.highcharts.com/6/modules/heatmap.js', + 'https://code.highcharts.com/6/modules/exporting.js' ] # set CSS src diff --git a/highcharts/highmaps/highmaps.py b/highcharts/highmaps/highmaps.py index 8ccfc36..0d73afc 100644 --- a/highcharts/highmaps/highmaps.py +++ b/highcharts/highmaps/highmaps.py @@ -66,11 +66,11 @@ def __init__(self, **kwargs): # Set Javascript src self.JSsource = [ 'https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js', - 'https://code.highcharts.com/maps/highmaps.js', - 'https://code.highcharts.com/highcharts.js', - 'https://code.highcharts.com/maps/modules/map.js', - 'https://code.highcharts.com/maps/modules/data.js', - 'https://code.highcharts.com/maps/modules/exporting.js' + 'https://code.highcharts.com/maps/6/highmaps.js', + 'https://code.highcharts.com/6/highcharts.js', + 'https://code.highcharts.com/maps/6/modules/map.js', + 'https://code.highcharts.com/maps/6/modules/data.js', + 'https://code.highcharts.com/maps/6/modules/exporting.js' ] # set CSS src diff --git a/highcharts/highstock/highstock.py b/highcharts/highstock/highstock.py index 659d032..ef8610d 100644 --- a/highcharts/highstock/highstock.py +++ b/highcharts/highstock/highstock.py @@ -62,9 +62,9 @@ def __init__(self, **kwargs): # 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://code.highcharts.com/stock/6/highstock.js', + 'https://code.highcharts.com/stock/6/modules/exporting.js', + 'https://code.highcharts.com/6/highcharts-more.js', ] # set CSS src From a4c488ae5c2e125616efad5a722f3dfd8a9bc450 Mon Sep 17 00:00:00 2001 From: Kyle Solan Date: Fri, 14 Dec 2018 13:39:47 -0800 Subject: [PATCH 35/35] Bumped version (0.4.2) --- highcharts/version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/highcharts/version.py b/highcharts/version.py index 1b4d830..c8472d3 100644 --- a/highcharts/version.py +++ b/highcharts/version.py @@ -1,7 +1,7 @@ version_info = ( "0", "4", - "1" + "2" ) __version__ = '.'.join(map(str, version_info))