Skip to content

Commit 267ffc0

Browse files
committed
feat: init python sdk for @visactor/vchart
1 parent 025c27b commit 267ffc0

File tree

5 files changed

+329
-0
lines changed

5 files changed

+329
-0
lines changed

setup.cfg

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
# This file is used to configure your project.
2+
# Read more about the various options under:
3+
# http://setuptools.readthedocs.io/en/latest/setuptools.html#configuring-setup-using-setup-cfg-files
4+
5+
[metadata]
6+
name = py-vchart
7+
description = python visualization sdk for @visactor/vchart
8+
author = VisActor
9+
author-email = VisActor
10+
license = mit
11+
long-description = file: README.rst
12+
long-description-content-type = text/x-rst; charset=UTF-8
13+
url = git@github.com:VisActor/py-vchart.git
14+
project-urls =
15+
Documentation = https://github.com/VisActor/py-vchart
16+
# Change if running only on Windows, Mac or Linux (comma-separated)
17+
platforms = any
18+
# Add here all kinds of additional classifiers as defined under
19+
# https://pypi.python.org/pypi?%3Aaction=list_classifiers
20+
classifiers =
21+
Development Status :: 4 - Beta
22+
Programming Language :: Python
23+
24+
[options]
25+
zip_safe = False
26+
packages = find:
27+
include_package_data = True
28+
package_dir =
29+
=src
30+
# DON'T CHANGE THE FOLLOWING LINE! IT WILL BE UPDATED BY PYSCAFFOLD!
31+
# setup_requires = pyscaffold>=3.2a0,<3.3a0
32+
# Add here dependencies of your project (semicolon/line-separated), e.g.
33+
install_requires =
34+
IPython
35+
jinja2
36+
pandas
37+
38+
# The usage of test_requires is discouraged, see `Dependency Management` docs
39+
# tests_require = pytest; pytest-cov
40+
# Require a specific Python version, e.g. Python 2.7 or >= 3.4
41+
42+
[options.packages.find]
43+
where = src
44+
exclude =
45+
tests
46+
47+
[options.extras_require]
48+
# Add here additional requirements for extra features, to install with:
49+
# `pip install vis[PDF]` like:
50+
# PDF = ReportLab; RXP
51+
# Add here test requirements (semicolon/line-separated)
52+
testing =
53+
pytest
54+
pytest-cov
55+
56+
[options.entry_points]
57+
# Add here console scripts like:
58+
# console_scripts =
59+
# script_name = vis.module:function
60+
# For example:
61+
# console_scripts =
62+
# fibonacci = vis.skeleton:run
63+
# And any other entry points, for example:
64+
# pyscaffold.cli =
65+
# awesome = pyscaffoldext.awesome.extension:AwesomeExtension
66+
67+
[test]
68+
# py.test options when running `python setup.py test`
69+
# addopts = --verbose
70+
extras = True
71+
72+
[tool:pytest]
73+
# Options for py.test:
74+
# Specify command line options as you would do when invoking py.test directly.
75+
# e.g. --cov-report html (or xml) for html/xml output or --junitxml junit.xml
76+
# in order to write a coverage file that can be read by Jenkins.
77+
addopts =
78+
--cov vis --cov-report term-missing
79+
--verbose
80+
norecursedirs =
81+
dist
82+
build
83+
.tox
84+
testpaths = tests
85+
86+
[aliases]
87+
dists = bdist_wheel
88+
89+
[bdist_wheel]
90+
# Use this option if your package is pure-python
91+
universal = 1
92+
93+
[build_sphinx]
94+
source_dir = docs
95+
build_dir = build/sphinx
96+
97+
[devpi:upload]
98+
# Options for the devpi: PyPI server and packaging tool
99+
# VCS export must be deactivated since we are using setuptools-scm
100+
no-vcs = 1
101+
formats = bdist_wheel
102+
103+
[flake8]
104+
# Some sane defaults for the code style checker flake8
105+
exclude =
106+
.tox
107+
build
108+
dist
109+
.eggs
110+
docs/conf.py
111+
112+
# [pyscaffold]
113+
# # PyScaffold's parameters when the project was created.
114+
# # This will be used when updating. Do not change!
115+
# version = 3.2.3
116+
# package = vis

setup.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import sys
2+
3+
from pkg_resources import VersionConflict, require
4+
from setuptools import setup
5+
6+
try:
7+
require('setuptools>=38.3')
8+
except VersionConflict:
9+
print("Error: version of setuptools is too old (<38.3)!")
10+
sys.exit(1)
11+
12+
13+
if __name__ == "__main__":
14+
setup(name='py-vchart',
15+
version='1.0.0'
16+
)

src/pyvchart/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
from .engine import render_chart, vaild_json
2+
__all__ = ["render_chart", "vaild_json"]

src/pyvchart/engine.py

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
import os
2+
from IPython.core.display import HTML
3+
from jinja2 import Environment, PackageLoader, select_autoescape, FileSystemLoader
4+
import json
5+
import uuid
6+
7+
env = Environment(
8+
loader=FileSystemLoader(
9+
os.path.join(
10+
os.path.dirname(__file__), "templates"
11+
)
12+
),
13+
autoescape=select_autoescape(['html', 'xml'])
14+
)
15+
16+
colors = [
17+
'#009DB5',
18+
'#F2B823',
19+
'#3DA241',
20+
'#1F5273',
21+
'#EB6F02',
22+
'#76BEC8',
23+
'#D44977',
24+
'#EF85A7',
25+
'#675DAE',
26+
'#B6BC65',
27+
'#829E0B',
28+
'#A6A6E1',
29+
'#4A525F',
30+
'#87B7DD',
31+
'#A13630',
32+
'#CB7B48',
33+
'#AA7F01',
34+
'#E1CA56',
35+
'#0F7000',
36+
'#7C878D',
37+
]
38+
39+
def _render_template(chart):
40+
template = env.get_template('jupyter_lab.html')
41+
html = template.render(chart=chart)
42+
return html
43+
44+
def vaild_json(data):
45+
try:
46+
json.dumps(data)
47+
return True
48+
except:
49+
return False
50+
51+
52+
def render_chart(data, width="100%", height="500px", colors=colors):
53+
""" render_chart
54+
chart: https://github.com/VisActor/VChart
55+
----------
56+
data: json
57+
is a json, which can render chart like new VChart(data, {dom: `${domId}`})
58+
width: string
59+
chart width: 100%, 500px
60+
height: string
61+
chart height: 100% 500px
62+
colors: list
63+
chart theme color
64+
----------
65+
"""
66+
if(vaild_json(data)):
67+
chart = {}
68+
chart_id = uuid.uuid4().hex
69+
chart['chart_id'] = chart_id
70+
chart['data_source'] = json.dumps(data)
71+
chart['width'] = width
72+
chart['height'] = height
73+
chart['colors'] = colors
74+
return HTML(_render_template(chart))
75+
else:
76+
return 'is not a vaild json to render chart'
Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
<div class="vis-arco-chart-wrap">
2+
<div id="arco_{{ chart.chart_id }}" style="width: {{chart.width}}; height: {{chart.height}}">
3+
</div>
4+
<script>
5+
// -> 这里代码请使用es5来写
6+
!function () {
7+
let libSrc = "https://www.unpkg.com/@visactor/vchart/build/index.js"
8+
let libdom = document.body.getAttribute('class');
9+
// 判断是经典notebook 还是lib -> 同一个输出需要兼容lab
10+
// let isClassicNotebook = libdom.indexOf('notebook_app') !== -1;
11+
let isAmd = ("function" == typeof define && define.amd);
12+
// 经典notebook 使用require 来加载, 导致页面的模块加载方式改变, 因为修改了exports, 导致vchart无法挂到window上
13+
console.log('isAmd', isAmd);
14+
if (isAmd && window.requirejs && window.require) {
15+
if (document.body.getAttribute('vchart_loaded') !== 'true') {
16+
// 只需要配置一次
17+
window.requirejs.config({
18+
enforceDefine: true,
19+
paths: {
20+
"VChart": libSrc
21+
},
22+
waitSeconds: 40
23+
});
24+
document.body.setAttribute('vchart_loaded', 'true');
25+
}
26+
27+
window.require(['VChart'], function (VChart) {
28+
window.VChart = VChart;
29+
check();
30+
})
31+
} else if (!isAmd) {
32+
// 动态创建一个js , 避免浏览器兼容apipyechart
33+
let libDom = document.querySelector('#vchart');
34+
// 全局唯一 lib, 之前有就不再加载
35+
if (!libDom) {
36+
let lib = document.createElement("script");
37+
lib.type = "text/javascript";
38+
lib.src = libSrc + ".js";
39+
lib.id = 'vchart';
40+
lib.async = true;
41+
document.head.append(lib);
42+
}
43+
44+
loop();
45+
}
46+
// 一段时间 check lib 是否已经加载成功,
47+
// 不监听onload 是避免有多个cell 的chart同时绘制
48+
function check() {
49+
if (window.VChart && window.VChart.default) {
50+
render(JSON.parse({{ chart.data_source | tojson }}))
51+
} else {
52+
loop()
53+
}
54+
}
55+
56+
function render(data_source) {
57+
console.log('data_source', data_source);
58+
let chart = new window.VChart.default("arco_{{chart.chart_id}}", data_source);
59+
let teaColor = {{ chart.colors | safe
60+
}}
61+
chart.setColors(teaColor);
62+
chart.renderAsync();
63+
// 移除.jp-RenderedHTMLCommon 对Table的样式, chart 的Tooltip是个Table
64+
let target = document.querySelector("#arco_{{chart.chart_id}}").parentNode.parentNode;
65+
let classList = target.getAttribute("class");
66+
let ignoreList = ['rendered_html', 'jp-RenderedHTMLCommon'];
67+
let newClassList = classList;
68+
for (var i = 0; i < ignoreList.length; i++) {
69+
newClassList = newClassList.replace(ignoreList[i], '');
70+
}
71+
72+
target.setAttribute('class', newClassList);
73+
}
74+
75+
function loop() {
76+
setTimeout(function () {
77+
check()
78+
}, 500);
79+
}
80+
}();
81+
</script>
82+
<style>
83+
/*********For Lab Template*********/
84+
/* html,
85+
body,
86+
body > .jp-Notebook-cell.jp-mod-noInput,
87+
body > .jp-Notebook-cell.jp-mod-noInput > .jp-Cell-outputWrapper,
88+
body > .jp-Notebook-cell.jp-mod-noInput > .jp-Cell-outputWrapper > .jp-Cell-outputArea,
89+
body > .jp-Notebook-cell.jp-mod-noInput > .jp-Cell-outputWrapper > .jp-Cell-outputArea > .jp-OutputArea-child,
90+
body > .jp-Notebook-cell.jp-mod-noInput > .jp-Cell-outputWrapper > .jp-Cell-outputArea > .jp-OutputArea-child > .jp-OutputArea-executeResult,
91+
body > .jp-Notebook-cell.jp-mod-noInput > .jp-Cell-outputWrapper > .jp-Cell-outputArea > .jp-OutputArea-child > .jp-OutputArea-executeResult > .vis-arco-chart-wrap {
92+
height: 100%;
93+
}
94+
body {
95+
padding: 0 !important;
96+
margin: 0 !important;
97+
}
98+
body > .jp-Notebook-cell.jp-mod-noInput {
99+
padding: 0 !important;
100+
} */
101+
102+
/*********For Classic Template*********/
103+
/* html,
104+
body,
105+
div#notebook,
106+
div#notebook>.container,
107+
div#notebook>.container>.cell,
108+
div#notebook>.container>.cell>.output_wrapper,
109+
div#notebook>.container>.cell>.output_wrapper>.output,
110+
div#notebook>.container>.cell>.output_wrapper>.output>.output_area,
111+
div#notebook>.container>.cell>.output_wrapper>.output>.output_area>.output_html,
112+
div#notebook>.container>.cell>.output_wrapper>.output>.output_area>.output_html>div {
113+
height: 100%;
114+
}
115+
div#notebook-container {
116+
box-sizing: border-box;
117+
} */
118+
</style>
119+
</div>

0 commit comments

Comments
 (0)