废话不多说,先把效果图搞上来。代码写的比较烂,想用的自己直接上手改。
看懂这份代码,基础绘图难不到你。 直接贴代码,主打一个量大管饱。
//绘制几何图形
private settings: RenderingContextSettings = new RenderingContextSettings(true)
//用来创建CanvasRenderingContext2D对象,通过在canvas中调用CanvasRenderingContext2D对象来绘制。
private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings)
private offContext: OffscreenCanvasRenderingContext2D = new OffscreenCanvasRenderingContext2D(600, 600, this.settings)
private xTitles: string[] = ['星期一', '星期二', '星期三', '星期四', '星期五', '星期六', '星期七'];
private yTitles: number[] = [0, 5, 10, 15, 20];
private dataList: number[] = [10, 13, 2, 7, 8, 17, 3];
//绘制折线
@Builder drawLineLayer() {
Column({ space: 20 }) {
Text('折线图-基础功能');
Canvas(this.context)
.backgroundColor(0xF5DC62)
.onReady(() => {
//父视图width: 300 height: 300
let marginRight = 10;
let marginLeft = 30;
let marginTop = 30;
let marginBottom = 30;
let areaWidth = 300.0 - marginLeft - marginRight;
let areaHeight = 300.0 - marginTop - marginBottom
let xWidth = areaWidth / (this.xTitles.length);
let yLabel: number = 300 - 10;
//绘制x轴
//数组最大值
this.context.beginPath()
var pointValues: Point[] = [];
for (let index = 0; index < this.xTitles.length; index++) {
const element = this.xTitles[index];
let x: number = index * xWidth + marginLeft;
this.context.font = '24px';
this.context.textAlign = 'start';
this.context.strokeText(element, x, yLabel);
//绘制贝塞尔曲线-造点
const valueElement = parseFloat(this.dataList[index].toString());
if (valueElement > 0) {
const percentValue = valueElement / 20.0;
const percentY = 300 - marginBottom - percentValue * areaHeight; //valueY
pointValues.push({ x: x, y: percentY });
}
}
//创建路径
let valueLinePath = new Path2D();
if (pointValues.length > 1) {
this.context.beginPath();
let point1 = pointValues[0];
let point2 = pointValues[pointValues.length - 1];
let point0: Point = { x: point1.x, y: 300 - marginBottom };
let pointEnd: Point = { x: point2.x, y: 300 - marginBottom };
pointValues.splice(0, 0, point0);
pointValues.push(pointEnd);
valueLinePath.moveTo(point1.x, point1.y)
for (let index = 0; index < pointValues.length - 3; index++) {
let p0: Point = pointValues[index];
let p1: Point = pointValues[index+1];
let p2: Point = pointValues[index+2];
let p3: Point = pointValues[index+3];
this.getControlPointPath(p0, p1, p2, p3, 300 - marginBottom, valueLinePath);
}
//路径封闭
valueLinePath.lineTo(pointValues[pointValues.length - 1].x, pointValues[pointValues.length - 1].y)
valueLinePath.lineTo(pointValues[0].x, pointValues[0].y)
this.context.strokeStyle = '#13d8c1';
this.context.stroke(valueLinePath)
this.context.fillStyle = "rgb(255,0,0)"
let gradientLayer = this.context.createLinearGradient(pointValues[0].x, pointValues[0].y, pointValues[pointValues.length - 1].x, pointValues[pointValues.length - 1].y);
gradientLayer.addColorStop(0.0, '#ff0000')
gradientLayer.addColorStop(1, '#00ff00')
this.context.fillStyle = gradientLayer //先给图层填充渐变图层
// this.context.fillRect(marginLeft, marginTop, areaWidth, areaHeight)
this.context.fill(valueLinePath, 'evenodd') //对封闭路径进行填充
//删除造的首尾点
pointValues.splice(0, 1);
pointValues.splice(pointValues.length - 1, 1)
for (let index = 0; index < pointValues.length; index++) {
const point = pointValues[index];
this.context.beginPath();
this.context.arc(point.x, point.y, 3, 0, 6.28);
this.context.fillStyle = '#F13153'
this.context.fill();
}
}
//绘制轴线
let lineY = 300 - marginBottom;
let axisLinePath = new Path2D();
axisLinePath.moveTo(marginLeft, lineY);
axisLinePath.lineTo(marginLeft, marginTop);
axisLinePath.moveTo(marginLeft, lineY);
axisLinePath.lineTo(300 - marginRight, lineY);
axisLinePath.closePath();
this.context.strokeStyle = '#999999';
this.context.stroke(axisLinePath)
//绘制y轴
let yAxisHeight = areaHeight / (this.yTitles.length - 1);
for (let index = 0; index < this.yTitles.length; index++) {
const element = this.yTitles[index];
let y: number = 300 - index * yAxisHeight - marginBottom;
this.context.font = '30px #333333';
this.context.strokeStyle = '#0x333333';
this.context.textAlign = 'center';
this.context.strokeText(element.toString(), 15, y);
}
})
}.width(300).height(300)
}
//根据四点获取一个path
private getControlPointPath(p0: Point, p1: Point, p2: Point, p3: Point, maxY: number, path: Path2D) {
let smooth_value = 0.7;
var ctrl1_x;
var ctrl1_y;
var ctrl2_x;
var ctrl2_y;
let xc1 = (p0.x + p0.x) / 2.0;
let yc1 = (p0.y + p1.y) / 2.0;
let xc2 = (p1.x + p2.x) / 2.0;
let yc2 = (p1.y + p2.y) / 2.0;
let xc3 = (p2.x + p3.x) / 2.0;
let yc3 = (p2.x + p3.y) / 2.0;
let len1 = Math.sqrt((p1.x - p0.x) * (p1.x - p0.x) + (p1.y - p0.y) * (p1.y - p0.y));
let len2 = Math.sqrt((p2.x - p1.x) * (p2.x - p1.x) + (p2.y - p1.y) * (p2.y - p1.y));
let len3 = Math.sqrt((p3.x - p2.x) * (p3.x - p2.x) + (p3.y - p2.y) * (p3.y - p2.y));
let k1 = len1 / (len1 + len2);
let k2 = len2 / (len2 + len3);
let xm1 = xc1 + (xc2 - xc1) * k1;
let ym1 = yc1 + (yc2 - yc1) * k1;
let xm2 = xc2 + (xc3 - xc2) * k2;
let ym2 = yc2 + (yc3 - yc2) * k2;
ctrl1_x = xm1 + (xc2 - xm1) * smooth_value + p1.x - xm1;
ctrl1_y = ym1 + (yc2 - ym1) * smooth_value + p1.y - ym1;
ctrl2_x = xm2 + (xc2 - xm2) * smooth_value + p2.x - xm2;
ctrl2_y = ym2 + (yc2 - ym2) * smooth_value + p2.y - ym2;
ctrl1_y = ctrl1_y > maxY ? maxY : ctrl1_y;
ctrl2_y = ctrl2_y > maxY ? maxY : ctrl2_y;
path.bezierCurveTo(ctrl1_x, ctrl1_y, ctrl2_x, ctrl2_y, p2.x, p2.y);
}
嘎嘎嘎,我也是为鸿蒙做贡献的人了。是不是遥遥领先~~~~~