* setup new 'statistiques' module * added 'graphos' package and created first test graph * put graphos in requirements, deleted local folder * added "load_csv" management command ! * added update of premiere_rencontre field in 'load_csv' management command * added missing urls.py file * added 'merge' action and view * added 'info_completed' ratio * linked sujets:merge views inside suivi:details * added link to maraudes:details in notes table headers, if any * Major reorganisation, moved 'suivi' and 'sujets' to 'notes', cleanup in 'maraudes', dropping 'website' mixins (mostly useless) * small cleanup * worked on Maraude and Sujet lists * corrected missing line in notes.__init__ * restored 'details' view for maraudes and sujets insie 'notes' module * worked on 'notes': added navigation between maraude's compte-rendu, right content in details, header to list tables * changed queryset for CompteRenduDetailsView to all notes of same date, minor layout changes * added right content to 'details-sujet', created 'statistiques' view and update templates * restored 'statistiques' ajax view in 'details-sujet', fixed 'merge_two' util function * added auto-creation of FicheStatistique (plus some tests), pagination for notes in 'details-sujet' * added error-prone cases in paginator * fixed non-working modals, added titles * added UpdateStatistiques capacity in CompteRenduCreate view * fixed missing AjaxTemplateMixin for CreateSujetView, worked on compte-rendu creation scripts * fixed MaraudeManager.all_of() for common Maraudeurs, added color hints in planning * re-instated statistiques module link and first test page * added FinalizeView to send a mail before finalizing compte-rendu * Added PieChart view for FicheStatistique fields * small style updates, added 'age' and 'genre' fields from sujets in statistiques.PieChartView * worked on statistiques, fixed small issues in 'notes' list views * small theme change * removed some dead code * fixed notes.tests, fixed statistiques.info_completed display, added filter in SujetLisView * added some tests * added customised admin templates * added authenticate in CustomAuthenticatationBackend, more verbose login thanks to messages * added django-nose for test coverage * Corrected raising exception on first migration On first migration, qs.exists() would previously be called and raising an Exception, sot he migrations would fail. * Better try block * cleaned up custom settings.py, added some overrides of django base_settings * corrected bad dictionnary key
71 lines
2.4 KiB
Python
71 lines
2.4 KiB
Python
from django.db.models import (Field, CharField, NullBooleanField,
|
|
Count,
|
|
)
|
|
from graphos.sources.simple import SimpleDataSource
|
|
from graphos.renderers import gchart
|
|
|
|
|
|
class PieWrapper(gchart.PieChart):
|
|
""" A wrapper around gchart.PieChart that generates a graph from :
|
|
|
|
- a queryset and a model field (NullBooleanField or field with choices)
|
|
- a data object and title
|
|
"""
|
|
|
|
height=400
|
|
width=800
|
|
labels = {
|
|
NullBooleanField: {True: "Oui", False: "Non", None:"Ne sait pas"},
|
|
}
|
|
|
|
def __init__( self, queryset=None, field=None,
|
|
data=None, title=None,
|
|
null_values=[],**kwargs):
|
|
if not data:
|
|
if not isinstance(field, Field):
|
|
raise TypeError(field, 'must be a child of django.models.db.fields.Field !')
|
|
if not queryset:
|
|
raise TypeError("You must give either a queryset and field or data")
|
|
|
|
if field.__class__ in PieWrapper.labels:
|
|
labels = PieWrapper.labels[field.__class__]
|
|
elif field.choices:
|
|
labels = dict(field.choices)
|
|
else:
|
|
raise ValueError("Could not guess labels for", field)
|
|
|
|
data = ([(field.name, 'count')] + # Headers
|
|
[(labels[item[field.name]],
|
|
item['nbr']) for item in queryset.values(
|
|
field.name
|
|
).annotate(
|
|
nbr=Count('pk')
|
|
).order_by()
|
|
if (not null_values
|
|
or item[field] not in null_values)
|
|
])
|
|
|
|
super().__init__(
|
|
SimpleDataSource(
|
|
data=data
|
|
),
|
|
options={
|
|
'title': getattr(field, 'verbose_name', title),
|
|
'is3D': True,
|
|
'pieSliceText': 'value',
|
|
'legend': {'position': 'labeled', 'maxLines': 3, 'textStyle': {'fontSize': 16,}},
|
|
},
|
|
width=kwargs.get('width', self.width), height=kwargs.get('height', self.height),
|
|
)
|
|
|
|
def get_js_template(self):
|
|
return "statistiques/gchart/pie_chart.html"
|
|
|
|
def get_html_template(self):
|
|
return "statistiques/gchart/html.html"
|
|
|
|
|
|
class ColumnWrapper(gchart.ColumnChart):
|
|
|
|
pass
|