# d3实例

# 柱状图实例

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8" />
		<meta name="viewport" content="width=device-width, initial-scale=1">
		<title></title>
		<style>
			*{margin:0;padding:0}
		</style>
	</head>
	<body>	
	</body>
	<script type="text/javascript" src="https://d3js.org/d3.v5.min.js"></script>
	<script type="text/javascript">

 
var dataset = [45, 70, 12, 79, 4, 127, 33, 150];
var width = 600;//svg画布宽
var height = 600;//svg画布高
var rectWidth = 50;//每个矩形的默认宽度
var rectPadding=10;//每个矩形间的间隔
var padding={top:40,bottom:40,left:40,right:40};//定义间隔
//定义画布
var svg = d3.select("body")
.append("svg")
.attr("width", width)
.attr("height", height)

//定义矩形比例尺
 
var yScale=d3.scaleLinear()
.domain([0,d3.max(dataset)])
.range([height-padding.top-padding.bottom,0]);
var yAxis=d3.axisLeft().scale(yScale).ticks(5);
var yAxis=d3.axisLeft(yScale).ticks(5);
svg.append("g")
.attr("transform",`translate(${padding.top},${padding.left})`)
.call(yAxis);
 
var xScale=d3.scaleBand()
.domain(d3.range(dataset.length))
.rangeRound([0,dataset.length*(rectWidth+(rectPadding/2))]);
var xAxis=d3.axisBottom(xScale)
.ticks(5);
svg.append("g")
.attr("transform",`translate(${padding.left},${height-padding.top})`)
.call(xAxis);
 
//定义矩形
var g=d3.selectAll("svg")
.append("g")
.attr("transform",`translate(${padding.top},${padding.left})`);
 
var graph=g.selectAll("rect")
.data(dataset)
.enter()
.append("g");
 
graph.append("rect")
.style("fill","#30dc76")
.attr("x",function (d,i) {
    return (i*rectWidth)+(i+1)*(rectPadding/2);
})
.attr("width",rectWidth-rectPadding/2)
.attr("y",function (d) {
    var min=yScale.domain()[0];
    return yScale(min);
})
.attr("height",function(d,i){
    return 0;
})
.transition()
.duration(2000)
.delay(function(d,i){
    return i*400;
})
//.ease(d3.easeBackOut)
.attr("y",function (d,i) {
    return yScale(d)
})
.attr("height",function (d,i) {
    return height-padding.top-padding.bottom-yScale(d);
})
 
graph.append("text")
.style("fill", "orange")
.attr("x", function (d, i) {
    return (i * rectWidth) + (i + 1) * (rectPadding / 2);
})
.attr("dx", 10)
.attr("dy",-10)
.attr("y", function (d) {
    var min = d3.min(dataset);
    return yScale(min)
})
.text(function (d) {
    return d
})
.transition()
.duration(2000)
.delay(function (d, i) {
    return i * 400;
})
.attr("y", function (d, i) {
    return yScale(d);
})
		
				 
	</script>
</html>
var yAxis=d3.axisLeft().scale(yScale).ticks(5);
var yAxis=d3.axisLeft(yScale).ticks(5);
//两种写法效果一致!

# 饼图

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8" />
		<meta name="viewport" content="width=device-width, initial-scale=1">
		<title></title>
		<style type="text/css">
			#a{
				width:100%;
				height:600px;
			}
		</style>
	</head>
	<body>
		<div id="a"></div>
	</body>
	<script src="https://d3js.org/d3.v5.min.js"></script>
	<script type="text/javascript">
	 let dataset=[["apple",14],["orange",22],["banana",36],["pear",18],["watermeln",5],["purple",70]]
	 pieChart("#a",dataset)
	 function pieChart(id, dataset) {
	  const width = 400;
	  const height = 400;
	  const fontsize = 14;
	  const svg = d3
		.select(id)
		.append('svg')
		.attr('width', width)
		.attr('height', height);
		
	  const pie = d3.pie().value(d => d[1]);
	  // dataset为转换前的数据 piedata为转换后的数据
	  const piedata = pie(dataset);

	  const outerRadius = width / 3;
	  const innerRadius = 0; // 内半径和外半径
	  // 创建弧生成器
	  const arc = d3
		.arc()
		.innerRadius(innerRadius)
		.outerRadius(outerRadius);
	  const color = d3.scaleOrdinal(d3.schemeCategory10);
	  // 添加对应数目的弧组
	  const arcs = svg
		.selectAll('g')
		.data(piedata)
		.enter()
		.append('g')
		.attr('transform', `translate(${width / 2},${height / 2})`);
	  // 添加弧的路径元素
	  arcs
		.append('path')
		.attr('fill', function(d, i) {
		  return color(i);
		})
		.attr('d', function(d) {
		  return arc(d); // 使用弧生成器获取路径
		});

	  // 添加弧内的文字
	  arcs
		.append('text')
		.attr('transform', function(d) {
		  const x = arc.centroid(d)[0] * 1.4; // 文字的x坐标
		  const y = arc.centroid(d)[1] * 1.4;
		  return `translate(${x},${y})`;
		})
		.attr('text-anchor', 'middle')
		.text(d => {
		  // 计算市场份额的百分比
		  const percent =
			(Number(d.value) /
			  d3.sum(dataset, a => {
				return a[1];
			  })) *
			100;
		  // 保留一位小数点 末尾加一个百分号返回
		  return `${percent.toFixed(1)}%`;
		});

	  // 添加连接弧外文字的直线元素
	  arcs
		.append('line')
		.attr('stroke', 'black')
		.attr('x1', d => {
		  return arc.centroid(d)[0] * 2;
		})
		.attr('y1', d => {
		  return arc.centroid(d)[1] * 2;
		})
		.attr('x2', d => {
		  return arc.centroid(d)[0] * 2.2;
		})
		.attr('y2', d => {
		  return arc.centroid(d)[1] * 2.2;
		});

	  arcs
		.append('line')
		.style('stroke', 'black')
		.each(d => {
		  d.textLine = {
			x1: 0,
			y1: 0,
			x2: 0,
			y2: 0,
		  };
		})
		.attr('x1', d => {
		  d.textLine.x1 = arc.centroid(d)[0] * 2.2;
		  return d.textLine.x1;
		})
		.attr('y1', d => {
		  d.textLine.y1 = arc.centroid(d)[1] * 2.2;
		  return d.textLine.y1;
		})
		.attr('x2', d => {
		  // console.log("d.data[0]:  "+d.data[0]);//产商名
		  const strLen = getPixelLength(d.data[0], fontsize) * 1.5;
		  const bx = arc.centroid(d)[0] * 2.2;
		  d.textLine.x2 = bx >= 0 ? bx + strLen : bx - strLen;
		  return d.textLine.x2;
		})
		.attr('y2', d => {
		  d.textLine.y2 = arc.centroid(d)[1] * 2.2;
		  return d.textLine.y2;
		});
	  arcs
		.append('text')
		.attr('transform', function(d) {
		  let x = 0;
		  let y = 0;
		  x = (d.textLine.x1 + d.textLine.x2) / 2;
		  y = d.textLine.y1;
		  y = y > 0 ? y + fontsize * 1.1 : y - fontsize * 0.4;
		  return `translate(${x},${y})`;
		})
		.style('text-anchor', 'middle')
		.style('font-size', fontsize)
		.text(function(d) {
		  return d.data[0];
		});
	  // 添加一个提示框
	  const tooltip = d3
		.select(id)
		.append('div')
		.attr('class', 'tooltip')
		.style('position', 'absolute')
		.style('background-color', '#fff')
		.style('opacity', 0);

	  // 添加提示框
	  arcs
		.on('mouseover', function(d, i) {
		  tooltip
			.html(`${d.data[0]}的销量为<br />${d.data[1]}`)
			.style('left', `${d3.event.pageX}px`)
			.style('top', `${d3.event.pageY + 20}px`)
			.style('opacity', 1.0)
			.style('box-shadow', `10px 0px 0px${color(i)}`); // 在提示框后添加阴影
		})
		.on('mousemove', () => {
		  tooltip.style('left', `${d3.event.pageX}px`).style('top', `${d3.event.pageY + 20}px`);
		})
		.on('mouseout', () => {
		  // 鼠标移除 透明度设为0
		  tooltip.style('opacity', 0.0);
		});
	}
	function getPixelLength(str, fontsize) {
	  let curLen = 0;
	  for (let i = 0; i < str.length; i += 1) {
		const code = str.charCodeAt(i);
		const pixelLen = code > 255 ? fontsize : fontsize / 2;
		curLen += pixelLen;
	  }
	  return curLen;
	}

	</script>
</html>
最后更新: 10/24/2019, 5:25:53 PM