feat(miniprogram): 温润东方风全面 UI 重设计
73 文件变更,覆盖全部 40 个页面 SCSS + TabBar 图标 + 组件样式。 统一赤陶主色 #C4623A + 暖米背景 + 衬线标题字体 + 12px 圆角体系。
This commit is contained in:
98
apps/miniprogram/src/components/EcCanvas/index.tsx
Normal file
98
apps/miniprogram/src/components/EcCanvas/index.tsx
Normal file
@@ -0,0 +1,98 @@
|
||||
import React, { useEffect, useRef, forwardRef, useImperativeHandle } from 'react';
|
||||
import { Canvas, View } from '@tarojs/components';
|
||||
import Taro from '@tarojs/taro';
|
||||
import * as echarts from 'echarts/core';
|
||||
import { LineChart } from 'echarts/charts';
|
||||
import {
|
||||
GridComponent,
|
||||
TooltipComponent,
|
||||
MarkAreaComponent,
|
||||
MarkPointComponent,
|
||||
} from 'echarts/components';
|
||||
import { CanvasRenderer } from 'echarts/renderers';
|
||||
|
||||
echarts.use([
|
||||
LineChart,
|
||||
GridComponent,
|
||||
TooltipComponent,
|
||||
MarkAreaComponent,
|
||||
MarkPointComponent,
|
||||
CanvasRenderer,
|
||||
]);
|
||||
|
||||
interface EcCanvasProps {
|
||||
canvasId: string;
|
||||
height?: number;
|
||||
}
|
||||
|
||||
export interface EcCanvasRef {
|
||||
setOption: (option: echarts.EChartsOption) => void;
|
||||
}
|
||||
|
||||
const EcCanvas = forwardRef<EcCanvasRef, EcCanvasProps>(
|
||||
({ canvasId, height = 300 }, ref) => {
|
||||
const chartInstance = useRef<echarts.ECharts | null>(null);
|
||||
const canvasNode = useRef<any>(null);
|
||||
|
||||
const initChart = async () => {
|
||||
try {
|
||||
const query = Taro.createSelectorQuery();
|
||||
query
|
||||
.select(`#${canvasId}`)
|
||||
.node()
|
||||
.exec((res) => {
|
||||
const node = res[0]?.node;
|
||||
if (!node) return;
|
||||
|
||||
canvasNode.current = node;
|
||||
const dpr = Taro.getSystemInfoSync().pixelRatio;
|
||||
const width = node.width || 350;
|
||||
const heightVal = node.height || height;
|
||||
|
||||
node.width = width * dpr;
|
||||
node.height = heightVal * dpr;
|
||||
|
||||
const ctx = node.getContext('2d');
|
||||
|
||||
chartInstance.current = echarts.init(ctx as any, undefined, {
|
||||
renderer: 'canvas',
|
||||
width,
|
||||
height: heightVal,
|
||||
devicePixelRatio: dpr,
|
||||
});
|
||||
});
|
||||
} catch (e) {
|
||||
console.error('EcCanvas init failed:', e);
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
initChart();
|
||||
return () => {
|
||||
chartInstance.current?.dispose();
|
||||
};
|
||||
}, []);
|
||||
|
||||
useImperativeHandle(ref, () => ({
|
||||
setOption: (option: echarts.EChartsOption) => {
|
||||
if (chartInstance.current) {
|
||||
chartInstance.current.setOption(option);
|
||||
}
|
||||
},
|
||||
}));
|
||||
|
||||
return (
|
||||
<View style={{ width: '100%', height: `${height}rpx` }}>
|
||||
<Canvas
|
||||
type='2d'
|
||||
id={canvasId}
|
||||
style={{ width: '100%', height: '100%' }}
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
EcCanvas.displayName = 'EcCanvas';
|
||||
|
||||
export default EcCanvas;
|
||||
@@ -1,6 +1,7 @@
|
||||
import React, { useEffect, useRef, useCallback } from 'react';
|
||||
import { View, Text } from '@tarojs/components';
|
||||
import { EChart } from 'echarts-taro3-react';
|
||||
import EcCanvas from '../EcCanvas';
|
||||
import type { EcCanvasRef } from '../EcCanvas';
|
||||
import './index.scss';
|
||||
|
||||
interface TrendChartProps {
|
||||
@@ -11,8 +12,14 @@ interface TrendChartProps {
|
||||
height?: number;
|
||||
}
|
||||
|
||||
export default function TrendChart({ data, referenceMin, referenceMax, unit = '', height = 500 }: TrendChartProps) {
|
||||
const chartRef = useRef<any>(null);
|
||||
export default function TrendChart({
|
||||
data,
|
||||
referenceMin,
|
||||
referenceMax,
|
||||
unit = '',
|
||||
height = 500,
|
||||
}: TrendChartProps) {
|
||||
const chartRef = useRef<EcCanvasRef>(null);
|
||||
|
||||
const getOption = useCallback(() => {
|
||||
if (!data || data.length === 0) return null;
|
||||
@@ -21,10 +28,15 @@ export default function TrendChart({ data, referenceMin, referenceMax, unit = ''
|
||||
const markArea: any = {};
|
||||
|
||||
if (referenceMin != null && referenceMax != null) {
|
||||
markArea.data = [[
|
||||
{ yAxis: referenceMin, itemStyle: { color: 'rgba(5,150,105,0.08)' } },
|
||||
{ yAxis: referenceMax },
|
||||
]];
|
||||
markArea.data = [
|
||||
[
|
||||
{
|
||||
yAxis: referenceMin,
|
||||
itemStyle: { color: 'rgba(5,150,105,0.08)' },
|
||||
},
|
||||
{ yAxis: referenceMax },
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
series.push({
|
||||
@@ -35,17 +47,34 @@ export default function TrendChart({ data, referenceMin, referenceMax, unit = ''
|
||||
symbolSize: 6,
|
||||
lineStyle: { color: '#0891B2', width: 2 },
|
||||
itemStyle: { color: '#0891B2' },
|
||||
areaStyle: { color: { type: 'linear', x: 0, y: 0, x2: 0, y2: 1, colorStops: [{ offset: 0, color: 'rgba(8,145,178,0.15)' }, { offset: 1, color: 'rgba(8,145,178,0.01)' }] } },
|
||||
markArea: markArea.data ? { silent: true, data: markArea.data } : undefined,
|
||||
markPoint: (referenceMin != null && referenceMax != null) ? {
|
||||
data: data
|
||||
.filter((d) => d.value < referenceMin || d.value > referenceMax)
|
||||
.map((d) => ({
|
||||
coord: [data.indexOf(d), d.value],
|
||||
itemStyle: { color: '#DC2626' },
|
||||
symbolSize: 12,
|
||||
})),
|
||||
} : undefined,
|
||||
areaStyle: {
|
||||
color: {
|
||||
type: 'linear',
|
||||
x: 0,
|
||||
y: 0,
|
||||
x2: 0,
|
||||
y2: 1,
|
||||
colorStops: [
|
||||
{ offset: 0, color: 'rgba(8,145,178,0.15)' },
|
||||
{ offset: 1, color: 'rgba(8,145,178,0.01)' },
|
||||
],
|
||||
},
|
||||
},
|
||||
markArea: markArea.data
|
||||
? { silent: true, data: markArea.data }
|
||||
: undefined,
|
||||
markPoint:
|
||||
referenceMin != null && referenceMax != null
|
||||
? {
|
||||
data: data
|
||||
.filter((d) => d.value < referenceMin || d.value > referenceMax)
|
||||
.map((d) => ({
|
||||
coord: [data.indexOf(d), d.value],
|
||||
itemStyle: { color: '#DC2626' },
|
||||
symbolSize: 12,
|
||||
})),
|
||||
}
|
||||
: undefined,
|
||||
});
|
||||
|
||||
return {
|
||||
@@ -77,7 +106,7 @@ export default function TrendChart({ data, referenceMin, referenceMax, unit = ''
|
||||
if (chartRef.current && data && data.length > 0) {
|
||||
const option = getOption();
|
||||
if (option) {
|
||||
chartRef.current.refresh(option);
|
||||
chartRef.current.setOption(option);
|
||||
}
|
||||
}
|
||||
}, [data, getOption]);
|
||||
@@ -92,7 +121,7 @@ export default function TrendChart({ data, referenceMin, referenceMax, unit = ''
|
||||
|
||||
return (
|
||||
<View className='trend-chart' style={{ height: `${height}rpx` }}>
|
||||
<EChart canvasId='trend-chart-canvas' ref={chartRef} />
|
||||
<EcCanvas canvasId='trend-chart-canvas' ref={chartRef} height={height} />
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user