0
点赞
收藏
分享

微信扫一扫

如何使用Odoo集成ECharts

登高且赋 2022-03-30 阅读 40

背景介绍

Odoo框架中自带的视图非常丰富,能给我们展示的数据关系和标准的流程体系。但是在实际的业务场景中,除了能将数据关系和流程体系展示出来,我们希望能够以更直观更美观更具科技感的形式的展示多维度的业务数据,以便给决策者提供依据。故此数据可视化的应用场景也开始变得更加多样且视觉要求更高,下面就给大家介绍一下Odoo如何集成ECharts,在Odoo上实现数据的可视化场景。

ECharts介绍

ECharts,一个使用 JavaScript 实现的开源可视化库,可以流畅的运行在 PC 和移动设备上,兼容当前绝大部分浏览器,底层依赖轻量级的矢量图形库 ZRender,提供直观,交互丰富,可高度个性化定制的数据可视化图表。

ECharts 提供了常规的折线图、柱状图、散点图、饼图、K线图,用于统计的盒形图,用于地理数据可视化的地图、热力图、线图,用于关系数据可视化的关系图、旭日图,多维数据可视化的平行坐标,还有用于 BI 的漏斗图,仪表盘,并且支持图与图之间的混搭,Echarts作为国内的优秀可视化库,兼容大部分场景,很容易进行定制化开发,所以选择使用Echarts。

更多详细的内容可查看官方文档(https://echarts.apache.org/zh/index.html)

如何使用odoo集成ECharts

(1)页面效果

我们希望使用Echarts来做活动分布和活动统计方面的相关展示,以下就是我们的最终效果。

(2)Odoo集成ECharts

1、下载ECharts源码到本地:

echarts源码:https://github.com/apache/echarts/blob/5.3.0/dist/echarts.min.js

2、下载中国地图源码到本地

China.js源码:https://github.com/apache/echarts/tree/master/test/data/map/js,还有中国各省份地图和世界地图,请按需下载

3、将ECharts集成到Odoo中

将ECharts.min.js和China.js放到对应模块的static/js中,并在template.xml中引入这两个js

(3)ECharts使用:

1、在menu.xml中创建一个地图菜单

2、在action.xml中绑定地图菜单的action

3、创建QWeb页面

<?xml version="1.0" encoding="utf-8" ?>
<template>
    &lt;t t-name="quotation_map_page">
        <div style="padding: 5px 10px 0 10px;">
            <div id="center" style="width:100%; height:58vh;background-color: #f7f9ff;display: flex;border-radius: 20px;">
                <div id="map" style="width: 40%; height: 80%;margin-top: 20px;"></div>
                <div id="activeFlows" style="width: 10%; height: 70%;margin-left: 40px;margin-top: 40px;">
                    <div class="innerbox">
                        <ul style="padding: 10px;background-color: white;border-radius: 6px;overflow-y: auto;margin-bottom: 0;">
                            <li class="image-click">
                                <img src="/xc_order/static/description/1.jpg" style="height: 100%;vertical-align: baseline;width: 100%;border-radius: 4px;"/>
                            </li>
                            <li class="image-click">
                                <img src="/xc_order/static/description/2.jpg" style="height: 100%;vertical-align: baseline;width: 100%;border-radius: 4px;"/>
                            </li>
                            <li class="image-click">
                                <img src="/xc_order/static/description/3.jpg" style="height: 100%;vertical-align: baseline;width: 100%;border-radius: 4px;"/>
                            </li>
                            <li class="image-click">
                                <img src="/xc_order/static/description/4.png" style="height: 100%;vertical-align: baseline;width: 100%;border-radius: 4px;"/>
                            </li>
                        </ul>
                    </div>
                </div>
                <div id="activeContent" style="width: 40%; height: 80%;margin-left: 40px;margin-top: 20px;">
                    <img id="activePhoto" src="/xc_order/static/description/4.png" style="height: 100%;vertical-align: baseline;width: 100%;border-radius: 8px;"/>
                    <div style="text-align: center;color: #5784fd">活动现场照片</div>
                </div>
            </div>
            <div id="footer" style="display: flex;align-items: center;border-radius: 20px;">
                <div id="left" style="width:27%; height:32vh;background-color: #f7f9ff;margin-top:10px; display: flex;">
                    <div id="pie2" style="width: 50%; height:100%"></div>
                </div>
                <div id="current" style="width:36%; height:32vh;background-color: #f7f9ff;margin-top:10px;margin-left: 10px">
                    <div id="bar" style="width: 100%; height:100%"></div>
                </div>
                <div id="right" style="width:36%; height:32vh;background-color: #f7f9ff;margin-top:10px;margin-left: 10px">
                    <div id="line" style="width: 100%; height:100%"></div>
                </div>
            </div>
        </div>
    &lt;/t>
</template>

4、创建对应js和css,可以通过option进行echarts配置,详情请看ECharts官网-配置项手册(https://echarts.apache.org/zh/option.html#title)

odoo.define('quotation.pre.sale', function (require) {
    var framework = require("web.framework");
    var session = require("web.session");
    var crash_manager = require("web.CrashManager");
    var AbstractAction = require('web.AbstractAction')
    var core = require('web.core')
    var map = AbstractAction.extend({
        template: 'quotation_map_page',
 
        start: function () {
            var self = this
            self.renderMap()
            self.renderPie()
            self.renderBar()
            self.renderLine()
        },
        renderMap: function () {
            let self = this
            let option = {
                tooltip: {
                    show: false
                },
                geo: {
                    map: "china",
                    roam: false,// 一定要关闭拖拽
                    zoom: 1.23,
                    center: [105, 36], // 调整地图位置
                    label: {
                        normal: {
                            show: false, //关闭省份名展示
                            fontSize: "10",
                            color: "rgba(0,0,0,0.7)"
                        },
                        emphasis: {
                            show: false
                        }
                    },
                    itemStyle: {
                        normal: {
                            areaColor: "#0d0059",
                            borderColor: "#389dff",
                            borderWidth: 1, //设置外层边框
                            shadowBlur: 5,
                            shadowOffsetY: 8,
                            shadowOffsetX: 0,
                            shadowColor: "#01012a"
                        },
                        emphasis: {
                            areaColor: "#184cff",
                            shadowOffsetX: 0,
                            shadowOffsetY: 0,
                            shadowBlur: 5,
                            borderWidth: 0,
                            shadowColor: "rgba(0, 0, 0, 0.5)"
                        }
                    }
                },
                series: [
                    {
                        type: "map",
                        map: "china",
                        roam: false,
                        zoom: 1.23,
                        center: [105, 36],
                        // geoIndex: 1,
                        // aspectScale: 0.75, //长宽比
                        showLegendSymbol: false, // 存在legend时显示
                        label: {
                            normal: {
                                show: false
                            },
                            emphasis: {
                                show: false,
                                textStyle: {
                                    color: "#fff"
                                }
                            }
                        },
                        itemStyle: {
                            normal: {
                                areaColor: "#0d0059",
                                borderColor: "#389dff",
                                borderWidth: 0.5
                            },
                            emphasis: {
                                areaColor: "#17008d",
                                shadowOffsetX: 0,
                                shadowOffsetY: 0,
                                shadowBlur: 5,
                                borderWidth: 0,
                                shadowColor: "rgba(0, 0, 0, 0.5)"
                            }
                        }
                    }
                ]
            };
            var dataValue = this.dealWithData();
            var data1 = dataValue.splice(0, 6);
            var options = {
                series: [
                    {
                        type: "map",
                        map: "china",
                        roam: false,
                        zoom: 1.23,
                        center: [105, 36],
                        // geoIndex: 1,
                        // aspectScale: 0.75, //长宽比
                        showLegendSymbol: false, // 存在legend时显示
                        label: {
                            normal: {
                                show: false
                            },
                            emphasis: {
                                show: false
                            }
                        },
                        itemStyle: {
                            normal: {
                                areaColor: "#0d0059",
                                borderColor: "#389dff",
                                borderWidth: 0.5
                            },
                            emphasis: {
                                areaColor: "#17008d",
                                shadowOffsetX: 0,
                                shadowOffsetY: 0,
                                shadowBlur: 5,
                                borderWidth: 0,
                                shadowColor: "rgba(0, 0, 0, 0.5)"
                            }
                        }
                    },
                    {
                        name: "",
                        type: "scatter",
                        coordinateSystem: "geo",
                        data: dataValue,
                        //   symbolSize: function(val) {
                        //     return val[2] / 10;
                        //   },
                        symbol: "circle",
                        symbolSize: 8,
                        hoverSymbolSize: 10,
                        tooltip: {
                            formatter(value) {
                                return value.data.name + "<br/>" + "设备数:" + "22";
                            },
                            show: true
                        },
                        encode: {
                            value: 2
                        },
                        label: {
                            formatter: "{b}",
                            position: "right",
                            show: false
                        },
                        itemStyle: {
                            color: "#0efacc"
                        },
                        emphasis: {
                            label: {
                                show: false
                            }
                        }
                    },
                    {
                        name: "人数",
                        type: "effectScatter",
                        coordinateSystem: "geo",
                        data: data1,
                        symbolSize: 15,
                        tooltip: {
                            show: true
                        },
                        encode: {
                            value: 2
                        },
                        showEffectOn: "render",
                        rippleEffect: {
                            brushType: "stroke",
                            color: "#0efacc",
                            period: 9,
                            scale: 5
                        },
                        hoverAnimation: true,
                        label: {
                            formatter: "{b}",
                            position: "bottom",
                            show: true
                        },
                        itemStyle: {
                            color: "#0efacc",
                            shadowBlur: 2,
                            shadowColor: "#333"
                        },
                        zlevel: 1
                    }
                ]
            };
 
            $(document).ready(() => {
                this.myEchart = echarts.init(document.getElementById('map'));
                this.myEchart.setOption(options);
                this.myEchart.setOption(option);
                this.myEchart.on('click', self.selectCity.bind(self))
                // $('.image-click').on('click', this.changeImage.bind(this))
                $(".image-click").on('click', self.changeImage.bind(self));
            });
        },
        selectCity: function (ev){
            console.log(ev.name)
 
        },
        changeImage: function (ev){
            let imageSrc = $($(ev.target)[0]).attr('src')
            $('#activePhoto').attr('src', imageSrc)
 
        },
        dealWithData: function () {
            var data = [
                { name: '北京', value: 1400 },
                { name: '上海', value: 1000 },
                { name: '深圳', value: 700 },
                { name: '武汉', value: 999 },
                { name: '成都', value: 400 },
            ]
            var geoCoordMap = {
                北京: [116.46, 39.92],
                上海: [121.48, 31.22],
                深圳: [114.07, 22.62],
                武汉: [114.31, 30.52],
                成都: [104.06, 30.67],
            };
            var res = [];
            // for (var key in geoCoordMap) {
            //     data.push({name: key, value: geoCoordMap[key]});
            // }
            for (var i = 0; i < data.length; i++) {
                var geoCoord = geoCoordMap[data[i].name];
                if (geoCoord) {
                  res.push({
                    name: data[i].name,
                    value: geoCoord.concat(data[i].value)
                  });
                }
            }
            return res;
        },
        renderPie: function () {
            let option2 = {
                title: {
                    text: '活动类型',
                    // subtext: 'Fake Data',
                    left: 'center'
                },
                color:['#1bfff1', '#5a87fd', '#5afdaf','#ffae63'],
                tooltip: {
                    trigger: 'item'
                },
                legend: {
                    // orient: 'vertical',
                    top:'bottom'
                },
                series: [
                    {
                        // name: 'Access From',
                        type: 'pie',
                        radius: '50%',
                        data: [
                            {value: 30, name: '市场活动'},
                            {value: 40, name: '签约活动'},
                            {value: 15, name: '技术大会'},
                            {value: 15, name: '员工培训'},
                        ],
                        emphasis: {
                            itemStyle: {
                                shadowBlur: 10,
                                shadowOffsetX: 0,
                                shadowColor: 'rgba(0, 0, 0, 0.5)'
                            }
                        }
                    }
                ]
            };
            $(document).ready(function () {
                this.myEchart2 = echarts.init(document.getElementById('pie2'));
                this.myEchart2.setOption(option2);
            });
        },
        renderBar: function () {
            let option = {
                title: {
                    text: '活动数量统计',
                    // subtext: 'Fake Data'
                    left: 'center'
                },
                color:['#1bfff1', '#5a87fd'],
                tooltip: {
                    trigger: 'axis'
                },
                legend: {
                    data: ['内部活动', '外部活动'],
                    top:'bottom'
                },
                toolbox: {
                    show: false,
                    feature: {
                        // dataView: {show: true, readOnly: false},
                        // magicType: {show: true, type: ['line', 'bar']},
                        // restore: {show: true},
                        // saveAsImage: {show: true}
                    }
                },
                calculable: true,
                xAxis: [
                    {
                        type: 'category',
                        // prettier-ignore
                        data: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
                    }
                ],
                yAxis: [
                    {
                        type: 'value'
                    }
                ],
                series: [
                    {
                        name: '内部活动',
                        type: 'bar',
                        data: [
                            200, 270, 320, 250, 380, 300, 200, 100, 50, 120, 170,200
                        ]
                    },
                    {
                        name: '外部活动',
                        type: 'bar',
                        data: [
                            100, 170, 120, 250, 280, 200, 400, 200, 250, 220, 70,200
                        ]
                    }
                ]
            };
            $(document).ready(function () {
                this.myEchart = echarts.init(document.getElementById('bar'));
                this.myEchart.setOption(option);
            });
        },
        renderLine: function () {
            let option = {
                title: {
                    text: '活动关注度',
                    // subtext: 'Fake Data',
                    left: 'center'
                },
                // color:['#1bfff1', '#5a87fd'],
                xAxis: {
                    type: 'category',
                    data: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
                },
                yAxis: {
                    type: 'value'
                },
                series: [
                    {
                        data: [150, 230, 224, 218, 135, 147, 260,200, 250, 100, 230,50],
                        type: 'line',
                        symbolSize: 3,//拐点大小
                        smooth:false,
                        itemStyle: {
                            normal : {
                                color:'#5a87fd',
                                lineStyle:{
                                    color:'#1bfff1'
                                }
                            }
                        }
                    }
                ]
            };
            $(document).ready(function () {
                this.myEchart = echarts.init(document.getElementById('line'));
                this.myEchart.setOption(option);
            });
        }
    })
 
    core.action_registry.add('quotation.map.page', map);
    return map;
})
.innerbox{
    overflow-x: hidden;
    overflow-y: auto;
    color: #000;
    font-size: .7rem;
    /*font-family: "\5FAE\8F6F\96C5\9ED1",Helvetica,"黑体",Arial,Tahoma;*/
    height: 100%;
}
/*滚动条样式*/
.innerbox::-webkit-scrollbar {
    width: 4px;
    /*height: 4px;*/
}
.innerbox::-webkit-scrollbar-thumb {
    border-radius: 10px;
    -webkit-box-shadow: inset 0 0 5px rgba(0,0,0,0.2);
    background: rgba(0,0,0,0.2);
}
.innerbox::-webkit-scrollbar-track {
    -webkit-box-shadow: inset 0 0 5px rgba(0,0,0,0.2);
    border-radius: 0;
    background: rgba(0,0,0,0.1);
 
}

5、将新建的xml和js文件引入,升级模块后,进入对应菜单


结语

感谢大家能够看完本文,以上就是odoo集成ECharts的整个过程和使用方式,从步骤来看整体还是比较简单的,大家赶紧在Odoo中操作起来吧!

Odoo相关推荐:

Odoo Tree视图操作,读完这篇就够了​confluence.digitalchina.com/pages/viewpage.action?pageId=25825071

版权声明:本文由神州数码云基地团队整理撰写,若转载请注明出处。

公众号搜索神州数码云基地,后台回复Odoo,加入Odoo技术交流群。

举报

相关推荐

0 条评论