Permalink
Browse files

Disable interator sort for Python 3, fix charts w/ multiple sources

also use .items() instead of .iteritems() which doesn't exist anymore
  • Loading branch information...
atodorov committed Aug 3, 2016
1 parent 0cfa5a0 commit 9d9033ecd5a8592a12872293cdf6d710cebf894f
Showing with 39 additions and 4 deletions.
  1. +4 −0 README.rst
  2. +35 −4 chartit/charts.py
View
@@ -28,6 +28,10 @@ pivoted by specific column(s).
Changelog
=========
* master
* Workaround Python 3 vs. Python 2 list sort issue which breaks
charts with multiple data sources displayed on the same axis!
* 0.2.4 (August 2, 2016)
* Fix for `get_all_field_names()` and `get_field_by_name()` removal
in Django 1.10. Fixes
View
@@ -1,3 +1,4 @@
import sys
import copy
from collections import defaultdict, OrderedDict
from itertools import groupby
@@ -15,6 +16,7 @@ class BaseChart(object):
"""
def __init__(self, datasource, series_options, chart_options=None):
self.hcoptions = HCOptions({})
self.PY2 = sys.version_info.major == 2
def to_json(self):
"""Load Chart's data as JSON
@@ -142,7 +144,11 @@ def __init__(self, datasource, series_options, chart_options=None,
corresponding datasource or if the ``series_options`` cannot be
parsed.
"""
super(self.__class__, self).__init__(
datasource,
series_options,
chart_options
)
self.user_input = locals()
if not isinstance(datasource, DataPool):
raise APIInputError("%s must be an instance of DataPool."
@@ -187,7 +193,27 @@ def sort2_fn(td_tk):
so = sorted(self.series_options.items(), key=sort_fn)
x_axis_groups = groupby(so, sort_fn)
for (x_axis, itr1) in x_axis_groups:
itr1 = sorted(itr1, key=sort2_fn)
# Python 2 and 3 have different rules for ordering comparisons
# https://docs.python.org/3/whatsnew/3.0.html#ordering-comparisons
# http://stackoverflow.com/a/3484456
#
# Here we're trying to sort the iterator based on values in the
# _data attribute, which are lists of dicts, holding model data.
#
# When we try to render charts using sources from two different
# models these dicts have different keys and the comparison
# list_A < list_B fails with
# TypeError: unorderable types: dict() < dict()
#
# for example try:
# [{'a':1}, {'b':2}] < [{'a':1}, {'b':2, 'c':3}]
#
# This is used in demoproject.chartdemo.multi_table_same_x()!
#
# At the moment I don't have an idea how to solve this
# but disabling the sort seems to work, at least in the demo!
if self.PY2:
itr1 = sorted(itr1, key=sort2_fn)
for _vqs_num, (_, itr2) in enumerate(groupby(itr1, sort2_fn)):
x_axis_vqs_groups[x_axis][_vqs_num] = _x_vqs = {}
for tk, td in itr2:
@@ -405,13 +431,13 @@ def cht_typ_grp(y_term):
if x_mapf:
data = ((x_mapf(x_value), y_vals) for
(x_value, y_vals) in
y_values_multi.iteritems())
y_values_multi.items())
sort_key = ((lambda x_y: x_sortf(x_y[1]))
if x_sortf is not None
else None)
data = sorted(data, key=sort_key)
else:
data = y_values_multi.iteritems()
data = y_values_multi.items()
sort_key = ((lambda x_y: x_sortf(x_y[1])) if x_sortf
is not None else None)
data = sorted(data, key=sort_key)
@@ -532,6 +558,11 @@ def __init__(self, datasource, series_options, chart_options=None):
corresponding datasource or if the ``series_options`` cannot be
parsed.
"""
super(self.__class__, self).__init__(
datasource,
series_options,
chart_options
)
self.user_input = locals()
if not isinstance(datasource, PivotDataPool):
raise APIInputError("%s must be an instance of PivotDataPool." %

0 comments on commit 9d9033e

Please sign in to comment.