diff --git a/.github/workflows/python-tests.yml b/.github/workflows/python-tests.yml
new file mode 100644
index 00000000..e6de3c53
--- /dev/null
+++ b/.github/workflows/python-tests.yml
@@ -0,0 +1,36 @@
+name: Python Tests
+
+on: [push, pull_request]
+
+jobs:
+ build:
+ runs-on: ubuntu-latest
+ strategy:
+ matrix:
+ python-version: ['3.7', '3.8', '3.9', '3.10', '3.11', '3.12']
+ fail-fast: false
+
+ steps:
+ - name: Check out code
+ uses: actions/checkout@v3
+
+ - name: Set up Python ${{ matrix.python-version }}
+ uses: actions/setup-python@v3
+ with:
+ python-version: ${{ matrix.python-version }}
+
+ - name: Install dependencies
+ run: |
+ python -m pip install --upgrade pip
+ pip install setuptools
+ pip install -r requirements.txt
+ python setup.py install
+ pip install coveralls
+
+ - name: Run tests
+ run: coverage run --source=nvd3 setup.py test
+
+ - name: Finish coveralls
+ run: coveralls
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
diff --git a/.gitignore b/.gitignore
index 7664d829..78b8d019 100644
--- a/.gitignore
+++ b/.gitignore
@@ -40,6 +40,9 @@ bower.json
bower_components
archive
+env
+myenv
+nvd3_env
htmlcov
test_*.html
diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index 2e4222da..00000000
--- a/.travis.yml
+++ /dev/null
@@ -1,21 +0,0 @@
-language: python
-
-python:
- - 2.7
- - 3.3
- - 3.4
- - 3.5
-
-install:
- - pip install -r requirements.txt
- - python setup.py install
- - pip install coveralls
-
-script:
- #- python tests.py
- - coverage run --source=nvd3 setup.py test
-notifications:
- email: true
-
-after_success:
- coveralls
diff --git a/CHANGELOG.rst b/CHANGELOG.rst
index 89477a5e..f0f16d1c 100644
--- a/CHANGELOG.rst
+++ b/CHANGELOG.rst
@@ -4,6 +4,13 @@ History
-------
+0.15.0 - current
+---------------------
+
+* new settings show_controls & xAxis_rotateLabel
+* add setting to add callback
+
+
0.14.0 - (2015-12-09)
---------------------
@@ -73,7 +80,7 @@ History
0.10.0 (2013-10-02)
-------------------
+-------------------
* Support new chart linePlusBarWithFocusChart
diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst
index ea2ed0b8..8afa5305 100644
--- a/CONTRIBUTING.rst
+++ b/CONTRIBUTING.rst
@@ -55,17 +55,17 @@ If you are proposing a feature:
Get Started!
------------
-Ready to contribute? Here's how to set up `python-msspeak` for local development.
+Ready to contribute? Here's how to set up `python-nvd3` for local development.
-1. Fork the `python-msspeak` repo on GitHub.
+1. Fork the `python-nvd3` repo on GitHub.
2. Clone your fork locally::
- $ git clone git@github.com:your_name_here/python-msspeak.git
+ $ git clone git@github.com:your_name_here/python-nvd3.git
3. Install your local copy into a virtualenv. Assuming you have virtualenvwrapper installed, this is how you set up your fork for local development::
- $ mkvirtualenv python-msspeak
- $ cd python-msspeak/
+ $ mkvirtualenv python-nvd3
+ $ cd python-nvd3/
$ python setup.py develop
4. Create a branch for local development::
@@ -76,7 +76,7 @@ Ready to contribute? Here's how to set up `python-msspeak` for local development
5. When you're done making changes, check that your changes pass flake8 and the tests, including testing other Python versions with tox::
- $ flake8 python-msspeak tests
+ $ flake8 python-nvd3 tests
$ python setup.py test
$ tox
diff --git a/MANIFEST.in b/MANIFEST.in
index f3c2a648..7697f68b 100644
--- a/MANIFEST.in
+++ b/MANIFEST.in
@@ -1,5 +1,5 @@
include CONTRIBUTING.rst
-include HISTORY.rst
+include CHANGELOG.rst
include LICENSE
include README.rst
diff --git a/README.rst b/README.rst
index 9e428c08..667d5ca5 100644
--- a/README.rst
+++ b/README.rst
@@ -10,9 +10,6 @@ Python Wrapper for NVD3 - It's time for beautiful charts
.. _Areski: https://github.com/areski/
.. _Oz: https://github.com/oz123/
-.. image:: https://api.travis-ci.org/areski/python-nvd3.png?branch=develop
- :target: https://travis-ci.org/areski/python-nvd3
-
.. image:: https://coveralls.io/repos/areski/python-nvd3/badge.png?branch=develop
:target: https://coveralls.io/r/areski/python-nvd3?branch=develop
@@ -32,10 +29,6 @@ Python Wrapper for NVD3 - It's time for beautiful charts
:target: https://pypi.python.org/pypi/python-nvd3/
:alt: License
-.. image:: https://requires.io/github/areski/python-nvd3/requirements.svg?branch=develop
- :target: https://requires.io/github/areski/python-nvd3/requirements/?branch=develop
- :alt: Requirements Status
-
NVD3 is an attempt to build re-usable charts and chart components
for d3.js without taking away the power that d3.js offers you.
@@ -46,13 +39,11 @@ These graphs can be part of your web application:
.. image:: https://raw.githubusercontent.com/areski/python-nvd3/develop/docs/showcase/multiple-charts.png
-
-
Want to try it yourself? Install python-nvd3, enter your python shell and try this quick demo::
>>> from nvd3 import pieChart
- >>> type = 'pieChart'
- >>> chart = pieChart(name=type, color_category='category20c', height=450, width=450)
+ >>> chart_name = 'pieChart'
+ >>> chart = pieChart(name=chart_name, color_category='category20c', height=450, width=450)
>>> xdata = ["Orange", "Banana", "Pear", "Kiwi", "Apple", "Strawberry", "Pineapple"]
>>> ydata = [3, 4, 0, 1, 5, 7, 3]
>>> extra_serie = {"tooltip": {"y_start": "", "y_end": " cal"}}
@@ -109,6 +100,7 @@ Check out the documentation on `Read the Docs`_ for some live Chart examples!
.. _Read the Docs: http://python-nvd3.readthedocs.org
+
Installation
------------
@@ -119,8 +111,8 @@ Install, upgrade and uninstall python-nvd3 with these commands::
$ pip uninstall python-nvd3
-Dependecies
------------
+Dependencies
+------------
D3 and NvD3 can be installed through bower (which itself can be installed through npm).
See http://bower.io/ and https://npmjs.org for further information.
@@ -132,8 +124,8 @@ Note : you might prefer to save your npm dependencies locally in a ``package.jso
Then in the directory where you will use python-nvd3, just execute the following commands::
- $ bower install d3#3.3.8
- $ bower install nvd3#1.1.12-beta
+ $ bower install d3#3.5.17
+ $ bower install nvd3#1.8.6
This will create a directory "bower_components" where d3 & nvd3 will be saved.
@@ -161,3 +153,9 @@ License
-------
Python-nvd3 is licensed under MIT, see `MIT-LICENSE.txt`.
+
+
+Maintainers
+-----------
+
+If you want to help maintain this project, please get in touch.
diff --git a/docs/source/_templates/page.html b/docs/source/_templates/page.html
index a58781ee..b6874d6c 100644
--- a/docs/source/_templates/page.html
+++ b/docs/source/_templates/page.html
@@ -5,9 +5,9 @@
{% endblock %}
{% block extrahead %}
-
-
-
+
+
+
{% endblock %}
{%- block body %}
diff --git a/docs/source/classes-doc/examples/NVD3Chart.html b/docs/source/classes-doc/examples/NVD3Chart.html
new file mode 100644
index 00000000..5a00bfb5
--- /dev/null
+++ b/docs/source/classes-doc/examples/NVD3Chart.html
@@ -0,0 +1,4 @@
+..
+ _Generated with generated_examples.sh script
+
+.. raw:: html
diff --git a/docs/source/classes-doc/examples/bulletChart.html b/docs/source/classes-doc/examples/bulletChart.html
new file mode 100644
index 00000000..5a00bfb5
--- /dev/null
+++ b/docs/source/classes-doc/examples/bulletChart.html
@@ -0,0 +1,4 @@
+..
+ _Generated with generated_examples.sh script
+
+.. raw:: html
diff --git a/docs/source/classes-doc/examples/cumulativeLineChart.html b/docs/source/classes-doc/examples/cumulativeLineChart.html
new file mode 100644
index 00000000..306af9e8
--- /dev/null
+++ b/docs/source/classes-doc/examples/cumulativeLineChart.html
@@ -0,0 +1,62 @@
+..
+ _Generated with generated_examples.sh script
+
+.. raw:: html
+
+
+
+
+
+
diff --git a/docs/source/classes-doc/examples/discreteBarChart.html b/docs/source/classes-doc/examples/discreteBarChart.html
new file mode 100644
index 00000000..2edf0818
--- /dev/null
+++ b/docs/source/classes-doc/examples/discreteBarChart.html
@@ -0,0 +1,58 @@
+..
+ _Generated with generated_examples.sh script
+
+.. raw:: html
+
+
+
+
+
+
diff --git a/docs/source/classes-doc/examples/lineChart.html b/docs/source/classes-doc/examples/lineChart.html
new file mode 100644
index 00000000..e86db5a6
--- /dev/null
+++ b/docs/source/classes-doc/examples/lineChart.html
@@ -0,0 +1,71 @@
+..
+ _Generated with generated_examples.sh script
+
+.. raw:: html
+
+
+
+
+
+
diff --git a/docs/source/classes-doc/examples/linePlusBarChart.html b/docs/source/classes-doc/examples/linePlusBarChart.html
new file mode 100644
index 00000000..9d03f2d4
--- /dev/null
+++ b/docs/source/classes-doc/examples/linePlusBarChart.html
@@ -0,0 +1,70 @@
+..
+ _Generated with generated_examples.sh script
+
+.. raw:: html
+
+
+
+
+
+
diff --git a/docs/source/classes-doc/examples/lineWithFocusChart.html b/docs/source/classes-doc/examples/lineWithFocusChart.html
new file mode 100644
index 00000000..77dc3263
--- /dev/null
+++ b/docs/source/classes-doc/examples/lineWithFocusChart.html
@@ -0,0 +1,67 @@
+..
+ _Generated with generated_examples.sh script
+
+.. raw:: html
+
+
+
+
+
+
diff --git a/docs/source/classes-doc/examples/multiBarChart.html b/docs/source/classes-doc/examples/multiBarChart.html
new file mode 100644
index 00000000..f3716400
--- /dev/null
+++ b/docs/source/classes-doc/examples/multiBarChart.html
@@ -0,0 +1,57 @@
+..
+ _Generated with generated_examples.sh script
+
+.. raw:: html
+
+
+
+
+
+
diff --git a/docs/source/classes-doc/examples/multiBarHorizontalChart.html b/docs/source/classes-doc/examples/multiBarHorizontalChart.html
new file mode 100644
index 00000000..9bca3f85
--- /dev/null
+++ b/docs/source/classes-doc/examples/multiBarHorizontalChart.html
@@ -0,0 +1,59 @@
+..
+ _Generated with generated_examples.sh script
+
+.. raw:: html
+
+
+
+
+
+
diff --git a/docs/source/classes-doc/examples/multiChart.html b/docs/source/classes-doc/examples/multiChart.html
new file mode 100644
index 00000000..5a00bfb5
--- /dev/null
+++ b/docs/source/classes-doc/examples/multiChart.html
@@ -0,0 +1,4 @@
+..
+ _Generated with generated_examples.sh script
+
+.. raw:: html
diff --git a/docs/source/classes-doc/examples/pieChart.html b/docs/source/classes-doc/examples/pieChart.html
new file mode 100644
index 00000000..5bd122b9
--- /dev/null
+++ b/docs/source/classes-doc/examples/pieChart.html
@@ -0,0 +1,62 @@
+..
+ _Generated with generated_examples.sh script
+
+.. raw:: html
+
+
+
+
+
+
diff --git a/docs/source/classes-doc/examples/scatterChart.html b/docs/source/classes-doc/examples/scatterChart.html
new file mode 100644
index 00000000..d8addb51
--- /dev/null
+++ b/docs/source/classes-doc/examples/scatterChart.html
@@ -0,0 +1,68 @@
+..
+ _Generated with generated_examples.sh script
+
+.. raw:: html
+
+
+
+
+
+
diff --git a/docs/source/classes-doc/examples/stackedAreaChart.html b/docs/source/classes-doc/examples/stackedAreaChart.html
new file mode 100644
index 00000000..7ed41e75
--- /dev/null
+++ b/docs/source/classes-doc/examples/stackedAreaChart.html
@@ -0,0 +1,57 @@
+..
+ _Generated with generated_examples.sh script
+
+.. raw:: html
+
+
+
+
+
+
diff --git a/docs/source/includes/introduction.txt b/docs/source/includes/introduction.txt
index 414241ec..a32fe22f 100644
--- a/docs/source/includes/introduction.txt
+++ b/docs/source/includes/introduction.txt
@@ -52,9 +52,9 @@ After installation use python-nvd3 as follows ::
# Open File to write the D3 Graph
output_file = open('test-nvd3.html', 'w')
- type = 'pieChart'
- chart = pieChart(name=type, color_category='category20c', height=450, width=450)
- chart.set_containerheader("\n\n" + type + " \n\n")
+ chart_name = 'pieChart'
+ chart = pieChart(name=chart_name, color_category='category20c', height=450, width=450)
+ chart.set_containerheader("\n\n" + chart_name + " \n\n")
xdata = ["Orange", "Banana", "Pear", "Kiwi", "Apple", "Strawberry", "Pineapple"]
ydata = [3, 4, 0, 1, 5, 7, 3]
diff --git a/docs/source/index.rst b/docs/source/index.rst
index 2915604c..30f22f45 100644
--- a/docs/source/index.rst
+++ b/docs/source/index.rst
@@ -25,8 +25,8 @@ These graphs can be part of your web application:
Want to try it yourself? Install python-nvd3, enter your python shell and try this quick demo::
>>> from nvd3 import pieChart
- >>> type = 'pieChart'
- >>> chart = pieChart(name=type, color_category='category20c', height=450, width=450)
+ >>> chart_name = 'pieChart'
+ >>> chart = pieChart(name=chart_name, color_category='category20c', height=450, width=450)
>>> xdata = ["Orange", "Banana", "Pear", "Kiwi", "Apple", "Strawberry", "Pineapple"]
>>> ydata = [3, 4, 0, 1, 5, 7, 3]
>>> extra_serie = {"tooltip": {"y_start": "", "y_end": " cal"}}
diff --git a/examples/cumulativeLineChart.py b/examples/cumulativeLineChart.py
index d0864fd3..63ae11ec 100644
--- a/examples/cumulativeLineChart.py
+++ b/examples/cumulativeLineChart.py
@@ -21,9 +21,9 @@
# Open File for test
output_file = open('test_cumulativeLineChart.html', 'w')
-type = "cumulativeLineChart"
-chart = cumulativeLineChart(name=type, height=350, x_is_date=True)
-chart.set_containerheader("\n\n" + type + " \n\n")
+chart_name = "cumulativeLineChart"
+chart = cumulativeLineChart(name=chart_name, height=350, x_is_date=True)
+chart.set_containerheader("\n\n" + chart_name + " \n\n")
xdata = list(range(nb_element))
xdata = [start_time + x * 1000000000 for x in xdata]
diff --git a/examples/demo_all.py b/examples/demo_all.py
index bf43f7b0..8886a4c1 100644
--- a/examples/demo_all.py
+++ b/examples/demo_all.py
@@ -35,19 +35,19 @@
-
-
-
-
+
+
+
+
"""
output_file.write(html_open)
-type = "discreteBarChart"
+chart_name = "discreteBarChart"
chart = discreteBarChart(name='my graphname', height=400, width=800, jquery_on_ready=True)
-chart.set_containerheader("\n\n" + type + " \n\n")
+chart.set_containerheader("\n\n" + chart_name + " \n\n")
xdata = ["A", "B", "C", "D", "E", "F", "G"]
ydata = [3, 12, -10, 5, 25, -7, 2]
@@ -58,10 +58,10 @@
output_file.write(chart.htmlcontent)
# ---------------------------------------
-type = "pie Chart"
-chart = pieChart(name=type, color_category='category20c', height=400,
+chart_name = "pie Chart"
+chart = pieChart(name=chart_name, color_category='category20c', height=400,
width=400, jquery_on_ready=True)
-chart.set_containerheader("\n\n" + type + " \n\n")
+chart.set_containerheader("\n\n" + chart_name + " \n\n")
color_list = ['orange', 'yellow', '#C5E946', '#95b43f', 'red', '#FF2259', '#F6A641']
extra_serie = {"tooltip": {"y_start": "", "y_end": " cal"}, "color_list": color_list}
@@ -74,7 +74,7 @@
# ---------------------------------------
name = "lineChart-different-x-axis"
-type = "lineChart"
+chart_name = "lineChart"
chart = lineChart(name=name, height=400, width=800, x_is_date=False,
jquery_on_ready=True)
@@ -98,11 +98,11 @@
output_file.write(chart.htmlcontent)
# ---------------------------------------
-type = "lineChart"
+chart_name = "lineChart"
chart = lineChart(height=400, width=800, x_is_date=True, x_axis_format="%d %b %Y %H",
jquery_on_ready=True)
-chart.set_containerheader("\n\n" + type + " \n\n")
+chart.set_containerheader("\n\n" + chart_name + " \n\n")
xdata = list(range(nb_element))
xdata = [start_time + x * 1000000000 for x in xdata]
ydata = [i + random.randint(1, 10) for i in range(nb_element)]
@@ -123,12 +123,12 @@
output_file.write(chart.htmlcontent)
# ---------------------------------------
-type = "lineChartWithInteractiveGuideline"
+chart_name = "lineChartWithInteractiveGuideline"
chart = lineChart(name="lineChart-With-Interactive-Guideline",
height=400, width=800, x_is_date=True, x_axis_format="%d %b %Y %H",
jquery_on_ready=True, use_interactive_guideline=True)
-chart.set_containerheader("\n\n" + type + " \n\n")
+chart.set_containerheader("\n\n" + chart_name + " \n\n")
xdata = list(range(nb_element))
xdata = [start_time + x * 1000000000 for x in xdata]
ydata = [i + random.randint(1, 10) for i in range(nb_element)]
@@ -149,11 +149,11 @@
output_file.write(chart.htmlcontent)
# ---------------------------------------
-type = "lineWithFocusChart"
+chart_name = "lineWithFocusChart"
chart = lineWithFocusChart(color_category='category20b', x_is_date=True,
height=400, width=800,
x_axis_format="%d %b %Y", jquery_on_ready=True)
-chart.set_containerheader("\n\n" + type + " \n\n")
+chart.set_containerheader("\n\n" + chart_name + " \n\n")
xdata = list(range(nb_element))
xdata = [start_time + x * 1000000000 for x in xdata]
@@ -177,10 +177,10 @@
# ---------------------------------------
-type = "stackedAreaChart"
+chart_name = "stackedAreaChart"
chart = stackedAreaChart(height=400, width=800, x_is_date=True,
x_axis_format="%d %b %Y %I", jquery_on_ready=True)
-chart.set_containerheader("\n\n" + type + " \n\n")
+chart.set_containerheader("\n\n" + chart_name + " \n\n")
xdata = list(range(nb_element))
xdata = [start_time + x * 1000000000 for x in xdata]
@@ -197,11 +197,11 @@
output_file.write(chart.htmlcontent)
# ---------------------------------------
-type = "linePlusBarChart"
+chart_name = "linePlusBarChart"
chart = linePlusBarChart(height=400, width=800, x_is_date=True,
x_axis_format="%d %b %Y", jquery_on_ready=True,
focus_enable=True)
-chart.set_containerheader("\n\n" + type + " \n\n")
+chart.set_containerheader("\n\n" + chart_name + " \n\n")
xdata = list(range(nb_element))
xdata = [start_time + x * 1000000000 for x in xdata]
@@ -219,11 +219,11 @@
output_file.write(chart.htmlcontent)
# ---------------------------------------
-type = "cumulativeLineChart"
+chart_name = "cumulativeLineChart"
chart = cumulativeLineChart(height=400, width=800,
x_is_date=True, x_axis_format="%d %b %Y",
jquery_on_ready=True)
-chart.set_containerheader("\n\n" + type + " \n\n")
+chart.set_containerheader("\n\n" + chart_name + " \n\n")
xdata = list(range(nb_element))
xdata = [start_time + x * 1000000000 for x in xdata]
@@ -240,9 +240,9 @@
output_file.write(chart.htmlcontent)
# ---------------------------------------
-type = "multiBarHorizontalChart"
+chart_name = "multiBarHorizontalChart"
chart = multiBarHorizontalChart(height=400, width=800, jquery_on_ready=True)
-chart.set_containerheader("\n\n" + type + " \n\n")
+chart.set_containerheader("\n\n" + chart_name + " \n\n")
nb_element = 10
xdata = list(range(nb_element))
@@ -258,9 +258,9 @@
output_file.write(chart.htmlcontent)
# ---------------------------------------
-type = "multiBarChart"
+chart_name = "multiBarChart"
chart = multiBarChart(height=400, width=800, jquery_on_ready=True)
-chart.set_containerheader("\n\n" + type + " \n\n")
+chart.set_containerheader("\n\n" + chart_name + " \n\n")
nb_element = 10
xdata = list(range(nb_element))
ydata = [random.randint(1, 10) for i in range(nb_element)]
@@ -275,9 +275,9 @@
output_file.write(chart.htmlcontent)
# ---------------------------------------
-type = "multiBarChartDate"
-chart = multiBarChart(name=type, height=400, width=800, x_is_date=True, jquery_on_ready=True)
-chart.set_containerheader("\n\n" + type + " \n\n")
+chart_name = "multiBarChartDate"
+chart = multiBarChart(name=chart_name, height=400, width=800, x_is_date=True, jquery_on_ready=True)
+chart.set_containerheader("\n\n" + chart_name + " \n\n")
nb_element = 100
start_time = int(time.mktime(datetime.datetime(2012, 6, 1).timetuple()) * 1000)
xdata = range(nb_element)
@@ -297,9 +297,9 @@
output_file.write(chart.htmlcontent)
# ---------------------------------------
-type = "scatterChart"
-chart = scatterChart(name=type, height=350, width=800, x_is_date=False)
-chart.set_containerheader("\n\n" + type + " \n\n")
+chart_name = "scatterChart"
+chart = scatterChart(name=chart_name, height=350, width=800, x_is_date=False)
+chart.set_containerheader("\n\n" + chart_name + " \n\n")
nb_element = 50
xdata = [i + random.randint(1, 10) for i in range(nb_element)]
ydata = [i * random.randint(1, 10) for i in range(nb_element)]
diff --git a/examples/discreteBarChart.py b/examples/discreteBarChart.py
index 533d61e0..776a47b0 100644
--- a/examples/discreteBarChart.py
+++ b/examples/discreteBarChart.py
@@ -15,9 +15,28 @@
# Open File for test
output_file = open('test_discreteBarChart.html', 'w')
-type = "discreteBarChart"
-chart = discreteBarChart(name='mygraphname', height=400, width=600)
-chart.set_containerheader("\n\n" + type + " \n\n")
+chart_name = "discreteBarChart"
+chart = discreteBarChart(name='mygraphname', height=400, width=600, show_values=True, extras="d3.selectAll('#mygraphname text').style('fill', 'red')")
+chart.set_containerheader("\n\n" + chart_name + " \n\n")
+xdata = ["A", "B", "C", "D", "E", "F", "G"]
+ydata = [3, 12, -10, 5, 25, -7, 2]
+
+extra_serie = {"tooltip": {"y_start": "", "y_end": " cal"}}
+chart.add_serie(y=ydata, x=xdata, extra=extra_serie)
+
+chart.buildhtml()
+output_file.write(chart.htmlcontent)
+# ---------------------------------------
+
+# close Html file
+output_file.close()
+
+output_file = open('test_discreteBarChart2.html', 'w')
+
+chart_name = "discreteBarChart"
+chart = discreteBarChart(name='mygraphname', height=400, width=600,
+ tooltips=False)
+chart.set_containerheader("\n\n" + chart_name + " \n\n")
xdata = ["A", "B", "C", "D", "E", "F", "G"]
ydata = [3, 12, -10, 5, 25, -7, 2]
diff --git a/examples/discreteBarChart_with_date.py b/examples/discreteBarChart_with_date.py
index f8798657..ebafafd4 100644
--- a/examples/discreteBarChart_with_date.py
+++ b/examples/discreteBarChart_with_date.py
@@ -18,7 +18,7 @@
# Open File for test
output_file = open('test_discreteBarChart_with_date.html', 'w')
-type = "discreteBarChart"
+chart_name = "discreteBarChart"
start_time = int(time.mktime(datetime.datetime(2012, 6, 1).timetuple()) * 1000)
nb_element = 10
@@ -27,8 +27,8 @@
xdata = [start_time + x * 1000000000 for x in xdata]
ydata = [i + random.randint(1, 10) for i in range(nb_element)]
-chart = discreteBarChart(name=type, height=400, width=600, x_is_date=True, x_axis_format="%d-%b")
-chart.set_containerheader("\n\n" + type + " \n\n")
+chart = discreteBarChart(name=chart_name, height=400, width=600, x_is_date=True, x_axis_format="%d-%b")
+chart.set_containerheader("\n\n" + chart_name + " \n\n")
extra_serie = {"tooltip": {"y_start": "", "y_end": " cal"}}
chart.add_serie(y=ydata, x=xdata, extra=extra_serie)
diff --git a/examples/ipythonDemo.ipynb b/examples/ipythonDemo.ipynb
index f2f5dd1c..46637d73 100644
--- a/examples/ipythonDemo.ipynb
+++ b/examples/ipythonDemo.ipynb
@@ -86,8 +86,8 @@
},
"outputs": [],
"source": [
- "type = 'stackedAreaChart'\n",
- "chart2 = nvd3.stackedAreaChart(name=type,height=450,width=500, \n",
+ "chart_name = 'stackedAreaChart'\n",
+ "chart2 = nvd3.stackedAreaChart(name=chart_name,height=450,width=500, \n",
" use_interactive_guideline=True)\n",
"nb_element = 50\n",
"xdata = range(nb_element)\n",
@@ -142,9 +142,9 @@
},
"outputs": [],
"source": [
- "type = 'pieChart'\n",
- "chart1 = nvd3.pieChart(name=type, color_category='category20c', height=450, width=450)\n",
- "chart1.set_containerheader(\"\\n\\n\" + type + \" \\n\\n\")\n",
+ "chart_name = 'pieChart'\n",
+ "chart1 = nvd3.pieChart(name=chart_name, color_category='category20c', height=450, width=450)\n",
+ "chart1.set_containerheader(\"\\n\\n\" + chart_name + \" \\n\\n\")\n",
"\n",
"#Create the keys\n",
"xdata = [\"Orange\", \"Banana\", \"Pear\", \"Kiwi\", \"Apple\", \"Strawberry\", \"Pineapple\"]\n",
diff --git a/examples/lineChart.py b/examples/lineChart.py
index 1dce1b9a..053b7e76 100644
--- a/examples/lineChart.py
+++ b/examples/lineChart.py
@@ -14,8 +14,8 @@
# Open File for test
output_file = open('test_lineChart.html', 'w')
# ---------------------------------------
-type = "lineChart"
-chart = lineChart(name=type, x_is_date=False, x_axis_format="AM_PM")
+chart_name = "lineChart"
+chart = lineChart(name=chart_name, x_is_date=False, x_axis_format="AM_PM")
xdata = list(range(0, 24))
ydata = [0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 4, 3, 3, 5, 7, 5, 3, 16, 6, 9, 15, 4, 12]
diff --git a/examples/lineChartXY.py b/examples/lineChartXY.py
index f74a1a9a..1e8ae2d8 100644
--- a/examples/lineChartXY.py
+++ b/examples/lineChartXY.py
@@ -14,8 +14,8 @@
output_file = open('test_lineChartXY.html', 'w')
-type = "lineChart"
-chart = lineChart(name=type, x_is_date=False,
+chart_name = "lineChart"
+chart = lineChart(name=chart_name, x_is_date=False,
x_axis_format=".1f", y_axis_format=".1f",
width=500, height=500,
show_legend=False)
diff --git a/examples/linePlusBarChart.py b/examples/linePlusBarChart.py
index 3dbeba71..f8981df7 100644
--- a/examples/linePlusBarChart.py
+++ b/examples/linePlusBarChart.py
@@ -20,11 +20,11 @@
output_file = open('test_linePlusBarChart.html', 'w')
-type = "linePlusBarChart"
-chart = linePlusBarChart(name=type, height=350, width=750,
+chart_name = "linePlusBarChart"
+chart = linePlusBarChart(name=chart_name, height=350, width=750,
x_is_date=True, x_axis_format="%d %b %Y",
focus_enable=True)
-chart.set_containerheader("\n\n" + type + " \n\n")
+chart.set_containerheader("\n\n" + chart_name + " \n\n")
xdata = list(range(nb_element))
xdata = [start_time + x * 1000000000 for x in xdata]
diff --git a/examples/lineWithFocusChart.py b/examples/lineWithFocusChart.py
index 7d765019..bd71dfee 100644
--- a/examples/lineWithFocusChart.py
+++ b/examples/lineWithFocusChart.py
@@ -21,11 +21,11 @@
# Open File for test
output_file = open('test_lineWithFocusChart.html', 'w')
# ---------------------------------------
-type = "lineWithFocusChart"
-chart = lineWithFocusChart(name=type, height=550, width=850,
+chart_name = "lineWithFocusChart"
+chart = lineWithFocusChart(name=chart_name, height=550, width=850,
color_category='category20b', x_is_date=True,
x_axis_format="%d %b %Y %H", focus_enable=True)
-chart.set_containerheader("\n\n" + type + " \n\n")
+chart.set_containerheader("\n\n" + chart_name + " \n\n")
xdata = list(range(nb_element))
xdata = [start_time + x * 1000000000 for x in xdata]
diff --git a/examples/multiBarChart.py b/examples/multiBarChart.py
index 709e662d..d07876e9 100644
--- a/examples/multiBarChart.py
+++ b/examples/multiBarChart.py
@@ -15,10 +15,21 @@
# Open File for test
output_file = open('test_multiBarChart.html', 'w')
-type = "multiBarChart"
-chart = multiBarChart(name=type, height=350)
-chart.set_containerheader("\n\n" + type + " \n\n")
+chart_name = "multiBarChart"
+chart = multiBarChart(name=chart_name, height=350)
+chart.set_containerheader("\n\n" + chart_name + " \n\n")
+chart.callback = '''
+ function(){
+ d3.selectAll(".nv-bar").on('click',
+ function(d){
+ console.log("barchart_callback_test: clicked on bar " + JSON.stringify(d));
+ console.log('/app/call?x='.concat(d['x']));
+ }
+ '''
nb_element = 10
+
+# On multiBarChart the xdata needs to be numeric,
+# if you want to use 'string' you should use discreteBarChart
xdata = list(range(nb_element))
ydata = [random.randint(1, 10) for i in range(nb_element)]
ydata2 = [x * 2 for x in ydata]
diff --git a/examples/multiBarChart_date.py b/examples/multiBarChart_date.py
index 39a12cd5..a4b65179 100644
--- a/examples/multiBarChart_date.py
+++ b/examples/multiBarChart_date.py
@@ -17,10 +17,10 @@
# Open File for test
output_file = open('test_multiBarChart_date.html', 'w')
-type = "multiBarChart"
+chart_name = "multiBarChart"
-chart = multiBarChart(name=type, height=350, x_is_date=True)
-chart.set_containerheader("\n\n" + type + " \n\n")
+chart = multiBarChart(name=chart_name, height=350, x_is_date=True)
+chart.set_containerheader("\n\n" + chart_name + " \n\n")
nb_element = 100
start_time = int(time.mktime(datetime.datetime(2013, 6, 1).timetuple()) * 1000)
diff --git a/examples/multiBarHorizontalChart.py b/examples/multiBarHorizontalChart.py
index c8b5c790..cd03fa9a 100644
--- a/examples/multiBarHorizontalChart.py
+++ b/examples/multiBarHorizontalChart.py
@@ -15,9 +15,9 @@
# Open File for test
output_file = open('test_multiBarHorizontalChart.html', 'w')
-type = "multiBarHorizontalChart"
-chart = multiBarHorizontalChart(name=type, height=350)
-chart.set_containerheader("\n\n" + type + " \n\n")
+chart_name = "multiBarHorizontalChart"
+chart = multiBarHorizontalChart(name=chart_name, height=350)
+chart.set_containerheader("\n\n" + chart_name + " \n\n")
nb_element = 10
xdata = list(range(nb_element))
diff --git a/examples/multiChart.py b/examples/multiChart.py
new file mode 100644
index 00000000..f1960e5c
--- /dev/null
+++ b/examples/multiChart.py
@@ -0,0 +1,36 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+
+"""
+Examples for Python-nvd3 is a Python wrapper for NVD3 graph library.
+NVD3 is an attempt to build re-usable charts and chart components
+for d3.js without taking away the power that d3.js gives you.
+
+Project location : https://github.com/areski/python-nvd3
+"""
+
+from nvd3 import multiChart
+
+# Open File for test
+output_file = open('test_multiChart.html', 'w')
+# ---------------------------------------
+chart_name = "multiChart"
+chart = multiChart(name=chart_name, x_is_date=False, x_axis_format="AM_PM")
+
+xdata = [1,2,3,4,5,6]
+ydata = [115.5,160.5,108,145.5,84,70.5]
+ydata2 = [48624,42944,43439,24194,38440,31651]
+
+kwargs1 = {'color': 'black'}
+kwargs2 = {'color': 'red'}
+extra_serie = {"tooltip": {"y_start": "There is ", "y_end": " calls"}}
+chart.add_serie(y=ydata, x=xdata, type='line', yaxis=1, name='visits', extra=extra_serie, **kwargs1)
+extra_serie = {"tooltip": {"y_start": "", "y_end": " min"}}
+chart.add_serie(y=ydata2, x=xdata, type='bar', yaxis=2,name='spend', extra=extra_serie, **kwargs2)
+
+chart.buildhtml()
+
+output_file.write(chart.htmlcontent)
+
+# close Html file
+output_file.close()
diff --git a/examples/pieChart.py b/examples/pieChart.py
index ed92f3e0..207695f4 100644
--- a/examples/pieChart.py
+++ b/examples/pieChart.py
@@ -15,9 +15,17 @@
# Open File for test
output_file = open('test_pieChart.html', 'w')
-type = "pieChart"
-chart = pieChart(name=type, color_category='category20c', height=400, width=400)
-chart.set_containerheader("\n\n" + type + " \n\n")
+chart_name = "pieChart"
+chart = pieChart(name=chart_name, color_category='category20c', height=400, width=400, extras="d3.selectAll('#piechart .nv-slice').style('opacity', 0.5);")
+chart.set_containerheader("\n\n" + chart_name + " \n\n")
+chart.callback = '''
+ function(){
+ d3.selectAll(".nv-pie .nv-pie .nv-slice").on('click',
+ function(d){
+ console.log("piechart_callback_test: clicked on slice " + JSON.stringify(d['data']));
+ console.log('/app/fruit?type='.concat(d['data']['label']));
+ }
+ '''
extra_serie = {"tooltip": {"y_start": "", "y_end": " cal"}}
xdata = ["Orange", "Banana", "Pear", "Kiwi", "Apple", "Strawberry", "Pineapple"]
diff --git a/examples/scatterChart.py b/examples/scatterChart.py
index 51338907..97c70af8 100644
--- a/examples/scatterChart.py
+++ b/examples/scatterChart.py
@@ -15,9 +15,9 @@
# Open File for test
output_file = open('test_scatterChart.html', 'w')
-type = "scatterChart"
-chart = scatterChart(name=type, height=350, width=800, x_is_date=False)
-chart.set_containerheader("\n\n" + type + " \n\n")
+chart_name = "scatterChart"
+chart = scatterChart(name=chart_name, height=350, width=800, x_is_date=False)
+chart.set_containerheader("\n\n" + chart_name + " \n\n")
nb_element = 50
xdata = [i + random.randint(1, 10) for i in range(nb_element)]
ydata = [i * random.randint(1, 10) for i in range(nb_element)]
diff --git a/generate_examples.sh b/generate_examples.sh
new file mode 100755
index 00000000..eda09418
--- /dev/null
+++ b/generate_examples.sh
@@ -0,0 +1,10 @@
+#!/bin/bash
+mkdir "docs/source/classes-doc/examples/"
+for file in nvd3/*Chart.py; do
+ html_filename="docs/source/classes-doc/examples/"`echo $file | sed "s/.*\///" | sed "s/\.py//"`".html"
+ echo $html_filename
+ echo -e "..\n _Generated with generated_examples.sh script\n\n.. raw:: html" > $html_filename
+
+ cat $file | grep "Python example" -A1000 | grep -E "Javascript generated|Note that in case you" -m 1 -B 1000 | tail -n+2 | head -n-1 | sed "s/^[ \t]*//g" | python | sed "s/^/ /" >> $html_filename
+done
+
diff --git a/nvd3/NVD3Chart.py b/nvd3/NVD3Chart.py
index 66699363..83c0666c 100644
--- a/nvd3/NVD3Chart.py
+++ b/nvd3/NVD3Chart.py
@@ -45,7 +45,7 @@ class NVD3Chart(object):
#: directory holding the assets (bower_components)
assets_directory = './bower_components/'
- # this attribute is overriden by children of this
+ # this attribute is overridden by children of this
# class
CHART_FILENAME = None
template_environment = Environment(lstrip_blocks=True, trim_blocks=True,
@@ -71,9 +71,16 @@ def __init__(self, **kwargs):
:keyword: **margin_top** - default - ``30``
:keyword: **height** - default - ``''``
:keyword: **width** - default - ``''``
+ :keyword: **show_values** - default - ``False``
:keyword: **stacked** - default - ``False``
:keyword: **focus_enable** - default - ``False``
:keyword: **resize** - define - ``False``
+ :keyword: **no_data_message** - default - ``None`` or nvd3 default
+ :keyword: **xAxis_rotateLabel** - default - ``0``
+ :keyword: **xAxis_staggerLabel** - default - ``False``
+ :keyword: **xAxis_showMaxMin** - default - ``True``
+ :keyword: **right_align_y_axis** - default - ``False``
+ :keyword: **show_controls** - default - ``True``
:keyword: **show_legend** - default - ``True``
:keyword: **show_labels** - default - ``True``
:keyword: **tag_script_js** - default - ``True``
@@ -87,6 +94,8 @@ def __init__(self, **kwargs):
Signal that x axis is a date axis
:keyword: **date_format** - default - ``%x``
see https://github.com/mbostock/d3/wiki/Time-Formatting
+ :keyword: **y_axis_scale_min** - default - ``''``.
+ :keyword: **y_axis_scale_max** - default - ``''``.
:keyword: **x_axis_format** - default - ``''``.
:keyword: **y_axis_format** - default - ``''``.
:keyword: **style** - default - ``''``
@@ -118,11 +127,19 @@ def __init__(self, **kwargs):
self.margin_top = kwargs.get('margin_top', 30)
self.height = kwargs.get('height', '')
self.width = kwargs.get('width', '')
+ self.show_values = kwargs.get('show_values', False)
self.stacked = kwargs.get('stacked', False)
self.focus_enable = kwargs.get('focus_enable', False)
self.resize = kwargs.get('resize', False)
+ self.no_data_message = kwargs.get('no_data_message', None)
+ self.xAxis_rotateLabel = kwargs.get('xAxis_rotateLabel', 0)
+ self.xAxis_staggerLabel = kwargs.get('xAxis_staggerLabel', False)
+ self.xAxis_showMaxMin = kwargs.get('xAxis_showMaxMin', True)
+ self.right_align_y_axis = kwargs.get('right_align_y_axis', False)
+ self.show_controls = kwargs.get('show_controls', True)
self.show_legend = kwargs.get('show_legend', True)
self.show_labels = kwargs.get('show_labels', True)
+ self.tooltip_separator = kwargs.get('tooltip_separator')
self.tag_script_js = kwargs.get('tag_script_js', True)
self.use_interactive_guideline = kwargs.get("use_interactive_guideline",
False)
@@ -131,12 +148,15 @@ def __init__(self, **kwargs):
self.style = kwargs.get('style', '')
self.date_format = kwargs.get('date_format', '%x')
self.x_axis_date = kwargs.get('x_axis_date', False)
+ self.y_axis_scale_min = kwargs.get('y_axis_scale_min', '')
+ self.y_axis_scale_max = kwargs.get('y_axis_scale_max', '')
#: x-axis contain date format or not
# possible duplicate of x_axis_date
self.date_flag = kwargs.get('date_flag', False)
self.x_axis_format = kwargs.get('x_axis_format', '')
# Load remote JS assets or use the local bower assets?
self.remote_js_assets = kwargs.get('remote_js_assets', True)
+ self.callback = kwargs.get('callback', None)
# None keywords attribute that should be modified by methods
# We should change all these to _attr
@@ -153,22 +173,21 @@ def __init__(self, **kwargs):
self.header_css = [
' ' % h for h in
(
- 'https://cdnjs.cloudflare.com/ajax/libs/nvd3/1.7.0/nv.d3.min.css' if self.remote_js_assets else self.assets_directory + 'nvd3/src/nv.d3.css',
+ 'https://cdnjs.cloudflare.com/ajax/libs/nvd3/1.8.6/nv.d3.min.css' if self.remote_js_assets else self.assets_directory + 'nvd3/src/nv.d3.css',
)
]
self.header_js = [
'' % h for h in
(
- 'https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js' if self.remote_js_assets else self.assets_directory + 'd3/d3.min.js',
- 'https://cdnjs.cloudflare.com/ajax/libs/nvd3/1.7.0/nv.d3.min.js' if self.remote_js_assets else self.assets_directory + 'nvd3/nv.d3.min.js'
+ 'https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.17/d3.min.js' if self.remote_js_assets else self.assets_directory + 'd3/d3.min.js',
+ 'https://cdnjs.cloudflare.com/ajax/libs/nvd3/1.8.6/nv.d3.min.js' if self.remote_js_assets else self.assets_directory + 'nvd3/nv.d3.min.js'
)
]
#: Javascript code as string
self.jschart = None
self.custom_tooltip_flag = False
- self.tooltip_condition_string = ''
self.charttooltip = ''
self.serie_no = 1
@@ -267,27 +286,11 @@ def add_serie(self, y, x, name=None, extra=None, **kwargs):
_start = ("'" + str(_start) + "' + ") if _start else ''
_end = (" + '" + str(_end) + "'") if _end else ''
- if self.model == 'linePlusBarChart':
- if self.tooltip_condition_string:
- self.tooltip_condition_string += stab(5)
- self.tooltip_condition_string += stab(0) + "if(key.indexOf('" + name + "') > -1 ){\n" +\
- stab(6) + "var y = " + _start + " String(graph.point.y) " + _end + ";\n" +\
- stab(5) + "}\n"
- elif self.model == 'cumulativeLineChart':
- self.tooltip_condition_string += stab(0) + "if(key == '" + name + "'){\n" +\
- stab(6) + "var y = " + _start + " String(e) " + _end + ";\n" +\
- stab(5) + "}\n"
- else:
- self.tooltip_condition_string += stab(5) + "if(key == '" + name + "'){\n" +\
- stab(6) + "var y = " + _start + " String(graph.point.y) " + _end + ";\n" +\
- stab(5) + "}\n"
-
if self.model == 'pieChart':
_start = extra['tooltip']['y_start']
_end = extra['tooltip']['y_end']
_start = ("'" + str(_start) + "' + ") if _start else ''
_end = (" + '" + str(_end) + "'") if _end else ''
- self.tooltip_condition_string += "var y = " + _start + " String(y) " + _end + ";\n"
# Increment series counter & append
self.serie_no += 1
@@ -349,7 +352,7 @@ def __str__(self):
def buildcontent(self):
"""Build HTML content only, no header or body tags. To be useful this
- will usually require the attribute `juqery_on_ready` to be set which
+ will usually require the attribute `jquery_on_ready` to be set which
will wrap the js in $(function(){};)
"""
self.buildcontainer()
@@ -408,11 +411,6 @@ def buildjschart(self):
"""generate javascript code for the chart"""
self.jschart = ''
- # add custom tooltip string in jschart
- # default condition (if build_custom_tooltip is not called explicitly with date_flag=True)
- if self.tooltip_condition_string == '':
- self.tooltip_condition_string = 'var y = String(graph.point.y);\n'
-
# Include data
self.series_js = json.dumps(self.series)
@@ -473,7 +471,7 @@ class TemplateMixin(object):
"""
def buildcontent(self):
"""Build HTML content only, no header or body tags. To be useful this
- will usually require the attribute `juqery_on_ready` to be set which
+ will usually require the attribute `jquery_on_ready` to be set which
will wrap the js in $(function(){};)
"""
self.buildcontainer()
diff --git a/nvd3/__init__.py b/nvd3/__init__.py
index 5b737b45..71823c58 100755
--- a/nvd3/__init__.py
+++ b/nvd3/__init__.py
@@ -9,11 +9,12 @@
Project location : https://github.com/areski/python-nvd3
"""
-__version__ = '0.15.0'
+__version__ = '0.16.0'
__all__ = ['lineChart', 'pieChart', 'lineWithFocusChart',
'stackedAreaChart', 'multiBarHorizontalChart',
'linePlusBarChart', 'cumulativeLineChart',
- 'scatterChart', 'discreteBarChart', 'multiBarChart']
+ 'scatterChart', 'discreteBarChart', 'multiBarChart',
+ 'bulletChart', 'multiChart']
from .lineChart import lineChart
@@ -26,4 +27,6 @@
from .scatterChart import scatterChart
from .discreteBarChart import discreteBarChart
from .multiBarChart import multiBarChart
+from .bulletChart import bulletChart
+from .multiChart import multiChart
from . import ipynb
diff --git a/nvd3/bulletChart.py b/nvd3/bulletChart.py
new file mode 100644
index 00000000..867c2e1a
--- /dev/null
+++ b/nvd3/bulletChart.py
@@ -0,0 +1,83 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+
+"""
+Python-nvd3 is a Python wrapper for NVD3 graph library.
+NVD3 is an attempt to build re-usable charts and chart components
+for d3.js without taking away the power that d3.js gives you.
+
+Project location : https://github.com/areski/python-nvd3
+"""
+
+from .NVD3Chart import NVD3Chart, TemplateMixin
+
+
+class bulletChart(TemplateMixin, NVD3Chart):
+ '''
+ A bullet chart is a variation of a bar graph
+ used to indicate the value of a single variable
+ in relation to a set of qualitative ranges. It is
+ inspired by a dashboard gauge or thermometer chart.
+
+ Python example:
+
+ from nvd3.bulletChart import bulletChart
+ chart = bulletChart.bulletChart(name=chart_name, height=100, width=500)
+ title = 'Revenue',
+ subtitle = 'US$, in thousands'
+ ranges = [150, 225, 300]
+ measures = [220, 270]
+ markers = [250]
+ chart.add_serie(
+ title=title,
+ subtitle=subtitle,
+ ranges=ranges,
+ measures=measures,
+ markers=markers)
+ chart.buildhtml()
+ print(chart.content)
+
+ JavaScript generated:
+
+ .. include:: ./examples/bulletChart.html
+
+ '''
+ CHART_FILENAME = './bulletchart.html'
+ template_chart_nvd3 = NVD3Chart.template_environment.get_template(
+ CHART_FILENAME)
+
+ def __init__(self, **kwargs):
+ super(bulletChart, self).__init__(**kwargs)
+ self.model = 'bulletChart'
+
+ height = kwargs.get('height', None)
+ width = kwargs.get('width', 200)
+
+ if height:
+ self.set_graph_height(height)
+ if width:
+ self.set_graph_width(width)
+
+ def add_serie(self, ranges, measures, title, subtitle, markers=None,
+ name=None, **kwargs):
+ if not name:
+ name = "Serie %d" % (self.serie_no)
+ if markers:
+ serie = [{
+ 'title': title,
+ 'subtitle': subtitle,
+ 'ranges': ranges,
+ 'measures': measures,
+ 'markers': markers
+ }]
+ else:
+ serie = [{
+ 'title': title,
+ 'subtitle': subtitle,
+ 'ranges': ranges,
+ 'measures': measures,
+ }]
+ data_keyvalue = {'values': serie, 'key': name}
+
+ self.serie_no += 1
+ self.series.append(data_keyvalue)
diff --git a/nvd3/cumulativeLineChart.py b/nvd3/cumulativeLineChart.py
index d98d0867..30c8f6d4 100644
--- a/nvd3/cumulativeLineChart.py
+++ b/nvd3/cumulativeLineChart.py
@@ -21,7 +21,7 @@ class cumulativeLineChart(TemplateMixin, NVD3Chart):
from nvd3 import cumulativeLineChart
chart = cumulativeLineChart(name='cumulativeLineChart', x_is_date=True)
- xdata = [1365026400000000, 1365026500000000, 1365026600000000]
+ xdata = [1365026400000, 1365026500000, 1365026600000]
ydata = [6, 5, 1]
y2data = [36, 55, 11]
@@ -31,49 +31,14 @@ class cumulativeLineChart(TemplateMixin, NVD3Chart):
extra_serie = {"tooltip": {"y_start": "", "y_end": " mins"}}
chart.add_serie(name="Serie 2", y=y2data, x=xdata, extra=extra_serie)
chart.buildhtml()
+ print(chart.content)
+
Javascript generated:
- .. raw:: html
-
-
-
+
+ .. include:: ./examples/cumulativeLineChart.html
+
"""
diff --git a/nvd3/discreteBarChart.py b/nvd3/discreteBarChart.py
index cf6c8a4a..1f5792da 100644
--- a/nvd3/discreteBarChart.py
+++ b/nvd3/discreteBarChart.py
@@ -17,6 +17,7 @@ class discreteBarChart(TemplateMixin, NVD3Chart):
A discrete bar chart or bar graph is a chart with rectangular bars with
lengths proportional to the values that they represent.
+
Python example::
from nvd3 import discreteBarChart
@@ -27,12 +28,25 @@ class discreteBarChart(TemplateMixin, NVD3Chart):
chart.add_serie(y=ydata, x=xdata)
chart.buildhtml()
+ print(chart.content)
Javascript generated:
+ .. include:: ./examples/discreteBarChart.html
+
+
+
+ You can also disable the tooltips by passing ``tooltips=False`` when
+ creating the bar chart.
+
+ Python example::
+
+ chart = discreteBarChart(name='discreteBarChart-notooltip', height=400, width=400,
+ tooltips=False)
+
.. raw:: html
-
+
-
"""
CHART_FILENAME = "./discretebarchart.html"
template_chart_nvd3 = NVD3Chart.template_environment.get_template(CHART_FILENAME)
@@ -89,3 +102,9 @@ def __init__(self, **kwargs):
self.set_graph_height(height)
if width:
self.set_graph_width(width)
+
+ tooltips = kwargs.get('tooltips', True)
+
+ if not tooltips:
+ self.chart_attr = {'tooltips': 'false'}
+
diff --git a/nvd3/ipynb.py b/nvd3/ipynb.py
index f421afc0..8edb4e83 100644
--- a/nvd3/ipynb.py
+++ b/nvd3/ipynb.py
@@ -39,9 +39,9 @@ def _setup_ipython_formatter(ip):
for chart_type in nvd3_all:
html_formatter.for_type_by_name('nvd3.' + chart_type, chart_type, _print_html)
- def initialize_javascript(d3_js_url='https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js',
- nvd3_js_url='https://cdnjs.cloudflare.com/ajax/libs/nvd3/1.7.0/nv.d3.min.js',
- nvd3_css_url='https://cdnjs.cloudflare.com/ajax/libs/nvd3/1.7.0/nv.d3.min.css',
+ def initialize_javascript(d3_js_url='https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.17/d3.min.js',
+ nvd3_js_url='https://cdnjs.cloudflare.com/ajax/libs/nvd3/1.8.6/nv.d3.min.js',
+ nvd3_css_url='https://cdnjs.cloudflare.com/ajax/libs/nvd3/1.8.6/nv.d3.min.css',
use_remote=False):
'''Initialize the ipython notebook to be able to display nvd3 results.
by instructing IPython to load the nvd3 JS and css files, and the d3 JS file.
@@ -52,9 +52,9 @@ def initialize_javascript(d3_js_url='https://cdnjs.cloudflare.com/ajax/libs/d3/3
use_remote: use remote hosts for d3.js, nvd3.js, and nv.d3.css (default False)
* Note: the following options are ignored if use_remote is False:
- nvd3_css_url: location of nvd3 css file (default https://cdnjs.cloudflare.com/ajax/libs/nvd3/1.7.0/nv.d3.min.css)
- nvd3_js_url: location of nvd3 javascript file (default https://cdnjs.cloudflare.com/ajax/libs/nvd3/1.7.0/nv.d3.min.css)
- d3_js_url: location of d3 javascript file (default https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js)
+ nvd3_css_url: location of nvd3 css file (default https://cdnjs.cloudflare.com/ajax/libs/nvd3/1.8.6/nv.d3.min.css)
+ nvd3_js_url: location of nvd3 javascript file (default https://cdnjs.cloudflare.com/ajax/libs/nvd3/1.8.6/nv.d3.min.css)
+ d3_js_url: location of d3 javascript file (default https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.17/d3.min.js)
'''
from IPython.display import display, Javascript, HTML
@@ -71,7 +71,7 @@ def initialize_javascript(d3_js_url='https://cdnjs.cloudflare.com/ajax/libs/d3/3
rel="stylesheet"/>''' % (nvd3_css_url)))
# The following two methods for loading the script file are redundant.
# This is intentional.
- # Ipython's loading of javscript in version 1.x is a bit squirrely, especially
+ # Ipython's loading of javascript in version 1.x is a bit squirrely, especially
# when creating demos to view in nbviewer.
# by trying twice, in two different ways (one using jquery and one using plain old
# HTML), we maximize our chances of successfully loading the script.
diff --git a/nvd3/lineChart.py b/nvd3/lineChart.py
index c237d069..d114007e 100644
--- a/nvd3/lineChart.py
+++ b/nvd3/lineChart.py
@@ -28,60 +28,15 @@ class lineChart(TemplateMixin, NVD3Chart):
ydata2 = [9, 8, 11, 8, 3, 7, 10, 8, 6, 6, 9, 6, 5, 4, 3, 10, 0, 6, 3, 1, 0, 0, 0, 1]
extra_serie = {"tooltip": {"y_start": "There are ", "y_end": " calls"}}
- chart.add_serie(y=ydata, x=xdata, name='sine', extra=extra_serie, **kwargs1)
+ chart.add_serie(y=ydata, x=xdata, name='sine', extra=extra_serie)
extra_serie = {"tooltip": {"y_start": "", "y_end": " min"}}
- chart.add_serie(y=ydata2, x=xdata, name='cose', extra=extra_serie, **kwargs2)
+ chart.add_serie(y=ydata2, x=xdata, name='cose', extra=extra_serie)
chart.buildhtml()
+ print(chart.content)
- Javascript renderd to:
-
- .. raw:: html
-
-
-
+ Javascript generated:
+
+ .. include:: ./examples/lineChart.html
See the source code of this page, to see the underlying javascript.
"""
diff --git a/nvd3/linePlusBarChart.py b/nvd3/linePlusBarChart.py
index 4eaa5fc6..2cfe533b 100644
--- a/nvd3/linePlusBarChart.py
+++ b/nvd3/linePlusBarChart.py
@@ -39,7 +39,8 @@ class linePlusBarChart(TemplateMixin, NVD3Chart):
extra_serie = {"tooltip": {"y_start": "There are ", "y_end": " min"}}
chart.add_serie(name="Serie 2", y=y2data, x=xdata, extra=extra_serie)
- chart.buildcontent()
+ chart.buildhtml()
+ print(chart.content)
Note that in case you have two data serie with extreme different numbers,
that you would like to format in different ways,
@@ -51,44 +52,7 @@ class linePlusBarChart(TemplateMixin, NVD3Chart):
Javascript generated:
- .. raw:: html
-
-
-
+ .. include:: ./examples/linePlusBarChart.html
"""
CHART_FILENAME = "./lineplusbarchart.html"
diff --git a/nvd3/lineWithFocusChart.py b/nvd3/lineWithFocusChart.py
index cd26cd47..b956d271 100644
--- a/nvd3/lineWithFocusChart.py
+++ b/nvd3/lineWithFocusChart.py
@@ -23,52 +23,19 @@ class lineWithFocusChart(TemplateMixin, NVD3Chart):
from nvd3 import lineWithFocusChart
chart = lineWithFocusChart(name='lineWithFocusChart', x_is_date=True, x_axis_format="%d %b %Y")
- xdata = [1365026400000000, 1365026500000000, 1365026600000000, 1365026700000000, 1365026800000000, 1365026900000000, 1365027000000000]
+ xdata = [1365026400000, 1365026500000, 1365026600000, 1365026700000, 1365026800000, 1365026900000, 1365027000000]
ydata = [-6, 5, -1, 2, 4, 8, 10]
extra_serie = {"tooltip": {"y_start": "", "y_end": " ext"},
"date_format": "%d %b %Y"}
chart.add_serie(name="Serie 1", y=ydata, x=xdata, extra=extra_serie)
chart.buildhtml()
+ print(chart.content)
Javascript generated:
- .. raw:: html
-
-
-
+ .. include:: ./examples/lineWithFocusChart.html
+
"""
diff --git a/nvd3/multiBarChart.py b/nvd3/multiBarChart.py
index cf335919..bab6adda 100644
--- a/nvd3/multiBarChart.py
+++ b/nvd3/multiBarChart.py
@@ -30,44 +30,11 @@ class multiBarChart(TemplateMixin, NVD3Chart):
chart.add_serie(name="Serie 1", y=ydata1, x=xdata)
chart.add_serie(name="Serie 2", y=ydata2, x=xdata)
chart.buildhtml()
+ print(chart.content)
Javascript generated:
- .. raw:: html
-
-
-
+ .. include:: ./examples/multiBarChart.html
"""
diff --git a/nvd3/multiBarHorizontalChart.py b/nvd3/multiBarHorizontalChart.py
index ac969c31..0028e86a 100644
--- a/nvd3/multiBarHorizontalChart.py
+++ b/nvd3/multiBarHorizontalChart.py
@@ -29,58 +29,12 @@ class multiBarHorizontalChart(TemplateMixin, NVD3Chart):
extra_serie = {"tooltip": {"y_start": "", "y_end": " calls"}}
chart.add_serie(name="Serie 2", y=y2data, x=xdata, extra=extra_serie)
- chart.buildcontent()
+ chart.buildhtml()
+ print(chart.content)
Javascript generated:
- .. raw:: html
-
-
-
+ .. include:: ./examples/multiBarHorizontalChart.html
"""
diff --git a/nvd3/multiChart.py b/nvd3/multiChart.py
new file mode 100644
index 00000000..2880fd82
--- /dev/null
+++ b/nvd3/multiChart.py
@@ -0,0 +1,83 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+
+"""
+Python-nvd3 is a Python wrapper for NVD3 graph library.
+NVD3 is an attempt to build re-usable charts and chart components
+for d3.js without taking away the power that d3.js gives you.
+
+Project location : https://github.com/areski/python-nvd3
+"""
+
+from .NVD3Chart import NVD3Chart, TemplateMixin
+
+
+class multiChart(TemplateMixin, NVD3Chart):
+
+ """
+ A multiChart is a type of chart which combines several plots of the same or different types.
+
+ Python example::
+
+ from nvd3 import multiChart
+ chart_name = "multiChart"
+ chart = multiChart(name=chart_name, x_is_date=False, x_axis_format="AM_PM")
+
+ xdata = [1,2,3,4,5,6]
+ ydata = [115.5,160.5,108,145.5,84,70.5]
+ ydata2 = [48624,42944,43439,24194,38440,31651]
+
+ kwargs1 = {'color': 'black'}
+ kwargs2 = {'color': 'red'}
+ extra_serie = {"tooltip": {"y_start": "There is ", "y_end": " calls"}}
+ chart.add_serie(y=ydata, x=xdata, type='line', yaxis=1, name='visits', extra=extra_serie, **kwargs1)
+ extra_serie = {"tooltip": {"y_start": "", "y_end": " min"}}
+ chart.add_serie(y=ydata2, x=xdata, type='bar', yaxis=2,name='spend', extra=extra_serie, **kwargs2)
+ chart.buildhtml()
+ print(chart.content)
+
+
+ Javascript rendered to:
+
+ .. include:: ./examples/multiChart.html
+
+ See the source code of this page, to see the underlying javascript.
+ """
+ CHART_FILENAME = "./multichart.html"
+ template_chart_nvd3 = NVD3Chart.template_environment.get_template(CHART_FILENAME)
+
+ def __init__(self, **kwargs):
+ super(multiChart, self).__init__(**kwargs)
+ self.model = 'multiChart'
+
+ height = kwargs.get('height', 450)
+ width = kwargs.get('width', None)
+
+ if kwargs.get('x_is_date', False):
+ self.set_date_flag(True)
+ self.create_x_axis('xAxis',
+ format=kwargs.get('x_axis_format', '%d %b %Y'),
+ date=True)
+ self.set_custom_tooltip_flag(True)
+ else:
+ if kwargs.get('x_axis_format') == 'AM_PM':
+ self.x_axis_format = format = 'AM_PM'
+ else:
+ format = kwargs.get('x_axis_format', 'r')
+ self.create_x_axis('xAxis', format=format,
+ custom_format=kwargs.get('x_custom_format',
+ False))
+ self.create_y_axis(
+ 'yAxis1',
+ format=kwargs.get('y1_axis_format', '.02f'),
+ custom_format=kwargs.get('y1_custom_format', False))
+
+ self.create_y_axis(
+ 'yAxis2',
+ format=kwargs.get('y2_axis_format', '.02f'),
+ custom_format=kwargs.get('y2_custom_format', False))
+
+ # must have a specified height, otherwise it superimposes both chars
+ self.set_graph_height(height)
+ if width:
+ self.set_graph_width(width)
diff --git a/nvd3/pieChart.py b/nvd3/pieChart.py
index 1db76bdb..6c513d83 100644
--- a/nvd3/pieChart.py
+++ b/nvd3/pieChart.py
@@ -32,51 +32,11 @@ class pieChart(TemplateMixin, NVD3Chart):
extra_serie = {"tooltip": {"y_start": "", "y_end": " cal"}}
chart.add_serie(y=ydata, x=xdata, extra=extra_serie)
chart.buildhtml()
+ print(chart.content)
Javascript generated:
- .. raw:: html
-
-
-
+ .. include:: ./examples/pieChart.html
"""
CHART_FILENAME = "./piechart.html"
@@ -99,3 +59,4 @@ def __init__(self, **kwargs):
self.set_graph_width(width)
self.donut = kwargs.get('donut', False)
self.donutRatio = kwargs.get('donutRatio', 0.35)
+ self.callback = kwargs.get('callback', None)
diff --git a/nvd3/scatterChart.py b/nvd3/scatterChart.py
index c3a87d29..b622649b 100644
--- a/nvd3/scatterChart.py
+++ b/nvd3/scatterChart.py
@@ -38,69 +38,11 @@ class scatterChart(TemplateMixin, NVD3Chart):
extra_serie = {"tooltip": {"y_start": "", "y_end": " min"}}
chart.add_serie(name="series 2", y=ydata2, x=xdata, extra=extra_serie, **kwargs2)
chart.buildhtml()
+ print(chart.content)
Javascript generated:
- .. raw:: html
-
-
-
+ .. include:: ./examples/scatterChart.html
"""
diff --git a/nvd3/stackedAreaChart.py b/nvd3/stackedAreaChart.py
index 8346cd2c..e246176f 100644
--- a/nvd3/stackedAreaChart.py
+++ b/nvd3/stackedAreaChart.py
@@ -30,47 +30,11 @@ class stackedAreaChart(TemplateMixin, NVD3Chart):
chart.add_serie(name="Serie 1", y=ydata, x=xdata, extra=extra_serie)
chart.add_serie(name="Serie 2", y=ydata2, x=xdata, extra=extra_serie)
chart.buildhtml()
+ print(chart.content)
Javascript generated:
- .. raw:: html
-
-
-
+ .. include:: ./examples/stackedAreaChart.html
"""
diff --git a/nvd3/templates/bulletchart.html b/nvd3/templates/bulletchart.html
new file mode 100644
index 00000000..985f4239
--- /dev/null
+++ b/nvd3/templates/bulletchart.html
@@ -0,0 +1,34 @@
+{# This template adds attributes unique
+ to bulletChart #}
+
+{% extends 'content.html' %}
+{% block body %}
+
+ {% block data %}
+ {{ super () }}
+ {% endblock data %}
+
+ function transformedData(){
+ return data_bulletchart[0]['values'][0]
+ }
+
+
+
+ nv.addGraph(function() {
+ var chart = nv.models.bulletChart();
+
+ d3.select('svg')
+ .datum(transformedData())
+ .transition().duration(1000)
+ .call(chart)
+ ;
+
+ return chart;
+ });
+
+ {% block extras %}
+ {{ super () }}
+ {% endblock extras %}
+{% endblock body %}
+
+
diff --git a/nvd3/templates/content.html b/nvd3/templates/content.html
index 787f39b5..70250c46 100644
--- a/nvd3/templates/content.html
+++ b/nvd3/templates/content.html
@@ -7,15 +7,17 @@
{% block body %}
{% block data %}
- data_{{ chart.name }}={{ chart.series_js }};
+ data_{{ chart.name }}={{ chart.series_js|striptags }};
{% endblock data %}
{% block init %}
nv.addGraph(function() {
- var chart = nv.models.{{ chart.model }}(){% if chart.use_interactive_guideline %}.useInteractiveGuideline(true){% endif %};
+ var chart = nv.models.{{ chart.model }}(){% if chart.use_interactive_guideline %}.useInteractiveGuideline(true){% endif %}{% if not chart.show_controls %}.showControls(false){% endif %}{% if chart.right_align_y_axis %}.rightAlignYAxis(true){% endif %};
chart.margin({top: {{ chart.margin_top }}, right: {{ chart.margin_right }}, bottom: {{ chart.margin_bottom }}, left: {{ chart.margin_left }}});
-
+ chart.xAxis.rotateLabels({{chart.xAxis_rotateLabel}})
+ chart.xAxis.staggerLabels({{chart.xAxis_staggerLabel|lower}})
+ chart.xAxis.showMaxMin({{chart.xAxis_showMaxMin|lower}})
var datum = data_{{ chart.name }};
{% if not chart.color_list and chart.color_category %}
@@ -23,10 +25,23 @@
{% endif %}
{% endblock init %}
+ {% block rendering_opts %}
{% if chart.stacked %}
chart.stacked(true);
{% endif %}
+ {% if chart.no_data_message %}
+ chart.noData('{{chart.no_data_message}}')
+ {% endif %}
+ {% if chart.show_controls == False %}
+ chart.showControls(false);
+ {% endif %}
+ {% if chart.show_values %}
+ chart.showValues(true);
+ {% endif %}
+
+ {% endblock rendering_opts %}
+
{% block focus %}
{% endblock focus %}
@@ -50,23 +65,23 @@
{% if chart.model == 'pieChart' %}
{% block pietooltip %}
{% endblock pietooltip %}
- {% else %}
- chart.tooltipContent(function(key, y, e, graph) {
- var x = String(graph.point.x);
- var y = String(graph.point.y);
- {{ chart.tooltip_condition_string }}
- tooltip_str = ''+key+' ' + y + ' at ' + x;
- return tooltip_str;
- });
{% endif %}
{% else %}
- chart.tooltipContent(function(key, y, e, graph) {
- var x = d3.time.format("{{ chart.charttooltip_dateformat }}")(new Date(parseInt(graph.point.x)));
- var y = String(graph.point.y);
- {{ chart.tooltip_condition_string }}
- tooltip_str = ''+key+' ' + y + ' on ' + x;
- return tooltip_str;
- });
+ {% if chart.model in ('discreteBarChart', ) %}
+ chart.tooltip.keyFormatter(function(d, i) {
+ return d3.time.format("{{ chart.charttooltip_dateformat }}")(new Date(parseInt(d)));
+ });
+ {% endif %}
+ {% if chart.model in ('linePlusBarChart', 'lineChart', 'multiBarChart', 'cumulativeLineChart', 'lineWithFocusChart') %}
+ chart.tooltip.headerFormatter(function(d, i) {
+ return d3.time.format("{{ chart.charttooltip_dateformat }}")(new Date(parseInt(d)));
+ });
+ {% endif %}
+ {% if chart.model in ('stackedAreaChart', ) %}
+ chart.interactiveLayer.tooltip.headerFormatter(function(d, i) {
+ return d3.time.format("{{ chart.charttooltip_dateformat }}")(new Date(parseInt(d)));
+ });
+ {% endif %}
{% endif %}
{% endif %}
{% endblock tooltip %}
@@ -80,7 +95,7 @@
{% block custoattr %}
{# add custom chart attributes #}
{% for attr, value in chart.chart_attr.items() %}
- {% if value is string and value.startswith(".") %}:
+ {% if value is string and value.startswith(".") %}
chart.{{ attr }}{{ value }};
{% else %}
chart.{{ attr }}({{ value }});
@@ -96,13 +111,19 @@
{% endblock custoattr %}
+ {% block y_axis_scale %}
+ {% if chart.y_axis_scale_min or chart.y_axis_scale_max %}
+ chart.forceY([{{ chart.y_axis_scale_min }},{{ chart.y_axis_scale_max }}]);
+ {% endif %}
+ {% endblock y_axis_scale %}
+
{% block inject %}
{# Inject data to D3 #}
d3.select('#{{ chart.name }} svg')
.datum(datum)
.transition().duration(500)
{% if chart.width %}
- .attr('width', {{ chart.width}})
+ .attr('width', '{{ chart.width}}')
{% endif %}
{% if chart.height %}
.attr('height', {{ chart.height}})
@@ -110,9 +131,16 @@
.call(chart);
{% endblock inject %}
- {# extra chart attributes #}
- {% if chart.extras %}
- {{ chart.extras }}
+ {% block extras %}
+ {# extra chart attributes #}
+ {% if chart.extras %}
+ {{ chart.extras }}
+ {% endif %}
+ {% endblock extras %}
+
+ {# callback for clicking on charts #}
+ {% if chart.callback %}
+ },{{ chart.callback }});
{% endif %}
{# closing nv.addGraph #}
diff --git a/nvd3/templates/discretebarchart.html b/nvd3/templates/discretebarchart.html
index 2e31ae48..adcc38d4 100644
--- a/nvd3/templates/discretebarchart.html
+++ b/nvd3/templates/discretebarchart.html
@@ -12,10 +12,18 @@
{{super()}}
{% endblock init %}
+ {% block rendering_opts %}
+ {{super()}}
+ {% endblock rendering_opts %}
+
{% block axes %}
{{super()}}
{% endblock axes %}
-
+
+ {% block tooltip %}
+ {{super()}}
+ {% endblock tooltip %}
+
{% block custoattr %}
{{super()}}
{% endblock custoattr %}
@@ -23,7 +31,11 @@
{% block inject %}
{{ super() }}
{% endblock inject %}
-
+
+ {% block extras %}
+ {{ super () }}
+ {% endblock extras %}
+
{% block close %}
{{ super() }}
{% endblock close %}
diff --git a/nvd3/templates/linebarwfocuschart.html b/nvd3/templates/linebarwfocuschart.html
index ad4866c8..7e4b9211 100644
--- a/nvd3/templates/linebarwfocuschart.html
+++ b/nvd3/templates/linebarwfocuschart.html
@@ -4,13 +4,16 @@
{% extends "content.html" %}
{% block body %}
{% block data %}
- data_{{ chart.name }}={{ chart.series_js }};
+ data_{{ chart.name }}={{ chart.series_js|striptags }};
{% endblock data %}
{% block init %}
{{super()}}
{% endblock init %}
+ {% block rendering_opts %}
+ {{super()}}
+ {% endblock rendering_opts %}
{% block axes %}
{{super()}}
{% endblock axes %}
@@ -49,9 +52,9 @@
{{super()}}
{% endblock inject %}
- {% if chart.extras %}
- {{ chart.extras }}
- {% endif %}
+ {% block extras %}
+ {{ super () }}
+ {% endblock extras %}
{% block close %}
});
diff --git a/nvd3/templates/linechart.html b/nvd3/templates/linechart.html
index cf15d330..d22aaa44 100644
--- a/nvd3/templates/linechart.html
+++ b/nvd3/templates/linechart.html
@@ -12,10 +12,18 @@
{{super()}}
{% endblock init %}
+ {% block rendering_opts %}
+ {{super()}}
+ {% endblock rendering_opts %}
+
{% block axes %}
{{super()}}
{% endblock axes %}
+ {% block tooltip %}
+ {{super()}}
+ {% endblock tooltip %}
+
{% if chart.x_axis_format == 'AM_PM' %}
function get_am_pm(d){
if (d > 12) {
@@ -39,6 +47,10 @@
{{ super() }}
{% endblock inject %}
+ {% block extras %}
+ {{ super () }}
+ {% endblock extras %}
+
{% block close %}
{{ super() }}
{% endblock close %}
diff --git a/nvd3/templates/lineplusbarchart.html b/nvd3/templates/lineplusbarchart.html
index 73aeceac..009a7050 100644
--- a/nvd3/templates/lineplusbarchart.html
+++ b/nvd3/templates/lineplusbarchart.html
@@ -24,6 +24,10 @@
{{super()}}
{% endblock axes %}
+ {% block tooltip %}
+ {{super()}}
+ {% endblock tooltip %}
+
{% block legend %}
{{super()}}
{% endblock legend %}
@@ -36,6 +40,10 @@
{{ super() }}
{% endblock inject %}
+ {% block extras %}
+ {{ super () }}
+ {% endblock extras %}
+
{% block close %}
{{ super() }}
{% endblock close %}
diff --git a/nvd3/templates/multichart.html b/nvd3/templates/multichart.html
new file mode 100644
index 00000000..8264b00e
--- /dev/null
+++ b/nvd3/templates/multichart.html
@@ -0,0 +1,55 @@
+{# This template adds attributes unique
+ to multiChart #}
+
+{% extends "content.html" %}
+{% block body %}
+
+ {% block data %}
+ {{super()}}
+ {% endblock data %}
+
+ {% block init %}
+ {{super()}}
+ {% endblock init %}
+
+ {% block rendering_opts %}
+ {{super()}}
+ {% endblock rendering_opts %}
+
+ {% block axes %}
+ {{super()}}
+ {% endblock axes %}
+
+ {% if chart.x_axis_format == 'AM_PM' %}
+ function get_am_pm(d){
+ if (d > 12) {
+ d = d - 12; return (String(d) + 'PM');
+ }
+ else {
+ return (String(d) + 'AM');
+ }
+ };
+ {% endif %}
+
+ {% block legend %}
+ {{super()}}
+ {% endblock legend %}
+
+ {% block custoattr %}
+ {{super()}}
+ {% endblock custoattr %}
+
+ {% block inject %}
+ {{ super() }}
+ {% endblock inject %}
+
+ {% block extras %}
+ {{ super () }}
+ {% endblock extras %}
+
+ {% block close %}
+ {{ super() }}
+ {% endblock close %}
+
+{% endblock body %}
+
diff --git a/nvd3/templates/piechart.html b/nvd3/templates/piechart.html
index a200e6d4..a707ac52 100644
--- a/nvd3/templates/piechart.html
+++ b/nvd3/templates/piechart.html
@@ -4,7 +4,7 @@
{% extends "content.html" %}
{% block body %}
- data_{{ chart.name }}={{ chart.series_js }};
+ data_{{ chart.name }}={{ chart.series_js|striptags }};
nv.addGraph(function() {
var chart = nv.models.{{ chart.model }}(){% if chart.use_interactive_guideline %}.useInteractiveGuideline(true){% endif %};
@@ -15,9 +15,9 @@
chart.color(d3.scale.{{ chart.color_category }}().range());
{% endif %}
- chart.tooltipContent(function(key, y, e, graph) {
- var x = String(key);
- {{ chart.tooltip_condition_string }}
+ chart.tooltip.contentGenerator(function(d, elem) {
+ var x = String(d.data.label);
+ var y = String(d.data.value);
tooltip_str = ''+x+' ' + y;
return tooltip_str;
});
@@ -69,10 +69,30 @@
chart.color(mycolor);
{% endif %}
+ {% block rendering_opts %}
+ {% if chart.no_data_message %}
+ chart.noData('{{chart.no_data_message}}')
+ {% endif %}
+ {% if chart.show_controls == False %}
+ chart.showControls(false);
+ {% endif %}
+ {% endblock rendering_opts %}
+
{% block inject %}
{{super()}}
{% endblock inject %}
+ {% block extras %}
+ {# extra chart attributes #}
+ {% if chart.extras %}
+ {{ chart.extras }}
+ {% endif %}
+ {% endblock extras %}
+
+ {% if chart.callback %}
+ },{{ chart.callback }});
+ {% endif %}
+
{% block close %}
{{ super() }}
{% endblock close %}
diff --git a/nvd3/templates/scatterchart.html b/nvd3/templates/scatterchart.html
index 8c2adaae..0a88a06c 100644
--- a/nvd3/templates/scatterchart.html
+++ b/nvd3/templates/scatterchart.html
@@ -12,6 +12,10 @@
{{super()}}
{% endblock init %}
+ {% block rendering_opts %}
+ {{super()}}
+ {% endblock rendering_opts %}
+
{% block axes %}
{{super()}}
{% endblock axes %}
@@ -45,6 +49,10 @@
{{ super() }}
{% endblock inject %}
+ {% block extras %}
+ {{ super () }}
+ {% endblock extras %}
+
{% block close %}
{{ super() }}
{% endblock close %}
diff --git a/setup.py b/setup.py
index 4b658697..27a2741e 100644
--- a/setup.py
+++ b/setup.py
@@ -22,7 +22,7 @@
setup(
name='python-nvd3',
- version='0.15.0',
+ version='0.16.0',
description="Python NVD3 - Chart Library for d3.js",
long_description=readme + '\n\n' + history,
keywords='plot, graph, nvd3, d3',
@@ -61,6 +61,13 @@
'Programming Language :: Python :: 3.3',
'Programming Language :: Python :: 3.4',
'Programming Language :: Python :: 3.5',
+ 'Programming Language :: Python :: 3.6',
+ 'Programming Language :: Python :: 3.7',
+ 'Programming Language :: Python :: 3.8',
+ 'Programming Language :: Python :: 3.9',
+ 'Programming Language :: Python :: 3.10',
+ 'Programming Language :: Python :: 3.11',
+ 'Programming Language :: Python :: 3.12',
'Topic :: Multimedia :: Graphics :: Presentation',
'Topic :: Software Development :: Libraries :: Python Modules',
],
diff --git a/tests.py b/tests.py
index 861268ab..2f3d80dc 100644
--- a/tests.py
+++ b/tests.py
@@ -11,6 +11,8 @@
from nvd3 import discreteBarChart
from nvd3 import pieChart
from nvd3 import multiBarChart
+from nvd3 import multiChart
+from nvd3 import bulletChart
from nvd3.NVD3Chart import stab
from nvd3.translator import Function, AnonymousFunction, Assignment
import random
@@ -30,8 +32,8 @@ def test_chartWithBadName(self):
def test_lineWithFocusChart(self):
"""Test Line With Focus Chart"""
- type = "lineWithFocusChart"
- chart = lineWithFocusChart(name=type, date=True, height=350)
+ chart_name = "lineWithFocusChart"
+ chart = lineWithFocusChart(name=chart_name, date=True, height=350)
nb_element = 100
xdata = list(range(nb_element))
xdata = [1365026400000 + x * 100000 for x in xdata]
@@ -43,8 +45,8 @@ def test_lineWithFocusChart(self):
def test_lineChart(self):
"""Test Line Chart"""
- type = "lineChart"
- chart = lineChart(name=type, date=True, height=350)
+ chart_name = "lineChart"
+ chart = lineChart(name=chart_name, date=True, height=350)
nb_element = 100
xdata = list(range(nb_element))
xdata = [1365026400000 + x * 100000 for x in xdata]
@@ -59,8 +61,8 @@ def test_lineChart(self):
def test_lineChart_tooltip(self):
"""Test Line Chart"""
- type = "lineChart"
- chart = lineChart(name=type, date=True, height=350)
+ chart_name = "lineChart"
+ chart = lineChart(name=chart_name, date=True, height=350)
nb_element = 100
xdata = list(range(nb_element))
xdata = [1365026400000 + x * 100000 for x in xdata]
@@ -77,10 +79,12 @@ def test_lineChart_tooltip(self):
chart.buildhtml()
+ assert(".tickFormat(d3.format(',.02f'));" in chart.htmlcontent)
+
def test_linePlusBarChart(self):
"""Test line Plus Bar Chart"""
- type = "linePlusBarChart"
- chart = linePlusBarChart(name=type, date=True, height=350)
+ chart_name = "linePlusBarChart"
+ chart = linePlusBarChart(name=chart_name, date=True, height=350)
start_time = int(time.mktime(datetime.datetime(2012, 6, 1).timetuple()) * 1000)
nb_element = 100
xdata = list(range(nb_element))
@@ -95,8 +99,8 @@ def test_linePlusBarChart(self):
def test_stackedAreaChart(self):
"""Test Stacked Area Chart"""
- type = "stackedAreaChart"
- chart = stackedAreaChart(name=type, height=400)
+ chart_name = "stackedAreaChart"
+ chart = stackedAreaChart(name=chart_name, height=400)
nb_element = 100
xdata = list(range(nb_element))
xdata = [100 + x for x in xdata]
@@ -108,8 +112,8 @@ def test_stackedAreaChart(self):
def test_MultiBarChart(self):
"""Test Multi Bar Chart"""
- type = "MultiBarChart"
- chart = multiBarChart(name=type, height=400)
+ chart_name = "MultiBarChart"
+ chart = multiBarChart(name=chart_name, height=400)
nb_element = 10
xdata = list(range(nb_element))
ydata = [random.randint(1, 10) for i in range(nb_element)]
@@ -117,10 +121,34 @@ def test_MultiBarChart(self):
chart.add_serie(y=ydata, x=xdata, extra=extra)
chart.buildhtml()
+ def test_multiChart(self):
+ """Test Multi (line plus bar) Chart"""
+ chart_name = "multiChart"
+ chart = multiChart(
+ name=chart_name, x_is_date=False, x_axis_format="AM_PM",
+ no_data_message='custom message shows when there is no data',
+ xAxis_staggerLabel=True
+ )
+
+ xdata = [1,2,3,4,5,6]
+ ydata = [115.5,160.5,108,145.5,84,70.5]
+ ydata2 = [48624,42944,43439,24194,38440,31651]
+ kwargs1 = {'color': 'brown'}
+ kwargs2 = {'color': '#bada55'}
+ extra_serie = {"tooltip": {"y_start": "There is ", "y_end": " calls"}}
+ chart.add_serie(y=ydata, x=xdata, type='line', yaxis=1, name='visits', extra=extra_serie, **kwargs1)
+ extra_serie = {"tooltip": {"y_start": "", "y_end": " at this point"}}
+ chart.add_serie(y=ydata2, x=xdata, type='bar', yaxis=2,name='spend', extra=extra_serie, **kwargs2)
+ chart.buildhtml()
+
+ assert("chart.noData('custom message shows when there is no data')" in chart.htmlcontent)
+ assert("function get_am_pm" in chart.htmlcontent)
+
+
def test_multiBarHorizontalChart(self):
"""Test multi Bar Horizontal Chart"""
- type = "multiBarHorizontalChart"
- chart = multiBarHorizontalChart(name=type, height=350)
+ chart_name = "multiBarHorizontalChart"
+ chart = multiBarHorizontalChart(name=chart_name, height=350)
nb_element = 10
xdata = list(range(nb_element))
ydata = [random.randint(-10, 10) for i in range(nb_element)]
@@ -131,8 +159,8 @@ def test_multiBarHorizontalChart(self):
def test_cumulativeLineChart(self):
"""Test Cumulative Line Chart"""
- type = "cumulativeLineChart"
- chart = cumulativeLineChart(name=type, height=400)
+ chart_name = "cumulativeLineChart"
+ chart = cumulativeLineChart(name=chart_name, height=400)
start_time = int(time.mktime(datetime.datetime(2012, 6, 1).timetuple()) * 1000)
nb_element = 100
xdata = list(range(nb_element))
@@ -145,8 +173,8 @@ def test_cumulativeLineChart(self):
def test_scatterChart(self):
"""Test Scatter Chart"""
- type = "scatterChart"
- chart = scatterChart(name=type, date=True, height=350)
+ chart_name = "scatterChart"
+ chart = scatterChart(name=chart_name, date=True, height=350)
nb_element = 100
xdata = [i + random.randint(1, 10) for i in range(nb_element)]
ydata = [i * random.randint(1, 10) for i in range(nb_element)]
@@ -163,8 +191,8 @@ def test_scatterChart(self):
def test_discreteBarChart(self):
"""Test discrete Bar Chart"""
- type = "discreteBarChart"
- chart = discreteBarChart(name=type, height=350)
+ chart_name = "discreteBarChart"
+ chart = discreteBarChart(name=chart_name, height=350)
xdata = ["A", "B", "C", "D", "E", "F", "G"]
ydata = [3, 12, -10, 5, 35, -7, 2]
@@ -172,12 +200,13 @@ def test_discreteBarChart(self):
chart.buildhtml()
# We don't modify the xAxis, so make sure that it's not invoked.
- assert("chart.xAxis" not in chart.htmlcontent)
+ assert("chart.xAxis" in chart.htmlcontent)
+ assert("var chart = nv.models.discreteBarChart();" in chart.htmlcontent)
def test_pieChart(self):
"""Test Pie Chart"""
- type = "pieChart"
- chart = pieChart(name=type, color_category='category20c', height=400, width=400)
+ chart_name = "pieChart"
+ chart = pieChart(name=chart_name, color_category='category20c', height=400, width=400)
xdata = ["Orange", "Banana", "Pear", "Kiwi", "Apple", "Strawberry", "Pineapple"]
color_list = ['orange', 'yellow', '#C5E946', '#95b43f', 'red', '#FF2259', '#F6A641']
extra_serie = {"tooltip": {"y_start": "", "y_end": " cal"}, "color_list": color_list}
@@ -185,15 +214,88 @@ def test_pieChart(self):
chart.add_serie(y=ydata, x=xdata, extra=extra_serie)
chart.buildhtml()
+ assert("tooltip_str =" in chart.htmlcontent)
+
def test_donutPieChart(self):
"""Test Donut Pie Chart"""
- type = "pieChart"
- chart = pieChart(name=type, height=400, width=400, donut=True, donutRatio=0.2)
+ chart_name = "pieChart"
+ chart = pieChart(name=chart_name, height=400, width=400, donut=True, donutRatio=0.2)
xdata = ["Orange", "Banana", "Pear", "Kiwi", "Apple", "Strawberry", "Pineapple"]
ydata = [3, 4, 0, 1, 5, 7, 3]
chart.add_serie(y=ydata, x=xdata)
chart.buildhtml()
+ def test_can_create_bulletChart(self):
+ chart_name = 'bulletChart'
+ chart = bulletChart(name=chart_name, height=100, width=500)
+ title = 'Revenue',
+ subtitle = 'US$, in thousands'
+ ranges = [150, 225, 300]
+ measures = [220, 270]
+ markers = [250]
+ chart.add_serie(
+ title=title,
+ subtitle=subtitle,
+ ranges=ranges,
+ measures=measures,
+ markers=markers)
+ chart.buildhtml()
+
+ def test_bulletChart_htmlcontent_correct(self):
+ chart_name = 'bulletChart'
+ chart = bulletChart(name=chart_name, height=100, width=500)
+ title = 'Revenue',
+ subtitle = 'USD, in mill'
+ ranges = [100, 250, 300]
+ measures = [220, 280]
+ markers = [260]
+ chart.add_serie(
+ title=title,
+ subtitle=subtitle,
+ ranges=ranges,
+ measures=measures,
+ markers=markers)
+ chart.buildhtml()
+ assert 'data_bulletchart' in chart.htmlcontent
+ assert '"title": ["Revenue"]' in chart.htmlcontent
+ assert '"ranges": [100, 250, 300]' in chart.htmlcontent
+ assert 'nv.models.bulletChart();' in chart.htmlcontent
+
+ def test_bulletChart_marker_optional(self):
+ chart_name = 'bulletChart'
+ chart = bulletChart(name=chart_name, height=100, width=500)
+ title = 'Revenue',
+ subtitle = 'USD, in mill'
+ ranges = [100, 250, 300]
+ measures = [220, 280]
+ chart.add_serie(
+ title=title,
+ subtitle=subtitle,
+ ranges=ranges,
+ measures=measures
+ )
+ chart.buildhtml()
+ assert 'data_bulletchart' in chart.htmlcontent
+ assert 'marker' not in chart.htmlcontent
+
+
+ def test_charts_with_extras(self):
+ # extras="d3.selectAll('#mygraphname text').style('opacity', 0.5)"
+ chart_name = 'bulletChart'
+ bullet_chart = bulletChart(name=chart_name, height=100, width=500, extras="d3.selectAll('#mygraphname text').style('opacity', 0.5)")
+ bullet_chart.buildhtml()
+ assert 'data_bulletchart' in bullet_chart.htmlcontent
+ assert "d3.selectAll('#mygraphname text').style('opacity', 0.5)" in bullet_chart.htmlcontent
+
+ chart_name = "pieChart"
+ pie_chart = pieChart(name=chart_name, height=400, width=400, donut=True, donutRatio=0.2, extras="alert('Example of extra not even related to d3!')")
+ pie_chart.buildhtml()
+ assert "alert('Example of extra not even related to d3!')" in pie_chart.htmlcontent
+
+ chart_name = "linePlusBarChart"
+ line_plus_bar_chart = linePlusBarChart(name=chart_name, date=True, height=350, extras="d3.selectAll('#mygraphname text').style('fill', 'red')")
+ line_plus_bar_chart.buildhtml()
+ assert "d3.selectAll('#mygraphname text').style('fill', 'red')" in line_plus_bar_chart.htmlcontent
class FuncTest(unittest.TestCase):
diff --git a/update_version.sh b/update_version.sh
index 8be0cab8..c342e7b9 100755
--- a/update_version.sh
+++ b/update_version.sh
@@ -1,6 +1,6 @@
#
# Usage:
-# ./update_version.sh 0.12.0
+# ./update_version.sh 0.16.0
#
git flow release start v$1
@@ -12,6 +12,6 @@ sed -i -e "s/version='.*'/version='$1'/g" setup.py
#git commit docs nvd3/__init__.py -m "Update to version v$1"
git commit -a -m "Update to version v$1"
git flow release finish v$1
-python setup.py sdist
+python setup.py sdist
twine upload dist/python-nvd3-$1.tar.gz
git push origin develop; git push origin master; git push --tags