当前位置: 首页 > news >正文

微网站建设包括哪些方面响应式表白网站源码

微网站建设包括哪些方面,响应式表白网站源码,软文写作模板,汕头市建设局造价信息网站本节笔者带领读者实现一个饼状图 PieChart 组件,该组件是根据笔者之前封装的 MiniCanvas 实现的, PieChart 的最终演示效果如下图所示: 饼状图实现的拆分 根据上图的样式效果,实现一个饼状图,实质就是绘制一个个的实…

本节笔者带领读者实现一个饼状图 PieChart 组件,该组件是根据笔者之前封装的 MiniCanvas 实现的, PieChart 的最终演示效果如下图所示:
PieChart

饼状图实现的拆分

根据上图的样式效果,实现一个饼状图,实质就是绘制一个个的实心圆弧加上圆弧对应颜色就搞定了,圆弧的大小是根据饼状的数据分布计算出来的,对应的颜色自己指定就可以了,其次手指点击到饼状图,需要找到对应的饼状块并突出显示,找到饼状块先计算手指点击坐标和圆弧中心的夹角,根据夹角和每个圆弧的大小找到对应的圆弧,找到圆弧后计算圆弧的突出偏移量并重置所有饼状块的圆弧起始值就可以了。

  • 计算夹角
    计算夹角就是计算手指点击饼状图上的坐标 (x, y) 和饼状图的圆心坐标 (centerX, centerY) 之间的顺时针角度,计算方法如下所示:
private getTouchedAngle(centerX: number, centerY, x: number, y: number) {var deltaX = x - centerX;var deltaY = centerY - y;var t = deltaY / Math.sqrt(deltaX * deltaX + deltaY * deltaY);var angle = 0;if (deltaX > 0) {if (deltaY > 0) {angle = Math.asin(t);} else {angle = Math.PI * 2 + Math.asin(t);}} else if (deltaY > 0) {angle = Math.PI - Math.asin(t);} else {angle = Math.PI - Math.asin(t);}return 360 - (angle * 180 / Math.PI) % 360;
}
  • 找圆弧块
    计算出手指点击位置和圆心的夹角后,遍历每一个饼状块做比较就可以了,代码如下所示:
private getTouchedPieItem(angle: number): PieItem {for(var i = 0; i < this.pieItems.length; i++) {var item = this.pieItems[i];if(item.getStopAngle() < 360) {if(angle >= item.getStartAngle() && angle < item.getStopAngle()) {return item;}} else {if(angle >= item.getStartAngle() && angle < 360 || (angle >= 0 && angle < item.getStopAngle() - 360)) {return item;}}}return null;
}
  • 计算偏移量
    找到圆弧块后,根据圆弧块的圆弧大小,计算出该圆弧突出后的偏移量,代码如下所示:
private calculateRoteAngle(item: PieItem): number {var result = item.getStartAngle() + item.getAngle() / 2 + this.getDirectionAngle();if (result >= 360) {result -= 360;}if (result <= 180) {result = -result;} else {result = 360 - result;}return result;
}
  • 重置偏移量
    有了目标圆弧块的偏移角度后,重置每一个圆弧块的起始偏移量就可以了,代码如下所示:
private resetStartAngle(angle: number) {this.pieItems.forEach((item) => {item.setSelected(false);item.setStartAngle(item.getStartAngle() + angle);});
}
  • 重新绘制圆弧
    绘制圆弧使用 MiniCanvas 提供的 drawArc() 方法即可,代码如下所示:
drawPieItem() {this.pieItems.forEach((item) => {this.paint.setColor(item.color);var x = this.calculateCenterX(item.isSelected());var y = this.calculateCenterY(item.isSelected());this.canvas.drawArc(x, y, this.radius, item.getStartAngle(), item.getStopAngle(), this.paint);})
}

饼状图的实现

拆分完饼状图的步骤后,实现起来就方便多了, PieChart 的完整代码如下所示:

import { MiniCanvas, Paint, ICanvas } from './icanvas'@Entry @Component struct PieChart {private delegate: PieChartDelegate;build() {Column() {MiniCanvas({attribute: {width: this.delegate.calculateWidth(),height: this.delegate.calculateHeight(),clickListener: (event) => {// 根据点击绘制突出的饼状块this.delegate.onClicked(event.x, event.y);}},onDraw: (canvas) => {// 开始绘制this.delegate.setCanvas(canvas);this.delegate.drawPieItem();}})}.padding(10).size({width: "100%", height: "100%"})}aboutToAppear() {// mock测试数据var pieItems = PieItem.mock();// 初始化delegatethis.delegate = new PieChartDelegate(pieItems, RotateDirection.BOTTOM);}
}// 定义饼状块的属性,包括角度,起始角度,占比,颜色,是否选中突出
export class PieItem {private startAngle: number = 0;private rate: number = 0;private angle: number = 0;private selected: boolean = false;constructor(public count: number, public color: string) {}setSelected(selected: boolean) {this.selected = selected;return this;}isSelected() {return this.selected;}setStartAngle(startAngle: number) {this.startAngle = startAngle > 360 ? startAngle - 360 : startAngle < 0 ? 360 + startAngle : startAngle;return this;}getStartAngle() {return this.startAngle;}getStopAngle() {return  this.startAngle + this.angle;}setRate(rate: number) {this.rate = rate;return this;}getRate() {return this.rate;}setAngle(angle: number) {this.angle = angle;return this;}getAngle() {return this.angle;}// mock一份测试数据static mock(): Array<PieItem> {var pieItems = new Array<PieItem>();pieItems.push(new PieItem(21, "#6A5ACD"))pieItems.push(new PieItem(18, "#20B2AA"))pieItems.push(new PieItem(29, "#FFFF00"))pieItems.push(new PieItem(12, "#00BBFF"))pieItems.push(new PieItem(20, "#DD5C5C"))pieItems.push(new PieItem(13, "#8B668B"))return pieItems;}
}// 饼状块的突出方向
export enum RotateDirection {LEFT,TOP,RIGHT,BOTTOM
}// 饼状图绘制的具体实现类
class PieChartDelegate {private paint: Paint;private canvas: ICanvas;constructor(private pieItems: Array<PieItem>, private direction: RotateDirection = RotateDirection.BOTTOM, private offset: number = 10, private radius: number = 80) {this.calculateItemAngle();}setPitItems(pieItems: Array<PieItem>) {this.pieItems = pieItems;}setCanvas(canvas: ICanvas) {this.canvas = canvas;this.paint = new Paint();}onClicked(x: number, y: number) {if(this.canvas) {var touchedAngle = this.getTouchedAngle(this.radius, this.radius, x, y);var touchedItem = this.getTouchedPieItem(touchedAngle);if(touchedItem) {var rotateAngle = this.calculateRoteAngle(touchedItem);this.resetStartAngle(rotateAngle);touchedItem.setSelected(true)this.clearCanvas();this.drawPieItem();}} else {console.warn("canvas invalid!!!")}}clearCanvas() {this.canvas.clear();}drawPieItem() {this.pieItems.forEach((item) => {this.paint.setColor(item.color);var x = this.calculateCenterX(item.isSelected());var y = this.calculateCenterY(item.isSelected());this.canvas.drawArc(x, y, this.radius, item.getStartAngle(), item.getStopAngle(), this.paint);})}calculateWidth(): number {if (this.direction == RotateDirection.LEFT || this.direction == RotateDirection.RIGHT) {return this.radius * 2 + this.offset;} else {return this.radius * 2;}}calculateHeight(): number {if (this.direction == RotateDirection.TOP || this.direction == RotateDirection.BOTTOM) {return this.radius * 2 + this.offset;} else {return this.radius * 2;}}private calculateCenterX(hint: boolean): number {if(this.direction == RotateDirection.LEFT) {return hint ? this.radius : this.radius + this.offset;} else if(this.direction == RotateDirection.TOP) {return this.radius;} else if(this.direction == RotateDirection.RIGHT) {return hint ? this.radius + this.offset : this.radius;} else {return this.radius;}}private calculateCenterY(hint: boolean): number {if(this.direction == RotateDirection.LEFT) {return this.radius;} else if(this.direction == RotateDirection.TOP) {return hint ? this.radius : this.radius + this.offset;} else if(this.direction == RotateDirection.RIGHT) {return this.radius;} else {return hint ? this.radius + this.offset : this.radius;}}private resetStartAngle(angle: number) {this.pieItems.forEach((item) => {item.setSelected(false);item.setStartAngle(item.getStartAngle() + angle);});}private calculateRoteAngle(item: PieItem): number {var result = item.getStartAngle() + item.getAngle() / 2 + this.getDirectionAngle();if (result >= 360) {result -= 360;}if (result <= 180) {result = -result;} else {result = 360 - result;}return result;}private calculateItemAngle() {var total = 0;this.pieItems.forEach((item) => {total += item.count;})for(var i = 0; i < this.pieItems.length; i++) {var data = this.pieItems[i];data.setRate(data.count / total);data.setAngle(data.getRate() * 360);if (i == 0) {data.setStartAngle(0);} else {var preData = this.pieItems[i - 1];data.setStartAngle(preData.getStopAngle());}}}private getDirectionAngle(): number {var result = 270;if (this.direction == RotateDirection.RIGHT) {result = 0;}if (this.direction == RotateDirection.BOTTOM) {result = 270;}if (this.direction == RotateDirection.LEFT) {result = 180;}if (this.direction == RotateDirection.TOP) {result = 90;}return result;}private getTouchedAngle(centerX: number, centerY, x: number, y: number) {var deltaX = x - centerX;var deltaY = centerY - y;var t = deltaY / Math.sqrt(deltaX * deltaX + deltaY * deltaY);var angle = 0;if (deltaX > 0) {if (deltaY > 0) {angle = Math.asin(t);} else {angle = Math.PI * 2 + Math.asin(t);}} else if (deltaY > 0) {angle = Math.PI - Math.asin(t);} else {angle = Math.PI - Math.asin(t);}return 360 - (angle * 180 / Math.PI) % 360;}private getTouchedPieItem(angle: number): PieItem {for(var i = 0; i < this.pieItems.length; i++) {var item = this.pieItems[i];if(item.getStopAngle() < 360) {if(angle >= item.getStartAngle() && angle < item.getStopAngle()) {return item;}} else {if(angle >= item.getStartAngle() && angle < 360 || (angle >= 0 && angle < item.getStopAngle() - 360)) {return item;}}}return null;}
}

以上就是笔者介绍的实现一个饼状图的思路和实现,读者可以阅读源码,目前 PieChart 在选中饼状块并突出时没有动画特效而是直接旋转过来了,后续笔者会把旋转的动效加上。

http://www.yayakq.cn/news/873826/

相关文章:

  • wordpress文章获取接口seo的含义是什么意思
  • 青羊区定制网站建设报价源服务器发生5xx错误
  • 做剧情网站侵权吗运城又一暂停通知
  • 阿里云 oss做网站黄石市seo关键词优化怎么做
  • 黄石做网站建设的辽宁建设工程造价管理网站
  • 网站项目计划书公司网页设计图
  • 太原网站制作优化seo公司网站制作苏州企业
  • 给网站首页图片做外网超链接_为什么会弹出一个服务器登录窗口公司网站制作策划
  • 进口食品销售销售在那个网站做深圳罗湖企业网站建设
  • 网站如何做数据库北京网站设计工资多少
  • 广州网站改版设计制作搜索引擎的营销方法有哪些
  • 网站换模板怎样做有趣的视频网站
  • 巩义网站phpcms仿行业网站
  • 琪恋网站建设做网站代码审计哪个工具比较好
  • 西宁网站制作公司wordpress 双首页
  • 网站开发必备人员普斯泰网站建设
  • 淄博网站建设排行榜东莞网站建设公司排名
  • 重庆奉节网站建设公司哪里有合肥建网站要多少钱
  • 泰州哪里做网站福州网站改版
  • 网站建设的商品分类编码长链接转短链接生成器
  • 建网站选服务器网站对比分析
  • 网上注册公司什么网站渝快办官方网站
  • 北碚区建设银行网站一个主机域名可以做多少个网站
  • flash源码网站猫扑网站开发的网游
  • 濮阳免费网站制作网站开发设计的技术
  • 网站开发好公司外贸局合并到哪个局
  • 什么叫宣传型网站营销网站建设专业团队在线服务
  • 建网站 服务器需要安装 tomcat什么是交换链接
  • 国外响应式网站网站页面
  • 用手机可以做网站吗网站打开空白页面