直方图
1 svg直方图
1.1 基本语法
- 获取屏幕分辨率&浏览器可用宽度
var w=window.innerWidth
|| document.documentElement.clientWidth
|| document.body.clientWidth;
var h=window.innerHeight
|| document.documentElement.clientHeight
|| document.body.clientHeight;
x=document.getElementById("demo");
x.innerHTML="浏览器的内部窗口宽度:" + w + ",高度:" + h + "。"
- 绘制一个矩形
//SVG添加图形
var myRect=document.createElement("rect");
hist.appendChild(myRect);
myRect.outerHTML="<rect x=20 y=50 width=100 height=300 style='fill:blue'/>";
- 添加文本
//SVG添加文本
var svgText=document.createElement("text");
hist.appendChild(svgText);
svgText.outerHTML="<text x=0 y=20 style='font-family:微软雅黑;fill:rgb(0,0,255);font-size:20'> "+w+" </text>";
- 随机色彩
var hiscolor=Math.round(Math.random()*255);
myRect[i].outerHTML="<rect x="+(i*120)+" y="+(300-rand)+" width=100 height="+rand+" style='fill:rgb("+(hiscolorR)+","+(hiscolorG)+","+(hiscolorB)+")'/>";
1.2 源码
<html>
<body>
<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(10);
var txt=new Array(10);
for(var i=0;i<10;i++){
rec[i]=document.createElement("rect");
svg.appendChild(rec[i]);
txt[i]=document.createElement("text");
svg.appendChild(txt[i]);
var height=Math.floor(Math.random()*255);
rec[i].outerHTML="<rect x="+(i*w/rec.length)+" y="+(h-height)+" width="+(0.9*w/rec.length)+" height="+height+" style='fill:rgb("+(255-height/2)+","+(height)+","+(height*200%255)+")'/>";
txt[i].outerHTML="<text x="+(i*w/rec.length+0.5*w/rec.length)+" y="+(h-height)+">"+height+"</text>";
}
</script>
</body>
</html>
1.3 效果图
2 D3直方图
2.1 基本语法
- D3库的准备
下载地址:http://d3js.org
引用方式:
<!-- 最好本地引用 -->
<script src=“d3.v3.min.js” charset=“utf-8”>
</script>
<!-- 网络引用 -->
<script src=“http://d3js.org/d3.v3.min.js” charset=“utf-8”>
</script>
标签 | 用法 | 示例 |
---|---|---|
select | 返回第一个元素 | .select(“body”) |
selectAll | 返回所有元素 | .selectAll(“.content”) |
append | 添加元素 | .append(name) |
remove | 删除元素 | .remove() |
data | 绑定数据 | .data(datasets) |
text | 添加文字 | .text( function(d) { return d } ) |
style | 修改样式 | .style(“color”,“red”).style(“font-size”,“72px”) |
attr | 设定属性 | .attr(“width”, width).attr(“height”, height) |
2.2 代码
<html>
<head>
<meta http-equiv="Content-Type" content="text/html" ; charset="utf-8"><!--字符集是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.90;
var tv = new Array("湖南卫视", "江苏卫视", "浙江卫视", "东方卫视", "北京卫视",
"深圳卫视", "广东卫视", "安徽卫视", "天津卫视", "山东卫视", "黑龙江卫视",
"重庆卫视", "辽宁卫视", "湖北卫视", "江西卫视", "内蒙古卫视", "吉林卫视",
"四川卫视", "贵州卫视", "东南卫视", "云南卫视", "山西卫视");
var view = new Array(0.444, 0.382, 0.266, 0.255, 0.178,
0.137, 0.134, 0.109, 0.065, 0.057, 0.043,
0.040, 0.036, 0.035, 0.035, 0.028, 0.024,
0.024, 0.018, 0.017, 0.016, 0.015);
var svg = d3.select("body")
.append("svg")
.attr("width", w)
.attr("height", h);
svg.selectAll("rect")
.data(view)
.enter()
.append("rect")
.attr("y", function (d, i) {//d是绑定的数据,i是数据的下标
return (h / view.length) * i+10;
})
.attr("x", 100)
.attr("height", function (d, i) {
return (h / view.length) - 10;
})
.attr("width", function (d) {
return Math.round(d * 2500);
})
.attr("fill", function (d, i) {
return "rgb(" + 10 * i + "," + 20 * i + ",200 )";
});
svg.selectAll("text1")
.data(view)
.enter()
.append("text")
.attr("x", function (d) {
return Math.round(d * 2500) + 110;
})
.attr("y", function (d, i) {
return (h / tv.length) * i + 24;
})
.text(function (d) {
return d;
})
.style("font-size", "80%")
.attr("fill", function (d, i) {
return "rgb(0,0,0)";
});
svg.selectAll("text2")
.data(tv)
.enter()
.append("text")
.attr("x", 20)
.attr("y", function (d,i) {
return (h / tv.length) * i+24;
})
.text(function (d) {
return d;
})
.style("font-size", "80%")
.attr("fill", function (d, i) {
return "rgb(" + 5 * i + "," + 10 * i + ", 0 )";
});
</script>
</body>
</html>
2.3 效果图
分形和二叉树
1 递归示意
2 递归实现
2. 1 主要代码
//初值:
show(myWidth/2,(int)(myHeight*3/4),200,0.5,-Math.PI/2,14,g2);
//绘直线:
//起点:
x1=x0;
y1=y0;
//终点:
x2=(int)(x1+length*Math.cos(angle));
y2=(int)(y1+lenght*Math.sin(angle));
lineL=new Line2D.Double(x1,y1,x2,y2);
g2.draw(lineL);
//左子树:
show(x2,y2,length*rate,0.6,angle-Math.PI/4,count-1,g2);
//右子树:
show(x2,y2,length*rate,0.6,angle+Math.PI/4,count-1,g2);
2.2 完整代码
<html>
<body>
<svg id="svg01">
</svg>
<script>
var w=window.innerWidth;
var h=window.innerHeight;
var svg=document.getElementById("svg01");
w=w*0.98;
h=h*0.98;
svg.setAttribute("width",w);
svg.setAttribute("height",h);
var x0=w/2;
var y0=h;
var L=200;
var rate=0.8;
var a=-Math.PI/2;
var count=10;
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.9+Math.random()*0.5);
var aL=a-Math.PI/6*(0.8+Math.random()*0.5);
var aR=a+Math.PI/6*(0.8+Math.random()*0.5);
var lineX=document.createElement("line");
svg.appendChild(lineX);
//lineX.outerHTML="<line x1="+x1+" y1="+y1+" x2="+x2+" y2="+y2+" stroke='blue' stroke-width=4 />";
lineX.outerHTML="<line x1="+x1+" y1="+y1+" x2="+x2+" y2="+y2+" stroke='blue' stroke-width="+(count/3+0.5)+" />";
if(count>0){
show(x2,y2,L*rate,rate,aL,count-1);
show(x2,y2,L*rate,rate,aR,count-1);
}
}
show(x0,y0,L,rate,a,count);
</script>
</body>
</html>
2.3 成果展示
3 文字二叉树
3.1 设置字号
Font font1 = new Font("微软雅黑", Font.BOLD, count*3);
g2.setFont(font1);
3.2 画字符
String str="窗外微云湿翠峦";
g2.drawString(str,(int)x1,(int)y1);
length=count*5*str.length();
//用正态分布调整角度:
java.util.Random rt = new java.util.Random(); double au=0.8,ap=0.2;
double angleAddL=au+ap*rt.nextGaussian();
double angleAddR=au+ap*rt.nextGaussian();
3.3 源码
<html>
<meta http-equiv="Content-Type" content="textt/html"; charset=utf-8>
<body>
<svg id="svg01">
<!-- <text x=200 y=200 fill="red">春江潮水连海平</text>
<text x=200 y=200 fill="green" transform="rotate(45)">海上明月共潮生</text>
<text x=200 y=200 fill="green" transform="rotate(45,200,200)">春江水暖鸭先知</text> -->
</svg>
<script>
var w=window.innerWidth;
var h=window.innerHeight;
var svg=document.getElementById("svg01");
w=w*0.98;
h=h*0.98;
svg.setAttribute("width",w);
svg.setAttribute("height",h);
var x0=w/2;
var y0=h;
var L=300;
var rate=0.8;
var a=-Math.PI/2;
var count=7;
var fontsize=20;
var str="春江潮水连海平";
function show(x0,y0,L,rate,a,count){
var fontsize=count*2;
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 L=L*rate*(0.5+Math.random()*0.5);
var aL=a-Math.PI/6*(0.5+0.5*Math.random()*0.5);
var aR=a+Math.PI/6*(0.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='blue' stroke-width=4 />";
//lineX.outerHTML="<line x1="+x1+" y1="+y1+" x2="+x2+" y2="+y2+" stroke='blue' stroke-width="+(count/3+0.5)+" />";
var words=document.createElement("text");
svg.appendChild(words);
//words.outerHTML="<text x="+x1+" y="+y1+" fill='green'>春江潮水连海平</text>"
//words.outerHTML="<text x="+x1+" y="+y1+" transform='rotate(-90,"+x1+","+y1+")' fill='green'>春江潮水连海平</text>"
//*180/Math.PI用来把弧度数换算成角度数
words.outerHTML="<text x="+x1+" y="+y1+" transform='rotate("+a*180/Math.PI+","+x1+","+y1+")' fill='green' 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="+x1+" cy="+y1+" r=4 fill='red' />";
}
}
}
show(x0,y0,L,rate,a,count);
</script>
</body>
</html>
3.3 效果图
饼图和环图
1 基本语法
1.1 Path路径
下面的命令可用于路径数据:
M = moveto
L = lineto
H = horizontal lineto
V = vertical lineto
C = curveto
S = smooth curveto
Q = quadratic Belzier curve
T = smooth quadratic Belzier curveto
A = elliptical Arc
Z = closepath
例如画出下面这个三角形:
代码如下:
<svg width="100%" height="100%" version="1.1"
xmlns="http://www.w3.org/2000/svg">
<path d="M250 150 L150 350 L350 350 Z" />
</svg>
1.2 圆弧绘制
var dataset = { startAngle: 0 , endAngle: Math.PI * 0.75 };
//创建一个弧生成器
var arcPath = d3.svg.arc()
.innerRadius(50)
.outerRadius(100);
//添加路径
svg.append("path")
.attr("d",arcPath(dataset))
.attr("transform","translate(250,250)")
.attr("stroke","black")
.attr("stroke-width","3px")
.attr("fill","yellow");
1.3 添加文字
//添加文字
svg.selectAll("text")
.data(dataset)
.enter()
.append("text")
.attr("transform",function(d){
return "translate(250,250)" +
"translate(" + arcPath.centroid(d) + ")";
})
.attr("text-anchor","middle")
.attr("fill","white")
.attr("font-size","18px")
.text(function(d){ return Math.floor((d.endAngle - d.startAngle)*180/Math.PI) + "°"; });
2 综合实验
2.1 实验要求
选择小组感兴趣的主题数据,主要使用直方图和饼图,设计实现可视化作品,考虑数据质量,色彩,交互,布局。
2.2 代码
<html>
<head>
<meta http-equiv="Content-Type" content="text/html" ; charset="utf-8"><!--字符集是utf-8-->
<title>环图</title>
</head>
<body>
<script src="https://d3js.org/d3.v4.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.90;
var dataset = [["湖南卫视", 0.3825],["江苏卫视", 0.3103], ["东方卫视", 0.2779], ["浙江卫视", 0.2072], ["北京卫视", 0.1561], ["山东卫视", 0.1467],
["深圳卫视", 0.1082], ["东南卫视", 0.1045], ["安徽卫视", 0.092], ["广东卫视", 0.0888], ["江西卫视", 0.0778], ["贵州卫视", 0.0738], ["天津卫视", 0.0595],["黑龙江卫视", 0.0554],
["重庆卫视", 0.055],["辽宁卫视", 0.0529], ["湖北卫视", 0.0523], ["四川卫视", 0.0519], ["河北卫视", 0.0478], ["河南卫视", 0.0389]
];
//转化数据为适合生成饼图的对象数组
var pie = d3.pie()
.value(function (d) { return d[1]; });
var width = 600;
var height = 600;
var outerRadius = width / 2;//外半径
var innerRadius = width / 3-25;//圆环内半径
//用svg的path绘制弧形的内置方法
var arc = d3.arc()//设置弧度的内外径,等待传入的数据生成弧度
.outerRadius(outerRadius)
.innerRadius(innerRadius);
var arc2 = d3.arc()//设置弧度的内外径,等待传入的数据生成弧度
.outerRadius(outerRadius+25)
.innerRadius(innerRadius);
var svg = d3.select("body")
.append("svg")
.attr("width", w)
.attr("height", h);
var color = d3.scaleOrdinal(d3.schemeCategory20b);//创建序数比例尺和包括20中颜色的输出范围
// 开始绘制,先为每个扇形及其对应的文字建立一个分组g
var arcs = svg.selectAll("g")
.data(pie(dataset))
.enter()
.append("g")
.attr('cursor', 'pointer')
//移到图表中心
.attr("transform", "translate(" + (w / 3+120) + "," + h / 2 + ")");//translate(a,b)a表示横坐标起点,b表示纵坐标起点
//为组中每个元素绘制弧形路路径
arcs.append("path")//每个g元素都追加一个path元素用绑定到这个g的数据d生成路径信息
.attr("fill", function (d, i) {//填充颜色
return color(i);
})
.attr("d", arc)//将角度转为弧度(d3使用弧度绘制
.on('mouseover', function (d, i) {
d3.select(this)
.attr("fill", d3.rgb(color(i)).brighter())
.transition()
.attr("d", function (d) {
return arc2(d);
})
svg.append("text")
.attr("id", "info")
.attr("x", width / 2 + 322)
.attr("y", height / 2 + 10)
.attr("text-anchor", "middle")
.attr("font-size", 36)
.attr("fill", color(i))
.text(d.data[0]+"收视率");
svg.append("text")
.attr("id", "value")
.attr("x", width / 2 + 322)
.attr("y", height / 2 + 60)
.attr("text-anchor", "middle")
.attr("font-size", 36)
.attr("fill", color(i))
.text(d.value + "%");
})
.on('mouseout', function (d, i) {
d3.select(this)
.attr("fill", color(i))
.transition()
.duration(800)
.attr("d", function (d) {
return arc(d);
});
d3.select("#info")
.remove();
d3.select("#value")
.remove();
});
//为组中每个元素添加文本
arcs.append("text")//每个g元素都追加一个path元素用绑定到这个g的数据d生成路径信息
.attr("transform", function (d) {
return "translate(" + arc.centroid(d) + ")";//计算每个弧形的中间点
})
.attr("text-anchor", "middle")
.attr("font-size", 14)
.attr("fill", "black")
.text(function (d) {
if (d.value > 0.07)
return d.value+"%";//这里已经转为对象了
});
let label = svg.selectAll('.label') //添加左侧的标签
.data(pie(dataset))
.enter()
.append('g')
.attr("transform", "translate(" + (width / 2 + outerRadius * 2) + "," + 10 + ")");
label.append('rect') //标签中的矩形
.attr("fill", function (d, i) {//填充颜色
return color(i);
})
.attr('x', -800)
.attr("y", function (d, i) {
return (height - outerRadius-200) / 2 + (i - 1) * 30;
})
.attr('rx', '10') //rx=ry 会出现圆角
.attr('ry', '10')
.attr('cursor', 'pointer')
.attr('width', function (d) {
return Math.round(d.data[1] * 500);
})
.attr('height', 20)
.on('mouseover', function (d, i) {
d3.select(this)
.attr("fill", d3.rgb(color(i)).brighter())
svg.append("text")
.attr("id", "info")
.attr("x", width / 2 + 322)
.attr("y", height / 2 + 10)
.attr("text-anchor", "middle")
.attr("font-size", 36)
.attr("fill", color(i))
.text(d.data[0] + "收视率");
svg.append("text")
.attr("id", "value")
.attr("x", width / 2 + 322)
.attr("y", height / 2 + 60)
.attr("text-anchor", "middle")
.attr("font-size", 36)
.attr("fill", color(i))
.text(d.value + "%");
})
.on('mouseout', function (d, i) {
d3.select(this)
.attr("fill", color(i))
d3.select("#info")
.remove();
d3.select("#value")
.remove();
});
label.append("text")
.attr("x", -885)
.attr("y", function (d, i) {
return (height - outerRadius - 165) / 2 + (i - 1) * 30;
})
.attr("font-size", 16)
.attr("fill", function (d, i) {//填充颜色
return color(i);
})
.text(function (d,i) {
return d.data[0];
});
</script>
</body>
</html>
2.2 效果图
JSP连接数据库
1 基本语法
1.1 加载驱动程序
String driverName="com.mysql.jdbc.Driver";
1.2 定义数据库和数据表
//数据库
String dbName="engword";
//数据表
String tableName="map_enword";
1.3 定义用户名和密码
String userName="root";
String userPasswd="2017";
1.4 建立链接
Class.forName(driverName).newInstance();
Connection connection=DriverManager.getConnection(url);
1.5 陈述&得到回答
Statement statement=connection.createStatement();
String sql="Select * from "+tableName+" order by english";
ResultSet rs=statement.executeQuery(sql);
int count=0;
while(rs.next())
{
count++;
if (count<10)
out.print(rs.getString(2)+"<br>");
}
out.print(count);
out.print("<br>");
1.6 关闭链接
rs.close(); //数据取完
statement.close(); //陈述结束
connection.close(); //断开链接
1.7 JSP运行原理
1.8 JSP 向 js 中传递数组
var dataset =new Array(26);
<% for(int i=0;i <count.length;i++){ %>
dataset[ <%=i%> ]= " <%=count[i]%> ";
<% } %>
1.9 易错提示
这里我单独写了一篇博客:
JSP连接数据库失败的问题
2 综合实验
2.1 要求
链接数据库,可视化英文字母的百分比(饼图),英文首字母的词数(直方图)
2.2 代码
<!DOCTYPE html>
<body>
<div id="wc"></div>
<%@ page contentType="text/html; charset=UTF-8" %>
<%@ page language="java"%>
<%@ page import="com.mysql.cj.jdbc.Driver" %>
<%@ page import="java.sql.*" %>
<%
//驱动程序名
String driverName="com.mysql.cj.jdbc.Driver";
//数据库用户名
String userName="root";
//密码
String userPasswd="******";
//数据库名
String dbName="Data_v";
//表名
String tableName="map_enword";
//联结字符串
String url="jdbc:mysql://localhost:3306/Data_v?useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=UTC";
Class.forName("com.mysql.cj.jdbc.Driver").newInstance();
Connection connection=DriverManager.getConnection(url,userName,userPasswd);
Statement statement = connection.createStatement();
int count[]=new int[26];
int count2[]=new int[26];
for(int i=0;i<26;i++){
int aa=Integer.valueOf('a')+i;
char cha = (char) aa;
//out.print(aa);
//out.print(cha);
//String sql="SELECT * FROM "+tableName+" where english like 'a%' "+"order by english";
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()) {
//rs.getString(1)代表取当前行的第1列,也可以直接写列名
str=(rs.getString("english")).substring(0,1);
//out.print(str+" ");
j++;
}
count[i]=j;
//out.print(" "+j+" <br>");
rs.close();
}
//String sql="SELECT * FROM "+tableName+" where english like 'a%' "+"order by english";
String sq2="SELECT english FROM "+tableName;
ResultSet rs2 = statement.executeQuery(sq2);
// 输出每一个数据值
int j=0;
String str2;
while(rs2.next()) {
for(int i=0;i<26;i++){
int aa=Integer.valueOf('a')+i;
char cha = (char) aa;
int find=0;
str2=(rs2.getString("english"));
find=str2.indexOf(cha);
while(find!=-1){
count2[i]++;
find=str2.indexOf(cha,find+1);
}
}
}
//out.print(" "+j+" <br>");
rs2.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*0.98;
var color=d3.scale.category20();
var dataset=new Array(26);
<%for(int i=0;i<count.length;i++){%>
dataset[<%=i%>]="<%=count[i]%>";
<%}%>
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/2/dataset.length})
.attr("y",function(d){return h-d*0.8-20})
.attr("rx",'5')
.attr("ry",'5')
.attr("width",ww/2*1.2)
.attr("height",function(d){return d*0.8})
.attr("fill",function(d,i){return color(i)})
.on('mouseover', function (d, i) {
d3.select(this)
.attr("fill", d3.rgb(color((5+i)%20)))
})
.on('mouseout', function (d, i) {
d3.select(this)
.attr("fill", color(i))
.duration(800)
})
svg.selectAll("text")
.data(dataset)
.enter()
.append("text")
.attr("x",function(d,i){return i*w/2/dataset.length})
.attr("y",function(d){return h-d*0.8})
.text(function(d){return d})
.attr("dx",ww/2*0.6)
.attr("dy","-2em")
.attr("text-anchor","middle")
.attr("fill",function(d,i){return color(i)});
svg.selectAll("text1")
.data(dataset)
.enter()
.append("text")
.attr("x",function(d,i){return i*w/2/dataset.length})
.attr("y",h-3)
.text(function(d,i){return String.fromCharCode(65+i)})
.attr("dx",ww/2*0.4)
.attr("fill","black");
var width = 600;
var height = 600;
var dataset2=new Array(26);
<%for(int i=0;i<count2.length;i++){%>
dataset2[<%=i%>]="<%=count2[i]%>";
<%}%>
var piee=d3.layout.pie()
.value(function(d){
return d;
});
//pie()算出来弧度数
var piedata=piee(dataset2);
//内半径100,外半径300
//var arcPath=d3.svg.arc()
var arc=d3.svg.arc()
.innerRadius(140)
.outerRadius(250);
//svg需要selectAll
var arc2=d3.svg.arc()
.innerRadius(150)
.outerRadius(320);
//svg需要selectAll
svg.selectAll("path")
.data(piedata)
.enter()
.append("path")
//function(d,i) i这里没什么用,d是所有的dataset元素
.attr("d",function(d){
//打印结果,在页面元素的Console里
//console.log(arcPath(d))
//打印pie()的输出,弧度数
//return arcPath(d)
return arc(d)
})
.attr("fill",function(d,i){
return color(i);
})
.attr("stroke","white")
.attr("transform","translate("+w*0.75+","+h/2+")")
.on('mouseover', function (d, i) {
d3.select(this)
.attr("fill", d3.rgb(color(i)))
.transition()
.attr("d", function (d) {
return arc2(d);
})
svg.append("text")
.attr("id", "info")
.attr("text-anchor", "middle")
.attr("font-size", 60)
.attr("fill", color(i))
.attr("transform","translate("+w*0.75+","+(h/2-20)+")")
.attr("text-anchor","middle")
.text(String.fromCharCode(65+i));
svg.append("text")
.attr("id", "value")
.attr("text-anchor", "middle")
.attr("font-size", 60)
.attr("fill", color(i))
.attr("transform","translate("+w*0.75+","+(h/2+30)+")")
.attr("text-anchor","middle")
.text(((d.endAngle-d.startAngle)/Math.PI*100).toFixed(2) + "%");
})
.on('mouseout', function (d, i) {
d3.select(this)
.attr("fill", color(i))
.transition()
.duration(800)
.attr("d", function (d) {
return arc(d);
});
d3.select("#info")
.remove();
d3.select("#value")
.remove();
})
svg.selectAll("text2")
.data(piedata)
.enter()
.append("text")
.attr("fill","black")
.attr("font-size",function(d){
return (d.endAngle-d.startAngle)*100/Math.PI+5;
})
.attr("text-anchor","middle")
.attr("transform",function(d,i){
var x=arc.centroid(d)[0]
var y=arc.centroid(d)[1]
//一定要将表达式放在一对括号里,否则不会显示
return "translate("+(w*0.75+x)+","+(h/2+y)+")";
})
.text(function(d){
var rate=(d.endAngle-d.startAngle)/Math.PI*100;
if(rate<=3){
}
else{
return (rate.toFixed(2) + "%");
}
});
//根据,自动换行
var label="18计科 石璇 201811113023,申汶 201811113018 ";
var text=svg.append("text")
.attr("x",w-300)
.attr("y",h-50)
.attr("font-size",20)
.attr("fill", "rgb(100,100,100)");
var strs = label.split(",") ;
console.log(strs);
text.selectAll("tspan")
.data(strs)
.enter()
.append("tspan")
.attr("x",text.attr("x"))
.attr("dy","1em")
.text(function(d){
return d;
});
svg.append("text")
.attr("x",w/4-170)
.attr("y",50)
.attr("fill","black")
.attr("font-size",30)
.attr("fill", "rgb(100,100,100)")
.text("首字母出现频数直方图");
svg.append("text")
.attr("x",w*0.75-110)
.attr("y",50)
.attr("fill","black")
.attr("font-size",30)
.attr("fill", "rgb(100,100,100)")
.text("字母出现频率环图");
</script>
</body>
2.3 效果图
力导向图
1 基本语法
1.1 两种方式
- 转换为Json格式的文本文件
- 拼写Json格式字符串
1.2 svg.layout.force数据准备:节点、边
var force=d3.layout.force()
.nodes(nodes)
.links(edges)
.size([width,height])
.linkDistance(200)
.charge(-600) .start();
1.3 添加结点文字
var texts=svg.selectAll(".forceText")
.data(nodes)
.enter()
.append("text")
.attr("class","forceText")
.attr("x",function(d){return d.x;})
.attr("y",function(d){return d.y;})
.style("stroke", "#336666")
.style("stroke-family","仿宋")
.style("font-size","10px")
.attr("dx","-1.5em")
.attr("dy","1.5em")
.text(function(d){return d.name;});
1.4 添加边文字
var edges_text = svg.selectAll(".linetext")
.data(edges)
.enter()
.append("text")
.attr("class","linetext")
.text(function(d){return d.relation;})
.style("stroke","gray")
.style("font-size",8);
2 代码
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
<style>
.tooltip{
position: absolute;
width: 240px;
height: auto;
font-family: simsun;
font-size: 10px;
text-align: left;
color: rgb(119, 111, 111);
border-width: 1px solid rgb(245, 241, 241);
background-color: rgb(253, 249, 238);
border-radius: 3px;
}
</style>
</head>
<body>
<script src="d3.v3.js"></script>
<script>
var nodes=[{"name":"米里哀主教","group":0,"describe":"视众生平等,苦众生苦,观众生相"},
{"name":"玛格洛","group":1},
{"name":"冉阿让","group":2,"describe":"因偷一块面包被判入狱十九年,出狱后被米里埃主教感化,改名在马德兰当上市长,帮助芳汀、收养珂赛特,战争中放走沙威,被不知真相的马吕斯鄙视遗憾死去"},
{"name":"沙威","group":3,"describe":"在冉阿让担任玛德兰市长时揭发他,一直追杀冉、沙威,在街堡战争被掳获冉救助,放过冉后自杀"},
{"name":"芳汀","group":4,"describe":"被欺骗感情后生下珂赛特,寄养珂赛特并到工厂工作,遭遇不幸悲惨死去"},
{"name":"珂赛特","group":5,"describe":"幼年遭受非人待遇,甘于接受命运安排,勇于追求爱情"},
{"name":"多罗米埃","group":6},
{"name":"德纳第夫妇","group":7,"describe":"战后搜刮钱财巧合救了彭眉胥,虐待珂赛特并骗取钱财,利用自己的女儿赚钱,试图敲诈马吕斯"},
{"name":"马吕斯","group":8,"describe":"共和派,参战被冉阿让救出,钟情于珂赛特"},
{"name":"吉诺曼先生","group":9,"describe":"影响马吉斯政治态度"},
{"name":"彭眉胥","group":10,"describe":"幼年收祖父影响误解父亲,父亲死后发现父亲是英雄脱离外祖父独自闯荡,滑铁卢战役男爵"},
{"name":"爱潘妮","group":11},
{"name":"二女儿","group":12},
{"name":"小伽弗洛升","group":13,"describe":"救了一个快冻死的姑娘和两个孩子,街垒战争中做出巨大贡献最终牺牲"},
{"name":"割风","group":14,"describe":"年轻时被马德兰市长所救,多年后帮助冉逃脱沙威的追捕"}];
var edges=[{"source":0,"target":1,"value":10,"name":"兄妹"},
{"source":0,"target":2,"value":10,"name":"收养、开导、感化"},
{"source":3,"target":2,"value":10,"name":"典狱官与苦奴犯"},
{"source":2,"target":4,"value":10,"name":"帮助,老板与工人"},
{"source":2,"target":5,"value":10,"name":"收养"},
{"source":6,"target":4,"value":10,"name":"始乱终弃"},
{"source":5,"target":4,"value":10,"name":"母女"},
{"source":5,"target":6,"value":10,"name":"父女"},
{"source":7,"target":5,"value":10,"name":"强迫劳动并虐待"},
{"source":5,"target":8,"value":10,"name":"情人"},
{"source":8,"target":9,"value":10,"name":"外祖父"},
{"source":7,"target":8,"value":10,"name":"欺骗"},
{"source":11,"target":8,"value":10,"name":"暗恋,并在起义中为其牺牲"},
{"source":10,"target":8,"value":10,"name":"父子"},
{"source":11,"target":7,"value":10,"name":"女儿"},
{"source":12,"target":7,"value":10,"name":"女儿"},
{"source":13,"target":7,"value":10,"name":"儿子"},
{"source":7,"target":10,"value":10,"name":"从战场救出实则为了偷东西"},
{"source":14,"target":2,"value":10,"name":"搭救"}];
var width=(window.innerWidth||document.documentElement.clientWidth||document.body.clientWidth)*0.98;
var height=(window.innerHeight||document.documentElement.clientHeight||document.body.clientHeight)*0.9;
var color=d3.scale.category20();
var force = d3.layout.force()
.nodes(nodes)
.links(edges)
.size([width, height])
.linkDistance(230)
.charge(-1000)
.on("tick", tick)
.start();
var svg = d3.select("body")
.append("svg")
.attr("width", width)
.attr("height", height);
svg.append("text")
.attr("x", function (d, i) {
return width / 2 + 300 ;
})
.attr("y", height-150)
.text("《悲惨世界》人物关系力导图")
.attr("fill", "rgb(100,100,100)")
.style("font-size", "190%");
//绘制箭头
var defs = svg.append("defs");
var radius=10;
var arrowMarker = defs.append("marker")
.attr("id","arrow")
.attr("markerUnits","strokeWidth")
.attr("markerWidth","6")
.attr("markerHeight","4")
.attr("viewBox","0 0 6 4")
.attr("refX",12+radius/8-2) //实际是radius/strokeWidth
.attr("refY",2)
.attr("orient","auto");
var arrow_path = "M0,1 L6,2 L0,3 L0,0";
arrowMarker.append("path")
.attr("d",arrow_path);
//提示框部分
var tooltip=d3.selectAll("body")
.append("div")
.attr("class","tooltip")
.style("opacity",0.0);
//用路径创建边
var path = svg.selectAll("path")
.data(edges)
.enter()
.append("path")
.attr("id", function(d,i) {
return "edgepath" +i;
})
.attr("class","edges");
var link=svg.selectAll(".link")
.data(edges)
.enter()
.append("line")
.attr("class","link")
.attr("stroke","gray")
.attr("stroke-width",2)
.attr("marker-end","url(#arrow)");
var circle = svg.selectAll("circle")
.data(nodes)
.enter()
.append("circle")
.attr("r",function(d){return d.weight*5})
.attr("fill",function(d,i){return color(i);})
.call(force.drag)
.on("mouseover",function(d,i){
tooltip.html(d.describe)
.style("left",(d3.event.pageX)+"px")
.style("top",(d3.event.pageY+20)+"px")
.style("opacity",1.0);
})
.on("mouseout",function(d,i){
tooltip.style("opacity",0.0);
});
var nodetext = svg.selectAll(".nodeText")
.data(nodes)
.enter()
.append("text")
.attr("font-size",function(d,i){
return d.weight*3+10;
})
.attr("class","nodeText")
.attr("x",function(d){return d.x;})
.attr("y",function(d){return d.y;})
.attr("dx","-1.5em")
.attr("dy","2em")
.text(function(d) { return d.name; });
var pathtext = svg.selectAll('g')
.data(edges)
.enter()
.append("text")
.attr("font-size","10")
.append('textPath')
.attr("text-anchor", "middle")//居中
.attr("startOffset","50%")
.attr('xlink:href', function(d,i) { return "#edgepath" + i; })
.text(function(d) { return d.name; });
function tick() {
path.attr("d", function(d) {
var dx = d.target.x - d.source.x;//增量
var dy = d.target.y - d.source.y;
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 + ")";
});
nodetext.attr("x",function(d){return d.x;});
nodetext.attr("y",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});
}
</script>
</body>
</html>
3 效果图
词云图
1 内容
连接数据库卫视收视率词云图可视化
2 代码
<!DOCTYPE html>
<body>
<div id="wc"></div>
<%@ page contentType="text/html; charset=UTF-8" %>
<%@ page language="java"%>
<%@ page import="com.mysql.cj.jdbc.Driver" %>
<%@ page import="java.sql.*" %>
<%
out.print("<center><h1><font color=grey>卫视收视率词云图</h1></center>");
//驱动程序名
String driverName="com.mysql.cj.jdbc.Driver";
//数据库用户名
String userName="root";
//密码
String userPasswd="******";
//数据库名
String dbName="mydata";
//表名
String tableName="startvratings";
//联结字符串
String url="jdbc:mysql://localhost:3306/mydata?useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=UTC";
Class.forName("com.mysql.cj.jdbc.Driver").newInstance();
Connection connection=DriverManager.getConnection(url,userName,userPasswd);
Statement statement = connection.createStatement();
String tv[]=new String[10];
double ratings[]=new double[10];
//String sql="SELECT * FROM "+tableName+" where english like 'a%' "+"order by english";
String sql="SELECT * FROM "+tableName;
ResultSet rs = statement.executeQuery(sql);
String str;
for(int i=0;i<10&&rs.next();i++){
tv[i]=rs.getString(2);
//out.print(tv[i]);
str=rs.getString(3);
ratings[i]=Double.valueOf(str).doubleValue();//将String类型转换成Double类型
//out.print(ratings[i]);
}
rs.close();
statement.close();
connection.close();
%>
<script src="d3.v3.min.js"></script>
<script src="d3.layout.cloud.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 fill = d3.scale.category20();
var datas = new Array(10);
var temp = new Array();//定义一个字典
<%for(int i=0;i<10;i++){ %>
temp={text:"<%=tv[i]%>",size:<%=ratings[i]%>};
//console.log(temp);
datas[<%=i%>]=temp;
<%}%>
//console.log(datas);
var wc=d3.layout.cloud()
.size([w, h])
.words(datas)
.padding(0)
.rotate(function() { return ~~(Math.random()*2)*90; })
.font("Impact")
.fontSize(function(d) { return ((d.size*1000)/5); })
.on("end", draw)//布局结束以后调用draw
.start();
function draw(datas) {
d3.select("body").append("svg")
.attr("width", w)
.attr("height", h)
.append("g")
.attr("transform", "translate(300,200)")
.selectAll("text")
.data(datas)
.enter().append("text")
.style("font-size", function(d) { return (d.size) + "px"; })
.style("font-family", "Impact")
.style("fill", function(d, i) { return fill(i); })
.attr("text-anchor", "middle")
.attr("transform", function(d) {
return "translate(" + [(w/5+d.x), (h/5+d.y)] + ")rotate(" + d.rotate + ")";//d.x和d.y是layout算出来的
})
.text(function(d) { return d.text; });
}
</script>
</body>
</html>