refactor(ems/report-charts): 优化折线图配置和样式,提升响应式表现

- 统一各报表折线图的grid布局,添加containLabel确保标签显示完整
- 增强tooltip轴指示器,全部改为cross类型,提升交互体验
- 添加多种类型dataZoom,支持滑块与内置缩放,增强图表缩放控制
- 优化x轴标签显示,超长时间字符串自动截取,长图时旋转标签避免重叠
- y轴添加虚线辅助分割线,完善刻度格式化规则,提升数值可读性
- 降低折线符号尺寸,保持图表整洁,保障不同设备的展示效果
- 使用flex布局替代inline-block,完善图表容器响应式宽高适配
- 添加媒体查询,动态调节图表高度与宽度,适配不同屏幕尺寸
- 重构振动曲线图配置,抽象公共配置对象复用,减少冗余代码
master
zangch@mesnac.com 2 weeks ago
parent bc92f566a9
commit 97d4e685e3

@ -187,28 +187,55 @@ async function getChart() {
right: 0
},
grid: {
top: '40',
bottom: '15%',
left: '3%',
right: '3%'
top: 60,
bottom: 80,
left: 60,
right: 40,
containLabel: true
},
tooltip: {
trigger: 'axis'
},
dataZoom: [{ type: 'slider' }],
dataZoom: [
{ type: 'slider', height: 20, bottom: 10, start: 0, end: 100 },
{ type: 'inside', zoomOnMouseWheel: true, moveOnMouseMove: true }
],
xAxis: {
type: 'category',
data: data.dataList.map((e: any) => e.collectTime),
axisLine: { show: true, lineStyle: { color: '#000' } },
axisLabel: { show: true, textStyle: { color: '#000' } }
axisTick: { alignWithLabel: true },
axisLabel: {
show: true,
color: '#000',
rotate: data.dataList.length > 20 ? 45 : 0,
interval: 'auto',
formatter: (value: string) => {
if (value && value.length > 16) {
return value.substring(11, 19);
}
return value;
}
}
},
yAxis: [{
type: 'value',
name: '数值',
nameTextStyle: { color: '#000' },
splitLine: { show: false },
splitLine: { show: true, lineStyle: { type: 'dashed', color: '#e0e0e0' } },
axisTick: { show: true },
axisLine: { show: true, lineStyle: { color: '#000' } },
axisLabel: { show: true, textStyle: { color: '#000' } }
axisLabel: {
show: true,
color: '#000',
formatter: (value: number) => {
if (Math.abs(value) >= 10000) return (value / 1000).toFixed(1) + 'k';
if (Math.abs(value) >= 1) return value.toFixed(1);
return value.toFixed(2);
}
},
scale: true,
splitNumber: 5
}],
series: [
{
@ -292,11 +319,25 @@ onMounted(() => {
<style scoped>
.chart1 {
width: 100%;
height: 75vh;
height: calc(100vh - 200px);
min-height: 400px;
max-height: 800px;
}
.chart2 {
width: 100%;
height: 40vh;
height: calc(50vh - 100px);
min-height: 300px;
}
@media screen and (max-width: 768px) {
.chart1 {
height: 60vh;
min-height: 300px;
}
.chart2 {
height: 40vh;
min-height: 250px;
}
}
</style>

@ -234,28 +234,32 @@ export default {
initBaseChartOptions() {
this.baseChartOptions = {
grid: {
top: '40',
bottom: '20%',
left: '10%',
right: '3%'
top: 50,
bottom: 70,
left: 20,
right: 20,
containLabel: true
},
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'shadow',
type: 'cross',
label: {
show: true
}
}
},
dataZoom: [{
type: 'slider'
}],
dataZoom: [
{ type: 'slider', height: 18, bottom: 8, start: 0, end: 100 },
{ type: 'inside', zoomOnMouseWheel: true, moveOnMouseMove: true }
],
legend: {
right: 0,
top: 5,
data: ['数据', '停电']
},
xAxis: {
type: 'category',
axisLine: {
show: true,
lineStyle: {
@ -263,19 +267,30 @@ export default {
}
},
axisTick: {
show: true
show: true,
alignWithLabel: true
},
axisLabel: {
show: true,
textStyle: {
color: '#000000'
color: '#000000',
rotate: 45,
interval: 'auto',
formatter: function(value) {
if (value && value.length > 16) {
return value.substring(11, 19);
}
return value;
}
}
},
yAxis: {
type: 'value',
splitLine: {
show: false
show: true,
lineStyle: {
type: 'dashed',
color: '#e0e0e0'
}
},
axisTick: {
show: true
@ -288,10 +303,10 @@ export default {
},
axisLabel: {
show: true,
textStyle: {
color: '#000000'
}
}
color: '#000000'
},
scale: true,
splitNumber: 5
}
}
},
@ -880,22 +895,40 @@ export default {
margin-top: 10px;
}
.chart1 {
width: 50%;
height: 40vh;
display: inline-block;
}
.chart2 {
width: 50%;
height: 40vh;
display: inline-block;
.charts-container {
display: flex;
flex-wrap: wrap;
gap: 10px;
}
.chart1,
.chart2,
.chart3 {
width: 50%;
height: 40vh;
display: inline-block;
flex: 1 1 calc(50% - 10px);
min-width: 400px;
height: calc(45vh - 60px);
min-height: 280px;
max-height: 380px;
}
@media screen and (max-width: 1200px) {
.chart1,
.chart2,
.chart3 {
flex: 1 1 100%;
min-width: 100%;
height: calc(40vh - 50px);
min-height: 260px;
}
}
@media screen and (max-width: 768px) {
.chart1,
.chart2,
.chart3 {
height: 35vh;
min-height: 240px;
}
}
.power-outage-summary {

@ -267,377 +267,117 @@ export default {
}
let query = JSON.parse(JSON.stringify(this.queryParams))
const {data} = await vibrationInstantList(query)
const timeData = data.map(e => e.collectTime);
const chartGridConfig = {
top: 50,
bottom: 70,
left: 20,
right: 20,
containLabel: true
};
const chartDataZoom = [
{ type: 'slider', height: 18, bottom: 8, start: 0, end: 100 },
{ type: 'inside', zoomOnMouseWheel: true, moveOnMouseMove: true }
];
const xAxisConfig = {
type: 'category',
data: timeData,
axisLine: { show: true, lineStyle: { color: '#000000' } },
axisTick: { show: true, alignWithLabel: true },
axisLabel: {
show: true,
color: '#000000',
rotate: timeData.length > 20 ? 45 : 0,
interval: 'auto',
formatter: function(value) {
if (value && value.length > 16) return value.substring(11, 19);
return value;
}
}
};
const createYAxisConfig = (name) => ({
type: 'value',
name: name,
nameTextStyle: { color: '#000000' },
splitLine: { show: true, lineStyle: { type: 'dashed', color: '#e0e0e0' } },
axisTick: { show: true },
axisLine: { show: true, lineStyle: { color: '#000000' } },
axisLabel: { show: true, color: '#000000' },
scale: true,
splitNumber: 5
});
let option1 = {
title: {
text: this.selectMonitorName + ' 速度曲线',
x: 'center'
},
grid: {
top: '40',
bottom: '10%',
left: '10%',
right: '3%'
},
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'shadow',
label: {
show: true
}
}
},
dataZoom: [{
type: 'slider'
}],
legend: {
right: 0
},
xAxis: {
data: data.map(e => e.collectTime),
axisLine: {
show: true, //X线
lineStyle: {
color: '#000000'
}
},
axisTick: {
show: true //X
},
axisLabel: {
show: true,
textStyle: {
color: '#000000' //X
}
}
},
yAxis: [
{
type: 'value',
name: '速度(mm/s)',
nameTextStyle: {
color: '#000000'
},
splitLine: {
show: false
},
axisTick: {
show: true
},
axisLine: {
show: true,
lineStyle: {
color: '#000000'
}
},
axisLabel: {
show: true,
textStyle: {
color: '#000000'
}
}
}
],
series: [
{
name: '速度(mm/s)',
type: 'line',
smooth: true, //线
showAllSymbol: true, //
symbol: 'circle', //
symbolSize: 10, //
// itemStyle: {
// //线
// color: "#058cff",
// },
// lineStyle: {
// color: "#058cff",
// },
// areaStyle: {
// color: "rgba(5,140,255, 0.2)",
// },
data: data.map(e => e.speed)
},
]
title: { text: this.selectMonitorName + ' 速度曲线', x: 'center' },
grid: chartGridConfig,
tooltip: { trigger: 'axis', axisPointer: { type: 'cross', label: { show: true } } },
dataZoom: chartDataZoom,
legend: { right: 0, top: 5 },
xAxis: xAxisConfig,
yAxis: [createYAxisConfig('速度(mm/s)')],
series: [{
name: '速度(mm/s)',
type: 'line',
smooth: true,
showAllSymbol: true,
symbol: 'circle',
symbolSize: 6,
data: data.map(e => e.speed)
}]
}
let option2 = {
title: {
text: this.selectMonitorName + ' 温度曲线',
x: 'center'
},
grid: {
top: '40',
bottom: '10%',
left: '10%',
right: '3%'
},
dataZoom: [{
type: 'slider'
}],
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'shadow',
label: {
show: true
}
}
},
legend: {
right: 0
},
xAxis: {
data: data.map(e => e.collectTime),
axisLine: {
show: true, //X线
lineStyle: {
color: '#000000'
}
},
axisTick: {
show: true //X
},
axisLabel: {
show: true,
textStyle: {
color: '#000000' //X
}
}
},
yAxis: [
{
type: 'value',
name: '温度(℃)',
nameTextStyle: {
color: '#000000'
},
splitLine: {
show: false
},
axisTick: {
show: true
},
axisLine: {
show: true,
lineStyle: {
color: '#000000'
}
},
axisLabel: {
show: true,
textStyle: {
color: '#000000'
}
}
}
],
series: [
{
name: '温度(℃)',
type: 'line',
smooth: true, //线
showAllSymbol: true, //
symbol: 'circle', //
symbolSize: 10, //
// itemStyle: {
// //线
// color: "#058cff",
// },
// lineStyle: {
// color: "#058cff",
// },
// areaStyle: {
// color: "rgba(5,140,255, 0.2)",
// },
data: data.map(e => e.temperature)
},
]
title: { text: this.selectMonitorName + ' 温度曲线', x: 'center' },
grid: chartGridConfig,
dataZoom: chartDataZoom,
tooltip: { trigger: 'axis', axisPointer: { type: 'cross', label: { show: true } } },
legend: { right: 0, top: 5 },
xAxis: xAxisConfig,
yAxis: [createYAxisConfig('温度(℃)')],
series: [{
name: '温度(℃)',
type: 'line',
smooth: true,
showAllSymbol: true,
symbol: 'circle',
symbolSize: 6,
data: data.map(e => e.temperature)
}]
}
let option3 = {
title: {
text: this.selectMonitorName + ' 位移曲线',
x: 'center'
},
grid: {
top: '40',
bottom: '10%',
left: '10%',
right: '3%'
},
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'shadow',
label: {
show: true
}
}
},
dataZoom: [{
type: 'slider'
}],
legend: {
right: 0
},
xAxis: {
data: data.map(e => e.collectTime),
axisLine: {
show: true, //X线
lineStyle: {
color: '#000000'
}
},
axisTick: {
show: true //X
},
axisLabel: {
show: true,
textStyle: {
color: '#000000' //X
}
}
},
yAxis: [
{
type: 'value',
name: '位移(um)',
nameTextStyle: {
color: '#000000'
},
splitLine: {
show: false
},
axisTick: {
show: true
},
axisLine: {
show: true,
lineStyle: {
color: '#000000'
}
},
axisLabel: {
show: true,
textStyle: {
color: '#000000'
}
}
}
],
series: [
{
name: '位移(um)',
type: 'line',
smooth: true, //线
showAllSymbol: true, //
symbol: 'circle', //
symbolSize: 10, //
// itemStyle: {
// //线
// color: "#058cff",
// },
// lineStyle: {
// color: "#058cff",
// },
// areaStyle: {
// color: "rgba(5,140,255, 0.2)",
// },
data: data.map(e => e.displacement)
},
]
title: { text: this.selectMonitorName + ' 位移曲线', x: 'center' },
grid: chartGridConfig,
tooltip: { trigger: 'axis', axisPointer: { type: 'cross', label: { show: true } } },
dataZoom: chartDataZoom,
legend: { right: 0, top: 5 },
xAxis: xAxisConfig,
yAxis: [createYAxisConfig('位移(um)')],
series: [{
name: '位移(um)',
type: 'line',
smooth: true,
showAllSymbol: true,
symbol: 'circle',
symbolSize: 6,
data: data.map(e => e.displacement)
}]
}
let option4 = {
title: {
text: this.selectMonitorName + ' 加速度曲线',
x: 'center'
},
grid: {
top: '40',
bottom: '10%',
left: '10%',
right: '3%'
},
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'shadow',
label: {
show: true
}
}
},
dataZoom: [{
type: 'slider'
}],
legend: {
right: 0
},
xAxis: {
data: data.map(e => e.collectTime),
axisLine: {
show: true, //X线
lineStyle: {
color: '#000000'
}
},
axisTick: {
show: true //X
},
axisLabel: {
show: true,
textStyle: {
color: '#000000' //X
}
}
},
yAxis: [
{
type: 'value',
name: '加速度(g)',
nameTextStyle: {
color: '#000000'
},
splitLine: {
show: false
},
axisTick: {
show: true
},
axisLine: {
show: true,
lineStyle: {
color: '#000000'
}
},
axisLabel: {
show: true,
textStyle: {
color: '#000000'
}
}
}
],
series: [
{
name: '加速度(g)',
type: 'line',
smooth: true, //线
showAllSymbol: true, //
symbol: 'circle', //
symbolSize: 10, //
// itemStyle: {
// color: "#058cff",
// },
// lineStyle: {
// color: "#058cff",
// },
// areaStyle: {
// color: "rgba(5,140,255, 0.2)",
// },
data: data.map(e => e.acceleration)
},
]
title: { text: this.selectMonitorName + ' 加速度曲线', x: 'center' },
grid: chartGridConfig,
tooltip: { trigger: 'axis', axisPointer: { type: 'cross', label: { show: true } } },
dataZoom: chartDataZoom,
legend: { right: 0, top: 5 },
xAxis: xAxisConfig,
yAxis: [createYAxisConfig('加速度(g)')],
series: [{
name: '加速度(g)',
type: 'line',
smooth: true,
showAllSymbol: true,
symbol: 'circle',
symbolSize: 6,
data: data.map(e => e.acceleration)
}]
}
this.$refs.Chart1.setData(option1)
this.$refs.Chart2.setData(option2)
@ -693,24 +433,36 @@ export default {
}
</script>
<style scoped>
.chart1 {
width: 50%;
height: 40vh;
display: inline-block;
}
.chart2 {
width: 50%;
height: 40vh;
display: inline-block;
}
.chart3 {
width: 50%;
height: 40vh;
display: inline-block;
}
.chart1,
.chart2,
.chart3,
.chart4 {
width: 50%;
display: inline-block;
height: 40vh;
width: calc(50% - 5px);
height: calc(45vh - 60px);
min-height: 280px;
max-height: 380px;
vertical-align: top;
}
@media screen and (max-width: 1200px) {
.chart1,
.chart2,
.chart3,
.chart4 {
width: 100%;
height: calc(40vh - 50px);
min-height: 260px;
}
}
@media screen and (max-width: 768px) {
.chart1,
.chart2,
.chart3,
.chart4 {
height: 35vh;
min-height: 240px;
}
}
</style>

@ -167,65 +167,91 @@ async function getChart() {
const currentOption: EChartsOption = {
title: { text: `${selectMonitorName.value} 电流曲线`, left: 'center' },
grid: { top: '15%', bottom: '10%', left: '3%', right: '3%' },
grid: { top: 50, bottom: 70, left: 60, right: 40, containLabel: true },
tooltip: {
trigger: 'axis',
axisPointer: { type: 'shadow', label: { show: true } }
axisPointer: { type: 'cross', label: { show: true } }
},
dataZoom: [{ type: 'slider', start: 0, end: 100 }],
legend: { right: 0 },
dataZoom: [
{ type: 'slider', height: 20, bottom: 8, start: 0, end: 100 },
{ type: 'inside', zoomOnMouseWheel: true, moveOnMouseMove: true }
],
legend: { right: 0, top: 5 },
xAxis: {
type: 'category',
data: collectTimes,
axisLine: { lineStyle: { color: '#000' } },
axisTick: { show: true },
axisLabel: { color: '#000' }
axisTick: { show: true, alignWithLabel: true },
axisLabel: {
color: '#000',
rotate: collectTimes.length > 20 ? 45 : 0,
interval: 'auto',
formatter: (value: string) => value && value.length > 16 ? value.substring(11, 19) : value
}
},
yAxis: [{
type: 'value',
name: '电流A',
nameTextStyle: { color: '#000' },
splitLine: { show: false },
splitLine: { show: true, lineStyle: { type: 'dashed', color: '#e0e0e0' } },
axisTick: { show: true },
axisLine: { lineStyle: { color: '#000' } },
axisLabel: { color: '#000' }
axisLabel: {
color: '#000',
formatter: (value: number) => Math.abs(value) >= 1000 ? (value / 1000).toFixed(1) + 'k' : value.toFixed(1)
},
scale: true,
splitNumber: 5
}],
series: [
{ name: 'A相电流', type: 'line', smooth: true, symbol: 'circle', symbolSize: 10, data: data.map((item: any) => item.ia) },
{ name: 'B相电流', type: 'line', smooth: true, symbol: 'circle', symbolSize: 10, data: data.map((item: any) => item.ib) },
{ name: 'C相电流', type: 'line', smooth: true, symbol: 'circle', symbolSize: 10, data: data.map((item: any) => item.ic) }
{ name: 'A相电流', type: 'line', smooth: true, symbol: 'circle', symbolSize: 6, data: data.map((item: any) => item.ia) },
{ name: 'B相电流', type: 'line', smooth: true, symbol: 'circle', symbolSize: 6, data: data.map((item: any) => item.ib) },
{ name: 'C相电流', type: 'line', smooth: true, symbol: 'circle', symbolSize: 6, data: data.map((item: any) => item.ic) }
]
};
const voltageOption: EChartsOption = {
title: { text: `${selectMonitorName.value} 电压曲线`, left: 'center' },
grid: { top: '15%', bottom: '10%', left: '3%', right: '3%' },
grid: { top: 50, bottom: 70, left: 60, right: 40, containLabel: true },
tooltip: {
trigger: 'axis',
axisPointer: { type: 'shadow', label: { show: true } }
axisPointer: { type: 'cross', label: { show: true } }
},
dataZoom: [{ type: 'slider', start: 0, end: 100 }],
legend: { right: 0 },
dataZoom: [
{ type: 'slider', height: 20, bottom: 8, start: 0, end: 100 },
{ type: 'inside', zoomOnMouseWheel: true, moveOnMouseMove: true }
],
legend: { right: 0, top: 5 },
xAxis: {
type: 'category',
data: collectTimes,
axisLine: { lineStyle: { color: '#000' } },
axisTick: { show: true },
axisLabel: { color: '#000' }
axisTick: { show: true, alignWithLabel: true },
axisLabel: {
color: '#000',
rotate: collectTimes.length > 20 ? 45 : 0,
interval: 'auto',
formatter: (value: string) => value && value.length > 16 ? value.substring(11, 19) : value
}
},
yAxis: [{
type: 'value',
name: '电压V',
nameTextStyle: { color: '#000' },
splitLine: { show: false },
splitLine: { show: true, lineStyle: { type: 'dashed', color: '#e0e0e0' } },
axisTick: { show: true },
axisLine: { lineStyle: { color: '#000' } },
axisLabel: { color: '#000' }
axisLabel: {
color: '#000',
formatter: (value: number) => Math.abs(value) >= 1000 ? (value / 1000).toFixed(1) + 'k' : value.toFixed(1)
},
scale: true,
splitNumber: 5
}],
series: [
{ name: 'A相电压', type: 'line', smooth: true, symbol: 'circle', symbolSize: 10, data: data.map((item: any) => item.va) },
{ name: 'B相电压', type: 'line', smooth: true, symbol: 'circle', symbolSize: 10, data: data.map((item: any) => item.vb) },
{ name: 'C相电压', type: 'line', smooth: true, symbol: 'circle', symbolSize: 10, data: data.map((item: any) => item.vc) }
{ name: 'A相电压', type: 'line', smooth: true, symbol: 'circle', symbolSize: 6, data: data.map((item: any) => item.va) },
{ name: 'B相电压', type: 'line', smooth: true, symbol: 'circle', symbolSize: 6, data: data.map((item: any) => item.vb) },
{ name: 'C相电压', type: 'line', smooth: true, symbol: 'circle', symbolSize: 6, data: data.map((item: any) => item.vc) }
]
};
@ -270,14 +296,28 @@ onMounted(() => {
getList();
});
</script>
<style>
.chart1 {
width: 100%;
height: 40vh;
}
<style scoped>
.chart1,
.chart2 {
width: 100%;
height: 40vh;
height: calc(50vh - 80px);
min-height: 280px;
max-height: 400px;
}
@media screen and (max-width: 1200px) {
.chart1,
.chart2 {
height: calc(45vh - 60px);
min-height: 250px;
}
}
@media screen and (max-width: 768px) {
.chart1,
.chart2 {
height: 40vh;
min-height: 220px;
}
}
</style>

Loading…
Cancel
Save