金沙国际官网_金沙国际平台登录

因为这个金沙国际官网_金沙国际平台登录网站与很多的大型澳门赌场都有合作,金沙国际官网_金沙国际平台登录尽职尽责,高效执行,保持好奇心,不断学习,追求卓越,点击进入金沙国际官网_金沙国际平台登录马上体验吧,所以现在也正式地开始了营业。

您的位置:金沙国际官网 > web前端 > 14款基于javascript的数据可视化工具,eval解析JSO

14款基于javascript的数据可视化工具,eval解析JSO

发布时间:2019-11-03 11:52编辑:web前端浏览(110)

    14款基于javascript的数据可视化工具

    2015/12/15 · JavaScript · 数据可视化

    原文出处: 百度EFE- Ceada   

    俗话说,一图胜千言。图形化的信息可以让人们对数据有更加直观清晰的理解,让信息发布者更加高效地展示自己的核心内容。在前端开发中,如果缺少合适工具,制作数据可视化图表会十分复杂。然而随着数据可视化概念逐年火热,有较多优秀的图表开源库和制作工具脱颖而出。下面,我们就拿其中比较有名的 14个产品进行简要介绍。

    eval解析JSON字符串的一个小问题

    2016/02/24 · JavaScript · JSON

    原文出处: 韩子迟   

    之前写过一篇 关于 JSON 的介绍文章,里面谈到了 JSON 的解析。我们都知道,高级浏览器可以用  JSON.parse() API 将一个 JSON 字符串解析成 JSON 数据,稍微欠妥点的做法,我们可以用 eval() 函数。

    JavaScript

    var str = '{"name": "hanzichi", "age": 10}'; var obj = eval('(' + str + ')'); console.log(obj); // Object {name: "hanzichi", age: 10}

    1
    2
    3
    var str = '{"name": "hanzichi", "age": 10}';
    var obj = eval('(' + str + ')');
    console.log(obj); // Object {name: "hanzichi", age: 10}

     

    是否注意到,向 eval() 传参时,str 变量外裹了一层小括号?为什么要这样做?

    我们先来看看 eval 函数的定义以及使用。

    eval() 的参数是一个字符串。如果字符串表示了一个表达式,eval() 会对表达式求值。如果参数表示了一个或多个 JavaScript 声明, 那么 eval() 会执行声明。不要调用 eval() 来为算数表达式求值; JavaScript 会自动为算数表达式求值。

    简单地说,eval 函数的参数是一个字符串,如果把字符串 “noString” 化处理,那么得到的将是正常的可以运行的 JavaScript 语句。

    怎么说?举个栗子,如下代码:

    JavaScript

    var str = "alert('hello world')"; eval(str);

    1
    2
    var str = "alert('hello world')";
    eval(str);

    执行后弹出 “hello world”。我们把 str 变量 “noString” 化,粗暴点的做法就是去掉外面的引号,内部调整(转义等),然后就变成了:

    JavaScript

    alert('hello world')

    1
    alert('hello world')

    very good!这是正常的可以运行的 JavaScript 语句!运行之!

    再回到开始的问题,为什么 JSON 字符串要裹上小括号。如果不加,是这个样子的:

    JavaScript

    var str = '{"name": "hanzichi", "age": 10}'; var obj = eval(str); // Uncaught SyntaxError: Unexpected token :

    1
    2
    var str = '{"name": "hanzichi", "age": 10}';
    var obj = eval(str);  // Uncaught SyntaxError: Unexpected token :

    恩,报错了。为什么会报错?试试把 str “noString” 化,执行一下:

    JavaScript

    {"name": "hanzichi", "age": 10}; // Uncaught SyntaxError: Unexpected token :

    1
    {"name": "hanzichi", "age": 10};  // Uncaught SyntaxError: Unexpected token :

    毫无疑问,一个 JSON 对象或者说是一个对象根本就不是能执行的 JavaScript 语句!等等,试试以下代码:

    JavaScript

    var str = '{name: "hanzichi"}'; var obj = eval(str); console.log(obj); // hanzichi

    1
    2
    3
    var str = '{name: "hanzichi"}';
    var obj = eval(str);
    console.log(obj); // hanzichi

    这又是什么鬼?但是给 name 加上 “” 又报错?

    JavaScript

    var str = '{"name": "hanzichi"}'; var obj = eval(str); // Uncaught SyntaxError: Unexpected token : console.log(obj);

    1
    2
    3
    var str = '{"name": "hanzichi"}';
    var obj = eval(str);  // Uncaught SyntaxError: Unexpected token :
    console.log(obj);

    好吧,快晕了,其实还是可以将 str “nostring” 化,看看是不是能正确执行的 JavaScript 语句。前者的结果是:

    JavaScript

    {name: "hanzichi"}

    1
    {name: "hanzichi"}

    这确实是一条合法的 JavaScript 语句。{} 我们不仅能在 if、for 语句等场景使用,甚至可以在任何时候,因为 ES6 之前 JavaScript 只有块级作用域,所以对于作用域什么的并不会有什么冲突。去掉 {} 后 name: "hanzichi"也是合法的语句,一个 label 语句,label 语句在跳出嵌套的循环中非常好用,具体可以参考 label,而作为 label 语句的标记,name 是不能带引号的,标记能放在 JavaScript 代码的任何位置,用不到也没关系。

    一旦一个对象有了两个 key,比如 {name: "hanzichi", age: 10} ,ok,两个 label 语句?将 “hanzhichi” 以及 10 分别看做是语句,但是 语句之间只能用封号连接!(表达式之间才能用逗号)。所以改成下面这样也是没有问题的:

    JavaScript

    var str = '{name: "hanzichi"; age: 10}'; var obj = eval(str); console.log(obj); // 10

    1
    2
    3
    var str = '{name: "hanzichi"; age: 10}';
    var obj = eval(str);  
    console.log(obj); // 10

    越扯越远,文章开头代码的错误的原因是找到了,为什么套个括号就能解决呢?简单来说,() 会把语句转换成表达式,称为语句表达式。括号里的代码都会被转换为表达式求值并且返回,对象字面量必须作为表达式而存在

    本文并不会大谈表达式,关于表达式,可以参考文末链接。值得记住的一点是,表达式永远有一个返回值。大部分表达式会包裹在() 内,小括号内不能为空,如果有多个表达式,用逗号隔开,也就是所谓的逗号表达式,会返回最后一个的值。

    说到表达式,不得不提函数表达式,以前翻译过一篇关于立即执行函数表达式的文章,可以参考下,文末。

    Read More:

    • [译]JavaScript中:表达式和语句的区别
    • (译)详解javascript立即执行函数表达式(IIFE)
    • 深入探究javascript的 {} 语句块

      1 赞 1 收藏 评论

    图片 1

    setTimeout 的黑魔法

    2016/05/03 · JavaScript · 1 评论 · settimeout

    原文出处: 李三思   

    setTimeout,前端工程师必定会打交道的一个函数.它看上去非常的简单,朴实.有着一个很不平凡的名字–定时器.让年少的我天真的以为自己可以操纵未来.却不知朴实之中隐含着惊天大密.我还记得我第一次用这个函数的时候,我天真的以为它就是js实现多线程的工具.当时用它实现了一个坦克大战的小游戏,玩儿不亦乐乎.可是随着在前端这条路上越走越远,对它理解开始产生了变化.它似乎开始蒙上了面纱,时常有一些奇怪的表现让我捉摸不透.终于,我的耐心耗尽,下定决心,要撕开它的面具,一探究竟.

    要说setTimeout的渊源,就得从它的官方定义说起.w3c是这么定义的

    setTimeout() 方法用于在指定的毫秒数后调用函数或计算表达式。

    看到这样一个说明,我们明白了它就是一个定时器,我们设定的函数就是一个”闹钟”,时间到了它就会去执行.然而聪明的你不禁有这样一个疑问,如果是settimeout(fn,0)呢?按照定义的说明,它是否会立马执行?实践是检验真理的唯一标准,让我们来看看下面的实验

    JavaScript

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title></title> </head> <body> <script> alert(1); setTimeout("alert(2)", 0); alert(3); </script> </body> </html>

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title></title>
    </head>
    <body>
        
        <script>
            alert(1);
            setTimeout("alert(2)", 0);
            alert(3);
        </script>
    </body>
    </html>

    这是一个很简单的实验,如果settimeout(0)会立即执行,那么这里的执行结果就应该是1->2>3  . 然而实际的结果却是1->3->2. 这说明了settimeout(0)并不是立即执行.同时让我们对settimeout的行为感到很诡异.

    AnyChart

    链接:

    AnyChart 是基于 Flash/JavaScript(HTML5) 的图表解决方案,它可以轻松地跨浏览器、跨平台工作。除了基础的图表功能外,它还有收费的交互式图表和仪表功能。它可以通过 XML 格式获取数据,该方式让开发人员非常灵活地控制图表上的每一个数据点,而当图表数据点数量偏大时,则可以采用 CSV 数据输入,减小数据文件大小和图表加载时间。

    js引擎是单线程执行的

    我们先把上面的问题放一放.从js语言的设计上来看看是否能找到蛛丝马迹.

    我们发现js语言设计的一个很重要的点是,js是没有多线程的.js引擎的执行是单线程执行.这个特性曾经困扰我很久,我想不明白既然js是单线程的,那么是谁来为定时器计时的?是谁来发送ajax请求的?我陷入了一个盲区.即将js等同于浏览器.我们习惯了在浏览器里面执行代码,却忽略了浏览器本身.js引擎是单线程的,可是浏览器却可以是多线程的,js引擎只是浏览器的一个线程而已.定时器计时,网络请求,浏览器渲染等等.都是由不同的线程去完成的. 口说无凭,咱们依然看一个例子

    JavaScript

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title></title> </head> <body> </body> <script> var isEnd = true; window.setTimeout(function () { isEnd = false;//1s后,改变isEnd的值 }, 1000); while (isEnd); alert('end'); </script> </html>

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title></title>
    </head>
    <body>
        
    </body>
    <script>
        var isEnd = true;
        window.setTimeout(function () {
            isEnd = false;//1s后,改变isEnd的值
        }, 1000);
        while (isEnd);
        alert('end');
    </script>
    </html>

    isEnd默认是true的,在while中是死循环的.最后的alert是不会执行的. 我添加了一个定时器,1秒后将isEnd改为false. 如果说js引擎是多线程的,那么在1秒后,alert就会被执行.然而实际情况是,页面会永远死循环下去.alert并没有执行.这很好的证明了,settimeout并不能作为多线程使用.js引擎执行是单线程的.

    amCharts

    链接:

    amCharts 是一款高级图表库,致力于对 Web 上的数据可视化提供支持。它所支持的图表包括柱状图、条状图、线图、蜡烛图、饼图、雷达、极坐标图、散点图、燃烧图和金字塔图等等。amCharts 库是一款完全独立的类库,在应用中不依赖任何其他第三方类库,就可直接编译运行。除了提供最基本的规范要素外,amCharts 还提供了交互特性。用户在浏览基于 amCharts 制作的图表时,用鼠标 hover 图表内容,可以与其进行交互,使图表展示细节信息,其中呈现信息的容器被叫做 Balloon(气球)。除此之外图表可以动态动画的形式被绘制出来,带来了了非常好的展示效果。

    event loop

    从上面的实验中,我们更加疑惑了,settimeout到底做了什么事情呢?

    原来还是得从js语言的设计上寻找答案.

    图片 2

    js引擎单线程执行的,它是基于事件驱动的语言.它的执行顺序是遵循一个叫做事件队列的机制.从图中我们可以看出,浏览器有各种各样的线程,比如事件触发器,网络请求,定时器等等.线程的联系都是基于事件的.js引擎处理到与其他线程相关的代码,就会分发给其他线程,他们处理完之后,需要js引擎计算时就是在事件队列里面添加一个任务. 这个过程中,js并不会阻塞代码等待其他线程执行完毕,而且其他线程执行完毕后添加事件任务告诉js引擎执行相关操作.这就是js的异步编程模型.

    如此我们再回过头来看settimeout(0)就会恍然大悟.js代码执行到这里时,会开启一个定时器线程,然后继续执行下面的代码.该线程会在指定时间后往事件队列里面插入一个任务.由此可知settimeout(0)里面的操作会放在所有主线程任务之后. 这也就解释了为什么第一个实验结果是1->3-2 .

    由此可见官方对于settimeout的定义是有迷惑性的.应该给一个新的定义:

    在指定时间内, 将任务放入事件队列,等待js引擎空闲后被执行.

    Cesium

    链接:

    Cesium 同样专注于地理数据可视化,它是一个 Javascript 库,可以在 Web 浏览器中绘制 3D/2D 地球。无需任何插件即可基于 WebGL 来进行硬件加速。除此之外,它还有跨平台、跨浏览器的特性。Cesium 本身基于 Apache 开源协议,支持商业及非商业项目。

    js引擎与GUI引擎是互斥的

    谈到这里,就不得不说浏览器的另外一个引擎—GUI渲染引擎. 在js中渲染操作也是异步的.比如dom操作的代码会在事件队列中生成一个任务,js执行到这个任务时就会去调用GUI引擎渲染.

    js语言设定js引擎与GUI引擎是互斥的,也就是说GUI引擎在渲染时会阻塞js引擎计算.原因很简单,如果在GUI渲染的时候,js改变了dom,那么就会造成渲染不同步. 我们需要深刻理解js引擎与GUI引擎的关系,因为这与我们平时开发息息相关,我们时长会遇到一些很奇葩的渲染问题.看这个例子

    JavaScript

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title></title> </head> <body> <table border=1> <tr><td><button id='do'>Do long calc - bad status!</button></td> <td><div id='status'>Not Calculating yet.</div></td> </tr> <tr><td><button id='do_ok'>Do long calc - good status!</button></td> <td><div id='status_ok'>Not Calculating yet.</div></td> </tr> </table> <script> function long_running(status_div) { var result = 0; for (var i = 0; i < 1000; i++) { for (var j = 0; j < 700; j++) { for (var k = 0; k < 300; k++) { result = result + i + j + k; } } } document.querySelector(status_div).innerHTML = 'calclation done' ; } document.querySelector('#do').onclick = function () { document.querySelector('#status').innerHTML = 'calculating....'; long_running('#status'); }; document.querySelector('#do_ok').onclick = function () { document.querySelector('#status_ok').innerHTML = 'calculating....'; window.setTimeout(function (){ long_running('#status_ok') }, 0); }; </script> </body> </html>

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title></title>
    </head>
    <body>
        <table border=1>
            <tr><td><button id='do'>Do long calc - bad status!</button></td>
                <td><div id='status'>Not Calculating yet.</div></td>
            </tr>
            <tr><td><button id='do_ok'>Do long calc - good status!</button></td>
                <td><div id='status_ok'>Not Calculating yet.</div></td>
            </tr>
        </table>    
    <script>
     
    function long_running(status_div) {
     
        var result = 0;
        for (var i = 0; i < 1000; i++) {
            for (var j = 0; j < 700; j++) {
                for (var k = 0; k < 300; k++) {
                    result = result + i + j + k;
                }
            }
        }
        document.querySelector(status_div).innerHTML = 'calclation done' ;
    }
     
    document.querySelector('#do').onclick = function () {
        document.querySelector('#status').innerHTML = 'calculating....';
        long_running('#status');
    };
     
    document.querySelector('#do_ok').onclick = function () {
        document.querySelector('#status_ok').innerHTML = 'calculating....';
        window.setTimeout(function (){ long_running('#status_ok') }, 0);
    };
     
    </script>
    </body>
    </html>

    我们希望能看到计算的每一个过程,我们在程序开始,计算,结束时,都执行了一个dom操作,插入了代表当前状态的字符串,Not Calculating yet.和calculating….和calclation done.计算中是一个耗时的3重for循环. 在没有使用settimeout的时候,执行结果是由Not Calculating yet 直接跳到了calclation done.这显然不是我们希望的.而造成这样结果的原因正是js的事件循环单线程机制.dom操作是异步的,for循环计算是同步的.异步操作都会被延迟到同步计算之后执行.也就是代码的执行顺序变了.calculating….和calclation done的dom操作都被放到事件队列后面而且紧跟在一起,造成了丢帧.无法实时的反应.这个例子也告诉了我们,在需要实时反馈的操作,如渲染等,和其他相关同步的代码,要么一起同步,要么一起异步才能保证代码的执行顺序.在js中,就只能让同步代码也异步.即给for计算加上settimeout.

    Chart.js

    链接:

    Chart.js 是一个简单、面向对象,为设计和开发者准备的图表绘制工具库。它提供了六种基础图表类型。基于 Html5,响应式,支持所有现代浏览器。同时它不依赖任何外部工具库,本身轻量级,且支持模块化,即开发者可以拆分 Chart.js 仅引入自己需要的部分进入工程。在小巧的身段中它同时支持可交互图表。

    settimeout(0)的作用

    不同浏览器的实现情况不同,HTML5定义的最小时间间隔是4毫秒. 使用settimeout(0)会使用浏览器支持的最小时间间隔.所以当我们需要把一些操作放到下一帧处理的时候,我们通常使用settimeout(0)来hack.

    本文由金沙国际官网发布于web前端,转载请注明出处:14款基于javascript的数据可视化工具,eval解析JSO

    关键词: