0

I am using Django with the Google Charts API. I need to construct a JavaScript array to render a bar chart showing the # of objects created in a given day.

The expected array printed to the template should look like:

  ...

  function drawStuff() {
    var data = new google.visualization.arrayToDataTable([
      ['Date', '# of records'],
      ['2015-03-07', 3],    // Expected format:  ['Date', # of objects]
      ['2015-03-08', 8],
    ]);

  ...

views.py:

class LogsView(TemplateView):
    template_name = 'logs.html'


    def ValuesQuerySetToDict(self, vqs):
        return [ [item['date_created'], item['created_count'] ] for item in vqs]

    def render_chart_data(self, **kwargs):
        queryset = LogEntry.objects.filter(user=self.request.user).extra(
            {'date_created': 'date(created)'}
            ).values('date_created').annotate(created_count=Count('id'))
        modified_dict = self.ValuesQuerySetToDict(queryset)

        return json.dumps(modified_dict)


     def get_context_data(self, **kwargs):
        context = super(
            LogsView, self
        ).get_context_data(**kwargs)

        context['chart_data'] = self.render_chart_data()

The following is rendered to my django template (I bypassed sending it to JavaScript for now to see what was returned...

weird formatted data

When I believe I need to return a JavaScript array like the following:

["2015-02-18", 3],
["2015-02-19", 12],
["2015-02-21", 1],

And feed that to the drawStuff function which will render the barchart.

Alternate Method

I followed the this thread on StackOverflow and modified the render_chart_data to use django serializer like this but I am getting an error: " 'dict' object has no attribute '_meta'

Community
  • 1
  • 1
Joe Fusaro
  • 847
  • 2
  • 11
  • 23
  • Are you sure that `queryset`, `converted` or `json_data` contains your expected values? – Joseph Mar 08 '15 at 04:37
  • @JosephtheDreamer - I updated and now confirm that the queryset data is being returned via the Django view. – Joe Fusaro Mar 08 '15 at 16:20
  • How about `modified_dict`? Can you update your post with the values so that we can all check if `json.dumps` is actually provided correct values? – Joseph Mar 08 '15 at 16:30
  • @JosephtheDreamer - Sorry for the confusion, here is all of the relevant views.py code: https://gist.github.com/joefusaro/4b6b400e45941e80220e – Joe Fusaro Mar 08 '15 at 16:37
  • 1
    @JosephtheDreamer - thank you for trying to help on this, I was able to work through the issue and now have the bar chart data rendered to the javascript & HTML. Any feedback you have on my solution would be greatly appreciated. Thanks! – Joe Fusaro Mar 08 '15 at 23:40

2 Answers2

1

Thanks to all who offered assistance on this.

Two things needed to changed; the ValuesQuerySetToDict function needed to be rewritten as follows:

def ValuesQuerySetToDict(self, vqs):
    list_vals = [ ['Date', '# of records'] ]
    for item in vqs:
        list_vals.append(
            # convert datetime object to string otherwise JSON serialization error
            [ str(item['date_created']), item['created_count'] ]
            )

    return list_vals

And the render_chart_data function needed to be rewritten as follows:

def render_chart_data(self, **kwargs):
    queryset = LogEntry.objects.filter(user=self.request.user).extra(
        {'date_created': 'date(created)'}
        ).values('date_created').annotate(created_count=Count('id')).order_by('created-date')
    modified_list = list(self.ValuesQuerySetToDict(queryset))
    json_data = json.dumps(modified_list)

    return json_data

Finally, {{ chart_data }} needed to be passed to to the drawStuff function, like so:

  function drawStuff() {
    var data = new google.visualization.arrayToDataTable(
        {{ chart_data|safe }}
        );

I've posted views.py and logs.html here.

Joe Fusaro
  • 847
  • 2
  • 11
  • 23
-1
  1. In your queryset, render created_count as string and not as integer. Json's do not behave well with Integers.
  2. In your JS function drawStuff, chart_data should be parsed as json. See below:
 var json_string = '{{chart_data}}';
 var json = JSON.parse(json_string);
 var data = new google.visualization.arrayToDataTable(json)
Hashem Qolami
  • 97,268
  • 26
  • 150
  • 164