使用方法
//饼状图
var d3PieHelper = (d3PieHelper || function() {
var ret = {},
options ={
height: 150,
width: 150,
title : ""
};
ret.init = function (element,dataset,opt) {
let o = $.extend({},options,opt || {});
let pie = d3.pie().value((d) => d[1]);
let pieData = pie(dataset);
let outerRadius = o.width / 3,
innerRadius = 0;
let svg = d3.select(element).append("svg").attr("width", o.width).attr("height", o.height).attr('fill', 'white');
let arc = d3.arc().innerRadius(innerRadius).outerRadius(outerRadius);
let color = d3.schemeCategory10;
var data = [];
var title = [];
$.each(dataset,function(i,v){
data.push(v[1]);
title.push(v[0]);
})
let g_s = d3.select(element).append("svg")
.attr("width",80)
.attr("height",o.height)
.style("backgroud", "#fff")
.selectAll(".rect")
.data(data)
.enter()
.append("g");
let step = o.height / (dataset.length + 1);
g_s.append("rect")
.attr("y", function (d, i) {
return step * i + 20;
})
.attr("x", function (d) {
return 0;
})
.attr("width", function (d) {
return 80;
})
.attr("height", function () {
return 21;
})
.attr("fill", function(d,i){
return color[i];
});
g_s.append("text")
.attr("x", function (d, i) {
return 0;
})
.attr("y", function (d, i) {
return step * i + 20;
})
.attr("dx", function () {
return 5;
})
.attr("dy", function () {
return 12;
})
.text(function (d,i) {
return title[i] + ":" + d + "人";
})
.attr("fill", "white")
.style("font-size", "9px");
let arcs = svg.selectAll("g").data(pieData).enter().append("g").attr("transform", "translate("+(o.width/2)+","+(o.height/2)+")");
arcs.append("path")
.attr("fill", (d, i) => {
return color[i];
})
.attr("d", d => {
return arc(d);
});
svg.append("text")
.attr("x", function (d, i) {
return 29;
})
.attr("y", function (d, i) {
return 130 ;
})
.attr("dx", function () {
return 5;
})
.attr("dy", function () {
return 12;
})
.text(function (d,i) {
return o.title;
})
.attr("fill", "white")
.style("font-size", "13px");
添加弧内的文字元素
//arcs.append('text').attr("transform", d => {
// let x = arc.centroid(d)[0] * 1.4; //文字的x坐标
// let y = arc.centroid(d)[1] * 1.4; //文字的y坐标
// return "translate("+x+","+y+")";
// })
// .attr("text-anchor", "middle").text(d => {
// let percent = (Number(d.value) / d3.sum(dataset, d => d[1])) * 100;
// return percent.toFixed(1) + "%"
// })
// .style("font-size","10px");
//arcs.append("line")
// .attr("stroke","black")
// .attr("x1",d=>arc.centroid(d)[0] * 2)
// .attr("y1", d=> arc.centroid(d)[1] * 2)
// .attr("x2", d=> arc.centroid(d)[0] * 2.2)
// .attr("y2", d=> arc.centroid(d)[1] * 2.2);
//arcs.append("text")
// .attr("transform",d => {
// let x = arc.centroid(d)[0] * 2.5;
// let y = arc.centroid(d)[1] * 2.5;
// return `translate(${x},${y})`
// })
//.attr("fill","balck")
//.attr("text-anchor","middle")
//.text(d=>d.data[0])
// .style("font-size","10px");
}
return ret;
} ());
//横向直方图
var d3RectHelper = (d3RectHelper || function () {
var ret = {},
options = {
height: 500,
width: 500,
rectPadding: 20,
color: "skyblue",
z: "人",
padding: {
top: 20,
left: 50,
right: 50,
bottom: 10
}
}
function init(element, data,titles, opt) {
var o = $.extend({}, options, opt || {});
var scale_x = d3.scaleLinear()
.domain([0, d3.max(data)])
.range([0, o.width - o.padding.left - o.padding.right]);
var step = (o.height - o.padding.top - o.padding.bottom) / data.length;
var g_s = d3.select(element)
.append("svg")
.attr("height", o.height)
.attr("width", o.width)
.style("backgroud", "#fff")
.selectAll(".rect")
.data(data)
.enter()
.append("g");
g_s.append("rect")
.attr("y", function (d, i) {
return step * i + o.padding.top;
})
.attr("x", function (d) {
return o.padding.left;
})
.attr("width", function (d) {
return scale_x(d);
})
.attr("height", function () {
return step - (o.rectPadding / 2);
})
.attr("fill", o.color);
g_s.append("text")
.attr("x", function (d, i) {
return scale_x(d3.max(data)) + o.padding.left;
})
.attr("y", function (d, i) {
return step * i + o.padding.top;
})
.attr("dx", function () {
return 5;
})
.attr("dy", function () {
return 12;
})
.text(function (d) {
return d + o.z;
})
.attr("fill", "white")
.style("font-size", "10px");
g_s.append("text")
.attr("x", function (d, i) {
return 0;
})
.attr("y", function (d, i) {
return step * i + o.padding.top;
})
.attr("dx", function () {
return 5;
})
.attr("dy", function () {
return 12;
})
.text(function (d,i) {
return titles[i];
})
.attr("fill", "white")
.style("font-size", "10px");
}
ret.init = init;
return ret;
}());
D3.js基础学习
1 如何选择元素
d3.select():是选择所有指定元素的第一个
d3.selectAll():是选择指定元素的全部
2 插入、删除元素
插入
append():在选择集末尾插入元素
insert():在选择集前面插入元素
body.append("p")
.text("append p element");
body.insert("p","#myid")
.text("insert p element");
删除
var p = body.select("#myid");
p.remove();
3 理解 Update、Enter、Exit
对数据的处理
4 比例尺
序数比例尺
let xScale = d3.scaleBand()
.domain(d3.range(data.length))
.rangeRound([0,width - padding.left - padding.right]);
线性比例尺
let yScale = d3.scaleLinear()
.domain([0,d3.max(data)])
.range([height - padding.top - padding.bottom,0]);
//为x轴 y轴添加坐标轴 该方法考虑抽出作为独立api d3.scaleBand() 序数比例尺 .domain()输入域 range() 输出域
5 坐标轴
//定义一个装图表的分组并且确定他的位置
let g = svg.append("g")
.attr("transform","translate(" + padding.top + "," + padding.left + ")")
.attr("background", "skyblue");
//坐标轴
// .axisBottom(canshu) 创建向下的坐标轴 参数是比例尺 axisLeft向左的坐标轴
let xAxis = d3.axisBottom(xScale);
let yAxis = d3.axisLeft(yScale);
//到这一步 柱状图的基本架子已经搭起来了,下面需要做的便是怎么把数据呈现了
//将坐标轴组件加入当前图表分组
g.append("g")
.attr("transform","translate(" + 0 + ","+(height - padding.top - padding.bottom)+")")
.call(xAxis);
g.append("g")
.attr("transform","translate(0,0)")
.call(yAxis);
6 动态效果
g_s.append("rect")
.attr("x",function (d,i) {
return xScale(i) + rectPadding / 2;
})
.attr("y",function (d) {
var min = yScale.domain()[0];
return yScale(min);
})
.attr("width",function () {
return xScale.step() - rectPadding;
})
.attr("height",function (d) {
console.log(d, yScale(400));
return 0;//height - padding.top - padding.bottom - yScale(d);
})
.attr("fill","skyblue")
.transition()//添加过度
.duration(1000)//持续时间
// .delay(function (d,i) {//延迟
// return i*400;
// })
.attr("y",function(d){//回到最终状态
return yScale(d);
})
.attr("height",function(d){//回到最终状态
return height-padding.top-padding.bottom-yScale(d);
});
7 交互式操作
g_s.append("rect")
.attr("x",function (d,i) {
return xScale(i) + rectPadding / 2;
})
.attr("y",function (d) {
var min = yScale.domain()[0];
return yScale(min);
})
.attr("width",function () {
return xScale.step() - rectPadding;
})
.attr("height",function (d) {
console.log(d, yScale(400));
return 0;//height - padding.top - padding.bottom - yScale(d);
})
.attr("fill","skyblue")
.on("mouseover",function () {
var rect = d3.select(this)
.transition()
.duration(200)
.attr("fill","yellow");
})
.on("mouseout",function () {
var rect = d3.select(this)
.transition()
.duration(200)
.attr("fill","skyblue");
})
D3js 完整基础实例
准备工作:引入d3.v5.js
//html
<div id="graph" ></div>
//画布 高 宽 padding
var height ="500";
var width = "500";
var padding = {
top: 30,
left: 30,
bottom: 30,
right: 30
}
//柱状距离
let rectPadding = 30;
//新建画布
let svg = d3.select("#graph")
.append("svg")
.attr("height", height)
.attr("width", width)
.style("background", "#fff");
//定义一个装图表的分组并且确定他的位置
let g = svg.append("g")
.attr("transform","translate(" + padding.top + "," + padding.left + ")")
.attr("background", "skyblue");
//数据集
let data = [100,200,50,20,400,80];
//为x轴 y轴添加坐标轴 该方法考虑抽出作为独立api d3.scaleBand() 序数比例尺 .domain()输入域 range() 输出域
//scaleBand()序数比例尺 scaleLinear()线性比例尺
var list = ["数字1","数字2","数字3","数字4","数字5","数字6"];
let xScale = d3.scaleBand()
// .domain(d3.range(data.length))
// .rangeRound([0,width - padding.left - padding.right]);
.domain(list)
.rangeRound([0, width - padding.left - padding.right],0,0);
//y轴输入域 [0,400] 输出域 [500-20-20,0]
let yScale = d3.scaleLinear()
.domain([0,d3.max(data)])
.range([height - padding.top - padding.bottom,0]);
//坐标轴
// .axisBottom(canshu) 创建向下的坐标轴 参数是比例尺 axisLeft向左的坐标轴
let xAxis = d3.axisBottom(xScale);
let yAxis = d3.axisLeft(yScale);
//到这一步 柱状图的基本架子已经搭起来了,下面需要做的便是怎么把数据呈现了
//将坐标轴组件加入当前图表分组
g.append("g")
.attr("transform","translate(" + 0 + ","+(height - padding.top - padding.bottom)+")")
.call(xAxis);
g.append("g")
.attr("transform","translate(0,0)")
.call(yAxis);
//加载数据
let g_s = g.selectAll(".rect")
.data(data)
.enter()
.append("g");
//柱状
g_s.append("rect")
.attr("x",function (d,i) {
return xScale(list[i]) + rectPadding / 2;
})
.attr("y",function (d) {
var min = yScale.domain()[0];
return yScale(min);
})
.attr("width",function () {
//科普一下哈 xScale.step() 这个得到的是每一个等差刻度的宽喔 这里是 76
return xScale.step() - rectPadding;
})
.attr("height",function (d) {
console.log(d, yScale(400));
return 0;//height - padding.top - padding.bottom - yScale(d);
})
.attr("fill","skyblue")
//交互动作
.on("mouseover",function () {
var rect = d3.select(this)
.transition()
.duration(200)
.attr("fill","yellow");
})
.on("mouseout",function () {
var rect = d3.select(this)
.transition()
.duration(200)
.attr("fill","skyblue");
})
//动态效果
.transition()//添加过度
.duration(1000)//持续时间
// .delay(function (d,i) {//延迟
// return i*400;
// })
.attr("y",function(d){//回到最终状态
return yScale(d);
})
.attr("height",function(d){//回到最终状态
return height-padding.top-padding.bottom-yScale(d);
});
//最后 给每个矩形加上文字
/*
<text> 元素用于定义文本。
属性:
主要属性有:x,y,dx,dy,rotate,textLength,lengthAdjust
x,y表示文本的横纵坐标。
dx,dy表示移动的横纵坐标。
rotate表示旋转的度数。
*/
g_s.append("text")
.attr("x", function (d, i) {
return xScale(list[i]) + rectPadding / 2;
})
.attr("y", function (d) {
return yScale(d)- 20;
})
.attr("dx", function () {
return (xScale.step() - rectPadding) / 8;
})
.attr("dy", 20)
.text(function (d) {
return d;
});