基础准备
js组件种类和分层
前端开发是一个B/S结构的开发,web前端工程师能够接触到的最底层的API就是由浏览器提供的API,浏览器API主要分为HTML
、CSS
、JS
三种,而我们的d3.js主要使用的是svg
和canvas
我们知道浏览器底层存在很多问题:(es6之前)
- js核心语法层面是比较薄弱的,像面向对象的
extend
- js原生API不好用,比如
cookie
ajax
- 浏览器兼容性问题
框架组件又可以分为:
- 框架通用组件
- 框架定制组件
闭包函数写法
在闭包函数上挂载配置项
function chart() {
//这里写cfg配置项
var width = 720, // default width
height = 80; // default height
function my() {
// generate chart here, using `width` and `height`
}
//函数本身也是对象 可以挂载变量和属性
//所以我们把绘制图表函数(闭包函数my())内的绘制用的变量width height等 挂载在它本身(my()这个对象) 上
// 这样如果我们可以自由的改变这些配置项
my.width = function(value) {
if (!arguments.length) return width;
width = value;
return my;
};
my.height = function(value) {
if (!arguments.length) return height;
height = value;
return my;
};
return my;
}
总结:这就是所谓的面向对象的写法,
把成员变量直接暴露在外不符合OOP的封装性原则,不安全,应该使用getter和seter方法来取值和赋值。
浅谈 JS 对象添加 getter与 setter 的5种方法以及如何让对象属性不可配置或枚举
实际案例
html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title></title>
<link rel="stylesheet" href="">
</head>
<body>
<p id="example"></p>
<script src="https://cdn.bootcss.com/d3/2.10.0/d3.v2.js"></script>
<script src="time-series-chart.js"></script>
<script>
var chart = timeSeriesChart()
.x(function(d) { return formatDate.parse(d.date); })
.y(function(d) { return +d.price; });
var formatDate = d3.time.format("%b %Y");
d3.csv("http://otc2ysde8.bkt.clouddn.com/charts/sp500.csv",function(data) {
d3.select("#example")
.datum(data)
.call(chart);
});
</script>
</body>
</html>
time-series-chart.js
function timeSeriesChart() {
var margin = {top: 20, right: 20, bottom: 20, left: 20},
width = 760,
height = 120,
xValue = function(d) { return d[0]; },
yValue = function(d) { return d[1]; },
xScale = d3.time.scale(),
yScale = d3.scale.linear(),
xAxis = d3.svg.axis().scale(xScale).orient("bottom").tickSize(6, 0),
area = d3.svg.area().x(X).y1(Y),
line = d3.svg.line().x(X).y(Y);
function chart(selection) {
selection.each(function(data) {
// Convert data to standard representation greedily;
// this is needed for nondeterministic accessors.
data = data.map(function(d, i) {
return [xValue.call(data, d, i), yValue.call(data, d, i)];
});
// Update the x-scale.
xScale
.domain(d3.extent(data, function(d) { return d[0]; }))
.range([0, width - margin.left - margin.right]);
// Update the y-scale.
yScale
.domain([0, d3.max(data, function(d) { return d[1]; })])
.range([height - margin.top - margin.bottom, 0]);
// Select the svg element, if it exists.
var svg = d3.select(this).selectAll("svg").data([data]);
// Otherwise, create the skeletal chart.
var gEnter = svg.enter().append("svg").append("g");
gEnter.append("path").attr("class", "area");
gEnter.append("path").attr("class", "line");
gEnter.append("g").attr("class", "x axis");
// Update the outer dimensions.
svg .attr("width", width)
.attr("height", height);
// Update the inner dimensions.
var g = svg.select("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
// Update the area path.
g.select(".area")
.attr("d", area.y0(yScale.range()[0]));
// Update the line path.
g.select(".line")
.attr("d", line);
// Update the x-axis.
g.select(".x.axis")
.attr("transform", "translate(0," + yScale.range()[0] + ")")
.call(xAxis);
});
}
// The x-accessor for the path generator; xScale ∘ xValue.
function X(d) {
return xScale(d[0]);
}
// The x-accessor for the path generator; yScale ∘ yValue.
function Y(d) {
return yScale(d[1]);
}
chart.margin = function(_) {
if (!arguments.length) return margin;
margin = _;
return chart;
};
chart.width = function(_) {
if (!arguments.length) return width;
width = _;
return chart;
};
chart.height = function(_) {
if (!arguments.length) return height;
height = _;
return chart;
};
chart.x = function(_) {
if (!arguments.length) return xValue;
xValue = _;
return chart;
};
chart.y = function(_) {
if (!arguments.length) return yValue;
yValue = _;
return chart;
};
console.log(chart);
return chart;
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。