记得收藏【国际动画教程网】,赶快注册吧!
注册

合作站点账号登陆

QQ登录

只需一步,快速开始

扫一扫,访问微社区

快捷导航

用JavaScript做一个简单的框选图表[含2P]

[复制链接]
发表于 2017-5-16 19:37:44 | 显示全部楼层 |阅读模式

故事背景:这几天遇到一个客户,是做会议记录的,每次会议过程中,都会有特定设备记录下讲话人的位置以角度值显示。他给我角度值,让我给他做一个图表来展示每个人的一个大概位置。

客户想到的是用 Echarts 图表来做,我首先想到的也是用 Echarts ,但是思考了他的要求以后,发现就一个简单的框选图表用 Echarts 来做是不是大材小用了,而且还要导入那么多的没用的代码。

于是我想到了用 canvas 画布来仿着做,但又考虑了一下, canvas 操作起来不顺手;究竟可不可以用普通的css结合 javascript 来把它做出来呢?此番思考验证了:任何事情一定要多动脑,才能 到更简单的解决问题的方式。

考虑到也许某天大家用得着,所以发布出来。注:拥有可移植性,可移到页面任何位置,效果不会改变

先看最终效果吧:

图一:

用JavaScript做一个简单的框选图表 javascript,会议记录,知识点,坐标轴,而且 【Java】 193747c5muqum7ntmu88l8 1

图二:

用JavaScript做一个简单的框选图表 javascript,会议记录,知识点,坐标轴,而且 【Java】 193747t0xwtbwoopao0zi0 2

这个小东西会涉及的知识点不多,归纳一下: js的三角函数 、 CSS3的transform 、 鼠标的坐标轴XY的计算 ...啊哈,差不多大体就这三方面的知识吧,如果你都只是有过了解也没关系,因为都只用的到皮毛所以不必担心。但是如果完全没听过,那就请您再去了解一下这方面知识。

代码区域

<!doctype html>
<html>
<head>
    <meta charset="utf-8" />
    <title>仿Echarts图表</title>
    <style>
        * {
            padding:0;
            margin:0;
        }
        #getcharts {
            position:relative;
            width:510px;
            height:510px;

        }
        #wrapcharts {
            list-style:none;
            height:500px;
            width:500px;
            border:2px solid #aaa;
            border-radius:50%;
            position:relative;
            margin:20px auto;
        }
        #wrapcharts li {
            height:10px;
            width:10px;
            diaplay:block;
            position:absolute;
            cursor:pointer;
            left:247px;
            top:2px;
            height:10px;
            width:10px;
            transition:0.2s;
            background:red;
            border-radius:50%;
        }
        #boxshadow {
            position:absolute;
            background:blue;
            opacity:0.2;
            height:0;
            width:0;
            left:0;
            top:0;
        }
    </style>
</head>
<body>

    <ul id="wrapcharts"></ul>
    <div id="boxshadow"></div>
    
<script>
    /*
     **模拟从后端取值过来的【角度】和相对应的【人名】数组
     **/
    var degArr = [25,88,252,323,33,28,30,90,290,100,300,50,180,205,220,331,195,97,102,77,62,38,32,79];
    var nameArr = ['内衣天使','小恶魔','金正恩','奥巴马','duolaA梦','午夜激情','梁静茹','刘亦菲','琪琪','大熊','小静','小屁孩','张三','李四','王五','麻六','小明','小张','丽丽','多多','瑾瑾','biubiu','Mr.boluo','Hanson'];
    /*
     **声明 getPos(param)函数: 利用三角函数定理根据传入的角度值获取对边和临边的x,y值
     **/
    function getPos(deg)
    {
        var X = Math.sin(deg*Math.PI/180)*250 + 245;
        var Y = -Math.cos(deg*Math.PI/180)*250 + 245;
        return {x:X,y:Y};
    }
    /*
     **这里不用说吧,获取页面中的ul,和ul中的li对象,以及框选时的那个任意变动大小的小方块对象
     **/
    var oWrap = document.getElementById('wrapcharts');
    var aLi = oWrap.getElementsByTagName('li');
    var oBox =document.getElementById('boxshadow');
    var allLi = '';
    var posArr = [];
    /*
     **for循环中调用getPos(param)来获取degArr数组中的所有角度对应的x,y值(就是每个角度对应的x,y坐标),并传入到一个数组中保存,方便取用
     **/
    for(var i=0;i<degArr.length; i++)
    {
        posArr.push(getPos(degArr));
    }
    /*
     **for循环根据度数数组degArr的长度插入li小圆点到ul中,并将之前获取的每个点对应的x,y左边插入到行内样式
     **/
    for(var i=0; i<degArr.length; i++)
    {
        allLi += '<li style="left:'+posArr.x+'px;top:'+posArr.y+'px;" title="'+degArr+'°;姓名:'+nameArr+'"></li>';
    }
    oWrap.innerHTML = allLi;
    /*
     **遍历最终得到的ul中的li
     **/
    for(var i=0; i<aLi.length; i++)
    {
        aLi.index = i;
        /*
         **封装鼠标移入每个小圆点时的放大事件,这里用到了matrix矩阵,为的事想兼容ie9以下浏览器,但是好像出了点问题
         */
        function focusOn(_this,color, size)
        {
            _this.style.background = color;
            _this.style.WebkitTransform = 'matrix('+size+', 0, 0, '+size+', 0, 0)';
            _this.style.MozTransform = 'matrix('+size+', 0, 0, '+size+', 0, 0)';
            _this.style.transform = 'matrix('+size+', 0, 0, '+size+', 0, 0)';
            _this.style.filter="progid用JavaScript做一个简单的框选图表 javascript,会议记录,知识点,坐标轴,而且 【Java】 biggrin 3XImageTransform.Microsoft.Matrix( M11= "+size+", M12= 0, M21= 0 , M22="+size+",SizingMethod='auto expend')";
        }
        aLi.onmouseover = function()
        {
            //alert(this.offsetLeft);
            _this = this;
            focusOn(_this,'blue', 2);
        }
        aLi.onmouseout = function()
        {
            //alert(this.offsetLeft);
            _this = this;
            focusOn(_this,'red', 1);

        }
    }
    /***框选***/
    /*
     **拖拽框选代码区域,这个我就不解释了,明白人都一眼知道什么意思,这就像是公式,
     */
    var allSelect = {};
    document.onmousedown = function(ev)
    {
        var ev = ev || window.event;
        var disX = ev.clientX;
        var disY = ev.clientY;
        var H = W = clientleft = clienttop =  clientright = clientbottom = 0;
        oBox.style.cssText = 'left:'+disX+'px;top:'+disY+'px;';
        //console.log(disX+';'+disY);
        function again(f)
        {
            for(var i=0; i<posArr.length; i++)
            {
                if(posArr.x > clientleft && posArr.y > clienttop  && (posArr.x + 10) < clientright && (posArr.y +10) < clientbottom)
                {
                    //console.log(clientleft+';'+ clienttop +';'+ clientright +';' +  clientbottom);
                    if(f){allSelect = i;}else{
                        aLi.style.background = 'blue';
                    }
                } else
                {
                    aLi.style.background = 'red';
                }
            }

        }

        document.onmousemove = function(ev)
        {
            var ev = ev || window.event;
            /*
             **当鼠标向四个方向拖拉的时候进行方向判断,并相应的改变小方块的left,top以及width,height
             **其实我这里有个问题,那就是,代码重复了一些,本想着合并一下,但是作者有点懒,嘿嘿,你们也可以尝试一下
             **修改后你们拿去当做你们的发布,作者不会介意的
             */
            if(ev.clientX > disX && ev.clientY > disY)
            {
                W = ev.clientX - disX;
                H = ev.clientY - disY;

                oBox.style.width = W + 'px';
                oBox.style.height = H + 'px';

                clienttop  = disY-oWrap.offsetTop;
                clientleft = disX-oWrap.offsetLeft;

            }else if(ev.clientX < disX && ev.clientY < disY)
            {
                W = disX - ev.clientX;
                H = disY - ev.clientY;

                oBox.style.top  = ev.clientY + 'px';
                oBox.style.left = ev.clientX + 'px';

                oBox.style.width  = W + 'px';
                oBox.style.height = H + 'px';

                clienttop  = ev.clientY - oWrap.offsetTop;
                clientleft = ev.clientX - oWrap.offsetLeft;

            }else if(ev.clientX > disX && ev.clientY < disY)
            {
                W = ev.clientX - disX;
                H = disY - ev.clientY;

                oBox.style.top  = ev.clientY + 'px';

                oBox.style.width = W + 'px';
                oBox.style.height = H + 'px';

                clienttop  = ev.clientY - oWrap.offsetTop;
                clientleft = disX - oWrap.offsetLeft;

            }else if(ev.clientX < disX && ev.clientY > disY)
            {
                W = disX - ev.clientX;
                H = ev.clientY - disY;

                oBox.style.left = ev.clientX + 'px';

                oBox.style.width  = W + 'px';
                oBox.style.height = H + 'px';

                clienttop  = disY-oWrap.offsetTop;
                clientleft = ev.clientX - oWrap.offsetLeft;
            }


            clientright  = clientleft+ W;
            clientbottom = clienttop + H;

            W = '';
            H = '';

            again();

        }
        document.onmouseup = function()
        {
            again(1);

            document.onmouseup = document.onmousemove = null;
            oBox.style.cssText = 'height:0;width:0;';
            if(JSON.stringify(allSelect) == '{}'){return;}
            console.log(allSelect);

            var lastSelect = [];
            for(var attr in allSelect){
                lastSelect.push(nameArr[attr]);
            }
            allSelect = {};

            console.log(lastSelect);
            alert('你选中的人是:\n\n'+lastSelect+'\n\n');

            for(var i=0; i<aLi.length; i++)
            {
                aLi.style.background = 'red';
            }
        }
        return false;
    }
</script>
</body>
</html>

会用到的一些知识点拓展

注:在js中设置Transform的时候我用到的不是scale()方法,因为我想兼容ie9以下的版本所以用了矩阵变化。当然,你们也可以改为scale(),毫无影响。

  1. 在标准浏览器下的矩阵函数matix(a,b,c,d,e,f)、ie下的矩阵函数progid用JavaScript做一个简单的框选图表 javascript,会议记录,知识点,坐标轴,而且 【Java】 biggrin 4XImageTransform.Microsoft.Matrix( M11= 1, M12= 0, M21= 0 , M22=1,SizingMethod='auto expend')

    他们的共同点:M11 == a; M12 == c; M21 == b; M22 == d

    不一样的地方:ie下的矩阵函数没有 e 和 f 两个参数,在矩阵函数中 e 和 f 是用来位移的,也就是说ie下没法通过矩阵函数来实现位移[ 不过我们这里好像不需要位移,嘿嘿 ]

  2. 在标准浏览器下矩阵函数matrix中a,b,c,d,e,f 一一对应的的初始值为:matix(1,0,0,1,0,0)

  3. 通过矩阵实现缩放:

    x轴缩放:a = x a c = x c e = x*e

    y轴缩放:b = y b d = y d f = y*f

  4. 通过矩阵实现位移:[ie下没位移]

    x轴位移:e = e+x

    y轴位移:f = f+y

  5. 通过矩阵实现倾斜:

    x轴倾斜:c = Math.tan(xDeg/180*Math.PI)

    y轴倾斜:b = Math.tan(yDeg/180*Math.PI)

  6. 通过矩阵实现旋转:

    a = Math.cos(deg/180*Math.PI);

    b = Math.sin(deg/180*Math.PI);

    c = -Math.sin(deg/180*Math.PI);

    d = Math.cos(deg/180*Math.PI);

  7. 至于三角函数我就不介绍了,百度一大把:

    三角函数

来自:https://segmentfault.com/a/1190000009411175

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
一起共享资源,共建精品资源平台。记得一定要收藏我们网站。www.gjdhjc.com ||||| 还有我们的网址导航:www.58q8.com【链接失效可以留言看到第一时间补帖,如果懒的回复我也是没办法了】
微信扫一扫,每天教程更新!
想学习最新知识关注“今日教程”微信公众号!站长每天更新教程,每天八条,欢迎关注支持!!!
快速回复 返回顶部 返回列表