chart

var pieChart = {
    width: 600,
    height: 400,
    series: [],
    unit: "kg",
    chartCanvas: null,
    selectable : true,
    title: "Pie Chart",
    legend : {
        enable : true
    },
    edge : {
        width: 50,
        height: 50
    },
    animation: {
        enable: true,
        animCanvas : null,
        hh: 1, // trick is here!! for animation play
        pctx: null
    },
    tooltips: {
        enable: true,
        tooltipCanvas : null,
        ttContext: null,
        index: -1
    },
    circle : {
        cx: 0,
        cy: 0,
        radius: 0

    },
    text : {
        enable: false,
        content:[]
    },

    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;
        this.unit = config.unit;
        if(config.tooltips != undefined) {
            this.tooltips.enable = config.tooltips.enable;
        }
        if(config.animation != undefined) {
            this.animation.enable = config.animation.enable;
        }
        if(config.legend != undefined) {
            this.legend.enable = config.legend.enable;
        }
        if(config.text != undefined) {
            this.text.enable = config.text.enable;
        }
    },

    render : function() {
        // initialization circle
        this.circle.cx = this.width/2;
        this.circle.cy = this.height/2;
        this.circle.radius = Math.min(this.width/2, this.height/2) - Math.max(this.edge.width, this.edge.height);
        var ctx = null;
        if(this.animation.enable) {
            this.animation.animCanvas = document.createElement("canvas");
            this.animation.animCanvas.width = this.width;
            this.animation.animCanvas.height = this.height;
            ctx = this.animation.animCanvas.getContext("2d");
        } else {
            ctx = this.chartCanvas.getContext("2d");
            this.renderBorder(ctx);
        }

        if(this.circle.radius <= 0) {
            ctx.strokeText("Can not reader the chart, Circle is too small.");
            return;
        }

        // draw each arc according to data series
        var sum = 0;
        var nums = this.series.length;
        for(var i=0; i<nums; i++) {
            sum += this.series[i].value;
        }

        // draw title
        ctx.font = ‘18pt Calibri‘;
        ctx.fillText(this.title, this.width/2 - this.edge.width, 30);
        ctx.save();
        var deltaArc = 0;
        for(var i=0; i<nums; i++) {
            var precent = this.series[i].value/sum;
            this.renderPie(ctx, i, precent, deltaArc);
            deltaArc += 2*Math.PI * precent;
        }
        ctx.restore();

        // add blur shadow
        ctx.save();
        ctx.shadowColor = "black";
        ctx.shadowOffsetX = 0;
        ctx.shadowOffsetY = 0;
        ctx.shadowBlur = 10;
        ctx.beginPath();
        ctx.arc(this.circle.cx, this.circle.cy, this.circle.radius, 0, Math.PI * 2, false);
        ctx.closePath();
        ctx.lineWidth = 1;
        ctx.strokeStyle = "RGBA(127,127,127,1)";
        ctx.stroke();
        ctx.restore();

        // render legend
        ctx.save();
        this.renderLegend(ctx, sum);
        ctx.restore();

        // play animation
        if(this.animation.enable) {
            var parent = this;
            this.animation.pctx = this.chartCanvas.getContext("2d");
            this.renderBorder(this.animation.pctx);
            setTimeout(function() {parent.playAnimation(parent);}, 1000/20);
        }
    },

    showTooltips : function(loc, ctx) {
        if(!this.tooltips.enable) {
            return;
        }
        var dx = loc.x - this.width/2;
        var dy = loc.y - this.height/2;
        var dis = Math.floor(Math.sqrt(dx * dx + dy * dy));
        if(dis <= this.circle.radius) {
            // draw tool tip text
            var angle = Math.atan2(dy,dx);
            if(angle <= 0) {
                // if[-Math.PI, 0], make it[Math.PI, 2*Math.PI]
                angle = angle + 2*Math.PI;
            }

            var sum = 0;
            var nums = this.series.length;
            for(var s=0; s<nums; s++) {
                sum += this.series[s].value;
            }

            var deltaArc = 0;
            var index = 0;
            for(var i=0; i<nums; i++) {
                var precent = this.series[i].value/sum;
                deltaArc += 2*Math.PI * precent;
                if(angle<=deltaArc) {
                    index = i;
                    break;
                }
            }
            if(this.tooltips.tooltipCanvas == null) {
                this.tooltips.tooltipCanvas = document.createElement("canvas");
                this.tooltips.ttContext = this.tooltips.tooltipCanvas.getContext("2d");
                this.tooltips.tooltipCanvas.width = 150;
                this.tooltips.tooltipCanvas.height = 100;
            } 

            // only draw once
            // if(index == this.tooltips.index){
            //     return;
            // }
            this.clearTooltips(ctx);

            this.tooltips.index = index;
            var m_context = this.tooltips.ttContext;
            m_context.save();
            m_context.clearRect(0, 0, this.tooltips.tooltipCanvas.width, this.tooltips.tooltipCanvas.height);
            m_context.lineWidth = 2;
            m_context.strokeStyle = this.series[index].color;
            m_context.fillStyle="RGBA(255,255,255,0.7)";
            // m_context.strokeRect(2, 2, this.tooltips.tooltipCanvas.width-4, this.tooltips.tooltipCanvas.height-4);
            // m_context.fillRect(2,2,this.tooltips.tooltipCanvas.width-4, this.tooltips.tooltipCanvas.height-4);
            m_context.roundRect(2,2,this.tooltips.tooltipCanvas.width-4, this.tooltips.tooltipCanvas.height-4, 5, true, true);
            m_context.font="14px Arial";
            m_context.fillStyle="RGBA(0,0,0,1)";
            m_context.fillText("Index: " + (index + 1), 5, 20);
            m_context.fillText(this.series[index].name + ": " + this.series[index].value + this.unit, 5, 40);
            m_context.fillText(this.series[index].precent, 5, 60);
            m_context.restore();

            // make tool-tip rectangle is always visible
            if((loc.x + this.tooltips.tooltipCanvas.width)> this.width) {
                loc.x = loc.x - this.tooltips.tooltipCanvas.width;
            }
            if((loc.y - this.tooltips.tooltipCanvas.height) <= 0) {
                loc.y = loc.y + this.tooltips.tooltipCanvas.height;
            }
            ctx.drawImage(this.tooltips.tooltipCanvas, 0, 0, this.tooltips.tooltipCanvas.width, this.tooltips.tooltipCanvas.height,
                    loc.x, loc.y-this.tooltips.tooltipCanvas.height, this.tooltips.tooltipCanvas.width, this.tooltips.tooltipCanvas.height);
        } else {
            this.tooltips.index = -1;
            this.clearTooltips(ctx);
        }
    },

    clearTooltips : function(ctx) {
        ctx.clearRect(0,0,this.width, this.height);
        this.renderBorder(ctx);
        ctx.drawImage(this.animation.animCanvas, 0, 0, this.width, this.height, 0, 0, this.width, this.height);
    },

    renderBorder : function(ctx) {
        ctx.save();
        ctx.fillStyle="white";
        ctx.strokeStyle="black";
        ctx.fillRect(0, 0, this.width, this.height);
        ctx.strokeRect(0, 0, this.width, this.height);
        ctx.restore();
    },

    renderPie : function(ctx, index, precent, deltaArc) {
        var endAngle = deltaArc + 2*Math.PI*precent;
        ctx.beginPath();
        ctx.arc(this.circle.cx, this.circle.cy, this.circle.radius, deltaArc, endAngle, false);
        ctx.moveTo(this.circle.cx, this.circle.cy);
        ctx.lineTo(this.circle.cx + this.circle.radius * Math.cos(deltaArc), this.circle.cy + this.circle.radius * Math.sin(deltaArc));
        ctx.lineTo(this.circle.cx + this.circle.radius * Math.cos(endAngle), this.circle.cy + this.circle.radius * Math.sin(endAngle));
        ctx.lineTo(this.circle.cx, this.circle.cy);
        ctx.closePath();
        ctx.fillStyle = this.series[index].color;
        ctx.fill();

        // render text content
        if(this.text.enable) {
            var halfEndAngle = deltaArc + Math.PI*precent;
            var hx = this.circle.cx + this.circle.radius * Math.cos(halfEndAngle);
            var hy = this.circle.cy + this.circle.radius * Math.sin(halfEndAngle);
            ctx.beginPath();
            ctx.moveTo(hx, hy);
            var linePos = (hx < this.circle.cx) ? (hx - this.edge.width) : (hx + this.edge.width);
            ctx.lineTo(linePos, hy);
            ctx.closePath();
            ctx.strokeStyle="black";
            ctx.stroke();
            var textPos = (hx < this.circle.cx) ? (hx - this.edge.width*2) : (hx + this.edge.width);
            precent = Math.round (precent*100) / 100;
            var size = this.text.content.length;
            var tipStr = (size > index) ? this.text.content[index] : this.series[index].name + ": " + (precent * 100).toFixed(0) + "%";
            ctx.font = ‘10pt Calibri‘;
            ctx.fillStyle="black";
            ctx.fillText(tipStr, textPos, hy);
        }
    },

    renderLegend : function(ctx, sum) {
        if(!this.legend.enable) return;
        var nums = this.series.length;
        ctx.font = ‘10pt Calibri‘;
        var pos = (this.width/2 > (this.circle.radius+50)) ? 50 : (this.circle.cx - this.circle.radius);
        for(var i=0; i<nums; i++) {
            var x = this.series[i].value/sum;
            x = Math.round (x*100) / 100;
            var tipStr =  this.series[i].name + ": " + (x * 100).toFixed(0) + "%";
            this.series[i].precent = tipStr;
            ctx.fillStyle = this.series[i].color;
            ctx.fillRect(pos - 40, 20*i+10, 10, 10);
            ctx.fillStyle = "black";
            ctx.fillText(tipStr, pos - 25, 20*i+20);
        }
    },

    playAnimation : function(parent) {
        if(parent.animation.hh < parent.height) {
            parent.animation.pctx.save();
            parent.animation.pctx.globalAlpha=0.5;
            parent.animation.pctx.clearRect(0,0,parent.width, parent.height);
            parent.renderBorder(parent.animation.pctx);
            parent.animation.pctx.drawImage(parent.animation.animCanvas, 0, 0, parent.width, this.animation.hh, 0, 0, parent.width, this.animation.hh);
            parent.animation.hh = parent.animation.hh + 10;
            parent.animation.pctx.restore();
            setTimeout(function() {parent.playAnimation(parent);}, 1000/20);
        } else {
            parent.animation.pctx.clearRect(0,0,parent.width, parent.height);
            parent.renderBorder(parent.animation.pctx);
            parent.animation.pctx.drawImage(parent.animation.animCanvas, 0, 0, parent.width, parent.height, 0, 0, parent.width, parent.height);

            // enable tool-tip functionality
            if(parent.animation.enable && parent.legend.enable) {
                parent.chartCanvas.addEventListener(‘mousemove‘, function(event) {
                    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)};

                    parent.showTooltips(loc, (parent.animation.enable ? parent.animation.pctx : ctx));
                }, false);
            }
        }
    },

};

时间: 2024-10-03 19:12:26

chart的相关文章

Html5之高级-7 HTML5 Chart.js(概述、入门、使用)

一.Chart.js 概述 Chart.js 简介 - Chart.js 是一个简单.面向对象.为设计者和开发者准备的图表绘制工具库 - 官方地址: http://www.chartjs.org/ Chart.js 特点 - 基于 HTML 5 - Chart.js 基于 HTML5 canvas技术,支持所有现代浏览器,并且针对IE7/8提供了降级替代方案 - 简单.灵活 - Chart.js 不依赖任何外部工具库,轻量级(压缩之后仅有4.5k),并且提供了加载外部参数的方法 Chart.js

C# chart,有关如何在鼠标移动到Series上时显示节点及数据 (有待继续更新)

一.效果与思路 效果: 解决方案1 用chart的mousemove时间,实时跟踪鼠标最近的X轴的位置,然后把cursorX设置到那个位置上,让用户知道我是选的那一个X的值,同时用tooltip显示该X轴上所有的Y值,结贴了谢谢大家. 至于如何显示鼠标移动到的那个series上的数据节点,可以在Mousmove时,用一个击中测试,判断. 参考代码,击中测试获得点数据点的索引: if (e.HitTestResult.ChartElementType == ChartElementType.Dat

ExtJS(5)- Ext5的统计图Chart

今天系统整理下Ext5中的chart使用以及遇到的一些问题. 首先是Ext5中chart的引用,在5之前的版本中chart的api会被集合在ext-all.js中,但是在5当中并不是这样,如果只引入ext-all.js,我们引用chart API时将无法找到,我们还需要引入以下js <script type="text/javascript" src="ext-5.0.0/build/packages/ext-charts/build/ext-charts.js&quo

Google Combo Chart example with database in ASP.NET

Hide demo Download In this article I'm going to explain how to create Google combo chart example with database in ASP.NET. Google charts allows you to create a chart that lets you render each series as a different marker type from the following list:

[转] angular2+highcharts+chart.js

这里是在ionic2下使用highchairs和chart.js的简单示例chartjs部分参考http://www.jianshu.com/p/bc18132da812 1.安装hightcharts npm install highcharts --save typings install dt~highcharts --global --save 2.编辑 html文件在html中添加一个div来显示图表 <ion-content class="about"> <

Excel_2017KB_02 PivotTable and Chart

Insert->PivotTable Row/ Col 拖拉 Slicer 集中几个维度查询,方便报表打印,展示,节省劳动力 Chart Insert->Column/so on 数据有效性->下拉菜单索引变动->取值变动->映射图标变动 =OFFSET($A$1,ROW(A3)-1,$J$1)

C# chart 关于实时更新传感器数据

因为自己毕业需要做一个有关环境监测的项目,原理是通过无线采集环境信息,将信息实时保存到数据库,上位机是winform程序,程序需要实时的显示已经采集到的数据,并用曲线的方式表现出来,自己折腾了几天,也算是有一些小的收货,自己也是刚接触C#编程,给我的感觉非常的好. 用到的chart控件下载地址  链接: http://pan.baidu.com/s/1eSnYj3W 密码: xqhm 我用的是VS2010. 分析我的目的要求:实时刷新获取数据库的数据,将数据实时的显示到chart表上. 我的解决

C# Chart控件,chart、Series、ChartArea曲线图绘制的重要属性

原文有备份,如有错误和需要改进的地方,请不吝指正会继续修改的 8个月没写博客了- -,一来是有不想继续干开发的想法,二来是赖的写,三来还是不想总结.所以为了继续坚持自己的开发和总结的信念,总结一下C# chart控件的一些基本属性,由于属性太多了,一时半会儿写不完,以后继续补充,这里总结重要的常用的属性 为避免耽误不喜欢这种曲线图效果的亲们的时间,先看一下小DEMO效果图: 先简单说一下,从图中可以看到一个chart可以绘制多个ChartArea,每个ChartArea都可以绘制多条Series

Excel Chart

using System.IO;using System.Runtime.InteropServices;using Excel = Microsoft.Office.Interop.Excel; private void Btn_Click(object sender, EventArgs e){ //创建一个EXCEL文档 CreateExcel("标题","文档.XLS", "工作表名"); } private void CreateExc

Open Flash Chart 之线图

天公司要求开发一个曲线图,简单看了一下之前公司的一个系统,发现一个曲线图效果还不错,查了一下叫OpenFlashChart,还是很不错的,很多人用.研究了一下,发现还不错,特地写了个DEMO测试下. public ActionResult ITooltip() { int DateLen = Convert.ToInt32(Request["d"]); int DateMode = Convert.ToInt32(Request["m"]); OpenFlashCh