Skip to content

Commit

Permalink
🐞 fix:merge
Browse files Browse the repository at this point in the history
  • Loading branch information
eleliauk committed Aug 30, 2024
2 parents 2aab785 + ea3166f commit 6d1aee2
Show file tree
Hide file tree
Showing 4 changed files with 280 additions and 150 deletions.
1 change: 1 addition & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,4 @@ babel.config.js
ec-canvas

*.js
src/pages/notification/index.tsx
173 changes: 130 additions & 43 deletions src/common/components/chart/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,51 +4,59 @@ import Taro, { CanvasContext, Canvas as CanvasInterface } from '@tarojs/taro';
import React, { CSSProperties, useEffect } from 'react';

interface LineChartProps {
data: number[];
data?: number[];
/** x轴标签 */
xLabels?: string[];
/** 边距 */
padding?: number;
style: CSSProperties;
style?: CSSProperties;
/** y坐标后缀 */
subfix?: string;
/** 线条颜色 */
lineColor?: string;
/** 点颜色 */
dotColor?: string;
className?: string;
/** heightLight 在的比例 */
heightLightPercent?: number;
/** 容器id,默认为lineCanvas */
id?: string;
/** 标题 */
title?: string;
/** 画布宽高 */
width?: number;
height?: number;
}
const DEFAULT_DOT_COLOR = '#0ff';
const DEFAULT_TEXT_COLOR = '#000';
const DEFAULT_LINE_COLOR = '#0ff';
const DEFAULT_HIGHLIGHT_COLOR = '#FFA5007F';
const DEFAULT_TEXT_COLOR = 'orange';
const DEFAULT_LINE_COLOR = 'orange';
const DEFAULT_PADDING = 30;
const DEFAULT_WIDTH = 300;
const DEFAULT_HEIGHT = 150;
const DEFAULT_DATA = [10, 20, 30, 40, 50, 60, 90];
const DEFAULT_X_LABELS = ['周一', '周二', '周三', '周四', '周五', '周六', '周日'];
const DEFAULT_HEIGHT = 200;
const DEFAULT_DATA = [10, 20, 30, 40, 50];
const DEFAULT_X_LABELS = ['0-40', '50-60', '70-80', '80-90', '90-100'];
const DEFAULT_CHART_ID = 'lineCanvas';
const DEFAULT_MARK_LINE_COLOR = '#ccc';
const DEFAULT_MARK_LINE_COLOR = '#cccccc8f';
const BLANK = 20;
const DEFAULT_HEIGHTLIGHT_POS = 1;
const DEFAULT_TITLE = '平均分';

const LineChart: React.FC<LineChartProps> = (props) => {
const {
width: propWidth,
height: propHeight,
heightLightPercent,
id,
data: propData,
className,
lineColor,
dotColor,
padding: propPadding,
xLabels: propX,
title,
style,
subfix,
} = props;
useEffect(() => {
drawLineChart();
}, []);

const drawLineChart = () => {
const query = Taro.createSelectorQuery();
query
Expand All @@ -69,29 +77,52 @@ const LineChart: React.FC<LineChartProps> = (props) => {
const padding = propPadding ?? DEFAULT_PADDING;
const xLabels = propX ?? DEFAULT_X_LABELS;
ctx.clearRect(0, 0, width, height);

// 适配不同比例
if (width / height > 2) {
ctx.scale((height * 2) / width, 1);
} else {
ctx.scale(1, width / 2 / height);
}
const barWidth = (width - 2 * padding) / data.length;
// 背景
drawRoundedRectangle(ctx, 0, 0, width, height, 10, () => null, '#f9f9f2');
// 标识线
ctx.beginPath();
ctx.strokeStyle = DEFAULT_MARK_LINE_COLOR;
ctx.lineWidth = 1;
for (let i = 0; i <= data.length; i++) {
const y = padding + (i * (height - 2 * padding)) / data.length;
ctx.beginPath();
ctx.moveTo(padding, y);
ctx.lineTo(width, y);
ctx.lineTo(width - padding, y);
ctx.stroke();
}

// 坐标轴标签
ctx.fillStyle = DEFAULT_TEXT_COLOR;
ctx.font = '10px sans-serif';
const step = Math.ceil(Math.max(...data) / data.length);
for (let i = 0; i <= data.length; i++) {
const y = height - padding - (i * (height - 2 * padding)) / data.length;
ctx.fillText((i * step).toString() + (subfix ? subfix : ''), 2, y + 3);
}
xLabels.forEach((value, index) => {
const x = padding + index * barWidth + BLANK;
ctx.fillText(value, x - 15, height - 5);
});

// 图
ctx.strokeStyle = lineColor ?? DEFAULT_LINE_COLOR;
ctx.lineWidth = 2;
ctx.lineWidth = 6;
ctx.beginPath();
data.forEach((value, index) => {
const x = padding + (index / (data.length - 1)) * (width - 2 * padding);
const y = height - padding - (value / 70) * (height - 2 * padding);
const x = padding + index * barWidth + BLANK;
const y =
height - padding - (value / (step * data.length)) * (height - 2 * padding);
if (index === 0) {
ctx.moveTo(x, y);
} else {
const prevX = padding + ((index - 1) / (data.length - 1)) * (width - 2 * padding);
const prevX = padding + (index - 1) * barWidth;
const prevY = height - padding - (data[index - 1] / 70) * (height - 2 * padding);
const cp1x = (prevX + x) / 2;
const cp1y = prevY;
Expand All @@ -102,40 +133,96 @@ const LineChart: React.FC<LineChartProps> = (props) => {
});
ctx.stroke();

// 数据点
ctx.fillStyle = dotColor ?? DEFAULT_DOT_COLOR;
data.forEach((value, index) => {
const x = padding + (index / (data.length - 1)) * (width - 2 * padding);
const y = height - padding - (value / 70) * (height - 2 * padding);
ctx.beginPath();
ctx.arc(x, y, 3, 0, 2 * Math.PI);
ctx.fill();
});

// 坐标轴标签
// 高亮
ctx.lineWidth = 1;
const highlightPos = heightLightPercent ?? DEFAULT_HEIGHTLIGHT_POS;
const centerX = padding + barWidth * highlightPos + BLANK;
drawGradientRectangle(
ctx,
centerX - barWidth / 2,
padding - 6,
barWidth,
height - 2 * padding + 6,
5
);
// 高亮文字
ctx.beginPath();
ctx.fillStyle = DEFAULT_TEXT_COLOR;
ctx.font = '10px';
const step = Math.ceil(Math.max(...data) / data.length);
for (let i = 0; i <= data.length; i++) {
const y = height - padding - (i * (height - 2 * padding)) / data.length;
ctx.fillText((i * step).toString(), 5, y + 3);
}
xLabels.forEach((value, index) => {
const x = padding + (index / (xLabels.length - 1)) * (width - 2 * padding);
ctx.fillText(value, x - 3, height - 5);
});
ctx.font = '15px sans-serif';
ctx.fillText(
title ?? DEFAULT_TITLE,
centerX - ctx.measureText(title ?? DEFAULT_TITLE).width / 2,
padding / 2
);
};

return (
<Canvas
id={id ?? DEFAULT_CHART_ID}
width={propWidth + 'px'}
height={propHeight + 'px'}
width={(propWidth ?? DEFAULT_WIDTH + 'px') as string}
height={(propHeight ?? DEFAULT_HEIGHT + 'px') as string}
className={className}
style={style}
style={{
...style,
...{
width: `${propWidth ?? DEFAULT_WIDTH}px`,
height: `${propHeight ?? DEFAULT_HEIGHT}px`,
},
}}
type="2d"
/>
);
};

export default LineChart;

function drawRoundedRectangle(
ctx: Taro.CanvasContext,
x: number,
y: number,
width: number,
height: number,
radius: number,
addtionFn?: (ctx: Taro.CanvasContext) => void,
background?: string
) {
// 确保半径不超过宽度或高度的一半
radius = Math.min(radius, width / 2, height / 2);
addtionFn && addtionFn(ctx);

ctx.beginPath();
ctx.moveTo(x + radius, y);
ctx.lineTo(x + width - radius, y);
ctx.arc(x + width - radius, y + radius, radius, -Math.PI / 2, 0, false);
ctx.lineTo(x + width, y + height - radius);
ctx.arc(x + width - radius, y + height - radius, radius, 0, Math.PI / 2, false);
ctx.lineTo(x + radius, y + height);
ctx.arc(x + radius, y + height - radius, radius, Math.PI / 2, Math.PI, false);
ctx.lineTo(x, y + radius);
ctx.arc(x + radius, y + radius, radius, Math.PI, (Math.PI * 3) / 2, false);
ctx.closePath();
if (background) {
ctx.fillStyle = background;
ctx.strokeStyle = background;
}
ctx.fill();
ctx.stroke(); // 如果需要边框,也可以绘制
}

function drawGradientRectangle(
ctx: Taro.CanvasContext,
x: number,
y: number,
width: number,
height: number,
radius: number
) {
// 创建渐变
drawRoundedRectangle(ctx, x, y, width, height, radius, () => {
const gradient = ctx.createLinearGradient(x, y, x, y + height);
gradient.addColorStop(0, DEFAULT_HIGHLIGHT_COLOR); // 顶部不透明橙色
gradient.addColorStop(1, 'rgba(255, 165, 0, 0)'); // 底部完全透明
// 应用渐变并填充路径
ctx.fillStyle = gradient;
});
}
3 changes: 0 additions & 3 deletions src/pages/classInfo/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,6 @@ function translateCourseProperty(englishDescription) {
}

export default function Index() {
// eslint-disable-next-line react-hooks/rules-of-hooks
const [course, setCourse] = useState<Course | null>(null);

const [courseId, setCourseId] = useState<string | null>(null);
Expand All @@ -76,7 +75,6 @@ export default function Index() {
getParams();
}, []); // 这个 effect 仅在组件挂载时运行一次

// eslint-disable-next-line react-hooks/rules-of-hooks
useEffect(() => {
// eslint-disable-next-line @typescript-eslint/require-await
const getCourseData = async () => {
Expand All @@ -103,7 +101,6 @@ export default function Index() {
).then((res) => {
console.log(res);
setComments(res.data as CommentInfoType[]);
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
});
} catch (error) {
// 错误处理,例如弹出提示
Expand Down
Loading

0 comments on commit 6d1aee2

Please sign in to comment.