# Path: graphos/renderers/base.py
# class BaseChart(object):
# 
#     def __init__(self, data_source, html_id=None,
#                  width=None, height=None,
#                  options=None, encoder=GraphosEncoder,
#                  *args, **kwargs):
#         """
#         : param data_source: :type graphos.sources.base.BaseDataSource subclass instance.
#         : param html_id: :type string: Id of the div where you would like chart to be rendered
#         : param width: :type integer: Width of the chart div
#         : param height: :type integer: Height of the chart div
#         """
#         self.data_source = data_source
#         self.html_id = html_id or get_random_string()
#         self.height = height or DEFAULT_HEIGHT
#         self.width = width or DEFAULT_WIDTH
#         # options could be an object, a list, a dictionary or a nested object or probably anything.
#         # Different renderers have different structure for options.
#         # Its responsibility of the renderer to read self.options in correct way and to use it in get_js_template.
#         self.options = options or {}
#         self.header = data_source.get_header()
#         self.encoder = encoder
#         self.context_data = kwargs
# 
#     def get_data(self):
#         return self.data_source.get_data()
# 
#     def get_data_json(self):
#         return json.dumps(self.get_data(), cls=JSONEncoderForHTML)
# 
#     def get_options(self):
#         options = self.options
#         if not 'title' in options:
#             options['title'] = "Chart"
#         return options
# 
#     def get_options_json(self):
#         return json.dumps(self.get_options(), cls=JSONEncoderForHTML)
# 
#     def get_template(self):
#         return 'graphos/as_html.html'
# 
#     def get_html_template(self):
#         raise GraphosException("Not Implemented")
# 
#     def get_js_template(self):
#         raise GraphosException("Not Implemented")
# 
#     def get_html_id(self):
#         return self.html_id
# 
#     def get_context_data(self):
#         return self.context_data
# 
#     def as_html(self):
#         context = {
#             'html': self.render_html(),
#             'js': self.render_js(),
#         }
#         return render_to_string(self.get_template(), context)
# 
#     def render_html(self):
#         context = {"chart": self}
#         return render_to_string(self.get_html_template(), context)
# 
#     def render_js(self):
#         context = {"chart": self}
#         return render_to_string(self.get_js_template(), context)
# 
#     def zip_list(self, *args):
#         rv = zip(*args)
#         if sys.version_info < (3,0):
#             return rv
#         return list(rv)
# 
# Path: graphos/utils.py
# class JSONEncoderForHTML(json.JSONEncoder):
#     """An encoder that produces JSON safe to embed in HTML.
#     To embed JSON content in, say, a script tag on a web page, the
#     characters &, < and > should be escaped. They cannot be escaped
#     with the usual entities (e.g. &amp;) because they are not expanded
#     within <script> tags.
#     """
#     def default(self, obj):
#         # Taken from https://github.com/tomchristie/django-rest-framework/blob/master/rest_framework/utils/encoders.py
#         # For Date Time string spec, see ECMA 262
#         # http://ecma-international.org/ecma-262/5.1/#sec-15.9.1.15
#         if isinstance(obj, Promise):
#             return force_text(obj)
#         elif isinstance(obj, datetime.datetime):
#             representation = obj.isoformat()
#             if representation.endswith('+00:00'):
#                 representation = representation[:-6] + 'Z'
#             return representation
#         elif isinstance(obj, datetime.date):
#             return obj.isoformat()
#         elif isinstance(obj, datetime.time):
#             if timezone and timezone.is_aware(obj):
#                 raise ValueError("JSON can't represent timezone-aware times.")
#             representation = obj.isoformat()
#             if obj.microsecond:
#                 representation = representation[:12]
#             return representation
#         elif isinstance(obj, decimal.Decimal):
#             # Serializers will coerce decimals to strings by default.
#             return float(obj)
#         elif isinstance(obj, uuid.UUID):
#             return six.text_type(obj)
#         elif isinstance(obj, QuerySet):
#             return tuple(obj)
#         elif isinstance(obj, six.binary_type):
#             # Best-effort for binary blobs. See #4187.
#             return obj.decode('utf-8')
#         elif hasattr(obj, 'tolist'):
#             # Numpy arrays and array scalars.
#             return obj.tolist()
#         elif hasattr(obj, '__getitem__'):
#             try:
#                 return dict(obj)
#             except:
#                 pass
#         elif hasattr(obj, '__iter__'):
#             return tuple(item for item in obj)
#         return super(JSONEncoderForHTML, self).default(obj)
# 
# 
#     def encode(self, o):
#         # Override JSONEncoder.encode because it has hacks for
#         # performance that make things more complicated.
#         chunks = self.iterencode(o, True)
#         if self.ensure_ascii:
#             return ''.join(chunks)
#         else:
#             return u''.join(chunks)
# 
#     def iterencode(self, o, _one_shot=False):
#         try:
#             chunks = super(JSONEncoderForHTML, self).iterencode(o, _one_shot)
#         except TypeError:
#             # for python 2.6 compatibility
#             chunks = super(JSONEncoderForHTML, self).iterencode(o)
#         for chunk in chunks:
#             chunk = chunk.replace('&', '&amp;')
#             chunk = chunk.replace('<', '&lt;')
#             chunk = chunk.replace('>', '&gt;')
#             yield chunk


from .base import BaseChart
from ..utils import JSONEncoderForHTML
import json


class BaseMorrisChart(BaseChart):

    def get_data(self):
        header = self.header
        data = super(BaseMorrisChart, self).get_data()
        data_only = data[1:]
        rows = []
        for row in data_only:
            rows.append(dict(zip(header, row)))
        return rows

    def get_category_key(self):
        return self.header[0]

    def get_y_keys(self):
        try:

# Path: graphos/renderers/base.py
# class BaseChart(object):
# 
#     def __init__(self, data_source, html_id=None,
#                  width=None, height=None,
#                  options=None, encoder=GraphosEncoder,
#                  *args, **kwargs):
#         """
#         : param data_source: :type graphos.sources.base.BaseDataSource subclass instance.
#         : param html_id: :type string: Id of the div where you would like chart to be rendered
#         : param width: :type integer: Width of the chart div
#         : param height: :type integer: Height of the chart div
#         """
#         self.data_source = data_source
#         self.html_id = html_id or get_random_string()
#         self.height = height or DEFAULT_HEIGHT
#         self.width = width or DEFAULT_WIDTH
#         # options could be an object, a list, a dictionary or a nested object or probably anything.
#         # Different renderers have different structure for options.
#         # Its responsibility of the renderer to read self.options in correct way and to use it in get_js_template.
#         self.options = options or {}
#         self.header = data_source.get_header()
#         self.encoder = encoder
#         self.context_data = kwargs
# 
#     def get_data(self):
#         return self.data_source.get_data()
# 
#     def get_data_json(self):
#         return json.dumps(self.get_data(), cls=JSONEncoderForHTML)
# 
#     def get_options(self):
#         options = self.options
#         if not 'title' in options:
#             options['title'] = "Chart"
#         return options
# 
#     def get_options_json(self):
#         return json.dumps(self.get_options(), cls=JSONEncoderForHTML)
# 
#     def get_template(self):
#         return 'graphos/as_html.html'
# 
#     def get_html_template(self):
#         raise GraphosException("Not Implemented")
# 
#     def get_js_template(self):
#         raise GraphosException("Not Implemented")
# 
#     def get_html_id(self):
#         return self.html_id
# 
#     def get_context_data(self):
#         return self.context_data
# 
#     def as_html(self):
#         context = {
#             'html': self.render_html(),
#             'js': self.render_js(),
#         }
#         return render_to_string(self.get_template(), context)
# 
#     def render_html(self):
#         context = {"chart": self}
#         return render_to_string(self.get_html_template(), context)
# 
#     def render_js(self):
#         context = {"chart": self}
#         return render_to_string(self.get_js_template(), context)
# 
#     def zip_list(self, *args):
#         rv = zip(*args)
#         if sys.version_info < (3,0):
#             return rv
#         return list(rv)
# 
# Path: graphos/utils.py
# class JSONEncoderForHTML(json.JSONEncoder):
#     """An encoder that produces JSON safe to embed in HTML.
#     To embed JSON content in, say, a script tag on a web page, the
#     characters &, < and > should be escaped. They cannot be escaped
#     with the usual entities (e.g. &amp;) because they are not expanded
#     within <script> tags.
#     """
#     def default(self, obj):
#         # Taken from https://github.com/tomchristie/django-rest-framework/blob/master/rest_framework/utils/encoders.py
#         # For Date Time string spec, see ECMA 262
#         # http://ecma-international.org/ecma-262/5.1/#sec-15.9.1.15
#         if isinstance(obj, Promise):
#             return force_text(obj)
#         elif isinstance(obj, datetime.datetime):
#             representation = obj.isoformat()
#             if representation.endswith('+00:00'):
#                 representation = representation[:-6] + 'Z'
#             return representation
#         elif isinstance(obj, datetime.date):
#             return obj.isoformat()
#         elif isinstance(obj, datetime.time):
#             if timezone and timezone.is_aware(obj):
#                 raise ValueError("JSON can't represent timezone-aware times.")
#             representation = obj.isoformat()
#             if obj.microsecond:
#                 representation = representation[:12]
#             return representation
#         elif isinstance(obj, decimal.Decimal):
#             # Serializers will coerce decimals to strings by default.
#             return float(obj)
#         elif isinstance(obj, uuid.UUID):
#             return six.text_type(obj)
#         elif isinstance(obj, QuerySet):
#             return tuple(obj)
#         elif isinstance(obj, six.binary_type):
#             # Best-effort for binary blobs. See #4187.
#             return obj.decode('utf-8')
#         elif hasattr(obj, 'tolist'):
#             # Numpy arrays and array scalars.
#             return obj.tolist()
#         elif hasattr(obj, '__getitem__'):
#             try:
#                 return dict(obj)
#             except:
#                 pass
#         elif hasattr(obj, '__iter__'):
#             return tuple(item for item in obj)
#         return super(JSONEncoderForHTML, self).default(obj)
# 
# 
#     def encode(self, o):
#         # Override JSONEncoder.encode because it has hacks for
#         # performance that make things more complicated.
#         chunks = self.iterencode(o, True)
#         if self.ensure_ascii:
#             return ''.join(chunks)
#         else:
#             return u''.join(chunks)
# 
#     def iterencode(self, o, _one_shot=False):
#         try:
#             chunks = super(JSONEncoderForHTML, self).iterencode(o, _one_shot)
#         except TypeError:
#             # for python 2.6 compatibility
#             chunks = super(JSONEncoderForHTML, self).iterencode(o)
#         for chunk in chunks:
#             chunk = chunk.replace('&', '&amp;')
#             chunk = chunk.replace('<', '&lt;')
#             chunk = chunk.replace('>', '&gt;')
#             yield chunk


# Path: graphos/renderers/morris.py
from .base import BaseChart
from ..utils import JSONEncoderForHTML
import json



class BaseMorrisChart(BaseChart):

    def get_data(self):
        header = self.header
        data = super(BaseMorrisChart, self).get_data()
        data_only = data[1:]
        rows = []
        for row in data_only:
            rows.append(dict(zip(header, row)))
        return rows

    def get_category_key(self):
        return self.header[0]

    def get_y_keys(self):
        try:

            return json.dumps(self.options['ykeys'], cls=JSONEncoderForHTML)