一、任务目标
使用vue制作一个包含d3直方图的网页 再加上一个饼图、词云图或力导向图。
二、代码实现主要部分
1. App.vue文件中加入力导向图
<template>
<img alt="Vue logo" src="./assets/logo.png" />
<HelloWorld msg="Hello Vue 3.0 + D3" />
<HelloD3 msg="D3.JS@Vue3"/>
<BarChart />
<Force />
</template>
<script>
import HelloWorld from './components/HelloWorld.vue'
import BarChart from './components/BarChart.vue';
import HelloD3 from './components/D3Hist.vue';
import Force from './components/1.vue';
export default {
name: 'App',
components: {
HelloWorld,BarChart,HelloD3,Force
}
}
</script>
2. 编写力导向图的js文件
代码如下:
data = pd.read_csv(
'https://labfile.oss.aliyuncs.com/courses/1283/adult.data.csv')
print(data.head())
3. 编写力导向图的js文件
代码如下:
<template>
<h2><a href="https://d3js.org" target="_blank" >D3力导向图@VUE3</a></h2>
<div>
<svg id="svg2" width="1200" height="800" ></svg>
</div>
</template>
<script>
import * as d3 from "d3";
export default {
name: "ForceDirected",
props: {
id: String,
width: String,
height: String,
nodes: Array,
edges: Array,
},
data() {
return {
};
},
mounted() {
this.init();
},
watch: {
load() {
this.init();
},
},
methods: {
init() {
let marge = { top: 100, bottom: 60, left: 60, right: 60 };
let svg = d3.select("#svg2");
let width = 900;
let height = 600;
let g = svg
.append("g")
.attr("transform", "translate(" + marge.top + "," + marge.left + ")");
// 准备数据
// 节点集
let nodes = [//节点集
{name:"中国传媒大学"},
{name:"信息科学与技术学部"},
{name:"新闻传播学部" },
{name:"艺术学部" },
{name:"人文社科学部" },
{name:"广告与经管学部" },
{name:"协同创新中心" },
{name:"直属学院" },
{name:"信息与通信工程学院" },
{name:"计算机与网络空间安全学院" },
{name:"数据科学与智能媒体学院" },
{name:"实验教学中心" },
{name:"新闻学院" },
{name:"电视学院" },
{name:"传播研究院" },
{name:"戏剧影视学院" },
{name:"播音主持艺术学院" },
{name:"动画与数字艺术学院" },
{name:"音乐与录音艺术学院" },
{name:"艺术研究院" },
{name:"艺术教育中心" },
{name:"人文学院" },
{name:"外国语言文化学院" },
{name:"政府与公共事务学院" },
{name:"汉语国际教育中心" },
{name:"体育部" },
{name:"经济与管理学院" },
{name:"广告学院" },
{name:"文化产业管理学院" },
{name:"文化发展研究院" },
{name:"雄安新区发展研究院" },
{name:"新媒体研究院" },
{name:"互联网信息研究院" },
{name:"脑科学与智能媒体研究院" },
{name:"马克思主义学院" },
];
// 边集
let edges = [
{source:0,target:1,value:3.5,relation: "隶属"}, //value控制线的长短
{source:0,target:2,value:3.5,relation: "隶属"},
{source:0,target:3,value:3.5,relation: "隶属"},
{source:0,target:4,value:3.5,relation: "隶属"},
{source:0,target:5,value:3.5,relation: "隶属"},
{source:0,target:6,value:3.5,relation: "隶属"},
{source:0,target:7,value:3.5,relation: "隶属"},
{source:1,target:8,value:2,relation: "隶属"},
{source:1,target:9,value:2,relation: "隶属"},
{source:1,target:10,value:2,relation: "隶属"},
{source:1,target:11,value:2,relation: "隶属"},
{source:2,target:12,value:2,relation: "隶属"},
{source:2,target:13,value:2,relation: "隶属"},
{source:2,target:14,value:2,relation: "隶属"},
{source:3,target:15,value:2,relation: "隶属"},
{source:3,target:16,value:2,relation: "隶属"},
{source:3,target:17,value:2,relation: "隶属"},
{source:3,target:18,value:2,relation: "隶属"},
{source:3,target:19,value:2,relation: "隶属"},
{source:3,target:20,value:2,relation: "隶属"},
{source:4,target:21,value:2,relation: "隶属"},
{source:4,target:22,value:2,relation: "隶属"},
{source:4,target:23,value:2,relation: "隶属"},
{source:4,target:24,value:2,relation: "隶属"},
{source:4,target:25,value:2,relation: "隶属"},
{source:5,target:26,value:2,relation: "隶属"},
{source:5,target:27,value:2,relation: "隶属"},
{source:5,target:28,value:2,relation: "隶属"},
{source:5,target:29,value:2,relation: "隶属"},
{source:5,target:30,value:2,relation: "隶属"},
{source:6,target:31,value:2,relation: "隶属"},
{source:6,target:32,value:2,relation: "隶属"},
{source:6,target:33,value:2,relation: "隶属"},
{source:7,target:34,value:2,relation: "隶属"},
];
let colorScale = d3
.scaleOrdinal()
.domain(d3.range(nodes.length))
.range(d3.schemeTableau10);
let forceSimulation = d3
.forceSimulation()
.force("link", d3.forceLink())
.force("charge", d3.forceManyBody())
.force("center", d3.forceCenter());
forceSimulation.nodes(nodes).on("tick", ticked);
forceSimulation
.force("link")
.links(edges)
.distance(function (d) {
return d.value * 90;
});
forceSimulation
.force("center")
.x(width / 2)
.y(height / 2);
let links = g
.append("g")
.selectAll("line")
.data(edges)
.enter()
.append("line")
.attr("stroke", function (d, i) {
return colorScale(i);
})
.attr("stroke-width", 1);
let linksText = g
.append("g")
.selectAll("text")
.data(edges)
.enter()
.append("text")
.text(function (d) {
return d.relation;
});
let gs = g
.selectAll(".circleText")
.data(nodes)
.enter()
.append("g")
.attr("transform", function (d) {
let cirX = d.x;
let cirY = d.y;
return "translate(" + cirX + "," + cirY + ")";
})
.call(
d3.drag().on("start", started).on("drag", dragged).on("end", ended)
);
gs.append("circle")
.attr("r", 10)
.attr("fill", function (d, i) {
return colorScale(i);
});
gs.append("text")
.attr("x", -10)
.attr("y", -20)
.attr("dy", 10)
.text(function (d) {
return d.name;
});
function ticked() {
links
.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;
});
linksText
.attr("x", function (d) {
return (d.source.x + d.target.x) / 2;
})
.attr("y", function (d) {
return (d.source.y + d.target.y) / 2;
});
gs.attr("transform", function (d) {
return "translate(" + d.x + "," + d.y + ")";
});
}
function started(d) {
if (!d3.event.active) {
forceSimulation.alphaTarget(0.5).restart();
}
d.fx = d.x;
d.fy = d.y;
}
function dragged(d) {
d.fx = d3.event.x;
d.fy = d3.event.y;
}
function ended(d) {
if (!d3.event.active) {
forceSimulation.alphaTarget(0);
}
d.fx = null;
d.fy = null;
}
},
},
};
</script>
4. 编写直方图的js文件
代码如下:
<template>
<h2><a href="https://d3js.org" target="_blank" >D3直方图@VUE3</a></h2>
<div id="bar-chart-container"></div>
</template>
<script>
import { defineComponent } from 'vue';
//import axios from "axios";
import * as d3 from "d3";
var data=new Array(10);
for (var i=0;i<10;i++)
{
data[i]=Math.floor(Math.random()*255);
console.log(data[i]);
}
var color=d3.schemeCategory10;
export default defineComponent({
mounted() {
this.drawBarChart(data);
},
methods:{
drawBarChart(data){
const width=800;
const height=400;
var svg=d3.select("#bar-chart-container")
.append("svg")
.attr("width",width)
.attr("height",height);
svg.selectAll("rect")
.data(data)
.enter()
.append("rect")
.attr("fill",(d,i)=>color[i])
.attr("x",function(d,i){
return width*i/10;
})
.attr("y",d=>(height-d))
.attr("height",d=>d)
.attr("width",width*0.9/10);
svg.selectAll("text")
.data(data)
.enter()
.append("text")
.attr("x",function(d,i){
return 25+width*i/10;
})
.attr("y",d=>(height-d-10))
.text(function(d,i){
return d;
})
}
}
})
</script>
三、注意事项
注意,在VUE中安装d3时,需要注意安装d3的版本,否则无法显示。
四、结果展示
总结
第一次学习VUE,项目的构建方法和以前接触过的方法完全不一样。这次尝试了将D3与VUE结构,实验效果较好,也比较顺利。能感觉到VUE的功能很强大,期待以后继续学习这方面的知识。