模块安装
1、下载dashboard以后放在插件目录。
2、pip install -r requirement.txt。
3、重启ODOO,刷新ODOO应用列表并安装。
创建看板
点击新建按扭,创建dashboard。完成后返回列表
1、点击编辑进入编辑模式。
2、点击预览进入预览模式。
3、点击绑定菜单,将编辑好的DASHBOARD绑定到菜单。
4、全屏,全屏预览。
5、导出,导出模板。
界面预览





编辑布局
编辑布局一般使用布局区块进行布局
布局使用bootstrap的网格布局,如果需要水平放置元素使用flex row组件,纵向使用flex column组件。
可以通过嵌套实现复杂的布局效果
一般情况下,为了更好的体现区块效果,会选择拖动卡片到布局中
单个调整好以后通过复制按扭复制到其它网格,这样可以保持样式统一
更改样式
选中元素后,在左侧通过样式面版调整区块样式

编辑工具栏
远中元素后会自动弹出编辑工具

2、十字箭头移动元素。



5、一些元素有自己特定的编辑按扭,如图表会有配置按扭。

添加图表
图表是开发中必不可少的元素

1、选择数据源,目前支持以下几种模式。
(1)、模型。
选择一个模型,同时在下方分组上选择分组的字段,注意,一些字段,如计算字段等无法进行分组。如上图。

[
{
product: "Matcha Latte",
"2015": 43.3,
"2016": 85.8,
"2017": 93.7,
},
{
product: "Milk Tea",
"2015": 83.1,
"2016": 73.4,
"2017": 55.1,
},
{
product: "Cheese Cocoa",
"2015": 86.4,
"2016": 65.2,
"2017": 82.5,
},
{
product: "Walnut Brownie",
"2015": 72.4,
"2016": 53.9,
"2017": 39.1,
},
]
(4)、python代码。
此方式可以直接写代码,调用整理后端数据。

结果一定要通过result返回。可能通过self.env['xxxx'].method()的形式获取数据,最终通过result返回数据。
(5)、无。
自定义图表
虽然内置了很多图表,但总有不满足的情况,通过自定义图表可以很好的解决此问题
点击编辑按扭进入配置界面,此种方式一般使用code作为后端数据源
后端代码示例如下
参考代码
result = [
{
"product: "Matcha Latte",
"2015": 43.3,
"2016": 85.8,
"2017": 93.7,
},
{
"product: "Milk Tea",
"2015": 83.1,
"2016": 73.4,
"2017": 55.1,
},
{
"product: "Cheese Cocoa",
"2015": 86.4,
"2016": 65.2,
"2017": 82.5,
},
{
"product": "Walnut Brownie",
"2015": 72.4,
"2016": 53.9,
"2017": 39.1,
},
]
function hexToRgb(hex, percent) {
// 去除 # 号,并转换为整数
hex = hex.replace('#', '');
// 提取每个颜色通道的值
const r = parseInt(hex.substring(0, 2), 16);
const g = parseInt(hex.substring(2, 4), 16);
const b = parseInt(hex.substring(4, 6), 16);
// 返回 RGB 格式的字符串
return `RGB(${r}, ${g}, ${b},${percent})`;
}
const xData = ['询价','竞争性磋商', '单一来源', '竞争性谈判','邀请招标','公开招标' ]
const yData = [234, 188, 315, 234, 188, 315]
const colorList = [
'#FFA600',
'#FEDB65',
'#026DB2',
'#12FEE0',
'#6DD400',
'#44D7B6',
'#5C64FF',
'#6988F8',
'#0E5FFF',
'#2DE1FD',
'#8221F1',
'#B26DF6',
]
option = {
title: {
text: 'ECharts柱状图入门示例',
left: "center",
top: "8%",
textStyle: {
color: '#111111', // 标题颜色
fontWeight: 'bold',
fontSize: 16,
},
},
tooltip: {
trigger: 'axis',
borderWidth: 0,
backgroundColor: 'rgba(0,0,0,0.75)',
color: '#fff',
textStyle: {
color: '#fff'
},
//避免出现多个信息
formatter: function (params) {
return params[0].name + `</br><span style="display:inline-block;width:10px;height:10px;border-radius:5px;background-color:${params[0].color.colorStops[0].color}"></span> ` + params[0].value; // 只显示第一个系列的信息
}
},
toolbox: {
show: true
},
grid: {
top: "15%",
bottom: "10%", //也可设置left和right设置距离来控制图表的大小
},
yAxis: [
{
data: xData,
axisLabel: {
show: false,
},
splitLine: {
show: false,
},
axisTick: {
show: false,
},
axisLine: {
show: false,
},
},
],
xAxis: {
show: true,
splitLine: {
show: false,
},
axisTick: {
show: true,
inside: true,
lineStyle: {
color: '#045d79'
}
},
axisLine: {
show: false,
lineStyle: {
color: '#045d79'
},
},
axisLabel: {
show: false,
// color: 'white' // 将 x 轴文字颜色改为白色
},
axisTick: {
show: false,
},
},
series: [
{
z: 1,
type: 'bar',
data: yData,
barWidth: 20,
zlevel: 1,
showBackground: false,
itemStyle: {
barBorderRadius: [0, 20, 20, 0], // 圆角(左上、右上、右下、左下)
color: function (params) {
var index = params.dataIndex + params.dataIndex;
//每个柱子单独颜色渐变 可多加几个渐变过程 colorStops[{},{},{}]
const colorStops = [{
offset: 1,
color: colorList[index]
}, {
offset: 0,
color: colorList[index + 1]
// color: lightenColor(colors[params.dataIndex], 0.5) // 使用 lightenColor 函数使颜色变浅
// color: hexToRgb(colorList[params.dataIndex % colorList.length], 0.2) // 使用 lightenColor 函数使颜色变浅
}];
return new echarts.graphic.LinearGradient(0, 0, 1, 0, colorStops)
},
},
label: {
normal: {
color: '#000',
show: true,
position: [0, '-20px'],
textStyle: {
fontSize: 12,
color: "#999999",
},
formatter: '{b}',
},
},
},
{
type: 'bar',
data: yData,
barWidth: 20,
barGap: '-100%',
itemStyle: {
normal: {
color: '#f5f8ff',
},
emphasis: {
color: '#f5f8ff',
},
},
label: {
normal: {
color: '#333333',
show: true,
position:'right',
distance: 4,
textStyle: {
fontSize: 14,
fontWeight: "bold"
},
formatter: '{c}',
},
},
},
],
//数据过多纵向滚动
dataZoom: [
{
type: 'inside', // 数据缩放
show: true,
yAxisIndex: 0, // 对应的y轴
start: 0,
end: yData.length > 10 ? 1000 / yData.length : 100 // 初始显示范围,根据需要调整
}
],
};
// config
let config = this.get_config();
// get the datasource
let data_source = this.get_data_source(0);
// get the catorgories
let datas = data_source.get_raw_datas()
// config
let config = this.get_config();
// get the datasource
let data_source = this.get_data_source(0);
// get the catorgories
let datas = data_source.get_raw_datas()
debugger
let names = datas.map(item => item['product'])
let values = datas.map(item => item['2015'])
function hexToRgb(hex, percent) {
// 去除 # 号,并转换为整数
hex = hex.replace('#', '');
// 提取每个颜色通道的值
const r = parseInt(hex.substring(0, 2), 16);
const g = parseInt(hex.substring(2, 4), 16);
const b = parseInt(hex.substring(4, 6), 16);
// 返回 RGB 格式的字符串
return `RGB(${r}, ${g}, ${b},${percent})`;
}
const xData = names
const yData = values
const colorList = [
'#FFA600',
'#FEDB65',
'#026DB2',
'#12FEE0',
'#6DD400',
'#44D7B6',
'#5C64FF',
'#6988F8',
'#0E5FFF',
'#2DE1FD',
'#8221F1',
'#B26DF6',
]
option = {
title: {
text: 'ECharts柱状图入门示例',
left: "center",
top: "8%",
textStyle: {
color: '#111111', // 标题颜色
fontWeight: 'bold',
fontSize: 16,
},
},
tooltip: {
trigger: 'axis',
borderWidth: 0,
backgroundColor: 'rgba(0,0,0,0.75)',
color: '#fff',
textStyle: {
color: '#fff'
},
//避免出现多个信息
formatter: function (params) {
return params[0].name + `</br><span style="display:inline-block;width:10px;height:10px;border-radius:5px;background-color:${params[0].color.colorStops[0].color}"></span> ` + params[0].value; // 只显示第一个系列的信息
}
},
toolbox: {
show: true
},
grid: {
top: "15%",
bottom: "10%", //也可设置left和right设置距离来控制图表的大小
},
yAxis: [
{
data: xData,
axisLabel: {
show: false,
},
splitLine: {
show: false,
},
axisTick: {
show: false,
},
axisLine: {
show: false,
},
},
],
xAxis: {
show: true,
splitLine: {
show: false,
},
axisTick: {
show: true,
inside: true,
lineStyle: {
color: '#045d79'
}
},
axisLine: {
show: false,
lineStyle: {
color: '#045d79'
},
},
axisLabel: {
show: false,
// color: 'white' // 将 x 轴文字颜色改为白色
},
axisTick: {
show: false,
},
},
series: [
{
z: 1,
type: 'bar',
data: yData,
barWidth: 20,
zlevel: 1,
showBackground: false,
itemStyle: {
barBorderRadius: [0, 20, 20, 0], // 圆角(左上、右上、右下、左下)
color: function (params) {
var index = params.dataIndex + params.dataIndex;
//每个柱子单独颜色渐变 可多加几个渐变过程 colorStops[{},{},{}]
const colorStops = [{
offset: 1,
color: colorList[index]
}, {
offset: 0,
color: colorList[index + 1]
// color: lightenColor(colors[params.dataIndex], 0.5) // 使用 lightenColor 函数使颜色变浅
// color: hexToRgb(colorList[params.dataIndex % colorList.length], 0.2) // 使用 lightenColor 函数使颜色变浅
}];
return new echarts.graphic.LinearGradient(0, 0, 1, 0, colorStops)
},
},
label: {
normal: {
color: '#000',
show: true,
position: [0, '-20px'],
textStyle: {
fontSize: 12,
color: "#999999",
},
formatter: '{b}',
},
},
},
{
type: 'bar',
data: yData,
barWidth: 20,
barGap: '-100%',
itemStyle: {
normal: {
color: '#f5f8ff',
},
emphasis: {
color: '#f5f8ff',
},
},
label: {
normal: {
color: '#333333',
show: true,
position:'right',
distance: 4,
textStyle: {
fontSize: 14,
fontWeight: "bold"
},
formatter: '{c}',
},
},
},
],
//数据过多纵向滚动
dataZoom: [
{
type: 'inside', // 数据缩放
show: true,
yAxisIndex: 0, // 对应的y轴
start: 0,
end: yData.length > 10 ? 1000 / yData.length : 100 // 初始显示范围,根据需要调整
}
],
};
this.set_option(option)

如此便可以大量使用第三方图表。