数据分析(3)
- 以下是工作中遇到问题时,检索到比较好的案例,
收集起来方便自己查看。 - 同时,希望也能给遇到相同问题的同学节约时间,
快速检索到解决方案。
说下自己直观感受,以上3个问题应该是优化样式时普遍会遇到的,但检索出来示例大都不是很满意,以下是一些相应的解决方案。
1. 任意位置添加文字
1.1 里面富文本比较有用
https://www.csdn.net/tags/OtDakg3sNDg1MDAtYmxvZwO0O0OO0O0O.html#_508
https://blog.csdn.net/Tomandjava/article/details/117480470
1.2 任意位置添加文字
官方文档
https://github.com/pyecharts/pyecharts/pull/1175/commits/692a55fe3ae0406b9921802d05d1bcc981c8b12a
python 代码示例, 建议在文字添加处封装成函数,方便调用;还有就是注意文字格式,踩了不少坑。
def bar_graphic_rect_text_two_component() -> Bar:
c = (
Bar()
.add_xaxis(Faker.choose())
.add_yaxis("商家A", Faker.values())
.add_yaxis("商家B", Faker.values())
.set_global_opts(
title_opts=opts.TitleOpts(title="Bar-Graphic Rect+Text 2 组件示例"),
graphic_opts=[
opts.GraphicGroup(
graphic_item=opts.GraphicItem(
# 控制整体的位置
left="50%",
top="15%",
),
children=[
# opts.GraphicRect控制方框的显示
# 如果不需要方框,去掉该段即可
opts.GraphicRect(
graphic_item=opts.GraphicItem(
z=100,
left="center",
top="middle",
),
graphic_shape_opts=opts.GraphicShapeOpts(
width=190, height=90,
),
graphic_basicstyle_opts=opts.GraphicBasicStyleOpts(
fill="#fff",
stroke="#555",
line_width=2,
shadow_blur=8,
shadow_offset_x=3,
shadow_offset_y=3,
shadow_color="rgba(0,0,0,0.3)",
)
),
# opts.GraphicText控制文字的显示
opts.GraphicText(
graphic_item=opts.GraphicItem(
left="center",
top="middle",
z=100,
),
graphic_textstyle_opts=opts.GraphicTextStyleOpts(
# 可以通过jsCode添加js代码,也可以直接用字符串
text=JsCode(
"['横轴表示数据类别',"
"'纵轴表示数值的值',"
"'这个文本块可以放在图中各',"
"'种位置'].join('\\n')"
),
font="14px Microsoft YaHei",
graphic_basicstyle_opts=opts.GraphicBasicStyleOpts(
fill="#333"
)
)
)
]
)
],
)
)
return c
2. 自适应居中
以下文档已经较完善了,但是有不足之处。单独绘制一幅图时,不会有感触,但是利用page或grid绘制多图时,就会让人奔溃。还好勉强能看懂一些前端代码,改了下效果就比较好了。
https://blog.csdn.net/weixin_42262769/article/details/118192412
本来准备贴代码了,突然想给遇到同样问题的小伙伴开个玩笑,
此处省略代码一行,其实也只需要修改一行代码即可。
3. table表格居中
这里同样是一个小坑, 本来已经准备放弃了的,突然想到一个折中的解决方案,算是比较好的达到了预期,这里就不和同学们卖关子。
基于2中已经自适应居中,只需添加一个空白table占位即可,应为页面通常只会显示1-2两个table
def blank_table():
table = Table()
return table
4. table居中 后续来了
- 过去一周了,新的需求中表格数量太多了,每次都需要用一个空白table去占位太麻烦了,就尝试着改了下mecro,和其他图形其实也是一个原理,只需要修改对应的table组件源码就好了。
- 给小伙伴们的建议,放心大胆改源码,毕竟只是第三方库,改错了
pip uninstall pyecharts
就好了。 - 其他内置库就谨慎修改,重装解释器还是赖得麻烦的。
5. 隔了几个月了
- 之前是在全局环境配置的,但由于新项目需要搭建虚拟环境,又得改一次,还是把代码直接贴出来,方便自己使用,对小伙伴们也友好些。
- 文件路径 venv --> Lib --> site-packages --> pyecharts --> render --> templates
–> macro 和 simple_chart.html, 其中venv是我的虚拟环境名, 如果是全局解释器通常为python3.x,也就是对应的解释器版本 - 创建虚拟环境:可以参考 传送门
- 找到对应文件后直接用以下代码替换源代码
5.1 路径图
5.2 对应文件源码替换
5.2.1 simple_chart.html
{% import 'macro' as macro %}
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>{{ chart.page_title }}</title>
{{ macro.render_chart_dependencies(chart) }}
</head>
<body onresize="resizeFresh()">
<style type="text/css">
html,body{
height:100%;
width:100%
}
</style>
{{ macro.render_chart_content(chart) }}
</body>
</html>
5.2.2 macro
{%- macro render_chart_content(c) -%}
<div id="{{ c.chart_id }}" class="chart-container" style="width:{{ c.width }}; height:{{ c.height }}; margin:auto;"></div>
<script>
var chart_{{ c.chart_id }} = echarts.init(
document.getElementById('{{ c.chart_id }}'), '{{ c.theme }}', {renderer: '{{ c.renderer }}'});
{% for js in c.js_functions.items %}
{{ js }}
{% endfor %}
var option_{{ c.chart_id }} = {{ c.json_contents }};
chart_{{ c.chart_id }}.setOption(option_{{ c.chart_id }});
{% if c._is_geo_chart %}
var bmap = chart_{{ c.chart_id }}.getModel().getComponent('bmap').getBMap();
{% if c.bmap_js_functions %}
{% for fn in c.bmap_js_functions.items %}
{{ fn }}
{% endfor %}
{% endif %}
{% endif %}
{% if c.width.endswith('%') %}
window.addEventListener('resize', function(){
chart_{{ c.chart_id }}.resize();
})
{% endif %}
</script>
<script>
var x=window.innerWidth;
function resizeFresh(){
if(x!=window.innerWidth)
location.reload();
}
</script>
{%- endmacro %}
{%- macro render_notebook_charts(charts, libraries) -%}
<script>
require([{{ libraries | join(', ') }}], function(echarts) {
{% for c in charts %}
{% if c._component_type not in ("table", "image") %}
var chart_{{ c.chart_id }} = echarts.init(
document.getElementById('{{ c.chart_id }}'), '{{ c.theme }}', {renderer: '{{ c.renderer }}'});
{% for js in c.js_functions.items %}
{{ js }}
{% endfor %}
var option_{{ c.chart_id }} = {{ c.json_contents }};
chart_{{ c.chart_id }}.setOption(option_{{ c.chart_id }});
{% if c._is_geo_chart %}
var bmap = chart_{{ c.chart_id }}.getModel().getComponent('bmap').getBMap();
bmap.addControl(new BMap.MapTypeControl());
{% endif %}
{% endif %}
{% endfor %}
});
</script>
{%- endmacro %}
{%- macro render_chart_dependencies(c) -%}
{% for dep in c.dependencies %}
<script type="text/javascript" src="{{ dep }}"></script>
{% endfor %}
{%- endmacro %}
{%- macro render_chart_css(c) -%}
{% for dep in c.css_libs %}
<link rel="stylesheet" href="{{ dep }}">
{% endfor %}
{%- endmacro %}
{%- macro display_tablinks(chart) -%}
<div class="tab">
{% for c in chart %}
<button class="tablinks" onclick="showChart(event, '{{ c.chart_id }}')">{{ c.tab_name }}</button>
{% endfor %}
</div>
{%- endmacro %}
{%- macro switch_tabs() -%}
<script>
(function() {
containers = document.getElementsByClassName("chart-container");
if(containers.length > 0) {
containers[0].style.display = "block";
}
})()
function showChart(evt, chartID) {
let containers = document.getElementsByClassName("chart-container");
for (let i = 0; i < containers.length; i++) {
containers[i].style.display = "none";
}
let tablinks = document.getElementsByClassName("tablinks");
for (let i = 0; i < tablinks.length; i++) {
tablinks[i].className = "tablinks";
}
document.getElementById(chartID).style.display = "block";
evt.currentTarget.className += " active";
}
</script>
{%- endmacro %}
{%- macro generate_tab_css() %}
<style>
.tab {
overflow: hidden;
border: 1px solid #ccc;
background-color: #f1f1f1;
}
.tab button {
background-color: inherit;
float: left;
border: none;
outline: none;
cursor: pointer;
padding: 12px 16px;
transition: 0.3s;
}
.tab button:hover {
background-color: #ddd;
}
.tab button.active {
background-color: #ccc;
}
.chart-container {
display: none;
padding: 6px 12px;
border-top: none;
}
</style>
{%- endmacro %}
{%- macro gen_components_content(chart) %}
{% if chart._component_type == "table" %}
<style>
.fl-table {
margin: auto;
border-radius: auto;
font-size: 48px;
border: none;
border-collapse: collapse;
max-width: 100%;
white-space: nowrap;
word-break: keep-all;
}
.fl-table th {
text-align: center;
font-size: 20px;
}
.fl-table tr {
display: table-row;
vertical-align: inherit;
border-color: inherit;
}
.fl-table tr:hover td {
background: #00d1b2;
color: #F8F8F8;
}
.fl-table td, .fl-table th {
border-style: none;
border-top: 1px solid #dbdbdb;
border-left: 1px solid #dbdbdb;
border-bottom: 3px solid #dbdbdb;
border-right: 1px solid #dbdbdb;
padding: .5em .55em;
font-size: 15px;
}
.fl-table td {
border-style: none;
font-size: 20px;
vertical-align: center;
border-bottom: 1px solid #dbdbdb;
border-left: 1px solid #dbdbdb;
border-right: 1px solid #dbdbdb;
height: 20px;
}
.fl-table tr:nth-child(even) {
background: #F8F8F8;
}
</style>
<div id="{{ chart.chart_id }}" class="chart-container" style= "margin:auto;"></div>
<p class="title" {{ chart.title_opts.title_style }}> {{ chart.title_opts.title }}</p>
<p class="subtitle" {{ chart.title_opts.subtitle_style }}> {{ chart.title_opts.subtitle }}</p>
{{ chart.html_content }}
</div>
{% elif chart._component_type == "image" %}
<div id="{{ chart.chart_id }}" class="chart-container" style="">
<p class="title" {{ chart.title_opts.title_style }}> {{ chart.title_opts.title }}</p>
<p class="subtitle" {{ chart.title_opts.subtitle_style }}> {{ chart.title_opts.subtitle }}</p>
<img {{ chart.html_content }}/>
</div>
{% endif %}
{%- endmacro %}