zoukankan      html  css  js  c++  java
  • 用Raphael绘制雷达图(radar chart)

    首先新建一个项目,当前要先在数据库设置一下。项目说简单也简单,说难也难。要用到Ajax与Raphael类库,不过更多的时候自己舞弄三角函数(做统计这少不了。)

    接着删除public下的index.html,并在routes下添加:

      map.root :abilities#★★★★
      # Install the default routes as the lowest priority.
      # Note: These default routes make all actions in every controller accessible via GET requests. You should
      # consider removing the them or commenting them out if you're using named routes and resources.
      map.connect ':controller/:action/:id'
      map.connect ':controller/:action/:id.:format'
    

    随便填几个数值。

    前台show.erb用Ajax来调用数据:

    <%= javascript_tag "window._token = '#{form_authenticity_token}'" if ActionController::Base.allow_forgery_protection %>
    <%= javascript_include_tag :defaults,"raphael" %>
    <script>
      window.onload = function(){
        var s= '&authenticity_token=' + window._token;
        var id = window.location.toString().split("/").last();
        new Ajax.Request("/abilities/show/"+id, {
          asynchronous:true,
          evalScripts:true,
          method:'post',
          parameters:s
        });
      }
    </script>
    <div id="holder"></div>
    
    <%= link_to 'Edit', edit_ability_path(@ability) %> |
    <%= link_to 'Back', abilities_path %>
    

    利用Prototype玩Ajax就是这么简单。由于Rails2.0中加入了form_authenticity_token来防止部分的cross-site的攻击,我们需要用一个全局变量来保存这个东西,然后作为Ajax的一个变量请求回去,防止ActionController::InvalidAuthenticityToken错误。

    然后在后台添加以下代码,全部包围在一个选择肢中,只有是xhr请求才会调用它们:

    主要要点是这是个五边形,因此我们先用360/5得出得每个点偏移的角度,我们通过cos与sin求得每个点的坐标。

    //以半径当作三角形的斜边
    //斜边*余弦得出点投射到X轴的坐标
    //斜边*正弦得出点投射到Y轴的坐标
    //我们以圆心边坐标系的中心,因此要分别加上圆心的X坐标与Y坐标
        var x=圆心X坐标+半径*Math.cos(-偏移的角度)*Math.PI/180)
        var y=圆心Y坐标+半径*Math.sin(-偏移的角度)*Math.PI/180)
    //角度之所以取负,是因为屏幕的坐标系与数学上的坐标系是相反的
    

    得出这五个点后,我们用path函数把它们连起来就是,和SVG的用法很相近。最后,后台截获我们的XHR请求就会完美地生成我们的雷达图。

    var paper=Raphael("holder",400,300),
    radii=120,
    cc=[200,150],
    ability=["认真","聪明","人气","人品","运气"],
    data=[78,90,67,100,80],
    color={
        keynote:"#586F85",
        circle:"#B3E2D5",
        bg:"#EEFFEE",
        edge:"#474747",
        shadow:"#ABD7CB",
        light:"#fff",
        dark:"#000"
    },
    circleStyle={
        fill:color.circle,
        stroke:color.edge,
        "stroke-dasharray":"- "
    },
    labelStyle={
        fill:color.dark,
        font:"12px 'Microsoft YaHei',Arial"
    },
    outterLabelStyle={
        stroke:color.shadow,
        "stroke-opacity":0.5,
        "stroke-linecap":"round",
        "stroke-width":"20px"
    },
    frameStyle={
        fill:color.light,
        stroke:color.dark,
        "stroke-width":1
    },
    coords=[];
    paper.rect(0,0,398,298,10).attr({
        fill:color.bg,
        stroke:color.edge,
        "stroke-width":"1px"
    });
    for(var i=0,n=data.length;i<n;i++){
        var x=+(cc[0]+data[i]/100*radii*Math.cos(-(18+72*i)*Math.PI/180)).toFixed(2),
        y=+(cc[1]+data[i]/100*radii*Math.sin(-(18+72*i)*Math.PI/180)).toFixed(2),
        el=[x,y],
        lineX=+(cc[0]+(radii-2)*Math.cos(-(18+72*i)*Math.PI/180)).toFixed(2),
        lineY=+(cc[1]+(radii-2)*Math.sin(-(18+72*i)*Math.PI/180)).toFixed(2),
        line=["M",cc[0],cc[1],"L",lineX,lineY,"z"],
        outX=cc[0]+(radii+20)*Math.cos(-(18+72*i)*Math.PI/180),
        outY=cc[1]+(radii+20)*Math.sin(-(18+72*i)*Math.PI/180);
        paper.circle(cc[0],cc[1],radii*(100-20*i)/100).attr(circleStyle);
        coords.push(el);
        paper.path(outterLabelStyle,line.join(" "));
        paper.text(outX,outY,ability[i]).attr({
            "font-size":"14px",
            "font-weight":700
        }).rotate(72-72*i)
    }
    var path=["M",coords[0],"L",coords[1],"L",coords[2],"L",coords[3],"L",coords[4],"z"],
    frame=paper.rect(10,10,55,20,5).attr(frameStyle).hide(),
    label=paper.text(5,5," ").attr(labelStyle).hide();
    path=path.join(" ");
    paper.path({
        fill:color.keynote,
        opacity:0.75,
        stroke:"none"
    },path);
    for(var i=0,n=coords.length;i<n;i++){
        var dot=paper.circle(coords[i][0],coords[i][1],5).attr({
            fill:color.keynote,
            opacity:0.95,
            stroke:"none"
        });
        (function(dot,i){
            dot.mouseover(function(){
                this.animate({
                    r:10
                },200);
                frame.show().animate({
                    x:coords[i][0],
                    y:coords[i][1]
                    },1);
                label.attr({
                    text:ability[i]+" "+data[i]
                    }).show().animate({
                    x:coords[i][0]+25,
                    y:coords[i][1]+10
                    },1);
            });
            dot.mouseout(function(){
                this.animate({
                    r:5
                },200);
                frame.hide();
                label.hide();
            });
        })(dot,i);
    }
    frame.toFront();
    label.toFront();
    
  • 相关阅读:
    寒露将至,略有所感:过河卒 DP入门
    linux 内核中EXPORT_SYMBOL()分析与实践
    Educational Codeforces Round 116 (Rated for Div. 2)
    Educational Codeforces Round 115 (Rated for Div. 2)
    学习笔记:UML类图
    论文阅读笔记Fully Functional Image Manipulation Using Scene Graphs in A Bounding-Box Free Way
    图像质量评价(六)主观评价 subjective ?还没写完
    image manipulation综述
    论文阅读笔记stargan
    10.14-11.7第一轮文献调研内容
  • 原文地址:https://www.cnblogs.com/rubylouvre/p/1605690.html
Copyright © 2011-2022 走看看