Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 56 additions & 4 deletions pandas_highcharts/core.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,15 @@
# -*- coding: utf-8 -*-

# @Author: phil
# @Date: 2016-11-25T10:16:14+08:00
# @Last modified by: phil
# @Last modified time: 2016-11-30T15:34:51+08:00
from string import Template

import pandas
import copy

import re

_pd2hc_kind = {
"bar": "column",
Expand All @@ -18,6 +25,7 @@ def pd2hc_kind(kind):
raise ValueError("%(kind)s plots are not yet supported" % locals())
return _pd2hc_kind[kind]


_pd2hc_linestyle = {
"-": "Solid",
"--": "Dash",
Expand Down Expand Up @@ -90,6 +98,7 @@ def serialize_plotOptions(df, output, *args, **kwargs):
def serialize_series(df, output, *args, **kwargs):
def is_secondary(c, **kwargs):
return c in kwargs.get("secondary_y", [])

if kwargs.get('sort_columns'):
df = df.sort_index()
series = df.to_dict('series')
Expand Down Expand Up @@ -120,8 +129,34 @@ def serialize_title(df, output, *args, **kwargs):

def serialize_tooltip(df, output, *args, **kwargs):
if 'tooltip' in kwargs:
# if we want to display more info in tooltip,
# we should provide `field__additional_info`
# additional_info should be a list-like obj that is of same length
# with df
additional_info_keys = [key for key in kwargs['tooltip'] if 'additional_info' in key]
if additional_info_keys:
for key in additional_info_keys:
field, _ = key.split('__')
additional_info = kwargs['tooltip'].pop(key)
# insert additional_info to the data field
field_idx = [idx for idx, dic in enumerate(output['series']) if dic['name'] == field][0]
dic = output['series'][field_idx]
dic['data'] = [{'x': x, 'y': y, 'additional_info': additional_info[idx]} for idx, (x, y) in
enumerate(dic['data'])]

output['tooltip'] = kwargs['tooltip']

# handle parameters that require functions
# first insert function into output['___functions___']
# then put a place-holder, $XXXXXX
if 'formatter' in output['tooltip']:
output['___functions___']['tooltip__formatter'] = output['tooltip'].pop('formatter')
output['tooltip']['formatter'] = "$tooltip__formatter"

if 'pointFormatter' in output['tooltip']:
output['___functions___']['tooltip__pointFormatter'] = output['tooltip'].pop('pointFormatter')
output['tooltip']['pointFormatter'] = '$tooltip_pointFormatter'

def serialize_xAxis(df, output, *args, **kwargs):
output["xAxis"] = {}
if df.index.name:
Expand Down Expand Up @@ -173,7 +208,7 @@ def serialize_zoom(df, output, *args, **kwargs):
raise ValueError("zoom must be in ('x', 'y', 'xy')")
output["chart"]["zoomType"] = kwargs["zoom"]

output = {}
output = {'___functions___': {}}
df_copy = copy.deepcopy(df)
if "x" in kwargs:
df_copy.index = df_copy.pop(kwargs["x"])
Expand Down Expand Up @@ -201,10 +236,27 @@ def serialize_zoom(df, output, *args, **kwargs):
serialize_xAxis(df_copy, output, *args, **kwargs)
serialize_yAxis(df_copy, output, *args, **kwargs)
serialize_zoom(df_copy, output, *args, **kwargs)

functions = output.pop('___functions___')
if output_type == "dict":
def update_dict(d, up):
for k, v in d.items():
if isinstance(v, str) and v.startswith('$'):
d[k] = up[v.replace('$', '')]
if isinstance(v, dict):
update_dict(v, up)
update_dict(output, functions)
return output

json_output = """{}""".format(json_encode(output))
# "$xxxxxx" --------> $xxxxxx
# then repalce $xxxxxx with real js function
json_output = re.sub('"(\$\w+)"', r'\1', json_output)
if output_type == "json":
return json_encode(output)
template = Template("""{}""".format(json_output))
return template.substitute(functions)
if chart_type == "stock":
return "new Highcharts.StockChart(%s);" % json_encode(output)
return "new Highcharts.Chart(%s);" % json_encode(output)
high_stocks = Template("""new Highcharts.StockChart(%s);""" % json_output)
return high_stocks.substitute(functions)
high_charts = Template("new Highcharts.Chart(%s);" % json_output)
return high_charts.substitute(functions)