Merge pull request #208 from 647-coder/add

Add datazoom type and date heatmap
This commit is contained in:
陈键冬 2017-10-12 21:40:40 +08:00 committed by GitHub
commit be89ad142f
6 changed files with 142 additions and 52 deletions

View File

@ -340,7 +340,7 @@ dataZoomdataZoom components for zoom-in and zoom-out. With them, it is possib
It specifies whether to use the datazoom component.
* datazoom_type -> str
defalut -> 'slider'
datazoom type, 'slider' or 'inside'
datazoom type, 'slider', 'inside', or 'both'
* datazoom_range -> list
defalut -> [50, 100]
The range percentage of the window out of the data extent, in the range of 0 ~ 100.
@ -1028,6 +1028,12 @@ add(name, x_axis, y_axis, data, **kwargs)
data of yAxis, it must be catagory axis.
* data -> [[],[]]
data array of series, it is represented by a two-dimension array
* is_date_heatmap -> bool
default -> False
Whether it is a date heatmap
* date_range -> str/list
date range of date heatmap, "2016" is year 2016, ["2016-5-5", "2017-5-5"] is 2016/5/5-2017/5/5
```python
import random
from pyecharts import HeatMap
@ -1044,6 +1050,23 @@ heatmap.render()
```
![heatmap-0](https://github.com/chenjiandongx/pyecharts/blob/master/images/heatmap-0.gif)
```python
import datetime
import random
from pyecharts import HeatMap
begin = datetime.date(2017, 1, 1)
end = datetime.date(2017, 12, 31)
data = [[str(begin + datetime.timedelta(days=i)),
random.randint(0, 100)] for i in range((end - begin).days+1)]
heatmap = HeatMap("日历热力图示例")
heatmap.add("日历热力图", data, date_range=["2017"], is_visualmap=True,
is_legend_show=False, is_date_heatmap=True, visual_orient="horizontal",
visual_pos="center", visual_top="top")
heatmap.render()
```
![heatmap-0](https://github.com/chenjiandongx/pyecharts/blob/master/images/heatmap-1.gif)
**Tip** Thermodynamic chart have to cooperate with VisualMap in use.

View File

@ -339,7 +339,7 @@ cast(seq)
* is_datazoom_show -> bool
是否使用区域缩放组件,默认为 False
* datazoom_type -> str
区域缩放组件类型,默认为'slider',有'slider', 'inside'可选
区域缩放组件类型,默认为'slider',有'slider', 'inside', 'both'可选
* datazoom_range -> list
区域缩放的范围,默认为[50, 100]
* datazoom_orient -> str
@ -1203,6 +1203,11 @@ add(name, x_axis, y_axis, data, **kwargs)
y 坐标轴数据。需为类目轴,也就是不能是数值。
* data -> [list],包含列表的列表
数据项,数据中,每一行是一个『数据项』,每一列属于一个『维度』
* is_date_heatmap -> bool
是否是日历热力图,默认为 False
* date_range -> str/list
日历热力图的日期, "2016"表示2016年, ["2016-5-5", "2017-5-5"]表示2016年5月5日至2017年5月5日
```python
import random
from pyecharts import HeatMap
@ -1218,6 +1223,23 @@ heatmap.render()
```
![heatmap-0](https://github.com/chenjiandongx/pyecharts/blob/master/images/heatmap-0.gif)
```python
import datetime
import random
from pyecharts import HeatMap
begin = datetime.date(2017, 1, 1)
end = datetime.date(2017, 12, 31)
data = [[str(begin + datetime.timedelta(days=i)),
random.randint(0, 100)] for i in range((end - begin).days+1)]
heatmap = HeatMap("日历热力图示例")
heatmap.add("日历热力图", data, date_range=["2017"], is_visualmap=True,
is_legend_show=False, is_date_heatmap=True, visual_orient="horizontal",
visual_pos="center", visual_top="top")
heatmap.render()
```
![heatmap-0](https://github.com/chenjiandongx/pyecharts/blob/master/images/heatmap-1.gif)
**Note** 热力图必须配合 [通用配置项](https://github.com/chenjiandongx/pyecharts/blob/master/docs/zh-cn/documentation.md#通用配置项) 中的 VisualMap 使用才有效果。

View File

@ -21,7 +21,7 @@ class HeatMap(Base):
def add(self, *args, **kwargs):
self.__add(*args, **kwargs)
def __add(self, name, x_axis, y_axis, data, **kwargs):
def __add(self, *args, **kwargs):
"""
:param name:
@ -36,16 +36,14 @@ class HeatMap(Base):
:param kwargs:
:return:
"""
if kwargs.get('is_date_heatmap', None) is True:
name, data = args
else:
name, x_axis, y_axis, data = args
chart = get_all_options(**kwargs)
self._option.get('legend')[0].get('data').append(name)
xaxis, yaxis = chart['xy_axis']
self._option.update(xAxis=xaxis, yAxis=yaxis)
self._option.get('xAxis')[0].update(
type='category', data=x_axis, splitArea={"show": True})
self._option.get('yAxis')[0].update(
type='category', data=y_axis, splitArea={"show": True})
self._option.get('series').append({
"type": "heatmap",
"name": name,
@ -53,4 +51,18 @@ class HeatMap(Base):
"label": chart['label'],
"seriesId": self._option.get('series_id'),
})
if kwargs.get('is_date_heatmap', None) is True:
self._option.get('toolbox')['show'] = False
self._option.get('series')[0].update(coordinateSystem='calendar',
calendarIndex=0)
self._option.update(calendar=chart['calendar'])
else:
xaxis, yaxis = chart['xy_axis']
self._option.update(xAxis=xaxis, yAxis=yaxis)
self._option.get('xAxis')[0].update(
type='category', data=x_axis, splitArea={"show": True})
self._option.get('yAxis')[0].update(
type='category', data=y_axis, splitArea={"show": True})
self._config_components(**kwargs)

View File

@ -795,7 +795,7 @@ def datazoom(is_datazoom_show=False,
:param is_datazoom_show:
It specifies whether to use the datazoom component.
:param datazoom_type:
datazoom type, 'slider' or 'inside'
datazoom type, 'slider', 'inside', or 'both'
:param datazoom_range:
The range percentage of the window out of the data extent,in
the range of 0 ~ 100.
@ -816,18 +816,24 @@ def datazoom(is_datazoom_show=False,
if datazoom_range:
if len(datazoom_range) == 2:
_min, _max = datazoom_range
if datazoom_type not in ("slider", "inside"):
if datazoom_type not in ("slider", "inside", "both"):
datazoom_type = "slider"
_datazoom = {
_datazoom = []
_datazoom_config = {
"show": is_datazoom_show,
"type": datazoom_type,
"type": "slider",
"start": _min,
"end": _max,
"orient": datazoom_orient,
"xAxisIndex": datazoom_xaxis_index,
"yAxisIndex": datazoom_yaxis_index
}
return [_datazoom]
if datazoom_type == "both":
_datazoom.append(_datazoom_config.copy())
datazoom_type = 'inside'
_datazoom_config['type'] = datazoom_type
_datazoom.append(_datazoom_config)
return _datazoom
@collectfuncs
@ -1127,6 +1133,16 @@ def tooltip(type=None,
return _tooltip
@collectfuncs
def calendar(date_range=None,
cellSize=['auto', 20], **kwargs):
_calendar = {
"range": date_range,
"cellSize": cellSize
}
return _calendar
def get_all_options(**kwargs):
""" Return all component options of charts

View File

@ -53,51 +53,52 @@ def test_bar():
bar.render()
def test_bar_datazoom_slider():
attr = ["{}".format(i) for i in range(1, 13)]
v1 = [2.0, 4.9, 7.0, 23.2, 25.6, 76.7,
135.6, 162.2, 32.6, 20.0, 6.4, 3.3]
v2 = [2.6, 5.9, 9.0, 26.4, 28.7, 70.7,
175.6, 182.2, 48.7, 18.8, 6.0, 2.3]
bar = Bar("柱状图示例")
bar.add("蒸发量", attr, v1, mark_line=["average"],
mark_point=["max", "min"])
bar.add("降水量", attr, v2, mark_line=["average"],
mark_point=["max", "min"], is_datazoom_show=True,
datazoom_range=[50, 80])
assert "dataZoom" in bar._repr_html_()
bar.render()
def test_bar_datazoom_undefined():
# bar dataZoom undefined-type
attr = ["{}".format(i) for i in range(30)]
v1 = [random.randint(1, 30) for _ in range(30)]
bar = Bar("Bar - datazoom - slider 示例")
bar = Bar("Bar - datazoom 默认 示例")
bar.add("", attr, v1, is_label_show=True, is_datazoom_show=True)
assert ': "slider"' in bar._repr_html_()
assert ': "inside"' not in bar._repr_html_()
bar.render()
html_content = bar._repr_html_()
assert "dataZoom" in html_content
assert ': "slider"' in html_content
assert ': "inside"' not in html_content
def test_bar_datazoom_slider():
# bar dataZoom slider-type
attr = ["{}".format(i) for i in range(30)]
v1 = [random.randint(1, 30) for _ in range(30)]
bar = Bar("Bar - datazoom 默认 示例")
bar.add("", attr, v1, is_datazoom_show=True, datazoom_type='slider',
datazoom_range=[10, 25])
html_content = bar._repr_html_()
assert "dataZoom" in html_content
assert ': "slider"' in html_content
assert ': "inside"' not in html_content
def test_bar_datazoom_inside():
# bar dataZoom inside-type
attr = ["{}".format(i) for i in range(1, 13)]
v1 = [2.0, 4.9, 7.0, 23.2, 25.6, 76.7,
135.6, 162.2, 32.6, 20.0, 6.4, 3.3]
v2 = [2.6, 5.9, 9.0, 26.4, 28.7, 70.7,
175.6, 182.2, 48.7, 18.8, 6.0, 2.3]
bar = Bar("柱状图示例")
bar.add("蒸发量", attr, v1, mark_line=["average"],
mark_point=["max", "min"])
bar.add("降水量", attr, v2, mark_line=["average"],
mark_point=["max", "min"], is_datazoom_show=True,
datazoom_range=[20, 60], datazoom_type='inside')
assert "dataZoom" in bar._repr_html_()
bar.render()
attr = ["{}".format(i) for i in range(30)]
v1 = [random.randint(1, 30) for _ in range(30)]
bar = Bar("Bar - datazoom - inside 示例")
bar.add("", attr, v1, is_datazoom_show=True, datazoom_type='inside',
datazoom_range=[10, 25], is_xaxis_show=False, is_yaxis_show=False)
assert ': "inside"' in bar._repr_html_()
assert ': "slider"' not in bar._repr_html_()
bar.render()
datazoom_range=[10, 25])
html_content = bar._repr_html_()
assert "dataZoom" in html_content
assert ': "inside"' in html_content
assert ': "slider"' not in html_content
def test_bar_datazoom_both():
# bar dataZoom both-type
attr = ["{}".format(i) for i in range(30)]
v1 = [random.randint(1, 30) for _ in range(30)]
bar = Bar("Bar - datazoom - both 示例")
bar.add("", attr, v1, is_datazoom_show=True, datazoom_type='both',
datazoom_range=[10, 25])
html_content = bar._repr_html_()
assert "dataZoom" in html_content
assert ': "inside"' in html_content
assert ': "slider"' in html_content

View File

@ -15,3 +15,19 @@ def test_heatmap():
xaxis_name='XNAME', yaxis_name='YNAME',
yaxis_name_pos='end', yaxis_name_gap=5)
heatmap.render()
def test_heatmap_date():
import random
import datetime
begin = datetime.date(2017, 1, 1)
end = datetime.date(2017, 12, 31)
data = [[str(begin + datetime.timedelta(days=i)),
random.randint(0, 100)] for i in range((end - begin).days + 1)]
heatmap = HeatMap("日历热力图示例")
heatmap.add("日历热力图", data,
is_visualmap=True, is_legend_show=False,
is_date_heatmap=True, date_range="2017",
visual_orient="horizontal", visual_pos="center",
visual_top="top")
heatmap.render()