准备部分:
Java下载:官网下载
tomcat下载教程:https://www.cnblogs.com/lpgit/p/10929507.html
需要配置三个环境变量
1.二叉树和文字树
1.1二叉树代码如下:
<html>
<head>
<meta charset="utf-8">
<title>吴羽琦和秦雪静的二叉树</title>
</head>
<body>
<h6 align="center">吴羽琦和秦雪静的二叉树</h6>
<svg id="mysvg" width=100 height=100>
</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);
h=h*0.9;
var L=130;
var rate=0.8;
var x0=w/2;
var y0=h;
var count=9;
var a=-Math.PI/2;
var iter=40
function show(x0,y0,L,a,count,iter){
var x1=x0;
var y1=y0;
var randomlong = L*(0.5+0.5*Math.random());
var x2=x1+randomlong*Math.cos(a);
var y2=y1+randomlong*Math.sin(a);
var lineX= document.createElement("line");
svg.appendChild(lineX);
lineX.outerHTML="<line x1="+x1+" y1="+y1+" x2="+x2+" y2="+y2+" style='stroke:rgb(0,"+(iter)+",0);stroke-width:"+(count)+"' />";
var aL=a-Math.PI/6*(0.5+Math.random()*0.5);
var aR=a+Math.PI/6*(0.5+Math.random()*0.5);
var rec=document.createElement("rect");
svg.appendChild(rec);
if(count==0){
rec.outerHTML="<rect x="+x1+" y="+y1+" width=2 height=2 fill='red' >";
}
if(count>0){
show(x2,y2,L*rate,aL,count-1,iter+20);
show(x2,y2,L*rate,aR,count-1,iter+20);
}
}
show(x0,y0,L,a,count,iter);
</script>
</body>
</html>
效果图
style='stroke:rgb(0,"+(iter)+",0);stroke-width:"+(count)+"' />"这里决定了颜色越往上会越来越浅,因为左右都是循环,进入下次循环时iter位置的数据变成了iter+20
之前还做过树枝顶端长着随机数的红果子,只用把圆环的填充色改成ARGB,A的数值是0,就可以再在X,Y处写文本,居圆果中需要再微微调整XY位置。
1.2文字树
代码如下:
<html>
<head>
<meta charset="utf-8">
<title>吴羽琦和秦雪静的二叉树</title>
</head>
<body>
<h6 align="right">吴羽琦和秦雪静的二叉树</h6>
<svg id="mysvg" width=100 height=100>
</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);
h=h*0.9;
var L=30;
var rate=0.8;
var x0=w/2;
var y0=h;
var str="二零六美少女";
var count=7;
var a=-Math.PI/2;
var iter=40
var fontsize=20;
function show(x0,y0,L,a,count,iter){
var fontsize=count*2.5;
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 lineX= document.createElement("line");
//svg.appendChild(lineX);
//lineX.outerHTML="<line x1="+x1+" y1="+y1+" x2="+x2+" y2="+y2+" style='stroke:rgb(0,"+(iter)+",0);stroke-width:"+(count)+"' />";
var words= document.createElement("text");
svg.appendChild(words);
words.outerHTML="<text x="+x1+" y="+y1+" transform='rotate("+a*180/Math.PI+","+x1+","+y1+")' fill='green' font-size="+fontsize+">"+str+"</text>";
var aL=a-Math.PI/6*(0.5+Math.random()*0.5);
var aR=a+Math.PI/6*(0.5+Math.random()*0.5);
var rec=document.createElement("rect");
svg.appendChild(rec);
if(count==0){
var num=Math.floor(Math.random()*100+1);
rec.outerHTML="<text x="+x1+" y="+y1+" fill='red' font-size=5>"+num+"</text>";
}
if(count>0){
show(x2,y2,L,aL,count-1,iter+20);
show(x2,y2,L,aR,count-1,iter+20);
}
}
show(x0,y0,L,a,count,iter);
</script>
</body>
效果图:
尝试过输入阿拉伯数字成为文字树,那样枝与枝之间有大量空隙。
2.饼图和直方图:
<head>
<meta charset="UTF-8">
<title>饼图</title>
<style>
.container {
margin: 30px auto;
width: 600px;
height: 300px;
border: 0px solid #000;
}
polyline {
fill: none;
stroke: #000000;
stroke-width: 2px;
stroke-dasharray: 5px;
}
</style>
</head>
<body>
<h2 align="center">湖北省2021年高考选科分布图</h2>
<div class="container">
<svg width="100%" height="100%"></svg>
</div>
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
<script>
window.onload = function() {
var width = 600, height = 300;
// 创建一个分组用来组合要画的图表元素
var main = d3.select('.container svg').append('g')
.classed('main', true)
.attr('transform', "translate(" + width/2 + ',' + height/2 + ')');
// 模拟数据
var dataset = [
{name: '生物', value: 69.80},
{name: '物理', value: 51.73},
{name: '化学', value: 47.14},
{name: '地理', value: 46.85},
{name: '政治', value: 48.28},
{name: '历史', value: 36.23},
];
// 转换原始数据为能用于绘图的数据
var pie = d3.layout.pie()
.sort(null)
.value(function(d) {
return d.value;
});
// pie是一个函数
var pieData = pie(dataset);
// 创建计算弧形路径的函数
var radius = 100;
var arc = d3.svg.arc()
.innerRadius(0)
.outerRadius(radius);
var outerArc = d3.svg.arc()
.innerRadius(1.2 * radius)
.outerRadius(1.2 * radius);
var oArc = d3.svg.arc()
.innerRadius(1.1 * radius)
.outerRadius(1.1 * radius);
var slices = main.append('g').attr('class', 'slices');
var lines = main.append('g').attr('class', 'lines');
var labels = main.append('g').attr('class', 'labels');
// 添加弧形元素(g中的path)
var arcs = slices.selectAll('g')
.data(pieData)
.enter()
arcs.append('path')
.attr('fill', function(d, i) {
return getColor(i);
})
.attr('d', function(d){
return arc(d);
});
arcs.append("text")//每个g元素都追加一个path元素用绑定到这个g的数据d生成路径信息
.attr("transform",function(d){
return "translate("+arc.centroid(d)+")";//计算每个弧形的中心点(几何中心)
})
.attr("text-anchor","middle")
.attr("font-size",12)
.attr("fill","#696969")
.text(function(d){
return d.value+ "%";//这里已经转为对象了
});
// 添加文字标签
var texts = labels.selectAll('text')
.data(pieData)
.enter()
.append('text')
.attr('dy', '0.35em')
.attr('fill', function(d, i) {
return getColor(i);
})
.text(function(d, i) {
return d.data.name;
})
.style('text-anchor', function(d, i) {
return midAngel(d)<Math.PI ? 'start' : 'end';
})
.attr('transform', function(d, i) {
// 找出外弧形的中心点
var pos = outerArc.centroid(d);
// 改变文字标识的x坐标
pos[0] = radius * (midAngel(d)<Math.PI ? 1.5 : -1.5);
return 'translate(' + pos + ')';
})
.style('opacity', 1);
var polylines = lines.selectAll('polyline')
.data(pieData)
.enter()
.append('polyline')
.attr('points', function(d) {
return [arc.centroid(d), arc.centroid(d), arc.centroid(d)];
})
.attr('points', function(d) {
var pos = outerArc.centroid(d);
pos[0] = radius * (midAngel(d)<Math.PI ? 1.5 : -1.5);
return [oArc.centroid(d), outerArc.centroid(d), pos];
})
.style('opacity', 0.5);
};
function midAngel(d) {
return d.startAngle + (d.endAngle - d.startAngle)/2;
}
function getColor(idx) {
var palette = [
'#2ec7c9', '#b6a2de', '#5ab1ef', '#ffb980', '#d87a80',
'#8d98b3', '#e5cf0d', '#97b552', '#95706d', '#dc69aa',
'#07a2a4', '#9a7fd1', '#588dd5', '#f5994e', '#c05050',
'#59678c', '#c9ab00', '#7eb00a', '#6f5553', '#c14089'
]
return palette[idx % palette.length];
}
</script>
</body>
<script type="text/javascript">
// 绘制柱状态
let width=500,height=400,num=40;
// 定义数据源 学员成绩
let score=[69.80,51.73,47.14,46.85,48.28,36.23]
let text=['生物','物理','化学','地理','政治','历史'];
// 1 创建svg容器
let svg = d3.select('body').append('svg').attr('width',1500).attr('height',height);
// 需要创建g元素 相当于 block 只起到包裹元素作用 方便后期代码维护管理
let g = svg.append('g').attr('transform',`translate(450,${num})`)
// // 定义比例尺
// let scaleY = d3.scale.linear().domain([0,d3.max(score)]).range([0,height-num*2])
let scaleY = d3.scale.linear().domain([0,d3.max(score)]).range([height-num*2,0])
let scaleX = d3.scale.ordinal().domain(text).rangeRoundBands([0,width-num*2],0.4)
// 颜色比例尺
let color = d3.scale.category10();
// 往g元素中追加rect矩形(根据数据) 绘制柱状图
//ease(): linear:线性 circle:缓慢 elastic:带有弹跳的到达最终状态 bounce:最后跳动
// transition:开启动画过度效果
// duration:指定每个元素的动画持续时间
// delay:指定每个元素的动画延迟时间
g.selectAll('rect').data(score).enter()
.append('rect')
.attr('x',(d,i)=>{return scaleX(text[i])})
// .attr('y',(d,i)=>{return scaleY(d)})
.attr('y',(d,i)=>{return height-num*2})
.attr('width',()=>{return scaleX.rangeBand()})
// .attr('height',(d,i)=>{return height-num*2-scaleY(d)})
.attr('height',(d,i)=>{return 0})
.attr('fill',(d,i)=>{return color(i)})
.on('mouseover',function(){
d3.select(this).attr('fill','yellow')
})
.on('mouseout',function(d,i){
d3.select(this).transition().duration(500).attr('fill',()=>{
return color(i)
})
})
.transition()
.duration(1000)
.delay((d,i)=>{
return i*400
})
.ease('bounce')
.attr('y',(d,i)=>{return scaleY(d)})
.attr('height',(d,i)=>{return height-num*2-scaleY(d)})
// 给柱状图添加文本描述
g.selectAll('text').data(score).enter()
.append('text')
.attr('x',(d,i)=>{return scaleX(text[i])})
.attr('y',(d,i)=>{return height-num*2})
.attr('dx',(d,i)=>{return 6})
.attr('dy',(d,i)=>{return -5})
.text((d,i)=>{return d})
.attr('fill',(d,i)=>{return "#696969"})
.transition()
.duration(1000)
.delay((d,i)=>{
return i*400
})
.ease('bounce')
.attr('y',(d,i)=>{return scaleY(d)})
// .attr('height',(d,i)=>{return height-num*2-scaleY(d)})
// 绘制比例尺 axis() orient() 控制文本在轴的展示方向问题 left right top bottom
let x = d3.svg.axis().scale(scaleX)
let y = d3.svg.axis().scale(scaleY).orient('left')
// 追加比例尺
g.append('g').attr('class','axis').call(x).attr('transform',`translate(0,${height-num*2})`)
g.append('g').attr('class','axis').call(y)
</script>
<h6 align="right">吴羽琦和秦雪静的饼图</h6>
代码是网上的,数据改了一下,再进行了整合,尝试着把两个色调统一一下,但总是运行不出来。它总是在我以为会报错的时候不报错,在我以为会报错的时候不报错。
3.词云图
<!DOCTYPE html>
<head>
<title>基于D3的词云图</title>
</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.*" %>
<%
//驱动程序名
String driverName="com.mysql.jdbc.Driver";
//数据库用户名
String userName="root";
//密码
String userPasswd="Xz8231600";
//数据库名
String dbName="sakila";
//表名
String tableName="p";
//联结字符串
String url="jdbc:mysql://localhost/"+dbName+"?user="+userName+"&password="+userPasswd+"&useUnicode=true&characterEncoding=utf8&serverTimezone=UTC";
Class.forName("com.mysql.jdbc.Driver").newInstance();
Connection connection=DriverManager.getConnection(url);
Statement statement = connection.createStatement();
double[] count=new double[12];
int j=0;
//String sql="SELECT * FROM "+tableName+" where english like 'a%' "+"order by english";
String sql="SELECT percentage FROM p";
ResultSet rs = statement.executeQuery(sql);
// 输出每一个数据值
double str;
while(rs.next()){
count[j]=rs.getDouble("percentage");
j=j+1;
}
rs.close();
statement.close();
connection.close();
%>
<script src="https://d3js.org/d3.v3.min.js" ></script>
<script src="d3.layout.cloud.js"></script>
<script charset="utf-8">
var w = window.innerWidth
|| document.documentElement.clientWidth
|| document.body.clientWidth;
var h = window.innnerHeight
|| document.documentElement.clientHeight
|| document.body.clientHeight;
w=w*0.9
h=h*0.98
var data=new Array(5)
var data1=["物化生","物生地","物化地","物生政","物政地","物化政","史政生","史政地","史地生","史化生","史政化","史地化"]
<% for(int i=0;i <12;i++){%>
data[ <%=i%> ]= {text:data1[<%=i%>],size:<%=count[i]%>*7 };
<% } %>
var svg = d3.select("body").append("svg").attr("width", w ).attr("height", h );
var fill = d3.scale.category20();
var words=[{text:"战狼2",size:57},{text:"速度与激情8",size:27},{text:"羞羞的铁拳",size:22},{text:"功夫瑜伽",size:18},
{text:"西游伏妖篇",size:17},{text:"变形金刚5",size:16},{text:"摔跤吧!爸爸",size:13},{text:"芳华",size:13},
{text:"寻梦环游记",size:12},{text:"加勒比海盗5",size:12}];
var wc=d3.layout.cloud()
.size([w, h])
.words(data)
.padding(5)
.rotate(function() { return ~~(Math.random() * 2) * 90; })
.font("Impact")
.fontSize(function(d) { return d.size; })
.on("end", draw)
.start();
function draw(words) {
svg.append("g")
.attr("transform", "translate("+w/2+",+"+h/2+")")
.selectAll("text")
.data(data)
.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(" + [d.x, d.y] + ")rotate(" + d.rotate + ")";
})
.text(function(d) { return d.text; });
}
svg.append("text").text("数据来源:数据表").attr("x",15).attr("y",45)
svg.append("text").text("版权信息:秦雪静吴羽琦").attr("x",15).attr("y",60)
svg.append("text").text("广东省新高考学生选课组合比例情况").attr("x",250).attr("y",50).attr("fill","green").attr("font-size","60px")
</script>
</body>
</html>
4.力导向
<html>
<head>
<title>
广州选课关系图
</title>
</head>
<body style=" opacity:1">
<script src="https://d3js.org/d3.v3.min.js" ></script>
<script type="text/javascript">
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 img_h=50;
var img_w=50;
var radius=10;
var svg=d3.select("body")
.append("svg")
.attr("width",width)
.attr("height",height);
var nodes=[{name:"物理",value:14,intro:"56.07%"},
{name:"历史",value:10,intro:"43.93%"},
{name:"政治",value:8,intro:"37.84%"},
{name:"化学",value:11,intro:"46.04%"},
{name:"生物",value:16,intro:"62.17%"},
{name:"地理",value:13,intro:"53.95%"}];
var edges=[{source:0,target:2,relation:"14.79%",weight:15},{source:0,target:3,relation:"30.78%",weight:31},
{source:0,target:4,relation:"35.14%",weight:35},{source:0,target:5,relation:"31.43%",weight:31}, {source:1,target:2,relation:"23.05%",weight:23},
{source:1,target:3,relation:"15.26%",weight:15},{source:1,target:4,relation:"27.03%",weight:27},{source:1,target:5,relation:"22.52%",weight:23},
{source:2,target:3,relation:"7.90%",weight:8},{source:2,target:4,relation:"15.84%",weight:16},{source:2,target:5,relation:"14.10%",weight:14},
{source:3,target:4,relation:"22.31%",weight:22},{source:3,target:5,relation:"15.83%",weight:16},{source:4,target:5,relation:"24.02%",weight:24}
];
var force=d3.layout.force()
.nodes(nodes)
.links(edges)
.size([width,height])
.linkDistance(function(l) { return (450-7*l.weight)
})
.charge(-400)
.start();
//绘制
var color=d3.scale.category20();
var lines=svg.selectAll(".forceLine")
.data(edges)
.enter()
.append("line")
.attr("class","forceLine")
.style("stroke","gray")
.style("opacity",0.6)
.style("stroke-width",1);
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",10);
var circles=svg.selectAll("forceCircle")
.data(nodes)
.enter()
.append("circle")
.attr("class","forceCircle")
.attr("r",function(d){return d.value;})
.style("stroke","DarkGray")
.style("stroke-width","1.0px")
.attr("fill",function(d,i){return color(i);})
.call(force.drag);
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","14px")
.attr("dx","-1.5em")
.attr("dy","1.5em")
.text(function(d){return d.name;});
force.on("tick",function(){
lines.attr("x1",function(d){return d.source.x;});
lines.attr("y1",function(d){return d.source.y;});
lines.attr("x2",function(d){return d.target.x;});
lines.attr("y2",function(d){return d.target.y;});
circles.attr("cx",function(d){return d.x;});
circles.attr("cy",function(d){return d.y;});
texts.attr("x",function(d){return d.x;});
texts.attr("y",function(d){return d.y;});
edges_text.attr("x",function(d){ return (d.source.x + d.target.x) / 2 ; });
edges_text.attr("y",function(d){ return (d.source.y + d.target.y) / 2 ; });
});
</script>
</body>
</html>
球的大小代表的是选课的人占比的多少,球距离的远近代表共同选课人数的多寡,选这两门科目的共同人数越多,两个小球越接近,使用了node的value属性和edge的weight属性,使edge长度不再固定。