JS 饼图/环形图表

来源:互联网 发布:网页 加密软件 编辑:程序博客网 时间:2024/05/18 01:12

js 圆形/环形图表

最近公司项目要求开发环形图表客户端(Android/IOS)组件,一开始想使用原生实现,但是需要开发2套代码,最后决定使用js来实现图表,原生调用html代码展示。


效果如下:
这里写图片描述
直接上代码:


html代码:

<html>  <head>   <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0" /> <script src="pieChart.js"></script>  <title>My Demo 1</title>      <script>      window.onload = function() {          var canvas = document.getElementById("pie_canvas");          var seriesData = [{name:"apples", value:0.1, color:"#FF00aa",label1:"描述1",label2:"200元"},                        {name:"orange", value:0.2, color:"#FF0011",label1:"描述2",label2:"200元"},                        {name:"banana", value:0.3, color:"#FFaaFF",label1:"描述3",label2:"200元"},                        {name:"peaches", value:0.2, color:"#FF33FF",label1:"描述4",label2:"200元"},                        {name:"strawberries", value:0.2, color:"#FF99FF",label1:"描述5",label2:"200元"}]          var config = {                  width : 400,                   height: 400,                  series: seriesData,                  canvas: canvas,                   title:"Fruit Sales",                callback:function(obj){                    console.log(obj.label1);                }        };          pieChart.initSettings(config);          pieChart.render();      }      </script>  </head>  <body>  <h1>Pie Chart Demo</h1>  <div id="my_container" style="width:600px; height:500px;">      <canvas id="pie_canvas"></canvas>  </div>   </body>  </html>  

JS代码块:

var pieChart = {      title: "Pie Chart",     width: 400,      height: 400,      series: [],  //格式[{"name":"","value":"","color":"","label1":"","label2":""}]    chartCanvas: null,     callback:null ,    legend : {          show : true      },     label:{        show:true,        linelength:40,        linelength2:50    },    circle : {          cx: 0,          cy: 0,          radius: 0      },     initSettings: function (config) {          this.chartCanvas = config.canvas;          this.chartCanvas.width = config.width;          this.chartCanvas.height = config.height;          this.width = config.width;          this.height = config.height;          this.series = config.series;          this.title = config.title;            if(config.legend != undefined) {              this.legend.show = config.legend.show;                    }        if(config.label != undefined) {              this.label.show = config.label.show;                    }        this.callback = config.callback;    },    getRatioSum:function(j){        var sum = 0;        for (var i = 0; i < j; i++) {            sum += this.series[i].value;        }        return sum;    },    getRatioHalfSumDegrees:function(index){        var sum = this.getRatioSum(index);        sum += (this.series[index].value / 2);        return sum * Math.PI * 2;    },    getRatioHalfSumDegrees360:function(index){        var sum = this.getRatioSum(index);        sum += (this.series[index].value / 2);        return sum * 360;    },    renderLegend:function(ctx, length){    },    renderLabel:function(ctx,length){        if(this.label.show){            for (var i = 0; i <length; i++) {                this.renderLabelLine(ctx,i) ;            }        }    },    renderLabelLine:function(ctx,index){        ctx.save();        ctx.translate(this.width / 2, this.height / 2);        ctx.rotate(this.getRatioHalfSumDegrees(index));        ctx.strokeStyle = this.series[index].color;        ctx.moveTo(this.circle.radius + 1, 0);        ctx.lineTo(this.circle.radius + this.label.linelength, 0);        ctx.stroke();        this.renderLabelLine2(ctx, index);        ctx.restore();    },    renderLabelLine2:function(ctx,index){        ctx.save();        ctx.translate(this.circle.radius + this.label.linelength, 0);        var ro = this.getRatioHalfSumDegrees(index);        ctx.rotate( - ro);        var xro = this.getRatioHalfSumDegrees360(index);        if ((xro > 270 && xro < 360) || (xro > 0 && xro < 90)) {            ctx.strokeStyle = this.series[index].color;            ctx.moveTo(0, 0);            ctx.lineTo(this.label.linelength2, 0);            ctx.stroke();            ctx.fillText(this.series[index].label1, 10, -4);            ctx.fillText(this.series[index].label2, 10, 14);         } else {            ctx.strokeStyle = this.series[index].color;            ctx.moveTo(0, 0);            ctx.lineTo( - this.label.linelength2, 0);            ctx.stroke();            ctx.fillText(this.series[index].label1, -40, -4);            ctx.fillText(this.series[index].label2, -40, 14);         }        ctx.restore();    },    renderPie:function(ctx,length){        let lastpos = pos = 0;        ctx.lineWidth = this.circle.radius * 0.4;        for (let i = 0; i < length; i++) {            ctx.beginPath();            ctx.strokeStyle = this.series[i].color;            pos = lastpos + Math.PI * 2 * this.series[i].value;            ctx.arc(this.circle.cx , this.circle.cy, this.circle.radius, lastpos, pos);            ctx.stroke();            lastpos = pos;        }    },    renderPieImage:function(ctx,length){    },    renderClick:function(event,obj){        var x = event.pageX;        var y = event.pageY;        var canvas = event.target;        var bbox = canvas.getBoundingClientRect();        var loc = { x: x - bbox.left * (canvas.width  / bbox.width),                    y: y - bbox.top  * (canvas.height / bbox.height)};        console.log(loc);        var dx = loc.x - obj.circle.cx;          var dy = loc.y - obj.circle.cy;          var dis = Math.floor(Math.sqrt(dx * dx + dy * dy));          console.log("dis="+dis+"  mRadius="+obj.circle.radius);        if(dis <= obj.circle.radius*1.2&&dis>=obj.circle.radius*0.8) {              // draw tool tip text              var angle = Math.atan2(dy,dx);              if(angle <= 0) {                   angle = angle + 2*Math.PI;              }               var deltaArc = 0;              var index = 0;              for(var i=0; i<obj.series.length; i++) {                  var precent = obj.series[i].value;                  deltaArc += 2*Math.PI * precent;                  if(angle<=deltaArc) {                      index = i;                      break;                  }              }            obj.callback(obj.series[index]);            //console.log(obj.series[index].label1);        }    },    render:function(){        this.circle.cx = this.width/2 ;        this.circle.cy = this.height/2 ;        this.circle.radius=(this.width - this.width  * 0.5) / 2;        var ctx = this.chartCanvas.getContext("2d");        if(this.circle.radius <= 0) {              ctx.strokeText("请设置布局大小.");              return;          }            if (window.devicePixelRatio) {            this.chartCanvas.style.width = this.width + "px";            this.chartCanvas.style.height = this.height + "px";            this.chartCanvas.height = this.height * window.devicePixelRatio;            this.chartCanvas.width = this.width * window.devicePixelRatio;            ctx.scale(window.devicePixelRatio, window.devicePixelRatio);        }        var length = this.series.length ;        this.renderLabel(ctx,length) ;        this.renderPie(ctx,length);         var parent = this ;        this.chartCanvas.addEventListener('click', function(event){            parent.renderClick(event,parent);        }, false);    }}
原创粉丝点击