# Chartkick.py
Create beautiful JavaScript charts with one line of Python. No more fighting with charting libraries!
[See it in action](https://chartkick.com/python)
**Chartkick.py 1.0 was recently released** - see [how to upgrade](#upgrading)
[](https://github.com/ankane/chartkick.py/actions)
## Quick Start
Run:
```sh
pip install chartkick
```
Then follow the instructions for your web framework:
- [Django](#django)
- [Flask](#flask)
This sets up Chartkick with [Chart.js](https://www.chartjs.org/). For other charting libraries, see [these instructions](#additional-charting-libraries).
### Django
Add to `INSTALLED_APPS` in `settings.py`
```python
INSTALLED_APPS = [
'chartkick.django',
# ...
]
```
Load the JavaScript
```django
{% load static %}
<script src="{% static 'chartkick/Chart.bundle.js' %}"></script>
<script src="{% static 'chartkick/chartkick.js' %}"></script>
```
Create a chart in a view
```python
from chartkick.django import PieChart
def index(request):
chart = PieChart({'Blueberry': 44, 'Strawberry': 23})
return render(request, 'home/index.html', {'chart': chart})
```
And add it to the template
```django
{{ chart }}
```
### Flask
Register the blueprint
```python
from chartkick.flask import chartkick_blueprint
app.register_blueprint(chartkick_blueprint)
```
Load the JavaScript
```jinja
<script src="{{ url_for('chartkick.static', filename='Chart.bundle.js') }}"></script>
<script src="{{ url_for('chartkick.static', filename='chartkick.js') }}"></script>
```
Create a chart in a route
```python
from chartkick.flask import PieChart
def index():
chart = PieChart({'Blueberry': 44, 'Strawberry': 23})
return render_template('home/index.html', chart=chart)
```
And add it to the template
```django
{{ chart }}
```
## Charts
Line chart
```python
LineChart({'2023-01-01': 11, '2023-01-02': 6})
```
Pie chart
```python
PieChart({'Blueberry': 44, 'Strawberry': 23})
```
Column chart
```python
ColumnChart({'Sun': 32, 'Mon': 46, 'Tue': 28})
```
Bar chart
```python
BarChart({'Work': 32, 'Play': 1492})
```
Area chart
```python
AreaChart({'2021-01-01': 11, '2021-01-02': 6})
```
Scatter chart
```python
ScatterChart([[174.0, 80.0], [176.5, 82.3]], xtitle='Size', ytitle='Population')
```
Geo chart - *Google Charts*
```python
GeoChart({'United States': 44, 'Germany': 23, 'Brazil': 22})
```
Timeline - *Google Charts*
```python
Timeline([['Washington', '1789-04-29', '1797-03-03'], ['Adams', '1797-03-03', '1801-03-03']])
```
Multiple series
```python
data = [
{'name': 'Workout', 'data': {'2021-01-01': 3, '2021-01-02': 4}},
{'name': 'Call parents', 'data': {'2021-01-01': 5, '2021-01-02': 3}}
]
LineChart(data)
```
## Data
Data can be a dictionary, list, or URL.
#### Dictionary
```python
LineChart({'2023-01-01': 2, '2023-01-02': 3})
```
#### List
```python
LineChart([['2023-01-01', 2], ['2023-01-02', 3]])
```
#### URL
Make your pages load super fast and stop worrying about timeouts. Give each chart its own endpoint.
```python
LineChart('/charts/tasks')
```
## Options
Width and height
```python
LineChart(data, width='800px', height='500px')
```
Min and max values
```python
LineChart(data, min=1000, max=5000)
```
`min` defaults to 0 for charts with non-negative values. Use `None` to let the charting library decide.
Min and max for x-axis - *Chart.js*
```python
LineChart(data, xmin='2021-01-01', xmax='2022-01-01')
```
Colors
```python
LineChart(data, colors=['#b00', '#666'])
```
Stacked columns or bars
```python
ColumnChart(data, stacked=True)
```
Discrete axis
```python
LineChart(data, discrete=True)
```
Label (for single series)
```python
LineChart(data, label='Value')
```
Axis titles
```python
LineChart(data, xtitle='Time', ytitle='Population')
```
Straight lines between points instead of a curve
```python
LineChart(data, curve=False)
```
Hide points
```python
LineChart(data, points=False)
```
Show or hide legend
```python
LineChart(data, legend=False)
```
Specify legend position
```python
LineChart(data, legend='bottom')
```
Donut chart
```python
PieChart(data, donut=True)
```
Prefix, useful for currency - *Chart.js, Highcharts*
```python
LineChart(data, prefix='$')
```
Suffix, useful for percentages - *Chart.js, Highcharts*
```python
LineChart(data, suffix='%')
```
Set a thousands separator - *Chart.js, Highcharts*
```python
LineChart(data, thousands=',')
```
Set a decimal separator - *Chart.js, Highcharts*
```python
LineChart(data, decimal=',')
```
Set significant digits - *Chart.js, Highcharts*
```python
LineChart(data, precision=3)
```
Set rounding - *Chart.js, Highcharts*
```python
LineChart(data, round=2)
```
Show insignificant zeros, useful for currency - *Chart.js, Highcharts*
```python
LineChart(data, round=2, zeros=True)
```
Friendly byte sizes - *Chart.js*
```python
LineChart(data, bytes=True)
```
Specify the message when data is loading
```python
LineChart(data, loading='Loading...')
```
Specify the message when data is empty
```python
LineChart(data, empty='No data')
```
Refresh data from a remote source every `n` seconds
```python
LineChart(url, refresh=60)
```
You can pass options directly to the charting library with:
```python
LineChart(data, library={'backgroundColor': '#eee'})
```
See the documentation for [Chart.js](https://www.chartjs.org/docs/), [Google Charts](https://developers.google.com/chart/interactive/docs/gallery), and [Highcharts](https://api.highcharts.com/highcharts) for more info.
To customize datasets in Chart.js, use:
```python
LineChart(data, dataset={'borderWidth': 10})
```
You can pass this option to individual series as well.
### Multiple Series
You can pass a few options with a series:
- `name`
- `data`
- `color`
- `dataset` - *Chart.js only*
- `points` - *Chart.js only*
- `curve` - *Chart.js only*
### Code
If you want to use the charting library directly, get the code with:
```python
LineChart(data, code=True)
```
The code will be logged to the JavaScript console. JavaScript functions cannot be logged, so it may not be identical.
### Download Charts
*Chart.js only*
Give users the ability to download charts. It all happens in the browser - no server-side code needed.
```python
LineChart(data, download=True)
```
Safari will open the image in a new window instead of downloading.
Set the filename
```python
LineChart(data, download={'filename': 'boom'})
```
Set the background color
```python
LineChart(data, download={'background': '#ffffff'})
```
Set title
```python
LineChart(data, title='Awesome chart')
```
## Additional Charting Libraries
- [Google Charts](#google-charts)
- [Highcharts](#highcharts)
### Google Charts
Load the JavaScript
Django
```django
{% load static %}
<script src="https://www.gstatic.com/charts/loader.js"></script>
<script src="{% static 'chartkick/chartkick.js' %}"></script>
```
Flask
```jinja
<script src="https://www.gstatic.com/charts/loader.js"></script>
<script src="{{ url_for('chartkick.static', filename='chartkick.js') }}"></script>
```
### Highcharts
Download [highcharts.js](https://code.highcharts.com/highcharts.js) and load the JavaScript
Django
```django
{% load static %}
<script src="{% static 'highcharts.js' %}"></script>
<script src="{% static 'chartkick/chartkick.js' %}"></script>
```
Flask
```jinja
<script src="{{ url_for('static', filename='highcharts.js') }}"></script>
<script src="{{ url_for('chartkick.static', filename='chartkick.js') }}"></script>
```
### Multiple Libraries
If more than one charting library is loaded, choose between them with:
```python
LineChart(data, adapter='google') # or highcharts or chartjs
```
## Credits
A big thanks to [Mher Movsisyan](https://github.com/mher) for creating the [initial version](https://github.com/mher/chartkick.py).
## Upgrading
### 1.0
For Django, change `chartkick` to `chartkick.django` under `INSTALLED_APPS` in `settings.py` and remove `chartkick.js()` from `STATICFILES_DIRS`. Then update charts to use classes.
```python
from chartkick.django import LineChart
LineChart({'2023-01-01': 11, '2023-01-02': 6})
```
For Flask, switch to the [included blueprint](#flask) (available in 1.0.1). Then update charts to use classes.
```python
from chartkick.flask import LineChart
LineChart({'2023-01-01': 11, '2023-01-02': 6})
```
## History
View the [changelog](https://github.com/ankane/chartkick.py/blob/master/CHANGELOG.md)
## Contributing
Everyone is encouraged to help improve this project. Here are a few ways you can help:
- [Report bugs](https://github.com/ankane/chartkick.py/issues)
- Fix bugs and [submit pull requests](https://github.com/ankane/chartkick.py/pulls)
- Write, clarify, or fix documentation
- Suggest or add new features
To get started with development:
```sh
git clone https://github.com/ankane/chartkick.py.git
cd chartkick.py
pip install -r requirements.txt
pytest
```