Heim  >  Artikel  >  Web-Frontend  >  js ist in ein Plug-in_Canvas-Statistikdiagramm-Plug-in gekapselt, das Beispiel_Javascript-Fähigkeiten schreibt

js ist in ein Plug-in_Canvas-Statistikdiagramm-Plug-in gekapselt, das Beispiel_Javascript-Fähigkeiten schreibt

韦小宝
韦小宝Original
2018-01-23 11:11:411864Durchsuche

Der folgende Editor zeigt Ihnen ein Beispiel für das Schreiben eines in ein Plug-in gepackten JS-Plug-ins_Canvas für statistische Diagramme. Der Herausgeber findet es ziemlich gut, deshalb teile ich jetzt den js-Quellcode mit Ihnen und gebe ihn als Referenz. Wenn Sie sich für js interessieren, folgen Sie bitte dem Editor, um einen Blick darauf zu werfen

Ich habe bereits gesagt, dass ich ein Plug-in zum Zeichnen statistischer Diagramme auf Leinwand schreiben möchte, und jetzt habe ich es geschrieben

Lassen Sie uns zunächst über die implementierten Funktionen sprechen:

1. Statistische Diagramme können proportional gezeichnet werden, indem die X-Achsen-Koordinatenattribute und die Y-Achsen-Koordinaten angepasst werden Attribute

2. Sie können wählen, ob Sie ein Rabattdiagramm oder ein Säulendiagramm oder beides zeichnen möchten

 3. Sie können die Rabattfarbe, die Koordinatenfarbe, die Farbe des Säulendiagramms und die Farbe des Leinwandrahmens frei definieren . Natürlich können Sie auch den Rand wählen

 4. Sie können wählen, ob die Animation des SäulendiagrammsImplementierung

Implementierungsprozess

Koordinaten zeichnen - Pfeile zeichnen - X-Achse und Y-Achse markieren - Säulendiagramm zeichnen - Rabattdiagramm zeichnen

Lassen Sie uns ohne weitere Umschweife den Code durchgehen

(function(window,document){
 var ChartDraws = function(options){
  if(!(this instanceof ChartDraws))return new ChartDraws(options);
  this.options = $.extend({
   //报表所需的参数
   "containerId" : "",  //canvas所在容器id
   "canvasWidth" : 400,
   "canvasHeight" : 300,
   "paddingLeft" : 20,
   "paddingTop" : 20,
   "columnChartData" :[], //柱形图的数量和对应得名称以及百分比
   "yChartData" :[],   //y轴的数量及名称
   "axisColor" : "white",  //坐标轴颜色
   "columnChartColor" : "#EEE685", //柱形图颜色
   "isNeedAnimation" : true, //是否需要动画
   "isNeedLineChart" : true, //是否需要折线图
   "isNeedColumnChart" : true, //是否需要柱形图
   "lineChartColor" : "#90EE90", //折线图颜色,当isNeedLineChart=true时有效
   "isNeedBorder" : false,  //canvas是否需要外边框
   "borderColor" : "white"  //外边框颜色
  },options);
  if(this.options.canvasWidth<=500)
  {
   this.axisBorderWidth = 3;
   this.fontSize = 8;
  }
  else if(this.options.canvasWidth<=800){
   this.axisBorderWidth = 4;
   this.fontSize = 12;
  }
  else{
   this.axisBorderWidth = 5;
   this.fontSize = 16;
  }
  var self = this;
  _init();
  function _init(){
   var canvasDom = document.createElement("canvas");
   canvasDom.id = self.options.containerId+"_"+"canvas";
   canvasDom.width = self.options.canvasWidth;
   canvasDom.height = self.options.canvasHeight;
   if(self.options.isNeedBorder){
    canvasDom.style.borderWidth = 1;
    canvasDom.style.borderStyle = "solid";
    canvasDom.style.borderColor = self.options.borderColor;
   }
   document.getElementById(self.options.containerId).appendChild(canvasDom);
   self.context = document.getElementById(self.options.containerId+"_"+"canvas");
   self.ctx = self.context.getContext("2d");
   _drawAxis();
  }

  function _drawAxis(){
   var XYData =transformAxis( [{x:self.options.paddingLeft,y:self.options.canvasHeight-self.options.paddingTop},{x:self.options.paddingLeft,y:self.options.paddingTop},{x:self.options.canvasWidth-self.options.paddingLeft,y:self.options.paddingTop}]);
   self.ctx.strokeStyle=self.options.axisColor;
   drawLine(self.ctx,XYData,self.axisBorderWidth);
   //画三角箭头
   //画y轴三角箭头
   drawLine(self.ctx,transformAxis([{x:self.options.paddingLeft-self.axisBorderWidth,y:self.options.canvasHeight-self.options.paddingTop-self.axisBorderWidth*2},{x:self.options.paddingLeft,y:self.options.canvasHeight-self.options.paddingTop},{x:self.options.paddingLeft+self.axisBorderWidth,y:self.options.canvasHeight-self.options.paddingTop-self.axisBorderWidth*2}]),self.axisBorderWidth);
   //画x轴三角箭头
   drawLine(self.ctx,transformAxis([{x:self.options.canvasWidth-self.options.paddingLeft-self.axisBorderWidth*2,y:self.options.paddingTop+self.axisBorderWidth},{x:self.options.canvasWidth-self.options.paddingLeft,y:self.options.paddingTop},{x:self.options.canvasWidth-self.options.paddingLeft-self.axisBorderWidth*2,y:self.options.paddingTop-self.axisBorderWidth}]),self.axisBorderWidth);
   _drawCoordinatePoints();
  }

  function _drawCoordinatePoints(){
   self.reactAngleWidth = (1-2*0.04)*(self.options.canvasWidth-(2*self.options.paddingLeft))/(self.options.columnChartData.length*2-1);
   self.lineDataList = [];
   for(var i = 0;i<self.options.columnChartData.length;i++)
   {
    drawXText(self.ctx,2*self.options.columnChartData[i].NO*self.reactAngleWidth+self.options.paddingLeft+0.04*(self.options.canvasWidth-(2*self.options.paddingLeft))+self.reactAngleWidth/2,self.options.paddingTop/2,self.options.columnChartData[i].Name);
    self.lineDataList.push({
     x:2*self.options.columnChartData[i].NO*self.reactAngleWidth+self.options.paddingLeft+0.04*(self.options.canvasWidth-(2*self.options.paddingLeft))+self.reactAngleWidth/2,
     y:self.options.canvasHeight-(self.options.paddingTop+(self.options.canvasHeight-2*self.options.paddingTop)*self.options.columnChartData[i].PT)
    })
   }

   //画Y轴title 画y轴虚线
   self.reactAngleHeight = (self.options.canvasHeight-2*self.options.paddingTop)/(self.options.yChartData.length+1);
   for(var j = 0;j<self.options.yChartData.length;j++)
   {
    drawYText(self.ctx,3*self.options.paddingLeft/4,self.options.paddingTop+self.reactAngleHeight*(j+1),self.options.yChartData[j].Name);
    //画虚线
    drawDottedLine(self.ctx,self.options.paddingLeft,self.options.paddingTop+self.reactAngleHeight*(j+1),self.options.canvasWidth-self.options.paddingLeft,self.options.paddingTop+self.reactAngleHeight*(j+1),self.options.canvasWidth-2*self.options.paddingLeft,10,self.axisBorderWidth/2);
   }
   _drawColumnChart();
  }

  function _drawColumnChart(){
   //柱形图循环
   var reactAngleTimer = 1;
   function loopColumnChart()
   {
    var columnChartLooped = window.requestAnimationFrame(loopColumnChart);
    if(reactAngleTimer<=100)
    {
     for(var k=0;k<self.options.columnChartData.length;k++)
     {
      self.ctx.fillStyle =self.options.columnChartColor;
      drawRectangle(self.ctx,self.lineDataList[k].x-self.reactAngleWidth/2,self.options.canvasHeight-((self.options.canvasHeight-2*self.options.paddingTop)*self.options.columnChartData[k].PT*reactAngleTimer/100+self.options.paddingTop),self.reactAngleWidth,(self.options.canvasHeight-2*self.options.paddingTop)*self.options.columnChartData[k].PT*reactAngleTimer/100);
     }
     reactAngleTimer++;
    }
    else
    {
     window.cancelAnimationFrame(columnChartLooped);
     columnChartLooped = null;
     reactAngleTimer = 1;
     if(self.options.isNeedLineChart)
     {
      loopLineChart();
     }
    }
   }
   //折线图循环
   var lineTimer = 0;
   function loopLineChart()
   {
    var lineChartLooped = window.requestAnimationFrame(loopLineChart);
    if(lineTimer<self.lineDataList.length-1)
    {
     self.ctx.lineWidth = 2*self.axisBorderWidth/3;
     if(lineTimer == 0)
     {
      drawCircle(self.ctx,self.lineDataList[lineTimer].x,self.lineDataList[lineTimer].y);
     }
     drawCircle(self.ctx,self.lineDataList[lineTimer+1].x,self.lineDataList[lineTimer+1].y);
     self.ctx.beginPath();
     self.ctx.moveTo(self.lineDataList[lineTimer].x,self.lineDataList[lineTimer].y);
     self.ctx.lineTo(self.lineDataList[lineTimer+1].x,self.lineDataList[lineTimer+1].y);
     self.ctx.strokeStyle = self.options.lineChartColor;
     self.ctx.lineWidth = 2*self.axisBorderWidth/3;
     self.ctx.stroke();
     lineTimer++;
    }
    else
    {
     window.cancelAnimationFrame(lineChartLooped);
     lineChartLooped = null;
     lineTimer = 0;
    }
   }
   //画柱形图
   function drawRectangle(context,x,y,width,height){
    context.beginPath();
    context.fillRect(x,y,width,height);
   }
   //画圆
   function drawCircle(context,x,y){
    context.beginPath();
    context.arc(x,y,self.axisBorderWidth/2,0,2*Math.PI,true);
    context.strokeStyle=self.options.lineChartColor;
    context.stroke();
    context.closePath();
   }
   if(self.options.isNeedAnimation)
   {
    if(self.options.isNeedColumnChart)
    {
     loopColumnChart();
    }
    else
    {
     if(self.options.isNeedLineChart) {
      loopLineChart();
     }
    }
   }
   else
   {
    if(self.options.isNeedColumnChart)
    {
     for(var k=0;k<self.options.columnChartData.length;k++)
     {
      self.ctx.fillStyle =self.options.columnChartColor;
      drawRectangle(self.ctx,self.lineDataList[k].x-self.reactAngleWidth/2,self.options.canvasHeight-((self.options.canvasHeight-2*self.options.paddingTop)*self.options.columnChartData[k].PT+self.options.paddingTop),self.reactAngleWidth,(self.options.canvasHeight-2*self.options.paddingTop)*self.options.columnChartData[k].PT);
     }
    }
    if(self.options.isNeedLineChart) {
     for (var l = 0; l < self.lineDataList.length - 1; l++) {
      self.ctx.lineWidth = 4;
      if (l == 0) {
       drawCircle(self.ctx, self.lineDataList[l].x, self.lineDataList[l].y);
      }
      drawCircle(self.ctx, self.lineDataList[l + 1].x, self.lineDataList[l + 1].y);
      self.ctx.beginPath();
      self.ctx.moveTo(self.lineDataList[l].x, self.lineDataList[l].y);
      self.ctx.lineTo(self.lineDataList[l + 1].x, self.lineDataList[l + 1].y);
      self.ctx.strokeStyle = self.options.lineChartColor;
      self.ctx.lineWidth = 2*self.axisBorderWidth/3;
      self.ctx.stroke();
     }
    }
   }
  }


  function transformAxis(data)
  {
   var newData=[];
   for(var i=0;i<data.length;i++){
    newData.push({
     x:data[i].x,
     y:self.options.canvasHeight-data[i].y
    })
   }
   return newData;
  }

  function drawLine(context,point,width){
   context.beginPath();
   context.moveTo(point[0].x,point[0].y);
   if(point.length>2)
   {
    for(var i=1;i<point.length;i++)
    {
     context.lineTo(point[i].x,point[i].y);
    }
   }
   context.lineWidth = width;
   context.lineJoin=&#39;round&#39;;
   context.stroke();
   context.closePath();
  }

  //画y轴title
  function drawYText(context,x,y,str) {
   context.beginPath();
   context.font = &#39;{fontSize} Microsoft Yahei&#39;.replace("{fontSize}",self.fontSize+"px");
   context.fillStyle = &#39;white&#39;;
   context.textAlign = &#39;right&#39;;
   context.fillText(str,x,self.options.canvasHeight-y);
   context.closePath();
  }
  //画x轴title
  function drawXText(context,x,y,str) {
   context.beginPath();
   context.font = &#39;{fontSize} Microsoft Yahei&#39;.replace("{fontSize}",self.fontSize+"px");
   context.fillStyle = &#39;white&#39;;
   context.textAlign = &#39;center&#39;;
   context.fillText(str,x,self.options.canvasHeight-y);
   context.closePath();
  }
  function drawDottedLine(context,x1,y1,x2,y2,totalLength,length,lineWidth){
   y1 = self.options.canvasHeight-y1;
   y2 = self.options.canvasHeight-y2;
   var dashLen = length === undefined ? 5 : length;
   //计算有多少个线段
   context.beginPath();
   var num = Math.floor(totalLength/dashLen);
   context.lineWidth = lineWidth;
   for(var i = 0 ; i < num; i++)
   {
    context[i%2==0 ? &#39;moveTo&#39; : &#39;lineTo&#39;](x1+(x2-x1)/num*i,y1+(y2-y1)/num*i);
   }
   context.stroke();
  }
 };
 window.ChartDraws = ChartDraws;
}(window,document));
und im Folgenden soll die Browserkompatibilität von requestAnimationFrame implementiert werden

(function(){
 var lastTime = 0;
 var prefixes = [&#39;ms&#39;,&#39;webkit&#39;,&#39;o&#39;,&#39;moz&#39;]; //各浏览器前缀

 var requestAnimationFrame = window.requestAnimationFrame;
 var cancelAnimationFrame = window.cancelAnimationFrame;

 var prefix;
 //通过遍历各浏览器前缀,来得到requestAnimationFrame和cancelAnimationFrame在当前浏览器的实现形式
 for( var i = 0; i < prefixes.length; i++ ) {
  if ( requestAnimationFrame && cancelAnimationFrame ) {
   break;
  }
  prefix = prefixes[i];
  requestAnimationFrame = requestAnimationFrame || window[ prefix + &#39;RequestAnimationFrame&#39; ];
  cancelAnimationFrame = cancelAnimationFrame || window[ prefix + &#39;CancelAnimationFrame&#39; ] || window[ prefix + &#39;CancelRequestAnimationFrame&#39; ];
 }

 //如果当前浏览器不支持requestAnimationFrame和cancelAnimationFrame,则会退到setTimeout
 if ( !requestAnimationFrame || !cancelAnimationFrame ) {
  requestAnimationFrame = function( callback, element ) {
   var currTime = new Date().getTime();
   //为了使setTimteout的尽可能的接近每秒60帧的效果
   var timeToCall = Math.max( 0, 16 - ( currTime - lastTime ) );
   var id = window.setTimeout( function() {
    callback( currTime + timeToCall );
   }, timeToCall );
   lastTime = currTime + timeToCall;
   return id;
  };
  cancelAnimationFrame = function( id ) {
   window.clearTimeout( id );
  };
 }

 window.requestAnimationFrame = requestAnimationFrame;
 window.cancelAnimationFrame = cancelAnimationFrame;
}());
Im Anhang finden Sie den 3f1c4e4b6b16bbbd69b2ee476dc4f83a-Aufruf

ChartDraws({
  "containerId" : "chart1",  //canvas所在容器id
  "canvasWidth" : 1000,
  "canvasHeight" : 250,
  "paddingLeft" : 50,
  "paddingTop" : 50,
  "columnChartData": [
   {NO:0,PT:0.2,Name:"Html/Css"},
   {NO:1,PT:0.4,Name:"Html5/Css3"},
   {NO:2,PT:0.4,Name:"JavaScript"},
   {NO:3,PT:0.5,Name:"JQuery"},
   {NO:4,PT:0.2,Name:"Angular.js"},
   {NO:5,PT:0.8,Name:"BootStrap"},
   {NO:6,PT:0.6,Name:"React.js"},
   {NO:7,PT:0.5,Name:"Java"}
  ],
  "yChartData" : [
   {NO:0,Name:"熟悉"},
   {NO:1,Name:"掌握"},
   {NO:2,Name:"精通"}
  ],
  "isNeedAnimation" : false,
  "isNeedBorder" : false,
  "isNeedLineChart":true,
  "axisColor" : "#8DEEEE"
 });
 ChartDraws({
  "containerId" : "chart2",  //canvas所在容器id
  "canvasWidth" : 1000,
  "canvasHeight" : 250,
  "paddingLeft" : 50,
  "paddingTop" : 50,
  "columnChartData": [
   {NO:0,PT:0.4,Name:"Html/Css"},
   {NO:1,PT:0.5,Name:"Html5/Css3"},
   {NO:2,PT:0.2,Name:"JavaScript"},
   {NO:3,PT:0.7,Name:"JQuery"},
   {NO:4,PT:0.2,Name:"Angular.js"},
   {NO:5,PT:0.3,Name:"BootStrap"},
   {NO:6,PT:0.8,Name:"React.js"},
   {NO:7,PT:0.2,Name:"Java"}
  ],
  "yChartData" : [
   {NO:0,Name:"熟悉"},
   {NO:1,Name:"掌握"},
   {NO:2,Name:"精通"}
  ],
  "isNeedAnimation" : false,
  "isNeedBorder" : false,
  "isNeedLineChart":false,
  "isNeedColumnChart" : true,
  "columnChartColor":"#9370DB"
 });

 ChartDraws({
  "containerId" : "chart3",  //canvas所在容器id
  "canvasWidth" : 1000,
  "canvasHeight" : 250,
  "paddingLeft" : 50,
  "paddingTop" : 50,
  "columnChartData": [
   {NO:0,PT:0.4,Name:"Html/Css"},
   {NO:1,PT:0.5,Name:"Html5/Css3"},
   {NO:2,PT:0.2,Name:"JavaScript"},
   {NO:3,PT:0.7,Name:"JQuery"},
   {NO:4,PT:0.2,Name:"Angular.js"},
   {NO:5,PT:0.3,Name:"BootStrap"},
   {NO:6,PT:0.8,Name:"React.js"},
   {NO:7,PT:0.2,Name:"Java"}
  ],
  "yChartData" : [
   {NO:0,Name:"熟悉"},
   {NO:1,Name:"掌握"},
   {NO:2,Name:"精通"}
  ],
  "isNeedAnimation" : false,
  "isNeedBorder" : true,
  "isNeedLineChart":true,
  "isNeedColumnChart" : false,
  "lineChartColor" : "#8DB6CD",
  "borderColor" : "#87CEFA"
 })
HTML-Code

<p class="section">
 <p id="chart1"></p>
 <p id="chart2"></p>
 <p id="chart3"></p>
 </p>
Das Folgende ist ein Rendering nach der Implementierung

Ich habe den Code während des gesamten Codierungsprozesses einmal geändert. Warum habe ich ihn geändert? Weil ich beim ersten Mal viele ChartDraws.prototype.XXXX = function(){}; verwendet habe.

Später dachte ich, es sei falsch , warum sollte ich das tun? Es gibt so viele Möglichkeiten, sie der Außenwelt preiszugeben... Sucht das nicht nur nach Ärger...

Wenn es also etwas gibt falsch und etwas, das verbessert werden kann. Ich hoffe, Sie können mir einen Rat geben, wenn Sie vorbeikommen, danke! Und warum kann ich den weißen Codehintergrund nicht löschen ...

Verwandte Empfehlungen:

Beispielanalyse für JavaScript-Konstruktormuster

Wie berechnet JavaScript die Länge eines Objekts?

Detaillierte Erklärung des Typs und der Typbeurteilung in JavaScript

Das obige ist der detaillierte Inhalt vonjs ist in ein Plug-in_Canvas-Statistikdiagramm-Plug-in gekapselt, das Beispiel_Javascript-Fähigkeiten schreibt. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn