• html5实现饼图和线图-我们到底能走多远系列(34)


    我们到底能走多远系列(34)

    扯淡:

      送给各位一段话:

        人生是一个不断做加法的过程
        从赤条条无牵无挂的来
        到学会荣辱羞耻 礼仪规范
        再到赚取世间的名声 财富 地位
        但是人生还要学会做减法
        财富名声这些身外之物有一天会失去
        朋友 亲人终有一天会离你而去
        我们自己会衰老 迟钝
        最后赤条条的离开这个世界
        我们都不太擅长做人生的减法
        很难学会放下
        放不下面子 所以要打肿脸充胖子
        放不下逝去的情感 就会沉溺其中 痛苦不堪
        放不下输赢 所以总是如履薄冰 心惊胆战
        佛说 我执 是痛苦的根源
        人生要学会 断 舍 离
        断绝不需要的东西
        舍弃多余的废物
        脱离对物品的执念
        所以想幸福 请先放下
     
     
    主题:
     
      最近想用html5来话图表,就接触了下,发现html5 是一个总称而已,进去后里面分成各种标签比如:HTML5 Video,HTML5 Audio,HTML5 Canvas等等,各不相关,所以学习起来也不复杂,比如我想画图表就先学习下Canvas就好了。
      
      所以,我感觉这东西也就是调下api,没什么太大的难度,难得地方是要实现一个东西还需要学习css,javascript这些东西才行。
      
      自己画的线图: 用一个function包起来,是为了简单的封装一下内部的变量。
      
      需要注意的是代码依赖jquery。
      
      这是一个比较初步的实现,对于canvas上画图,其实直接理解成现实中那笔在话就可以了,像下面的线图,先画好x y 轴,然后再话线,再来画事件现实文字。画面变化的产生目前我发现的是用clearRect方法先清空画面,然后重画....
     
    function lineChart(data){
        var xPadding = 60;//x轴离边框的距离
        var yPadding = 50;//y轴离边框的距离
        var canvasWidth;
        var canvasHeight;
        var xAxisLength; //x轴长度
        var yAxisLength; //y轴长度
        var xTextColour = "#000000";   // x轴字体颜色
        var yTextColour = "#000000";  // y轴字体颜色
        var dotsColour = "#183487";  // 图标点的颜色
        var lineWidth = 2 //线宽度
        var lineColour = "#194E9C";  // 线颜色
        var lineShadowColour = "rgba( 0, 0, 0, .5 )"; // 线阴影颜色
        var lineShadowBlur = 15;
        var lineShadowOffsetX = 3;
        var lineShadowOffsetY = 3;
        var xyColour = "#4B0082";   //xy轴颜色
        var xToTextlength = 20; //x轴和文字的间距
        var yToTextlength = 10; //y轴和文字的间距
        var yTextNum = 6;  //y轴和文字数量
        var chartLineFont = "bold 16px 'Trebuchet MS', Verdana, sans-serif";// xy轴字体
        var chooseDotTextFont = "bold 16px 'Trebuchet MS', Verdana, sans-serif";//显示提示字体
        var dotsToDotsXLength; //x轴间距
        var dotsXArray = [];
        var divideXArray = [];  //分割每个点的竖切线的x坐标
        var lineChart;                       // The canvas element in the page
        init(data);
    
        function init(data){
            lineChart =  document.getElementById('lineChart');
            // Initialise some properties of the canvas and chart
            canvasWidth = lineChart.width;
            canvasHeight = lineChart.height;
            xAxisLength = canvasWidth - 2*xPadding;
            yAxisLength = canvasHeight - 2*yPadding;
            dotsToDotsXLength = xAxisLength / data.length;
            drawLineChart();
            // 添加事件
            $('#lineChart').mousemove(handleDotsMousemoveEvent);
        }
    
        function drawLineChart(index){
            var c = lineChart.getContext('2d');
            // Clear the canvas, ready for the new frame
            c.clearRect ( 0, 0, canvasWidth, canvasHeight );
            
            c.lineWidth = lineWidth;
            c.strokeStyle = xyColour;
            
            // Draw the axises
            c.beginPath();
            c.moveTo(xPadding, yPadding);
            // y轴
            c.lineTo(xPadding, lineChart.height - yPadding);
            // x轴
            c.lineTo(lineChart.width - yPadding, lineChart.height - yPadding);
            c.stroke();
            
            // Draw the the background line
            c.beginPath();
            c.strokeStyle = '#D9D6D6';
            for(var i = 0; i <= getMaxYPoint(getMaxY()); i += getYSpace()) {
                if(i != 0){
                    c.moveTo(xPadding + 2, getYPixel(i));
                    c.lineTo(xPadding + xAxisLength + 2, getYPixel(i));
                }
            }
            c.stroke();
            
            // Draw the X value texts
            c.font = chartLineFont;
            c.fillStyle = xTextColour;
            c.textAlign = "center";
            var step = parseInt(data.length/yTextNum);
            for(var i = 0; i < data.length; i =i + step) {
                c.fillText(data[i].X, getXPixel(i), lineChart.height - yPadding + xToTextlength);
            }
            
            // Draw the Y value texts
            c.textAlign = "right";
            c.textBaseline = "middle";
            c.fillStyle = yTextColour;
            for(var i = 0; i <= getMaxYPoint(getMaxY()); i += getYSpace()) {
                c.fillText(formatNum(i), xPadding - yToTextlength, getYPixel(i));
            }
            
            // Draw the line graph
            drawLineAndDots(c, index);
        }
    
        /**
         * 画线
         * @param c
         * @param index
         */
        function drawLineAndDots(c, index){
            c.beginPath();
            c.strokeStyle = lineColour;
            c.moveTo(getXPixel(0), getYPixel(data[0].value));
            for(var i = 1; i < data.length; i ++) {
                // 使用直线
                //c.lineTo(getXPixel(i), getYPixel(data[i].value));
                //var cps = getControlPoints(getXPixel(i-1),getYPixel(data[i-1].value),getXPixel(i),getYPixel(data[i].value));
                //为了更美观一点 使用了弯曲的线 
                c.bezierCurveTo(getXPixel(i-1)+9,getYPixel(data[i-1].value)+9,getXPixel(i)-9,getYPixel(data[i].value)-9,getXPixel(i), getYPixel(data[i].value))
                
                /**
                // 线的阴影部分
                c.shadowBlur = lineShadowBlur;
                c.shadowOffsetX = lineShadowOffsetX;
                c.shadowOffsetY = lineShadowOffsetY;
                c.shadowColor = lineShadowColour;
                **/
                
            }
    
            c.stroke();
            c.shadowColor = "rgba( 0, 0, 0, 0 )";
            c.closePath();
            // Draw the dots
            c.fillStyle = dotsColour;
    
            for(var i = 0; i < data.length; i ++) {
                // 有点中的节点
                if(i == index){
                    c.beginPath();
                    c.arc(getXPixel(i), getYPixel(data[i].value), 8, 0, Math.PI * 2, true);
                    c.fill();
                    c.textAlign = "center";
                    c.font = chooseDotTextFont;
                    c.fillText(data[i].X, xAxisLength + xPadding + 5 , 20 )
                    c.fillText(data[i].value, xAxisLength + xPadding + 5 , 40 )
                }else{
                    c.beginPath();
                    c.arc(getXPixel(i), getYPixel(data[i].value), 4, 0, Math.PI * 2, true);
                    c.fill();
                }
                divideXArray[i] = getXPixel(i) + dotsToDotsXLength/2;
            }
        }
    
        function getMaxY() {
            var max = 0;
            for(var i = 0; i < data.length; i ++) {
                if(data[i].value > max) {
                    max = data[i].value;
                }
            }
            max += 10 - max % 10;
            return max;
        }
    
        /**
         * 计算x轴间距
         * @param val
         * @returns {number}
         */
        function getXPixel(val) {
            return (dotsToDotsXLength) * val + (xPadding * 1.5);
        }
    
        /**
         * 计算y轴间距
         * @param val
         * @returns {number}
         */
        function getYPixel(val) {
            return lineChart.height - ((yAxisLength / getMaxYPoint(getMaxY())) * val) - yPadding;
        }
    
        /**
         * 计算Y轴显示最大值
         * 输入1234 输出2000
         * @param maxY
         */
        function getMaxYPoint(maxY){
            var firstDigit  =  parseInt((maxY + '').substring(0,1)) + 1;
            var digitNum =  parseInt((maxY+"").length);
            for(var i = 1; i<digitNum; i++){
                firstDigit = firstDigit *10
            }
            return firstDigit;
        }
    
        /**
         * 计算Y轴坐标增加数量
         * @returns {number}
         */
        function getYSpace(){
            return getMaxYPoint(getMaxY())/5;
        }
    
        /**
         * 格式化:三位数字加逗号
         * @param num
         * @returns {*}
         */
        function formatNum(num){
            if(!/^(+|-)?d+(.d+)?$/.test(num)){
                alert("wrong!");
                return num;
            }
            var re = new RegExp();
            re.compile("(\d)(\d{3})(,|\.|$)");
            num += "";
            while(re.test(num)){
                num = num.replace(re, "$1,$2$3")
            }    
            return num;
        }
    
        //鼠标事件
        function handleDotsMousemoveEvent(mousemoveEvent){
            //取得鼠标位置
            var mouseX = mousemoveEvent.pageX - this.offsetLeft;
            var dot = 0;
            if(0 < mouseX && mouseX< xPadding){
                return;
            }
            if((xPadding + xAxisLength) < mouseX){
                return;
            }
            for(var i=0; i<divideXArray.length; i++){
                
                if(mouseX < divideXArray[i]){
                    dot = i;
                    break;
                }
            }
            drawLineChart(dot);
        }
    }
    效果:
     
     
     
     
     饼图:
    里面有详细的解释。
    注意以上网站上的源码无法直接使用所以 本人进行了部分的修改,以实现能够动态的处理后台传输的数据,并增加一个栏目,使功能完整。可以直接作为插件放入项目。
     

    修改后的代码:(直接保存html文件即可)

    <!DOCTYPE html>
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
    <title>Pie Chart with HTML5 and jQuery - 1.0</title>
    <meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
    
    <style>
    
    body {
      background: #fff;
      color: #333;
      font-family: "Trebuchet MS", Verdana, Arial, Helvetica, sans-serif;
      font-size: 0.9em;
      padding: 40px;
    }
    
    #container {
       900px;
      margin: 0 auto;
    }
    
    .chart, .chartData {
      border: 1px solid #333;
      background: #ebedf2 url("images/gradient.png") repeat-x 0 0;
    }
    
    .chart {
      display: block;
      margin: 0 0 50px 0;
      float: left;
      cursor: pointer;
    }
    
    .chartData {
       200px;
      margin: 0 40px 0 0;
      float: right;
      border-collapse: collapse;
      box-shadow: 0 0 1em rgba(0, 0, 0, 0.5);
      -moz-box-shadow: 0 0 1em rgba(0, 0, 0, 0.5);
      -webkit-box-shadow: 0 0 1em rgba(0, 0, 0, 0.5);
      background-position: 0 -100px;
    }
    
    .chartData th, .chartData td {
      padding: 0.5em;
      border: 1px dotted #666;
      text-align: left;
    }
    
    .chartData th {
      border-bottom: 2px solid #333;
      text-transform: uppercase;
    }
    
    .chartData td {
      cursor: pointer;
    }
    
    .chartData td.highlight {
      background: #e8e8e8;
    }
    
    .chartData tr:hover td {
      background: #f0f0f0;
    }
    
    </style>
    
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
    <!--[if IE]>
    <script src="http://explorercanvas.googlecode.com/svn/trunk/excanvas.js"></script>
    <![endif]-->
    </head>
    <body>
    
    <div id="container">
    
      <canvas id="chart" width="600" height="500" class="chart"></canvas>
    
      <table id="chartData" class="chartData">
        <tr><th>Widget</th><th>Sales ($)</th><th>prcent (%)</th></tr>
      </table>
    
    </div>
    
    </body>
    </html>
    <script>
    var data=[{label:"SuperWidget",value:1862.12},{label:"MegaWidget1",value:1316.00},{label:"redasd",value:1300.00},{label:"hope",value:300.00},{label:"hack",value:300.00},{label:"MegaWidget",value:1316.00},{label:"redasd",value:1300.00},{label:"hope",value:300.00},{label:"hack",value:300.00}];
    // Run the code when the DOM is ready
    //$( pieChart );
    pieChart(data, 'chart', 'chartData');
    
    function pieChart(data, chartElementId, chartTableElementId) {
    
      // Config settings
      var chartSizePercent = 55;                        // The chart radius relative to the canvas width/height (in percent)
      var sliceBorderWidth = 1;                         // Width (in pixels) of the border around each slice
      var sliceBorderStyle = "#fff";                    // Colour of the border around each slice
      var sliceGradientColour = "#ddd";                 // Colour to use for one end of the chart gradient
      var maxPullOutDistance = 25;                      // How far, in pixels, to pull slices out when clicked
      var pullOutFrameStep = 4;                         // How many pixels to move a slice with each animation frame
      var pullOutFrameInterval = 40;                    // How long (in ms) between each animation frame
      var pullOutLabelPadding = 65;                     // Padding between pulled-out slice and its label  
      var pullOutLabelFont = "bold 16px 'Trebuchet MS', Verdana, sans-serif";  // Pull-out slice label font
      var pullOutValueFont = "bold 12px 'Trebuchet MS', Verdana, sans-serif";  // Pull-out slice value font
      var pullOutValuePrefix = "";                     // Pull-out slice value prefix
      var pullOutShadowColour = "rgba( 0, 0, 0, .5 )";  // Colour to use for the pull-out slice shadow
      var pullOutShadowOffsetX = 5;                     // X-offset (in pixels) of the pull-out slice shadow
      var pullOutShadowOffsetY = 5;                     // Y-offset (in pixels) of the pull-out slice shadow
      var pullOutShadowBlur = 5;                        // How much to blur the pull-out slice shadow
      var pullOutBorderWidth = 2;                       // Width (in pixels) of the pull-out slice border
      var pullOutBorderStyle = "#333";                  // Colour of the pull-out slice border
      var chartStartAngle = -.5 * Math.PI;              // Start the chart at 12 o'clock instead of 3 o'clock
    
      // Declare some variables for the chart
      var canvas;                       // The canvas element in the page
      var currentPullOutSlice = -1;     // The slice currently pulled out (-1 = no slice)
      var currentPullOutDistance = 0;   // How many pixels the pulled-out slice is currently pulled out in the animation
      var animationId = 0;              // Tracks the interval ID for the animation created by setInterval()
      var chartData = data;               // Chart data (labels, values, and angles)
      var chartColours = [];            // Chart colours (pulled from the HTML table)
      var totalValue = 0;               // Total of all the values in the chart
      var canvasWidth;                  // Width of the canvas, in pixels
      var canvasHeight;                 // Height of the canvas, in pixels
      var centreX;                      // X-coordinate of centre of the canvas/chart
      var centreY;                      // Y-coordinate of centre of the canvas/chart
      var chartRadius;                  // Radius of the pie chart, in pixels
      
      var chartElementId = chartElementId; // 圆饼元素id
      var chartTableElementId = chartTableElementId; // 数据表格元素id
      
      // Set things up and draw the chart
      init();
    
    
      /**
       * Set up the chart data and colours, as well as the chart and table click handlers,
       * and draw the initial pie chart
       */
    
      function init() {
        var colors=['#FF4500','#0DA068','#194E9C','#ED9C13','#ED5713','#CD00CD','#7A378B','#B8860B','#8B2500','#9932CC','#5F91DC','#F88E5D','#0000FF','#B3EE3A','#7A378B','#FF1493','#F5DA81','#80FF00','#173B0B','#0B3B39','#0B0B3B','#A901DB','#6E6E6E','#5F04B4','#01DFD7','#A31A1A','#1A653C','#A49D0C','#790CA4','#CA80E8','#6E87D7','#D76ED2','#D7B86E','#49543B','#9EEBE8','#9ED9EB','#549B21']
        // Get the canvas element in the page
        canvas = document.getElementById(chartElementId);
    
        // Exit if the browser isn't canvas-capable
        if ( typeof canvas.getContext === 'undefined' ) return;
    
        // Initialise some properties of the canvas and chart
        canvasWidth = canvas.width;
        canvasHeight = canvas.height;
        centreX = canvasWidth / 2;
        centreY = canvasHeight / 2;
        chartRadius = Math.min( canvasWidth, canvasHeight ) / 2 * ( chartSizePercent / 100 );
    
        // Grab the data from the table,
        // and assign click handlers to the table data cells
        
        var currentRow = 0;
        var currentCell = 0;
        //$('#chartData').append('<tr><th>Widget</th><th>Sales ($)</th><th>prcent (%)</th></tr>')
        $.each(chartData, function(index,value){
            totalValue += value.value;
        });
        $.each(chartData, function(index,value){
            $('#'+chartTableElementId).append('<tr style="color: '+colors[index]+'"><td>'+value.label+'</td><td>'+value.value+'</td><td>'+ ( value.value / totalValue * 100 + .5 ).toFixed(2) +  '%'+'</td></tr>')
            
        });
    
        $('#'+chartTableElementId+' td').each( function() {
          currentCell++;
          // Store the slice index in this cell, and attach a click handler to it
          $(this).data( 'slice', currentRow );
          $(this).click( handleTableClick );
          // Extract and store the cell colour
          if ( rgb = $(this).css('color').match( /rgb((d+), (d+), (d+)/) ) {
            chartColours[currentRow] = [ rgb[1], rgb[2], rgb[3] ];
          } else if ( hex = $(this).css('color').match(/#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/) ) {
            chartColours[currentRow] = [ parseInt(hex[1],16) ,parseInt(hex[2],16), parseInt(hex[3], 16) ];
          } else {
            alert( "Error: Colour could not be determined! Please specify table colours using the format '#xxxxxx'" );
            return;
          }
          if(currentCell % 3 == 0){
            currentRow++;
          }
        } );
    
        // Now compute and store the start and end angles of each slice in the chart data
    
        var currentPos = 0; // The current position of the slice in the pie (from 0 to 1)
    
        for ( var slice in chartData ) {
          chartData[slice]['startAngle'] = 2 * Math.PI * currentPos;
          chartData[slice]['endAngle'] = 2 * Math.PI * ( currentPos + ( chartData[slice]['value'] / totalValue ) );
          currentPos += chartData[slice]['value'] / totalValue;
        }
    
        // All ready! Now draw the pie chart, and add the click handler to it
        drawChart();
        $('#'+chartElementId).click ( handleChartClick );
      }
    
    
      /**
       * Process mouse clicks in the chart area.
       *
       * If a slice was clicked, toggle it in or out.
       * If the user clicked outside the pie, push any slices back in.
       *
       * @param Event The click event
       */
    
      function handleChartClick ( clickEvent ) {
    
        // Get the mouse cursor position at the time of the click, relative to the canvas
        var mouseX = clickEvent.pageX - this.offsetLeft;
        var mouseY = clickEvent.pageY - this.offsetTop;
    
        // Was the click inside the pie chart?
        var xFromCentre = mouseX - centreX;
        var yFromCentre = mouseY - centreY;
        var distanceFromCentre = Math.sqrt( Math.pow( Math.abs( xFromCentre ), 2 ) + Math.pow( Math.abs( yFromCentre ), 2 ) );
    
        if ( distanceFromCentre <= chartRadius ) {
    
          // Yes, the click was inside the chart.
          // Find the slice that was clicked by comparing angles relative to the chart centre.
    
          var clickAngle = Math.atan2( yFromCentre, xFromCentre ) - chartStartAngle;
          if ( clickAngle < 0 ) clickAngle = 2 * Math.PI + clickAngle;
                      
          for ( var slice in chartData ) {
            if ( clickAngle >= chartData[slice]['startAngle'] && clickAngle <= chartData[slice]['endAngle'] ) {
    
              // Slice found. Pull it out or push it in, as required.
              toggleSlice ( slice );
              return;
            }
          }
        }
    
        // User must have clicked outside the pie. Push any pulled-out slice back in.
        pushIn();
      }
    
    
      /**
       * Process mouse clicks in the table area.
       *
       * Retrieve the slice number from the jQuery data stored in the
       * clicked table cell, then toggle the slice
       *
       * @param Event The click event
       */
    
      function handleTableClick ( clickEvent ) {
        var slice = $(this).data('slice');
        toggleSlice ( slice );
      }
    
    
      /**
       * Push a slice in or out.
       *
       * If it's already pulled out, push it in. Otherwise, pull it out.
       *
       * @param Number The slice index (between 0 and the number of slices - 1)
       */
    
      function toggleSlice ( slice ) {
        if ( slice == currentPullOutSlice ) {
          pushIn();
        } else {
          startPullOut ( slice );
        }
      }
    
     
      /**
       * Start pulling a slice out from the pie.
       *
       * @param Number The slice index (between 0 and the number of slices - 1)
       */
    
      function startPullOut ( slice ) {
    
        // Exit if we're already pulling out this slice
        if ( currentPullOutSlice == slice ) return;
    
        // Record the slice that we're pulling out, clear any previous animation, then start the animation
        currentPullOutSlice = slice;
        currentPullOutDistance = 0;
        clearInterval( animationId );
        animationId = setInterval( function() { animatePullOut( slice ); }, pullOutFrameInterval );
    
        // Highlight the corresponding row in the key table
                $('#'+chartTableElementId+' td').removeClass('highlight');
        var labelCell = $('#'+chartTableElementId+' td:eq(' + (slice*3) + ')');
        var valueCell = $('#'+chartTableElementId+' td:eq(' + (slice*3+1) + ')');
        var prcentCell = $('#'+chartTableElementId+' td:eq(' + (slice*3+2) + ')');
        labelCell.addClass('highlight');
        valueCell.addClass('highlight');
        prcentCell.addClass('highlight');
      }
    
     
      /**
       * Draw a frame of the pull-out animation.
       *
       * @param Number The index of the slice being pulled out
       */
    
      function animatePullOut ( slice ) {
    
        // Pull the slice out some more
        currentPullOutDistance += pullOutFrameStep;
    
        // If we've pulled it right out, stop animating
        if ( currentPullOutDistance >= maxPullOutDistance ) {
          clearInterval( animationId );
          return;
        }
    
        // Draw the frame
        drawChart();
      }
    
     
      /**
       * Push any pulled-out slice back in.
       *
       * Resets the animation variables and redraws the chart.
       * Also un-highlights all rows in the table.
       */
    
      function pushIn() {
        currentPullOutSlice = -1;
        currentPullOutDistance = 0;
        clearInterval( animationId );
        drawChart();
        $('#'+chartTableElementId+' td').removeClass('highlight');
      }
     
     
      /**
       * Draw the chart.
       *
       * Loop through each slice of the pie, and draw it.
       */
    
      function drawChart() {
    
        // Get a drawing context
        var context = canvas.getContext('2d');
            
        // Clear the canvas, ready for the new frame
        context.clearRect ( 0, 0, canvasWidth, canvasHeight );
    
        // Draw each slice of the chart, skipping the pull-out slice (if any)
        for ( var slice in chartData ) {
          if ( slice != currentPullOutSlice ) drawSlice( context, slice );
        }
    
        // If there's a pull-out slice in effect, draw it.
        // (We draw the pull-out slice last so its drop shadow doesn't get painted over.)
        if ( currentPullOutSlice != -1 ) drawSlice( context, currentPullOutSlice );
      }
    
    
      /**
       * Draw an individual slice in the chart.
       *
       * @param Context A canvas context to draw on  
       * @param Number The index of the slice to draw
       */
    
      function drawSlice ( context, slice ) {
    
        // Compute the adjusted start and end angles for the slice
        var startAngle = chartData[slice]['startAngle']  + chartStartAngle;
        var endAngle = chartData[slice]['endAngle']  + chartStartAngle;
          
        if ( slice == currentPullOutSlice ) {
    
          // We're pulling (or have pulled) this slice out.
          // Offset it from the pie centre, draw the text label,
          // and add a drop shadow.
    
          var midAngle = (startAngle + endAngle) / 2;
          var actualPullOutDistance = currentPullOutDistance * easeOut( currentPullOutDistance/maxPullOutDistance, .8 );
          startX = centreX + Math.cos(midAngle) * actualPullOutDistance;
          startY = centreY + Math.sin(midAngle) * actualPullOutDistance;
          context.fillStyle = 'rgb(' + chartColours[slice].join(',') + ')';
          context.textAlign = "center";
          context.font = pullOutLabelFont;
          context.fillText( chartData[slice]['label'], centreX + Math.cos(midAngle) * ( chartRadius + maxPullOutDistance + pullOutLabelPadding ), centreY + Math.sin(midAngle) * ( chartRadius + maxPullOutDistance + pullOutLabelPadding ) );
          context.font = pullOutValueFont;
          context.fillText( pullOutValuePrefix + chartData[slice]['value'] + " (" + (  chartData[slice]['value'] / totalValue * 100 + .5 ).toFixed(2) +  "%)", centreX + Math.cos(midAngle) * ( chartRadius + maxPullOutDistance + pullOutLabelPadding ), centreY + Math.sin(midAngle) * ( chartRadius + maxPullOutDistance + pullOutLabelPadding ) + 20 );
          context.shadowOffsetX = pullOutShadowOffsetX;
          context.shadowOffsetY = pullOutShadowOffsetY;
          context.shadowBlur = pullOutShadowBlur;
    
        } else {
    
          // This slice isn't pulled out, so draw it from the pie centre
          startX = centreX;
          startY = centreY;
        }
    
        // Set up the gradient fill for the slice
        var sliceGradient = context.createLinearGradient( 0, 0, canvasWidth*.75, canvasHeight*.75 );
        sliceGradient.addColorStop( 0, sliceGradientColour );
        sliceGradient.addColorStop( 1, 'rgb(' + chartColours[slice].join(',') + ')' );
    
        // Draw the slice
        context.beginPath();
        context.moveTo( startX, startY );
        context.arc( startX, startY, chartRadius, startAngle, endAngle, false );
        context.lineTo( startX, startY );
        context.closePath();
        context.fillStyle = sliceGradient;
        context.shadowColor = ( slice == currentPullOutSlice ) ? pullOutShadowColour : "rgba( 0, 0, 0, 0 )";
        context.fill();
        context.shadowColor = "rgba( 0, 0, 0, 0 )";
    
        // Style the slice border appropriately
        if ( slice == currentPullOutSlice ) {
          context.lineWidth = pullOutBorderWidth;
          context.strokeStyle = pullOutBorderStyle;
        } else {
          context.lineWidth = sliceBorderWidth;
          context.strokeStyle = sliceBorderStyle;
        }
    
        // Draw the slice border
        context.stroke();
      }
    
    
      /**
       * Easing function.
       *
       *
       * @param Number The ratio of the current distance travelled to the maximum distance
       * @param Number The power (higher numbers = more gradual easing)
       * @return Number The new ratio
       */
    
      function easeOut( ratio, power ) {
        return ( Math.pow ( 1 - ratio, power ) + 1 );
      }
    };
    
    </script>
    View Code

    总结:

     
    1,我们完全可以只利用API画出自己想要的东西API
     
    2,关于html5图表的插件有很多比如:国内的 国外的  
    3,阅读网站:http://diveintohtml5.info/
     
    4,不管html5以后发不发展,学点然后做个比较复杂的动画玩玩,也不错
     
     
     补充:
      鉴于项目压力,为了竟可能满足需求,可能最终我们不得不选择网上更加成熟的框架,但无论如何,本人还是希望能够完善出一个比较好的图表框架出来。
     
     
     

    让我们继续前行

    ----------------------------------------------------------------------

    努力不一定成功,但不努力肯定不会成功。
    共勉。

  • 相关阅读:
    Git设置HTTP/HTTPS代理服务器
    队列(Queue)顺序存储C语言实现
    二叉树前序序列和中序序列转为后序序列
    CFileDialog对话框中,如何修改对话框标题
    轻型读写锁 Slim Reader/Writer (SRW) Locks
    PC lint -sem 用法示例
    C# Linq 取得两个列表的交集
    wpf datagrid row的命中测试
    C# Unit Test 备注
    DataGrid 滚动特定的行或者列
  • 原文地址:https://www.cnblogs.com/killbug/p/3333675.html
Copyright © 2020-2023  润新知