如何在Angular2中使用SVG自定义图表
作者
如何在Angular2中使用SVG自定义图表?针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。
demo:
html:
<ngo-chart[inputParams]="options"></ngo-chart>
ts:
options={ type:'line',//图表类型 xAxis:{//X轴的数据 data:['Mon','Tue','Wed','Thu','Fri','Sat','Sun'] }, yAxis:{//X轴的数据 data:[120,220,150,111,-150,55,60], }, width:600,//宽 height:500,//高 dataPadding:8//条形图之间的距离 };
效果:
源代码:
import{ Input, OnInit, ViewChild, Component, ViewEncapsulation, ElementRef, AfterViewInit, ChangeDetectorRef, }from'@angular/core'; import{NgoChartSvgParams,Scale,Axis,Chart}from'./chart-svg-params'; @Component({ selector:'ngo-chart-svg', templateUrl:'./chart-svg.html', styleUrls:['./chart-svg.scss'], encapsulation:ViewEncapsulation.Native }) exportclassNgoChartSvgimplementsOnInit,AfterViewInit{ @Input()inputParams:NgoChartSvgParams; @ViewChild('svg')svg:ElementRef; @ViewChild('polyline')polyline:ElementRef; params:NgoChartSvgParams; AxisY:Axis;//Y轴 AxisX:Axis;//X轴 valueToPxRatio:number;//值转px的比率 Y0:number;//坐标轴(0,0)的Y轴 Yscale:Array<Scale>=[];//Y轴刻度值 Xscale:Array<Scale>=[];//X轴刻度值 XgapWidth:number;//X轴刻度之间的间隙宽度 data:Array<Chart>=[]; color:string; type:string; polyLinePoints:string; polyLineLength:number; constructor( privateele:ElementRef, privatecd:ChangeDetectorRef ){} ... ngOnInit(){ this.initParams(); constsvg=this.svg.nativeElement; const_width=this.params.width; const_height=this.params.height; svg.setAttribute('width',_width); svg.setAttribute('height',_height); //绘制y轴 this.drawAxisY(); this.drawScaleY(); //绘制x轴 this.drawAxisX(); this.drawScaleX(); this.drawRect(); if(this.params.type==='line'){ this.drawLine(); } } ngAfterViewInit(){ if(this.polyline){ this.polyLineLength=this.polyline.nativeElement.getTotalLength(); this.cd.detectChanges(); } } }
html
<svg#svg> <!--Y轴--> <g> <line[attr.x1]="AxisY.x1"[attr.y1]="AxisY.y1+15"[attr.x2]="AxisY.x2"[attr.y2]="AxisY.y2"[attr.stroke]="color"[attr.fill]="color" /> <polygon[attr.points]="AxisY.arrow"/> <ng-container*ngFor="letscaleofYscale"> <lineclass="dash"[attr.x1]="scale.x1"[attr.x2]="scale.x2"[attr.y1]="scale.y1"[attr.y2]="scale.y2"stroke="rgba(0,0,0,0.3)" /> <textclass="_label"[attr.x]="scale.x1-5"[attr.y]="scale.y1"[attr.fill]="color"[attr.fill]="color">{{scale.label}}</text> </ng-container> </g> <!--X轴--> <g> <line[attr.x1]="AxisX.x1-15"[attr.x2]="AxisX.x2"[attr.y1]="AxisX.y1"[attr.y2]="AxisX.y2"[attr.stroke]="color"[attr.fill]="color" /> <polygon[attr.points]="AxisX.arrow"/> <ng-container*ngFor="letscaleofXscale"> <line[attr.x1]="scale.x1"[attr.x2]="scale.x2"[attr.y1]="scale.y1"[attr.y2]="scale.y2"[attr.stroke]="color"[attr.fill]="color" /> <textclass="_label"[attr.x]="scale.x1-XgapWidth/2"[attr.y]="AxisY.y1+15"[attr.fill]="color">{{scale.label}}</text> </ng-container> </g> <!--矩形--> <ng-container*ngIf="type==='bar'"> <textx="10"y="20"fill="red">bar</text> <g> <ng-container*ngFor="letitemofdata"> <ng-container*ngIf="item.value<=0"> <rectclass="_rect"[attr.x]="item.x"[attr.y]="item.y"[attr.width]="item.w"[attr.height]="item.h"fill="color"> <animateattributeName="height"[attr.from]="item.h*0.6"[attr.to]="item.h"begin="0s"dur="1.1s"/> </rect> <text[attr.x]="item.x+item.w/2"[attr.y]="item.y+item.h-5"fill="white">{{item.value}}</text> </ng-container> <ng-container*ngIf="item.value>0"> <rect[attr.x]="item.x"[attr.y]="item.y"[attr.width]="item.w"[attr.height]="item.h"fill="color"> <animateattributeName="y"[attr.from]="item.y+item.h*0.4"[attr.to]="item.y"begin="0s"dur="1.1s"/> <animateattributeName="height"[attr.from]="item.h*0.6"[attr.to]="item.h"begin="0s"dur="1.1s"/> </rect> <textclass="_label"[attr.x]="item.x+item.w/2"[attr.y]="item.y+18"fill="white">{{item.value}} <animateattributeName="opacity"from="0"to="1"begin="0s"dur="1.1s"/> </text> </ng-container> </ng-container> </g> </ng-container> <!--折线--> <ng-container*ngIf="type==='line'"> <textx="10"y="20"fill="red">line</text> <g> <polyline#polylineclass="_polyline"[attr.points]="polyLinePoints"fill="none"[attr.stroke]='color'[attr.stroke-dasharray]="polyLineLength" [attr.stroke-dashoffset]="polyLineLength"/> <ng-container*ngFor="letitemofdata"> <circle[attr.cx]="item.x+item.w/2"[attr.cy]="item.y"r="2"[attr.fill]="color"[attr.stroke]='color'/> <textclass="_label"[attr.x]="item.x+item.w/2"[attr.y]="item.y+20"fill="white">{{item.value}} <animateattributeName="opacity"from="0"to="1"begin="0s"dur="1.1s"/> </text> </ng-container> </g> </ng-container> </svg>
css
svg{ background:rgba(0,0,0,0.2); border:1pxsolidblack; } svg*{ position:static; font-size:16px; } ._polyline{ fill:none; animation:lineMove1.5sease-in-outforwards; } @keyframeslineMove{ to{ stroke-dashoffset:0; } }
一、初始化参数
//首先获取传入的参数 @Input()inputParams; //初始化 const_params:NgoChartSvgParams={ xAxis:this.inputParams.xAxis, yAxis:this.inputParams.yAxis, type:this.inputParams.type?this.inputParams.type:'bar', width:this.inputParams.width?this.inputParams.width:700, height:this.inputParams.height?this.inputParams.height:500, dataPadding:this.inputParams.dataPadding!==undefined?this.inputParams.dataPadding:8, YscaleNo:this.inputParams.YscaleNo>=3?this.inputParams.YscaleNo:6, }; this.color='black'; this.type=_params.type; this.params=_params;
二:绘制坐标轴Y轴
const_height=this.params.height; const_pad=this.params.padding; const_arrow=_pad+','+(_pad-5)+''+(_pad-6)+','+(_pad+12)+''+(_pad+6)+','+(_pad+12); this.AxisY={ x1:_pad, y1:_height-_pad, x2:_pad, y2:_pad, arrow:_arrow };
三、绘制Y轴的刻度
const_height=this.params.height; const_width=this.params.width; //显示label的边距 const_padding=this.params.padding; const_Ydata=this.params.yAxis.data; //显示的刻度数 const_YscaleNo=this.params.YscaleNo; const_dataMax=this.getMinAndMaxData(_Ydata).dataMax; const_dataMin=this.getMinAndMaxData(_Ydata).dataMin; let_YminValue; let_YgapValue; if(_dataMin<0){ _YgapValue=Math.ceil((_dataMax-_dataMin)/(_YscaleNo)/10)*10; _YminValue=Math.floor(_dataMin/_YgapValue)*_YgapValue; }else{ _YgapValue=Math.ceil((_dataMax)/(_YscaleNo)/10)*10; _YminValue=0; } //Y轴坐标点 const_y2=this.AxisY.y2; const_y1=this.AxisY.y1; const_x1=this.AxisY.x1; //Y轴刻度的间隙宽度 const_YgapWidth=(_y1-_y2)/(this.params.YscaleNo); this.valueToPxRatio=_YgapValue/_YgapWidth; //坐标轴(0,0)的Y轴坐标 const_Y0=_y1-Math.abs(_YminValue/this.valueToPxRatio); this.Y0=_Y0; for(leti=0;i<this.params.YscaleNo;i++){ const_obj:Scale={x1:0,x2:0,y1:0,y2:0,label:'',value:0}; _obj.x1=_x1; _obj.y1=_y1-_YgapWidth*i; _obj.x2=_x1+_width-2*_padding; _obj.y2=_y1-_YgapWidth*i; _obj.label=_YminValue+_YgapValue*i; this.Yscale.push(_obj); }
四、绘制X坐标轴
const_width=this.params.width; //显示label的边距 const_pad=this.params.padding; const_x2=_width-_pad; const_y2=this.Y0; const_arrow=(_x2+5)+','+_y2+''+(_x2-10)+','+(_y2-6)+''+(_x2-10)+','+(_y2+6); this.AxisX={ x1:_pad, y1:_y2, x2:_x2, y2:_y2, arrow:_arrow };
五、绘制X轴刻度
const_width=this.params.width; const_Xdata=this.params.xAxis.data; const_Ydata=this.params.yAxis.data; constY0=this.Y0; const_x1=this.AxisX.x1; const_x2=this.AxisX.x2; constXgapWidth=((_x2-_x1)/(this.params.xAxis.data.length+1)); this.XgapWidth=XgapWidth; for(leti=0;i<_Xdata.length;i++){ const_obj:Scale={x1:0,x2:0,y1:0,y2:0,value:0,label:''}; _obj.y1=Y0; _obj.y2=Y0+5; _obj.label=_Xdata[i]; _obj.value=_Ydata[i]; _obj.x1=_x1+XgapWidth*(i+1); _obj.x2=_x1+XgapWidth*(i+1); this.Xscale.push(_obj);
六、绘制矩形
const_value=this.params.yAxis.data; const_dataPadding=this.params.dataPadding; const_XgapWidth=this.XgapWidth; for(leti=0;i<_value.length;i++){ constelement=_value[i]; const_obj:Chart={x:0,y:0,w:0,h:0,value:0}; _obj.w=_XgapWidth-2*_dataPadding; _obj.x=this.Xscale[i].x1-_obj.w-_dataPadding; _obj.h=Math.abs(this.Xscale[i].value/this.valueToPxRatio); _obj.value=this.Xscale[i].value; if(this.Xscale[i].value>=0){ _obj.y=this.Y0-(this.Xscale[i].value)/this.valueToPxRatio; }else{ _obj.y=this.Y0; } this.data.push(_obj); } }
七、绘制折线
const_data=this.data; let_str=''; _data.forEach(ele=>{ if(ele.value<0){ ele.y=ele.y+ele.h; } _str+=(ele.x+ele.w/2)+','+ele.y+''; }); this.polyLinePoints=_str;
关于如何在Angular2中使用SVG自定义图表问题的解答就分享到这里了,希望以上内容可以对大家有一定的帮助,如果你还有很多疑惑没有解开,可以关注恰卡编程网行业资讯频道了解更多相关知识。
目录
0 条评论
本站已关闭游客评论,请登录或者注册后再评论吧~