redesigned customize module,make it more reasonable

This commit is contained in:
chenjiandongx 2017-08-14 02:41:18 +08:00
parent 67117d3ec8
commit 0eef4fd345
8 changed files with 325 additions and 168 deletions

View File

@ -4,6 +4,7 @@
__version__ = '0.1.9.4'
__author__ = 'chenjiandongx'
# chart
from pyecharts.charts.bar import Bar
from pyecharts.charts.bar3D import Bar3D
from pyecharts.charts.effectscatter import EffectScatter
@ -24,4 +25,9 @@ from pyecharts.charts.radar import Radar
from pyecharts.charts.scatter import Scatter
from pyecharts.charts.scatter3D import Scatter3D
from pyecharts.charts.wordcloud import WordCloud
# customize component
from pyecharts.page import Page
from pyecharts.grid import Grid
from pyecharts.overlap import Overlap
from pyecharts.timeline import Timeline

View File

@ -23,8 +23,7 @@ class Base(object):
subtitle_color="#aaa",
title_text_size=18,
subtitle_text_size=12,
background_color="#fff",
is_grid=False):
background_color="#fff"):
"""
:param title:
@ -62,12 +61,8 @@ class Base(object):
Color can be represented in RGB, for example 'rgb(128, 128, 128)'.
RGBA can be used when you need alpha channel, for example 'rgba(128, 128, 128, 0.5)'.
You may also use hexadecimal format, for example '#ccc'.
:param is_grid:
It specifies whether to use the grid component.
"""
self._option = {}
if is_grid:
self._option.update(grid=[])
self._width, self._height = width, height
self._colorlst = ['#c23531', '#2f4554', '#61a0a8', '#d48265', '#749f83',
'#ca8622', '#bda29a', '#6e7074', '#546570', '#c4ccd3',
@ -245,103 +240,6 @@ class Base(object):
""" The base class's add() is just to provide a hint option """
pass
def custom(self, series):
""" Appends the data for the series of the chart type
:param series:
series data
"""
_name, _series, _xaxis, _yaxis, _legend, _title = series
for n in _name:
self._option.get('legend')[0].get('data').append(n)
for s in _series:
self._option.get('series').append(s)
def __custom_for_grid(self, series):
"""
:param series:
series data
:return:
"""
_name, _series, _xaxis, _yaxis, _legend, _title = series
for s in _series:
self._option.get('series').append(s)
return len(self._option.get('series')), len(_series), _xaxis, _yaxis, _legend, _title
def grid(self, series,
grid_width=None,
grid_height=None,
grid_top=None,
grid_bottom=None,
grid_left=None,
grid_right=None):
""" Concurrently show charts
:param series:
append other chart series data
:param grid_width:
Width of grid component. Adaptive by default.
:param grid_height:
Height of grid component. Adaptive by default.
:param grid_top:
Distance between grid component and the top side of the container.
grid_top value can be instant pixel value like 20;
it can also be percentage value relative to container width like '20%';
and it can also be 'top', 'middle', or 'bottom'.
If the grid_top value is set to be 'top', 'middle', or 'bottom',
then the component will be aligned automatically based on position.
:param grid_bottom:
Distance between grid component and the bottom side of the container.
grid_bottom value can be instant pixel value like 20;
it can also be percentage value relative to container width like '20%'.
:param grid_left:
Distance between grid component and the left side of the container.
grid_left value can be instant pixel value like 20;
it can also be percentage value relative to container width like '20%';
and it can also be 'left', 'center', or 'right'.
If the grid_left value is set to be 'left', 'center', or 'right',
then the component will be aligned automatically based on position.
:param grid_right:
Distance between grid component and the right side of the container.
grid_right value can be instant pixel value like 20;
it can also be percentage value relative to container width like '20%'.
:return:
"""
from pyecharts.option import grid
_index, _index_once, _xaxis, _yaxis, _legned, _title = self.__custom_for_grid(series)
self._option.get('legend').append(_legned)
self._option.get('title').append(_title)
if _xaxis and _yaxis is not None:
try:
_xaxis[0].update(gridIndex=_index - 1)
_yaxis[0].update(gridIndex=_index - 1)
self._option.get('xAxis').append(_xaxis[0])
self._option.get('yAxis').append(_yaxis[0])
except:
pass
# indexflag is only identify for every series
_flag = self._option.get('series')[0].get('indexflag')
_series_index = 0
for s in self._option.get('series'):
if _flag == s.get('indexflag'):
s.update(xAxisIndex=_series_index, yAxisIndex=_series_index)
else:
_series_index += 1
s.update(xAxisIndex=_series_index, yAxisIndex=_series_index)
_flag = s.get('indexflag')
_grid = grid(grid_width, grid_height, grid_top,
grid_bottom, grid_left, grid_right)
for _ in range(_index_once):
self._option.get('grid').append(_grid)
def get_series(self):
""" Get chart series data """
return self._option.get('legend')[0].get('data'), self._option.get('series'),\
self._option.get('xAxis', None), self._option.get('yAxis', None),\
self._option.get('legend')[0], self._option.get('title')[0]
def show_config(self):
""" Print all options of charts"""
pprint(self._option)
@ -391,10 +289,6 @@ class Base(object):
self._option.get('legend')[0].update(chart['legend'])
self._option.update(color=chart['color'])
# grid component
if chart['grid']:
self._option.get('grid').append(chart['grid'])
# datazoom component
if kwargs.get('is_datazoom_show', None) is True:
self._option.update(dataZoom=chart['datazoom'])

122
pyecharts/grid.py Normal file
View File

@ -0,0 +1,122 @@
#!/usr/bin/env python
# coding=utf-8
from pyecharts.option import grid
class Grid(object):
def __init__(self):
self._chart = None
def add(self, chart,
grid_width=None,
grid_height=None,
grid_top=None,
grid_bottom=None,
grid_left=None,
grid_right=None):
"""
:param chart:
chart instance
:param grid_width:
Width of grid component. Adaptive by default.
:param grid_height:
Height of grid component. Adaptive by default.
:param grid_top:
Distance between grid component and the top side of the container.
:param grid_bottom:
Distance between grid component and the bottom side of the container.
:param grid_left:
Distance between grid component and the left side of the container.
:param grid_right:
Distance between grid component and the right side of the container.
:return:
"""
if self._chart is None:
self._chart = chart
self._chart._option.update(grid=[])
_grid = grid(grid_width, grid_height, grid_top, grid_bottom, grid_left, grid_right)
if _grid:
for _ in range(len(self._chart._option.get('series'))):
self._chart._option.get('grid').append(_grid)
else:
_index, _index_once, _xaxis, _yaxis, _legned, _title = self.__custom(self.__get_series(chart))
self._chart._option.get('legend').append(_legned)
self._chart._option.get('title').append(_title)
if _xaxis and _yaxis is not None:
try:
_xaxis[0].update(gridIndex=_index - 1)
_yaxis[0].update(gridIndex=_index - 1)
self._chart._option.get('xAxis').append(_xaxis[0])
self._chart._option.get('yAxis').append(_yaxis[0])
except:
pass
# indexflag is only identify for every series
_flag = self._chart._option.get('series')[0].get('indexflag')
_series_index = 0
for s in self._chart._option.get('series'):
if _flag == s.get('indexflag'):
s.update(xAxisIndex=_series_index, yAxisIndex=_series_index)
else:
_series_index += 1
s.update(xAxisIndex=_series_index, yAxisIndex=_series_index)
_flag = s.get('indexflag')
_grid = grid(grid_width, grid_height, grid_top, grid_bottom, grid_left, grid_right)
for _ in range(_index_once):
self._chart._option.get('grid').append(_grid)
def __get_series(self, chart):
""" Get chart series data """
return (
chart._option.get('legend')[0].get('data'),
chart._option.get('series'),
chart._option.get('xAxis', None),
chart._option.get('yAxis', None),
chart._option.get('legend')[0],
chart._option.get('title')[0]
)
def __custom(self, series):
"""
:param series:
series data
:return:
"""
_name, _series, _xaxis, _yaxis, _legend, _title = series
for s in _series:
self._chart._option.get('series').append(s)
return len(self._chart._option.get('series')), len(_series), _xaxis, _yaxis, _legend, _title
def render(self, path="render.html"):
"""
:param path:
:return:
"""
self._chart.render(path)
def render_embed(self):
"""
:return:
"""
return self._chart.render_embed()
def show_config(self):
"""
:return:
"""
import pprint
return pprint.pprint(self._chart._option)
def get_chart(self):
"""
:return:
"""
return self._chart

74
pyecharts/overlap.py Normal file
View File

@ -0,0 +1,74 @@
#!/usr/bin/env python
# coding=utf-8
class Overlap(object):
def __init__(self):
self._chart = None
def add(self, chart):
"""
:param chart:
chart instance
:return:
"""
if self._chart is None:
self._chart = chart
else:
self.__custom(self.__get_series(chart))
def __get_series(self, chart):
""" Get chart series data
:param chart:
chart instance
:return:
"""
return (
chart._option.get('legend')[0].get('data'),
chart._option.get('series'),
)
def __custom(self, series):
""" Appends the data for the series of the chart type
:param series:
series data
"""
_name, _series = series
for n in _name:
self._chart._option.get('legend')[0].get('data').append(n)
for s in _series:
self._chart._option.get('series').append(s)
def render(self, path="render.html"):
"""
:param path:
:return:
"""
self._chart.render(path)
def render_embed(self):
"""
:return:
"""
return self._chart.render_embed()
def show_config(self):
"""
:return:
"""
import pprint
return pprint.pprint(self._chart._option)
def get_chart(self):
"""
:return:
"""
return self._chart

View File

@ -1,3 +1,6 @@
#!/usr/bin/env python
# coding=utf-8
from pyecharts import template

View File

@ -3,10 +3,11 @@
from __future__ import unicode_literals
from pyecharts import Bar, Line, Scatter, EffectScatter, Kline
from pyecharts import Overlap
def test_custom():
# custom_0
def test_custom_0():
attr = ['A', 'B', 'C', 'D', 'E', 'F']
v1 = [10, 20, 30, 40, 50, 60]
v2 = [15, 25, 35, 45, 55, 65]
@ -15,11 +16,15 @@ def test_custom():
bar.add("bar", attr, v1)
line = Line()
line.add("line", v2, v3)
bar.custom(line.get_series())
bar.show_config()
bar.render()
# custom_1
overlap = Overlap()
overlap.add(bar)
overlap.add(line)
overlap.render()
def test_custom_1():
v1 = [10, 20, 30, 40, 50, 60]
v2 = [30, 30, 30, 30, 30, 30]
v3 = [50, 50, 50, 50, 50, 50]
@ -28,14 +33,18 @@ def test_custom():
es.add("es", v1, v2)
scatter = Scatter()
scatter.add("scatter", v1, v3)
es.custom(scatter.get_series())
es_1 = EffectScatter()
es_1.add("es_1", v1, v4, symbol='pin', effect_scale=5)
es.custom(es_1.get_series())
es.show_config()
es.render()
# custom_2
overlap = Overlap()
overlap.add(es)
overlap.add(scatter)
overlap.add(es_1)
overlap.render()
def test_custom_2():
import random
v1 = [[2320.26, 2320.26, 2287.3, 2362.94],
[2300, 2291.3, 2288.26, 2308.38],
@ -75,7 +84,9 @@ def test_custom():
line_1.add("line-1", attr, [random.randint(2400, 2500) for _ in range(31)])
line_2 = Line()
line_2.add("line-2", attr, [random.randint(2400, 2500) for _ in range(31)])
kline.custom(line_1.get_series())
kline.custom(line_2.get_series())
kline.show_config()
kline.render()
overlap = Overlap()
overlap.add(kline)
overlap.add(line_1)
overlap.add(line_2)
overlap.render()

View File

@ -3,44 +3,53 @@
from __future__ import unicode_literals
from pyecharts import Bar, Line, Scatter, EffectScatter, Pie, Kline, HeatMap
from pyecharts import Grid
def test_grid():
# grid_0
def test_grid_0():
attr = ["衬衫", "羊毛衫", "雪纺衫", "裤子", "高跟鞋", "袜子"]
v1 = [5, 20, 36, 10, 75, 90]
v2 = [10, 25, 8, 60, 20, 80]
bar = Bar("柱状图示例", height=720, is_grid=True)
bar.add("商家A", attr, v1, is_stack=True, grid_bottom="60%")
bar.add("商家B", attr, v2, is_stack=True, grid_bottom="60%")
bar = Bar("柱状图示例", height=720)
bar.add("商家A", attr, v1, is_stack=True)
bar.add("商家B", attr, v2, is_stack=True)
line = Line("折线图示例", title_top="50%")
attr = ['周一', '周二', '周三', '周四', '周五', '周六', '周日']
line.add("最高气温", attr, [11, 11, 15, 13, 12, 13, 10], mark_point=["max", "min"], mark_line=["average"])
line.add("最低气温", attr, [1, -2, 2, 5, 3, 2, 0], mark_point=["max", "min"],
mark_line=["average"], legend_top="50%")
bar.grid(line.get_series(), grid_top="60%")
grid = Grid()
grid.add(bar, grid_bottom="60%")
grid.add(line, grid_top="60%")
bar.show_config()
bar.render()
grid.render()
def test_grid_1():
# grid_1
v1 = [5, 20, 36, 10, 75, 90]
v2 = [10, 25, 8, 60, 20, 80]
scatter = Scatter(width=1200, is_grid=True)
scatter.add("散点图示例", v1, v2, grid_left="60%", legend_pos="70%")
scatter = Scatter(width=1200)
scatter.add("散点图示例", v1, v2, legend_pos="70%")
es = EffectScatter()
es.add("动态散点图示例", [11, 11, 15, 13, 12, 13, 10], [1, -2, 2, 5, 3, 2, 0],
effect_scale=6, legend_pos="20%")
scatter.grid(es.get_series(), grid_right="60%")
scatter.show_config()
scatter.render()
# grid_2
grid = Grid()
grid.add(scatter, grid_left="60%")
grid.add(es, grid_right="60%")
grid.render()
def test_grid_2():
attr = ["衬衫", "羊毛衫", "雪纺衫", "裤子", "高跟鞋", "袜子"]
v1 = [5, 20, 36, 10, 75, 90]
v2 = [10, 25, 8, 60, 20, 80]
bar = Bar("柱状图示例", height=720, width=1200, title_pos="65%", is_grid=True)
bar.add("商家A", attr, v1, is_stack=True, grid_bottom="60%", grid_left="60%")
bar.add("商家B", attr, v2, is_stack=True, grid_bottom="60%", grid_left="60%", legend_pos="80%")
bar = Bar("柱状图示例", height=720, width=1200, title_pos="65%")
bar.add("商家A", attr, v1, is_stack=True)
bar.add("商家B", attr, v2, is_stack=True, legend_pos="80%")
line = Line("折线图示例")
attr = ['周一', '周二', '周三', '周四', '周五', '周六', '周日']
line.add("最高气温", attr, [11, 11, 15, 13, 12, 13, 10], mark_point=["max", "min"], mark_line=["average"])
@ -53,36 +62,40 @@ def test_grid():
es = EffectScatter("动态散点图示例", title_top="50%")
es.add("es", [11, 11, 15, 13, 12, 13, 10], [1, -2, 2, 5, 3, 2, 0], effect_scale=6,
legend_top="50%", legend_pos="20%")
bar.grid(line.get_series(), grid_bottom="60%", grid_right="60%")
bar.grid(scatter.get_series(), grid_top="60%", grid_left="60%")
bar.grid(es.get_series(), grid_top="60%", grid_right="60%")
bar.show_config()
bar.render()
# grid_3
line = Line("折线图示例", width=1200, is_grid=True)
grid = Grid()
grid.add(bar, grid_bottom="60%", grid_left="60%")
grid.add(line, grid_bottom="60%", grid_right="60%")
grid.add(scatter, grid_top="60%", grid_left="60%")
grid.add(es, grid_top="60%", grid_right="60%")
grid.render()
def test_grid_3():
line = Line("折线图示例", width=1200)
attr = ['周一', '周二', '周三', '周四', '周五', '周六', '周日']
line.add("最高气温", attr, [11, 11, 15, 13, 12, 13, 10], mark_point=["max", "min"],
mark_line=["average"], grid_right="65%")
line.add("最高气温", attr, [11, 11, 15, 13, 12, 13, 10], mark_point=["max", "min"], mark_line=["average"])
line.add("最低气温", attr, [1, -2, 2, 5, 3, 2, 0], mark_point=["max", "min"],
mark_line=["average"], legend_pos="20%")
attr = ["衬衫", "羊毛衫", "雪纺衫", "裤子", "高跟鞋", "袜子"]
v1 = [11, 12, 13, 10, 10, 10]
pie = Pie("饼图示例", title_pos="45%")
pie.add("", attr, v1, radius=[30, 55], legend_pos="65%", legend_orient='vertical')
line.grid(pie.get_series(), grid_left="60%")
line.show_config()
line.render()
# grid_4
line = Line("折线图示例", width=1200, is_grid=True)
grid = Grid()
grid.add(line, grid_right="65%")
grid.add(pie, grid_left="60%")
grid.render()
def test_grid_4():
line = Line("折线图示例", width=1200)
attr = ['周一', '周二', '周三', '周四', '周五', '周六', '周日']
line.add("最高气温", attr, [11, 11, 15, 13, 12, 13, 10], mark_point=["max", "min"],
mark_line=["average"], grid_right="60%")
line.add("最高气温", attr, [11, 11, 15, 13, 12, 13, 10], mark_point=["max", "min"], mark_line=["average"])
line.add("最低气温", attr, [1, -2, 2, 5, 3, 2, 0], mark_point=["max", "min"],
mark_line=["average"], legend_pos="20%", grid_right="60%")
attr = ["衬衫", "羊毛衫", "雪纺衫", "裤子", "高跟鞋", "袜子"]
value = [20, 40, 60, 80, 100, 120]
mark_line=["average"], legend_pos="20%")
v1 = [[2320.26, 2320.26, 2287.3, 2362.94],
[2300, 2291.3, 2288.26, 2308.38],
[2295.35, 2346.5, 2295.35, 2345.92],
@ -116,25 +129,31 @@ def test_grid():
[2255.77, 2270.28, 2253.31, 2276.22]]
kline = Kline("K 线图示例", title_pos="60%")
kline.add("日K", ["2017/7/{}".format(i + 1) for i in range(31)], v1, legend_pos="80%")
line.grid(kline.get_series(), grid_left="55%")
line.show_config()
line.render()
# grid_5
grid = Grid()
grid.add(line, grid_right="60%")
grid.add(kline, grid_left="55%")
grid.render()
def test_grid_5():
import random
x_axis = ["12a", "1a", "2a", "3a", "4a", "5a", "6a", "7a", "8a", "9a", "10a", "11a",
"12p", "1p", "2p", "3p", "4p", "5p", "6p", "7p", "8p", "9p", "10p", "11p"]
y_aixs = ["Saturday", "Friday", "Thursday", "Wednesday", "Tuesday", "Monday", "Sunday"]
data = [[i, j, random.randint(0, 50)] for i in range(24) for j in range(7)]
heatmap = HeatMap("热力图示例", height=700, is_grid=True)
heatmap = HeatMap("热力图示例", height=700)
heatmap.add("热力图直角坐标系", x_axis, y_aixs, data, is_visualmap=True, visual_top="45%",
visual_text_color="#000", visual_orient='horizontal', grid_bottom="60%")
visual_text_color="#000", visual_orient='horizontal')
attr = ["衬衫", "羊毛衫", "雪纺衫", "裤子", "高跟鞋", "袜子"]
v1 = [5, 20, 36, 10, 75, 90]
v2 = [10, 25, 8, 60, 20, 80]
bar = Bar("柱状图示例", title_top="52%")
bar.add("商家A", attr, v1, is_stack=True)
bar.add("商家B", attr, v2, is_stack=True, legend_top="50%")
heatmap.grid(bar.get_series(), grid_top="60%")
heatmap.show_config()
heatmap.render()
grid = Grid()
grid.add(heatmap, grid_bottom="60%")
grid.add(bar, grid_top="60%")
grid.render()

View File

@ -1,10 +1,11 @@
#!/usr/bin/env python
#coding=utf-8
from __future__ import unicode_literals
from random import randint
from pyecharts.timeline import Timeline
from pyecharts import Bar, Pie
from pyecharts import Bar, Pie, Line
def test_timeline():
@ -80,3 +81,30 @@ def test_timeline_pie():
timeline.add(pie_5, '2016 年')
timeline.show_config()
timeline.render()
def test_timeline_bar_line():
from pyecharts import Overlap
attr = ["{}".format(i) for i in range(1, 7)]
bar = Bar("Line - Bar 示例")
bar.add("bar", attr, [randint(10, 50) for _ in range(6)])
line = Line()
line.add("line", attr, [randint(50, 80) for _ in range(6)])
overlap = Overlap()
overlap.add(bar)
overlap.add(line)
bar_1 = Bar("Line")
bar_1.add("bar", attr, [randint(10, 50) for _ in range(6)])
line_1 = Line()
line_1.add("line", attr, [randint(50, 80) for _ in range(6)])
overlap_1 = Overlap()
overlap_1.add(bar_1)
overlap_1.add(line_1)
overlap_1.get_chart()
timeline = Timeline(timeline_bottom=0)
timeline.add(overlap.get_chart(), '2012')
timeline.add(overlap_1.get_chart(), '2013')
timeline.render()