├── highcharts
├── __init__.py
├── templatetags
│ ├── __init__.py
│ └── highcharts_tags.py
├── models.py
├── templates
│ └── highcharts
│ │ ├── highcharts_theme.html
│ │ └── highcharts_js.html
├── utils.py
├── views
│ ├── area.py
│ ├── line.py
│ ├── __init__.py
│ ├── pie.py
│ ├── speedometer.py
│ ├── bar.py
│ ├── heatmap.py
│ ├── polar.py
│ ├── common.py
│ └── multiple_axes.py
└── static
│ └── js
│ └── highcharts
│ ├── modules
│ ├── no-data-to-display.js
│ ├── funnel.js
│ ├── solid-gauge.js
│ ├── no-data-to-display.src.js
│ ├── data.js
│ ├── solid-gauge.src.js
│ ├── heatmap.js
│ ├── exporting.js
│ └── funnel.src.js
│ ├── themes
│ ├── grid-light.js
│ ├── skies.js
│ ├── sand-signika.js
│ ├── grid.js
│ ├── dark-unica.js
│ ├── dark-green.js
│ ├── dark-blue.js
│ └── gray.js
│ ├── .fr-amL3gv
│ ├── funnel.js
│ ├── skies.js
│ ├── grid.js
│ ├── annotations.js
│ ├── data.js
│ ├── dark-green.js
│ ├── dark-blue.js
│ ├── gray.js
│ ├── exporting.js
│ ├── funnel.src.js
│ └── annotations.src.js
│ ├── adapters
│ └── standalone-framework.js
│ ├── stock_exporting.js
│ ├── heatmap.js
│ └── technical-indicators.src.js
├── .gitignore
├── MANIFEST.in
├── README.rst
├── docs
├── index.rst
├── make.bat
├── Makefile
└── conf.py
├── setup.py
├── LICENSE
└── README.md
/highcharts/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/highcharts/templatetags/__init__.py:
--------------------------------------------------------------------------------
1 | __author__ = 'ernesto'
2 |
--------------------------------------------------------------------------------
/highcharts/models.py:
--------------------------------------------------------------------------------
1 | # empty models.py - yes, that's a django requisite
2 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .idea
2 | *.pyc
3 | demo
4 | *.sqlite3
5 | manage.py
6 | django_highcharts.egg-info
7 | build
8 | dist
9 | manage.py
10 |
--------------------------------------------------------------------------------
/MANIFEST.in:
--------------------------------------------------------------------------------
1 | include LICENSE
2 | include README.md
3 | recursive-include highcharts/static *
4 | recursive-include highcharts/templates *
5 |
--------------------------------------------------------------------------------
/highcharts/templates/highcharts/highcharts_theme.html:
--------------------------------------------------------------------------------
1 |
4 | {% load static %}
5 | {% if theme_name %}
6 |
7 | {% endif %}
--------------------------------------------------------------------------------
/highcharts/utils.py:
--------------------------------------------------------------------------------
1 | from django.conf import settings
2 |
3 |
4 | def get_static_url(subfix='highcharts'):
5 | static_url = getattr(settings, 'STATIC_URL', None)
6 | if static_url:
7 | return static_url
8 | else: # To old django versions
9 | return '%s%s/' % (getattr(settings, 'MEDIA_URL', None), subfix)
10 |
--------------------------------------------------------------------------------
/README.rst:
--------------------------------------------------------------------------------
1 | #################
2 | Django Highcharts
3 | #################
4 | This is a Fork of novapost package to
5 | generate charts in your Django application using Highcharts helpers.
6 |
7 | - Pie with drilldown charts
8 | - 3D Pie Options
9 | - Speedometer charts
10 | - Multiple Axes charts
11 | - Area charts
12 | - Bar charts
13 | - Heatmap charts
14 | - Polar Spider web charts
15 | - HighStock basic charts
16 |
17 | * `Source code is on Github `_
18 |
--------------------------------------------------------------------------------
/docs/index.rst:
--------------------------------------------------------------------------------
1 | .. django-highcharts documentation master file, created by
2 | sphinx-quickstart on Thu Feb 11 15:28:11 2016.
3 | You can adapt this file completely to your liking, but it should at least
4 | contain the root `toctree` directive.
5 |
6 | Welcome to django-highcharts's documentation!
7 | =============================================
8 |
9 | Contents:
10 |
11 | .. toctree::
12 | :maxdepth: 2
13 |
14 |
15 |
16 | Indices and tables
17 | ==================
18 |
19 | * :ref:`genindex`
20 | * :ref:`modindex`
21 | * :ref:`search`
22 |
23 |
--------------------------------------------------------------------------------
/highcharts/views/area.py:
--------------------------------------------------------------------------------
1 | from django.views.generic import View
2 | from highcharts.views.common import HighChartsDualAxisView
3 |
4 |
5 | class HighChartsAreaView(HighChartsDualAxisView, View):
6 | chart_type = 'area'
7 | _series = []
8 |
9 | def get_data(self):
10 | data = super(HighChartsAreaView, self).get_data()
11 | data['series'] = self.series
12 | return data
13 |
14 | @property
15 | def series(self):
16 | return self._series
17 |
18 | @series.setter
19 | def series(self, value):
20 | self._series = value
21 |
--------------------------------------------------------------------------------
/highcharts/views/line.py:
--------------------------------------------------------------------------------
1 | from django.views.generic import View
2 | from highcharts.views.common import HighChartsDualAxisView
3 |
4 |
5 | class HighChartsLineView(HighChartsDualAxisView, View):
6 | categories = []
7 | _series = []
8 |
9 | def get_data(self):
10 | data = super(HighChartsLineView, self).get_data()
11 | data['xAxis']['categories'] = self.categories
12 | data['series'] = self.series
13 | return data
14 |
15 | @property
16 | def series(self):
17 | return self._series
18 |
19 | @series.setter
20 | def series(self, value):
21 | self._series = value
--------------------------------------------------------------------------------
/highcharts/views/__init__.py:
--------------------------------------------------------------------------------
1 | from highcharts.views.bar import HighChartsBarView
2 | from highcharts.views.line import HighChartsLineView
3 | from highcharts.views.area import HighChartsAreaView
4 | from highcharts.views.multiple_axes import HighChartsMultiAxesView
5 | from highcharts.views.pie import HighChartsPieView
6 | from highcharts.views.speedometer import HighChartsSpeedometerView
7 | from highcharts.views.multiple_axes import HighChartsStockView
8 | from highcharts.views.heatmap import HighChartsHeatMapView
9 | from highcharts.views.polar import HighChartsPolarView
10 | from highcharts.views.multiple_axes import HighChartsMultiXAxesView
--------------------------------------------------------------------------------
/highcharts/views/pie.py:
--------------------------------------------------------------------------------
1 | from django.views.generic import View
2 | from highcharts.views.common import HighChartsBasicView
3 |
4 |
5 | class HighChartsPieView(HighChartsBasicView, View):
6 | chart_type = 'pie'
7 | options3d = ''
8 | _series = []
9 | _drilldown = []
10 |
11 | def get_data(self):
12 | data = super(HighChartsPieView, self).get_data()
13 | data['series'] = self.series
14 | data['drilldown'] = self.drilldown
15 | data['chart']['options3d'] = self.options3d
16 | return data
17 |
18 | @property
19 | def series(self):
20 | return self._series
21 |
22 | @property
23 | def drilldown(self):
24 | return self._drilldown
25 |
26 | @series.setter
27 | def series(self, value):
28 | self._series = value
29 |
30 | @drilldown.setter
31 | def drilldown(self, value):
32 | self._drilldown = value
--------------------------------------------------------------------------------
/highcharts/views/speedometer.py:
--------------------------------------------------------------------------------
1 | from django.views.generic import View
2 | from highcharts.views.common import HighChartsDualAxisView
3 |
4 |
5 | class HighChartsSpeedometerView(HighChartsDualAxisView, View):
6 | chart_type = 'gauge'
7 |
8 | _series = []
9 | _yaxis = []
10 | _pane = []
11 |
12 | def get_data(self):
13 | data = super(HighChartsSpeedometerView, self).get_data()
14 | data['series'] = self.series
15 | data['yAxis'] = self.yaxis
16 | data['pane'] = self.pane
17 | return data
18 |
19 | @property
20 | def series(self):
21 | return self._series
22 |
23 | @property
24 | def yaxis(self):
25 | return self._yaxis
26 |
27 | @property
28 | def pane(self):
29 | return self._pane
30 |
31 | @series.setter
32 | def series(self, value):
33 | self._series = value
34 |
35 | @yaxis.setter
36 | def yaxis(self, value):
37 | self._yaxis = value
38 |
39 | @pane.setter
40 | def pane(self, value):
41 | self._pane = value
--------------------------------------------------------------------------------
/highcharts/templatetags/highcharts_tags.py:
--------------------------------------------------------------------------------
1 | __author__ = 'ernesto.arbitrio@gmail.com'
2 |
3 | from django.template import Library
4 | from ..utils import get_static_url
5 |
6 | register = Library()
7 |
8 |
9 | def highcharts_js(context,
10 | activate_highcharts=True,
11 | enable_highstock=False,
12 | enable_3d=False,
13 | enable_heatmap=False):
14 | return {
15 | 'STATIC_URL': get_static_url(),
16 | 'activate_highcharts': activate_highcharts,
17 | 'enable_highstock': enable_highstock,
18 | 'enable_3d': enable_3d,
19 | 'enable_heatmap': enable_heatmap
20 | }
21 |
22 |
23 | def set_highcharts_theme(context, theme_name=None):
24 | return {
25 | 'STATIC_URL': get_static_url(),
26 | 'theme_name': '{}{}'.format(theme_name, '.js')
27 | }
28 | register.inclusion_tag("highcharts/highcharts_js.html", takes_context=True)(highcharts_js)
29 | register.inclusion_tag("highcharts/highcharts_theme.html", takes_context=True)(set_highcharts_theme)
30 |
--------------------------------------------------------------------------------
/highcharts/views/bar.py:
--------------------------------------------------------------------------------
1 | from django.views.generic import View
2 | from highcharts.views.common import HighChartsDualAxisView
3 |
4 |
5 | class HighChartsBarView(HighChartsDualAxisView, View):
6 | chart_type = 'bar'
7 | categories = []
8 | _series = []
9 |
10 | def get_data(self):
11 | data = super(HighChartsBarView, self).get_data()
12 | data['xAxis']['categories'] = self.categories
13 | data['series'] = self.series
14 | return data
15 |
16 | @property
17 | def series(self):
18 | return self._series
19 |
20 | @series.setter
21 | def series(self, value):
22 | self._series = value
23 |
24 |
25 | class HighChartsStackedView(HighChartsBarView):
26 |
27 | @property
28 | def plot_options(self):
29 | plot_options = super(HighChartsBarView, self).plot_options
30 | if plot_options is None:
31 | plot_options = {}
32 | if 'series' not in plot_options:
33 | plot_options['series'] = {}
34 | plot_options['series']['stacking'] = 'normal'
35 | return plot_options
36 |
37 |
38 | class HighChartsColumnView(HighChartsBarView):
39 | chart_type = 'column'
40 |
--------------------------------------------------------------------------------
/highcharts/templates/highcharts/highcharts_js.html:
--------------------------------------------------------------------------------
1 |
4 | {% load static %}
5 | {% if activate_highcharts %}
6 | {% if enable_highstock %}
7 |
8 |
9 |
10 |
11 | {% else %}
12 |
13 |
14 |
15 |
16 | {% endif %}
17 | {% if enable_3d %}
18 |
19 | {% endif %}
20 | {% if enable_heatmap %}
21 |
22 | {% endif %}
23 | {% endif %}
--------------------------------------------------------------------------------
/highcharts/views/heatmap.py:
--------------------------------------------------------------------------------
1 | from django.views.generic import View
2 | from highcharts.views.common import HighChartsDualAxisView
3 |
4 |
5 | class HighChartsHeatMapView(HighChartsDualAxisView, View):
6 | chart_type = 'heatmap'
7 | margin_top = 40
8 | margin_bottom = 40
9 | categories = []
10 | _series = []
11 | _yaxis = []
12 | legend = {'align': 'right',
13 | 'layout': 'vertical',
14 | 'margin': 0,
15 | 'verticalAlign': 'top',
16 | 'y': 25,
17 | 'symbolHeight': 320}
18 |
19 | def get_data(self):
20 | data = super(HighChartsHeatMapView, self).get_data()
21 | data['series'] = self.series
22 | data['yAxis'] = self.yaxis
23 | data['chart']['marginTop'] = self.margin_top
24 | data['chart']['marginBottom'] = self.margin_bottom
25 | data['xAxis']['categories'] = self.categories
26 | data['legend'] = self.legend
27 | return data
28 |
29 | @property
30 | def series(self):
31 | return self._series
32 |
33 | @property
34 | def yaxis(self):
35 | return self._yaxis
36 |
37 | @series.setter
38 | def series(self, value):
39 | self._series = value
40 |
41 | @yaxis.setter
42 | def yaxis(self, value):
43 | self._yaxis = value
--------------------------------------------------------------------------------
/highcharts/views/polar.py:
--------------------------------------------------------------------------------
1 | from django.views.generic import View
2 | from highcharts.views.common import HighChartsDualAxisView
3 |
4 |
5 | class HighChartsPolarView(HighChartsDualAxisView, View):
6 | chart_type = 'line'
7 | polar = True
8 | pane_size = '80%'
9 | categories = []
10 | _series = []
11 | _yaxis = []
12 | legend = {
13 | 'align': 'right',
14 | 'verticalAlign': 'top',
15 | 'y': 70,
16 | 'layout': 'vertical'
17 | }
18 | tickmarkPlacement = 'on'
19 | lineWidth = 0
20 |
21 | def get_data(self):
22 | data = super(HighChartsPolarView, self).get_data()
23 | data['series'] = self.series
24 | data['yAxis'] = self.yaxis
25 | data['chart']['polar'] = self.polar
26 | data['pane'] = self.pane_size
27 | data['xAxis']['categories'] = self.categories
28 | data['xAxis']['tickmarkPlacement'] = self.tickmarkPlacement
29 | data['xAxis']['lineWidth'] = self.lineWidth
30 | data['legend'] = self.legend
31 | return data
32 |
33 | @property
34 | def series(self):
35 | return self._series
36 |
37 | @property
38 | def yaxis(self):
39 | return self._yaxis
40 |
41 | @series.setter
42 | def series(self, value):
43 | self._series = value
44 |
45 | @yaxis.setter
46 | def yaxis(self, value):
47 | self._yaxis = value
--------------------------------------------------------------------------------
/highcharts/static/js/highcharts/modules/no-data-to-display.js:
--------------------------------------------------------------------------------
1 | /*
2 | Highcharts JS v4.0.1 (2014-04-24)
3 | Plugin for displaying a message when there is no data visible in chart.
4 |
5 | (c) 2010-2014 Highsoft AS
6 | Author: Oystein Moseng
7 |
8 | License: www.highcharts.com/license
9 | */
10 | (function(c){function f(){return!!this.points.length}function g(){this.hasData()?this.hideNoData():this.showNoData()}var d=c.seriesTypes,e=c.Chart.prototype,h=c.getOptions(),i=c.extend;i(h.lang,{noData:"No data to display"});h.noData={position:{x:0,y:0,align:"center",verticalAlign:"middle"},attr:{},style:{fontWeight:"bold",fontSize:"12px",color:"#60606a"}};if(d.pie)d.pie.prototype.hasData=f;if(d.gauge)d.gauge.prototype.hasData=f;if(d.waterfall)d.waterfall.prototype.hasData=f;c.Series.prototype.hasData=
11 | function(){return this.dataMax!==void 0&&this.dataMin!==void 0};e.showNoData=function(a){var b=this.options,a=a||b.lang.noData,b=b.noData;if(!this.noDataLabel)this.noDataLabel=this.renderer.label(a,0,0,null,null,null,null,null,"no-data").attr(b.attr).css(b.style).add(),this.noDataLabel.align(i(this.noDataLabel.getBBox(),b.position),!1,"plotBox")};e.hideNoData=function(){if(this.noDataLabel)this.noDataLabel=this.noDataLabel.destroy()};e.hasData=function(){for(var a=this.series,b=a.length;b--;)if(a[b].hasData()&&
12 | !a[b].options.isInternal)return!0;return!1};e.callbacks.push(function(a){c.addEvent(a,"load",g);c.addEvent(a,"redraw",g)})})(Highcharts);
13 |
--------------------------------------------------------------------------------
/highcharts/static/js/highcharts/themes/grid-light.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Grid-light theme for Highcharts JS
3 | * @author Torstein Honsi
4 | */
5 |
6 | // Load the fonts
7 | Highcharts.createElement('link', {
8 | href: 'http://fonts.googleapis.com/css?family=Dosis:400,600',
9 | rel: 'stylesheet',
10 | type: 'text/css'
11 | }, null, document.getElementsByTagName('head')[0]);
12 |
13 | Highcharts.theme = {
14 | colors: ["#7cb5ec", "#f7a35c", "#90ee7e", "#7798BF", "#aaeeee", "#ff0066", "#eeaaee",
15 | "#55BF3B", "#DF5353", "#7798BF", "#aaeeee"],
16 | chart: {
17 | backgroundColor: null,
18 | style: {
19 | fontFamily: "Dosis, sans-serif"
20 | }
21 | },
22 | title: {
23 | style: {
24 | fontSize: '16px',
25 | fontWeight: 'bold',
26 | textTransform: 'uppercase'
27 | }
28 | },
29 | tooltip: {
30 | borderWidth: 0,
31 | backgroundColor: 'rgba(219,219,216,0.8)',
32 | shadow: false
33 | },
34 | legend: {
35 | itemStyle: {
36 | fontWeight: 'bold',
37 | fontSize: '13px'
38 | }
39 | },
40 | xAxis: {
41 | gridLineWidth: 1,
42 | labels: {
43 | style: {
44 | fontSize: '12px'
45 | }
46 | }
47 | },
48 | yAxis: {
49 | minorTickInterval: 'auto',
50 | title: {
51 | style: {
52 | textTransform: 'uppercase'
53 | }
54 | },
55 | labels: {
56 | style: {
57 | fontSize: '12px'
58 | }
59 | }
60 | },
61 | plotOptions: {
62 | candlestick: {
63 | lineColor: '#404048'
64 | }
65 | },
66 |
67 |
68 | // General
69 | background2: '#F0F0EA'
70 |
71 | };
72 |
73 | // Apply the theme
74 | Highcharts.setOptions(Highcharts.theme);
75 |
--------------------------------------------------------------------------------
/setup.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | from __future__ import unicode_literals
3 | from os.path import abspath, dirname, join
4 | from setuptools import find_packages, setup
5 |
6 |
7 | def read_relative_file(filename):
8 | """Returns contents of the given file, whose path is supposed relative
9 | to this module."""
10 | with open(join(dirname(abspath(__file__)), filename)) as f:
11 | return f.read()
12 |
13 |
14 | if __name__ == '__main__': # ``import setup`` doesn't trigger setup().
15 | setup(
16 | name='django-highcharts',
17 | version='0.1.7',
18 | description="Django Highcharts helpers",
19 | long_description=read_relative_file('README.rst'),
20 | classifiers=['Development Status :: 4 - Beta',
21 | 'Environment :: Web Environment',
22 | 'Framework :: Django',
23 | 'Intended Audience :: Developers',
24 | 'License :: OSI Approved :: BSD License',
25 | 'Programming Language :: Python',
26 | 'Programming Language :: Python :: 2.7'
27 | ],
28 | keywords='django chart highcharts ajax class based views',
29 | author='ernestoarbitrio',
30 | author_email='ernesto.arbitrio@gmail.com',
31 | url='https://github.com/ernestoarbitrio/django-highcharts',
32 | license='BSD Licence',
33 | packages=find_packages(),
34 | include_package_data=True,
35 | zip_safe=False,
36 | install_requires=[
37 | 'six',
38 | 'django-braces',
39 | ]
40 | )
41 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/highcharts/static/js/highcharts/.fr-amL3gv/funnel.js:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | Highcharts funnel module, Beta
4 |
5 | (c) 2010-2012 Torstein Hønsi
6 |
7 | License: www.highcharts.com/license
8 | */
9 | (function(l){var B=l.getOptions().plotOptions,q=l.seriesTypes,D=l.merge,C=function(){},z=l.each;B.funnel=D(B.pie,{center:["50%","50%"],width:"90%",neckWidth:"30%",height:"100%",neckHeight:"25%",dataLabels:{connectorWidth:1,connectorColor:"#606060"},size:!0,states:{select:{color:"#C0C0C0",borderColor:"#000000",shadow:!1}}});q.funnel=l.extendClass(q.pie,{type:"funnel",animate:C,translate:function(){var a=function(i,a){return/%$/.test(i)?a*parseInt(i,10)/100:parseInt(i,10)},f=0,d=this.chart,e=d.plotWidth,
10 | d=d.plotHeight,g=0,c=this.options,j=c.center,b=a(j[0],e),j=a(j[0],d),l=a(c.width,e),h,r,m=a(c.height,d),s=a(c.neckWidth,e),u=a(c.neckHeight,d),v=m-u,a=this.data,w,x,q=c.dataLabels.position==="left"?1:0,y,n,A,o,k,t,p;this.getWidthAt=r=function(i){return i>m-u?s:s+(l-s)*((m-u-i)/(m-u))};this.getX=function(i,a){return b+(a?-1:1)*(r(i)/2+c.dataLabels.distance)};this.center=[b,j,m];this.centerX=b;z(a,function(a){f+=a.y});z(a,function(a){p=null;x=f?a.y/f:0;n=g*m;k=n+x*m;h=r(n);y=b-h/2;A=y+h;h=r(k);o=b-
11 | h/2;t=o+h;n>v?(y=o=b-s/2,A=t=b+s/2):k>v&&(p=k,h=r(v),o=b-h/2,t=o+h,k=v);w=["M",y,n,"L",A,n,t,k];p&&w.push(t,p,o,p);w.push(o,k,"Z");a.shapeType="path";a.shapeArgs={d:w};a.percentage=x*100;a.plotX=b;a.plotY=(n+(p||k))/2;a.tooltipPos=[b,a.plotY];a.slice=C;a.half=q;g+=x});this.setTooltipPoints()},drawPoints:function(){var a=this,f=a.options,d=a.chart.renderer;z(a.data,function(e){var g=e.graphic,c=e.shapeArgs;g?g.animate(c):e.graphic=d.path(c).attr({fill:e.color,stroke:f.borderColor,"stroke-width":f.borderWidth}).add(a.group)})},
12 | drawDataLabels:function(){var a=this.data,f=this.options.dataLabels.distance,d,e,g,c=a.length,j,b;for(this.center[2]-=2*f;c--;)g=a[c],e=(d=g.half)?1:-1,b=g.plotY,j=this.getX(b,d),g.labelPos=[0,b,j+(f-5)*e,b,j+f*e,b,d?"right":"left",0];q.pie.prototype.drawDataLabels.call(this)}})})(Highcharts);
13 |
--------------------------------------------------------------------------------
/highcharts/static/js/highcharts/.fr-amL3gv/skies.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Skies theme for Highcharts JS
3 | * @author Torstein Hønsi
4 | */
5 |
6 | Highcharts.theme = {
7 | colors: ["#514F78", "#42A07B", "#9B5E4A", "#72727F", "#1F949A", "#82914E", "#86777F", "#42A07B"],
8 | chart: {
9 | className: 'skies',
10 | borderWidth: 0,
11 | plotShadow: true,
12 | plotBackgroundImage: '/demo/gfx/skies.jpg',
13 | plotBackgroundColor: {
14 | linearGradient: [0, 0, 250, 500],
15 | stops: [
16 | [0, 'rgba(255, 255, 255, 1)'],
17 | [1, 'rgba(255, 255, 255, 0)']
18 | ]
19 | },
20 | plotBorderWidth: 1
21 | },
22 | title: {
23 | style: {
24 | color: '#3E576F',
25 | font: '16px Lucida Grande, Lucida Sans Unicode, Verdana, Arial, Helvetica, sans-serif'
26 | }
27 | },
28 | subtitle: {
29 | style: {
30 | color: '#6D869F',
31 | font: '12px Lucida Grande, Lucida Sans Unicode, Verdana, Arial, Helvetica, sans-serif'
32 | }
33 | },
34 | xAxis: {
35 | gridLineWidth: 0,
36 | lineColor: '#C0D0E0',
37 | tickColor: '#C0D0E0',
38 | labels: {
39 | style: {
40 | color: '#666',
41 | fontWeight: 'bold'
42 | }
43 | },
44 | title: {
45 | style: {
46 | color: '#666',
47 | font: '12px Lucida Grande, Lucida Sans Unicode, Verdana, Arial, Helvetica, sans-serif'
48 | }
49 | }
50 | },
51 | yAxis: {
52 | alternateGridColor: 'rgba(255, 255, 255, .5)',
53 | lineColor: '#C0D0E0',
54 | tickColor: '#C0D0E0',
55 | tickWidth: 1,
56 | labels: {
57 | style: {
58 | color: '#666',
59 | fontWeight: 'bold'
60 | }
61 | },
62 | title: {
63 | style: {
64 | color: '#666',
65 | font: '12px Lucida Grande, Lucida Sans Unicode, Verdana, Arial, Helvetica, sans-serif'
66 | }
67 | }
68 | },
69 | legend: {
70 | itemStyle: {
71 | font: '9pt Trebuchet MS, Verdana, sans-serif',
72 | color: '#3E576F'
73 | },
74 | itemHoverStyle: {
75 | color: 'black'
76 | },
77 | itemHiddenStyle: {
78 | color: 'silver'
79 | }
80 | },
81 | labels: {
82 | style: {
83 | color: '#3E576F'
84 | }
85 | }
86 | };
87 |
88 | // Apply the theme
89 | var highchartsOptions = Highcharts.setOptions(Highcharts.theme);
90 |
--------------------------------------------------------------------------------
/highcharts/static/js/highcharts/themes/skies.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Skies theme for Highcharts JS
3 | * @author Torstein Honsi
4 | */
5 |
6 | Highcharts.theme = {
7 | colors: ["#514F78", "#42A07B", "#9B5E4A", "#72727F", "#1F949A", "#82914E", "#86777F", "#42A07B"],
8 | chart: {
9 | className: 'skies',
10 | borderWidth: 0,
11 | plotShadow: true,
12 | plotBackgroundImage: 'http://www.highcharts.com/demo/gfx/skies.jpg',
13 | plotBackgroundColor: {
14 | linearGradient: [0, 0, 250, 500],
15 | stops: [
16 | [0, 'rgba(255, 255, 255, 1)'],
17 | [1, 'rgba(255, 255, 255, 0)']
18 | ]
19 | },
20 | plotBorderWidth: 1
21 | },
22 | title: {
23 | style: {
24 | color: '#3E576F',
25 | font: '16px Lucida Grande, Lucida Sans Unicode, Verdana, Arial, Helvetica, sans-serif'
26 | }
27 | },
28 | subtitle: {
29 | style: {
30 | color: '#6D869F',
31 | font: '12px Lucida Grande, Lucida Sans Unicode, Verdana, Arial, Helvetica, sans-serif'
32 | }
33 | },
34 | xAxis: {
35 | gridLineWidth: 0,
36 | lineColor: '#C0D0E0',
37 | tickColor: '#C0D0E0',
38 | labels: {
39 | style: {
40 | color: '#666',
41 | fontWeight: 'bold'
42 | }
43 | },
44 | title: {
45 | style: {
46 | color: '#666',
47 | font: '12px Lucida Grande, Lucida Sans Unicode, Verdana, Arial, Helvetica, sans-serif'
48 | }
49 | }
50 | },
51 | yAxis: {
52 | alternateGridColor: 'rgba(255, 255, 255, .5)',
53 | lineColor: '#C0D0E0',
54 | tickColor: '#C0D0E0',
55 | tickWidth: 1,
56 | labels: {
57 | style: {
58 | color: '#666',
59 | fontWeight: 'bold'
60 | }
61 | },
62 | title: {
63 | style: {
64 | color: '#666',
65 | font: '12px Lucida Grande, Lucida Sans Unicode, Verdana, Arial, Helvetica, sans-serif'
66 | }
67 | }
68 | },
69 | legend: {
70 | itemStyle: {
71 | font: '9pt Trebuchet MS, Verdana, sans-serif',
72 | color: '#3E576F'
73 | },
74 | itemHoverStyle: {
75 | color: 'black'
76 | },
77 | itemHiddenStyle: {
78 | color: 'silver'
79 | }
80 | },
81 | labels: {
82 | style: {
83 | color: '#3E576F'
84 | }
85 | }
86 | };
87 |
88 | // Apply the theme
89 | var highchartsOptions = Highcharts.setOptions(Highcharts.theme);
90 |
--------------------------------------------------------------------------------
/highcharts/static/js/highcharts/themes/sand-signika.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Sand-Signika theme for Highcharts JS
3 | * @author Torstein Honsi
4 | */
5 |
6 | // Load the fonts
7 | Highcharts.createElement('link', {
8 | href: 'http://fonts.googleapis.com/css?family=Signika:400,700',
9 | rel: 'stylesheet',
10 | type: 'text/css'
11 | }, null, document.getElementsByTagName('head')[0]);
12 |
13 | // Add the background image to the container
14 | Highcharts.wrap(Highcharts.Chart.prototype, 'getContainer', function (proceed) {
15 | proceed.call(this);
16 | this.container.style.background = 'url(http://www.highcharts.com/samples/graphics/sand.png)';
17 | });
18 |
19 |
20 | Highcharts.theme = {
21 | colors: ["#f45b5b", "#8085e9", "#8d4654", "#7798BF", "#aaeeee", "#ff0066", "#eeaaee",
22 | "#55BF3B", "#DF5353", "#7798BF", "#aaeeee"],
23 | chart: {
24 | backgroundColor: null,
25 | style: {
26 | fontFamily: "Signika, serif"
27 | }
28 | },
29 | title: {
30 | style: {
31 | color: 'black',
32 | fontSize: '16px',
33 | fontWeight: 'bold'
34 | }
35 | },
36 | subtitle: {
37 | style: {
38 | color: 'black'
39 | }
40 | },
41 | tooltip: {
42 | borderWidth: 0
43 | },
44 | legend: {
45 | itemStyle: {
46 | fontWeight: 'bold',
47 | fontSize: '13px'
48 | }
49 | },
50 | xAxis: {
51 | labels: {
52 | style: {
53 | color: '#6e6e70'
54 | }
55 | }
56 | },
57 | yAxis: {
58 | labels: {
59 | style: {
60 | color: '#6e6e70'
61 | }
62 | }
63 | },
64 | plotOptions: {
65 | series: {
66 | shadow: true
67 | },
68 | candlestick: {
69 | lineColor: '#404048'
70 | }
71 | },
72 |
73 | // Highstock specific
74 | navigator: {
75 | xAxis: {
76 | gridLineColor: '#D0D0D8'
77 | }
78 | },
79 | rangeSelector: {
80 | buttonTheme: {
81 | fill: 'white',
82 | stroke: '#C0C0C8',
83 | 'stroke-width': 1,
84 | states: {
85 | select: {
86 | fill: '#D0D0D8'
87 | }
88 | }
89 | }
90 | },
91 | scrollbar: {
92 | trackBorderColor: '#C0C0C8'
93 | },
94 |
95 | // General
96 | background2: '#E0E0E8'
97 |
98 | };
99 |
100 | // Apply the theme
101 | Highcharts.setOptions(Highcharts.theme);
102 |
--------------------------------------------------------------------------------
/highcharts/static/js/highcharts/modules/funnel.js:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | Highcharts funnel module
4 |
5 | (c) 2010-2014 Torstein Honsi
6 |
7 | License: www.highcharts.com/license
8 | */
9 | (function(b){var d=b.getOptions(),v=d.plotOptions,q=b.seriesTypes,E=b.merge,D=function(){},A=b.each;v.funnel=E(v.pie,{animation:!1,center:["50%","50%"],width:"90%",neckWidth:"30%",height:"100%",neckHeight:"25%",reversed:!1,dataLabels:{connectorWidth:1,connectorColor:"#606060"},size:!0,states:{select:{color:"#C0C0C0",borderColor:"#000000",shadow:!1}}});q.funnel=b.extendClass(q.pie,{type:"funnel",animate:D,singularTooltips:!0,translate:function(){var a=function(j,a){return/%$/.test(j)?a*parseInt(j,
10 | 10)/100:parseInt(j,10)},B=0,f=this.chart,c=this.options,g=c.reversed,b=f.plotWidth,n=f.plotHeight,o=0,f=c.center,h=a(f[0],b),d=a(f[0],n),q=a(c.width,b),k,r,e=a(c.height,n),s=a(c.neckWidth,b),t=a(c.neckHeight,n),w=e-t,a=this.data,x,y,v=c.dataLabels.position==="left"?1:0,z,l,C,p,i,u,m;this.getWidthAt=r=function(j){return j>e-t||e===t?s:s+(q-s)*((e-t-j)/(e-t))};this.getX=function(j,a){return h+(a?-1:1)*(r(g?n-j:j)/2+c.dataLabels.distance)};this.center=[h,d,e];this.centerX=h;A(a,function(a){B+=a.y});
11 | A(a,function(a){m=null;y=B?a.y/B:0;l=d-e/2+o*e;i=l+y*e;k=r(l);z=h-k/2;C=z+k;k=r(i);p=h-k/2;u=p+k;l>w?(z=p=h-s/2,C=u=h+s/2):i>w&&(m=i,k=r(w),p=h-k/2,u=p+k,i=w);g&&(l=e-l,i=e-i,m=m?e-m:null);x=["M",z,l,"L",C,l,u,i];m&&x.push(u,m,p,m);x.push(p,i,"Z");a.shapeType="path";a.shapeArgs={d:x};a.percentage=y*100;a.plotX=h;a.plotY=(l+(m||i))/2;a.tooltipPos=[h,a.plotY];a.slice=D;a.half=v;o+=y})},drawPoints:function(){var a=this,b=a.options,f=a.chart.renderer;A(a.data,function(c){var g=c.graphic,d=c.shapeArgs;
12 | g?g.animate(d):c.graphic=f.path(d).attr({fill:c.color,stroke:b.borderColor,"stroke-width":b.borderWidth}).add(a.group)})},sortByAngle:function(a){a.sort(function(a,b){return a.plotY-b.plotY})},drawDataLabels:function(){var a=this.data,b=this.options.dataLabels.distance,f,c,g,d=a.length,n,o;for(this.center[2]-=2*b;d--;)g=a[d],c=(f=g.half)?1:-1,o=g.plotY,n=this.getX(o,f),g.labelPos=[0,o,n+(b-5)*c,o,n+b*c,o,f?"right":"left",0];q.pie.prototype.drawDataLabels.call(this)}});d.plotOptions.pyramid=b.merge(d.plotOptions.funnel,
13 | {neckWidth:"0%",neckHeight:"0%",reversed:!0});b.seriesTypes.pyramid=b.extendClass(b.seriesTypes.funnel,{type:"pyramid"})})(Highcharts);
14 |
--------------------------------------------------------------------------------
/highcharts/static/js/highcharts/themes/grid.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Grid theme for Highcharts JS
3 | * @author Torstein Honsi
4 | */
5 |
6 | Highcharts.theme = {
7 | colors: ['#058DC7', '#50B432', '#ED561B', '#DDDF00', '#24CBE5', '#64E572', '#FF9655', '#FFF263', '#6AF9C4'],
8 | chart: {
9 | backgroundColor: {
10 | linearGradient: { x1: 0, y1: 0, x2: 1, y2: 1 },
11 | stops: [
12 | [0, 'rgb(255, 255, 255)'],
13 | [1, 'rgb(240, 240, 255)']
14 | ]
15 | },
16 | borderWidth: 2,
17 | plotBackgroundColor: 'rgba(255, 255, 255, .9)',
18 | plotShadow: true,
19 | plotBorderWidth: 1
20 | },
21 | title: {
22 | style: {
23 | color: '#000',
24 | font: 'bold 16px "Trebuchet MS", Verdana, sans-serif'
25 | }
26 | },
27 | subtitle: {
28 | style: {
29 | color: '#666666',
30 | font: 'bold 12px "Trebuchet MS", Verdana, sans-serif'
31 | }
32 | },
33 | xAxis: {
34 | gridLineWidth: 1,
35 | lineColor: '#000',
36 | tickColor: '#000',
37 | labels: {
38 | style: {
39 | color: '#000',
40 | font: '11px Trebuchet MS, Verdana, sans-serif'
41 | }
42 | },
43 | title: {
44 | style: {
45 | color: '#333',
46 | fontWeight: 'bold',
47 | fontSize: '12px',
48 | fontFamily: 'Trebuchet MS, Verdana, sans-serif'
49 |
50 | }
51 | }
52 | },
53 | yAxis: {
54 | minorTickInterval: 'auto',
55 | lineColor: '#000',
56 | lineWidth: 1,
57 | tickWidth: 1,
58 | tickColor: '#000',
59 | labels: {
60 | style: {
61 | color: '#000',
62 | font: '11px Trebuchet MS, Verdana, sans-serif'
63 | }
64 | },
65 | title: {
66 | style: {
67 | color: '#333',
68 | fontWeight: 'bold',
69 | fontSize: '12px',
70 | fontFamily: 'Trebuchet MS, Verdana, sans-serif'
71 | }
72 | }
73 | },
74 | legend: {
75 | itemStyle: {
76 | font: '9pt Trebuchet MS, Verdana, sans-serif',
77 | color: 'black'
78 |
79 | },
80 | itemHoverStyle: {
81 | color: '#039'
82 | },
83 | itemHiddenStyle: {
84 | color: 'gray'
85 | }
86 | },
87 | labels: {
88 | style: {
89 | color: '#99b'
90 | }
91 | },
92 |
93 | navigation: {
94 | buttonOptions: {
95 | theme: {
96 | stroke: '#CCCCCC'
97 | }
98 | }
99 | }
100 | };
101 |
102 | // Apply the theme
103 | var highchartsOptions = Highcharts.setOptions(Highcharts.theme);
104 |
--------------------------------------------------------------------------------
/highcharts/static/js/highcharts/.fr-amL3gv/grid.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Grid theme for Highcharts JS
3 | * @author Torstein Hønsi
4 | */
5 |
6 | Highcharts.theme = {
7 | colors: ['#058DC7', '#50B432', '#ED561B', '#DDDF00', '#24CBE5', '#64E572', '#FF9655', '#FFF263', '#6AF9C4'],
8 | chart: {
9 | backgroundColor: {
10 | linearGradient: { x1: 0, y1: 0, x2: 1, y2: 1 },
11 | stops: [
12 | [0, 'rgb(255, 255, 255)'],
13 | [1, 'rgb(240, 240, 255)']
14 | ]
15 | },
16 | borderWidth: 2,
17 | plotBackgroundColor: 'rgba(255, 255, 255, .9)',
18 | plotShadow: true,
19 | plotBorderWidth: 1
20 | },
21 | title: {
22 | style: {
23 | color: '#000',
24 | font: 'bold 16px "Trebuchet MS", Verdana, sans-serif'
25 | }
26 | },
27 | subtitle: {
28 | style: {
29 | color: '#666666',
30 | font: 'bold 12px "Trebuchet MS", Verdana, sans-serif'
31 | }
32 | },
33 | xAxis: {
34 | gridLineWidth: 1,
35 | lineColor: '#000',
36 | tickColor: '#000',
37 | labels: {
38 | style: {
39 | color: '#000',
40 | font: '11px Trebuchet MS, Verdana, sans-serif'
41 | }
42 | },
43 | title: {
44 | style: {
45 | color: '#333',
46 | fontWeight: 'bold',
47 | fontSize: '12px',
48 | fontFamily: 'Trebuchet MS, Verdana, sans-serif'
49 |
50 | }
51 | }
52 | },
53 | yAxis: {
54 | minorTickInterval: 'auto',
55 | lineColor: '#000',
56 | lineWidth: 1,
57 | tickWidth: 1,
58 | tickColor: '#000',
59 | labels: {
60 | style: {
61 | color: '#000',
62 | font: '11px Trebuchet MS, Verdana, sans-serif'
63 | }
64 | },
65 | title: {
66 | style: {
67 | color: '#333',
68 | fontWeight: 'bold',
69 | fontSize: '12px',
70 | fontFamily: 'Trebuchet MS, Verdana, sans-serif'
71 | }
72 | }
73 | },
74 | legend: {
75 | itemStyle: {
76 | font: '9pt Trebuchet MS, Verdana, sans-serif',
77 | color: 'black'
78 |
79 | },
80 | itemHoverStyle: {
81 | color: '#039'
82 | },
83 | itemHiddenStyle: {
84 | color: 'gray'
85 | }
86 | },
87 | labels: {
88 | style: {
89 | color: '#99b'
90 | }
91 | },
92 |
93 | navigation: {
94 | buttonOptions: {
95 | theme: {
96 | stroke: '#CCCCCC'
97 | }
98 | }
99 | }
100 | };
101 |
102 | // Apply the theme
103 | var highchartsOptions = Highcharts.setOptions(Highcharts.theme);
104 |
--------------------------------------------------------------------------------
/highcharts/static/js/highcharts/modules/solid-gauge.js:
--------------------------------------------------------------------------------
1 | /*
2 | Highcharts JS v4.0.1 (2014-04-24)
3 | Solid angular gauge module
4 |
5 | (c) 2010-2014 Torstein Honsi
6 |
7 | License: www.highcharts.com/license
8 | */
9 | (function(a){var l=a.getOptions().plotOptions,o=a.pInt,p=a.pick,j=a.each,m;l.solidgauge=a.merge(l.gauge,{colorByPoint:!0});m={initDataClasses:function(b){var h=this,e=this.chart,c,k=0,f=this.options;this.dataClasses=c=[];j(b.dataClasses,function(g,d){var i,g=a.merge(g);c.push(g);if(!g.color)f.dataClassColor==="category"?(i=e.options.colors,g.color=i[k++],k===i.length&&(k=0)):g.color=h.tweenColors(a.Color(f.minColor),a.Color(f.maxColor),d/(b.dataClasses.length-1))})},initStops:function(b){this.stops=
10 | b.stops||[[0,this.options.minColor],[1,this.options.maxColor]];j(this.stops,function(b){b.color=a.Color(b[1])})},toColor:function(b,h){var e,c=this.stops,a,f=this.dataClasses,g,d;if(f)for(d=f.length;d--;){if(g=f[d],a=g.from,c=g.to,(a===void 0||b>=a)&&(c===void 0||b<=c)){e=g.color;if(h)h.dataClass=d;break}}else{this.isLog&&(b=this.val2lin(b));e=1-(this.max-b)/(this.max-this.min);for(d=c.length;d--;)if(e>c[d][0])break;a=c[d]||c[d+1];c=c[d+1]||a;e=1-(c[0]-e)/(c[0]-a[0]||1);e=this.tweenColors(a.color,
11 | c.color,e)}return e},tweenColors:function(b,a,e){var c=a.rgba[3]!==1||b.rgba[3]!==1;return b.rgba.length===0||a.rgba.length===0?"none":(c?"rgba(":"rgb(")+Math.round(a.rgba[0]+(b.rgba[0]-a.rgba[0])*(1-e))+","+Math.round(a.rgba[1]+(b.rgba[1]-a.rgba[1])*(1-e))+","+Math.round(a.rgba[2]+(b.rgba[2]-a.rgba[2])*(1-e))+(c?","+(a.rgba[3]+(b.rgba[3]-a.rgba[3])*(1-e)):"")+")"}};a.seriesTypes.solidgauge=a.extendClass(a.seriesTypes.gauge,{type:"solidgauge",bindAxes:function(){var b;a.seriesTypes.gauge.prototype.bindAxes.call(this);
12 | b=this.yAxis;a.extend(b,m);b.options.dataClasses&&b.initDataClasses(b.options);b.initStops(b.options)},drawPoints:function(){var b=this,h=b.yAxis,e=h.center,c=b.options,k=b.chart.renderer;a.each(b.points,function(f){var g=f.graphic,d=h.startAngleRad+h.translate(f.y,null,null,null,!0),i=o(p(c.radius,100))*e[2]/200,l=o(p(c.innerRadius,60))*e[2]/200,n=h.toColor(f.y,f),j;if(n!=="none")j=f.color,f.color=n;c.wrap===!1&&(d=Math.max(h.startAngleRad,Math.min(h.endAngleRad,d)));d=d*180/Math.PI;d={x:e[0],y:e[1],
13 | r:i,innerR:l,start:h.startAngleRad,end:d/(180/Math.PI)};g?(i=d.d,g.attr({fill:f.color}).animate(d,{step:function(b,c){g.attr("fill",m.tweenColors(a.Color(j),a.Color(n),c.pos))}}),d.d=i):f.graphic=k.arc(d).attr({stroke:c.borderColor||"none","stroke-width":c.borderWidth||0,fill:f.color}).add(b.group)})},animate:null})})(Highcharts);
14 |
--------------------------------------------------------------------------------
/highcharts/views/common.py:
--------------------------------------------------------------------------------
1 | from braces.views import JSONResponseMixin, AjaxResponseMixin
2 |
3 |
4 | class HighChartsBasicView(JSONResponseMixin, AjaxResponseMixin):
5 | title = None
6 | title_style = None
7 | subtitle = None
8 | chart_type = None
9 | tooltip = None
10 | tooltip_point_format = None
11 | plot_options = {}
12 | chart = {}
13 | legend = True
14 | credits = {
15 | 'enabled': False
16 | }
17 | coloraxis = {}
18 | exporting = {
19 | 'sourceWidth': 1600,
20 | 'sourceHeight': 900,
21 | 'chartOptions': {
22 | 'subtitle': None
23 | }
24 | }
25 |
26 | def get_data(self):
27 | data = dict()
28 | # Title of the graph
29 |
30 | data['title'] = {}
31 | data['title']['text'] = self.title or None
32 | data['title']['style'] = self.title_style or {}
33 | data['colorAxis'] = self.coloraxis
34 | data['exporting'] = self.exporting
35 | data['credits'] = self.credits
36 | # Subtitle option
37 | if self.subtitle:
38 | data['subtitle'] = {}
39 | data['subtitle']['text'] = self.subtitle
40 |
41 | # Chart type option
42 | # Chart object to define options such as zoomType
43 | data['chart'] = self.chart
44 | if self.chart_type:
45 | data['chart']['type'] = self.chart_type
46 |
47 | # tooltip
48 | if self.tooltip or self.tooltip_point_format:
49 | if not self.tooltip:
50 | self.tooltip = {}
51 | data['tooltip'] = self.tooltip
52 | if self.tooltip_point_format:
53 | data['tooltip']['pointFormat'] = self.tooltip_point_format
54 |
55 | # plotOptions is just dict dumping
56 | if self.plot_options:
57 | data['plotOptions'] = self.plot_options
58 |
59 | data['legend'] = self.legend
60 |
61 | return data
62 |
63 | def get(self, request, *args, **kwargs):
64 | return self.get_ajax(request, *args, **kwargs)
65 |
66 | def get_ajax(self, request, *args, **kwargs):
67 | return self.render_json_response(self.get_data())
68 |
69 |
70 | class HighChartsDualAxisView(HighChartsBasicView):
71 | y_axis = {}
72 | y_axis_title = None
73 |
74 | def get_data(self):
75 | data = super(HighChartsDualAxisView, self).get_data()
76 | data['xAxis'] = {}
77 | data['yAxis'] = self.y_axis
78 | data['yAxis']['title'] = {"text": self.y_axis_title}
79 | return data
80 |
--------------------------------------------------------------------------------
/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/modules/no-data-to-display.src.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @license Highcharts JS v4.0.1 (2014-04-24)
3 | * Plugin for displaying a message when there is no data visible in chart.
4 | *
5 | * (c) 2010-2014 Highsoft AS
6 | * Author: Oystein Moseng
7 | *
8 | * License: www.highcharts.com/license
9 | */
10 |
11 | (function (H) { // docs
12 |
13 | var seriesTypes = H.seriesTypes,
14 | chartPrototype = H.Chart.prototype,
15 | defaultOptions = H.getOptions(),
16 | extend = H.extend;
17 |
18 | // Add language option
19 | extend(defaultOptions.lang, {
20 | noData: 'No data to display'
21 | });
22 |
23 | // Add default display options for message
24 | defaultOptions.noData = {
25 | position: {
26 | x: 0,
27 | y: 0,
28 | align: 'center',
29 | verticalAlign: 'middle'
30 | },
31 | attr: {
32 | },
33 | style: {
34 | fontWeight: 'bold',
35 | fontSize: '12px',
36 | color: '#60606a'
37 | }
38 | };
39 |
40 | /**
41 | * Define hasData functions for series. These return true if there are data points on this series within the plot area
42 | */
43 | function hasDataPie() {
44 | return !!this.points.length; /* != 0 */
45 | }
46 |
47 | if (seriesTypes.pie) {
48 | seriesTypes.pie.prototype.hasData = hasDataPie;
49 | }
50 |
51 | if (seriesTypes.gauge) {
52 | seriesTypes.gauge.prototype.hasData = hasDataPie;
53 | }
54 |
55 | if (seriesTypes.waterfall) {
56 | seriesTypes.waterfall.prototype.hasData = hasDataPie;
57 | }
58 |
59 | H.Series.prototype.hasData = function () {
60 | return this.dataMax !== undefined && this.dataMin !== undefined;
61 | };
62 |
63 | /**
64 | * Display a no-data message.
65 | *
66 | * @param {String} str An optional message to show in place of the default one
67 | */
68 | chartPrototype.showNoData = function (str) {
69 | var chart = this,
70 | options = chart.options,
71 | text = str || options.lang.noData,
72 | noDataOptions = options.noData;
73 |
74 | if (!chart.noDataLabel) {
75 | chart.noDataLabel = chart.renderer.label(text, 0, 0, null, null, null, null, null, 'no-data')
76 | .attr(noDataOptions.attr)
77 | .css(noDataOptions.style)
78 | .add();
79 | chart.noDataLabel.align(extend(chart.noDataLabel.getBBox(), noDataOptions.position), false, 'plotBox');
80 | }
81 | };
82 |
83 | /**
84 | * Hide no-data message
85 | */
86 | chartPrototype.hideNoData = function () {
87 | var chart = this;
88 | if (chart.noDataLabel) {
89 | chart.noDataLabel = chart.noDataLabel.destroy();
90 | }
91 | };
92 |
93 | /**
94 | * Returns true if there are data points within the plot area now
95 | */
96 | chartPrototype.hasData = function () {
97 | var chart = this,
98 | series = chart.series,
99 | i = series.length;
100 |
101 | while (i--) {
102 | if (series[i].hasData() && !series[i].options.isInternal) {
103 | return true;
104 | }
105 | }
106 |
107 | return false;
108 | };
109 |
110 | /**
111 | * Show no-data message if there is no data in sight. Otherwise, hide it.
112 | */
113 | function handleNoData() {
114 | var chart = this;
115 | if (chart.hasData()) {
116 | chart.hideNoData();
117 | } else {
118 | chart.showNoData();
119 | }
120 | }
121 |
122 | /**
123 | * Add event listener to handle automatic display of no-data message
124 | */
125 | chartPrototype.callbacks.push(function (chart) {
126 | H.addEvent(chart, 'load', handleNoData);
127 | H.addEvent(chart, 'redraw', handleNoData);
128 | });
129 |
130 | }(Highcharts));
131 |
--------------------------------------------------------------------------------
/highcharts/views/multiple_axes.py:
--------------------------------------------------------------------------------
1 | from django.views.generic import View
2 | from highcharts.views.common import HighChartsDualAxisView
3 |
4 |
5 | class HighChartsMultiAxesView(HighChartsDualAxisView, View):
6 |
7 | chart_type = ''
8 | categories = []
9 | xlabels = {'rotation': -45}
10 | plotlines = None
11 | _series = []
12 | _yaxis = []
13 | xtitle = {}
14 | legend = {}
15 |
16 | def get_data(self):
17 | data = super(HighChartsMultiAxesView, self).get_data()
18 | data['xAxis']['categories'] = self.categories
19 | data['xAxis']['labels'] = self.xlabels
20 | data['xAxis']['plotLines'] = self.plotlines
21 | data['xAxis']['title'] = self.xtitle
22 | data['series'] = self.series
23 | data['yAxis'] = self.yaxis
24 | return data
25 |
26 | @property
27 | def series(self):
28 | return self._series
29 |
30 | @property
31 | def yaxis(self):
32 | return self._yaxis
33 |
34 | @series.setter
35 | def series(self, value):
36 | self._series = value
37 |
38 | @yaxis.setter
39 | def yaxis(self, value):
40 | self._yaxis = value
41 |
42 |
43 | class HighChartsStockView(HighChartsDualAxisView, View):
44 |
45 | chart_type = ''
46 | categories = []
47 | plotlines = None
48 | _series = []
49 | _yaxis = []
50 | _xaxis = []
51 |
52 | def get_data(self):
53 | data = super(HighChartsStockView, self).get_data()
54 | data['series'] = self.series
55 | data['yAxis'] = self.yaxis
56 | data['xAxis'] = {}
57 | return data
58 |
59 | @property
60 | def series(self):
61 | return self._series
62 |
63 | @property
64 | def yaxis(self):
65 | return self._yaxis
66 |
67 | @series.setter
68 | def series(self, value):
69 | self._series = value
70 |
71 | @yaxis.setter
72 | def yaxis(self, value):
73 | self._yaxis = value
74 |
75 | @property
76 | def xaxis(self):
77 | return self._xaxis
78 |
79 | @xaxis.setter
80 | def xaxis(self, value):
81 | self._xaxis = value
82 |
83 |
84 | class HighChartsStackedView(HighChartsMultiAxesView):
85 |
86 | @property
87 | def plot_options(self):
88 | plot_options = super(HighChartsMultiAxesView, self).plot_options
89 | if plot_options is None:
90 | plot_options = {}
91 | if 'series' not in plot_options:
92 | plot_options['series'] = {}
93 | plot_options['series']['stacking'] = 'normal'
94 | return plot_options
95 |
96 |
97 | class HighChartsColumnView(HighChartsMultiAxesView):
98 | chart_type = 'column'
99 |
100 |
101 | class HighChartsMultiXAxesView(HighChartsDualAxisView, View):
102 |
103 | chart_type = ''
104 | categories = []
105 | _series = []
106 | _yaxis = []
107 | _xaxis = []
108 |
109 | def get_data(self):
110 | data = super(HighChartsMultiXAxesView, self).get_data()
111 | data['series'] = self.series
112 | data['yAxis'] = self.yaxis
113 | data['xAxis'] = self.xaxis
114 | return data
115 |
116 | @property
117 | def series(self):
118 | return self._series
119 |
120 | @property
121 | def yaxis(self):
122 | return self._yaxis
123 |
124 | @series.setter
125 | def series(self, value):
126 | self._series = value
127 |
128 | @yaxis.setter
129 | def yaxis(self, value):
130 | self._yaxis = value
131 |
132 | @property
133 | def xaxis(self):
134 | return self._xaxis
135 |
136 | @xaxis.setter
137 | def xaxis(self, value):
138 | self._xaxis = value
--------------------------------------------------------------------------------
/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=e&&c<=h&&!j&&k!==""&&(k=b.split(f),m(k,function(b,a){a>=i&&a<=g&&(d[a-i]||(d[a-i]=[]),d[a-i][o]=b)}),o+=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,h=a.startColumn||0,i=a.endColumn||Number.MAX_VALUE;b&&(typeof b==="string"&&(b=document.getElementById(b)),m(b.getElementsByTagName("tr"),function(a,
11 | b){b>=d&&b<=e&&m(a.children,function(a,e){if((a.tagName==="TD"||a.tagName==="TH")&&e>=h&&e<=i)c[e-h]||(c[e-h]=[]),c[e-h][b-d]=a.innerHTML})}),this.dataFound())},parseGoogleSpreadsheet:function(){var a=this,b=this.options,c=b.googleSpreadsheetKey,d=this.columns,e=b.startRow||0,h=b.endRow||Number.MAX_VALUE,i=b.startColumn||0,g=b.endColumn||Number.MAX_VALUE,f,k;c&&jQuery.ajax({dataType:"json",url:"https://spreadsheets.google.com/feeds/cells/"+c+"/"+(b.googleSpreadsheetWorksheet||"od6")+"/public/values?alt=json-in-script&callback=?",
12 | error:b.error,success:function(b){var b=b.feed.entry,c,j=b.length,m=0,n=0,l;for(l=0;l=i&&l<=g)d[l-i]=[],d[l-i].length=Math.min(n,h-e);for(l=0;l=i&&k<=g&&f>=e&&f<=h)d[k-i][f-e]=c.content.$t;a.dataFound()}})},findHeaderRow:function(){m(this.columns,function(){});this.headerRow=0},trim:function(a){return typeof a==="string"?a.replace(/^\s+|\s+$/g,""):a},parseTypes:function(){for(var a=
13 | this.columns,b=a.length,c,d,e,h;b--;)for(c=a[b].length;c--;)d=a[b][c],e=parseFloat(d),h=this.trim(d),h==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]=h===""?null:h)},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,e;b&&(c=b(a));if(typeof a==="string")for(d in this.dateFormats)b=
14 | this.dateFormats[d],(e=a.match(b.regex))&&(c=b.parser(e));return c},rowsToColumns:function(a){var b,c,d,e,h;if(a){h=[];c=a.length;for(b=0;b1&&(b=a.shift(),this.headerRow===0&&b.shift(),b.isDatetime?c="datetime":b.isNumeric||
15 | (c="category"));for(g=0;g1&&i[f].push(a[g+1][f]!==void 0?a[g+1][f]:null),e>2&&i[f].push(a[g+2][f]!==void 0?a[g+2][f]:null),e>3&&i[f].push(a[g+3][f]!==void 0?a[g+3][f]:null),e>4&&i[f].push(a[g+4][f]!==void 0?a[g+4][f]:null);h[k]={name:a[g].name,data:i};g+=
16 | e}d.complete({xAxis:{type:c},series:h})}}});j.Data=n;j.data=function(a,b){return new n(a,b)};j.wrap(j.Chart.prototype,"init",function(a,b,c){var d=this;b&&b.data?j.data(j.extend(b.data,{complete:function(e){b.hasOwnProperty("series")&&(typeof b.series==="object"?m(b.series,function(a,c){b.series[c]=j.merge(a,e.series[c])}):delete b.series);b=j.merge(e,b);a.call(d,b,c)}}),b):a.call(d,b,c)})})(Highcharts);
17 |
--------------------------------------------------------------------------------
/highcharts/static/js/highcharts/themes/dark-unica.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Dark theme for Highcharts JS
3 | * @author Torstein Honsi
4 | */
5 |
6 | // Load the fonts
7 | Highcharts.createElement('link', {
8 | href: 'http://fonts.googleapis.com/css?family=Unica+One',
9 | rel: 'stylesheet',
10 | type: 'text/css'
11 | }, null, document.getElementsByTagName('head')[0]);
12 |
13 | Highcharts.theme = {
14 | colors: ["#2b908f", "#90ee7e", "#f45b5b", "#7798BF", "#aaeeee", "#ff0066", "#eeaaee",
15 | "#55BF3B", "#DF5353", "#7798BF", "#aaeeee"],
16 | chart: {
17 | backgroundColor: {
18 | linearGradient: { x1: 0, y1: 0, x2: 1, y2: 1 },
19 | stops: [
20 | [0, '#2a2a2b'],
21 | [1, '#3e3e40']
22 | ]
23 | },
24 | style: {
25 | fontFamily: "'Unica One', sans-serif"
26 | },
27 | plotBorderColor: '#606063'
28 | },
29 | title: {
30 | style: {
31 | color: '#E0E0E3',
32 | textTransform: 'uppercase',
33 | fontSize: '20px'
34 | }
35 | },
36 | subtitle: {
37 | style: {
38 | color: '#E0E0E3',
39 | textTransform: 'uppercase'
40 | }
41 | },
42 | xAxis: {
43 | gridLineColor: '#707073',
44 | labels: {
45 | style: {
46 | color: '#E0E0E3'
47 | }
48 | },
49 | lineColor: '#707073',
50 | minorGridLineColor: '#505053',
51 | tickColor: '#707073',
52 | title: {
53 | style: {
54 | color: '#A0A0A3'
55 |
56 | }
57 | }
58 | },
59 | yAxis: {
60 | gridLineColor: '#707073',
61 | labels: {
62 | style: {
63 | color: '#E0E0E3'
64 | }
65 | },
66 | lineColor: '#707073',
67 | minorGridLineColor: '#505053',
68 | tickColor: '#707073',
69 | tickWidth: 1,
70 | title: {
71 | style: {
72 | color: '#A0A0A3'
73 | }
74 | }
75 | },
76 | tooltip: {
77 | backgroundColor: 'rgba(0, 0, 0, 0.85)',
78 | style: {
79 | color: '#F0F0F0'
80 | }
81 | },
82 | plotOptions: {
83 | series: {
84 | dataLabels: {
85 | color: '#B0B0B3'
86 | },
87 | marker: {
88 | lineColor: '#333'
89 | }
90 | },
91 | boxplot: {
92 | fillColor: '#505053'
93 | },
94 | candlestick: {
95 | lineColor: 'white'
96 | },
97 | errorbar: {
98 | color: 'white'
99 | }
100 | },
101 | legend: {
102 | itemStyle: {
103 | color: '#E0E0E3'
104 | },
105 | itemHoverStyle: {
106 | color: '#FFF'
107 | },
108 | itemHiddenStyle: {
109 | color: '#606063'
110 | }
111 | },
112 | credits: {
113 | style: {
114 | color: '#666'
115 | }
116 | },
117 | labels: {
118 | style: {
119 | color: '#707073'
120 | }
121 | },
122 |
123 | drilldown: {
124 | activeAxisLabelStyle: {
125 | color: '#F0F0F3'
126 | },
127 | activeDataLabelStyle: {
128 | color: '#F0F0F3'
129 | }
130 | },
131 |
132 | navigation: {
133 | buttonOptions: {
134 | symbolStroke: '#DDDDDD',
135 | theme: {
136 | fill: '#505053'
137 | }
138 | }
139 | },
140 |
141 | // scroll charts
142 | rangeSelector: {
143 | buttonTheme: {
144 | fill: '#505053',
145 | stroke: '#000000',
146 | style: {
147 | color: '#CCC'
148 | },
149 | states: {
150 | hover: {
151 | fill: '#707073',
152 | stroke: '#000000',
153 | style: {
154 | color: 'white'
155 | }
156 | },
157 | select: {
158 | fill: '#000003',
159 | stroke: '#000000',
160 | style: {
161 | color: 'white'
162 | }
163 | }
164 | }
165 | },
166 | inputBoxBorderColor: '#505053',
167 | inputStyle: {
168 | backgroundColor: '#333',
169 | color: 'silver'
170 | },
171 | labelStyle: {
172 | color: 'silver'
173 | }
174 | },
175 |
176 | navigator: {
177 | handles: {
178 | backgroundColor: '#666',
179 | borderColor: '#AAA'
180 | },
181 | outlineColor: '#CCC',
182 | maskFill: 'rgba(255,255,255,0.1)',
183 | series: {
184 | color: '#7798BF',
185 | lineColor: '#A6C7ED'
186 | },
187 | xAxis: {
188 | gridLineColor: '#505053'
189 | }
190 | },
191 |
192 | scrollbar: {
193 | barBackgroundColor: '#808083',
194 | barBorderColor: '#808083',
195 | buttonArrowColor: '#CCC',
196 | buttonBackgroundColor: '#606063',
197 | buttonBorderColor: '#606063',
198 | rifleColor: '#FFF',
199 | trackBackgroundColor: '#404043',
200 | trackBorderColor: '#404043'
201 | },
202 |
203 | // special colors for some of the
204 | legendBackgroundColor: 'rgba(0, 0, 0, 0.5)',
205 | background2: '#505053',
206 | dataLabelsColor: '#B0B0B3',
207 | textColor: '#C0C0C0',
208 | contrastTextColor: '#F0F0F3',
209 | maskColor: 'rgba(255,255,255,0.3)'
210 | };
211 |
212 | // Apply the theme
213 | Highcharts.setOptions(Highcharts.theme);
214 |
--------------------------------------------------------------------------------
/highcharts/static/js/highcharts/adapters/standalone-framework.js:
--------------------------------------------------------------------------------
1 | /*
2 | Highcharts JS v4.0.1 (2014-04-24)
3 |
4 | Standalone Highcharts Framework
5 |
6 | License: MIT License
7 | */
8 | var HighchartsAdapter=function(){function o(c){function b(b,a,d){b.removeEventListener(a,d,!1)}function d(b,a,d){d=b.HCProxiedMethods[d.toString()];b.detachEvent("on"+a,d)}function a(a,c){var f=a.HCEvents,i,g,k,j;if(a.removeEventListener)i=b;else if(a.attachEvent)i=d;else return;c?(g={},g[c]=!0):g=f;for(j in g)if(f[j])for(k=f[j].length;k--;)i(a,j,f[j][k])}c.HCExtended||Highcharts.extend(c,{HCExtended:!0,HCEvents:{},bind:function(b,a){var d=this,c=this.HCEvents,g;if(d.addEventListener)d.addEventListener(b,
9 | a,!1);else if(d.attachEvent){g=function(b){b.target=b.srcElement||window;a.call(d,b)};if(!d.HCProxiedMethods)d.HCProxiedMethods={};d.HCProxiedMethods[a.toString()]=g;d.attachEvent("on"+b,g)}c[b]===r&&(c[b]=[]);c[b].push(a)},unbind:function(c,h){var f,i;c?(f=this.HCEvents[c]||[],h?(i=HighchartsAdapter.inArray(h,f),i>-1&&(f.splice(i,1),this.HCEvents[c]=f),this.removeEventListener?b(this,c,h):this.attachEvent&&d(this,c,h)):(a(this,c),this.HCEvents[c]=[])):(a(this),this.HCEvents={})},trigger:function(b,
10 | a){var d=this.HCEvents[b]||[],c=d.length,g,k,j;k=function(){a.defaultPrevented=!0};for(g=0;g=a.duration+this.startTime){this.now=this.end;
14 | this.pos=this.state=1;this.update();b=this.options.curAnim[this.prop]=!0;for(h in a.curAnim)a.curAnim[h]!==!0&&(b=!1);b&&a.complete&&a.complete.call(e);a=!1}else e=c-this.startTime,this.state=e/a.duration,this.pos=a.easing(e,0,1,a.duration),this.now=this.start+(this.end-this.start)*this.pos,this.update(),a=!0;return a}};this.animate=function(b,d,a){var e,h="",f,i,g;b.stopAnimation=!1;if(typeof a!=="object"||a===null)e=arguments,a={duration:e[2],easing:e[3],complete:e[4]};if(typeof a.duration!=="number")a.duration=
15 | 400;a.easing=Math[a.easing]||Math.easeInOutSine;a.curAnim=Highcharts.extend({},d);for(g in d)i=new n(b,a,g),f=null,g==="d"?(i.paths=c.init(b,b.d,d.d),i.toD=d.d,e=0,f=1):b.attr?e=b.attr(g):(e=parseFloat(HighchartsAdapter._getStyle(b,g))||0,g!=="opacity"&&(h="px")),f||(f=parseFloat(d[g])),i.custom(e,f,h)}},_getStyle:function(c,b){return window.getComputedStyle(c,void 0).getPropertyValue(b)},getScript:function(c,b){var d=l.getElementsByTagName("head")[0],a=l.createElement("script");a.type="text/javascript";
16 | a.src=c;a.onload=b;d.appendChild(a)},inArray:function(c,b){return b.indexOf?b.indexOf(c):p.indexOf.call(b,c)},adapterRun:function(c,b){return parseInt(HighchartsAdapter._getStyle(c,b),10)},grep:function(c,b){return p.filter.call(c,b)},map:function(c,b){for(var d=[],a=0,e=c.length;a= from) && (to === UNDEFINED || value <= to)) {
89 | color = dataClass.color;
90 | if (point) {
91 | point.dataClass = i;
92 | }
93 | break;
94 | }
95 | }
96 |
97 | } else {
98 |
99 | if (this.isLog) {
100 | value = this.val2lin(value);
101 | }
102 | pos = 1 - ((this.max - value) / (this.max - this.min));
103 | i = stops.length;
104 | while (i--) {
105 | if (pos > stops[i][0]) {
106 | break;
107 | }
108 | }
109 | from = stops[i] || stops[i + 1];
110 | to = stops[i + 1] || from;
111 |
112 | // The position within the gradient
113 | pos = 1 - (to[0] - pos) / ((to[0] - from[0]) || 1);
114 |
115 | color = this.tweenColors(
116 | from.color,
117 | to.color,
118 | pos
119 | );
120 | }
121 | return color;
122 | },
123 | tweenColors: function (from, to, pos) {
124 | // Check for has alpha, because rgba colors perform worse due to lack of
125 | // support in WebKit.
126 | var hasAlpha = (to.rgba[3] !== 1 || from.rgba[3] !== 1);
127 |
128 | if (from.rgba.length === 0 || to.rgba.length === 0) {
129 | return 'none';
130 | }
131 | return (hasAlpha ? 'rgba(' : 'rgb(') +
132 | Math.round(to.rgba[0] + (from.rgba[0] - to.rgba[0]) * (1 - pos)) + ',' +
133 | Math.round(to.rgba[1] + (from.rgba[1] - to.rgba[1]) * (1 - pos)) + ',' +
134 | Math.round(to.rgba[2] + (from.rgba[2] - to.rgba[2]) * (1 - pos)) +
135 | (hasAlpha ? (',' + (to.rgba[3] + (from.rgba[3] - to.rgba[3]) * (1 - pos))) : '') + ')';
136 | }
137 | };
138 |
139 | // The series prototype
140 | H.seriesTypes.solidgauge = H.extendClass(H.seriesTypes.gauge, {
141 | type: 'solidgauge',
142 |
143 | bindAxes: function () {
144 | var axis;
145 | H.seriesTypes.gauge.prototype.bindAxes.call(this);
146 |
147 | axis = this.yAxis;
148 | H.extend(axis, colorAxisMethods);
149 |
150 | // Prepare data classes
151 | if (axis.options.dataClasses) {
152 | axis.initDataClasses(axis.options);
153 | }
154 | axis.initStops(axis.options);
155 | },
156 |
157 | /**
158 | * Draw the points where each point is one needle
159 | */
160 | drawPoints: function () {
161 | var series = this,
162 | yAxis = series.yAxis,
163 | center = yAxis.center,
164 | options = series.options,
165 | renderer = series.chart.renderer;
166 |
167 | H.each(series.points, function (point) {
168 | var graphic = point.graphic,
169 | rotation = yAxis.startAngleRad + yAxis.translate(point.y, null, null, null, true),
170 | radius = (pInt(pick(options.radius, 100)) * center[2]) / 200,
171 | innerRadius = (pInt(pick(options.innerRadius, 60)) * center[2]) / 200,
172 | shapeArgs,
173 | d,
174 | toColor = yAxis.toColor(point.y, point),
175 | fromColor;
176 |
177 | if (toColor !== 'none') {
178 | fromColor = point.color;
179 | point.color = toColor;
180 | }
181 |
182 | // Handle the wrap option
183 | if (options.wrap === false) {
184 | rotation = Math.max(yAxis.startAngleRad, Math.min(yAxis.endAngleRad, rotation));
185 | }
186 | rotation = rotation * 180 / Math.PI;
187 |
188 | shapeArgs = {
189 | x: center[0],
190 | y: center[1],
191 | r: radius,
192 | innerR: innerRadius,
193 | start: yAxis.startAngleRad,
194 | end: rotation / (180 / Math.PI)
195 | };
196 |
197 | if (graphic) {
198 | d = shapeArgs.d;
199 |
200 | /*jslint unparam: true*/
201 | graphic.attr({
202 | fill: point.color
203 | }).animate(shapeArgs, {
204 | step: function (value, fx) {
205 | graphic.attr('fill', colorAxisMethods.tweenColors(H.Color(fromColor), H.Color(toColor), fx.pos));
206 | }
207 | });
208 | /*jslint unparam: false*/
209 | shapeArgs.d = d; // animate alters it
210 | } else {
211 | point.graphic = renderer.arc(shapeArgs)
212 | .attr({
213 | stroke: options.borderColor || 'none',
214 | 'stroke-width': options.borderWidth || 0,
215 | fill: point.color
216 | })
217 | .add(series.group);
218 | }
219 | });
220 | },
221 | animate: null
222 | });
223 |
224 | }(Highcharts));
225 |
--------------------------------------------------------------------------------
/highcharts/static/js/highcharts/modules/heatmap.js:
--------------------------------------------------------------------------------
1 | /*
2 | Highcharts JS v4.0.1 (2014-04-24)
3 |
4 | (c) 2011-2014 Torstein Honsi
5 |
6 | License: www.highcharts.com/license
7 | */
8 | (function(g){var j=g.Axis,x=g.Chart,o=g.Color,y=g.Legend,s=g.LegendSymbolMixin,t=g.Series,u=g.getOptions(),k=g.each,p=g.extend,z=g.extendClass,l=g.merge,q=g.pick,v=g.numberFormat,m=g.seriesTypes,w=g.wrap,n=function(){},r=g.ColorAxis=function(){this.isColorAxis=!0;this.init.apply(this,arguments)};p(r.prototype,j.prototype);p(r.prototype,{defaultColorAxisOptions:{lineWidth:0,gridLineWidth:1,tickPixelInterval:72,startOnTick:!0,endOnTick:!0,offset:0,marker:{animation:{duration:50},color:"gray",width:0.01},
9 | labels:{overflow:"justify"},minColor:"#EFEFFF",maxColor:"#003875",tickLength:5},init:function(b,a){var d=b.options.legend.layout!=="vertical",c;c=l(this.defaultColorAxisOptions,{side:d?2:1,reversed:!d},a,{isX:d,opposite:!d,showEmpty:!1,title:null,isColor:!0});j.prototype.init.call(this,b,c);a.dataClasses&&this.initDataClasses(a);this.initStops(a);this.isXAxis=!0;this.horiz=d;this.zoomEnabled=!1},tweenColors:function(b,a,d){var c=a.rgba[3]!==1||b.rgba[3]!==1;return(c?"rgba(":"rgb(")+Math.round(a.rgba[0]+
10 | (b.rgba[0]-a.rgba[0])*(1-d))+","+Math.round(a.rgba[1]+(b.rgba[1]-a.rgba[1])*(1-d))+","+Math.round(a.rgba[2]+(b.rgba[2]-a.rgba[2])*(1-d))+(c?","+(a.rgba[3]+(b.rgba[3]-a.rgba[3])*(1-d)):"")+")"},initDataClasses:function(b){var a=this,d=this.chart,c,e=0,h=this.options;this.dataClasses=c=[];k(b.dataClasses,function(f,i){var g,f=l(f);c.push(f);if(!f.color)h.dataClassColor==="category"?(g=d.options.colors,f.color=g[e++],e===g.length&&(e=0)):f.color=a.tweenColors(o(h.minColor),o(h.maxColor),i/(b.dataClasses.length-
11 | 1))})},initStops:function(b){this.stops=b.stops||[[0,this.options.minColor],[1,this.options.maxColor]];k(this.stops,function(a){a.color=o(a[1])})},setOptions:function(b){j.prototype.setOptions.call(this,b);this.options.crosshair=this.options.marker;this.coll="colorAxis"},setAxisSize:function(){var b=this.legendSymbol,a=this.chart,d,c,e;if(b)this.left=d=b.attr("x"),this.top=c=b.attr("y"),this.width=e=b.attr("width"),this.height=b=b.attr("height"),this.right=a.chartWidth-d-e,this.bottom=a.chartHeight-
12 | c-b,this.len=this.horiz?e:b,this.pos=this.horiz?d:c},toColor:function(b,a){var d,c=this.stops,e,h=this.dataClasses,f,i;if(h)for(i=h.length;i--;){if(f=h[i],e=f.from,c=f.to,(e===void 0||b>=e)&&(c===void 0||b<=c)){d=f.color;if(a)a.dataClass=i;break}}else{this.isLog&&(b=this.val2lin(b));d=1-(this.max-b)/(this.max-this.min);for(i=c.length;i--;)if(d>c[i][0])break;e=c[i]||c[i+1];c=c[i+1]||e;d=1-(c[0]-d)/(c[0]-e[0]||1);d=this.tweenColors(e.color,c.color,d)}return d},getOffset:function(){var b=this.legendGroup;
13 | if(b&&(j.prototype.getOffset.call(this),!this.axisGroup.parentGroup))this.axisGroup.add(b),this.gridGroup.add(b),this.labelGroup.add(b),this.added=!0},setLegendColor:function(){var b,a=this.options;b=this.horiz?[0,0,1,0]:[0,0,0,1];this.legendColor={linearGradient:{x1:b[0],y1:b[1],x2:b[2],y2:b[3]},stops:a.stops||[[0,a.minColor],[1,a.maxColor]]}},drawLegendSymbol:function(b,a){var d=b.padding,c=b.options,e=this.horiz,h=q(c.symbolWidth,e?200:12),f=q(c.symbolHeight,e?12:200),c=q(c.labelPadding,e?10:30);
14 | this.setLegendColor();a.legendSymbol=this.chart.renderer.rect(0,b.baseline-11,h,f).attr({zIndex:1}).add(a.legendGroup);a.legendSymbol.getBBox();this.legendItemWidth=h+d+(e?0:c);this.legendItemHeight=f+d+(e?c:0)},setState:n,visible:!0,setVisible:n,getSeriesExtremes:function(){var b;if(this.series.length)b=this.series[0],this.dataMin=b.valueMin,this.dataMax=b.valueMax},drawCrosshair:function(b,a){var d=!this.cross,c=a&&a.plotX,e=a&&a.plotY,h,f=this.pos,i=this.len;if(a)h=this.toPixels(a.value),hf+i&&(h=f+i+2),a.plotX=h,a.plotY=this.len-h,j.prototype.drawCrosshair.call(this,b,a),a.plotX=c,a.plotY=e,!d&&this.cross&&this.cross.attr({fill:this.crosshair.color}).add(this.labelGroup)},getPlotLinePath:function(b,a,d,c,e){return e?this.horiz?["M",e-4,this.top-6,"L",e+4,this.top-6,e,this.top,"Z"]:["M",this.left,e,"L",this.left-6,e+6,this.left-6,e-6,"Z"]:j.prototype.getPlotLinePath.call(this,b,a,d,c)},update:function(b,a){k(this.series,function(a){a.isDirtyData=!0});j.prototype.update.call(this,
16 | b,a);this.legendItem&&(this.setLegendColor(),this.chart.legend.colorizeItem(this,!0))},getDataClassLegendSymbols:function(){var b=this,a=this.chart,d=[],c=a.options.legend,e=c.valueDecimals,h=c.valueSuffix||"",f;k(this.dataClasses,function(c,g){var j=!0,l=c.from,m=c.to;f="";l===void 0?f="< ":m===void 0&&(f="> ");l!==void 0&&(f+=v(l,e)+h);l!==void 0&&m!==void 0&&(f+=" - ");m!==void 0&&(f+=v(m,e)+h);d.push(p({chart:a,name:f,options:{},drawLegendSymbol:s.drawRectangle,visible:!0,setState:n,setVisible:function(){j=
17 | this.visible=!j;k(b.series,function(a){k(a.points,function(a){a.dataClass===g&&a.setVisible(j)})});a.legend.colorizeItem(this,j)}},c))});return d},name:""});w(x.prototype,"getAxes",function(b){var a=this.options.colorAxis;b.call(this);this.colorAxis=[];a&&new r(this,a)});w(y.prototype,"getAllItems",function(b){var a=[],d=this.chart.colorAxis[0];d&&(d.options.dataClasses?a=a.concat(d.getDataClassLegendSymbols()):a.push(d),k(d.series,function(a){a.options.showInLegend=!1}));return a.concat(b.call(this))});
18 | g={pointAttrToOptions:{stroke:"borderColor","stroke-width":"borderWidth",fill:"color",dashstyle:"dashStyle"},pointArrayMap:["value"],axisTypes:["xAxis","yAxis","colorAxis"],optionalAxis:"colorAxis",trackerGroups:["group","markerGroup","dataLabelsGroup"],getSymbol:n,parallelArrays:["x","y","value"],translateColors:function(){var b=this,a=this.options.nullColor,d=this.colorAxis;k(this.data,function(c){var e=c.value;if(e=e===null?a:d?d.toColor(e,c):c.color||b.color)c.color=e})}};u.plotOptions.heatmap=
19 | l(u.plotOptions.scatter,{animation:!1,borderWidth:0,nullColor:"#F8F8F8",dataLabels:{format:"{point.value}",verticalAlign:"middle",crop:!1,overflow:!1,style:{color:"white",fontWeight:"bold",textShadow:"0 0 5px black"}},marker:null,tooltip:{pointFormat:"{point.x}, {point.y}: {point.value}
"},states:{normal:{animation:!0},hover:{brightness:0.2}}});m.heatmap=z(m.scatter,l(g,{type:"heatmap",pointArrayMap:["y","value"],hasPointSpecificOptions:!0,supportsDrilldown:!0,getExtremesFromAll:!0,init:function(){m.scatter.prototype.init.apply(this,
20 | arguments);this.pointRange=this.options.colsize||1;this.yAxis.axisPointRange=this.options.rowsize||1},translate:function(){var b=this.options,a=this.xAxis,d=this.yAxis;this.generatePoints();k(this.points,function(c){var e=(b.colsize||1)/2,h=(b.rowsize||1)/2,f=Math.round(a.len-a.translate(c.x-e,0,1,0,1)),e=Math.round(a.len-a.translate(c.x+e,0,1,0,1)),g=Math.round(d.translate(c.y-h,0,1,0,1)),h=Math.round(d.translate(c.y+h,0,1,0,1));c.plotX=(f+e)/2;c.plotY=(g+h)/2;c.shapeType="rect";c.shapeArgs={x:Math.min(f,
21 | e),y:Math.min(g,h),width:Math.abs(e-f),height:Math.abs(h-g)}});this.translateColors()},drawPoints:m.column.prototype.drawPoints,animate:n,getBox:n,drawLegendSymbol:s.drawRectangle,getExtremes:function(){t.prototype.getExtremes.call(this,this.valueData);this.valueMin=this.dataMin;this.valueMax=this.dataMax;t.prototype.getExtremes.call(this)}}))})(Highcharts);
22 |
--------------------------------------------------------------------------------
/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.*?$/,"").replace(/ /g," ").replace(//g,"").replace(/
/g,'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()});return c=c.replace(/(url\(#highcharts-[0-9]+)"/g,"$1").replace(/"/g,"'")},exportChart:function(b,a){var b=b||{},d=this.options.exporting,d=this.getSVG(k({chart:{borderRadius:0}},d.chartOptions,a,{exporting:{sourceWidth:b.sourceWidth||
16 | d.sourceWidth,sourceHeight:b.sourceHeight||d.sourceHeight}})),b=k(this.options.exporting,b);f.post(b.url,{filename:b.filename||"chart",type:b.type,width:b.width||0,scale:b.scale||2,svg:d},b.formAttributes)},print:function(){var b=this,a=b.container,d=[],c=a.parentNode,f=j.body,h=f.childNodes;if(!b.isPrinting)b.isPrinting=!0,r(h,function(a,b){if(a.nodeType===1)d[b]=a.style.display,a.style.display="none"}),f.appendChild(a),C.focus(),C.print(),setTimeout(function(){c.appendChild(a);r(h,function(a,b){if(a.nodeType===
17 | 1)a.style.display=d[b]});b.isPrinting=!1},1E3)},contextMenu:function(b,a,d,c,f,h,g){var e=this,k=e.options.navigation,q=k.menuItemStyle,m=e.chartWidth,n=e.chartHeight,j="cache-"+b,i=e[j],u=D(f,h),w,x,o,s=function(a){e.pointer.inClass(a.target,b)||x()};if(!i)e[j]=i=l("div",{className:b},{position:"absolute",zIndex:1E3,padding:u+"px"},e.container),w=l("div",null,p({MozBoxShadow:"3px 3px 10px #888",WebkitBoxShadow:"3px 3px 10px #888",boxShadow:"3px 3px 10px #888"},k.menuStyle),i),x=function(){v(i,{display:"none"});
18 | g&&g.setState(0);e.openMenu=!1},t(i,"mouseleave",function(){o=setTimeout(x,500)}),t(i,"mouseenter",function(){clearTimeout(o)}),t(document,"mouseup",s),t(e,"destroy",function(){B(document,"mouseup",s)}),r(a,function(a){if(a){var b=a.separator?l("hr",null,null,w):l("div",{onmouseover:function(){v(this,k.menuItemHoverStyle)},onmouseout:function(){v(this,q)},onclick:function(){x();a.onclick.apply(e,arguments)},innerHTML:a.text||e.options.lang[a.textKey]},p({cursor:"pointer"},q),w);e.exportDivElements.push(b)}}),
19 | e.exportDivElements.push(w,i),e.exportMenuWidth=i.offsetWidth,e.exportMenuHeight=i.offsetHeight;a={display:"block"};d+e.exportMenuWidth>m?a.right=m-d-f-u+"px":a.left=d-u+"px";c+h+e.exportMenuHeight>n&&g.alignOptions.verticalAlign!=="top"?a.bottom=n-c-u+"px":a.top=c+h-u+"px";v(i,a);e.openMenu=!0},addButton:function(b){var a=this,d=a.renderer,c=k(a.options.navigation.buttonOptions,b),j=c.onclick,h=c.menuItems,g,e,l={stroke:c.symbolStroke,fill:c.symbolFill},q=c.symbolSize||12;if(!a.btnCount)a.btnCount=
20 | 0;if(!a.exportDivElements)a.exportDivElements=[],a.exportSVGElements=[];if(c.enabled!==!1){var m=c.theme,n=m.states,o=n&&n.hover,n=n&&n.select,i;delete m.states;j?i=function(){j.apply(a,arguments)}:h&&(i=function(){a.contextMenu(e.menuClassName,h,e.translateX,e.translateY,e.width,e.height,e);e.setState(2)});c.text&&c.symbol?m.paddingLeft=f.pick(m.paddingLeft,25):c.text||p(m,{width:c.width,height:c.height,padding:0});e=d.button(c.text,0,0,i,m,o,n).attr({title:a.options.lang[c._titleKey],"stroke-linecap":"round"});
21 | e.menuClassName=b.menuClassName||"highcharts-menu-"+a.btnCount++;c.symbol&&(g=d.symbol(c.symbol,c.symbolX-q/2,c.symbolY-q/2,q,q).attr(p(l,{"stroke-width":c.symbolStrokeWidth||1,zIndex:1})).add(e));e.add().align(p(c,{width:e.width,x:f.pick(c.x,y)}),!0,"spacingBox");y+=(e.width+c.buttonSpacing)*(c.align==="right"?-1:1);a.exportSVGElements.push(e,g)}},destroyExport:function(b){var b=b.target,a,d;for(a=0;a.*?$/,"").replace(/(fill|stroke)="rgba\(([ 0-9]+,[ 0-9]+,[ 0-9]+),([ 0-9\.]+)\)"/g,'$1="rgb($2)" $1-opacity="$3"').replace(/ /g,
15 | "Â ").replace(//g,"Â").replace(/
/g,'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()});return c=c.replace(/(url\(#highcharts-[0-9]+)"/g,"$1").replace(/"/g,"'")},exportChart:function(b,a){var b=
16 | b||{},d=this.options.exporting,d=this.getSVG(k({chart:{borderRadius:0}},d.chartOptions,a,{exporting:{sourceWidth:b.sourceWidth||d.sourceWidth,sourceHeight:b.sourceHeight||d.sourceHeight}})),b=k(this.options.exporting,b);f.post(b.url,{filename:b.filename||"chart",type:b.type,width:b.width||0,scale:b.scale||2,svg:d},b.formAttributes)},print:function(){var b=this,a=b.container,d=[],c=a.parentNode,f=j.body,h=f.childNodes;if(!b.isPrinting)b.isPrinting=!0,r(h,function(a,b){if(a.nodeType===1)d[b]=a.style.display,
17 | a.style.display="none"}),f.appendChild(a),C.focus(),C.print(),setTimeout(function(){c.appendChild(a);r(h,function(a,b){if(a.nodeType===1)a.style.display=d[b]});b.isPrinting=!1},1E3)},contextMenu:function(b,a,d,c,f,h,g){var e=this,k=e.options.navigation,q=k.menuItemStyle,m=e.chartWidth,n=e.chartHeight,j="cache-"+b,i=e[j],u=D(f,h),w,x,o,s=function(a){e.pointer.inClass(a.target,b)||x()};if(!i)e[j]=i=l("div",{className:b},{position:"absolute",zIndex:1E3,padding:u+"px"},e.container),w=l("div",null,p({MozBoxShadow:"3px 3px 10px #888",
18 | WebkitBoxShadow:"3px 3px 10px #888",boxShadow:"3px 3px 10px #888"},k.menuStyle),i),x=function(){v(i,{display:"none"});g&&g.setState(0);e.openMenu=!1},t(i,"mouseleave",function(){o=setTimeout(x,500)}),t(i,"mouseenter",function(){clearTimeout(o)}),t(document,"mouseup",s),t(e,"destroy",function(){B(document,"mouseup",s)}),r(a,function(a){if(a){var b=a.separator?l("hr",null,null,w):l("div",{onmouseover:function(){v(this,k.menuItemHoverStyle)},onmouseout:function(){v(this,q)},onclick:function(){x();a.onclick.apply(e,
19 | arguments)},innerHTML:a.text||e.options.lang[a.textKey]},p({cursor:"pointer"},q),w);e.exportDivElements.push(b)}}),e.exportDivElements.push(w,i),e.exportMenuWidth=i.offsetWidth,e.exportMenuHeight=i.offsetHeight;a={display:"block"};d+e.exportMenuWidth>m?a.right=m-d-f-u+"px":a.left=d-u+"px";c+h+e.exportMenuHeight>n&&g.alignOptions.verticalAlign!=="top"?a.bottom=n-c-u+"px":a.top=c+h-u+"px";v(i,a);e.openMenu=!0},addButton:function(b){var a=this,d=a.renderer,c=k(a.options.navigation.buttonOptions,b),j=
20 | c.onclick,h=c.menuItems,g,e,l={stroke:c.symbolStroke,fill:c.symbolFill},q=c.symbolSize||12;if(!a.btnCount)a.btnCount=0;if(!a.exportDivElements)a.exportDivElements=[],a.exportSVGElements=[];if(c.enabled!==!1){var m=c.theme,n=m.states,o=n&&n.hover,n=n&&n.select,i;delete m.states;j?i=function(){j.apply(a,arguments)}:h&&(i=function(){a.contextMenu(e.menuClassName,h,e.translateX,e.translateY,e.width,e.height,e);e.setState(2)});c.text&&c.symbol?m.paddingLeft=f.pick(m.paddingLeft,25):c.text||p(m,{width:c.width,
21 | height:c.height,padding:0});e=d.button(c.text,0,0,i,m,o,n).attr({title:a.options.lang[c._titleKey],"stroke-linecap":"round"});e.menuClassName=b.menuClassName||"highcharts-menu-"+a.btnCount++;c.symbol&&(g=d.symbol(c.symbol,c.symbolX-q/2,c.symbolY-q/2,q,q).attr(p(l,{"stroke-width":c.symbolStrokeWidth||1,zIndex:1})).add(e));e.add().align(p(c,{width:e.width,x:f.pick(c.x,y)}),!0,"spacingBox");y+=(e.width+c.buttonSpacing)*(c.align==="right"?-1:1);a.exportSVGElements.push(e,g)}},destroyExport:function(b){var b=
22 | b.target,a,d;for(a=0;a height - neckHeight ?
98 | neckWidth :
99 | neckWidth + (width - neckWidth) * ((height - neckHeight - y) / (height - neckHeight));
100 | };
101 | series.getX = function (y, half) {
102 | return centerX + (half ? -1 : 1) * ((getWidthAt(y) / 2) + options.dataLabels.distance);
103 | };
104 |
105 | // Expose
106 | series.center = [centerX, centerY, height];
107 | series.centerX = centerX;
108 |
109 | /*
110 | * Individual point coordinate naming:
111 | *
112 | * x1,y1 _________________ x2,y1
113 | * \ /
114 | * \ /
115 | * \ /
116 | * \ /
117 | * \ /
118 | * x3,y3 _________ x4,y3
119 | *
120 | * Additional for the base of the neck:
121 | *
122 | * | |
123 | * | |
124 | * | |
125 | * x3,y5 _________ x4,y5
126 | */
127 |
128 |
129 |
130 |
131 | // get the total sum
132 | each(data, function (point) {
133 | sum += point.y;
134 | });
135 |
136 | each(data, function (point) {
137 | // set start and end positions
138 | y5 = null;
139 | fraction = sum ? point.y / sum : 0;
140 | y1 = cumulative * height;
141 | y3 = y1 + fraction * height;
142 | //tempWidth = neckWidth + (width - neckWidth) * ((height - neckHeight - y1) / (height - neckHeight));
143 | tempWidth = getWidthAt(y1);
144 | x1 = centerX - tempWidth / 2;
145 | x2 = x1 + tempWidth;
146 | tempWidth = getWidthAt(y3);
147 | x3 = centerX - tempWidth / 2;
148 | x4 = x3 + tempWidth;
149 |
150 | // the entire point is within the neck
151 | if (y1 > neckY) {
152 | x1 = x3 = centerX - neckWidth / 2;
153 | x2 = x4 = centerX + neckWidth / 2;
154 |
155 | // the base of the neck
156 | } else if (y3 > neckY) {
157 | y5 = y3;
158 |
159 | tempWidth = getWidthAt(neckY);
160 | x3 = centerX - tempWidth / 2;
161 | x4 = x3 + tempWidth;
162 |
163 | y3 = neckY;
164 | }
165 |
166 | // save the path
167 | path = [
168 | 'M',
169 | x1, y1,
170 | 'L',
171 | x2, y1,
172 | x4, y3
173 | ];
174 | if (y5) {
175 | path.push(x4, y5, x3, y5);
176 | }
177 | path.push(x3, y3, 'Z');
178 |
179 | // prepare for using shared dr
180 | point.shapeType = 'path';
181 | point.shapeArgs = { d: path };
182 |
183 |
184 | // for tooltips and data labels
185 | point.percentage = fraction * 100;
186 | point.plotX = centerX;
187 | point.plotY = (y1 + (y5 || y3)) / 2;
188 |
189 | // Placement of tooltips and data labels
190 | point.tooltipPos = [
191 | centerX,
192 | point.plotY
193 | ];
194 |
195 | // Slice is a noop on funnel points
196 | point.slice = noop;
197 |
198 | // Mimicking pie data label placement logic
199 | point.half = half;
200 |
201 | cumulative += fraction;
202 | });
203 |
204 |
205 | series.setTooltipPoints();
206 | },
207 | /**
208 | * Draw a single point (wedge)
209 | * @param {Object} point The point object
210 | * @param {Object} color The color of the point
211 | * @param {Number} brightness The brightness relative to the color
212 | */
213 | drawPoints: function () {
214 | var series = this,
215 | options = series.options,
216 | chart = series.chart,
217 | renderer = chart.renderer;
218 |
219 | each(series.data, function (point) {
220 |
221 | var graphic = point.graphic,
222 | shapeArgs = point.shapeArgs;
223 |
224 | if (!graphic) { // Create the shapes
225 | point.graphic = renderer.path(shapeArgs).
226 | attr({
227 | fill: point.color,
228 | stroke: options.borderColor,
229 | 'stroke-width': options.borderWidth
230 | }).
231 | add(series.group);
232 |
233 | } else { // Update the shapes
234 | graphic.animate(shapeArgs);
235 | }
236 | });
237 | },
238 |
239 | /**
240 | * Extend the pie data label method
241 | */
242 | drawDataLabels: function () {
243 | var data = this.data,
244 | labelDistance = this.options.dataLabels.distance,
245 | leftSide,
246 | sign,
247 | point,
248 | i = data.length,
249 | x,
250 | y;
251 |
252 | // In the original pie label anticollision logic, the slots are distributed
253 | // from one labelDistance above to one labelDistance below the pie. In funnels
254 | // we don't want this.
255 | this.center[2] -= 2 * labelDistance;
256 |
257 | // Set the label position array for each point.
258 | while (i--) {
259 | point = data[i];
260 | leftSide = point.half;
261 | sign = leftSide ? 1 : -1;
262 | y = point.plotY;
263 | x = this.getX(y, leftSide);
264 |
265 | // set the anchor point for data labels
266 | point.labelPos = [
267 | 0, // first break of connector
268 | y, // a/a
269 | x + (labelDistance - 5) * sign, // second break, right outside point shape
270 | y, // a/a
271 | x + labelDistance * sign, // landing point for connector
272 | y, // a/a
273 | leftSide ? 'right' : 'left', // alignment
274 | 0 // center angle
275 | ];
276 | }
277 |
278 | seriesTypes.pie.prototype.drawDataLabels.call(this);
279 | }
280 |
281 | });
282 |
283 |
284 | }(Highcharts));
285 |
--------------------------------------------------------------------------------
/highcharts/static/js/highcharts/heatmap.js:
--------------------------------------------------------------------------------
1 | /*
2 | Highcharts JS v4.0.4 (2014-09-02)
3 |
4 | (c) 2011-2014 Torstein Honsi
5 |
6 | License: www.highcharts.com/license
7 | */
8 | (function(h){var k=h.Axis,y=h.Chart,l=h.Color,z=h.Legend,t=h.LegendSymbolMixin,u=h.Series,v=h.SVGRenderer,w=h.getOptions(),i=h.each,r=h.extend,A=h.extendClass,m=h.merge,o=h.pick,x=h.numberFormat,p=h.seriesTypes,s=h.wrap,n=function(){},q=h.ColorAxis=function(){this.isColorAxis=!0;this.init.apply(this,arguments)};r(q.prototype,k.prototype);r(q.prototype,{defaultColorAxisOptions:{lineWidth:0,gridLineWidth:1,tickPixelInterval:72,startOnTick:!0,endOnTick:!0,offset:0,marker:{animation:{duration:50},color:"gray",
9 | width:0.01},labels:{overflow:"justify"},minColor:"#EFEFFF",maxColor:"#003875",tickLength:5},init:function(b,a){var c=b.options.legend.layout!=="vertical",d;d=m(this.defaultColorAxisOptions,{side:c?2:1,reversed:!c},a,{isX:c,opposite:!c,showEmpty:!1,title:null,isColor:!0});k.prototype.init.call(this,b,d);a.dataClasses&&this.initDataClasses(a);this.initStops(a);this.isXAxis=!0;this.horiz=c;this.zoomEnabled=!1},tweenColors:function(b,a,c){var d=a.rgba[3]!==1||b.rgba[3]!==1;return(d?"rgba(":"rgb(")+Math.round(a.rgba[0]+
10 | (b.rgba[0]-a.rgba[0])*(1-c))+","+Math.round(a.rgba[1]+(b.rgba[1]-a.rgba[1])*(1-c))+","+Math.round(a.rgba[2]+(b.rgba[2]-a.rgba[2])*(1-c))+(d?","+(a.rgba[3]+(b.rgba[3]-a.rgba[3])*(1-c)):"")+")"},initDataClasses:function(b){var a=this,c=this.chart,d,e=0,f=this.options,g=b.dataClasses.length;this.dataClasses=d=[];this.legendItems=[];i(b.dataClasses,function(b,h){var i,b=m(b);d.push(b);if(!b.color)f.dataClassColor==="category"?(i=c.options.colors,b.color=i[e++],e===i.length&&(e=0)):b.color=a.tweenColors(l(f.minColor),
11 | l(f.maxColor),g<2?0.5:h/(g-1))})},initStops:function(b){this.stops=b.stops||[[0,this.options.minColor],[1,this.options.maxColor]];i(this.stops,function(a){a.color=l(a[1])})},setOptions:function(b){k.prototype.setOptions.call(this,b);this.options.crosshair=this.options.marker;this.coll="colorAxis"},setAxisSize:function(){var b=this.legendSymbol,a=this.chart,c,d,e;if(b)this.left=c=b.attr("x"),this.top=d=b.attr("y"),this.width=e=b.attr("width"),this.height=b=b.attr("height"),this.right=a.chartWidth-
12 | c-e,this.bottom=a.chartHeight-d-b,this.len=this.horiz?e:b,this.pos=this.horiz?c:d},toColor:function(b,a){var c,d=this.stops,e,f=this.dataClasses,g,j;if(f)for(j=f.length;j--;){if(g=f[j],e=g.from,d=g.to,(e===void 0||b>=e)&&(d===void 0||b<=d)){c=g.color;if(a)a.dataClass=j;break}}else{this.isLog&&(b=this.val2lin(b));c=1-(this.max-b)/(this.max-this.min||1);for(j=d.length;j--;)if(c>d[j][0])break;e=d[j]||d[j+1];d=d[j+1]||e;c=1-(d[0]-c)/(d[0]-e[0]||1);c=this.tweenColors(e.color,d.color,c)}return c},getOffset:function(){var b=
13 | this.legendGroup,a=this.chart.axisOffset[this.side];if(b){k.prototype.getOffset.call(this);if(!this.axisGroup.parentGroup)this.axisGroup.add(b),this.gridGroup.add(b),this.labelGroup.add(b),this.added=!0;this.chart.axisOffset[this.side]=a}},setLegendColor:function(){var b,a=this.options;b=this.horiz?[0,0,1,0]:[0,0,0,1];this.legendColor={linearGradient:{x1:b[0],y1:b[1],x2:b[2],y2:b[3]},stops:a.stops||[[0,a.minColor],[1,a.maxColor]]}},drawLegendSymbol:function(b,a){var c=b.padding,d=b.options,e=this.horiz,
14 | f=o(d.symbolWidth,e?200:12),g=o(d.symbolHeight,e?12:200),j=o(d.labelPadding,e?16:30),d=o(d.itemDistance,10);this.setLegendColor();a.legendSymbol=this.chart.renderer.rect(0,b.baseline-11,f,g).attr({zIndex:1}).add(a.legendGroup);a.legendSymbol.getBBox();this.legendItemWidth=f+c+(e?d:j);this.legendItemHeight=g+c+(e?j:0)},setState:n,visible:!0,setVisible:n,getSeriesExtremes:function(){var b;if(this.series.length)b=this.series[0],this.dataMin=b.valueMin,this.dataMax=b.valueMax},drawCrosshair:function(b,
15 | a){var c=!this.cross,d=a&&a.plotX,e=a&&a.plotY,f,g=this.pos,j=this.len;if(a)f=this.toPixels(a.value),fg+j&&(f=g+j+2),a.plotX=f,a.plotY=this.len-f,k.prototype.drawCrosshair.call(this,b,a),a.plotX=d,a.plotY=e,!c&&this.cross&&this.cross.attr({fill:this.crosshair.color}).add(this.labelGroup)},getPlotLinePath:function(b,a,c,d,e){return e?this.horiz?["M",e-4,this.top-6,"L",e+4,this.top-6,e,this.top,"Z"]:["M",this.left,e,"L",this.left-6,e+6,this.left-6,e-6,"Z"]:k.prototype.getPlotLinePath.call(this,
16 | b,a,c,d)},update:function(b,a){i(this.series,function(a){a.isDirtyData=!0});k.prototype.update.call(this,b,a);this.legendItem&&(this.setLegendColor(),this.chart.legend.colorizeItem(this,!0))},getDataClassLegendSymbols:function(){var b=this,a=this.chart,c=this.legendItems,d=a.options.legend,e=d.valueDecimals,f=d.valueSuffix||"",g;c.length||i(this.dataClasses,function(d,h){var k=!0,l=d.from,m=d.to;g="";l===void 0?g="< ":m===void 0&&(g="> ");l!==void 0&&(g+=x(l,e)+f);l!==void 0&&m!==void 0&&(g+=" - ");
17 | m!==void 0&&(g+=x(m,e)+f);c.push(r({chart:a,name:g,options:{},drawLegendSymbol:t.drawRectangle,visible:!0,setState:n,setVisible:function(){k=this.visible=!k;i(b.series,function(a){i(a.points,function(a){a.dataClass===h&&a.setVisible(k)})});a.legend.colorizeItem(this,k)}},d))});return c},name:""});i(["fill","stroke"],function(b){HighchartsAdapter.addAnimSetter(b,function(a){a.elem.attr(b,q.prototype.tweenColors(l(a.start),l(a.end),a.pos))})});s(y.prototype,"getAxes",function(b){var a=this.options.colorAxis;
18 | b.call(this);this.colorAxis=[];a&&new q(this,a)});s(z.prototype,"getAllItems",function(b){var a=[],c=this.chart.colorAxis[0];c&&(c.options.dataClasses?a=a.concat(c.getDataClassLegendSymbols()):a.push(c),i(c.series,function(a){a.options.showInLegend=!1}));return a.concat(b.call(this))});h={pointAttrToOptions:{stroke:"borderColor","stroke-width":"borderWidth",fill:"color",dashstyle:"dashStyle"},pointArrayMap:["value"],axisTypes:["xAxis","yAxis","colorAxis"],optionalAxis:"colorAxis",trackerGroups:["group",
19 | "markerGroup","dataLabelsGroup"],getSymbol:n,parallelArrays:["x","y","value"],colorKey:"value",translateColors:function(){var b=this,a=this.options.nullColor,c=this.colorAxis,d=this.colorKey;i(this.data,function(e){var f=e[d];if(f=f===null?a:c&&f!==void 0?c.toColor(f,e):e.color||b.color)e.color=f})}};s(v.prototype,"buildText",function(b,a){var c=a.styles&&a.styles.HcTextStroke;b.call(this,a);c&&a.applyTextStroke&&a.applyTextStroke(c)});v.prototype.Element.prototype.applyTextStroke=function(b){var a=
20 | this.element,c,d,b=b.split(" ");c=a.getElementsByTagName("tspan");d=a.firstChild;this.ySetter=this.xSetter;i([].slice.call(c),function(c,f){var g;f===0&&(c.setAttribute("x",a.getAttribute("x")),(f=a.getAttribute("y"))!==null&&c.setAttribute("y",f));g=c.cloneNode(1);g.setAttribute("stroke",b[1]);g.setAttribute("stroke-width",b[0]);g.setAttribute("stroke-linejoin","round");a.insertBefore(g,d)})};w.plotOptions.heatmap=m(w.plotOptions.scatter,{animation:!1,borderWidth:0,nullColor:"#F8F8F8",dataLabels:{formatter:function(){return this.point.value},
21 | verticalAlign:"middle",crop:!1,overflow:!1,style:{color:"white",fontWeight:"bold",HcTextStroke:"1px rgba(0,0,0,0.5)"}},marker:null,tooltip:{pointFormat:"{point.x}, {point.y}: {point.value}
"},states:{normal:{animation:!0},hover:{brightness:0.2}}});p.heatmap=A(p.scatter,m(h,{type:"heatmap",pointArrayMap:["y","value"],hasPointSpecificOptions:!0,supportsDrilldown:!0,getExtremesFromAll:!0,init:function(){p.scatter.prototype.init.apply(this,arguments);this.pointRange=this.options.colsize||1;this.yAxis.axisPointRange=
22 | this.options.rowsize||1},translate:function(){var b=this.options,a=this.xAxis,c=this.yAxis;this.generatePoints();i(this.points,function(d){var e=(b.colsize||1)/2,f=(b.rowsize||1)/2,g=Math.round(a.len-a.translate(d.x-e,0,1,0,1)),e=Math.round(a.len-a.translate(d.x+e,0,1,0,1)),h=Math.round(c.translate(d.y-f,0,1,0,1)),f=Math.round(c.translate(d.y+f,0,1,0,1));d.plotX=(g+e)/2;d.plotY=(h+f)/2;d.shapeType="rect";d.shapeArgs={x:Math.min(g,e),y:Math.min(h,f),width:Math.abs(e-g),height:Math.abs(f-h)}});this.translateColors();
23 | this.chart.hasRendered&&i(this.points,function(a){a.shapeArgs.fill=a.options.color||a.color})},drawPoints:p.column.prototype.drawPoints,animate:n,getBox:n,drawLegendSymbol:t.drawRectangle,getExtremes:function(){u.prototype.getExtremes.call(this,this.valueData);this.valueMin=this.dataMin;this.valueMax=this.dataMax;u.prototype.getExtremes.call(this)}}))})(Highcharts);
--------------------------------------------------------------------------------
/docs/make.bat:
--------------------------------------------------------------------------------
1 | @ECHO OFF
2 |
3 | REM Command file for Sphinx documentation
4 |
5 | if "%SPHINXBUILD%" == "" (
6 | set SPHINXBUILD=sphinx-build
7 | )
8 | set BUILDDIR=_build
9 | set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% .
10 | set I18NSPHINXOPTS=%SPHINXOPTS% .
11 | if NOT "%PAPER%" == "" (
12 | set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS%
13 | set I18NSPHINXOPTS=-D latex_paper_size=%PAPER% %I18NSPHINXOPTS%
14 | )
15 |
16 | if "%1" == "" goto help
17 |
18 | if "%1" == "help" (
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. text to make text files
32 | echo. man to make manual pages
33 | echo. texinfo to make Texinfo files
34 | echo. gettext to make PO message catalogs
35 | echo. changes to make an overview over all changed/added/deprecated items
36 | echo. xml to make Docutils-native XML files
37 | echo. pseudoxml to make pseudoxml-XML files for display purposes
38 | echo. linkcheck to check all external links for integrity
39 | echo. doctest to run all doctests embedded in the documentation if enabled
40 | echo. coverage to run coverage check of the documentation if enabled
41 | goto end
42 | )
43 |
44 | if "%1" == "clean" (
45 | for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i
46 | del /q /s %BUILDDIR%\*
47 | goto end
48 | )
49 |
50 |
51 | REM Check if sphinx-build is available and fallback to Python version if any
52 | %SPHINXBUILD% 1>NUL 2>NUL
53 | if errorlevel 9009 goto sphinx_python
54 | goto sphinx_ok
55 |
56 | :sphinx_python
57 |
58 | set SPHINXBUILD=python -m sphinx.__init__
59 | %SPHINXBUILD% 2> nul
60 | if errorlevel 9009 (
61 | echo.
62 | echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
63 | echo.installed, then set the SPHINXBUILD environment variable to point
64 | echo.to the full path of the 'sphinx-build' executable. Alternatively you
65 | echo.may add the Sphinx directory to PATH.
66 | echo.
67 | echo.If you don't have Sphinx installed, grab it from
68 | echo.http://sphinx-doc.org/
69 | exit /b 1
70 | )
71 |
72 | :sphinx_ok
73 |
74 |
75 | if "%1" == "html" (
76 | %SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html
77 | if errorlevel 1 exit /b 1
78 | echo.
79 | echo.Build finished. The HTML pages are in %BUILDDIR%/html.
80 | goto end
81 | )
82 |
83 | if "%1" == "dirhtml" (
84 | %SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml
85 | if errorlevel 1 exit /b 1
86 | echo.
87 | echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml.
88 | goto end
89 | )
90 |
91 | if "%1" == "singlehtml" (
92 | %SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml
93 | if errorlevel 1 exit /b 1
94 | echo.
95 | echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml.
96 | goto end
97 | )
98 |
99 | if "%1" == "pickle" (
100 | %SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle
101 | if errorlevel 1 exit /b 1
102 | echo.
103 | echo.Build finished; now you can process the pickle files.
104 | goto end
105 | )
106 |
107 | if "%1" == "json" (
108 | %SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json
109 | if errorlevel 1 exit /b 1
110 | echo.
111 | echo.Build finished; now you can process the JSON files.
112 | goto end
113 | )
114 |
115 | if "%1" == "htmlhelp" (
116 | %SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp
117 | if errorlevel 1 exit /b 1
118 | echo.
119 | echo.Build finished; now you can run HTML Help Workshop with the ^
120 | .hhp project file in %BUILDDIR%/htmlhelp.
121 | goto end
122 | )
123 |
124 | if "%1" == "qthelp" (
125 | %SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp
126 | if errorlevel 1 exit /b 1
127 | echo.
128 | echo.Build finished; now you can run "qcollectiongenerator" with the ^
129 | .qhcp project file in %BUILDDIR%/qthelp, like this:
130 | echo.^> qcollectiongenerator %BUILDDIR%\qthelp\django-highcharts.qhcp
131 | echo.To view the help file:
132 | echo.^> assistant -collectionFile %BUILDDIR%\qthelp\django-highcharts.ghc
133 | goto end
134 | )
135 |
136 | if "%1" == "devhelp" (
137 | %SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp
138 | if errorlevel 1 exit /b 1
139 | echo.
140 | echo.Build finished.
141 | goto end
142 | )
143 |
144 | if "%1" == "epub" (
145 | %SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub
146 | if errorlevel 1 exit /b 1
147 | echo.
148 | echo.Build finished. The epub file is in %BUILDDIR%/epub.
149 | goto end
150 | )
151 |
152 | if "%1" == "latex" (
153 | %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
154 | if errorlevel 1 exit /b 1
155 | echo.
156 | echo.Build finished; the LaTeX files are in %BUILDDIR%/latex.
157 | goto end
158 | )
159 |
160 | if "%1" == "latexpdf" (
161 | %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
162 | cd %BUILDDIR%/latex
163 | make all-pdf
164 | cd %~dp0
165 | echo.
166 | echo.Build finished; the PDF files are in %BUILDDIR%/latex.
167 | goto end
168 | )
169 |
170 | if "%1" == "latexpdfja" (
171 | %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
172 | cd %BUILDDIR%/latex
173 | make all-pdf-ja
174 | cd %~dp0
175 | echo.
176 | echo.Build finished; the PDF files are in %BUILDDIR%/latex.
177 | goto end
178 | )
179 |
180 | if "%1" == "text" (
181 | %SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text
182 | if errorlevel 1 exit /b 1
183 | echo.
184 | echo.Build finished. The text files are in %BUILDDIR%/text.
185 | goto end
186 | )
187 |
188 | if "%1" == "man" (
189 | %SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man
190 | if errorlevel 1 exit /b 1
191 | echo.
192 | echo.Build finished. The manual pages are in %BUILDDIR%/man.
193 | goto end
194 | )
195 |
196 | if "%1" == "texinfo" (
197 | %SPHINXBUILD% -b texinfo %ALLSPHINXOPTS% %BUILDDIR%/texinfo
198 | if errorlevel 1 exit /b 1
199 | echo.
200 | echo.Build finished. The Texinfo files are in %BUILDDIR%/texinfo.
201 | goto end
202 | )
203 |
204 | if "%1" == "gettext" (
205 | %SPHINXBUILD% -b gettext %I18NSPHINXOPTS% %BUILDDIR%/locale
206 | if errorlevel 1 exit /b 1
207 | echo.
208 | echo.Build finished. The message catalogs are in %BUILDDIR%/locale.
209 | goto end
210 | )
211 |
212 | if "%1" == "changes" (
213 | %SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes
214 | if errorlevel 1 exit /b 1
215 | echo.
216 | echo.The overview file is in %BUILDDIR%/changes.
217 | goto end
218 | )
219 |
220 | if "%1" == "linkcheck" (
221 | %SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck
222 | if errorlevel 1 exit /b 1
223 | echo.
224 | echo.Link check complete; look for any errors in the above output ^
225 | or in %BUILDDIR%/linkcheck/output.txt.
226 | goto end
227 | )
228 |
229 | if "%1" == "doctest" (
230 | %SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest
231 | if errorlevel 1 exit /b 1
232 | echo.
233 | echo.Testing of doctests in the sources finished, look at the ^
234 | results in %BUILDDIR%/doctest/output.txt.
235 | goto end
236 | )
237 |
238 | if "%1" == "coverage" (
239 | %SPHINXBUILD% -b coverage %ALLSPHINXOPTS% %BUILDDIR%/coverage
240 | if errorlevel 1 exit /b 1
241 | echo.
242 | echo.Testing of coverage in the sources finished, look at the ^
243 | results in %BUILDDIR%/coverage/python.txt.
244 | goto end
245 | )
246 |
247 | if "%1" == "xml" (
248 | %SPHINXBUILD% -b xml %ALLSPHINXOPTS% %BUILDDIR%/xml
249 | if errorlevel 1 exit /b 1
250 | echo.
251 | echo.Build finished. The XML files are in %BUILDDIR%/xml.
252 | goto end
253 | )
254 |
255 | if "%1" == "pseudoxml" (
256 | %SPHINXBUILD% -b pseudoxml %ALLSPHINXOPTS% %BUILDDIR%/pseudoxml
257 | if errorlevel 1 exit /b 1
258 | echo.
259 | echo.Build finished. The pseudo-XML files are in %BUILDDIR%/pseudoxml.
260 | goto end
261 | )
262 |
263 | :end
264 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ## Django Highcharts
2 |
3 | This project starts from a fork of novapost package to
4 | generate charts in your Django application using Highcharts helpers.
5 |
6 | - Pie with drilldown charts
7 | - 3D Pie Options
8 | - Speedometer charts
9 | - Multiple Axes charts
10 | - Area charts
11 | - Bar charts
12 | - Heatmap charts
13 | - Polar Spider web charts
14 | - HighStock basic charts
15 |
16 | * `Source code is on Github `
17 |
18 | ### Install
19 | There are a few different ways you can install pyechonest:
20 |
21 | * Use setuptools: `pip install django-highcharts`
22 | * Download the zipfile from the [downloads](https://github.com/ernestoarbitrio/django-highcharts/archive/master.zip) page and install it.
23 | * Checkout the source: `git@github.com:ernestoarbitrio/django-highcharts.git` and install it yourself.
24 |
25 | In your settings file:
26 | ```
27 | INSTALLED_APPS = [
28 | ### other apps ###
29 | 'highcharts'
30 | ### other apps ###
31 | ]
32 | ```
33 |
34 | Don’t forget to set your STATIC_ROOT path and to run the following command to update the static files:
35 |
36 | `python manage.py collectstatic`
37 |
38 | Write a graph with different series type (in view.py file or if you want in a graph.py file):
39 | ```
40 | from highcharts.views import (HighChartsMultiAxesView, HighChartsPieView,
41 | HighChartsSpeedometerView, HighChartsHeatMapView, HighChartsPolarView)
42 |
43 | class BarView(HighChartsMultiAxesView):
44 | title = 'Example Bar Chart'
45 | subtitle = 'my subtitle'
46 | categories = ['Orange', 'Bananas', 'Apples']
47 | chart_type = ''
48 | chart = {'zoomType': 'xy'}
49 | tooltip = {'shared': 'true'}
50 | legend = {'layout': 'horizontal', 'align': 'left',
51 | 'floating': 'true', 'verticalAlign': 'top',
52 | 'y': -10, 'borderColor': '#e3e3e3'}
53 |
54 | @property
55 | def yaxis(self):
56 | y_axis = [
57 | {'labels': {'format': '{value} pz/sc ', 'style': {'color': '#f67d0a'}},
58 | 'title': {'text': "Oranges", 'style': {'color': '#f67d0a'}},
59 | 'opposite': 'true'},
60 | {'gridLineWidth': 1,
61 | 'title': {'text': "Bananas", 'style': {'color': '#3771c8'}},
62 | 'labels': {'style': {'color': '#3771c8'}, 'format': '{value} euro'}},
63 | {'gridLineWidth': 1,
64 | 'title': {'text': "Apples", 'style': {'color': '#666666'}},
65 | 'labels': {'format': '{value} pz', 'style': {'color': '#666666'}},
66 | 'opposite': 'true'}
67 | ]
68 | return y_axis
69 |
70 | @property
71 | def series(self):
72 | series = [
73 | {
74 | 'name': 'Orange',
75 | 'type': 'column',
76 | 'yAxis': 1,
77 | 'data': [90,44,55,67,4,5,6,3,2,45,2,3,2,45,5],
78 | 'tooltip': "{ valueSuffix: ' euro' }",
79 | 'color': '#3771c8'
80 | },
81 | {
82 | 'name': 'Bananas',
83 | 'type': 'spline',
84 | 'yAxis': 2,
85 | 'data': [12,34,34,34, 5,34,3,45,2,3,2,4,4,1,23],
86 | 'marker': { 'enabled': 'true' },
87 | 'dashStyle': 'shortdot',
88 | 'color': '#666666',
89 | },
90 | {
91 | 'name': 'Apples',
92 | 'type': 'spline',
93 | 'data': [12,23,23,23,21,4,4,76,3,66,6,4,5,2,3],
94 | 'color': '#f67d0a'
95 | }
96 | ]
97 | return series
98 | ```
99 | if you want you can write a graph based on a particular class of chart. For example if you need a pie chart with drilldown interaction:
100 | ```
101 | from highcharts.views import (HighChartsMultiAxesView, HighChartsPieView,
102 | HighChartsSpeedometerView, HighChartsHeatMapView, HighChartsPolarView)
103 |
104 | class PieDrilldown(HighChartsPieView):
105 | title = 'Torta'
106 | subtitle = 'torino'
107 |
108 | @property
109 | def series(self):
110 | series = [
111 | {
112 | 'name': 'Classi',
113 | 'colorByPoint': 'true',
114 | 'data': [
115 | {'name': 'Emorroidi',
116 | 'y': 10,
117 | 'drilldown': 'emorroidi'},
118 | {'name': 'Igiene e bellezza',
119 | 'y': 12,
120 | 'drilldown': 'igiene'},
121 | {'name': 'Omeopatia',
122 | 'y': 8,
123 | 'drilldown': 'omeopatia'}
124 | ]
125 | }
126 | ]
127 | return series
128 |
129 | @property
130 | def drilldown(self):
131 | drilldown = {
132 | 'series': [
133 | {'id': 'emorroidi',
134 | 'name': 'Emorroidi',
135 | 'data': [
136 | ['brand1', 7],
137 | ['brand2', 3],
138 | ['brand3', 5]
139 | ]},
140 | {'id': 'igiene',
141 | 'name': 'Igiene e Bellezza',
142 | 'data': [
143 | ['brand1', 3],
144 | ['brand2', 1],
145 | ['brand3', 4],
146 | ['brand4', 5]
147 | ]},
148 | {'id': 'omeopatia',
149 | 'name': 'Omeopatia',
150 | 'data': [
151 | ['brand1', 3],
152 | ['brand2', 1],
153 | ['brand3', 4],
154 | ['', 0]
155 | ]}
156 | ]
157 | }
158 | return drilldown
159 |
160 |
161 | ```
162 |
163 |
164 | Then you need to map the graph to an url in url.py file:
165 | ```
166 | from graphs.py import BarView
167 | url(regex='^bar/$', view=BarView.as_view(), name='bar')
168 | ```
169 |
170 | In the template:
171 | ```
172 | {% load highcharts_tags %}
173 |
174 |
175 | {% highcharts_js 1 0 0 0 %}
176 |
177 |
178 |
179 | $(function () {
180 | $.getJSON("{% url 'bar' %}", function(data) {
181 | $('#container').highcharts(data);
182 | });
183 | })
184 | ```
185 |
186 | An advanced example with parameters passed via url and data retrived from db (using orm or raw query)
187 | ```
188 | class AdvancedGraph(HighChartsMultiAxesView):
189 | title = 'Advanced graph'
190 | subtitle = 'params and query'
191 | chart = {'zoomType': 'xy'}
192 | tooltip = {'shared': 'true'}
193 | legend = {
194 | 'layout': 'vertical',
195 | 'align': 'left',
196 | 'verticalAlign': 'top',
197 | 'y': 30
198 | }
199 |
200 | def get_data(self):
201 | param = self.kwargs['param1']
202 | f = MyModel.objects.get(field=param)
203 | cursor = connection.cursor()
204 | cursor.execute("select * from mydbfunction(%s)" as (outvalues json)", [f.pk])
205 | graph = cursor.fetchall()
206 |
207 | #### SERIES
208 | self.serie = graph[0]
209 |
210 | ##### X LABELS
211 | self.categories = graph[1]
212 |
213 | ##### Y AXIS DEFINITIONS
214 | self.yaxis = {
215 | 'title': {
216 | 'text': 'Title 1'
217 | },
218 | 'plotLines': [
219 | {
220 | 'value': 0,
221 | 'width': 1,
222 | 'color': '#808080'
223 | }
224 | ]
225 | }
226 |
227 | ##### SERIES WITH VALUES
228 | self.series = self.serie
229 | data = super(AdvancedGraph, self).get_data()
230 | return data
231 | ```
232 | then in urls.py
233 | Then you need to map the graph to an url in url.py file:
234 | ```
235 | from graphs.py import AdvancedGraph
236 | url(regex='^adv/(?P\d+)/$', view=AdvancedGraph.as_view(), name='adv')
237 | ```
238 |
--------------------------------------------------------------------------------
/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 | # User-friendly check for sphinx-build
11 | ifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1)
12 | $(error The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx installed, then set the SPHINXBUILD environment variable to point to the full path of the '$(SPHINXBUILD)' executable. Alternatively you can add the directory with the executable to your PATH. If you don't have Sphinx installed, grab it from http://sphinx-doc.org/)
13 | endif
14 |
15 | # Internal variables.
16 | PAPEROPT_a4 = -D latex_paper_size=a4
17 | PAPEROPT_letter = -D latex_paper_size=letter
18 | ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
19 | # the i18n builder cannot share the environment and doctrees with the others
20 | I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
21 |
22 | .PHONY: help
23 | help:
24 | @echo "Please use \`make ' where is one of"
25 | @echo " html to make standalone HTML files"
26 | @echo " dirhtml to make HTML files named index.html in directories"
27 | @echo " singlehtml to make a single large HTML file"
28 | @echo " pickle to make pickle files"
29 | @echo " json to make JSON files"
30 | @echo " htmlhelp to make HTML files and a HTML help project"
31 | @echo " qthelp to make HTML files and a qthelp project"
32 | @echo " applehelp to make an Apple Help Book"
33 | @echo " devhelp to make HTML files and a Devhelp project"
34 | @echo " epub to make an epub"
35 | @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
36 | @echo " latexpdf to make LaTeX files and run them through pdflatex"
37 | @echo " latexpdfja to make LaTeX files and run them through platex/dvipdfmx"
38 | @echo " text to make text files"
39 | @echo " man to make manual pages"
40 | @echo " texinfo to make Texinfo files"
41 | @echo " info to make Texinfo files and run them through makeinfo"
42 | @echo " gettext to make PO message catalogs"
43 | @echo " changes to make an overview of all changed/added/deprecated items"
44 | @echo " xml to make Docutils-native XML files"
45 | @echo " pseudoxml to make pseudoxml-XML files for display purposes"
46 | @echo " linkcheck to check all external links for integrity"
47 | @echo " doctest to run all doctests embedded in the documentation (if enabled)"
48 | @echo " coverage to run coverage check of the documentation (if enabled)"
49 |
50 | .PHONY: clean
51 | clean:
52 | rm -rf $(BUILDDIR)/*
53 |
54 | .PHONY: html
55 | html:
56 | $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
57 | @echo
58 | @echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
59 |
60 | .PHONY: dirhtml
61 | dirhtml:
62 | $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
63 | @echo
64 | @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
65 |
66 | .PHONY: singlehtml
67 | singlehtml:
68 | $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml
69 | @echo
70 | @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml."
71 |
72 | .PHONY: pickle
73 | pickle:
74 | $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
75 | @echo
76 | @echo "Build finished; now you can process the pickle files."
77 |
78 | .PHONY: json
79 | json:
80 | $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
81 | @echo
82 | @echo "Build finished; now you can process the JSON files."
83 |
84 | .PHONY: htmlhelp
85 | htmlhelp:
86 | $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
87 | @echo
88 | @echo "Build finished; now you can run HTML Help Workshop with the" \
89 | ".hhp project file in $(BUILDDIR)/htmlhelp."
90 |
91 | .PHONY: qthelp
92 | qthelp:
93 | $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
94 | @echo
95 | @echo "Build finished; now you can run "qcollectiongenerator" with the" \
96 | ".qhcp project file in $(BUILDDIR)/qthelp, like this:"
97 | @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/django-highcharts.qhcp"
98 | @echo "To view the help file:"
99 | @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/django-highcharts.qhc"
100 |
101 | .PHONY: applehelp
102 | applehelp:
103 | $(SPHINXBUILD) -b applehelp $(ALLSPHINXOPTS) $(BUILDDIR)/applehelp
104 | @echo
105 | @echo "Build finished. The help book is in $(BUILDDIR)/applehelp."
106 | @echo "N.B. You won't be able to view it unless you put it in" \
107 | "~/Library/Documentation/Help or install it in your application" \
108 | "bundle."
109 |
110 | .PHONY: devhelp
111 | devhelp:
112 | $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp
113 | @echo
114 | @echo "Build finished."
115 | @echo "To view the help file:"
116 | @echo "# mkdir -p $$HOME/.local/share/devhelp/django-highcharts"
117 | @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/django-highcharts"
118 | @echo "# devhelp"
119 |
120 | .PHONY: epub
121 | epub:
122 | $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub
123 | @echo
124 | @echo "Build finished. The epub file is in $(BUILDDIR)/epub."
125 |
126 | .PHONY: latex
127 | latex:
128 | $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
129 | @echo
130 | @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
131 | @echo "Run \`make' in that directory to run these through (pdf)latex" \
132 | "(use \`make latexpdf' here to do that automatically)."
133 |
134 | .PHONY: latexpdf
135 | latexpdf:
136 | $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
137 | @echo "Running LaTeX files through pdflatex..."
138 | $(MAKE) -C $(BUILDDIR)/latex all-pdf
139 | @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
140 |
141 | .PHONY: latexpdfja
142 | latexpdfja:
143 | $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
144 | @echo "Running LaTeX files through platex and dvipdfmx..."
145 | $(MAKE) -C $(BUILDDIR)/latex all-pdf-ja
146 | @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
147 |
148 | .PHONY: text
149 | text:
150 | $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text
151 | @echo
152 | @echo "Build finished. The text files are in $(BUILDDIR)/text."
153 |
154 | .PHONY: man
155 | man:
156 | $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man
157 | @echo
158 | @echo "Build finished. The manual pages are in $(BUILDDIR)/man."
159 |
160 | .PHONY: texinfo
161 | texinfo:
162 | $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
163 | @echo
164 | @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo."
165 | @echo "Run \`make' in that directory to run these through makeinfo" \
166 | "(use \`make info' here to do that automatically)."
167 |
168 | .PHONY: info
169 | info:
170 | $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
171 | @echo "Running Texinfo files through makeinfo..."
172 | make -C $(BUILDDIR)/texinfo info
173 | @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo."
174 |
175 | .PHONY: gettext
176 | gettext:
177 | $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale
178 | @echo
179 | @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale."
180 |
181 | .PHONY: changes
182 | changes:
183 | $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
184 | @echo
185 | @echo "The overview file is in $(BUILDDIR)/changes."
186 |
187 | .PHONY: linkcheck
188 | linkcheck:
189 | $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
190 | @echo
191 | @echo "Link check complete; look for any errors in the above output " \
192 | "or in $(BUILDDIR)/linkcheck/output.txt."
193 |
194 | .PHONY: doctest
195 | doctest:
196 | $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
197 | @echo "Testing of doctests in the sources finished, look at the " \
198 | "results in $(BUILDDIR)/doctest/output.txt."
199 |
200 | .PHONY: coverage
201 | coverage:
202 | $(SPHINXBUILD) -b coverage $(ALLSPHINXOPTS) $(BUILDDIR)/coverage
203 | @echo "Testing of coverage in the sources finished, look at the " \
204 | "results in $(BUILDDIR)/coverage/python.txt."
205 |
206 | .PHONY: xml
207 | xml:
208 | $(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml
209 | @echo
210 | @echo "Build finished. The XML files are in $(BUILDDIR)/xml."
211 |
212 | .PHONY: pseudoxml
213 | pseudoxml:
214 | $(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml
215 | @echo
216 | @echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml."
217 |
--------------------------------------------------------------------------------
/highcharts/static/js/highcharts/modules/funnel.src.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @license
3 | * Highcharts funnel module
4 | *
5 | * (c) 2010-2014 Torstein Honsi
6 | *
7 | * License: www.highcharts.com/license
8 | */
9 |
10 | /*global Highcharts */
11 | (function (Highcharts) {
12 |
13 | 'use strict';
14 |
15 | // create shortcuts
16 | var defaultOptions = Highcharts.getOptions(),
17 | defaultPlotOptions = defaultOptions.plotOptions,
18 | seriesTypes = Highcharts.seriesTypes,
19 | merge = Highcharts.merge,
20 | noop = function () {},
21 | each = Highcharts.each;
22 |
23 | // set default options
24 | defaultPlotOptions.funnel = merge(defaultPlotOptions.pie, {
25 | animation: false,
26 | center: ['50%', '50%'],
27 | width: '90%',
28 | neckWidth: '30%',
29 | height: '100%',
30 | neckHeight: '25%',
31 | reversed: false,
32 | dataLabels: {
33 | //position: 'right',
34 | connectorWidth: 1,
35 | connectorColor: '#606060'
36 | },
37 | size: true, // to avoid adapting to data label size in Pie.drawDataLabels
38 | states: {
39 | select: {
40 | color: '#C0C0C0',
41 | borderColor: '#000000',
42 | shadow: false
43 | }
44 | }
45 | });
46 |
47 |
48 | seriesTypes.funnel = Highcharts.extendClass(seriesTypes.pie, {
49 |
50 | type: 'funnel',
51 | animate: noop,
52 | singularTooltips: true,
53 |
54 | /**
55 | * Overrides the pie translate method
56 | */
57 | translate: function () {
58 |
59 | var
60 | // Get positions - either an integer or a percentage string must be given
61 | getLength = function (length, relativeTo) {
62 | return (/%$/).test(length) ?
63 | relativeTo * parseInt(length, 10) / 100 :
64 | parseInt(length, 10);
65 | },
66 |
67 | sum = 0,
68 | series = this,
69 | chart = series.chart,
70 | options = series.options,
71 | reversed = options.reversed,
72 | plotWidth = chart.plotWidth,
73 | plotHeight = chart.plotHeight,
74 | cumulative = 0, // start at top
75 | center = options.center,
76 | centerX = getLength(center[0], plotWidth),
77 | centerY = getLength(center[0], plotHeight),
78 | width = getLength(options.width, plotWidth),
79 | tempWidth,
80 | getWidthAt,
81 | height = getLength(options.height, plotHeight),
82 | neckWidth = getLength(options.neckWidth, plotWidth),
83 | neckHeight = getLength(options.neckHeight, plotHeight),
84 | neckY = height - neckHeight,
85 | data = series.data,
86 | path,
87 | fraction,
88 | half = options.dataLabels.position === 'left' ? 1 : 0,
89 |
90 | x1,
91 | y1,
92 | x2,
93 | x3,
94 | y3,
95 | x4,
96 | y5;
97 |
98 | // Return the width at a specific y coordinate
99 | series.getWidthAt = getWidthAt = function (y) {
100 | return y > height - neckHeight || height === neckHeight ?
101 | neckWidth :
102 | neckWidth + (width - neckWidth) * ((height - neckHeight - y) / (height - neckHeight));
103 | };
104 | series.getX = function (y, half) {
105 | return centerX + (half ? -1 : 1) * ((getWidthAt(reversed ? plotHeight - y : y) / 2) + options.dataLabels.distance);
106 | };
107 |
108 | // Expose
109 | series.center = [centerX, centerY, height];
110 | series.centerX = centerX;
111 |
112 | /*
113 | * Individual point coordinate naming:
114 | *
115 | * x1,y1 _________________ x2,y1
116 | * \ /
117 | * \ /
118 | * \ /
119 | * \ /
120 | * \ /
121 | * x3,y3 _________ x4,y3
122 | *
123 | * Additional for the base of the neck:
124 | *
125 | * | |
126 | * | |
127 | * | |
128 | * x3,y5 _________ x4,y5
129 | */
130 |
131 |
132 |
133 |
134 | // get the total sum
135 | each(data, function (point) {
136 | sum += point.y;
137 | });
138 |
139 | each(data, function (point) {
140 | // set start and end positions
141 | y5 = null;
142 | fraction = sum ? point.y / sum : 0;
143 | y1 = centerY - height / 2 + cumulative * height;
144 | y3 = y1 + fraction * height;
145 | //tempWidth = neckWidth + (width - neckWidth) * ((height - neckHeight - y1) / (height - neckHeight));
146 | tempWidth = getWidthAt(y1);
147 | x1 = centerX - tempWidth / 2;
148 | x2 = x1 + tempWidth;
149 | tempWidth = getWidthAt(y3);
150 | x3 = centerX - tempWidth / 2;
151 | x4 = x3 + tempWidth;
152 |
153 | // the entire point is within the neck
154 | if (y1 > neckY) {
155 | x1 = x3 = centerX - neckWidth / 2;
156 | x2 = x4 = centerX + neckWidth / 2;
157 |
158 | // the base of the neck
159 | } else if (y3 > neckY) {
160 | y5 = y3;
161 |
162 | tempWidth = getWidthAt(neckY);
163 | x3 = centerX - tempWidth / 2;
164 | x4 = x3 + tempWidth;
165 |
166 | y3 = neckY;
167 | }
168 |
169 | if (reversed) {
170 | y1 = height - y1;
171 | y3 = height - y3;
172 | y5 = (y5 ? height - y5 : null);
173 | }
174 | // save the path
175 | path = [
176 | 'M',
177 | x1, y1,
178 | 'L',
179 | x2, y1,
180 | x4, y3
181 | ];
182 | if (y5) {
183 | path.push(x4, y5, x3, y5);
184 | }
185 | path.push(x3, y3, 'Z');
186 |
187 | // prepare for using shared dr
188 | point.shapeType = 'path';
189 | point.shapeArgs = { d: path };
190 |
191 |
192 | // for tooltips and data labels
193 | point.percentage = fraction * 100;
194 | point.plotX = centerX;
195 | point.plotY = (y1 + (y5 || y3)) / 2;
196 |
197 | // Placement of tooltips and data labels
198 | point.tooltipPos = [
199 | centerX,
200 | point.plotY
201 | ];
202 |
203 | // Slice is a noop on funnel points
204 | point.slice = noop;
205 |
206 | // Mimicking pie data label placement logic
207 | point.half = half;
208 |
209 | cumulative += fraction;
210 | });
211 | },
212 | /**
213 | * Draw a single point (wedge)
214 | * @param {Object} point The point object
215 | * @param {Object} color The color of the point
216 | * @param {Number} brightness The brightness relative to the color
217 | */
218 | drawPoints: function () {
219 | var series = this,
220 | options = series.options,
221 | chart = series.chart,
222 | renderer = chart.renderer;
223 |
224 | each(series.data, function (point) {
225 |
226 | var graphic = point.graphic,
227 | shapeArgs = point.shapeArgs;
228 |
229 | if (!graphic) { // Create the shapes
230 | point.graphic = renderer.path(shapeArgs).
231 | attr({
232 | fill: point.color,
233 | stroke: options.borderColor,
234 | 'stroke-width': options.borderWidth
235 | }).
236 | add(series.group);
237 |
238 | } else { // Update the shapes
239 | graphic.animate(shapeArgs);
240 | }
241 | });
242 | },
243 |
244 | /**
245 | * Funnel items don't have angles (#2289)
246 | */
247 | sortByAngle: function (points) {
248 | points.sort(function (a, b) {
249 | return a.plotY - b.plotY;
250 | });
251 | },
252 |
253 | /**
254 | * Extend the pie data label method
255 | */
256 | drawDataLabels: function () {
257 | var data = this.data,
258 | labelDistance = this.options.dataLabels.distance,
259 | leftSide,
260 | sign,
261 | point,
262 | i = data.length,
263 | x,
264 | y;
265 |
266 | // In the original pie label anticollision logic, the slots are distributed
267 | // from one labelDistance above to one labelDistance below the pie. In funnels
268 | // we don't want this.
269 | this.center[2] -= 2 * labelDistance;
270 |
271 | // Set the label position array for each point.
272 | while (i--) {
273 | point = data[i];
274 | leftSide = point.half;
275 | sign = leftSide ? 1 : -1;
276 | y = point.plotY;
277 | x = this.getX(y, leftSide);
278 |
279 | // set the anchor point for data labels
280 | point.labelPos = [
281 | 0, // first break of connector
282 | y, // a/a
283 | x + (labelDistance - 5) * sign, // second break, right outside point shape
284 | y, // a/a
285 | x + labelDistance * sign, // landing point for connector
286 | y, // a/a
287 | leftSide ? 'right' : 'left', // alignment
288 | 0 // center angle
289 | ];
290 | }
291 |
292 | seriesTypes.pie.prototype.drawDataLabels.call(this);
293 | }
294 |
295 | });
296 |
297 | /**
298 | * Pyramid series type.
299 | * A pyramid series is a special type of funnel, without neck and reversed by default.
300 | */
301 | defaultOptions.plotOptions.pyramid = Highcharts.merge(defaultOptions.plotOptions.funnel, {
302 | neckWidth: '0%',
303 | neckHeight: '0%',
304 | reversed: true
305 | });
306 | Highcharts.seriesTypes.pyramid = Highcharts.extendClass(Highcharts.seriesTypes.funnel, {
307 | type: 'pyramid'
308 | });
309 |
310 | }(Highcharts));
311 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/docs/conf.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | #
3 | # django-highcharts documentation build configuration file, created by
4 | # sphinx-quickstart on Thu Feb 11 15:28:11 2016.
5 | #
6 | # This file is execfile()d with the current directory set to its
7 | # containing dir.
8 | #
9 | # Note that not all possible configuration values are present in this
10 | # autogenerated file.
11 | #
12 | # All configuration values have a default; values that are commented out
13 | # serve to show the default.
14 |
15 | import sys
16 | import os
17 |
18 | # If extensions (or modules to document with autodoc) are in another directory,
19 | # add these directories to sys.path here. If the directory is relative to the
20 | # documentation root, use os.path.abspath to make it absolute, like shown here.
21 | #sys.path.insert(0, os.path.abspath('.'))
22 |
23 | # -- General configuration ------------------------------------------------
24 |
25 | # If your documentation needs a minimal Sphinx version, state it here.
26 | #needs_sphinx = '1.0'
27 |
28 | # Add any Sphinx extension module names here, as strings. They can be
29 | # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
30 | # ones.
31 | extensions = []
32 |
33 | # Add any paths that contain templates here, relative to this directory.
34 | templates_path = ['_templates']
35 |
36 | # The suffix(es) of source filenames.
37 | # You can specify multiple suffix as a list of string:
38 | # source_suffix = ['.rst', '.md']
39 | source_suffix = '.rst'
40 |
41 | # The encoding of source files.
42 | #source_encoding = 'utf-8-sig'
43 |
44 | # The master toctree document.
45 | master_doc = 'index'
46 |
47 | # General information about the project.
48 | project = u'django-highcharts'
49 | copyright = u'2016, Ernesto Arbitrio'
50 | author = u'Ernesto Arbitrio'
51 |
52 | # The version info for the project you're documenting, acts as replacement for
53 | # |version| and |release|, also used in various other places throughout the
54 | # built documents.
55 | #
56 | # The short X.Y version.
57 | version = u'0.1.7'
58 | # The full version, including alpha/beta/rc tags.
59 | release = u'0.1.7'
60 |
61 | # The language for content autogenerated by Sphinx. Refer to documentation
62 | # for a list of supported languages.
63 | #
64 | # This is also used if you do content translation via gettext catalogs.
65 | # Usually you set "language" from the command line for these cases.
66 | language = None
67 |
68 | # There are two options for replacing |today|: either, you set today to some
69 | # non-false value, then it is used:
70 | #today = ''
71 | # Else, today_fmt is used as the format for a strftime call.
72 | #today_fmt = '%B %d, %Y'
73 |
74 | # List of patterns, relative to source directory, that match files and
75 | # directories to ignore when looking for source files.
76 | exclude_patterns = ['_build']
77 |
78 | # The reST default role (used for this markup: `text`) to use for all
79 | # documents.
80 | #default_role = None
81 |
82 | # If true, '()' will be appended to :func: etc. cross-reference text.
83 | #add_function_parentheses = True
84 |
85 | # If true, the current module name will be prepended to all description
86 | # unit titles (such as .. function::).
87 | #add_module_names = True
88 |
89 | # If true, sectionauthor and moduleauthor directives will be shown in the
90 | # output. They are ignored by default.
91 | #show_authors = False
92 |
93 | # The name of the Pygments (syntax highlighting) style to use.
94 | pygments_style = 'sphinx'
95 |
96 | # A list of ignored prefixes for module index sorting.
97 | #modindex_common_prefix = []
98 |
99 | # If true, keep warnings as "system message" paragraphs in the built documents.
100 | #keep_warnings = False
101 |
102 | # If true, `todo` and `todoList` produce output, else they produce nothing.
103 | todo_include_todos = False
104 |
105 |
106 | # -- Options for HTML output ----------------------------------------------
107 |
108 | # The theme to use for HTML and HTML Help pages. See the documentation for
109 | # a list of builtin themes.
110 | html_theme = 'alabaster'
111 |
112 | # Theme options are theme-specific and customize the look and feel of a theme
113 | # further. For a list of options available for each theme, see the
114 | # documentation.
115 | #html_theme_options = {}
116 |
117 | # Add any paths that contain custom themes here, relative to this directory.
118 | #html_theme_path = []
119 |
120 | # The name for this set of Sphinx documents. If None, it defaults to
121 | # " v documentation".
122 | #html_title = None
123 |
124 | # A shorter title for the navigation bar. Default is the same as html_title.
125 | #html_short_title = None
126 |
127 | # The name of an image file (relative to this directory) to place at the top
128 | # of the sidebar.
129 | #html_logo = None
130 |
131 | # The name of an image file (within the static path) to use as favicon of the
132 | # docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
133 | # pixels large.
134 | #html_favicon = None
135 |
136 | # Add any paths that contain custom static files (such as style sheets) here,
137 | # relative to this directory. They are copied after the builtin static files,
138 | # so a file named "default.css" will overwrite the builtin "default.css".
139 | html_static_path = ['_static']
140 |
141 | # Add any extra paths that contain custom files (such as robots.txt or
142 | # .htaccess) here, relative to this directory. These files are copied
143 | # directly to the root of the documentation.
144 | #html_extra_path = []
145 |
146 | # If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
147 | # using the given strftime format.
148 | #html_last_updated_fmt = '%b %d, %Y'
149 |
150 | # If true, SmartyPants will be used to convert quotes and dashes to
151 | # typographically correct entities.
152 | #html_use_smartypants = True
153 |
154 | # Custom sidebar templates, maps document names to template names.
155 | #html_sidebars = {}
156 |
157 | # Additional templates that should be rendered to pages, maps page names to
158 | # template names.
159 | #html_additional_pages = {}
160 |
161 | # If false, no module index is generated.
162 | #html_domain_indices = True
163 |
164 | # If false, no index is generated.
165 | #html_use_index = True
166 |
167 | # If true, the index is split into individual pages for each letter.
168 | #html_split_index = False
169 |
170 | # If true, links to the reST sources are added to the pages.
171 | #html_show_sourcelink = True
172 |
173 | # If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
174 | #html_show_sphinx = True
175 |
176 | # If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
177 | #html_show_copyright = True
178 |
179 | # If true, an OpenSearch description file will be output, and all pages will
180 | # contain a tag referring to it. The value of this option must be the
181 | # base URL from which the finished HTML is served.
182 | #html_use_opensearch = ''
183 |
184 | # This is the file name suffix for HTML files (e.g. ".xhtml").
185 | #html_file_suffix = None
186 |
187 | # Language to be used for generating the HTML full-text search index.
188 | # Sphinx supports the following languages:
189 | # 'da', 'de', 'en', 'es', 'fi', 'fr', 'hu', 'it', 'ja'
190 | # 'nl', 'no', 'pt', 'ro', 'ru', 'sv', 'tr'
191 | #html_search_language = 'en'
192 |
193 | # A dictionary with options for the search language support, empty by default.
194 | # Now only 'ja' uses this config value
195 | #html_search_options = {'type': 'default'}
196 |
197 | # The name of a javascript file (relative to the configuration directory) that
198 | # implements a search results scorer. If empty, the default will be used.
199 | #html_search_scorer = 'scorer.js'
200 |
201 | # Output file base name for HTML help builder.
202 | htmlhelp_basename = 'django-highchartsdoc'
203 |
204 | # -- Options for LaTeX output ---------------------------------------------
205 |
206 | latex_elements = {
207 | # The paper size ('letterpaper' or 'a4paper').
208 | #'papersize': 'letterpaper',
209 |
210 | # The font size ('10pt', '11pt' or '12pt').
211 | #'pointsize': '10pt',
212 |
213 | # Additional stuff for the LaTeX preamble.
214 | #'preamble': '',
215 |
216 | # Latex figure (float) alignment
217 | #'figure_align': 'htbp',
218 | }
219 |
220 | # Grouping the document tree into LaTeX files. List of tuples
221 | # (source start file, target name, title,
222 | # author, documentclass [howto, manual, or own class]).
223 | latex_documents = [
224 | (master_doc, 'django-highcharts.tex', u'django-highcharts Documentation',
225 | u'Ernesto Arbitrio', 'manual'),
226 | ]
227 |
228 | # The name of an image file (relative to this directory) to place at the top of
229 | # the title page.
230 | #latex_logo = None
231 |
232 | # For "manual" documents, if this is true, then toplevel headings are parts,
233 | # not chapters.
234 | #latex_use_parts = False
235 |
236 | # If true, show page references after internal links.
237 | #latex_show_pagerefs = False
238 |
239 | # If true, show URL addresses after external links.
240 | #latex_show_urls = False
241 |
242 | # Documents to append as an appendix to all manuals.
243 | #latex_appendices = []
244 |
245 | # If false, no module index is generated.
246 | #latex_domain_indices = True
247 |
248 |
249 | # -- Options for manual page output ---------------------------------------
250 |
251 | # One entry per manual page. List of tuples
252 | # (source start file, name, description, authors, manual section).
253 | man_pages = [
254 | (master_doc, 'django-highcharts', u'django-highcharts Documentation',
255 | [author], 1)
256 | ]
257 |
258 | # If true, show URL addresses after external links.
259 | #man_show_urls = False
260 |
261 |
262 | # -- Options for Texinfo output -------------------------------------------
263 |
264 | # Grouping the document tree into Texinfo files. List of tuples
265 | # (source start file, target name, title, author,
266 | # dir menu entry, description, category)
267 | texinfo_documents = [
268 | (master_doc, 'django-highcharts', u'django-highcharts Documentation',
269 | author, 'django-highcharts', 'One line description of project.',
270 | 'Miscellaneous'),
271 | ]
272 |
273 | # Documents to append as an appendix to all manuals.
274 | #texinfo_appendices = []
275 |
276 | # If false, no module index is generated.
277 | #texinfo_domain_indices = True
278 |
279 | # How to display URL addresses: 'footnote', 'no', or 'inline'.
280 | #texinfo_show_urls = 'footnote'
281 |
282 | # If true, do not generate a @detailmenu in the "Top" node's menu.
283 | #texinfo_no_detailmenu = False
284 |
--------------------------------------------------------------------------------
/highcharts/static/js/highcharts/technical-indicators.src.js:
--------------------------------------------------------------------------------
1 | (function (H) {
2 |
3 | // create shortcuts
4 | var defaultOptions = H.getOptions(),
5 | defaultPlotOptions = defaultOptions.plotOptions,
6 | seriesTypes = H.seriesTypes;
7 |
8 | // Trendline functionality and default options.
9 | defaultPlotOptions.trendline = H.merge(defaultPlotOptions.line, {
10 |
11 | marker: {
12 | enabled: false
13 | },
14 |
15 | tooltip: {
16 | valueDecimals: 2
17 | }
18 | });
19 |
20 | seriesTypes.trendline = H.extendClass(seriesTypes.line, {
21 |
22 | type: 'trendline',
23 | animate: null,
24 | requiresSorting: false,
25 | processData: function() {
26 | var data;
27 |
28 | if (this.linkedParent) {
29 | data = [].concat(this.linkedParent.options.data)
30 | this.setData(this.runAlgorithm(), false);
31 | }
32 |
33 | H.Series.prototype.processData.call(this);
34 | },
35 | runAlgorithm: function () {
36 |
37 | var xData = this.linkedParent.xData,
38 | yData = this.linkedParent.yData,
39 | periods = this.options.periods || 100, // Set this to what default? should be defaults for each algorithm.
40 | algorithm = this.options.algorithm || 'linear';
41 |
42 | return this[algorithm](xData, yData, periods);
43 | },
44 |
45 |
46 | /* Function that uses the calcMACD function to return the MACD line.
47 | *
48 | * @return : the first index of the calcMACD return, the MACD.
49 | **/
50 | MACD: function (xData, yData, periods) {
51 |
52 | return calcMACD(xData, yData, periods)[0];
53 | },
54 |
55 | /* Function that uses the global calcMACD.
56 | *
57 | * @return : the second index of the calcMACD return, the signalLine.
58 | **/
59 | signalLine: function (xData, yData, periods) {
60 |
61 | return calcMACD(xData, yData, periods)[1];
62 | },
63 |
64 | /* Function using the global SMA function.
65 | *
66 | * @return : an array of SMA data.
67 | **/
68 | SMA: function (xData, yData, periods) {
69 |
70 | return SMA(xData, yData, periods);
71 | },
72 |
73 |
74 | /* Function using the global EMA function.
75 | *
76 | * @return : an array of EMA data.
77 | **/
78 | EMA: function (xData, yData, periods) {
79 |
80 | return EMA(xData, yData, periods);
81 | },
82 |
83 | /* Function that uses the global linear function.
84 | *
85 | * @return : an array of EMA data
86 | **/
87 | linear: function (xData, yData, periods) {
88 |
89 | return linear(xData, yData, periods);
90 | }
91 |
92 | });
93 |
94 | // Setting default options for the Histogram type.
95 | defaultPlotOptions.histogram = H.merge(defaultPlotOptions.column, {
96 |
97 | borderWidth : 0,
98 |
99 | tooltip: {
100 | valueDecimals: 2
101 | }
102 |
103 | });
104 |
105 |
106 | seriesTypes.histogram = H.extendClass(seriesTypes.column, {
107 |
108 | type: 'histogram',
109 | animate: null,
110 | requiresSorting: false,
111 | processData: function() {
112 | var data;
113 |
114 | if (this.linkedParent) {
115 | data = [].concat(this.linkedParent.options.data)
116 | this.setData(this.runAlgorithm(), false);
117 | }
118 |
119 | H.Series.prototype.processData.call(this);
120 | },
121 |
122 | runAlgorithm: function () {
123 |
124 | var xData = this.linkedParent.xData,
125 | yData = this.linkedParent.yData,
126 | periods = this.options.periods || 100, // Set this to what default? should be defaults for each algorithm.
127 | algorithm = this.options.algorithm || 'histogram';
128 |
129 | return this[algorithm](xData, yData, periods);
130 | },
131 |
132 |
133 | histogram: function (xData, yData, periods) {
134 |
135 | return calcMACD(xData, yData, periods)[2];
136 | },
137 |
138 | });
139 |
140 |
141 | // Global functions.
142 |
143 | /* Function that calculates the MACD (Moving Average Convergance-Divergence).
144 | *
145 | * @param yData : array of y variables.
146 | * @param xData : array of x variables.
147 | * @param periods : The amount of "days" to average from.
148 | * @return : An array with 3 arrays. (0 : macd, 1 : signalline , 2 : histogram)
149 | **/
150 | function calcMACD (xData, yData, periods) {
151 |
152 | var chart = this,
153 | shortPeriod = 12,
154 | longPeriod = 26,
155 | signalPeriod = 9,
156 | shortEMA,
157 | longEMA,
158 | MACD = [],
159 | xMACD = [],
160 | yMACD = [],
161 | signalLine = [],
162 | histogram = [];
163 |
164 |
165 | // Calculating the short and long EMA used when calculating the MACD
166 | shortEMA = EMA(xData, yData, 12);
167 | longEMA = EMA(xData, yData, 26);
168 |
169 | // subtract each Y value from the EMA's and create the new dataset (MACD)
170 | for (var i = 0; i < shortEMA.length; i++) {
171 |
172 | if (longEMA[i][1] == null) {
173 |
174 | MACD.push( [xData[i] , null]);
175 |
176 | } else {
177 | MACD.push( [ xData[i] , (shortEMA[i][1] - longEMA[i][1]) ] );
178 | }
179 | }
180 |
181 | // Set the Y and X data of the MACD. This is used in calculating the signal line.
182 | for (var i = 0; i < MACD.length; i++) {
183 | xMACD.push(MACD[i][0]);
184 | yMACD.push(MACD[i][1]);
185 | }
186 |
187 | // Setting the signalline (Signal Line: X-day EMA of MACD line).
188 | signalLine = EMA(xMACD, yMACD, signalPeriod);
189 |
190 | // Setting the MACD Histogram. In comparison to the loop with pure MACD this loop uses MACD x value not xData.
191 | for (var i = 0; i < MACD.length; i++) {
192 |
193 | if (MACD[i][1] == null) {
194 |
195 | histogram.push( [ MACD[i][0], null ] );
196 |
197 | } else {
198 |
199 | histogram.push( [ MACD[i][0], (MACD[i][1] - signalLine[i][1]) ] );
200 |
201 | }
202 | }
203 |
204 | return [MACD, signalLine, histogram];
205 | }
206 |
207 | /**
208 | * Calculating a linear trendline.
209 | * The idea of a trendline is to reveal a linear relationship between
210 | * two variables, x and y, in the "y = mx + b" form.
211 | * @param yData : array of y variables.
212 | * @param xData : array of x variables.
213 | * @param periods : Only here for overloading purposes.
214 | * @return an array containing the linear trendline.
215 | **/
216 | function linear (xData, yData, periods) {
217 |
218 | var lineData = [],
219 | step1,
220 | step2 = 0,
221 | step3 = 0,
222 | step3a = 0,
223 | step3b = 0,
224 | step4 = 0,
225 | step5 = 0,
226 | step5a = 0,
227 | step6 = 0,
228 | step7 = 0,
229 | step8 = 0,
230 | step9 = 0;
231 |
232 |
233 | // Step 1: The number of data points.
234 | step1 = xData.length;
235 |
236 | // Step 2: "step1" times the summation of all x-values multiplied by their corresponding y-values.
237 | // Step 3: Sum of all x-values times the sum of all y-values. 3a and b are used for storing data.
238 | // Step 4: "step1" times the sum of all squared x-values.
239 | // Step 5: The squared sum of all x-values. 5a stores data.
240 | // Step 6: Equation to calculate the slope of the regression line.
241 | // Step 7: The sum of all y-values.
242 | // Step 8: "step6" times the sum of all x-values (step5).
243 | // Step 9: The equation for the y-intercept of the trendline.
244 | for ( var i = 0; i < step1; i++) {
245 | step2 = (step2 + (xData[i] * yData[i]));
246 | step3a = (step3a + xData[i]);
247 | step3b = (step3b + yData[i]);
248 | step4 = (step4 + Math.pow(xData[i], 2));
249 | step5a = (step5a + xData[i]);
250 | step7 = (step7 + yData[i]);
251 | }
252 | step2 = (step1 * step2);
253 | step3 = (step3a * step3b);
254 | step4 = (step1 * step4);
255 | step5 = (Math.pow(step5a, 2));
256 | step6 = ((step2 - step3) / (step4 - step5));
257 | step8 = (step6 * step5a);
258 | step9 = ((step7 - step8) / step1);
259 |
260 | // Step 10: Plotting the trendline. Only two points are calulated.
261 | // The starting point.
262 | // This point will have values equal to the first X and Y value in the original dataset.
263 | lineData.push([xData[0] , yData[0]]);
264 |
265 | // Calculating the ending point.
266 | // The point X is equal the X in the original dataset.
267 | // The point Y is calculated using the function of a straight line and our variables found.
268 | step10 = ( ( step6 * xData[step1 - 1] ) + step9 );
269 | lineData.push([ ( xData[step1 - 1] ), step10 ]);
270 |
271 | return lineData;
272 | }
273 |
274 |
275 | /* Function based on the idea of an exponential moving average.
276 | *
277 | * Formula: EMA = Price(t) * k + EMA(y) * (1 - k)
278 | * t = today, y = yesterday, N = number of days in EMA, k = 2/(2N+1)
279 | *
280 | * @param yData : array of y variables.
281 | * @param xData : array of x variables.
282 | * @param periods : The amount of "days" to average from.
283 | * @return an array containing the EMA.
284 | **/
285 | function EMA (xData, yData, periods) {
286 |
287 | var t,
288 | y = false,
289 | n = periods,
290 | k = (2 / (n + 1)),
291 | ema, // exponential moving average.
292 | emLine = [],
293 | periodArr = [],
294 | length = yData.length,
295 | pointStart = xData[0];
296 |
297 | // loop through data
298 | for (var i = 0; i < length; i++) {
299 |
300 |
301 | // Add the last point to the period arr, but only if its set.
302 | if (yData[i-1]) {
303 | periodArr.push(yData[i]);
304 | }
305 |
306 |
307 | // 0: runs if the periodArr has enough points.
308 | // 1: set currentvalue (today).
309 | // 2: set last value. either by past avg or yesterdays ema.
310 | // 3: calculate todays ema.
311 | if (n == periodArr.length) {
312 |
313 |
314 | t = yData[i];
315 |
316 | if (!y) {
317 | y = arrayAvg(periodArr);
318 | } else {
319 | ema = (t * k) + (y * (1 - k));
320 | y = ema;
321 | }
322 |
323 | emLine.push([xData[i] , y]);
324 |
325 | // remove first value in array.
326 | periodArr.splice(0,1);
327 |
328 | } else {
329 |
330 | emLine.push([xData[i] , null]);
331 | }
332 |
333 | }
334 |
335 | return emLine;
336 | }
337 |
338 | /* Function based on the idea of a simple moving average.
339 | * @param yData : array of y variables.
340 | * @param xData : array of x variables.
341 | * @param periods : The amount of "days" to average from.
342 | * @return an array containing the SMA.
343 | **/
344 | function SMA (xData, yData, periods) {
345 | var periodArr = [],
346 | smLine = [],
347 | length = yData.length,
348 | pointStart = xData[0];
349 |
350 | // Loop through the entire array.
351 | for (var i = 0; i < length; i++) {
352 |
353 | // add points to the array.
354 | periodArr.push(yData[i]);
355 |
356 | // 1: Check if array is "filled" else create null point in line.
357 | // 2: Calculate average.
358 | // 3: Remove first value.
359 | if (periods == periodArr.length) {
360 |
361 | smLine.push([ xData[i] , arrayAvg(periodArr)]);
362 | periodArr.splice(0,1);
363 |
364 | } else {
365 | smLine.push([ xData[i] , null]);
366 | }
367 | }
368 | return smLine;
369 | }
370 |
371 | /* Function that returns average of an array's values.
372 | *
373 | **/
374 | function arrayAvg (arr) {
375 | var sum = 0,
376 | arrLength = arr.length,
377 | i = arrLength;
378 |
379 | while (i--) {
380 | sum = sum + arr[i];
381 | }
382 |
383 | return (sum / arrLength);
384 | }
385 |
386 | }(Highcharts));
--------------------------------------------------------------------------------