Package: django-graphos
Graphos is a Django app to normalize data to create beautiful charts. It
provides a JS agnostic way to work with charts and allows seamless and
quick switching between different chart providers.Demo:http://agiliq.com/demo/graphos/.Docs:http://agiliq.com/docs/django-graphos/.Supported Backends:Python Nested listsDjango ORMCSV FilesMongoDBCharting API SupportedFlotGoogle Charts APIYUI ChartsMorris.jsHighchartsMatplotlibChart types supportedFlotLine chartBar ChartColumn chartPie chartPoint ChartGoogle ChartsLine chartBar chartColumn chartPie chartArea chartCandlestick chartTreemap chartGauge chartYUILine chartBar chartColumn chartPie chartArea chartSpline chartAreaspline chartMorris.jsLine chartBar chartDonut chartArea chartHighcharts(You will need to buy a license if you use highcharts for commerical
use)Line ChartBar ChartColumn ChartPie ChartArea ChartC3.jsLine chartColumn chart (You need to rotate the axis of bar chart to render
column chart)Bar chartDonut chartPie chartSpline chartMatplotlibLineChartBarChartWith Graphos, switching from google’s LineChart to yui LineChart can be
done within minutes. So would be the case in switching from yui
AreaChart to morris AreaChart.Running demo project locallyClone the projectgit clonehttps://github.com/agiliq/django-graphos.gitCd to demo directorycd django-graphos/demo_project/Create local settings.cp demo_project/settings/local.py-dist
demo_project/settings/local.pyInstall requirementspip install -r requirements.txtRun migratepython manage.py migrateRun serverpython manage.py runserverThe installed demo app shows the various suported chart types.In case you want to use mongo data while charting, you must have mongodb
properly setup andpymongoinstalled. Make sure mongo server is
running.mongod --dbpath ~/data/dbMongo setup is optional and is not needed to get running with demo
project.Overview of Plot generationGenerating a plot requires two things. A DataSource object and a Chart
object.In your view, you do something like this:from graphos.sources.simple import SimpleDataSource
from graphos.renderers.gchart import LineChart

data =  [
        ['Year', 'Sales', 'Expenses'],
        [2004, 1000, 400],
        [2005, 1170, 460],
        [2006, 660, 1120],
        [2007, 1030, 540]
    ]
# DataSource object
data_source = SimpleDataSource(data=data)
# Chart object
chart = LineChart(data_source)
context = {'chart': chart}
return render(request, 'yourtemplate.html', context)And then in the template:{{ chart.as_html }}In this example we are planning to use Google chart, as is evident from
the import statement in the view, we import gchart.LineChart. So we must
also include the google chart javascript in our template.<script type="text/javascript" src="https://www.google.com/jsapi"></script>
<script type="text/javascript">
    google.load("visualization", "1", {packages:["corechart"]});
</script>So the template would look like<script type="text/javascript" src="https://www.google.com/jsapi"></script>
<script type="text/javascript">
    google.load("visualization", "1", {packages:["corechart"]});
</script>

{{ chart.as_html }}If we want to use yui LineChart instead of google LineChart, our view
would have:from graphos.renderers.yui import LineChart
chart = LineChart(data_source)And our template would inclue yui javascript and it would look like:<script src="http://yui.yahooapis.com/3.10.0/build/yui/yui-min.js"></script>
{{ chart.as_html }}See, how easy it was to switch from gchart to yui. You did not have to
write or change a single line of javascript to switch from gchart to
yui. All that was taken care of by as_html() of the chart object.DataSourcesSimpleDataSourceThis should be used if you want to generate a chart from Python list.from graphos.sources.simple import SimpleDataSource
data = SimpleDataSource(data=data)Data could be:data = [
       ['Year', 'Sales', 'Expenses', 'Items Sold', 'Net Profit'],
       ['2004', 1000, 400, 100, 600],
       ['2005', 1170, 460, 120, 710],
       ['2006', 660, 1120, 50, -460],
       ['2007', 1030, 540, 100, 490],
       ]or it could bedata = [
       ['Year', 'Sales', 'Expenses'],
       ['2004', 1000, 400],
       ['2005', 1170, 460],
       ['2006', 660, 1120],
       ['2007', 1030, 540],
       ]or it could bedata = [
       ['Year', 'Sales', 'Expenses'],
       ['2004', 1000, 400],
       ['2005', 1170, 460],
       ]You got the idea.data has to be a list of lists. First row of data tells the headers.
First element of each list elementis the x axis.This data essentially tells that in year 2004, sales was 1000 units and
expense was 400 units. And in year 2005, sales was 1170 units and
expense was 460 units.ModelDataSourceThis should be used if you want to generate a chart from a Django
queryset.from graphos.sources.model import ModelDataSource
queryset = Account.objects.all()
data_source = ModelDataSource(queryset,
                              fields=['year', 'sales'])This assumes that there is a Django model called Account which has
fieldsyearandsales. And you plan to plot year on x axis and
sales on y axis.Or you could saydata_source = ModelDataSource(queryset,
                              fields=['year', 'sales', 'expenses'])This would plot the yearly sale and yearly expenseCSVDataSourceThis should be used if you want to generate a chart from a CSV file.from graphos.sources.csv_file import CSVDataSource
csv_file = open("hello.csv")
data_source = CSVDataSource(csv_file)MongoDataSourceTODOChartsWe have following chartsGchartgchart.LineChartgchart.BarChartgchart.ColumnChartgchart.PieChartgchart.AreaChartgchart.TreeMapChartgchart.CandlestickChartgchart.GaugeChartYuiyui.LineChartyui.BarChartyui.ColumnChartyui.PieChartyui.AreaChartyui.SplineChartyui.AreaSplineChartFlotflot.LineChartflot.BarChartflot.ColumnChartflot.PieChartflot.PointChartMorrismorris.LineChartmorris.BarChartmorris.AreaChartmorris.DonutChartHighchartshighcharts.LineCharthighcharts.BarCharthighcharts.ColumnCharthighcharts.PieCharthighcharts.AreaChartMost of the chart providers support LineChart, BarChart, ColumnChart and
PieChart, and it is very easy to switch from specific chart type of one
provider to other. eg: It is super quick to switch from gchart LineChart
to flot LineChart.More ExamplesUsing SimpleDataSource with gchart LineChartViewdata =  [
        ['Year', 'Sales', 'Expenses'],
        [2004, 1000, 400],
        [2005, 1170, 460],
        [2006, 660, 1120],
        [2007, 1030, 540]
    ]
from graphos.sources.simple import SimpleDataSource
from graphos.renderers.gchart import LineChart
chart = LineChart(SimpleDataSource(data=data))Template<script type="text/javascript" src="https://www.google.com/jsapi"></script>
<script type="text/javascript">
    google.load("visualization", "1", {packages:["corechart"]});
</script>

{{ chart.as_html }}Using SimpleDataSource with yui LineChartViewdata =  [
        ['Year', 'Sales', 'Expenses'],
        [2004, 1000, 400],
        [2005, 1170, 460],
        [2006, 660, 1120],
        [2007, 1030, 540]
    ]
from graphos.sources.simple import SimpleDataSource
from graphos.renderers.yui import LineChart
chart = LineChart(SimpleDataSource(data=data))Template<script src="http://yui.yahooapis.com/3.10.0/build/yui/yui-min.js"></script>
{{ chart.as_html }}Using SimpleDataSource with yui BarChartViewdata =  [
        ['Year', 'Sales', 'Expenses'],
        [2004, 1000, 400],
        [2005, 1170, 460],
        [2006, 660, 1120],
        [2007, 1030, 540]
    ]
from graphos.sources.simple import SimpleDataSource
from graphos.renderers.yui import BarChart
chart = BarChart(SimpleDataSource(data=data))Template<script src="http://yui.yahooapis.com/3.10.0/build/yui/yui-min.js"></script>
{{ chart.as_html }}Using SimpleDataSource with gchart BarChartViewdata =  [
        ['Year', 'Sales', 'Expenses'],
        [2004, 1000, 400],
        [2005, 1170, 460],
        [2006, 660, 1120],
        [2007, 1030, 540]
    ]
from graphos.sources.simple import SimpleDataSource
from graphos.renderers.gchart import BarChart
chart = BarChart(SimpleDataSource(data=data))Template<script type="text/javascript" src="https://www.google.com/jsapi"></script>
<script type="text/javascript">
    google.load("visualization", "1", {packages:["corechart"]});
</script>
{{ chart.as_html }}OptionsYour rendered chart is contained in a div.Setting id of chart containing divYou might want to do additional jquery or javascript operations with
your chart containing div. In such case you might want to set an id on
the div. You can do this while instantiating the chart element.chart = gchart.LineChart(html_id='gchart_div')Setting width and height of chart containing divYou can control the width and height of chart containing div while
instantiating the chart element.chart = gchart.LineChart(simple_data_source, height=100, width=100)Chart specific optionsDifferent chart providers give different options to customise the chart.Google chart api allows setting title for the rendered chart, seeGchart
documentation,
usingtitleattribute. You can accomplish this by adding a keyword
argument calledoptionswhile instantiating the chart element.chart = gchart.LineChart(simple_data_source, height=100, width=100, options={'title': 'Sales growth'})Google pie chart allows making the chart as 3 dimensional. You can
accomplish this by using keyword argumentoptions.pie_chart = gchart.PieChart(simple_data_source, options={'is3D': True})Morris.js allows options like lineWidth, smooth etc. You can find morehere. You can
accomplish this by usingoptions.chart = morris.LineChart(simple_data_source, options={'lineWidth': 50, 'smooth': False})Installationpip install django-graphosCompatibilityGraphos is compatible with Python 2.7 and Python 3.3+available on pypiHandling non serializable fieldsYou need to override get_data() of existing DataSource and convert
datetime field into something which could be serialized.Assuming you are using a Python list as data, then you need to do:from graphos.sources.simple import SimpleDataSource
class MySimpleDataSource(SimpleDataSource):
    def get_data(self):
        data = super(MySimpleDataSource, self).get_data()
        header = data[0]
        data_without_header = data[1:]
        for row in data_without_header:
            # Assuming first column contains datetime
            row[0] = row[0].year
        data_without_header.insert(0, header)
        return data_without_headerAnd data hasd1 = datetime(2015, 7, 8, 1, 1)
d2 = datetime(2016, 7, 8, 3, 1)

data1 = [
         ['Year', 'Sales', 'Expenses', 'Items Sold', 'Net Profit'],
         [d1, 1000, 400, 100, 600],
         [d2, 1170, 460, 120, 310],
 ]

chart = flot.LineChart(MySimpleDataSource(data=data1))If you are planning to use queryset with ModelDataSource, then you would
create following classfrom graphos.sources.model import ModelDataSource
class MyModelDataSource(ModelDataSource):
    def get_data(self):
        data = super(MyModelDataSource, self).get_data()
        header = data[0]
        data_without_header = data[1:]
        for row in data_without_header:
            # Assuming second column contains datetime
            row[1] = row[1].year
        data_without_header.insert(0, header)
        return data_without_headerAnd you would use this class like:queryset = Account.objects.all()
chart = flot.LineChart(MyModelDataSource(queryset=queryset, fields=['sales', 'datetime_field','expenses']))Creating new DataSourceA DataSource is a class which has these three methods.get_data
get_header
get_first_columnget_headeris used by aRendererto create the labels.get_first_columnis used to set the x axis labelsget_datais
used to get the data for display. It should always return a nested list.
Eg:[
    ['Year', 'Sales', 'Expenses'],
    [2004, 1000, 400],
    [2005, 1170, 460],
    [2006, 660, 1120],
    [2007, 1030, 540]
]If you create a class extendingSimpleDataSource, and implementget_data. You getget_headerandget_first_columnfor free.Creating new RendererA renderer is a class which takes aDataSourceand can convert it to
the html to display.The only required method on aRendererisas_html. This will
convert the data to a format which can display the chart.Generally you will convert the data to json and pass it to the template
which you return.LicenseBSD