前言
D3JS的简单学习
D3JS教程
安装
npm install d3 import * as d3 from "d3";
选择元素
例如:
d3.select("div") d3.select(".myclass").text() d3.select("#hello").text()
常用方法
text: 读写文字内容
//读 d3.select('#pie').text() //写,会替换原来的内容 d3.select('#pie').text('eee');
append: 将新元素作为当前选择中元素的最后一个子元素追加。 此方法还可以修改元素的样式,其属性,HTML和文本内容。
d3.select('#pie').append('span').text('aa');
这个试了一下,只能添加标签
html: 读取和设置html
d3.select('#pie').html()
试了一下,标签内部是文字就返回文字,是html就返回html。追加时会替换掉原来的内容
attr: 读写html的属性
d3.select('#pie').attr('title')
试了一下只能读写到当前对象,对应对象内部的html无法读取到。
style: 只能读写当前对象的样式
d3.select('#pie').style('color','red'); console.log(d3.select('#pie').style('color'));
一次只能读写一个样式
classed:用于设置HTML元素的”class”属性
//添加类 d3.select(".myclass").classed("myanotherclass", true); //删除类 d3.select(".myclass").classed("myanotherclass", false); //检查是否存在该类 d3.select(".myclass").classed("myanotherclass");
selectAll: 选择符合条件的所有元素
数据连接
什么是数据连接?
四种方法:
datum: 用于为HTML文档中的单个元素设置值。 一旦使用选择器选择元素,就会使用它。
<p></p> d3.select('p') .datum(50) .text(function(d) {
return '在p标签里添加的值是:' + d; });

从结果来看可以用来添加变量
data: 用于将数据集分配给HTML文档中的元素集合。 使用选择器选择HTML元素后使用它。
<ul id="list"> <li>5</li> <li></li> <li></li> <li></li> <li></li> </ul> d3.select('#list').selectAll('li') .data([10, 0, 30, 25, 15]) .text((d) => d);

第一点:只写data是无效的,必须使用text、html这类的来写入数据
第二点:写入的数据会替换掉原来的数据
第三点:如果dom元素不存在,就不会生效
enter: 输出之前没有图形元素的数据项集。
这个挺难理解的,特地查了一下。以下面这个例子为例:
<ul id="list"> <li></li> </ul> d3.select('#list').selectAll('li') .data([10, 20, 30, 25, 15]) .text(function(d) {
return '之前存在的 ' + d; }) .enter() .append('li') .text(function(d) {
return '后来创建的 ' + d; });

data里有5个数据,实际上只一个li元素。这里enter起的作用就相对于占位,占位后通过append往这个位置放入一个元素
exit: 输出不再存在数据的图形元素集。
<ul id="list"> <li></li> <li></li> <li>多余的</li> <li>多余的</li> </ul> d3.select('#list').selectAll('li') .data([10, 20]) .text(d => d) .exit() .remove();
实际上有4个元素,但是data里只有两个数据。exit 作用相对于来标识那些是多余的,再通过remove可以将多与的删除
Data Function
在使用data后,原来的text等方法内部可以使用匿名函数,匿名函数里可以获取到对应的值和索引
<ul id="list"> <li></li> <li></li> </ul> d3.select('#list').selectAll('li') .data([10, 20]) .text((d,i) => {
console.log('值:',d,',索引:',i,',this:',this); return d; });


svg
svg的内容不介绍了,不熟悉的可以看一下:svg的简单学习 ,简单了解一些基础知识。这里主要记录使用d3来操作svg
示例:
// 获取容器并创建一个svg d3.select('#svgContainer').append('svg').attr('width', 300).attr('height', 300) // 绘制一条直线 .append('line').attr('x1', 100).attr('y1', 100).attr('x2', 200).attr('y2', 200).style('stroke', 'blue').style('stroke-width', 2);

Transition 过度
transition()方法适用于所有选择器,它启动过渡进程.此方法支持大多数选择方法,如-attr(),style()等.但是,它不支持append()和data()方法,这些方法需要在transition()方法之前调用.此外,它提供了特定于转换的方法,如duration(),ease()等.
// 过度时间 let t = d3.transition().duration(3000); d3.select('#box') .style('width','300px') .style('height','100px') .transition(t) .style('background-color', 'lightblue');

注: 有关很重要的地方是:过度效果只会对transition(t)后面的样式生效。比如上面的只会对背景色起过度效果。
动画
d3中没有animation这个东西,动画的实现还是需要基于过度
duration: 过度时间
d3.selectAll("h3").transition().style("color","green").duration(5000);
delay: 延迟
d3.select('#box') .style('width','300px') .style('height','100px') .transition() .style('background-color', 'lightblue') .delay(2000).duration(2000);
绘制图表
柱状图
// 数值 var data = [10, 5, 12, 15]; // 定义svg的宽 var width = 500; // 定义 缩放到屏幕上可见的像素值。 var scaleFactor = 20; // 柱状图的高 var barHeight = 30; // 获取到一个svg var graph = d3 .select('#box') .append('svg') .attr('width', width) .attr('height', barHeight * data.length); // g标签分组用的 var bar = graph .selectAll('g') .data(data) .enter() .append('g') // 平移确定4个柱状图的位置 .attr('transform', function (d, i) {
return 'translate(0,' + i * barHeight + ')'; }); // 绘制矩形 bar.append('rect') .attr('width', function (d) {
// 10*20 = 200 像素值 // 直接返回 '200px' 也可以 return d * scaleFactor; }) .attr('height', barHeight - 1) // 设置柱状图的填充颜色 .attr('fill','red'); // 添加文本 bar.append('text') // 通过偏移量来设置文本的位置 .attr('x', function (d) {
return d * scaleFactor; }) .attr('y', barHeight / 2) .attr('dy', '.35em') // 设置文字颜色 .attr('fill','blue') .text(function (d) {
return d; });

饼图
从网上找了个例子,从头捋顺了一下
<svg id="abc" /> // 创建一个svg let svg = d3.select('#abc').append('svg').attr('width',350).attr('height',400); // 数据源 let data = [{
label: '电影',value: 50},{
label: '电视剧',value: 60},{
label: '动漫',value: 100}]; // 颜色 let colors = ['#5c84f2','#C8D0E6','#dddddd']; // 创建一个饼图 let pie = d3.pie().value(d => d.value); // 饼图数据 let pieData = pie(data); // 创建饼图的弧路径 let arcPath = d3.arc().innerRadius(60).outerRadius(100); // 创建分组,每一组里保存一个扇形信息 let arcList = svg.selectAll('g') .data(pieData) .enter() .append('g') .attr('transform','translate(150,200)'); // 在组里添加路径 arcList.append('path') .attr('d',d => arcPath(d)) .attr('fill',(d,i) => colors[i]) .attr('stroke','black') .on('mouseover',function(e,d) {
d3.select(this) .attr('fill','#f8aba6'); }) // e是事件对象,d是数据对象 .on('mouseout',function(e,d) {
d3.select(this) .attr('fill',colors[d.index]); }); /* 上面的代码是绘制饼图,下面绘制饼图的文字 */ // 绘制扇形区域的数值 arcList.append('text') .attr('fill','white') .attr('text-anchor','middle') .attr('transform',function(d) {
// 获取弧的中线点 var x = arcPath.centroid(d)[0]; var y = arcPath.centroid(d)[1]; return 'translate(' + x + ',' + y + ')'; }) .text(d => d.value); // 绘制扇形区域对应的类型,就是线条加类型 arcList.append('line') .attr('stroke',(d,i) => colors[i]) .attr('x1',function(d) {
return arcPath.centroid(d)[0] * 1.34; }) .attr('y1',function(d) {
return arcPath.centroid(d)[1] * 1.34; }) .attr('x2',function(d) {
return arcPath.centroid(d)[0] * 1.8; }) .attr('y2',function(d) {
return arcPath.centroid(d)[1] * 1.8; }); arcList.append('text') .attr('fill',(d,i) => colors[i]) .attr('transform',function(d) {
var x = arcPath.centroid(d)[0] * 1.9; var y = arcPath.centroid(d)[1] * 1.9; return 'translate(' + x + ',' + y + ')'; }) .attr('text-anchor','middle') .text(d => d.data.label);

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/218141.html原文链接:https://javaforall.net
