pyecharts任意位置添加文字 + 自适应居中 + table表格居中

数据分析(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 路径图

](https://img-blog.csdnimg.cn/59b0f3c52b5b45ac8b3259c6d6127717.png)

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 %}

  • 4
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值