Skip to content

Commit

Permalink
Prepare for version 2.0.8 (pyecharts#2393)
Browse files Browse the repository at this point in the history
version 2.0.8
  • Loading branch information
sunhailin-Leo authored Jan 24, 2025
1 parent 8ef2ae3 commit 0fbbcf9
Show file tree
Hide file tree
Showing 17 changed files with 470 additions and 7 deletions.
4 changes: 4 additions & 0 deletions .github/workflows/python-app.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,13 @@ jobs:
exclude: # Python < v3.8 does not support Apple Silicon ARM64.
- python-version: "3.7"
os: macos-latest
- python-version: "3.7"
os: ubuntu-latest
include: # So run those legacy versions on Intel CPUs.
- python-version: "3.7"
os: macos-13
- python-version: "3.7"
os: ubuntu-22.04
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v4
Expand Down
2 changes: 2 additions & 0 deletions pyecharts/charts/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,13 @@
from ..charts.basic_charts.funnel import Funnel
from ..charts.basic_charts.gauge import Gauge
from ..charts.basic_charts.geo import Geo
from ..charts.basic_charts.gmap import GMap
from ..charts.basic_charts.graph import Graph
from ..charts.basic_charts.heatmap import HeatMap
from ..charts.basic_charts.kline import Kline
from ..charts.basic_charts.line import Line
from ..charts.basic_charts.liquid import Liquid
from ..charts.basic_charts.lmap import LMap
from ..charts.basic_charts.map import Map
from ..charts.basic_charts.parallel import Parallel
from ..charts.basic_charts.pictorialbar import PictorialBar
Expand Down
4 changes: 4 additions & 0 deletions pyecharts/charts/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,10 @@ def __init__(
self.render_options.update(embed_js=bool(_render_opts.get("embed_js")))
self._render_cache: dict = dict()

def use_echarts_stat(self):
self.js_dependencies.add("echarts-stat")
return self

def get_chart_id(self) -> str:
return self.chart_id

Expand Down
7 changes: 5 additions & 2 deletions pyecharts/charts/basic_charts/calendar.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ def __init__(
render_opts: types.RenderInit = opts.RenderOpts(),
):
super().__init__(init_opts=init_opts, render_opts=render_opts)
self.options.update(calendar=opts.CalendarOpts().opts)

def add(
self,
Expand All @@ -37,7 +36,11 @@ def add(
**other_calendar_opts,
):
if calendar_opts:
self.options.update(calendar=calendar_opts)
if self.options.get("calendar"):
self.options.get("calendar").append(calendar_opts)
else:
self.options.update(calendar=[calendar_opts])

if visualmap_opts:
self.options.update(visualMap=visualmap_opts)

Expand Down
77 changes: 77 additions & 0 deletions pyecharts/charts/basic_charts/gmap.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
from ... import options as opts
from ... import types
from ...charts.basic_charts.geo import GeoChartBase
from ...commons.utils import OrderedSet, JsCode
from ...exceptions import NonexistentCoordinatesException
from ...globals import ChartType

GMAP_API = "https://maps.googleapis.com/maps/api/js?key={}"


class GMap(GeoChartBase):
"""
<<< GMap(Google Map) coordinate system >>>
Support scatter plot, line.
"""

def __init__(
self,
init_opts: types.Init = opts.InitOpts(),
is_ignore_nonexistent_coord: bool = False,
render_opts: types.RenderInit = opts.RenderOpts(),
):
super().__init__(init_opts=init_opts, render_opts=render_opts)
self.js_dependencies.add("gmap")
self._is_geo_chart = True
self._coordinate_system: types.Optional[str] = "gmap"
self.gmap_js_functions: OrderedSet = OrderedSet()
self._is_ignore_nonexistent_coord = is_ignore_nonexistent_coord

def _feed_data(self, data_pair: types.Sequence, type_: str) -> types.Sequence:
result = []
type_list = [ChartType.LINES, ChartType.CUSTOM]
if type_ in type_list:
result = data_pair
else:
for n, v in data_pair:
try:
lng, lat = self.get_coordinate(n)
result.append({"name": n, "value": [lng, lat, v]})
except TypeError as err:
if self._is_ignore_nonexistent_coord is not True:
raise NonexistentCoordinatesException(err, (n, v))
return result

def add_schema(
self,
gmap_ak: str,
center: types.Sequence,
zoom: types.Union[types.Numeric, str] = None,
is_render_on_map: bool = True,
z_index: types.Optional[int] = None,
is_roam: bool = True,
):
self.js_dependencies.add(GMAP_API.format(gmap_ak))
self.options.update(
gmap={
"center": center,
"zoom": zoom,
"renderOnMoving": is_render_on_map,
"echartsLayerZIndex": z_index,
"roam": is_roam
}
)
return self

def add_control_panel(
self,
is_add_traffic_layer: bool = False,
):
if is_add_traffic_layer:
self.gmap_js_functions.add(
"var trafficLayer = new google.maps.TrafficLayer(); "
"trafficLayer.setMap(gmap);"
)

return self
2 changes: 2 additions & 0 deletions pyecharts/charts/basic_charts/line.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ def add_yaxis(
xaxis_index: types.Optional[types.Numeric] = None,
yaxis_index: types.Optional[types.Numeric] = None,
polar_index: types.Optional[types.Numeric] = None,
dataset_index: types.Optional[types.Numeric] = None,
coordinate_system: types.Optional[str] = None,
color_by: types.Optional[str] = None,
color: types.Optional[str] = None,
Expand Down Expand Up @@ -78,6 +79,7 @@ def add_yaxis(
"xAxisIndex": xaxis_index,
"yAxisIndex": yaxis_index,
"polarIndex": polar_index,
"datasetIndex": dataset_index,
"coordinateSystem": coordinate_system,
"colorBy": color_by,
"symbol": symbol,
Expand Down
66 changes: 66 additions & 0 deletions pyecharts/charts/basic_charts/lmap.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
from ... import options as opts
from ... import types
from ...charts.basic_charts.geo import GeoChartBase
from ...commons.utils import OrderedSet, JsCode
from ...exceptions import NonexistentCoordinatesException
from ...globals import ChartType


class LMap(GeoChartBase):
"""
<<< LMap(leaflet) coordinate system >>>
Support scatter plot, line.
"""

def __init__(
self,
init_opts: types.Init = opts.InitOpts(),
is_ignore_nonexistent_coord: bool = False,
render_opts: types.RenderInit = opts.RenderOpts(),
):
super().__init__(init_opts=init_opts, render_opts=render_opts)
self.js_dependencies.add("lmap-css")
self.js_dependencies.add("lmap-src")
self.js_dependencies.add("lmap")
self._is_geo_chart = True
self._coordinate_system: types.Optional[str] = "lmap"
self.lmap_js_functions: OrderedSet = OrderedSet()
self._is_ignore_nonexistent_coord = is_ignore_nonexistent_coord

def _feed_data(self, data_pair: types.Sequence, type_: str) -> types.Sequence:
result = []
type_list = [ChartType.LINES, ChartType.CUSTOM]
if type_ in type_list:
result = data_pair
else:
for n, v in data_pair:
try:
lng, lat = self.get_coordinate(n)
result.append({"name": n, "value": [lng, lat, v]})
except TypeError as err:
if self._is_ignore_nonexistent_coord is not True:
raise NonexistentCoordinatesException(err, (n, v))
return result

def add_schema(
self,
center: types.Sequence,
zoom: types.Union[types.Numeric, str] = None,
is_enable_resize: bool = True,
is_render_on_map: bool = True,
is_layer_interactive: bool = True,
is_large: bool = False,
):
self.options.update(
lmap={
"center": center,
"zoom": zoom,
"resizeEnable": is_enable_resize,
"renderOnMoving": is_render_on_map,
"echartsLayerInteractive": is_layer_interactive,
"largeMode": is_large,
}
)

return self
5 changes: 5 additions & 0 deletions pyecharts/datasets/map_filename.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
{
"amap": ["echarts-extension-amap.min", "js"],
"lmap": ["echarts-extension-leaflet.min", "js"],
"lmap-src": ["leaflet/leaflet", "js"],
"lmap-css": ["leaflet/leaflet", "css"],
"gmap": ["echarts-extension-gmap.min", "js"],
"bulma": ["bulma.min", "css"],
"jquery": ["jquery.min", "js"],
"jquery-ui": ["jquery-ui.min", "js"],
Expand All @@ -8,6 +12,7 @@
"echarts-gl": ["echarts-gl.min", "js"],
"echarts-liquidfill": ["echarts-liquidfill.min", "js"],
"echarts-wordcloud": ["echarts-wordcloud.min", "js"],
"echarts-stat": ["ecStat.min", "js"],
"bmap": ["bmap.min", "js"],
"chalk": ["themes/chalk", "js"],
"essos": ["themes/essos", "js"],
Expand Down
16 changes: 14 additions & 2 deletions pyecharts/render/engine.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,22 +31,34 @@ def generate_js_link(chart: Any) -> Any:
if not chart.js_host:
chart.js_host = CurrentConfig.ONLINE_HOST
links = []
css_links = []
for dep in chart.js_dependencies.items:
# TODO: if?
if dep.startswith("https://api.map.baidu.com"):
links.append(dep)
if dep.startswith("https://webapi.amap.com"):
links.append(dep)
if dep.startswith("https://maps.googleapis.com"):
links.append(dep)
if dep in FILENAMES:
f, ext = FILENAMES[dep]
links.append("{}{}.{}".format(chart.js_host, f, ext))
_link = "{}{}.{}".format(chart.js_host, f, ext)
if ext == "css":
css_links.append(_link)
else:
links.append(_link)
else:
for url, files in EXTRA.items():
if dep in files:
f, ext = files[dep]
links.append("{}{}.{}".format(url, f, ext))
_link = "{}{}.{}".format(url, f, ext)
if ext == "css":
css_links.append(_link)
else:
links.append(_link)
break
chart.dependencies = links
chart.css_libs = css_links
return chart

def render_chart_to_file(self, template_name: str, chart: Any, path: str, **kwargs):
Expand Down
38 changes: 37 additions & 1 deletion pyecharts/render/templates/macro
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,24 @@
{{ fn }}
{% endfor %}
{% endif %}
{% elif c._coordinate_system == 'lmap' %}
var lmapComponent = chart_{{ c.chart_id }}.getModel().getComponent('lmap');
var lmap = lmapComponent.getLeaflet();
L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
}).addTo(lmap);
{% elif c._coordinate_system == 'gmap' %}
// Get the instance of Google Map
var gmap = chart_{{ c.chart_id }}.getModel().getComponent('gmap').getGoogleMap();
// Add some markers to map
var marker = new google.maps.Marker({ position: gmap.getCenter() });
marker.setMap(gmap);
// Add TrafficLayer to map
{% if c.gmap_js_functions %}
{% for fn in c.gmap_js_functions.items %}
{{ fn }}
{% endfor %}
{% endif %}
{% endif %}
{% endif %}
{% if c.width.endswith('%') %}
Expand Down Expand Up @@ -111,6 +129,24 @@
{{ fn }}
{% endfor %}
{% endif %}
{% elif c._coordinate_system == 'lmap' %}
var lmapComponent = chart_{{ c.chart_id }}.getModel().getComponent('lmap');
var lmap = lmapComponent.getLeaflet();
L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
}).addTo(lmap);
{% elif c._coordinate_system == 'gmap' %}
// Get the instance of Google Map
var gmap = chart_{{ c.chart_id }}.getModel().getComponent('gmap').getGoogleMap();
// Add some markers to map
var marker = new google.maps.Marker({ position: gmap.getCenter() });
marker.setMap(gmap);
// Add TrafficLayer to map
{% if c.gmap_js_functions %}
{% for fn in c.gmap_js_functions.items %}
{{ fn }}
{% endfor %}
{% endif %}
{% endif %}
{% endif %}
{% if c.js_events %}
Expand Down Expand Up @@ -141,7 +177,7 @@

{%- macro render_chart_css(c) -%}
{% for dep in c.css_libs %}
<link rel="stylesheet" href="{{ dep }}">
<link rel="stylesheet" href="{{ dep }}">
{% endfor %}
{%- endmacro %}

Expand Down
1 change: 1 addition & 0 deletions pyecharts/render/templates/simple_chart.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
<meta charset="UTF-8">
<title>{{ chart.page_title }}</title>
{{ macro.render_chart_dependencies(chart) }}
{{ macro.render_chart_css(chart) }}
</head>
<body {% if chart.fill_bg %}style="background-color: {{ chart.bg_color }}"{% endif %}>
{{ macro.render_chart_content(chart) }}
Expand Down
4 changes: 4 additions & 0 deletions test/test_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,3 +90,7 @@ def test_base_chart_id(self):

c1 = Base(init_opts=InitOpts(chart_id="1234567"))
self.assertEqual(c1.get_chart_id(), "1234567")

def test_use_echarts_stat(self):
c0 = Base().use_echarts_stat()
self.assertEqual(c0.js_dependencies.items, ["echarts", "echarts-stat"])
Loading

0 comments on commit 0fbbcf9

Please sign in to comment.