数据可视化

本文探讨了数据可视化的概念,并详细介绍了使用JavaScript和D3库创建直方图、二叉树、文字树、饼图、环图以及力导向图的过程。同时,也展示了如何利用JavaScript连接MySQL数据库进行数据可视化。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、数据可视化

屈华民在《大数据时代的可视化与协同创新》一文中曾说过:

可视化,简要地讲,就是把数据转换为图形图像的方式,帮助人们理解大量的和复杂的数据。

由此可见,数据可视化的本质是分析数据、清晰有效地传达与沟通信息,是十分具有现实意义的。本篇博客简单记录了笔者在数据可视化课程中的学习。

二、Javascript

2.1 JavaScript直方图绘制

(1)代码

<html>
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width">
    <title>Percentage of Australian men doing regular physical activity:2010</title>
</head>
<body>
    <h2><center>Percentage of Australian men doing regular physical activity:2010</center></h2>
    <svg id="mysvg" width=800 height=600></svg>
    <script>
    var w = window.innerWidth
|| document.documentElement.clientWidth
|| document.body.clientWidth;

    var h = window.innerHeight
|| document.documentElement.clientHeight
|| document.body.clientHeight;

    var svg=document.getElementById("mysvg");
    svg.setAttribute("width",w);
    svg.setAttribute("height",h);
    var rec=new Array(6);
    var txt=new Array(6);
    var title=new Array(6);
    var height=new Array(52.8,42.2,39.5,43.1,45.1,46.7);
    var age=new Array("AGE15-24","AGE25-34","AGE35-44","AGE45-54","AGE55-64","AGE65+");
    for(var i=0;i<6;i++){
        rec[i]=document.createElement("rect");
        svg.appendChild(rec[i]);
        txt[i]=document.createElement("text");
        svg.appendChild(txt[i]);
        title[i]=document.createElement("text");
        svg.appendChild(title[i]);
        rec[i].outerHTML="<rect x="+(i*w/rec.length)+" y="+(h-height[i]*10)+" width="+(w*0.9/rec.length)+" height="+(height[i]*10)+" fill='rgb(0,0,"+(height[i]*20-750)+")'>";
        txt[i].outerHTML="<text x="+(i*w/rec.length)+" y="+(h-height[i]*10)+">"+height[i]+"</text>";
        title[i].outerHTML="<text x="+((i*w/rec.length)+50)+" y="+(h-height[i]*10)+">"+age[i]+"</text>";
    }


    </script>
</body>
</html>

(2)实验结果
在这里插入图片描述
(3)总结
这是笔者第一次实现JavaScript直方图的绘制,当时对数据本身的选取并不重视。数据可视化主要是借助于图形化手段,有效地传达与沟通信息,所选取的信息应具有时效性、参考价值。笔者在后面的可视化实现中会更重视数据本身。

2.2 基于JavaScript和SVG的二叉树

(1)代码

<html>
    <body>
        <h2><center>仿真二叉树</center></h2>
        <svg id="mysvg" width=800 height=600>
        </svg>

        <script>
            var w=window.innerWidth 
            || document.documentElement.clientWidth 
            || document.body.clientWidth;

            var h=window.innerHeight
            || document.documentElement.clientHeight
            || document.body.clientHeight;

            var svg=document.getElementById("mysvg");
            svg.setAttribute("width",w);
            svg.setAttribute("height",h);
            w=w*0.98;
            h=h*0.98;

            var x0=w/2;
            var y0=h;
            var L=200;
            var rate=0.92;
            var a=-Math.PI/2;
            var count=11;
            function show(x0,y0,L,rate,a,count){
                var x1=x0;
                var y1=y0;
                var x2=x1+L*Math.cos(a);
                var y2=y1+L*Math.sin(a);

                var L=L*rate*(0.5+Math.random()*0.5);
                var aL=a-Math.PI/4.5*(0.5+Math.random()*0.5);
                var aR=a+Math.PI/4.5*(0.5+Math.random()*0.5);
                var lineX=document.createElement("line");
                svg.appendChild(lineX);
                lineX.outerHTML="<line x1="+x1+" y1="+y1+" x2="+x2+" y2="+y2+" stroke='green' stroke-width="+count+" />";
                if(count>0){
                    show(x2,y2,L,rate,aL,count-1);
                    show(x2,y2,L,rate,aR,count-1);
                }
            }
            show(x0,y0,L,rate,a,count);
        </script>
    </body>
</html>

(2)实验结果
在这里插入图片描述

2.3 基于JavaScript和SVG的文字树

(1)代码

<html>
    <head>
        <meta charset="UTF-8">
    </head>
    <body>
        <h2><center>文字二叉树</center></h2>
        <svg id="mysvg" width=800 height=600>
            
        </svg>

        <script>
            var w=window.innerWidth 
            || document.documentElement.clientWidth 
            || document.body.clientWidth;

            var h=window.innerHeight
            || document.documentElement.clientHeight
            || document.body.clientHeight;

            var svg=document.getElementById("mysvg");
            svg.setAttribute("width",w);
            svg.setAttribute("height",h);
            w=w*0.98;
            h=h*0.98;

            var str="这是一棵文字树";
            var x0=w/2;
            var y0=h;
            var L=200;
            var rate=0.6;
            var a=-Math.PI/2;
            var count=7;
            var fontsize=20;
            function show(x0,y0,L,rate,a,count){
                var fontsize=count*3;
                var L=str.length*fontsize;
                var x1=x0;
                var y1=y0;
                var x2=x1+L*Math.cos(a);
                var y2=y1+L*Math.sin(a);

                var aL=a-Math.PI/6*(0.5+0.5*Math.random());
                var aR=a+Math.PI/6*(0.5+0.5*Math.random());

                var words=document.createElement("text");
                svg.appendChild(words);
                words.outerHTML="<text x="+x1+" y="+y1+" transform='rotate("+a*180/Math.PI+","+x1+","+y1+")' fill='rgb(0,"+(250-count*30)+",0)' font-size="+fontsize+">"+str+"</text>";
                if(count>0){
                    show(x2,y2,L,rate,aL,count-1);
                    show(x2,y2,L,rate,aR,count-1);
                    if (count==1){
                        var apple=document.createElement("circle");
                        svg.appendChild(apple);
                        apple.outerHTML="<circle cx="+x2+" cy="+y2+" r="+6*Math.random()+" fill='rgb("+(150+100*Math.random())+",0,0)'/>";
                    }
                }
            }
            show(x0,y0,L,rate,a,count);
            show(x0,y0,L,rate,a,count);
        </script>
    </body>
</html>

(2)实验结果
在这里插入图片描述

三、D3

3.1 D3直方图的绘制

(1)代码

<html>
    <head>
        <meta charset="UTF-8">
    </head>
    <body> 
        <h2><center>当前热映电影的豆瓣评分</center></h2>    
        <script src="d3.v3.min.js"></script>
        <script>           
            var w=window.innerWidth 
            || document.documentElement.clientWidth 
            || document.body.clientWidth;

            var h=window.innerHeight
            || document.documentElement.clientHeight
            || document.body.clientHeight;
            w=w*0.98;
            h=h*0.9;

            var dataset=new Array(10);
            dataset=[8.8,7.4,6.6,3.7,6.7,8.2,2.8,7.2,8.1,7.4];
            var film=new Array(10);
            film=["阿凡达","又见奈良","21座桥","合法伴侣","哥斯拉大战金刚","波斯语课","日不落酒店","寻龙传说","你好李焕英","五尺天涯"];
            var color = d3.scale.category10();
            var svg=d3.select("body")
                    .append("svg")
                    .attr("width",w)
                    .attr("height",h);       
            svg.selectAll("rect")
                .data(dataset)
                .enter()
                .append("rect")
                .attr("x",function(d,i){
                    return (w/dataset.length)*i;
                })
                .attr("y",function(d){
                    return h-20-d*50;
                })
                .attr("width",(w/dataset.length)-10)
                .attr("height",function(d){
                    return 50*d;
                })
                .attr("fill",function(d,i){
                    return color(i);
                });
                
            svg.selectAll("text.title")
                .data(film)
                .enter()
                .append("text")
                .attr("font-size","18px")
                .attr("x",function(d,i){
                    return (w/dataset.length)*i+10;
                })
                .attr("y",h-20)
                .attr("dx",(w/dataset.length)/2-70)
                .attr("dy","18px")
                .text(function(d){
                    return d;
                });

            svg.selectAll("text.value")
                .data(dataset)
                .enter()
                .append("text")
                .attr("font-size","18px")
                .attr("x",function(d,i){
                    return (w/dataset.length)*i+10;
                })
                .attr("y",function(d){
                    return h-40-d*50;
                })
                .attr("dx",(w/dataset.length)/2-70)
                .attr("dy","18px")
                .text(function(d){
                    return d;
                });
        </script>
    </body>
</html>

(2)实验结果
在这里插入图片描述

3.2 饼图和环图的绘制

用D3绘制饼图有两种方法,一种是基于弧度的可视化,一种是基于数据的可视化。

基于弧度的可视化
(1)代码

<html>
    <head>
        <meta charset="UTF-8">
    </head>
    <body>       
        <script src="d3.v3.min.js"></script>
        <script>           
            var w=window.innerWidth 
            || document.documentElement.clientWidth 
            || document.body.clientWidth;

            var h=window.innerHeight
            || document.documentElement.clientHeight
            || document.body.clientHeight;
            w=w*0.98;
            h=h*0.9;
            var svg=d3.select("body")
                    .append("svg")
                    .attr("width",w)
                    .attr("height",h);
            
            var dataset=[{startAngle:0,endAngle:1},
            {startAngle:1,endAngle:2},
            {startAngle:2,endAngle:4},
            {startAngle:4,endAngle:5},
            {startAngle:5,endAngle:Math.PI*2}];
            var arcPath=d3.svg.arc()
                            .innerRadius(150)
                            .outerRadius(300)
            svg.selectAll("path")
                .data(dataset)
                .enter()
                .append("path")
                .attr("d",function(d){
                    return arcPath(d)
                })
                .attr("fill","yellow")
                .attr("stroke","blue")
                .attr("transform","translate("+w/2+","+h/2+")");

        </script>
    </body>
</html>

(2)实验结果
在这里插入图片描述

基于数据的可视化
(1)代码

<html>
    <head>
        <meta charset="UTF-8">
    </head>
    <body>       
        <script src="d3.v3.min.js"></script>
        <script>           
            var w=window.innerWidth 
            || document.documentElement.clientWidth 
            || document.body.clientWidth;

            var h=window.innerHeight
            || document.documentElement.clientHeight
            || document.body.clientHeight;
            w=w*0.98;
            h=h*0.9;
            var svg=d3.select("body")
                    .append("svg")
                    .attr("width",w)
                    .attr("height",h);
            
            var dataset=[["农业",90],["工业",200],["第三产业",400]];
            var pie=d3.layout.pie()
                        .value(function(d){return d[1];});
            var piedata=pie(dataset);
            var arc=d3.svg.arc()
                            .innerRadius(100)
                            .outerRadius(300)
            svg.selectAll("path")
                .data(piedata)
                .enter()
                .append("path")
                .attr("d",function(d){
                    return arc(d)
                })
                .attr("fill","yellow")
                .attr("stroke","blue")
                .attr("transform","translate("+w/2+","+h/2+")");

        </script>
    </body>
</html>

(2)实验结果
在这里插入图片描述

基于弧度的电影数据可视化:
(1)代码

<html>
    <head>
        <meta charset="UTF-8">
        <center><font size="8"><strong>2020年各题材电影票房占比</strong></font></center>
    </head>
    <body>
        <div style="position: absolute; bottom: 630px; right: 465px;"><font size="2"><strong>数据来源:艺恩数据</strong></font></div>       
        <script src="d3.v3.min.js"></script>
        <script>           
            var w=window.innerWidth 
            || document.documentElement.clientWidth 
            || document.body.clientWidth;

            var h=window.innerHeight
            || document.documentElement.clientHeight
            || document.body.clientHeight;
            w=w*0.98;
            h=h*0.9;
            var svg=d3.select("body")
                    .append("svg")
                    .attr("width",w)
                    .attr("height",h);
            
            var dataset=[["剧情",23],["喜剧",21],["战争",18],["动画",15],["动作",13],["爱情",5],["其他",5]];
            var pie=d3.layout.pie()
                        .value(function(d){return d[1];});
            var piedata=pie(dataset);
            var arc=d3.svg.arc()
                            .innerRadius(100)
                            .outerRadius(200)

            var arcs=svg.selectAll("g")
                        .data(piedata)
                        .enter()
                        .append("g")
                        .attr("transform","translate("+(w/2)+","+(h/2)+")");
            arcs.append("path")
                .attr("d",function(d){
                    return arc(d)
                })
                .attr("fill","#7bbfea")
                .attr("stroke","white")
                .on("mouseover",function(d){
                    d3.select(this)
                        .attr("fill","#f8aba6")
                })
                .on("mouseout",function(d){
                    d3.select(this)
                        .attr("fill","#7bbfea")
                });            
            svg.selectAll("text")
                .data(piedata)
                .enter()
                .append("text")
                .attr("fill","white")
                .attr("text-anchor","middle")
                .attr("transform",function(d){
                    var x=arc.centroid(d)[0];
                    var y=arc.centroid(d)[1];
                    return "translate("+(w/2+x)+","+(h/2+y)+")";
                })
                .text(function(d){return d.value+"%"});
            arcs.append("line")
                .attr("stroke","#cde6c7")
                .attr("x1",function(d){ return arc.centroid(d)[0]*1.34;})
                .attr("y1",function(d){ return arc.centroid(d)[1]*1.34;})
                .attr("x2",function(d){ return arc.centroid(d)[0]*1.5;})
                .attr("y2",function(d){ return arc.centroid(d)[1]*1.5;});

            arcs.append("text")
                .attr("fill","#145b7d")
                .attr("transform",function(d){
                    var x=arc.centroid(d)[0]*1.6;
                    var y=arc.centroid(d)[1]*1.6;
                    return "translate("+x+","+y+")";
                })
                .attr("text-anchor","middle")
                .text(function(d){
                    return d.data[0];
                });
        </script>

    </body>
</html>

(2)实验结果
在这里插入图片描述

3.3 力导向图可视化

用D3绘制力导向图有两种方法,一种是基于直线Line的,一种是基于路径Path的。
基于直线Line的力导向图可视化
(1)代码

<html>
    <head>
        <meta charset="UTF-8">
        <center><font size="8"><strong>巴黎圣母院人物关系图</strong></font></center>
    </head>
    <body>
        <div style="position: absolute; bottom: 630px; right: 525px;"><font size="2"><strong>数据来源:百度</strong></font></div>
        <script src="d3.v3.min.js"></script>
        <script>           
            var w=window.innerWidth 
            || document.documentElement.clientWidth 
            || document.body.clientWidth;

            var h=window.innerHeight
            || document.documentElement.clientHeight
            || document.body.clientHeight;
            w=w*0.98;
            h=h*0.9;

            var nodes=[{name:"埃斯梅拉达"},{name:"卡西莫多"},{name:"克洛德"},{name:"甘果瓦"},{name:"菲比斯"},{name:"若望"},{name:"小百合"},{name:"居第尔"}];
            
            var edges=[{source:0,target:1,relation:"爱慕"},
            {source:0,target:2,relation:"由爱生恨"},
            {source:0,target:3,relation:"名义夫妻"},
            {source:0,target:4,relation:"爱慕"},
            {source:1,target:2,relation:"养父子"},
            {source:1,target:4,relation:"被逮捕&逮捕"},
            {source:2,target:3,relation:"师生"},
            {source:2,target:4,relation:"情敌"},
            {source:2,target:5,relation:"兄弟"},
            {source:4,target:6,relation:"订婚"},
            {source:0,target:7,relation:"母女"},
            {source:2,target:7,relation:"上下级"}];


            var color=d3.scale.category20();
            var svg=d3.select("body")
                        .append("svg")
                        .attr("width",w)
                        .attr("height",h);
            var force=d3.layout.force()
                        .nodes(nodes)
                        .links(edges)
                        .size([w,h])
                        .linkDistance(300)
                        .charge(-600)
                        .on("tick",tick)
                        .start();
            var path=svg.selectAll("path")
                        .data(edges)
                        .enter()
                        .append("path")
                        .attr("id",function(d,i){return "edgepath"+i;})
                        .attr("stroke","grey");
            var circle=svg.selectAll("circle")
                            .data(nodes)
                            .enter()
                            .append("circle")
                            .attr("r",function(d){
                                if(d.weight<3){
                                    return d.weight*10;
                                }
                                else{
                                    return d.weight*5;
                                }
                            })
                            .attr("fill",function(d,i){
                                return color(i);
                            })
                            .call(force.drag);
            var ntext=svg.selectAll("ntext")
                            .data(nodes)
                            .enter()
                            .append("text")
                            .attr("class",".ntext")
                            .attr("fill","black")
                            .attr("text-anchor","middle")
                            .attr("dy",function(d){
                            if(d.weight<3){
                                    return d.weight*10+12;
                                }
                                else{
                                    return d.weight*5+12;
                                }
                            })
                            .text(function(d){return d.name;})
                            .style("font-size","14px");
            var etext=svg.selectAll("etext")
                            .data(edges)
                            .enter()
                            .append("text")
                            .append("textPath")
                            .attr("xlink:href",function(d,i){return "#edgepath"+i;})
                            .attr("class",".etext")
                            .attr("startOffset","50%")
                            .attr("fill","grey")
                            .attr("text-anchor","middle")
                            .text(function(d){return d.relation;})
                            .style("font-size","14px");
            
            function tick(){
                path.attr("d",function(d){
                    return "M"+d.source.x+","+d.source.y+"L"+d.target.x+","+d.target.y;
                })
                circle.attr("transform",function(d){
                    return "translate("+d.x+","+d.y+")";
                })
                ntext.attr("x",function(d){return d.x;})
                    .attr("y",function(d){return d.y;});
            }
        </script>
    </body>
</html>

基于路径Path的力导向图可视化

<html>
    <head>
        <meta charset="UTF-8">
        <center><font size="8"><strong>巴黎圣母院人物关系图</strong></font></center>
        <style>
			path{
                fill: none;
                stroke: #666;
                stroke-width: 1.5px;
			}
			circle {
                stroke: #333;
                stroke-width: 1.5px;
			}
			text {
                font: 10px sans-serif;
                pointer-events: none;
			}
			.tooltip{  
				position: absolute;  
				width: 240px;  
				height: auto;  
				font-family: simsun;  
				font-size: 12px;
				text-align: left;  
				color: black;  
				border-width: 1px solid black;  
				background-color: A9A9A9;  
				border-radius: 3px;  
			}  
			.tooltip:after{   
				content: '';  
				position: absolute;  
				bottom: 100%;  
				left: 20%;  
				margin-left: -3px;  
				width: 0;  
				height: 0;  
				border-bottom: 12px solid rgb(182, 174, 174);  
				border-right: 12px solid transparent;  
				border-left: 12px solid transparent;  
			}  
	</style> 
    </head>
    <body>
        <div style="position: absolute; bottom: 630px; right: 525px;"><font size="2"><strong>数据来源:百度</strong></font></div>
        <script src="d3.v3.min.js"></script>
        <script>           
            var w=window.innerWidth 
            || document.documentElement.clientWidth 
            || document.body.clientWidth;

            var h=window.innerHeight
            || document.documentElement.clientHeight
            || document.body.clientHeight;
            w=w*0.98;
            h=h*0.9;
            
            var nodes=[{name:"埃斯梅拉达",intro:"埃斯梅拉达是雨果笔下集真、善、美于一体的完美的艺术形象。她在小时候被吉普赛人从妓女母亲的呵护下偷走,流浪街头以卖艺为生,虽然饱尝人世的艰辛与苦难,但是却始终保持着一颗善良纯真、乐于助人的心。她是美丽善良的,当乞丐国王要绞死甘果瓦时,她承诺要与甘果瓦结婚救下了他的命;当卡西莫多接受刑法口渴难耐时,只有她站出来以德报怨为他送水。她是勇敢执着的,当克洛德威胁她,只要接受他的爱就能够获得自由时,她斩钉截铁地拒绝了;当菲比斯不顾她的安危死活时,却依然痴心执着的爱着他。"},
            {name:"卡西莫多",intro:"卡西莫多是一个有着几何形的脸,四面体的鼻子,马蹄形的嘴,参差不齐的牙齿,独眼,耳聋,驼背,难听而忠厚的声音的畸形儿。他幼时被父母遗弃在巴黎圣母院门口,后被克洛德收养,成为敲钟人。为报恩,他对克洛德言听计从,绑架了埃斯梅拉达。但在遇到埃斯梅拉达之后,他真诚善良、忠实勇敢的本性被复活了。他奋不顾身地去救处于危险中的埃斯梅拉达,并且不图任何回报。"},
            {name:"克洛德",intro:"克洛德从小接受了良好的宗教教育,是一个勤奋好学、积极向上、知识渊博的青年,他收养丑陋的卡西莫多、照顾年少的弟弟,是有些许善良的。在成为巴黎圣母院的副主教遇到美丽的埃斯梅拉达后,克洛德真实的人性开始表现出来,内心强烈的占有欲迫使他去跟踪、绑架、强抢埃斯梅拉达,这并不是真正意义上的爱情,只是人性中的贪婪和欲望而已。他对埃斯梅拉达的占有欲已经超越了教会思想的束缚,不顾任何人的想法采用极端的做法只能造成悲剧的结局。"},
            {name:"甘果瓦",intro:"流浪诗人,曾因误闯乞丐王国要被绞死,行刑前被埃斯梅拉达以名义婚姻的形式救下。长时间的流浪使他更清楚地认识这个时代和社会,在爱情和物质面前更倾向于选择实际的物质。"},
            {name:"菲比斯",intro:"菲比斯表面上是一个英俊潇洒、美好的皇家卫队队长,深受女孩子的欢迎和喜爱,但是内在却是一个口蜜腹剑、风流成性的伪君子。一方面,菲比斯并不爱他的表妹,却因为表妹的丰厚嫁妆和贵族地位,而同意和表妹结婚,这是一个将金钱、地位摆在第一位的人;另一方面,他虚伪地爱着埃斯梅拉达,因其美丽的外表才一时兴起去追求。单纯的埃斯梅拉达却死心塌地爱上了这个男子,当克洛德因嫉妒袭击菲比斯时,他侥幸逃脱一劫,埃斯梅拉达却冤死在了绞刑架上。"},
            {name:"若望",intro:"巴黎圣母院副主教克洛德之弟,一个游戏人生的小混混,后不满哥哥的所作所为,加入“圣母院”暴动队伍,死于伽西莫多之手。"},
            {name:"小百合",intro:"菲比斯的原未婚妻,最终和甘果瓦成婚。"},
            {name:"居第尔",intro:"埃斯梅拉达的母亲。她在监狱里认出了自己的女儿,在得知分散15年后刚刚找回的骨肉马上就要被吊死了后发狂一样地保护女儿,最后死在女儿的绞架下。"}];
            
            var edges=[{source:0,target:1,relation:"爱慕"},
            {source:0,target:2,relation:"由爱生恨"},
            {source:0,target:3,relation:"名义夫妻"},
            {source:0,target:4,relation:"爱慕"},
            {source:1,target:2,relation:"养父子"},
            {source:1,target:4,relation:"被逮捕&逮捕"},
            {source:2,target:3,relation:"师生"},
            {source:2,target:4,relation:"情敌"},
            {source:2,target:5,relation:"兄弟"},
            {source:4,target:6,relation:"订婚"},
            {source:0,target:7,relation:"母女"},
            {source:2,target:7,relation:"上下级"},
            {source:3,target:6,relation:"夫妻"}];

            var color=d3.scale.category20();
            var force=d3.layout.force()
                        .charge(-600)
                        .linkDistance(300)
                        .size([w,h]);
            var svg=d3.select("body")
                        .append("svg")
                        .attr("width",w)
                        .attr("height",h);
            force.nodes(nodes)
                .links(edges)
                .start();
            var tooltip=d3.selectAll("body")  
                .append("div")  
                .attr("class","tooltip")  
                .style("opacity",0.0); 
            
            var link=svg.selectAll()
                        .data(edges)
                        .enter()
                        .append("line")
                        .attr("class","link")
                        .style("stroke-width",1)
                        .style("stroke","grey")
                        .style("opacity",0.4);
            
            var node=svg.selectAll(".node")
                        .data(nodes)
                        .enter()
                        .append("circle")
                        .attr("class","node")
                        .attr("r",function(d){
                            if(d.weight<3){
                                    return d.weight*10;
                                }
                                else{
                                    return d.weight*5;
                                }
                        })
                        .attr("cx",100)
                        .attr("cy",100)
                        .style("fill",function(d,i){return color(i);})
                        .on("mouseover",function(d,i){    //加入提示框
                            tooltip.html("角色简介:"+d.intro)
                                .style("left",(d3.event.pageX)+"px")  
                                .style("top",(d3.event.pageY+20)+"px")  
                                .style("opacity",1.0);
                            })
					.on("mousemove",function(d){            
                        tooltip.style("left",(d3.event.pageX)+"px")  
                                .style("top",(d3.event.pageY+20)+"px"); })           
                    .on("mouseout",function(d){  
                        tooltip.style("opacity",0.0); })
                    .call(force.drag);
            var text=svg.selectAll(".forcetxt")
                        .data(nodes)
                        .enter()
                        .append("text")
                        .attr("class","forcetxt")
                        .attr("text-anchor","middle")
                        .attr("x",function(d){return d.x;})
                        .attr("y",function(d){return d.y;})
                        .attr("dy",function(d){
                            if(d.weight<3){
                                    return d.weight*10+12;
                                }
                                else{
                                    return d.weight*5+12;
                                }
                        })
                        .text(function(d){return d.name;})
                        .style("font-size","14px");
            var edges_text=svg.selectAll(".linetext")
                                .data(edges)
                                .enter()
                                .append("text")
                                .attr("class","linetext")
                                .attr("fill","grey")  
                                .attr("x",100)
                                .attr("y",200)
                                .text(function(d){return d.relation;})
                                .style("font-size","14px");
                                
            force.on("tick",function(){
                node.attr("cx",function(d){return d.x;})
                    .attr("cy",function(d){return d.y;});

                link.attr("x1",function(d){return d.source.x;})
                    .attr("y1",function(d){return d.source.y;})
                    .attr("x2",function(d){return d.target.x;})
                    .attr("y2",function(d){return d.target.y;});
                
                text.attr("x",function(d){return d.x;})
                    .attr("y",function(d){return d.y;});
                
                edges_text.attr("x",function(d){ return (d.source.x + d.target.x) / 2 ; })
                            .attr("y",function(d){ return (d.source.y + d.target.y) / 2 ; });

            })
            
        </script>
    </body>
</html>

(2)实验结果

四、JavaScrip与MySql的连接

JavaScript连接MySql数据库中的六级单词数据并进行可视化
(1)数据库
在这里插入图片描述
(2)代码

<!DOCTYPE html>
<body>
<div id="wc"></div>
<%@ page contentType="text/html; charset=UTF-8" %> 
<%@ page language="java" %> 
<%@ page import="com.mysql.jdbc.Driver" %> 
<%@ page import="java.sql.*" %> 
<% 
                        out.print("<center><h1><font color=blue>Matrix Word Cloud English Learning</h1></center>"); 
						
						String driverName="com.mysql.jdbc.Driver"; 
						
						String userName="root"; 
						
						String userPasswd="54.wfy"; 
						
						String dbName="flask"; 
						
						String tableName="map_enword"; 

						int count[]=new int[26];
						
						Class.forName("com.mysql.jdbc.Driver").newInstance(); 
						Connection connection=DriverManager.getConnection("jdbc:mysql://localhost:3306/"+dbName+"?serverTimezone=GMT%2B8","root","54.wfy"); 
						Statement statement = connection.createStatement(); 

						for(int i=0;i<26;i++){
							int aa=Integer.valueOf('a')+i;
							char cha = (char) aa;
							
							String sql="SELECT * FROM "+tableName+" where english like '"+cha+"%' "+"order by english"; 
							ResultSet rs = statement.executeQuery(sql);  
							
							String str;
							int j=0;
							while(rs.next()) { 
								str=(rs.getString(2)).substring(0,1);
								//out.print(str+" "); 
								j++;
							}
							count[i]=j;							
							//out.print(" "+count[i]+" <br>"); 
							rs.close();
						}
						statement.close(); 
						connection.close(); 
%>
<script src="d3.v3.min.js"></script>
		<script>
			var w=window.innerWidth
			|| document.documentElement.clientWidth
			|| document.body.clientWidth;

			var h=window.innerHeight
			|| document.documentElement.clientHeight
			|| document.body.clientHeight;
			w=w*0.98;
			h=h*2.3;
			var color=d3.scale.category10();
			
			var dataset=new Array(26);
			var name=new Array(26);
			var name1=new Array(26);
			<% for (int i=0;i<26;i++){ %>
				dataset[<%=i%>]="<%=count[i]%>";
			<% } %>
			
			name1=["a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z"];
			var name=name1.join('');
			
			var ww=w/dataset.length;
			var svg=d3.select("body")
					.append("svg")
					.attr("width",w)
					.attr("height",h);
			var rect=svg.selectAll("rect")
						.data(dataset)
						.enter()
						.append("rect")
						.attr("x",function(d,i){return i*w/dataset.length})
						.attr("y",function(d){return h-d*0.6-90})
						.attr("width",ww*0.95)
						.attr("height",function(d){return d*0.6})
						.attr("fill",function(d,i){return color(i)});
			var value=svg.selectAll("text.value")
						.data(dataset)
						.enter()
						.append("text")
						.attr("x",function(d,i){return i*w/dataset.length})
						.attr("y",function(d){return h-d*0.6-90})
						.text(function(d){return d})
						.attr("dx",ww/2)
						.attr("dy","-1em")
						.attr("text-anchor","middle")
						.attr("fill",function(d,i){return color(i)});
			var title=svg.selectAll("text.title")
						.data(name)
						.enter()
						.append("text")
						.attr("x",function(d,i){return i*w/name.length})
						.attr("y",function(d){return h-60})
						.text(function(d){return d})
						.attr("dx",ww/2)
						.attr("dy","-lem")
						.attr("text-anchor","middle")
						.attr("fill",function(d,i){return color(i)});

			//饼图
/*			var pie=d3.layout.pie()
			.value(function(d){return d;});
            var piedata=pie(dataset);
            var arc=d3.svg.arc()
                            .innerRadius(100)
                            .outerRadius(300)
            svg.selectAll("path")
                .data(piedata)
                .enter()
                .append("path")
                .attr("d",function(d){
                    return arc(d)
                })
                .attr("fill",function(d,i){return color(i);})
                .attr("transform","translate("+w/2+","+(h/2-400)+")");				
*/
var dataset2 =new Array();
		for(var i=0;i<26;i++){
			dataset2[i]=new Array(); 
			for(var j=0;j<2;j++){
				dataset2[i][j]=1;
			}
		}

		var datas=["a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z"];

		dataset2[0][0]='a';		dataset2[1][0]='b';		dataset2[2][0]='c';		dataset2[3][0]='d';		dataset2[4][0]='e';		dataset2[5][0]='f';
		dataset2[6][0]='g';		dataset2[7][0]='h';		dataset2[8][0]='i';		dataset2[9][0]='j';		dataset2[10][0]='k';	dataset2[11][0]='l';
		dataset2[12][0]='m';	dataset2[13][0]='n';	dataset2[14][0]='o';	dataset2[15][0]='p';	dataset2[16][0]='q';	dataset2[17][0]='r';
		dataset2[18][0]='s';	dataset2[19][0]='t';	dataset2[20][0]='u';	dataset2[21][0]='v';	dataset2[22][0]='w';	dataset2[23][0]='x';
		dataset2[24][0]='y';	dataset2[25][0]='z';
		<%for(int i=0;i <count.length;i++){%>dataset2[<%=i%>][1]=" <%=count[i]%> ";<%}%>

		var pie = d3.layout.pie()
			.value(function (d) { return d[1]; });

		innerRadius=30
		var arcPath=d3.svg.arc()
			.innerRadius(innerRadius)
			.outerRadius(function (d) {
			var value=d.value;
			return value*0.6+ innerRadius;});		

		var piedata = pie(dataset2);

		var arcs=svg.selectAll("path")
			.data(piedata).enter()
			.append("path")
			.attr("d", function (d) { return arcPath(d); })
			.attr("fill", function(d,i){return color(i);})
			.attr("transform", "translate("+ w / 2 + "," + h / 3 +")");


		arcs.append("path")
			.attr("fill",function(d,i){
			return color(i);})
			.attr("d",arcPath)

		var rect=svg.selectAll("rect")
			.data(dataset2)
			.enter()
			.append("rect")
			.attr("x",function(d,i){return i*w/dataset2.length})
			.attr("y",function(d){return h-d[1]-30})
			.attr("width",ww*0.95)
			.attr("height",function(d){return d[1]})
			.attr("fill",function(d,i){return color(i)});
		
		bar1 = svg.append("g").attr("class", "bar1");

		bar1.selectAll("text")
			.data(piedata)
			.enter()
			.append("text")
			.attr("fill","white")
			.attr("transform",function(d){
		var x=arcPath.centroid(d)[0];
		var y=arcPath.centroid(d)[1];
		return "translate("+(w/2+x)+","+(y+h/3)+")";})
			.attr("text-anchor","middle")
			.attr("font-size",function(d){
			return d.data[1]*0.05+"px";})
			.text(function(d){return d.data[0]});
		</script>
</body>

(3)实验结果
在这里插入图片描述

JavaScript连接MySql数据库中的疫苗接种情况数据并进行可视化
(1)数据库
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
(2)代码

<!DOCTYPE html>
<head>
	<meta charset="UTF-8">
</head>
<body>
<div id="wc"></div>
<%@ page contentType="text/html; charset=UTF-8" %> 
<%@ page language="java" %> 
<%@ page import="com.mysql.jdbc.Driver" %> 
<%@ page import="java.sql.*" %> 
<% 
                        //out.print("<center><h1><font color=black>疫苗接种人数</h1></center>");
						
						String driverName="com.mysql.jdbc.Driver"; 
						
						String userName="root"; 
						
						String userPasswd="54.wfy"; 
						
						String dbName="yimiao"; 
						
						String tableName1="renshu"; 

						String tableName2="baifenbi"; 

						String tableName3="douyou";

                        String country1[]=new String[25];

						double data1[]=new double[25];

						String country2[]=new String[25];

						double data2[]=new double[25];

						String country3[]=new String[25];

						double data31[]=new double[25];

						double data32[]=new double[25];
						
						Class.forName("com.mysql.jdbc.Driver").newInstance(); 
						Connection connection=DriverManager.getConnection("jdbc:mysql://localhost:3306/"+dbName+"?serverTimezone=GMT%2B8","root","54.wfy"); 
						Statement statement = connection.createStatement(); 					
						
						for(int i=1;i < 21;i++){
							String sql="SELECT * FROM "+tableName1+" where id='"+i+"'";
							String str=" ";
							double per=1;

							ResultSet rs = statement.executeQuery(sql); 
							while(rs.next()){
								str=rs.getString(2);
								
								per=rs.getDouble(3);
							}
							country1[i-1]=str;
							data1[i-1]=per;
							//out.print(country[i-1]+" ");
							//out.print(data[i-1]);
							rs.close();
						}

						for(int i=1;i < 21;i++){
							String sql="SELECT * FROM "+tableName2+" where id='"+i+"'";
							String str=" ";
							double per=1;

							ResultSet rs = statement.executeQuery(sql); 
							while(rs.next()){
								str=rs.getString(2);
								
								per=rs.getDouble(3);
							}
							country2[i-1]=str;
							data2[i-1]=per;
							//out.print(country[i-1]+" ");
							//out.print(data[i-1]);
							rs.close();
						}

						for(int i=1;i < 17;i++){
							String sql="SELECT * FROM "+tableName3+" where id='"+i+"'";
							String str=" ";
							double per1=1;
							double per2=1;

							ResultSet rs = statement.executeQuery(sql); 
							while(rs.next()){
								str=rs.getString(2);
								
								per1=rs.getDouble(3);
								per2=rs.getDouble(4);
							}
							country3[i-1]=str;
							data31[i-1]=per1;
							data32[i-1]=per2;
							//out.print(country[i-1]+" ");
							//out.print(data[i-1]);
							rs.close();
						}

						statement.close(); 
						connection.close(); 
%>
<div style="position: absolute; bottom: 2150px; right: 365px;"><font size="8"><strong>COVID-19疫苗接种人数(单位:百万)</strong></font></div>
<div style="position: absolute; bottom: 1400px; right: 340px;"><font size="8"><strong>COVID-19疫苗接种人次(单位:次/百人)</strong></font></div>
<div style="position: absolute; bottom: 680px; right: 340px;"><font size="8"><strong>COVID-19疫苗接种人数与人次对比</strong></font></div>
<div style="position: absolute; bottom: 2100px; right: 365px;"><font size="2"><strong>数据来源:Our World in Data</strong></font></div>
<script src="d3.v3.min.js"></script>
		<script>
			var width=window.innerWidth
			|| document.documentElement.clientWidth
			|| document.body.clientWidth;

			var height=window.innerHeight
			|| document.documentElement.clientHeight
			|| document.body.clientHeight;
			w=width*0.98;
			h=height*3;
			var color=d3.scale.category10();
			
			var dataset1=new Array(20);

			var country1=new Array(20);

			var dataset2=new Array(20);

			var country2=new Array(20);

			var dataset31=new Array(16);

			var dataset32=new Array(16);

			var country3=new Array(16);

			<% for (int i=0;i<20;i++){ %>
				dataset1[<%=i%>]= "<%=data1[i]%>";
				country1[<%=i%>]= "<%=country1[i]%>";
			<% } %>

			<% for (int i=0;i<20;i++){ %>
				dataset2[<%=i%>]= "<%=data2[i]%>";
				country2[<%=i%>]= "<%=country2[i]%>";
			<% } %>

			<% for (int i=0;i<16;i++){ %>
				dataset31[<%=i%>]= "<%=data31[i]%>";
				dataset32[<%=i%>]= "<%=data32[i]%>";
				country3[<%=i%>]= "<%=country3[i]%>";
			<% } %>

			var w1=w/dataset1.length;
			var svg=d3.select("body")
					.append("svg")
					.attr("width",w)
					.attr("height",h);
			var rect=svg.selectAll("rect1")
						.data(dataset1)
						.enter()
						.append("rect")
						.attr("x",function(d,i){return i*w/dataset1.length})
						.attr("y",function(d){return h-2*height-d*3-80})
						.attr("width",w1*0.95)
						.attr("height",function(d){return d*3})
						.attr("fill",function(d,i){return color(i)});

			var value=svg.selectAll("text.value1")
						.data(dataset1)
						.enter()
						.append("text")
						.attr("x",function(d,i){return i*w/dataset1.length})
						.attr("y",function(d){return h-2*height-d*3-80})
						.text(function(d){return d})
						.attr("dx",w1/2)
						.attr("dy","-1em")
						.attr("text-anchor","middle")
						.attr("fill",function(d,i){return color(i)});
			svg.selectAll("text.title1")
                .data(country1)
                .enter()
                .append("text")
                .attr("font-size","13px")
                .attr("x",function(d,i){
                    return (w/dataset1.length)*i;
                })
                .attr("y",h-2*height-70)
                .attr("dx",(w/dataset1.length)/2-35)
                .attr("dy","13px")
                .text(function(d){
                    return d;
                })
				.attr("fill",function(d,i){return color(i)});

			var w2=w/dataset2.length;
			var rect=svg.selectAll("rect2")
						.data(dataset2)
						.enter()
						.append("rect")
						.attr("x",function(d,i){return i*w/dataset2.length})
						.attr("y",function(d){return h-height-d*3-80})
						.attr("width",w2*0.95)
						.attr("height",function(d){return d*3})
						.attr("fill",function(d,i){return color(i)});
			var value=svg.selectAll("text.value2")
						.data(dataset2)
						.enter()
						.append("text")
						.attr("x",function(d,i){return i*w/dataset2.length})
						.attr("y",function(d){return h-height-d*3-80})
						.text(function(d){return d})
						.attr("dx",w2/2)
						.attr("dy","-1em")
						.attr("text-anchor","middle")
						.attr("fill",function(d,i){return color(i)});
			svg.selectAll("text.title2")
                .data(country2)
                .enter()
                .append("text")
                .attr("font-size","13px")
                .attr("x",function(d,i){
                    return (w/dataset2.length)*i;
                })
                .attr("y",h-height-70)
                .attr("dx",(w/dataset2.length)/2-35)
                .attr("dy","13px")
                .text(function(d){
                    return d;
                })
				.attr("fill",function(d,i){return color(i)});


			var w3=w/dataset31.length;
			var rect=svg.selectAll("rect31")
						.data(dataset31)
						.enter()
						.append("rect")
						.attr("x",function(d,i){return i*w/dataset31.length+4;})
						.attr("y",function(d){return h-d*3-80})
						.attr("width",w3*0.4)
						.attr("height",function(d){return d*3})
						.attr("fill",function(d,i){return color(i)});
			var value=svg.selectAll("text.value31")
						.data(dataset31)
						.enter()
						.append("text")
						.attr("x",function(d,i){return i*w/dataset31.length-w3/2+20;})
						.attr("y",function(d){return h-d*3-80})
						.text(function(d){return d})
						.attr("dx",w3/2)
						.attr("dy","-1em")
						.attr("text-anchor","middle")
						.attr("fill",function(d,i){return color(i)});
			var rect=svg.selectAll("rect32")
						.data(dataset32)
						.enter()
						.append("rect")
						.attr("x",function(d,i){return i*w/dataset32.length+w3/2-4;})
						.attr("y",function(d){return h-d*3-80})
						.attr("width",w3*0.4)
						.attr("height",function(d){return d*3})
						.attr("fill",function(d,i){return color(i)});
			var value=svg.selectAll("text.value32")
						.data(dataset32)
						.enter()
						.append("text")
						.attr("x",function(d,i){return i*w/dataset32.length+w3/2-30;})
						.attr("y",function(d){return h-d*3-80})
						.text(function(d){return d})
						.attr("dx",w3/2)
						.attr("dy","-1em")
						.attr("text-anchor","middle")
						.attr("fill",function(d,i){return color(i)});
			
			svg.selectAll("text.title3")
                .data(country3)
                .enter()
                .append("text")
                .attr("font-size","13px")
                .attr("x",function(d,i){
                    return (w/dataset31.length)*i;
                })
                .attr("y",h-70)
                .attr("dx",(w/dataset31.length)/2-25)
                .attr("dy","13px")
                .text(function(d){
                    return d;
                })
				.attr("fill",function(d,i){return color(i)});
		</script>
</body>

(3)实验结果
在这里插入图片描述

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值