精华内容
下载资源
问答
  • 使用AChartEngine图表库实现动态饼图,可以实时传入数据并刷新饼图
  • FLASH实现的动态饼图效果FLASH实现的动态饼图效果FLASH实现的动态饼图效果
  • js实现动态饼图

    2013-11-14 11:05:03
    html5画饼图,js实现动态饼图,可以下载下来看看
  • d3.js动态饼图

    2020-04-26 09:04:08
    看看如何用d3.js绘制动态饼图: 原文地址: d3.js动态饼图

    看看如何用d3.js绘制动态饼图:
    d3.js动态饼图
    原文地址:
    d3.js动态饼图

    展开全文
  • 否则那些数据都会被加载,最后重新绘制饼图,构建动态饼图的步骤主要分为以下四步,还需要在项目中引入AChartEngine依赖jar包,在Manifest中添加<activityandroid:name="org.achartengine.GraphicalActivity" />
  • canvas+js实现动态饼图效果 参考了一些网上的例子,利用canvas+js实现动态饼图效果demo,包括鼠标移入图块颜色变化以及带有tooltip提示。实现逻辑可分为三个步骤: 1、首先利用canvas画布原理画饼图。 2、添加鼠标移...

    canvas+js实现动态饼图效果

    参考了一些网上的例子,利用canvas+js实现动态饼图效果demo,包括鼠标移入图块颜色变化以及带有tooltip提示。实现逻辑可分为三个步骤:

    1、首先利用canvas画布原理画饼图。
    2、添加鼠标移入监听事件,获取鼠标当前坐标。
    3、判断当前鼠标坐标是否在所画饼图扇形区域,改变饼图颜色和显示tooltip提示。
    

    1、画饼图

    利用canvas实现一个饼图效果,我们首先需要知道canvas画布画图原理以及相关需要的API。
    W3school这样介绍canvas,还不太了解的朋友可以先去熟悉熟悉。

    什么是 Canvas?
    HTML5 的 canvas 元素使用 JavaScript 在网页上绘制图像。
    画布是一个矩形区域,您可以控制其每一像素。
    canvas 拥有多种绘制路径、矩形、圆形、字符以及添加图像的方法。

    创建 Canvas 元素
    向 HTML5 页面添加 canvas 元素。
    规定元素的 id、宽度和高度:

      <canvas id="myCanvas" width="200" height="100"></canvas>
    

    通过上面的介绍,即画图的html部分我们已经了解,只需要定义一个带有宽高及id的canvas即可,接下来便是通过js来绘制图形,首先我们需要利用id来寻找canvas元素。

    let el = document.getElementById("myCanvas");
    

    然后创建画布的绘制对象:

    let cxt = el.getContext("2d"); 
    

    接下来,即可利用canvas的相关API来绘制我们需要的图像,canvas的API可参考《HTML Canvas 参考手册》。本次画饼图设计需要的API整理如下:

    ctx.beginPath(); // 起始一条路径,或重置当前路径
    ctx.fillStyle; // 设置或返回用于填充绘画的颜色、渐变或模式 ctx.moveTo(x, y); // 把路径移动到画布中的指定点,不创建线条
    ctx.arc(x, y, radius, sAngle, eAngle, false); // 创建弧/曲线(用于创建圆形或部分圆)
    ctx.fill(); // 填充当前绘图(路径)

    以上只列出了几个化饼图的关键API,其他包括饼图具体实现、小图标以及文字的相关API详细参见下面的代码。

    2、添加鼠标监听

    利用js的addEventListener,添加所绘画布鼠标监听,获取当前鼠标移入的坐标。

    // 鼠标位置监听
    getPosition(element) {
        let mouseTimer = null;
        element.addEventListener('mousemove', (e) => {
            e = e || window.event;
            if ( e.ofSfsetX || e.offsetX==0 ) {
                this.mousePosition.x = e.offsetX;
                this.mousePosition.y = e.offsetY;
            } else if ( e.layerX || e.layerX==0 ){
                this.mousePosition.x = e.layerX;
                this.mousePosition.y = e.layerY;
            } 
    
            // 监听tooltip显示
            let el =  document.getElementById('self-tooltip');
            el.style.visibility = 'hidden';
            
            clearTimeout(mouseTimer);
            mouseTimer = setTimeout(() => {
                this.drawPie(element, this.pieData);
            }, 50)
        });
    }, 
    

    3、鼠标移入,改变饼图样式

    在绘制饼图方法中调用getPosition(element)方法,利用ctx.isPointInPath()API判断当前鼠标坐标是否在所绘制扇形中,以改变相关样式和显示tooltip提示。

    // 监听鼠标是否移动到绘制扇形处
    if (ctx.isPointInPath(this.mousePosition.x, this.mousePosition.y)) {
        // 鼠标移上改变颜色
        ctx.fillStyle = '#F56C6C';
        // tooltip显示
        let el =  document.getElementById('self-tooltip');
        el.innerHTML = data.labels[index] + ":" + (percent * 100).toFixed(2) + "%";
        el.style.left = `${this.mousePosition.x + 15}px`;
        el.style.top = `${this.mousePosition.y + 15}px`;
        el.style.visibility = 'visible';
    }
    

    4、详细代码如下

    <template>
        <div class="box-style">
            <canvas :id="canvasId" :width="width"  :height="height" style="border: 1px solid #909399"></canvas>
            <span id="self-tooltip" class="tooltip-text"></span>
        </div>
    </template>
    
    <script>
    export default {
        props: {
            pieData: {
                type: Object,
                default: function() {
                    return {
                        colors: ['#AFB4DB', '#91CC75', '#FFC333', '#FFC0CB', '#73C0DE'], // 颜色
                        labels: ['周一', '周二', '周三', '周四', '周五'], //标签
                        values: [10, 20, 30 , 40, 50], //值
                        radius: 100 //圆半径
                    };
                }
            },
            width: {
                type: Number,
                default: function() {
                    return 400;
                }
            },
            height: {
                type: Number,
                default: function() {
                    return 400;
                }
            },
            canvasId: {
                type: String,
                default: function() {
                    return 'pie';
                }
            }
        },
        data() {
            return {
                // 鼠标移动是坐标
                mousePosition: {}
            }
        },
        mounted() {
            let pieElement = document.getElementById(this.canvasId);
            this.drawPie(pieElement, this.pieData);
            this.getPosition(pieElement);
        },
        methods: {
            // 画饼状图
            drawPie(element, data) {
                // 在画布上初始化绘图环境
                let ctx = element.getContext('2d');
                let drawData = data.values; // 画图数据
                let sum = this.getSum(drawData); //获取绘制数据的总和
                let sAngle = 0; // 扇形开始的角度
                let eAngle; // 结束的角度
                let x = element.width / 2;
                let y = element.height / 2; //圆心坐标
                let radius = data.radius;  // 圆半径
                let xMarker = 20; // 标记坐标
                let yMarker = 20; // 标记坐标
                drawData.forEach((value, index) => {
                    // 绘制饼图
                    let percent = value / sum; // 计算每个数据的占比,根据占比求扇形的弧度,即每个扇形结束的角度
                    eAngle = sAngle + Math.PI * 2 * (percent);
                    ctx.beginPath(); //新路径
                    ctx.fillStyle = data.colors[index];
                    ctx.moveTo(x, y);
                    ctx.arc(x, y, radius, sAngle, eAngle, false);
                    // 监听鼠标是否移动到绘制扇形处
                    if (ctx.isPointInPath(this.mousePosition.x, this.mousePosition.y)) {
                        // 鼠标移上改变颜色
                        ctx.fillStyle = '#F56C6C';
                        // tooltip显示
                        let el =  document.getElementById('self-tooltip');
                        el.innerHTML = data.labels[index] + ":" + (percent * 100).toFixed(2) + "%";
                        el.style.left = `${this.mousePosition.x + 15}px`;
                        el.style.top = `${this.mousePosition.y + 15}px`;
                        el.style.visibility = 'visible';
                    }
    
                    // 绘制左侧标记
                    ctx.moveTo(xMarker, yMarker);
                    // 绘制矩形
                    ctx.fillRect(xMarker, yMarker, 30, 10);
                    // 绘制文字
                    ctx.font = 'blod 14px';
                    ctx.txtalgin = 'center';
                    ctx.textBaseline = 'top';
                    
                    ctx.fillText(data.labels[index] + ":" + (percent * 100).toFixed(2) + "%", xMarker + 35, yMarker);
    
                    // 填充以上绘制
                    ctx.fill(); 
                    // 绘制下一个扇形时初始值改变
                    sAngle = eAngle;
                    yMarker += 20;
                });
            },
            // 求和
            getSum(data) {
                let sum = 0;
                data.map(value => {
                    sum += value;
                });
                return sum;
            },
            // 鼠标位置监听
            getPosition(element) {
                let mouseTimer = null;
                element.addEventListener('mousemove', (e) => {
                    e = e || window.event;
                    if ( e.ofSfsetX || e.offsetX==0 ) {
                        this.mousePosition.x = e.offsetX;
                        this.mousePosition.y = e.offsetY;
                    } else if ( e.layerX || e.layerX==0 ){
                        this.mousePosition.x = e.layerX;
                        this.mousePosition.y = e.layerY;
                    } 
    
                    // 监听tooltip显示
                    let el =  document.getElementById('self-tooltip');
                    el.style.visibility = 'hidden';
                    
                    clearTimeout(mouseTimer);
                    mouseTimer = setTimeout(() => {
                        this.drawPie(element, this.pieData);
                    }, 50)
                });
            }, 
        }
    }
    </script>
    
    <style lang="less" scoped>
    .box-style {
        position: relative;
        display: inline-block;
        width: 100%;
        height: 100%;
        // 画布
        canvas {
            cursor: pointer;
        }
    } 
    // 提示工具
    .tooltip-text {
        position: absolute;
        width: 150px;
        z-index: 10;
        background-color: #909399;
        color: #fff;
        border-radius: 5px;
        padding: 5px;
        left: 0;
        top: 0;
        visibility: hidden;
    }
    </style>>
    

    5、效果

    在这里插入图片描述

    展开全文
  • canvas入门&绘制动态饼图

    千次阅读 2019-07-18 15:47:51
    canvas是什么就不介绍了,我是怎么了解到canvas的我自己都不记得了,我只知道开始学习了解之后感觉就是欲罢不能啊,这东西很酷也很强大...不多说了,这里分两部分,第一部分是简单的入门,第二部分是绘制一个动态饼图

    canvas是什么就不介绍了,我是怎么了解到canvas的我自己都不记得了,我只知道开始学习了解之后感觉就是欲罢不能啊,这东西很酷也很强大,而我喜欢的原因就是它能够进行画画!当然它主要的用途是进行数据可视化,echarts就是canvas写的。不多说了,这里分两部分,第一部分是简单的入门,第二部分是绘制一个动态饼图。

    入门

    使用canvas你就理解为画画就好了,画画需要画布、画笔(或者说是工具箱,工具箱中有画笔这些),有了这两样东西就可以画画了,画画需要确定开始位置、结束位置,开始位置和结束位置之间如何连线的问题,然后是关注画笔的笔头形状,画笔颜色,填充颜色。基本上使用canvas就是这样一个思路了

    <style>
    	canvas{
    		border:1px solid #ccc;
    	}
    </style>
    <!--
    不要通过css进行画布大小的设置,canvas默认大小是300*150,如果通过css
    设置大小,其实是设置画布内容区域的大小,这会导致内容被拉大或缩小
    -->
    <canvas width="600" height="400"></canvas>
    
    //获取画板
    var myCanvas=document.querySelector('canvas');
    //获取上下文,(工具箱)
    var ctx=myCanvas.getContext('2d');
    
    //开启新路径,这样防止被其他未关闭的路径的影响
    ctx.beginPath();
    //移动到点(100,100)开始位置
    ctx.moveTo(100,100);
    //画到点(100,200)结束位置
    ctx.lineTo(100,200);
    //线条颜色
    ctx.strokeStyle="red";
    //线条宽度
    ctx.lineWidth=10;
    //描边,上面是进行画画的初始定义,stroke方法才是真正将线条画在画布上
    ctx.stroke();
    

    上面就是一个最基本的东西,了解一个最简单的线段应该如何画,剩下的画圆、矩形、曲线等,都可以通过工具箱ctx找得到对应的工具进行绘制,查看canvas文档就可以。
    注意:这里有线模糊的问题,原因是在进行绘制的时候是从线的中间画的,而显示器处理不了0.5这种问题,导致线变大变模糊,详细的东西自己去查查就知道了

    路径闭合的问题

    起始点moveTo和移动点lineTo的结束点无法完全闭合,会产生缺角的问题
    如果确定要闭合路径,可以使用canvas的自动闭合办法,在描边之前闭合

    ctx.closePath();
    

    填充区域和非零环绕

    对于闭合路径之间区域的填充问题,主要与路径轨迹的方向相关,这里会用到非零环绕原则,我个人的简记是顺加逆减
    通过一张图来进行非零环绕原则的理解,图是来自简书上的,地址
    在这里插入图片描述
    对于S1区域,从该区域内部向外拉一条线L1,方向随意,可以看到与L1相交的路径轨迹只有一条,方向是逆时针,减1,则相交轨迹总和为-1,不等于0,所以S1区域被填充。

    对于S2区域,与L2相交的轨迹为两条,方向都为逆时针,相交轨迹总和为-2,不等于0,所以S2被填充

    对于S3区域,与L3相加的轨迹为两条,一条为逆时针,减1,一条为顺时针,加1,则相交轨迹总和为0,所以S3区域不填充

    绘制动态饼图

    一般来说工作上使用canvas很多是用来做数据可视化(当然一般使用已有的库),也有用来做一些简单动画的,这里写的demo是参考了别人的写法进行的,原文见这里,我这里只写了如何进行动态效果的实现。节流没做到,有一个已知bug。效果图如下:
    在这里插入图片描述
    源码

    <!DOCTYPE html>
    <html lang="en">
    
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>动态饼图</title>
        <style>
            canvas {
                border: 1px solid #000;
                /* background-color: rgb(54, 252, 120); */
            }
    
            .draw {
                display: inline-block;
                left: 50%;
                top: 50%;
                position: absolute;
                transform: translate(-50%, -50%);
                cursor: pointer;
                overflow: hidden;
            }
    
            .tooltip {
                position: absolute;
                cursor: pointer;
                background-color: black;
                opacity: 0.5;
                color: rgb(255, 255, 255);
                padding: 12px;
            }
        </style>
    </head>
    
    <body>
        <div class="draw">
            <canvas width="600" height="400">你的浏览器不支持canvas</canvas>
            <div id="tooltip" class="tooltip"></div>
        </div>
        <script>
            let ctx = document.querySelector("canvas").getContext("2d");
            data = [
                { range: "0 - 59", count: 9, color: "rgb(252, 54, 54)" },
                { range: "60 - 69", count: 15, color: "rgb(249, 252, 54)" },
                { range: "70 - 79", count: 23, color: "rgb(54, 252, 54)" },
                { range: "80 - 89", count: 17, color: "rgb(252, 54, 252)" },
                { range: "90 - 100", count: 12, color: "rgb(54, 90, 252)" }
            ];
            function DrawPipe(data) {
                this.data = data;
                this.ctx = document.querySelector("canvas").getContext("2d");
                this.width = this.ctx.canvas.width;
                this.height = this.ctx.canvas.height;
                // 圆心与半径
                this.x0 = this.width / 2;
                this.y0 = this.height / 2;
                this.r = 100;
                // 运动速率
                this.steps = 1;
                this.stepsCounts = 50;
                this.speed = 1.2;
                // 初始化相关需要的值
                this.counts = 0;
                this.dataTransformToAngle = [];
                this.startAngle = 0;
                this.endAngle = 0;
                const that = this;
                // 鼠标移入坐标
                this.mousePosition = {};
                this.mouseTimer = null;
                // 计算总和
                this.data.forEach(element => {
                    that.counts += element.count;
                });
                // 计算角度
                this.data.forEach(item => {
                    // 我这里直接进行角度的转换了,和参考文章不一样,要注意了
                    // 一开始不注意困扰了我好久
                    item.angle = item.count / that.counts * Math.PI * 2;
                    that.dataTransformToAngle.push(item);
                });
            }
            DrawPipe.prototype.init = function () {
                this.dynamicPipe();
                this.addEvent();
            }
            // 开始画圆
            // 思路:将一个圆分成多个部分进行绘制。同时进行旋转使人眼看不到重新绘制的过程
            DrawPipe.prototype.dynamicPipe = function () {
                const that = this;
                // 这里用到save和restore方法,想想为什么
                this.ctx.save();
                // 这里是进行坐标系的偏移和设置旋转,如果要使用的话,圆心的位置要进行重新设置
                this.ctx.translate(this.x0, this.y0);
                this.ctx.rotate((Math.PI * 2 / this.stepsCounts) * this.steps / 2);
    
                this.dataTransformToAngle.forEach((item, i) => {
                    // 这里增加的角度不能是固定乘以多少倍,不然得到的值都是固定的
                    that.endAngle = that.endAngle + item.angle * that.steps / that.stepsCounts;
                    that.ctx.beginPath();
                    // 圆心的位置进行重新设置,半径看自己需要
                    that.ctx.moveTo(that.x0 - 300, that.y0 - 200);
                    that.ctx.arc(that.x0 - 300, that.y0 - 200, that.r * that.steps / that.stepsCounts, that.startAngle, that.endAngle);
    
                    if (that.ctx.isPointInPath(that.mousePosition.x, that.mousePosition.y)) {
                        that.ctx.moveTo(that.x0 - 300, that.y0 - 200);
                        that.ctx.arc(that.x0 - 300, that.y0 - 200, that.r + 10, that.startAngle, that.endAngle);
                        let text = (item.angle / (Math.PI * 2) * 100.00).toFixed(2) + '%';
                        that.toolTip(that.mousePosition.x, that.mousePosition.y, text);
                    }
    
                    that.ctx.closePath();
                    that.ctx.fillStyle = item.color;
                    that.ctx.fill();
                    that.ctx.globalAlpha = 1;
                    that.startAngle = that.endAngle;
    
                    // 画完一个周期把起始位置恢复
                    if (i == that.dataTransformToAngle.length - 1) {
                        that.startAngle = 0;
                        that.endAngle = 0;
                    }
    
                });
    
                this.ctx.restore();
    
                if (this.steps < this.stepsCounts) {
                    // 这个steps作用很重要,决定了动画的状态
                    this.steps++;
                    setTimeout(() => {
                        that.ctx.clearRect(0, 0, that.width, that.height);
                        that.dynamicPipe();
                    }, that.speed *= 1.085);
                }
            }
            DrawPipe.prototype.addEvent = function () {
                this.ctx.canvas.addEventListener("mousemove", function (e) {
                    // 这里就不做兼容了
                    this.mousePosition.x = e.offsetX;
                    this.mousePosition.y = e.offsetY;
                    clearTimeout(this.mouseTimer);
                    this.mouseTimer = setTimeout(() => {
                        this.ctx.clearRect(0, 0, this.width, this.height);
                        this.dynamicPipe();
                    }, 50);
                    if (!this.ctx.isPointInPath(this.mousePosition.x, this.mousePosition.y)) {
                        let doc = document.getElementById("tooltip");
                        doc.style.visibility = "hidden";
                    }
                }.bind(this))
            }
            DrawPipe.prototype.toolTip = function (x, y, text) {
                let doc = document.getElementById("tooltip");
                doc.style.visibility = "visible";
                if (doc.hasChildNodes()) {
                    doc.childNodes[0].innerText = text;
                    doc.style.left = x + 20 + "px";
                    doc.style.top = y + 20 + "px";
                }
                else {
                    let span = document.createElement("span");
                    span.innerText = text;
                    doc.style.left = x + 20 + "px";
                    doc.style.top = y + 20 + "px";
                    doc.appendChild(span);
                }
            }
            let test = new DrawPipe(data);
            test.init();
        </script>
    
    </body>
    
    </html>
    
    展开全文
  • flash报表中,比较出名的有以下三个,open flash chart(OFC),amcharts, funsionchart,OFC开源,但是感觉没其他两个漂亮。amcahrts感觉太复杂,功能太强一般都用不到。...一个动态饼图的demo打开test.html即可看到效果~!
  • 透视表做动态饼图有点小坑,话不多说上例子 1、原表 一般表格的形式都类似于这样 2、数据处理 不能直接插入透视表,需要先处理下数据形式 Alt+d 同时按两下 p-------多重合并计算数据区域--------下一步-----...

    透视表做动态饼图有点小坑,话不多说上例子

    1、原表

     一般表格的形式都类似于这样

    2、数据处理

    不能直接插入透视表,需要先处理下数据形式

    Alt+d  同时按两下  p-------多重合并计算数据区域--------下一步------选定区域-----选定表位置-------双击表右下角----

    ----会弹出一个新的sheet------删除最后一项-----插入数据透视表-----插入数据透视图------插入切片器(选择行)-----调整饼图格式

     

    Alt+d  同时按两下  p-------多重合并计算数据区域


    选定区域-----

    选定表位置------

    双击表右下角--------会弹出一个新的sheet------删除最后一项-----

    插入数据透视表-----

    插入数据透视图------

    插入切片器(选择行)-----

    调整饼图格式

    就酱啦

     

     

    展开全文
  • 现成的动态饼图

    2011-10-21 16:31:33
    本代码可以实现动态绘制饼图,下载后记得配置web.config还有数据库(sql)
  • AChartEngine应用之PieChart(动态饼图) 接着上一次写的内容,构建动态饼图,并产生与用户交互,官方的API并没有提供可以借鉴的动态更新饼图的方法,考虑到数据都是活动的,不可能总是用静态数据,所以我下面的demo...
  • 柱状图、饼图比例展示,根据年份自动变化,饼图柱状图相互切换。
  • 在一些统计类软件中,我们经常看到饼图、柱图等效果,那么在VB中能不能...今天烈火下载就给大家带来了一款形象的三维动态饼图、比例效果,源程序免费提供给大家学习和研究,请勿用于商业,在此我们对原作者表示感谢!
  • 如果你已经看了前面的关于曲线和柱状图的实现,饼图你看...javascript, jquery highcharts 高级应用—动态饼图的实现" width="600" border="0"> 直接运行该JSP,你会看到效果,代码如下: java" import="java
  • 安卓实现AChartEngine+动态饼图+柱形图

    热门讨论 2014-01-16 23:10:06
    官方的API并没有提供可以借鉴的动态更新饼图的方法,考虑到数据都是活动的,不可能总是用静态数据,所以我下面的demo就是模拟动态数据用饼图显示,但是肯定可以使用的,具体是通过定时器+Handler实现定时任务,通过...
  • Flash 制作动态饼图

    千次阅读 2006-06-15 12:02:00
    Flash 制作动态饼图 2002-09-27· ·dofy··天极设计在线 1 2 3 下一页
  • Datav的动态饼图还是挺好用的, 下载datav:npm install @jiaminghi/data-view main.js中引入:import dataV from ‘@jiaminghi/data-view’ Vue.use(dataV) 我做的是假数据展示,真实数据渲染的话可以参考别的大神...
  • 用Python制作动态饼图

    2021-01-14 16:04:45
    前言 本文的文字及图片来源于网络,仅供学习、交流使用,不具有任何商业用途,如有问题请及时联系我们以作处理。 ... ... 假设有一块蛋糕,分给猫猫、狗狗、牛牛和羊羊四个小动物吃。...想要画这样一张饼图,可以用以下Python
  • h5--手写svg动态饼图

    2019-06-12 20:22:00
    手写了一个动态饼图效果如下,由于不会传视频不清晰请见谅 做这个的难点是三角函数的知识可能忘干净了。现在来整理下思路 首先我们需要分析环形有哪些属性  圆心,外半径,内半径,两个个可变的数组...
  • 这次给大家带来ajax实现动态饼图和柱形图的图文详解,ajax实现动态饼图和柱形图的注意事项有哪些,下面就是实战案例,一起来看一下。本文以柱形图和饼形图ajax动态赋值为例一、饼形图赋值步骤(1)jsp页面[html] view ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 12,666
精华内容 5,066
关键字:

动态饼图