ckinmind / d3hub Goto Github PK
View Code? Open in Web Editor NEWd3相关
d3相关
在新版d3.v4版本中,如果要使用attrs方法需要额外引入一个库
<script src="https://d3js.org/d3-selection-multi.v1.min.js"></script>
参考资料:
d3.selectAll(elements).style('fill-opacity', 1);
参考资料:fill-opacity
var quantizeScale = d3.scaleQuantize()
.domain([0, 100]) // 数据范围, 会平均分成三部分对应range的三个值
.range(['red', 'white', 'green']) // 映射范围
console.log(quantizeScale(22)) // red
console.log(quantizeScale(50)) // white
console.log(quantizeScale(88)) // green
console.log(quantizeScale.invertExtent('white'))
// [33.333333336, 66.666667] , 从颜色倒推回数值范围
.classed('bar', true) // 两种方式
.attr('class', 'bar')
const data = [10, 20, 40, 70, 50, 30, 90, 120, 5, 65, 75];
d3.shuffle(data) // [40, 20, 120, 70, 10, 50, 5, 30, 75, 90, 65]
重新排序
.on('mouseover', function (d, i, elements) {
d3.select(this).style('transform', 'scaleX(2)');
d3.selectAll(elements)
.filter(':not(:hover)')
.style('fill-opacity', 0.5);
})
var margin = { top: 10, right: 20, bottom: 60, left: 40 };
var width = 425 - margin.left - margin.right;
var height = 625 - margin.top - margin.bottom;
var svg = d3.select('.chart')
.append('svg')
.attr('width', width + margin.left + margin.right)
.attr('height', height + margin.top + margin.bottom)
var xScale = d3.scaleTime()
.domain([new Date(2016, 0, 1, 6), new Date(2016, 0, 1, 12)])
.range([0, width]);
var xAxis = d3.axisBottom(xScale).ticks(5);
bar.append('rect')
.style('width', d => d.score)
.attr('class', 'bar')
.on('mouseover', function (d, i, elements) {
d3.select(this).style('transform', 'scaleX(2)');
d3.selectAll(elements)
.filter(':not(:hover)')
.style('fill-opacity', 0.5);
})
.on('mouseout', function (d, i, elements) {
d3.select(this).style('transform', 'scaleX(1)');
d3.selectAll(elements)
.style('fill-opacity', 1);
});
变成
function scaleBar (selection, scale) {
selection.style('transform', 'scaleX(' + scale + ')');
}
function setFill (selection, color) {
selection.style('fill', color);
}
function fade (selection, opacity) {
selection.style('fill-opacity', opacity);
}
bar.append('rect')
.style('width', d => d.score)
.attr('class', 'bar')
.on('mouseover', function (d, i, elements) {
d3.select(this)
.call(scaleBar, 2)
.call(setFill, 'orange');
d3.selectAll(elements)
.filter(':not(:hover)')
.call(fade, 0.5);
})
var margin = { top: 10, right: 20, bottom: 60, left: 30 };
var width = 400 - margin.left - margin.right;
var height = 565 - margin.top - margin.bottom;
var svg = d3.select('.chart')
.append('svg')
.attr('width', width + margin.left + margin.right)
.attr('height', height + margin.top + margin.bottom)
.append('g')
.attr('transform', 'translate(' + margin.left + ', ' + margin.top + ')');
var data = [
{score: 63, subject: 'Mathematics'},
{score: 82, subject: 'Geography'},
{score: 74, subject: 'Spelling'},
{score: 97, subject: 'Reading'},
{score: 52, subject: 'Science'},
{score: 74, subject: 'Chemistry'},
{score: 97, subject: 'Physics'},
{score: 52, subject: 'ASL'}
];
// y轴
var yScale = d3.scaleLinear()
.domain([0, 100])
.range([height, 0]);
var yAxis = d3.axisLeft(yScale);
svg.call(yAxis);
// x轴, scaleBand创建序数段比例尺
var xScale = d3.scaleBand()
.padding(0.2)
.domain(data.map(d => d.subject))
.range([0, width]);
var xAxis = d3.axisBottom(xScale)
.ticks(5)
.tickSize(10)
.tickPadding(5);
// 调整刻度文字
svg
.append('g')
.attr('transform', `translate(0, ${height})`)
.call(xAxis)
.selectAll('text')
.style('text-anchor', 'end')
.attr('transform', 'rotate(-45) translate(-10, -10)');
svg.selectAll('rect')
.data(data)
.enter()
.append('rect')
.attr('x', d => xScale(d.subject))
.attr('y', d => yScale(d.score))
.attr('width', d => xScale.bandwidth()) // bandwidth获取每段宽度
.attr('height', d => height - yScale(d.score));
.attr('transform', 'rotate(-45) translate(-10, -10)');
多个变幻函数写一起viewBox="x, y, width, height" // x:左上角横坐标,y:左上角纵坐标,width:宽度,height:高度
viewBox的放大效果就相当于从左上角x, y的位置圈定一块width,height的范围然后将之放大到整块svg
preserveAspectRatio 此属性也是应用在svg元素上,且作用的对象都是viewBox,第1个值表示,
viewBox如何与SVG viewport对齐;第2个值表示,如何维持高宽比(如果有
var timeScale = d3.scaleTime()
.domain([new Date(2016,0,1), new Date()]) // 数据范围
.range([0, 100]) // 映射范围
console.log(timeScale(new Date(2016, 0, 15))) // 6.348066...
console.log(timeScale(new Date(2016, 3, 15))) // 47.594155...
console.log(timeScale(new Date(new Date()))) // 100.000031...
console.log(timeScale.invert(50))// Wed Apr 20 2016 07:19:59 , 从数字倒推回时间
参考资料:github: d3.tip
// 2. 添加柱状图容器g
const chart = svg.append('g')
.attr('transform', `translate(${margin.left}, -${margin.bottom})`)
.selectAll('rect').data(chartdata)
.enter().append('rect')
.attr('width', xScale.bandwidth())
.attr('x', (data, i) => xScale(i))
// Starting position prior to transition
.attr('height', 0)
.attr('y', height)
chart.transition()
.attr('height', yScale)
.attr('y', data => height - yScale(data))
.delay((data, i) => i * 20)
.duration(650)
.ease(d3.easeSinIn);
// x轴比例尺
const xScale = d3.scaleBand() // 创建序数段比例尺
.domain(d3.range(0, chartdata.length))
.range([0, chartWidth]);
// 2. 添加柱状图容器g
const chart = svg.append('g')
.attr('transform', `translate(${margin.left}, -${margin.bottom})`)
.selectAll('rect').data(chartdata)
.enter().append('rect')
.attr('width', xScale.bandwidth())
两个Y轴
var margin = { top: 10, right: 20, bottom: 60, left: 40 };
var width = 425 - margin.left - margin.right;
var height = 625 - margin.top - margin.bottom;
var svg = d3.select('.chart')
.append('svg')
.attr('width', width + margin.left + margin.right)
.attr('height', height + margin.top + margin.bottom)
// 左边轴的容器g
var leftG = svg.append('g')
.attr('transform', 'translate(' + margin.left + ', ' + margin.top + ')');
var yScale = d3.scaleLinear()
.domain([0, 100])
.range([height, 0]);
var yAxis = d3.axisLeft(yScale).tickValues([0, 8, 19, 43, 77, 100]);
leftG.call(yAxis);
// 右边轴的容器g
var rightG = svg.append('g').attr('transform', `translate(${300}, ${margin.top})`);
var yScale2 = d3.scaleLinear()
.domain([0, 100])
.range([height, 0]);
var yAxis2 = d3.axisLeft(yScale2);
rightG.call(yAxis2);
d3.range(0,7) // [0,1,2,3,4,5,6]
d3.range(-3, 7) // [-3, -2, -1, 0, 1, 2, 3, 4, 5, 6]
传送门:dataV #8
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Egghead D3 v4</title>
<script src="//d3js.org/d3.v4.min.js"></script>
<style>
#block {
background: lightgray;
border: 1px solid black;
width: 100px;
height: 100px;
}
</style>
</head>
<body>
<div id="block"></div>
<script src="src/app.js"></script>
</body>
</html>
d3.select('#block')
.transition()
.duration(600)
.delay(750)
.ease(d3.easeBounceOut)
.style('width', '400px')
.transition()
.duration(600)
.ease(d3.easeBounceOut)
.style('height', '600px')
.transition()
.duration(2000)
.ease(d3.easeQuadOut)
.style('background-color', 'purple')
var scores = [
{ name: 'Alice', score: 96 },
{ name: 'Billy', score: 83 },
{ name: 'Cindy', score: 91 },
{ name: 'David', score: 96 },
{ name: 'Emily', score: 88 }
];
var bar = d3.select('.chart')
.append('svg')
.attr('width', 225)
.attr('height', 300)
.selectAll('g')
.data(scores)
.enter()
.append('g')
.attr('transform', (d, i) => 'translate(0, ' + i * 33 + ')');
bar.append('rect')
.style('width', d => d.score)
.attr('class', 'bar');
bar.append('text')
.attr('y', 20)
.text(function (d) {
return d.name;
});
注意:
.on('mouseover', data => {
const { target } = d3.event;
dynamicColor = d3.color(target.style.fill);
d3.select(target).style('fill', dynamicColor.brighter(1.5))
})
选中鼠标mouseover的元素将其颜色改变
.on("mouseover", function(d) {
div.transition()
.duration(200)
.style("opacity", .9);
div.html(formatTime(d[0]) + "<br/>" + "$" + d[1] + " Billion")
.style("left", (d3.event.pageX) - 20 + "px")
.style("top", (d3.event.pageY - 60) + "px");
})
通过d3.event获取到鼠标的x,y距离
var linearScale = d3.scaleLinear() // 比例尺
.domian([0, 100]) // 数据的边界范围
.range([0,600]) // 映射后的数据范围
.clamp(true) // 启用闭合(如果超出数据的边界范围)
console.log(linearScale(-20)) // 0 , clamp生效
console.log(linearScale(50)) // 300
console.log(linearScale(105)) // 600, clamp生效
console.log(linearScale.invert(300)) // 50, 反转,根据映射倒推出原数据的数值
传送门: dataV: issue 8
var data = [
{ value: 99, label: 'Mon' },
{ value: 63, label: 'Tues' },
{ value: 41, label: 'Wed' },
{ value: 100, label: 'Thur' },
{ value: 50, label: 'Fri' },
{ value: 23, label: 'Sat' },
{ value: 8, label: 'Sun' }
];
var yScale = d3.scaleLinear()
.domain([0, d3.max(data, d => d.value)]) // 第一种方法
.domain (d3.extent(data, d => d.value)) // 第二种方法
.range([0, 400]);
var margin = { top: 10, right: 20, bottom: 30, left: 30 };
var width = 400 - margin.left - margin.right;
var height = 600 - margin.top - margin.bottom;
var svg = d3.select('.chart')
.append('svg')
.attr('width', width + margin.left + margin.right)
.attr('height', height + margin.top + margin.bottom)
.call(responsivefy)
.append('g')
.attr('transform', 'translate(' + margin.left + ', ' + margin.top + ')');
var yScale = d3.scaleLinear()
.domain([0, 100])
.range([height, 0]);
var yAxis = d3.axisLeft(yScale);
svg.call(yAxis);
var xScale = d3.scaleTime()
.domain([new Date(2016, 0, 1, 6), new Date(2016, 0, 1, 9)])
.range([0, width]);
var xAxis = d3.axisBottom(xScale)
.ticks(5)
.tickSize(10)
.tickPadding(5);
svg
.append('g')
.attr('transform', `translate(0, ${height})`)
.call(xAxis);
function responsivefy(svg) {
// get container + svg aspect ratio
var container = d3.select(svg.node().parentNode),
width = parseInt(svg.style("width")),
height = parseInt(svg.style("height")),
aspect = width / height;
// add viewBox and preserveAspectRatio properties,
// and call resize so that svg resizes on inital page load
svg.attr("viewBox", "0 0 " + width + " " + height)
.attr("preserveAspectRatio", "xMinYMid")
.call(resize);
// to register multiple listeners for same event type,
// you need to add namespace, i.e., 'click.foo'
// necessary if you call invoke this function for multiple svgs
// api docs: https://github.com/mbostock/d3/wiki/Selections#on
d3.select(window).on("resize" , resize);
// get width of container and resize svg to fit it
function resize() {
var targetWidth = parseInt(container.style("width"));
svg.attr("width", targetWidth);
svg.attr("height", Math.round(targetWidth / aspect));
}
}
<div class="title">
<a href="#">About</a>
<a href="#">Products</a>
<a href="#">Contact</a>
</div>
var div = d3.select('div');
console.log(div.nodes()); //打印dom节点
var divLinks = div.selectAll('a');
console.log(divLinks.nodes()); // 同上
var secondLink = d3.selectAll('a:nth-child(2)'); //同css
console.log(secondLink.nodes());
var allLinks = d3.selectAll(document.links);
console.log(allLinks.size());
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Egghead D3 v4</title>
<script src="//d3js.org/d3.v4.min.js"></script>
<style>
.chart {
background: lightgray;
border: 1px solid black;
min-width: 200px;
min-height: 350px;
}
.bar {
height: 30px;
color: green;
fill: lightgreen;
stroke: black;
stroke-width: 1;
}
</style>
</head>
<body>
<div class="chart"></div>
<script src="src/app.js"></script>
</body>
</html>
var scores = [
{ name: 'Alice', score: 96 },
{ name: 'Billy', score: 83 },
{ name: 'Cindy', score: 91 },
{ name: 'David', score: 96 },
{ name: 'Emily', score: 88 }
];
d3.select('.chart')
.append('svg') // 添加svg, 并设置宽高
.attr('width', 225)
.attr('height', 300)
.selectAll('rect') // 选择矩形元素
.data(scores) // 数据填充
.enter()
.append('rect')
.attr('y', (d, i) => i * 33) // 每个矩形距离原点的竖直距离
.style('width', d => d.score)
.text(function (d) { // 但是文字没有显示出来
return d.name;
})
.attr('class', 'bar');
var margin = { top: 10, right: 20, bottom: 60, left: 40 };
var width = 425 - margin.left - margin.right;
var height = 625 - margin.top - margin.bottom;
var svg = d3.select('.chart')
.append('svg')
.attr('width', width + margin.left + margin.right)
.attr('height', height + margin.top + margin.bottom)
.append('g')
.attr('transform', 'translate(' + margin.left + ', ' + margin.top + ')');
svg.append('rect')
.attr('width', width)
.attr('height', height)
.style('fill', 'lightblue')
.style('stroke', 'green');
var yScale = d3.scaleLinear()
.domain([0, 100])
.range([height, 0]);
var yAxis = d3.axisLeft(yScale);
svg.call(yAxis);
var ordinalScale = d3.scaleOrdinal()
.domain(['poor', 'good', 'great']) // 数据范围, 会平均分成三部分对应range的三个值
.range(['red', 'white', 'green']) // 映射范围
console.log(ordinalScale('good')) // white
console.log(ordinalScale('great')) // green
console.log(ordinalScale('poor')) // red
selection.data - 元素和数据绑定
d3.merge - 将多个数组合并成一个
selection.enter - 获得进入(enter)选择器(数据无元素)
selection.exit - 获得退出(exit)选择器(元素无数据)
<div class="chart">
<div>Billy</div>
<div>Cindy</div>
<div>Walter</div>
</div>
var scores = [
{ name: 'Alice', score: 96 },
{ name: 'Billy', score: 83 },
{ name: 'Cindy', score: 91 },
{ name: 'David', score: 96 },
{ name: 'Emily', score: 88 }
];
var update = d3.select('.chart')
.selectAll('div')
.data(scores, function (d) {
return d ? d.name : this.innerText;
})
.style('color', 'blue'); // 已存在的三个div文字变蓝色(有一个后面删了)
var enter = update.enter()
.append('div')
.text(function (d) {
return d.name;
})
.style('color', 'green'); // 选出enter部分(有数据无div)然后改变文字为绿色
update.exit().remove(); // 将Walter删除了,暂时不知道为什么
update.merge(enter) // merge后返回新数组(即存在的加上添加的)
.style('width', d => d.score + 'px')
.style('height', '50px')
.style('background', 'lightgreen')
.style('border', '1px solid black')
<div class="title">
<a href="#">About</a>
<a href="#">Products</a>
<a href="#">Contact</a>
</div>
d3.selectAll('a:nth-child(2)')
.attr('href', 'http://google.com')
.classed('red', true)
.html('Inventory <b>SALE</b>');
selection.attr - 设置或获取特性。
selection.classed - 获取,添加或移除CSS类。
selection.style - 设置或获取样式。
selection.property - 设置或获取行内属性。
selection.text - 设置或获取文本内容。
selection.html - 设置或获取inner HTML。
selection.append - 创建,添加或选择新的元素。
selection.remove - 移除文档中的元素。
selection.sort - 基于数据给文档中的元素排序。
selection.order - 重排列文档中的元素以匹配选择中的顺序。
selection.raise - 重新排列每个元素为父元素的最后一个子节点。
selection.lower - 重新排列每个元素为父元素的第一个子节点。
d3.creator - 通过名称创建元素
参考资料:d3
// 读json数据
d3.json('data/data.json', function (data) {
console.log(data)
})
// 读csv数据
d3.csv('data/data.json', function (data) {
console.log(data)
})
// 读tsv数据
d3.json('data/data.tsv', function (data) {
console.log(data)
})
备注:csv和tsv打印来的data会多columns数组,保存的是数据项
var scores = [
{ name: 'Alice', score: 96 },
{ name: 'Billy', score: 83 },
{ name: 'Cindy', score: 91 },
{ name: 'David', score: 96 },
{ name: 'Emily', score: 88 }
];
var bar = d3.select('.chart')
.append('svg')
.attr('width', 225)
.attr('height', 300)
.selectAll('g')
.data(scores)
.enter()
.append('g')
.attr('transform', (d, i) => 'translate(0, ' + i * 33 + ')');
bar.append('rect')
.style('width', d => d.score)
.attr('class', 'bar')
.on('mouseover', function (d, i, elements) {
d3.select(this).style('transform', 'scaleX(2)');
d3.selectAll(elements)
.filter(':not(:hover)')
.style('fill-opacity', 0.5);
})
.on('mouseout', function (d, i, elements) {
d3.select(this).style('transform', 'scaleX(1)');
d3.selectAll(elements)
.style('fill-opacity', 1);
});
bar.append('text')
.attr('y', 20)
.text(function (d) {
return d.name;
});
d3.select(this)
function(d, i, elements)
分别带别data, index,和所有dom元素d3.json('data/data.json', function (data) {
var extent = d3.extent(data, function (d) {
return d.age;
});
console.log(extent); // [13.38]
var scale = d3.scaleLinear()
.domain(extent)
.range([0, 600]);
console.log(scale(37)); // 576
var ages = d3.set(data, function (d) {
return d.age;
});
console.log(ages.values()); // [23, 38, 13, 37]
})
// data.json
[
{
"age": 23,
"name": "Welch"
},
{
"age": 38,
"name": "Villarreal"
},
{
"age": 13,
"name": "Sheryl"
},
{
"age": 37,
"name": "Marshall"
},
{
"age": 37,
"name": "Aimee"
}
]
d3.set类似ES6 Set,但是键时字符类型的,并且有点其他区别
set.values - 获取值数组
参考资料:d3.set
var margin = { top: 10, right: 20, bottom: 25, left: 25 };
var svgWidth = 425;
var svgHeight = 625;
var width = 425 - margin.left - margin.right;
var height = 625 - margin.top - margin.bottom;
var svg = d3.select('.chart')
.append('svg')
.attr('width', svgWidth)
.attr('height', svgHeight)
.append('g')
.attr('transform', `translate(${margin.left}, ${margin.top})`);
svg.append('rect')
.attr('width', width / 2)
.attr('height', height)
.style('fill', 'lightblue')
.style('stroke', 'green');
svg.append('rect')
.attr('x', width / 2)
.attr('width', width / 2)
.attr('height', height)
.style('fill', 'lightblue')
.style('stroke', 'green');
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.