├── .gitignore ├── LICENSE ├── README.rst ├── VERSION ├── docs ├── Makefile ├── conf.py ├── index.rst └── views.rst ├── highcharts ├── __init__.py ├── models.py ├── static │ └── js │ │ └── highcharts │ │ ├── .fr-amL3gv │ │ ├── annotations.js │ │ ├── annotations.src.js │ │ ├── canvas-tools.js │ │ ├── canvas-tools.src.js │ │ ├── dark-blue.js │ │ ├── dark-green.js │ │ ├── data.js │ │ ├── data.src.js │ │ ├── exporting.js │ │ ├── exporting.src.js │ │ ├── funnel.js │ │ ├── funnel.src.js │ │ ├── gray.js │ │ ├── grid.js │ │ ├── highcharts-more.js │ │ ├── highcharts-more.src.js │ │ ├── highcharts.js │ │ ├── highcharts.src.js │ │ └── skies.js │ │ ├── highcharts-more.js │ │ ├── highcharts-more.src.js │ │ ├── highcharts.js │ │ ├── highcharts.src.js │ │ ├── modules │ │ ├── annotations.js │ │ ├── annotations.src.js │ │ ├── canvas-tools.js │ │ ├── canvas-tools.src.js │ │ ├── data.js │ │ ├── data.src.js │ │ ├── exporting.js │ │ ├── exporting.src.js │ │ ├── funnel.js │ │ └── funnel.src.js │ │ └── themes │ │ ├── dark-blue.js │ │ ├── dark-green.js │ │ ├── gray.js │ │ ├── grid.js │ │ └── skies.js ├── tests.py └── views │ ├── __init__.py │ ├── area.py │ ├── bar.py │ ├── common.py │ └── line.py └── setup.py /.gitignore: -------------------------------------------------------------------------------- 1 | *.pyc 2 | *.pyo 3 | *.egg-info 4 | docs/_build/ 5 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | ####### 2 | License 3 | ####### 4 | 5 | Copyright (c) 2013 Bruno Bord 6 | 7 | All rights reserved. 8 | Redistribution and use in source and binary forms, with or without 9 | modification, are permitted provided that the following conditions are 10 | met: 11 | 12 | * Redistributions of source code must retain the above copyright 13 | notice, this list of conditions and the following disclaimer. 14 | 15 | * Redistributions in binary form must reproduce the above copyright 16 | notice, this list of conditions and the following disclaimer in the 17 | documentation and/or other materials provided with the distribution. 18 | 19 | * Neither the name of the copyright holder nor the names of its 20 | contributors may be used to endorse or promote products derived from 21 | this software without specific prior written permission. 22 | 23 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 24 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 25 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 26 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 27 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 28 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 29 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 30 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 31 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 32 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 33 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 34 | -------------------------------------------------------------------------------- /README.rst: -------------------------------------------------------------------------------- 1 | **WARNING: this project is not maintained** 2 | 3 | ################# 4 | Django Highcharts 5 | ################# 6 | 7 | Generate charts in you Django application using Highcharts helpers. 8 | 9 | This library is mostly based on `django-chartjs `_, 10 | by Rémy Hubscher. 11 | 12 | Please don't try to use it yet, it's really not ready. 13 | 14 | * `Documentation is on RTFD `_ 15 | * `Source code is on Github `_ 16 | -------------------------------------------------------------------------------- /VERSION: -------------------------------------------------------------------------------- 1 | 0.0.1 -------------------------------------------------------------------------------- /docs/Makefile: -------------------------------------------------------------------------------- 1 | # Makefile for Sphinx documentation 2 | # 3 | 4 | # You can set these variables from the command line. 5 | SPHINXOPTS = 6 | SPHINXBUILD = sphinx-build 7 | PAPER = 8 | BUILDDIR = _build 9 | 10 | # Internal variables. 11 | PAPEROPT_a4 = -D latex_paper_size=a4 12 | PAPEROPT_letter = -D latex_paper_size=letter 13 | ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . 14 | # the i18n builder cannot share the environment and doctrees with the others 15 | I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . 16 | 17 | .PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext 18 | 19 | help: 20 | @echo "Please use \`make ' where is one of" 21 | @echo " html to make standalone HTML files" 22 | @echo " dirhtml to make HTML files named index.html in directories" 23 | @echo " singlehtml to make a single large HTML file" 24 | @echo " pickle to make pickle files" 25 | @echo " json to make JSON files" 26 | @echo " htmlhelp to make HTML files and a HTML help project" 27 | @echo " qthelp to make HTML files and a qthelp project" 28 | @echo " devhelp to make HTML files and a Devhelp project" 29 | @echo " epub to make an epub" 30 | @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" 31 | @echo " latexpdf to make LaTeX files and run them through pdflatex" 32 | @echo " text to make text files" 33 | @echo " man to make manual pages" 34 | @echo " texinfo to make Texinfo files" 35 | @echo " info to make Texinfo files and run them through makeinfo" 36 | @echo " gettext to make PO message catalogs" 37 | @echo " changes to make an overview of all changed/added/deprecated items" 38 | @echo " linkcheck to check all external links for integrity" 39 | @echo " doctest to run all doctests embedded in the documentation (if enabled)" 40 | 41 | clean: 42 | -rm -rf $(BUILDDIR)/* 43 | 44 | html: 45 | $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html 46 | @echo 47 | @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." 48 | 49 | dirhtml: 50 | $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml 51 | @echo 52 | @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." 53 | 54 | singlehtml: 55 | $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml 56 | @echo 57 | @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." 58 | 59 | pickle: 60 | $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle 61 | @echo 62 | @echo "Build finished; now you can process the pickle files." 63 | 64 | json: 65 | $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json 66 | @echo 67 | @echo "Build finished; now you can process the JSON files." 68 | 69 | htmlhelp: 70 | $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp 71 | @echo 72 | @echo "Build finished; now you can run HTML Help Workshop with the" \ 73 | ".hhp project file in $(BUILDDIR)/htmlhelp." 74 | 75 | qthelp: 76 | $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp 77 | @echo 78 | @echo "Build finished; now you can run "qcollectiongenerator" with the" \ 79 | ".qhcp project file in $(BUILDDIR)/qthelp, like this:" 80 | @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/DjangoHighcharts.qhcp" 81 | @echo "To view the help file:" 82 | @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/DjangoHighcharts.qhc" 83 | 84 | devhelp: 85 | $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp 86 | @echo 87 | @echo "Build finished." 88 | @echo "To view the help file:" 89 | @echo "# mkdir -p $$HOME/.local/share/devhelp/DjangoHighcharts" 90 | @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/DjangoHighcharts" 91 | @echo "# devhelp" 92 | 93 | epub: 94 | $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub 95 | @echo 96 | @echo "Build finished. The epub file is in $(BUILDDIR)/epub." 97 | 98 | latex: 99 | $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex 100 | @echo 101 | @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." 102 | @echo "Run \`make' in that directory to run these through (pdf)latex" \ 103 | "(use \`make latexpdf' here to do that automatically)." 104 | 105 | latexpdf: 106 | $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex 107 | @echo "Running LaTeX files through pdflatex..." 108 | $(MAKE) -C $(BUILDDIR)/latex all-pdf 109 | @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." 110 | 111 | text: 112 | $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text 113 | @echo 114 | @echo "Build finished. The text files are in $(BUILDDIR)/text." 115 | 116 | man: 117 | $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man 118 | @echo 119 | @echo "Build finished. The manual pages are in $(BUILDDIR)/man." 120 | 121 | texinfo: 122 | $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo 123 | @echo 124 | @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo." 125 | @echo "Run \`make' in that directory to run these through makeinfo" \ 126 | "(use \`make info' here to do that automatically)." 127 | 128 | info: 129 | $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo 130 | @echo "Running Texinfo files through makeinfo..." 131 | make -C $(BUILDDIR)/texinfo info 132 | @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo." 133 | 134 | gettext: 135 | $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale 136 | @echo 137 | @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale." 138 | 139 | changes: 140 | $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes 141 | @echo 142 | @echo "The overview file is in $(BUILDDIR)/changes." 143 | 144 | linkcheck: 145 | $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck 146 | @echo 147 | @echo "Link check complete; look for any errors in the above output " \ 148 | "or in $(BUILDDIR)/linkcheck/output.txt." 149 | 150 | doctest: 151 | $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest 152 | @echo "Testing of doctests in the sources finished, look at the " \ 153 | "results in $(BUILDDIR)/doctest/output.txt." 154 | -------------------------------------------------------------------------------- /docs/conf.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # Django Highcharts documentation build configuration file, created by 4 | # sphinx-quickstart on Thu Oct 31 21:14:39 2013. 5 | # 6 | # This file is execfile()d with the current directory set to its containing dir. 7 | # 8 | # Note that not all possible configuration values are present in this 9 | # autogenerated file. 10 | # 11 | # All configuration values have a default; values that are commented out 12 | # serve to show the default. 13 | 14 | import sys, os 15 | 16 | # If extensions (or modules to document with autodoc) are in another directory, 17 | # add these directories to sys.path here. If the directory is relative to the 18 | # documentation root, use os.path.abspath to make it absolute, like shown here. 19 | #sys.path.insert(0, os.path.abspath('.')) 20 | 21 | # -- General configuration ----------------------------------------------------- 22 | 23 | # If your documentation needs a minimal Sphinx version, state it here. 24 | #needs_sphinx = '1.0' 25 | 26 | # Add any Sphinx extension module names here, as strings. They can be extensions 27 | # coming with Sphinx (named 'sphinx.ext.*') or your custom ones. 28 | extensions = [] 29 | 30 | # Add any paths that contain templates here, relative to this directory. 31 | templates_path = ['_templates'] 32 | 33 | # The suffix of source filenames. 34 | source_suffix = '.rst' 35 | 36 | # The encoding of source files. 37 | #source_encoding = 'utf-8-sig' 38 | 39 | # The master toctree document. 40 | master_doc = 'index' 41 | 42 | # General information about the project. 43 | project = u'Django Highcharts' 44 | copyright = u'2013, Bruno Bord' 45 | 46 | # The version info for the project you're documenting, acts as replacement for 47 | # |version| and |release|, also used in various other places throughout the 48 | # built documents. 49 | # 50 | # The short X.Y version. 51 | version = '0.0.1' 52 | # The full version, including alpha/beta/rc tags. 53 | release = '0.0.1' 54 | 55 | # The language for content autogenerated by Sphinx. Refer to documentation 56 | # for a list of supported languages. 57 | #language = None 58 | 59 | # There are two options for replacing |today|: either, you set today to some 60 | # non-false value, then it is used: 61 | #today = '' 62 | # Else, today_fmt is used as the format for a strftime call. 63 | #today_fmt = '%B %d, %Y' 64 | 65 | # List of patterns, relative to source directory, that match files and 66 | # directories to ignore when looking for source files. 67 | exclude_patterns = ['_build'] 68 | 69 | # The reST default role (used for this markup: `text`) to use for all documents. 70 | #default_role = None 71 | 72 | # If true, '()' will be appended to :func: etc. cross-reference text. 73 | #add_function_parentheses = True 74 | 75 | # If true, the current module name will be prepended to all description 76 | # unit titles (such as .. function::). 77 | #add_module_names = True 78 | 79 | # If true, sectionauthor and moduleauthor directives will be shown in the 80 | # output. They are ignored by default. 81 | #show_authors = False 82 | 83 | # The name of the Pygments (syntax highlighting) style to use. 84 | pygments_style = 'sphinx' 85 | 86 | # A list of ignored prefixes for module index sorting. 87 | #modindex_common_prefix = [] 88 | 89 | 90 | # -- Options for HTML output --------------------------------------------------- 91 | 92 | # The theme to use for HTML and HTML Help pages. See the documentation for 93 | # a list of builtin themes. 94 | html_theme = 'default' 95 | 96 | # Theme options are theme-specific and customize the look and feel of a theme 97 | # further. For a list of options available for each theme, see the 98 | # documentation. 99 | #html_theme_options = {} 100 | 101 | # Add any paths that contain custom themes here, relative to this directory. 102 | #html_theme_path = [] 103 | 104 | # The name for this set of Sphinx documents. If None, it defaults to 105 | # " v documentation". 106 | #html_title = None 107 | 108 | # A shorter title for the navigation bar. Default is the same as html_title. 109 | #html_short_title = None 110 | 111 | # The name of an image file (relative to this directory) to place at the top 112 | # of the sidebar. 113 | #html_logo = None 114 | 115 | # The name of an image file (within the static path) to use as favicon of the 116 | # docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 117 | # pixels large. 118 | #html_favicon = None 119 | 120 | # Add any paths that contain custom static files (such as style sheets) here, 121 | # relative to this directory. They are copied after the builtin static files, 122 | # so a file named "default.css" will overwrite the builtin "default.css". 123 | html_static_path = ['_static'] 124 | 125 | # If not '', a 'Last updated on:' timestamp is inserted at every page bottom, 126 | # using the given strftime format. 127 | #html_last_updated_fmt = '%b %d, %Y' 128 | 129 | # If true, SmartyPants will be used to convert quotes and dashes to 130 | # typographically correct entities. 131 | #html_use_smartypants = True 132 | 133 | # Custom sidebar templates, maps document names to template names. 134 | #html_sidebars = {} 135 | 136 | # Additional templates that should be rendered to pages, maps page names to 137 | # template names. 138 | #html_additional_pages = {} 139 | 140 | # If false, no module index is generated. 141 | #html_domain_indices = True 142 | 143 | # If false, no index is generated. 144 | #html_use_index = True 145 | 146 | # If true, the index is split into individual pages for each letter. 147 | #html_split_index = False 148 | 149 | # If true, links to the reST sources are added to the pages. 150 | #html_show_sourcelink = True 151 | 152 | # If true, "Created using Sphinx" is shown in the HTML footer. Default is True. 153 | #html_show_sphinx = True 154 | 155 | # If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. 156 | #html_show_copyright = True 157 | 158 | # If true, an OpenSearch description file will be output, and all pages will 159 | # contain a tag referring to it. The value of this option must be the 160 | # base URL from which the finished HTML is served. 161 | #html_use_opensearch = '' 162 | 163 | # This is the file name suffix for HTML files (e.g. ".xhtml"). 164 | #html_file_suffix = None 165 | 166 | # Output file base name for HTML help builder. 167 | htmlhelp_basename = 'DjangoHighchartsdoc' 168 | 169 | 170 | # -- Options for LaTeX output -------------------------------------------------- 171 | 172 | latex_elements = { 173 | # The paper size ('letterpaper' or 'a4paper'). 174 | #'papersize': 'letterpaper', 175 | 176 | # The font size ('10pt', '11pt' or '12pt'). 177 | #'pointsize': '10pt', 178 | 179 | # Additional stuff for the LaTeX preamble. 180 | #'preamble': '', 181 | } 182 | 183 | # Grouping the document tree into LaTeX files. List of tuples 184 | # (source start file, target name, title, author, documentclass [howto/manual]). 185 | latex_documents = [ 186 | ('index', 'DjangoHighcharts.tex', u'Django Highcharts Documentation', 187 | u'Bruno Bord', 'manual'), 188 | ] 189 | 190 | # The name of an image file (relative to this directory) to place at the top of 191 | # the title page. 192 | #latex_logo = None 193 | 194 | # For "manual" documents, if this is true, then toplevel headings are parts, 195 | # not chapters. 196 | #latex_use_parts = False 197 | 198 | # If true, show page references after internal links. 199 | #latex_show_pagerefs = False 200 | 201 | # If true, show URL addresses after external links. 202 | #latex_show_urls = False 203 | 204 | # Documents to append as an appendix to all manuals. 205 | #latex_appendices = [] 206 | 207 | # If false, no module index is generated. 208 | #latex_domain_indices = True 209 | 210 | 211 | # -- Options for manual page output -------------------------------------------- 212 | 213 | # One entry per manual page. List of tuples 214 | # (source start file, name, description, authors, manual section). 215 | man_pages = [ 216 | ('index', 'djangohighcharts', u'Django Highcharts Documentation', 217 | [u'Bruno Bord'], 1) 218 | ] 219 | 220 | # If true, show URL addresses after external links. 221 | #man_show_urls = False 222 | 223 | 224 | # -- Options for Texinfo output ------------------------------------------------ 225 | 226 | # Grouping the document tree into Texinfo files. List of tuples 227 | # (source start file, target name, title, author, 228 | # dir menu entry, description, category) 229 | texinfo_documents = [ 230 | ('index', 'DjangoHighcharts', u'Django Highcharts Documentation', 231 | u'Bruno Bord', 'DjangoHighcharts', 'One line description of project.', 232 | 'Miscellaneous'), 233 | ] 234 | 235 | # Documents to append as an appendix to all manuals. 236 | #texinfo_appendices = [] 237 | 238 | # If false, no module index is generated. 239 | #texinfo_domain_indices = True 240 | 241 | # How to display URL addresses: 'footnote', 'no', or 'inline'. 242 | #texinfo_show_urls = 'footnote' 243 | -------------------------------------------------------------------------------- /docs/index.rst: -------------------------------------------------------------------------------- 1 | ================= 2 | Django Highcharts 3 | ================= 4 | 5 | Django Highchart will make it easier for you to display highcharts graphs. 6 | 7 | Quickstart 8 | ========== 9 | 10 | Install django-highcharts using pip (we do recommend to do it in a virtualenv). 11 | 12 | .. code-block:: sh 13 | 14 | git clone https://github.com/novapost/django-highcharts.git 15 | cd django-highcharts 16 | pip install -e ./ 17 | 18 | To integrate it into a Django project, simply add it to your `INSTALLED_APPS`: 19 | 20 | .. code-block:: python 21 | 22 | INSTALLED_APPS = [ 23 | # some interesting stuff... 24 | 'highcharts', 25 | # some other stuff... 26 | ] 27 | 28 | Don't forget to set your `STATIC_ROOT` path and to run the following command to 29 | update the static files: 30 | 31 | .. code-block:: sh 32 | 33 | python manage.py collectstatic 34 | 35 | You're now ready to use the available views. 36 | 37 | The view 38 | -------- 39 | 40 | .. code-block:: python 41 | 42 | from highcharts.views import HighChartsBarView 43 | 44 | class BarView(HighChartsBarView): 45 | categories = ['Orange', 'Bananas', 'Apples'] 46 | 47 | @property 48 | def series(self): 49 | result = [] 50 | for name in ('Joe', 'Jack', 'William', 'Averell'): 51 | data = [] 52 | for x in range(len(self.categories)): 53 | data.append(random.randint(0, 10)) 54 | result.append({'name': name, "data": data}) 55 | return result 56 | 57 | The template 58 | ------------ 59 | 60 | .. code-block:: django 61 | 62 | {% load staticfiles %} 63 | 64 | 65 | 66 | Hello 67 | 68 | 69 | 76 | 77 | 78 |
79 | 80 | 81 | 82 | .. warning:: 83 | 84 | Please note that the highcharts.js file should be called **after** the 85 | JQuery library. 86 | 87 | Further documentation 88 | ===================== 89 | 90 | .. toctree:: 91 | :maxdepth: 2 92 | :glob: 93 | 94 | views 95 | 96 | Indices and tables 97 | ================== 98 | 99 | * :ref:`genindex` 100 | * :ref:`modindex` 101 | * :ref:`search` 102 | 103 | -------------------------------------------------------------------------------- /docs/views.rst: -------------------------------------------------------------------------------- 1 | ===== 2 | Views 3 | ===== 4 | 5 | Common options 6 | ============== 7 | 8 | Highchart views all share the same general options. If one of these options 9 | is not set by a class property or an instance property, it'll use the 10 | default value (generally ``None``) 11 | 12 | * ``title``: The title of the graph 13 | * ``subtitle``: will display a subtitle. May contain 14 | HTML tags (including links) 15 | * ``tooltip_point_format``: formatting the tooltip over a data point using the 16 | Highchart appropriate format. (e.g.: ``"{series.name} produced {point.y:,.0f}
warheads in {point.x}"``) 17 | * ``plot_options`` (defaults to ``{}``): this dictionary will be directly 18 | converted into a JSON object and assigned to the data.plotOptions property on 19 | the client-side (it was too difficult to cover all the cases implied by this 20 | dictionary.) 21 | 22 | Basic usage 23 | =========== 24 | 25 | Overriding options 26 | ------------------ 27 | 28 | Any option (or parameter) is a property, but it can be easily replaced by a 29 | method if you need to generate it using code. 30 | 31 | Examples: 32 | 33 | .. code-block:: python 34 | 35 | class BarView(HighChartsBarView): 36 | title = 'My new (static) title' 37 | 38 | class BarViewAgain(HighChartsBarView): 39 | @property 40 | def title(self): 41 | return 'My stats for %s' % datetime.date.today() 42 | 43 | Available views 44 | =============== 45 | 46 | HighChartsBarView 47 | ----------------- 48 | 49 | :: 50 | 51 | from highcharts.views import HighChartsBarView 52 | 53 | 54 | Extra options 55 | ############# 56 | 57 | * ``categories`` (defaults to ``[]``): should return a list of string, 58 | * ``y_axis_title`` (defaults to ``""``): the title of the Y axis. 59 | 60 | HighChartsStackedView 61 | --------------------- 62 | 63 | :: 64 | 65 | from highcharts.views import HighChartsStackedView 66 | 67 | Extra options 68 | ############# 69 | 70 | Since it's a variant of the ``HighChartsBarView``, it supports the same options. 71 | 72 | HighChartsLineView 73 | ------------------ 74 | 75 | :: 76 | 77 | from highcharts.views import HighChartsLineView 78 | 79 | 80 | Extra options 81 | ############# 82 | 83 | * ``categories`` (defaults to ``[]``): should return a list of string, 84 | * ``y_axis_title`` (defaults to ``""``): the title of the Y axis. 85 | 86 | 87 | HighChartsAreaView 88 | ------------------ 89 | 90 | :: 91 | 92 | from highcharts.views import HighChartsAreaView 93 | 94 | 95 | Extra options 96 | ############# 97 | 98 | No extra options for the Area View (yet). 99 | -------------------------------------------------------------------------------- /highcharts/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/peopledoc/django-highcharts/34dd1b644325aaf8d9772feaf09827c730e8b154/highcharts/__init__.py -------------------------------------------------------------------------------- /highcharts/models.py: -------------------------------------------------------------------------------- 1 | # empty models.py - yes, that's a django requisite 2 | -------------------------------------------------------------------------------- /highcharts/static/js/highcharts/.fr-amL3gv/annotations.js: -------------------------------------------------------------------------------- 1 | (function(f,A){function k(a){return typeof a==="number"}function l(a){return a!==B&&a!==null}var B,n,o,w=f.Chart,r=f.extend,x=f.each,y;y={xAxis:0,yAxis:0,title:{style:{},text:"",x:0,y:0},shape:{params:{stroke:"#000000",fill:"transparent",strokeWidth:2}}};o=["path","rect","circle"];n={top:0,left:0,center:0.5,middle:0.5,bottom:1,right:1};var s=A.inArray,C=f.merge,z=function(){this.init.apply(this,arguments)};z.prototype={init:function(a,d){this.chart=a;this.options=C({},y,d)},render:function(a){var d= 2 | this.chart,c=this.chart.renderer,b=this.group,m=this.title,e=this.shape,g=this.options,f=g.title,i=g.shape;if(!b)b=this.group=c.g();if(!m&&f)m=this.title=c.label(f),m.add(b);if(!e&&i&&s(i.type,o)!==-1)e=this.shape=c[g.shape.type](i.params),e.add(b);b.add(d.annotations.group);this.linkObjects();a!==!1&&this.redraw()},redraw:function(){var a=this.options,d=this.chart,c=this.group,b=this.title,m=this.shape,e=this.linkedObject,g=d.xAxis[a.xAxis],o=d.yAxis[a.yAxis],i=a.width,t=a.height,u=n[a.anchorY], 3 | v=n[a.anchorX],h,q,j,p;if(e)h=e instanceof f.Point?"point":e instanceof f.Series?"series":null,h==="point"?(a.xValue=e.x,a.yValue=e.y,q=e.series):h==="series"&&(q=e),c.visibility!==q.group.visibility&&c.attr({visibility:q.group.visibility});e=(l(a.xValue)?g.toPixels(a.xValue+g.minPointOffset):a.x)-g.minPixelPadding;h=l(a.yValue)?o.toPixels(a.yValue):a.y;if(!isNaN(e)&&!isNaN(h)&&k(e)&&k(h)){b&&(b.attr(a.title),b.css(a.title.style));if(m){b=r({},a.shape.params);if(a.units==="values"){for(j in b)s(j, 4 | ["width","x"])>-1?b[j]=g.translate(b[j]):s(j,["height","y"])>-1&&(b[j]=o.translate(b[j]));b.width&&(b.width-=g.toPixels(0)-g.left);b.x&&(b.x+=g.minPixelPadding)}m.attr(b)}c.bBox=null;if(!k(i))p=c.getBBox(),i=p.width;if(!k(t))p||(p=c.getBBox()),t=p.height;if(!k(v))v=n.center;if(!k(u))u=n.center;e-=i*v;h-=t*u;d.animation&&l(c.translateX)&&l(c.translateY)?c.animate({translateX:e,translateY:h}):c.translate(e,h)}},destroy:function(){var a=this,d=this.chart.annotations.allItems,c=d.indexOf(a);c>-1&&d.splice(c, 5 | 1);x(["title","shape","group"],function(b){a[b]&&(a[b].destroy(),a[b]=null)});a.group=a.title=a.shape=a.chart=a.options=null},update:function(a,d){r(this.options,a);this.linkObjects();this.render(d)},linkObjects:function(){var a=this.chart,d=this.linkedObject,c=d&&(d.id||d.options.id),b=this.options.linkedTo;if(l(b)){if(!l(d)||b!==c)this.linkedObject=a.get(b)}else this.linkedObject=null}};r(w.prototype,{annotations:{add:function(a,d){var c=this.allItems,b=this.chart,f,e;Object.prototype.toString.call(a)=== 6 | "[object Array]"||(a=[a]);for(e=a.length;e--;)f=new z(b,a[e]),c.push(f),f.render(d)},redraw:function(){x(this.allItems,function(a){a.redraw()})}}});w.prototype.callbacks.push(function(a){var d=a.options.annotations,c;c=a.renderer.g("annotations");c.attr({zIndex:7});c.add();a.annotations.allItems=[];a.annotations.chart=a;a.annotations.group=c;Object.prototype.toString.call(d)==="[object Array]"&&d.length>0&&a.annotations.add(a.options.annotations);f.addEvent(a,"redraw",function(){a.annotations.redraw()})})})(Highcharts, 7 | HighchartsAdapter); 8 | -------------------------------------------------------------------------------- /highcharts/static/js/highcharts/.fr-amL3gv/annotations.src.js: -------------------------------------------------------------------------------- 1 | (function (Highcharts, HighchartsAdapter) { 2 | 3 | var UNDEFINED, 4 | ALIGN_FACTOR, 5 | ALLOWED_SHAPES, 6 | Chart = Highcharts.Chart, 7 | extend = Highcharts.extend, 8 | each = Highcharts.each, 9 | defaultOptions; 10 | 11 | defaultOptions = { 12 | xAxis: 0, 13 | yAxis: 0, 14 | title: { 15 | style: {}, 16 | text: "", 17 | x: 0, 18 | y: 0 19 | }, 20 | shape: { 21 | params: { 22 | stroke: "#000000", 23 | fill: "transparent", 24 | strokeWidth: 2 25 | } 26 | } 27 | }; 28 | 29 | ALLOWED_SHAPES = ["path", "rect", "circle"]; 30 | 31 | ALIGN_FACTOR = { 32 | top: 0, 33 | left: 0, 34 | center: 0.5, 35 | middle: 0.5, 36 | bottom: 1, 37 | right: 1 38 | }; 39 | 40 | 41 | // Highcharts helper methods 42 | var inArray = HighchartsAdapter.inArray, 43 | merge = Highcharts.merge; 44 | 45 | function isArray(obj) { 46 | return Object.prototype.toString.call(obj) === '[object Array]'; 47 | } 48 | 49 | function isNumber(n) { 50 | return typeof n === 'number'; 51 | } 52 | 53 | function defined(obj) { 54 | return obj !== UNDEFINED && obj !== null; 55 | } 56 | 57 | 58 | // Define annotation prototype 59 | var Annotation = function () { 60 | this.init.apply(this, arguments); 61 | }; 62 | Annotation.prototype = { 63 | /* 64 | * Initialize the annotation 65 | */ 66 | init: function (chart, options) { 67 | this.chart = chart; 68 | this.options = merge({}, defaultOptions, options); 69 | }, 70 | 71 | /* 72 | * Render the annotation 73 | */ 74 | render: function (redraw) { 75 | var annotation = this, 76 | chart = this.chart, 77 | renderer = annotation.chart.renderer, 78 | group = annotation.group, 79 | title = annotation.title, 80 | shape = annotation.shape, 81 | options = annotation.options, 82 | titleOptions = options.title, 83 | shapeOptions = options.shape; 84 | 85 | if (!group) { 86 | group = annotation.group = renderer.g(); 87 | } 88 | 89 | if (!title && titleOptions) { 90 | title = annotation.title = renderer.label(titleOptions); 91 | title.add(group); 92 | } 93 | 94 | if (!shape && shapeOptions && inArray(shapeOptions.type, ALLOWED_SHAPES) !== -1) { 95 | shape = annotation.shape = renderer[options.shape.type](shapeOptions.params); 96 | shape.add(group); 97 | } 98 | 99 | group.add(chart.annotations.group); 100 | 101 | // link annotations to point or series 102 | annotation.linkObjects(); 103 | 104 | if (redraw !== false) { 105 | annotation.redraw(); 106 | } 107 | }, 108 | 109 | /* 110 | * Redraw the annotation title or shape after options update 111 | */ 112 | redraw: function () { 113 | var options = this.options, 114 | chart = this.chart, 115 | group = this.group, 116 | title = this.title, 117 | shape = this.shape, 118 | linkedTo = this.linkedObject, 119 | xAxis = chart.xAxis[options.xAxis], 120 | yAxis = chart.yAxis[options.yAxis], 121 | width = options.width, 122 | height = options.height, 123 | anchorY = ALIGN_FACTOR[options.anchorY], 124 | anchorX = ALIGN_FACTOR[options.anchorX], 125 | resetBBox = false, 126 | shapeParams, 127 | linkType, 128 | series, 129 | param, 130 | bbox, 131 | x, 132 | y; 133 | 134 | if (linkedTo) { 135 | linkType = (linkedTo instanceof Highcharts.Point) ? 'point' : 136 | (linkedTo instanceof Highcharts.Series) ? 'series' : null; 137 | 138 | if (linkType === 'point') { 139 | options.xValue = linkedTo.x; 140 | options.yValue = linkedTo.y; 141 | series = linkedTo.series; 142 | } else if (linkType === 'series') { 143 | series = linkedTo; 144 | } 145 | 146 | if (group.visibility !== series.group.visibility) { 147 | group.attr({ 148 | visibility: series.group.visibility 149 | }); 150 | } 151 | } 152 | 153 | 154 | // Based on given options find annotation pixel position 155 | x = (defined(options.xValue) ? xAxis.toPixels(options.xValue + xAxis.minPointOffset) : options.x) - xAxis.minPixelPadding; 156 | y = defined(options.yValue) ? yAxis.toPixels(options.yValue) : options.y; 157 | 158 | 159 | if (isNaN(x) || isNaN(y) || !isNumber(x) || !isNumber(y)) { 160 | return; 161 | } 162 | 163 | 164 | if (title) { 165 | title.attr(options.title); 166 | title.css(options.title.style); 167 | resetBBox = true; 168 | } 169 | 170 | if (shape) { 171 | shapeParams = extend({}, options.shape.params); 172 | 173 | if (options.units === 'values') { 174 | for (param in shapeParams) { 175 | if (inArray(param, ['width', 'x']) > -1) { 176 | shapeParams[param] = xAxis.translate(shapeParams[param]); 177 | } else if (inArray(param, ['height', 'y']) > -1) { 178 | shapeParams[param] = yAxis.translate(shapeParams[param]); 179 | } 180 | } 181 | 182 | if (shapeParams.width) { 183 | shapeParams.width -= xAxis.toPixels(0) - xAxis.left; 184 | } 185 | 186 | if (shapeParams.x) { 187 | shapeParams.x += xAxis.minPixelPadding; 188 | } 189 | 190 | } 191 | 192 | resetBBox = true; 193 | shape.attr(shapeParams); 194 | } 195 | 196 | group.bBox = null; 197 | 198 | // If annotation width or height is not defined in options use bounding box size 199 | if (!isNumber(width)) { 200 | bbox = group.getBBox(); 201 | width = bbox.width; 202 | } 203 | 204 | if (!isNumber(height)) { 205 | // get bbox only if it wasn't set before 206 | if (!bbox) { 207 | bbox = group.getBBox(); 208 | } 209 | 210 | height = bbox.height; 211 | } 212 | 213 | // Calculate anchor point 214 | if (!isNumber(anchorX)) { 215 | anchorX = ALIGN_FACTOR.center; 216 | } 217 | 218 | if (!isNumber(anchorY)) { 219 | anchorY = ALIGN_FACTOR.center; 220 | } 221 | 222 | // Translate group according to its dimension and anchor point 223 | x = x - width * anchorX; 224 | y = y - height * anchorY; 225 | 226 | if (chart.animation && defined(group.translateX) && defined(group.translateY)) { 227 | group.animate({ 228 | translateX: x, 229 | translateY: y 230 | }); 231 | } else { 232 | group.translate(x, y); 233 | } 234 | }, 235 | 236 | /* 237 | * Destroy the annotation 238 | */ 239 | destroy: function () { 240 | var annotation = this, 241 | chart = this.chart, 242 | allItems = chart.annotations.allItems, 243 | index = allItems.indexOf(annotation); 244 | 245 | if (index > -1) { 246 | allItems.splice(index, 1); 247 | } 248 | 249 | each(['title', 'shape', 'group'], function (element) { 250 | if (annotation[element]) { 251 | annotation[element].destroy(); 252 | annotation[element] = null; 253 | } 254 | }); 255 | 256 | annotation.group = annotation.title = annotation.shape = annotation.chart = annotation.options = null; 257 | }, 258 | 259 | /* 260 | * Update the annotation with a given options 261 | */ 262 | update: function (options, redraw) { 263 | extend(this.options, options); 264 | 265 | // update link to point or series 266 | this.linkObjects(); 267 | 268 | this.render(redraw); 269 | }, 270 | 271 | linkObjects: function () { 272 | var annotation = this, 273 | chart = annotation.chart, 274 | linkedTo = annotation.linkedObject, 275 | linkedId = linkedTo && (linkedTo.id || linkedTo.options.id), 276 | options = annotation.options, 277 | id = options.linkedTo; 278 | 279 | if (!defined(id)) { 280 | annotation.linkedObject = null; 281 | } else if (!defined(linkedTo) || id !== linkedId) { 282 | annotation.linkedObject = chart.get(id); 283 | } 284 | } 285 | }; 286 | 287 | 288 | // Add annotations methods to chart prototype 289 | extend(Chart.prototype, { 290 | annotations: { 291 | /* 292 | * Unified method for adding annotations to the chart 293 | */ 294 | add: function (options, redraw) { 295 | var annotations = this.allItems, 296 | chart = this.chart, 297 | item, 298 | len; 299 | 300 | if (!isArray(options)) { 301 | options = [options]; 302 | } 303 | 304 | len = options.length; 305 | 306 | while (len--) { 307 | item = new Annotation(chart, options[len]); 308 | annotations.push(item); 309 | item.render(redraw); 310 | } 311 | }, 312 | 313 | /** 314 | * Redraw all annotations, method used in chart events 315 | */ 316 | redraw: function () { 317 | each(this.allItems, function (annotation) { 318 | annotation.redraw(); 319 | }); 320 | } 321 | } 322 | }); 323 | 324 | 325 | // Initialize on chart load 326 | Chart.prototype.callbacks.push(function (chart) { 327 | var options = chart.options.annotations, 328 | group; 329 | 330 | group = chart.renderer.g("annotations"); 331 | group.attr({ 332 | zIndex: 7 333 | }); 334 | group.add(); 335 | 336 | // initialize empty array for annotations 337 | chart.annotations.allItems = []; 338 | 339 | // link chart object to annotations 340 | chart.annotations.chart = chart; 341 | 342 | // link annotations group element to the chart 343 | chart.annotations.group = group; 344 | 345 | if (isArray(options) && options.length > 0) { 346 | chart.annotations.add(chart.options.annotations); 347 | } 348 | 349 | // update annotations after chart redraw 350 | Highcharts.addEvent(chart, 'redraw', function () { 351 | chart.annotations.redraw(); 352 | }); 353 | }); 354 | }(Highcharts, HighchartsAdapter)); 355 | -------------------------------------------------------------------------------- /highcharts/static/js/highcharts/.fr-amL3gv/dark-blue.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Dark blue theme for Highcharts JS 3 | * @author Torstein Hønsi 4 | */ 5 | 6 | Highcharts.theme = { 7 | colors: ["#DDDF0D", "#55BF3B", "#DF5353", "#7798BF", "#aaeeee", "#ff0066", "#eeaaee", 8 | "#55BF3B", "#DF5353", "#7798BF", "#aaeeee"], 9 | chart: { 10 | backgroundColor: { 11 | linearGradient: { x1: 0, y1: 0, x2: 1, y2: 1 }, 12 | stops: [ 13 | [0, 'rgb(48, 48, 96)'], 14 | [1, 'rgb(0, 0, 0)'] 15 | ] 16 | }, 17 | borderColor: '#000000', 18 | borderWidth: 2, 19 | className: 'dark-container', 20 | plotBackgroundColor: 'rgba(255, 255, 255, .1)', 21 | plotBorderColor: '#CCCCCC', 22 | plotBorderWidth: 1 23 | }, 24 | title: { 25 | style: { 26 | color: '#C0C0C0', 27 | font: 'bold 16px "Trebuchet MS", Verdana, sans-serif' 28 | } 29 | }, 30 | subtitle: { 31 | style: { 32 | color: '#666666', 33 | font: 'bold 12px "Trebuchet MS", Verdana, sans-serif' 34 | } 35 | }, 36 | xAxis: { 37 | gridLineColor: '#333333', 38 | gridLineWidth: 1, 39 | labels: { 40 | style: { 41 | color: '#A0A0A0' 42 | } 43 | }, 44 | lineColor: '#A0A0A0', 45 | tickColor: '#A0A0A0', 46 | title: { 47 | style: { 48 | color: '#CCC', 49 | fontWeight: 'bold', 50 | fontSize: '12px', 51 | fontFamily: 'Trebuchet MS, Verdana, sans-serif' 52 | 53 | } 54 | } 55 | }, 56 | yAxis: { 57 | gridLineColor: '#333333', 58 | labels: { 59 | style: { 60 | color: '#A0A0A0' 61 | } 62 | }, 63 | lineColor: '#A0A0A0', 64 | minorTickInterval: null, 65 | tickColor: '#A0A0A0', 66 | tickWidth: 1, 67 | title: { 68 | style: { 69 | color: '#CCC', 70 | fontWeight: 'bold', 71 | fontSize: '12px', 72 | fontFamily: 'Trebuchet MS, Verdana, sans-serif' 73 | } 74 | } 75 | }, 76 | tooltip: { 77 | backgroundColor: 'rgba(0, 0, 0, 0.75)', 78 | style: { 79 | color: '#F0F0F0' 80 | } 81 | }, 82 | toolbar: { 83 | itemStyle: { 84 | color: 'silver' 85 | } 86 | }, 87 | plotOptions: { 88 | line: { 89 | dataLabels: { 90 | color: '#CCC' 91 | }, 92 | marker: { 93 | lineColor: '#333' 94 | } 95 | }, 96 | spline: { 97 | marker: { 98 | lineColor: '#333' 99 | } 100 | }, 101 | scatter: { 102 | marker: { 103 | lineColor: '#333' 104 | } 105 | }, 106 | candlestick: { 107 | lineColor: 'white' 108 | } 109 | }, 110 | legend: { 111 | itemStyle: { 112 | font: '9pt Trebuchet MS, Verdana, sans-serif', 113 | color: '#A0A0A0' 114 | }, 115 | itemHoverStyle: { 116 | color: '#FFF' 117 | }, 118 | itemHiddenStyle: { 119 | color: '#444' 120 | } 121 | }, 122 | credits: { 123 | style: { 124 | color: '#666' 125 | } 126 | }, 127 | labels: { 128 | style: { 129 | color: '#CCC' 130 | } 131 | }, 132 | 133 | navigation: { 134 | buttonOptions: { 135 | symbolStroke: '#DDDDDD', 136 | hoverSymbolStroke: '#FFFFFF', 137 | theme: { 138 | fill: { 139 | linearGradient: { x1: 0, y1: 0, x2: 0, y2: 1 }, 140 | stops: [ 141 | [0.4, '#606060'], 142 | [0.6, '#333333'] 143 | ] 144 | }, 145 | stroke: '#000000' 146 | } 147 | } 148 | }, 149 | 150 | // scroll charts 151 | rangeSelector: { 152 | buttonTheme: { 153 | fill: { 154 | linearGradient: { x1: 0, y1: 0, x2: 0, y2: 1 }, 155 | stops: [ 156 | [0.4, '#888'], 157 | [0.6, '#555'] 158 | ] 159 | }, 160 | stroke: '#000000', 161 | style: { 162 | color: '#CCC', 163 | fontWeight: 'bold' 164 | }, 165 | states: { 166 | hover: { 167 | fill: { 168 | linearGradient: { x1: 0, y1: 0, x2: 0, y2: 1 }, 169 | stops: [ 170 | [0.4, '#BBB'], 171 | [0.6, '#888'] 172 | ] 173 | }, 174 | stroke: '#000000', 175 | style: { 176 | color: 'white' 177 | } 178 | }, 179 | select: { 180 | fill: { 181 | linearGradient: { x1: 0, y1: 0, x2: 0, y2: 1 }, 182 | stops: [ 183 | [0.1, '#000'], 184 | [0.3, '#333'] 185 | ] 186 | }, 187 | stroke: '#000000', 188 | style: { 189 | color: 'yellow' 190 | } 191 | } 192 | } 193 | }, 194 | inputStyle: { 195 | backgroundColor: '#333', 196 | color: 'silver' 197 | }, 198 | labelStyle: { 199 | color: 'silver' 200 | } 201 | }, 202 | 203 | navigator: { 204 | handles: { 205 | backgroundColor: '#666', 206 | borderColor: '#AAA' 207 | }, 208 | outlineColor: '#CCC', 209 | maskFill: 'rgba(16, 16, 16, 0.5)', 210 | series: { 211 | color: '#7798BF', 212 | lineColor: '#A6C7ED' 213 | } 214 | }, 215 | 216 | scrollbar: { 217 | barBackgroundColor: { 218 | linearGradient: { x1: 0, y1: 0, x2: 0, y2: 1 }, 219 | stops: [ 220 | [0.4, '#888'], 221 | [0.6, '#555'] 222 | ] 223 | }, 224 | barBorderColor: '#CCC', 225 | buttonArrowColor: '#CCC', 226 | buttonBackgroundColor: { 227 | linearGradient: { x1: 0, y1: 0, x2: 0, y2: 1 }, 228 | stops: [ 229 | [0.4, '#888'], 230 | [0.6, '#555'] 231 | ] 232 | }, 233 | buttonBorderColor: '#CCC', 234 | rifleColor: '#FFF', 235 | trackBackgroundColor: { 236 | linearGradient: { x1: 0, y1: 0, x2: 0, y2: 1 }, 237 | stops: [ 238 | [0, '#000'], 239 | [1, '#333'] 240 | ] 241 | }, 242 | trackBorderColor: '#666' 243 | }, 244 | 245 | // special colors for some of the 246 | legendBackgroundColor: 'rgba(0, 0, 0, 0.5)', 247 | legendBackgroundColorSolid: 'rgb(35, 35, 70)', 248 | dataLabelsColor: '#444', 249 | textColor: '#C0C0C0', 250 | maskColor: 'rgba(255,255,255,0.3)' 251 | }; 252 | 253 | // Apply the theme 254 | var highchartsOptions = Highcharts.setOptions(Highcharts.theme); 255 | -------------------------------------------------------------------------------- /highcharts/static/js/highcharts/.fr-amL3gv/dark-green.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Dark blue theme for Highcharts JS 3 | * @author Torstein Hønsi 4 | */ 5 | 6 | Highcharts.theme = { 7 | colors: ["#DDDF0D", "#55BF3B", "#DF5353", "#7798BF", "#aaeeee", "#ff0066", "#eeaaee", 8 | "#55BF3B", "#DF5353", "#7798BF", "#aaeeee"], 9 | chart: { 10 | backgroundColor: { 11 | linearGradient: [0, 0, 250, 500], 12 | stops: [ 13 | [0, 'rgb(48, 96, 48)'], 14 | [1, 'rgb(0, 0, 0)'] 15 | ] 16 | }, 17 | borderColor: '#000000', 18 | borderWidth: 2, 19 | className: 'dark-container', 20 | plotBackgroundColor: 'rgba(255, 255, 255, .1)', 21 | plotBorderColor: '#CCCCCC', 22 | plotBorderWidth: 1 23 | }, 24 | title: { 25 | style: { 26 | color: '#C0C0C0', 27 | font: 'bold 16px "Trebuchet MS", Verdana, sans-serif' 28 | } 29 | }, 30 | subtitle: { 31 | style: { 32 | color: '#666666', 33 | font: 'bold 12px "Trebuchet MS", Verdana, sans-serif' 34 | } 35 | }, 36 | xAxis: { 37 | gridLineColor: '#333333', 38 | gridLineWidth: 1, 39 | labels: { 40 | style: { 41 | color: '#A0A0A0' 42 | } 43 | }, 44 | lineColor: '#A0A0A0', 45 | tickColor: '#A0A0A0', 46 | title: { 47 | style: { 48 | color: '#CCC', 49 | fontWeight: 'bold', 50 | fontSize: '12px', 51 | fontFamily: 'Trebuchet MS, Verdana, sans-serif' 52 | 53 | } 54 | } 55 | }, 56 | yAxis: { 57 | gridLineColor: '#333333', 58 | labels: { 59 | style: { 60 | color: '#A0A0A0' 61 | } 62 | }, 63 | lineColor: '#A0A0A0', 64 | minorTickInterval: null, 65 | tickColor: '#A0A0A0', 66 | tickWidth: 1, 67 | title: { 68 | style: { 69 | color: '#CCC', 70 | fontWeight: 'bold', 71 | fontSize: '12px', 72 | fontFamily: 'Trebuchet MS, Verdana, sans-serif' 73 | } 74 | } 75 | }, 76 | tooltip: { 77 | backgroundColor: 'rgba(0, 0, 0, 0.75)', 78 | style: { 79 | color: '#F0F0F0' 80 | } 81 | }, 82 | toolbar: { 83 | itemStyle: { 84 | color: 'silver' 85 | } 86 | }, 87 | plotOptions: { 88 | line: { 89 | dataLabels: { 90 | color: '#CCC' 91 | }, 92 | marker: { 93 | lineColor: '#333' 94 | } 95 | }, 96 | spline: { 97 | marker: { 98 | lineColor: '#333' 99 | } 100 | }, 101 | scatter: { 102 | marker: { 103 | lineColor: '#333' 104 | } 105 | }, 106 | candlestick: { 107 | lineColor: 'white' 108 | } 109 | }, 110 | legend: { 111 | itemStyle: { 112 | font: '9pt Trebuchet MS, Verdana, sans-serif', 113 | color: '#A0A0A0' 114 | }, 115 | itemHoverStyle: { 116 | color: '#FFF' 117 | }, 118 | itemHiddenStyle: { 119 | color: '#444' 120 | } 121 | }, 122 | credits: { 123 | style: { 124 | color: '#666' 125 | } 126 | }, 127 | labels: { 128 | style: { 129 | color: '#CCC' 130 | } 131 | }, 132 | 133 | 134 | navigation: { 135 | buttonOptions: { 136 | symbolStroke: '#DDDDDD', 137 | hoverSymbolStroke: '#FFFFFF', 138 | theme: { 139 | fill: { 140 | linearGradient: { x1: 0, y1: 0, x2: 0, y2: 1 }, 141 | stops: [ 142 | [0.4, '#606060'], 143 | [0.6, '#333333'] 144 | ] 145 | }, 146 | stroke: '#000000' 147 | } 148 | } 149 | }, 150 | 151 | // scroll charts 152 | rangeSelector: { 153 | buttonTheme: { 154 | fill: { 155 | linearGradient: { x1: 0, y1: 0, x2: 0, y2: 1 }, 156 | stops: [ 157 | [0.4, '#888'], 158 | [0.6, '#555'] 159 | ] 160 | }, 161 | stroke: '#000000', 162 | style: { 163 | color: '#CCC', 164 | fontWeight: 'bold' 165 | }, 166 | states: { 167 | hover: { 168 | fill: { 169 | linearGradient: { x1: 0, y1: 0, x2: 0, y2: 1 }, 170 | stops: [ 171 | [0.4, '#BBB'], 172 | [0.6, '#888'] 173 | ] 174 | }, 175 | stroke: '#000000', 176 | style: { 177 | color: 'white' 178 | } 179 | }, 180 | select: { 181 | fill: { 182 | linearGradient: { x1: 0, y1: 0, x2: 0, y2: 1 }, 183 | stops: [ 184 | [0.1, '#000'], 185 | [0.3, '#333'] 186 | ] 187 | }, 188 | stroke: '#000000', 189 | style: { 190 | color: 'yellow' 191 | } 192 | } 193 | } 194 | }, 195 | inputStyle: { 196 | backgroundColor: '#333', 197 | color: 'silver' 198 | }, 199 | labelStyle: { 200 | color: 'silver' 201 | } 202 | }, 203 | 204 | navigator: { 205 | handles: { 206 | backgroundColor: '#666', 207 | borderColor: '#AAA' 208 | }, 209 | outlineColor: '#CCC', 210 | maskFill: 'rgba(16, 16, 16, 0.5)', 211 | series: { 212 | color: '#7798BF', 213 | lineColor: '#A6C7ED' 214 | } 215 | }, 216 | 217 | scrollbar: { 218 | barBackgroundColor: { 219 | linearGradient: { x1: 0, y1: 0, x2: 0, y2: 1 }, 220 | stops: [ 221 | [0.4, '#888'], 222 | [0.6, '#555'] 223 | ] 224 | }, 225 | barBorderColor: '#CCC', 226 | buttonArrowColor: '#CCC', 227 | buttonBackgroundColor: { 228 | linearGradient: { x1: 0, y1: 0, x2: 0, y2: 1 }, 229 | stops: [ 230 | [0.4, '#888'], 231 | [0.6, '#555'] 232 | ] 233 | }, 234 | buttonBorderColor: '#CCC', 235 | rifleColor: '#FFF', 236 | trackBackgroundColor: { 237 | linearGradient: { x1: 0, y1: 0, x2: 0, y2: 1 }, 238 | stops: [ 239 | [0, '#000'], 240 | [1, '#333'] 241 | ] 242 | }, 243 | trackBorderColor: '#666' 244 | }, 245 | 246 | // special colors for some of the 247 | legendBackgroundColor: 'rgba(0, 0, 0, 0.5)', 248 | legendBackgroundColorSolid: 'rgb(35, 35, 70)', 249 | dataLabelsColor: '#444', 250 | textColor: '#C0C0C0', 251 | maskColor: 'rgba(255,255,255,0.3)' 252 | }; 253 | 254 | // Apply the theme 255 | var highchartsOptions = Highcharts.setOptions(Highcharts.theme); 256 | -------------------------------------------------------------------------------- /highcharts/static/js/highcharts/.fr-amL3gv/data.js: -------------------------------------------------------------------------------- 1 | /* 2 | Data plugin for Highcharts 3 | 4 | (c) 2012-2013 Torstein Hønsi 5 | Last revision 2012-11-27 6 | 7 | License: www.highcharts.com/license 8 | */ 9 | (function(f){var k=f.each,n=function(a){this.init(a)};f.extend(n.prototype,{init:function(a){this.options=a;this.columns=a.columns||this.rowsToColumns(a.rows)||[];this.columns.length?this.dataFound():(this.parseCSV(),this.parseTable(),this.parseGoogleSpreadsheet())},dataFound:function(){this.parseTypes();this.findHeaderRow();this.parsed();this.complete()},parseCSV:function(){var a=this,b=this.options,c=b.csv,d=this.columns,e=b.startRow||0,g=b.endRow||Number.MAX_VALUE,h=b.startColumn||0,l=b.endColumn|| 10 | Number.MAX_VALUE,q=0;c&&(c=c.replace(/\r\n/g,"\n").replace(/\r/g,"\n").split(b.lineDelimiter||"\n"),k(c,function(c,m){var o=a.trim(c),f=o.indexOf("#")===0;m>=e&&m<=g&&!f&&o!==""&&(o=c.split(b.itemDelimiter||","),k(o,function(b,a){a>=h&&a<=l&&(d[a-h]||(d[a-h]=[]),d[a-h][q]=b)}),q+=1)}),this.dataFound())},parseTable:function(){var a=this.options,b=a.table,c=this.columns,d=a.startRow||0,e=a.endRow||Number.MAX_VALUE,g=a.startColumn||0,h=a.endColumn||Number.MAX_VALUE,l;b&&(typeof b==="string"&&(b=document.getElementById(b)), 11 | k(b.getElementsByTagName("tr"),function(a,b){l=0;b>=d&&b<=e&&k(a.childNodes,function(a){if((a.tagName==="TD"||a.tagName==="TH")&&l>=g&&l<=h)c[l]||(c[l]=[]),c[l][b-d]=a.innerHTML,l+=1})}),this.dataFound())},parseGoogleSpreadsheet:function(){var a=this,b=this.options,c=b.googleSpreadsheetKey,d=this.columns,e=b.startRow||0,g=b.endRow||Number.MAX_VALUE,h=b.startColumn||0,l=b.endColumn||Number.MAX_VALUE,f,j;c&&jQuery.getJSON("https://spreadsheets.google.com/feeds/cells/"+c+"/"+(b.googleSpreadsheetWorksheet|| 12 | "od6")+"/public/values?alt=json-in-script&callback=?",function(b){var b=b.feed.entry,c,k=b.length,n=0,p=0,i;for(i=0;i=h&&i<=l)d[i-h]=[],d[i-h].length=Math.min(p,g-e);for(i=0;i=h&&j<=l&&f>=e&&f<=g)d[j-h][f-e]=c.content.$t;a.dataFound()})},findHeaderRow:function(){k(this.columns,function(){});this.headerRow=0},trim:function(a){return typeof a==="string"?a.replace(/^\s+|\s+$/g, 13 | ""):a},parseTypes:function(){for(var a=this.columns,b=a.length,c,d,e,g;b--;)for(c=a[b].length;c--;)d=a[b][c],e=parseFloat(d),g=this.trim(d),g==e?(a[b][c]=e,e>31536E6?a[b].isDatetime=!0:a[b].isNumeric=!0):(d=this.parseDate(d),b===0&&typeof d==="number"&&!isNaN(d)?(a[b][c]=d,a[b].isDatetime=!0):a[b][c]=g===""?null:g)},dateFormats:{"YYYY-mm-dd":{regex:"^([0-9]{4})-([0-9]{2})-([0-9]{2})$",parser:function(a){return Date.UTC(+a[1],a[2]-1,+a[3])}}},parseDate:function(a){var b=this.options.parseDate,c,d, 14 | e;b&&(c=b(a));if(typeof a==="string")for(d in this.dateFormats)b=this.dateFormats[d],(e=a.match(b.regex))&&(c=b.parser(e));return c},rowsToColumns:function(a){var b,c,d,e,g;if(a){g=[];c=a.length;for(b=0;b1&&(d=a.shift(),this.headerRow===0&& 15 | d.shift(),(b=d.isNumeric||d.isDatetime)||(c=d),d.isDatetime&&(e="datetime"));h=[];for(j=0;j> 20 | * A two-dimensional array representing the input data on tabular form. This input can 21 | * be used when the data is already parsed, for example from a grid view component. 22 | * Each cell can be a string or number. If not switchRowsAndColumns is set, the columns 23 | * are interpreted as series. See also the rows option. 24 | * 25 | * - complete : Function(chartOptions) 26 | * The callback that is evaluated when the data is finished loading, optionally from an 27 | * external source, and parsed. The first argument passed is a finished chart options 28 | * object, containing series and an xAxis with categories if applicable. Thise options 29 | * can be extended with additional options and passed directly to the chart constructor. 30 | * 31 | * - csv : String 32 | * A comma delimited string to be parsed. Related options are startRow, endRow, startColumn 33 | * and endColumn to delimit what part of the table is used. The lineDelimiter and 34 | * itemDelimiter options define the CSV delimiter formats. 35 | * 36 | * - endColumn : Integer 37 | * In tabular input data, the first row (indexed by 0) to use. Defaults to the last 38 | * column containing data. 39 | * 40 | * - endRow : Integer 41 | * In tabular input data, the last row (indexed by 0) to use. Defaults to the last row 42 | * containing data. 43 | * 44 | * - googleSpreadsheetKey : String 45 | * A Google Spreadsheet key. See https://developers.google.com/gdata/samples/spreadsheet_sample 46 | * for general information on GS. 47 | * 48 | * - googleSpreadsheetWorksheet : String 49 | * The Google Spreadsheet worksheet. The available id's can be read from 50 | * https://spreadsheets.google.com/feeds/worksheets/{key}/public/basic 51 | * 52 | * - itemDelimiter : String 53 | * Item or cell delimiter for parsing CSV. Defaults to ",". 54 | * 55 | * - lineDelimiter : String 56 | * Line delimiter for parsing CSV. Defaults to "\n". 57 | * 58 | * - parsed : Function 59 | * A callback function to access the parsed columns, the two-dimentional input data 60 | * array directly, before they are interpreted into series data and categories. 61 | * 62 | * - parseDate : Function 63 | * A callback function to parse string representations of dates into JavaScript timestamps. 64 | * Return an integer on success. 65 | * 66 | * - rows : Array> 67 | * The same as the columns input option, but defining rows intead of columns. 68 | * 69 | * - startColumn : Integer 70 | * In tabular input data, the first column (indexed by 0) to use. 71 | * 72 | * - startRow : Integer 73 | * In tabular input data, the first row (indexed by 0) to use. 74 | * 75 | * - table : String|HTMLElement 76 | * A HTML table or the id of such to be parsed as input data. Related options ara startRow, 77 | * endRow, startColumn and endColumn to delimit what part of the table is used. 78 | */ 79 | 80 | // JSLint options: 81 | /*global jQuery */ 82 | 83 | (function (Highcharts) { 84 | 85 | // Utilities 86 | var each = Highcharts.each; 87 | 88 | 89 | // The Data constructor 90 | var Data = function (options) { 91 | this.init(options); 92 | }; 93 | 94 | // Set the prototype properties 95 | Highcharts.extend(Data.prototype, { 96 | 97 | /** 98 | * Initialize the Data object with the given options 99 | */ 100 | init: function (options) { 101 | this.options = options; 102 | this.columns = options.columns || this.rowsToColumns(options.rows) || []; 103 | 104 | // No need to parse or interpret anything 105 | if (this.columns.length) { 106 | this.dataFound(); 107 | 108 | // Parse and interpret 109 | } else { 110 | 111 | // Parse a CSV string if options.csv is given 112 | this.parseCSV(); 113 | 114 | // Parse a HTML table if options.table is given 115 | this.parseTable(); 116 | 117 | // Parse a Google Spreadsheet 118 | this.parseGoogleSpreadsheet(); 119 | } 120 | 121 | }, 122 | 123 | dataFound: function () { 124 | // Interpret the values into right types 125 | this.parseTypes(); 126 | 127 | // Use first row for series names? 128 | this.findHeaderRow(); 129 | 130 | // Handle columns if a handleColumns callback is given 131 | this.parsed(); 132 | 133 | // Complete if a complete callback is given 134 | this.complete(); 135 | 136 | }, 137 | 138 | /** 139 | * Parse a CSV input string 140 | */ 141 | parseCSV: function () { 142 | var self = this, 143 | options = this.options, 144 | csv = options.csv, 145 | columns = this.columns, 146 | startRow = options.startRow || 0, 147 | endRow = options.endRow || Number.MAX_VALUE, 148 | startColumn = options.startColumn || 0, 149 | endColumn = options.endColumn || Number.MAX_VALUE, 150 | lines, 151 | activeRowNo = 0; 152 | 153 | if (csv) { 154 | 155 | lines = csv 156 | .replace(/\r\n/g, "\n") // Unix 157 | .replace(/\r/g, "\n") // Mac 158 | .split(options.lineDelimiter || "\n"); 159 | 160 | each(lines, function (line, rowNo) { 161 | var trimmed = self.trim(line), 162 | isComment = trimmed.indexOf('#') === 0, 163 | isBlank = trimmed === '', 164 | items; 165 | 166 | if (rowNo >= startRow && rowNo <= endRow && !isComment && !isBlank) { 167 | items = line.split(options.itemDelimiter || ','); 168 | each(items, function (item, colNo) { 169 | if (colNo >= startColumn && colNo <= endColumn) { 170 | if (!columns[colNo - startColumn]) { 171 | columns[colNo - startColumn] = []; 172 | } 173 | 174 | columns[colNo - startColumn][activeRowNo] = item; 175 | } 176 | }); 177 | activeRowNo += 1; 178 | } 179 | }); 180 | 181 | this.dataFound(); 182 | } 183 | }, 184 | 185 | /** 186 | * Parse a HTML table 187 | */ 188 | parseTable: function () { 189 | var options = this.options, 190 | table = options.table, 191 | columns = this.columns, 192 | startRow = options.startRow || 0, 193 | endRow = options.endRow || Number.MAX_VALUE, 194 | startColumn = options.startColumn || 0, 195 | endColumn = options.endColumn || Number.MAX_VALUE, 196 | colNo; 197 | 198 | if (table) { 199 | 200 | if (typeof table === 'string') { 201 | table = document.getElementById(table); 202 | } 203 | 204 | each(table.getElementsByTagName('tr'), function (tr, rowNo) { 205 | colNo = 0; 206 | if (rowNo >= startRow && rowNo <= endRow) { 207 | each(tr.childNodes, function (item) { 208 | if ((item.tagName === 'TD' || item.tagName === 'TH') && colNo >= startColumn && colNo <= endColumn) { 209 | if (!columns[colNo]) { 210 | columns[colNo] = []; 211 | } 212 | columns[colNo][rowNo - startRow] = item.innerHTML; 213 | 214 | colNo += 1; 215 | } 216 | }); 217 | } 218 | }); 219 | 220 | this.dataFound(); // continue 221 | } 222 | }, 223 | 224 | /** 225 | * TODO: 226 | * - switchRowsAndColumns 227 | */ 228 | parseGoogleSpreadsheet: function () { 229 | var self = this, 230 | options = this.options, 231 | googleSpreadsheetKey = options.googleSpreadsheetKey, 232 | columns = this.columns, 233 | startRow = options.startRow || 0, 234 | endRow = options.endRow || Number.MAX_VALUE, 235 | startColumn = options.startColumn || 0, 236 | endColumn = options.endColumn || Number.MAX_VALUE, 237 | gr, // google row 238 | gc; // google column 239 | 240 | if (googleSpreadsheetKey) { 241 | jQuery.getJSON('https://spreadsheets.google.com/feeds/cells/' + 242 | googleSpreadsheetKey + '/' + (options.googleSpreadsheetWorksheet || 'od6') + 243 | '/public/values?alt=json-in-script&callback=?', 244 | function (json) { 245 | 246 | // Prepare the data from the spreadsheat 247 | var cells = json.feed.entry, 248 | cell, 249 | cellCount = cells.length, 250 | colCount = 0, 251 | rowCount = 0, 252 | i; 253 | 254 | // First, find the total number of columns and rows that 255 | // are actually filled with data 256 | for (i = 0; i < cellCount; i++) { 257 | cell = cells[i]; 258 | colCount = Math.max(colCount, cell.gs$cell.col); 259 | rowCount = Math.max(rowCount, cell.gs$cell.row); 260 | } 261 | 262 | // Set up arrays containing the column data 263 | for (i = 0; i < colCount; i++) { 264 | if (i >= startColumn && i <= endColumn) { 265 | // Create new columns with the length of either end-start or rowCount 266 | columns[i - startColumn] = []; 267 | 268 | // Setting the length to avoid jslint warning 269 | columns[i - startColumn].length = Math.min(rowCount, endRow - startRow); 270 | } 271 | } 272 | 273 | // Loop over the cells and assign the value to the right 274 | // place in the column arrays 275 | for (i = 0; i < cellCount; i++) { 276 | cell = cells[i]; 277 | gr = cell.gs$cell.row - 1; // rows start at 1 278 | gc = cell.gs$cell.col - 1; // columns start at 1 279 | 280 | // If both row and col falls inside start and end 281 | // set the transposed cell value in the newly created columns 282 | if (gc >= startColumn && gc <= endColumn && 283 | gr >= startRow && gr <= endRow) { 284 | columns[gc - startColumn][gr - startRow] = cell.content.$t; 285 | } 286 | } 287 | self.dataFound(); 288 | }); 289 | } 290 | }, 291 | 292 | /** 293 | * Find the header row. For now, we just check whether the first row contains 294 | * numbers or strings. Later we could loop down and find the first row with 295 | * numbers. 296 | */ 297 | findHeaderRow: function () { 298 | var headerRow = 0; 299 | each(this.columns, function (column) { 300 | if (typeof column[0] !== 'string') { 301 | headerRow = null; 302 | } 303 | }); 304 | this.headerRow = 0; 305 | }, 306 | 307 | /** 308 | * Trim a string from whitespace 309 | */ 310 | trim: function (str) { 311 | return typeof str === 'string' ? str.replace(/^\s+|\s+$/g, '') : str; 312 | }, 313 | 314 | /** 315 | * Parse numeric cells in to number types and date types in to true dates. 316 | * @param {Object} columns 317 | */ 318 | parseTypes: function () { 319 | var columns = this.columns, 320 | col = columns.length, 321 | row, 322 | val, 323 | floatVal, 324 | trimVal, 325 | dateVal; 326 | 327 | while (col--) { 328 | row = columns[col].length; 329 | while (row--) { 330 | val = columns[col][row]; 331 | floatVal = parseFloat(val); 332 | trimVal = this.trim(val); 333 | 334 | /*jslint eqeq: true*/ 335 | if (trimVal == floatVal) { // is numeric 336 | /*jslint eqeq: false*/ 337 | columns[col][row] = floatVal; 338 | 339 | // If the number is greater than milliseconds in a year, assume datetime 340 | if (floatVal > 365 * 24 * 3600 * 1000) { 341 | columns[col].isDatetime = true; 342 | } else { 343 | columns[col].isNumeric = true; 344 | } 345 | 346 | } else { // string, continue to determine if it is a date string or really a string 347 | dateVal = this.parseDate(val); 348 | 349 | if (col === 0 && typeof dateVal === 'number' && !isNaN(dateVal)) { // is date 350 | columns[col][row] = dateVal; 351 | columns[col].isDatetime = true; 352 | 353 | } else { // string 354 | columns[col][row] = trimVal === '' ? null : trimVal; 355 | } 356 | } 357 | 358 | } 359 | } 360 | }, 361 | //* 362 | dateFormats: { 363 | 'YYYY-mm-dd': { 364 | regex: '^([0-9]{4})-([0-9]{2})-([0-9]{2})$', 365 | parser: function (match) { 366 | return Date.UTC(+match[1], match[2] - 1, +match[3]); 367 | } 368 | } 369 | }, 370 | // */ 371 | /** 372 | * Parse a date and return it as a number. Overridable through options.parseDate. 373 | */ 374 | parseDate: function (val) { 375 | var parseDate = this.options.parseDate, 376 | ret, 377 | key, 378 | format, 379 | match; 380 | 381 | if (parseDate) { 382 | ret = parseDate(val); 383 | } 384 | 385 | if (typeof val === 'string') { 386 | for (key in this.dateFormats) { 387 | format = this.dateFormats[key]; 388 | match = val.match(format.regex); 389 | if (match) { 390 | ret = format.parser(match); 391 | } 392 | } 393 | } 394 | return ret; 395 | }, 396 | 397 | /** 398 | * Reorganize rows into columns 399 | */ 400 | rowsToColumns: function (rows) { 401 | var row, 402 | rowsLength, 403 | col, 404 | colsLength, 405 | columns; 406 | 407 | if (rows) { 408 | columns = []; 409 | rowsLength = rows.length; 410 | for (row = 0; row < rowsLength; row++) { 411 | colsLength = rows[row].length; 412 | for (col = 0; col < colsLength; col++) { 413 | if (!columns[col]) { 414 | columns[col] = []; 415 | } 416 | columns[col][row] = rows[row][col]; 417 | } 418 | } 419 | } 420 | return columns; 421 | }, 422 | 423 | /** 424 | * A hook for working directly on the parsed columns 425 | */ 426 | parsed: function () { 427 | if (this.options.parsed) { 428 | this.options.parsed.call(this, this.columns); 429 | } 430 | }, 431 | 432 | /** 433 | * If a complete callback function is provided in the options, interpret the 434 | * columns into a Highcharts options object. 435 | */ 436 | complete: function () { 437 | 438 | var columns = this.columns, 439 | hasXData, 440 | categories, 441 | firstCol, 442 | type, 443 | options = this.options, 444 | series, 445 | data, 446 | name, 447 | i, 448 | j; 449 | 450 | 451 | if (options.complete) { 452 | 453 | // Use first column for X data or categories? 454 | if (columns.length > 1) { 455 | firstCol = columns.shift(); 456 | if (this.headerRow === 0) { 457 | firstCol.shift(); // remove the first cell 458 | } 459 | 460 | // Use the first column for categories or X values 461 | hasXData = firstCol.isNumeric || firstCol.isDatetime; 462 | if (!hasXData) { // means type is neither datetime nor linear 463 | categories = firstCol; 464 | } 465 | 466 | if (firstCol.isDatetime) { 467 | type = 'datetime'; 468 | } 469 | } 470 | 471 | // Use the next columns for series 472 | series = []; 473 | for (i = 0; i < columns.length; i++) { 474 | if (this.headerRow === 0) { 475 | name = columns[i].shift(); 476 | } 477 | data = []; 478 | for (j = 0; j < columns[i].length; j++) { 479 | data[j] = columns[i][j] !== undefined ? 480 | (hasXData ? 481 | [firstCol[j], columns[i][j]] : 482 | columns[i][j] 483 | ) : 484 | null; 485 | } 486 | series[i] = { 487 | name: name, 488 | data: data 489 | }; 490 | } 491 | 492 | // Do the callback 493 | options.complete({ 494 | xAxis: { 495 | categories: categories, 496 | type: type 497 | }, 498 | series: series 499 | }); 500 | } 501 | } 502 | }); 503 | 504 | // Register the Data prototype and data function on Highcharts 505 | Highcharts.Data = Data; 506 | Highcharts.data = function (options) { 507 | return new Data(options); 508 | }; 509 | 510 | // Extend Chart.init so that the Chart constructor accepts a new configuration 511 | // option group, data. 512 | Highcharts.wrap(Highcharts.Chart.prototype, 'init', function (proceed, userOptions, callback) { 513 | var chart = this; 514 | 515 | if (userOptions && userOptions.data) { 516 | Highcharts.data(Highcharts.extend(userOptions.data, { 517 | complete: function (dataOptions) { 518 | 519 | // Merge series configs 520 | if (userOptions.series) { 521 | each(userOptions.series, function (series, i) { 522 | userOptions.series[i] = Highcharts.merge(series, dataOptions.series[i]); 523 | }); 524 | } 525 | 526 | // Do the merge 527 | userOptions = Highcharts.merge(dataOptions, userOptions); 528 | 529 | proceed.call(chart, userOptions, callback); 530 | } 531 | })); 532 | } else { 533 | proceed.call(chart, userOptions, callback); 534 | } 535 | }); 536 | 537 | }(Highcharts)); 538 | -------------------------------------------------------------------------------- /highcharts/static/js/highcharts/.fr-amL3gv/exporting.js: -------------------------------------------------------------------------------- 1 | /* 2 | Highcharts JS v3.0.2 (2013-06-05) 3 | Exporting module 4 | 5 | (c) 2010-2013 Torstein Hønsi 6 | 7 | License: www.highcharts.com/license 8 | */ 9 | (function(e){var y=e.Chart,v=e.addEvent,B=e.removeEvent,m=e.createElement,j=e.discardElement,t=e.css,k=e.merge,r=e.each,p=e.extend,C=Math.max,i=document,z=window,D=e.isTouchDevice,E=e.Renderer.prototype.symbols,s=e.getOptions(),w;p(s.lang,{printChart:"Print chart",downloadPNG:"Download PNG image",downloadJPEG:"Download JPEG image",downloadPDF:"Download PDF document",downloadSVG:"Download SVG vector image",contextButtonTitle:"Chart context menu"});s.navigation={menuStyle:{border:"1px solid #A0A0A0", 10 | background:"#FFFFFF",padding:"5px 0"},menuItemStyle:{padding:"0 10px",background:"none",color:"#303030",fontSize:D?"14px":"11px"},menuItemHoverStyle:{background:"#4572A5",color:"#FFFFFF"},buttonOptions:{symbolFill:"#E0E0E0",symbolSize:14,symbolStroke:"#666",symbolStrokeWidth:3,symbolX:12.5,symbolY:10.5,align:"right",buttonSpacing:3,height:22,theme:{fill:"white",stroke:"none"},verticalAlign:"top",width:24}};s.exporting={type:"image/png",url:"http://export.highcharts.com/",buttons:{contextButton:{symbol:"menu", 11 | _titleKey:"contextButtonTitle",menuItems:[{textKey:"printChart",onclick:function(){this.print()}},{separator:!0},{textKey:"downloadPNG",onclick:function(){this.exportChart()}},{textKey:"downloadJPEG",onclick:function(){this.exportChart({type:"image/jpeg"})}},{textKey:"downloadPDF",onclick:function(){this.exportChart({type:"application/pdf"})}},{textKey:"downloadSVG",onclick:function(){this.exportChart({type:"image/svg+xml"})}}]}}};e.post=function(a,b){var c,d;d=m("form",{method:"post",action:a,enctype:"multipart/form-data"}, 12 | {display:"none"},i.body);for(c in b)m("input",{type:"hidden",name:c,value:b[c]},null,d);d.submit();j(d)};p(y.prototype,{getSVG:function(a){var b=this,c,d,x,g,f=k(b.options,a);if(!i.createElementNS)i.createElementNS=function(a,b){return i.createElement(b)};a=m("div",null,{position:"absolute",top:"-9999em",width:b.chartWidth+"px",height:b.chartHeight+"px"},i.body);d=b.renderTo.style.width;g=b.renderTo.style.height;d=f.exporting.sourceWidth||f.chart.width||/px$/.test(d)&&parseInt(d,10)||600;g=f.exporting.sourceHeight|| 13 | f.chart.height||/px$/.test(g)&&parseInt(g,10)||400;p(f.chart,{animation:!1,renderTo:a,forExport:!0,width:d,height:g});f.exporting.enabled=!1;f.series=[];r(b.series,function(a){x=k(a.options,{animation:!1,showCheckbox:!1,visible:a.visible});x.isInternal||f.series.push(x)});c=new e.Chart(f,b.callback);r(["xAxis","yAxis"],function(a){r(b[a],function(b,d){var f=c[a][d],e=b.getExtremes(),g=e.userMin,e=e.userMax;(g!==void 0||e!==void 0)&&f.setExtremes(g,e,!0,!1)})});d=c.container.innerHTML;f=null;c.destroy(); 14 | j(a);d=d.replace(/zIndex="[^"]+"/g,"").replace(/isShadow="[^"]+"/g,"").replace(/symbolName="[^"]+"/g,"").replace(/jQuery[0-9]+="[^"]+"/g,"").replace(/url\([^#]+#/g,"url(#").replace(/.*?$/,"").replace(/ /g," ").replace(/­/g,"­").replace(//g, 15 | 'xlink:href="$1"/>').replace(/id=([^" >]+)/g,'id="$1"').replace(/class=([^" >]+)/g,'class="$1"').replace(/ transform /g," ").replace(/:(path|rect)/g,"$1").replace(/style="([^"]+)"/g,function(a){return a.toLowerCase()});d=d.replace(/(url\(#highcharts-[0-9]+)"/g,"$1").replace(/"/g,"'");d.match(/ xmlns="/g).length===2&&(d=d.replace(/xmlns="[^"]+"/,""));return d},exportChart:function(a,b){var a=a||{},c=this.options.exporting,c=this.getSVG(k({chart:{borderRadius:0}},c.chartOptions,b,{exporting:{sourceWidth:a.sourceWidth|| 16 | c.sourceWidth,sourceHeight:a.sourceHeight||c.sourceHeight}})),a=k(this.options.exporting,a);e.post(a.url,{filename:a.filename||"chart",type:a.type,width:a.width||0,scale:a.scale||2,svg:c})},print:function(){var a=this,b=a.container,c=[],d=b.parentNode,e=i.body,g=e.childNodes;if(!a.isPrinting)a.isPrinting=!0,r(g,function(a,b){if(a.nodeType===1)c[b]=a.style.display,a.style.display="none"}),e.appendChild(b),z.focus(),z.print(),setTimeout(function(){d.appendChild(b);r(g,function(a,b){if(a.nodeType=== 17 | 1)a.style.display=c[b]});a.isPrinting=!1},1E3)},contextMenu:function(a,b,c,d,e,g,f){var h=this,q=h.options.navigation,n=q.menuItemStyle,o=h.chartWidth,i=h.chartHeight,A="cache-"+a,l=h[A],k=C(e,g),u,j,s;if(!l)h[A]=l=m("div",{className:"highcharts-"+a},{position:"absolute",zIndex:1E3,padding:k+"px"},h.container),u=m("div",null,p({MozBoxShadow:"3px 3px 10px #888",WebkitBoxShadow:"3px 3px 10px #888",boxShadow:"3px 3px 10px #888"},q.menuStyle),l),j=function(){t(l,{display:"none"});f&&f.setState(0);h.openMenu= 18 | !1},v(l,"mouseleave",function(){s=setTimeout(j,500)}),v(l,"mouseenter",function(){clearTimeout(s)}),r(b,function(a){if(a){var b=a.separator?m("hr",null,null,u):m("div",{onmouseover:function(){t(this,q.menuItemHoverStyle)},onmouseout:function(){t(this,n)},onclick:function(){j();a.onclick.apply(h,arguments)},innerHTML:a.text||h.options.lang[a.textKey]},p({cursor:"pointer"},n),u);h.exportDivElements.push(b)}}),h.exportDivElements.push(u,l),h.exportMenuWidth=l.offsetWidth,h.exportMenuHeight=l.offsetHeight; 19 | a={display:"block"};c+h.exportMenuWidth>o?a.right=o-c-e-k+"px":a.left=c-k+"px";d+g+h.exportMenuHeight>i?a.bottom=i-d-k+"px":a.top=d+g-k+"px";t(l,a);h.openMenu=!0},addButton:function(a){var b=this,c=b.renderer,a=k(b.options.navigation.buttonOptions,a),d=a.onclick,i=a.menuItems,g,f,h={stroke:a.symbolStroke,fill:a.symbolFill},q=a.symbolSize||12;if(!b.btnCount)b.btnCount=0;b.btnCount++;if(!b.exportDivElements)b.exportDivElements=[],b.exportSVGElements=[];if(a.enabled!==!1){var n=a.theme,o=n.states,m= 20 | o&&o.hover,o=o&&o.select,j;delete n.states;d?j=function(){d.apply(b,arguments)}:i&&(j=function(){b.contextMenu("contextmenu",i,f.translateX,f.translateY,f.width,f.height,f);f.setState(2)});a.text&&a.symbol?n.paddingLeft=e.pick(n.paddingLeft,25):a.text||p(n,{width:a.width,height:a.height,padding:0});f=c.button(a.text,0,0,j,n,m,o).attr({title:b.options.lang[a._titleKey],"stroke-linecap":"round"});a.symbol&&(g=c.symbol(a.symbol,a.symbolX-q/2,a.symbolY-q/2,q,q).attr(p(h,{"stroke-width":a.symbolStrokeWidth|| 21 | 1,zIndex:1})).add(f));f.add().align(p(a,{width:f.width,x:e.pick(a.x,w)}),!0,"spacingBox");w+=(f.width+a.buttonSpacing)*(a.align==="right"?-1:1);b.exportSVGElements.push(f,g)}},destroyExport:function(a){var a=a.target,b,c;for(b=0;b