Published
Edited
Feb 8, 2021
1 star
Insert cell
Insert cell
md`# Observable对比常规Javascript`
Insert cell
Insert cell
md `
### Observable中的Javascript

Observable单元有两种形式: *表达式* 和 *块*。
`
Insert cell
Insert cell
md `
#### 表达式

表达式用于简单定义(如基本计算)以及定义将在整个笔记本中使用的基本对象。

全局范围,拓扑结构
`
Insert cell
height = 500
Insert cell
Insert cell
md`
Observable中表达式的两个关键功能是它们具有 *全局范围* 和 *拓扑求值*。这对我们来说意味着表达式在整个笔记本中可用,并且在定义元素之前可以出现对元素的引用。下面,您将看到高度和宽度在不同于它们被调用的单元格中可访问,并且在定义宽度之前正在引用该宽度。
`
Insert cell
Insert cell
md`
这也意味着我们不能在可观察中重新定义全局变量,因此请谨慎使用它们!查看尝试取消注释下面的单元格时会发生什么。
`
Insert cell
//height = 20
Insert cell
Insert cell
md `
#### 块
单元格的另一个主要形式位于*块*中。块被 {大括号} 包围,用于更复杂的定义。您可能已经注意到,您不能有一个多行的表达式单元格,这就是块的作用!它们非常适合包含局部变量或循环的定义:


`
Insert cell
{
let firstNumber = 55
return firstNumber + 10
}
Insert cell
Insert cell
md`
如果你想在另一个单元格里引用一个块,你可以将它定义成函数:
`
Insert cell
function addingNumbers(number3, number4){
let number5 = number3 + number4
return number5
}
Insert cell
Insert cell
md`
关于块,重要的是要记住,它们不能被其他单元格引用,因为它们不是全局定义的。
`
Insert cell
Insert cell
md `### 用Observable写的D3示例
让我们看一个简单的 D3 示例,该示例使用 *块* 和 *表达式* 编写
`
Insert cell
bosData = d3.csv("https://gist.githubusercontent.com/jdev42092/46071bf3284265c37ea07d6328ef7a3a/raw/cc7bfc53f3853437749906ccf7d2cac49c43c9a2/neigh_311.csv", ({neighborhood, num_311}) => ({neighborhood: neighborhood, calls: +num_311}))
Insert cell
Insert cell
md `### 作为单个代码块的图表`
Insert cell
{
var margin = ({top: 15, right: 10, bottom: 25, left: 30})
// Initialize SVG object (using our pre-defined width and height)
const svg = d3.select(DOM.svg(width, height));

// Get length of dataset
let arrayLength = bosData.length; // length of dataset
let maxValue = d3.max(bosData, d=> d.calls); // get max value of our dataset
let x_axisLength = (width - margin.right - margin.left); // length of x-axis in our layout
let y_axisLength = (height - margin.top - margin.bottom); // length of y-axis in our layout


// Use a scale for the height of the visualization
const yScale = d3.scaleLinear()
.domain([0, d3.max(bosData, d=> d.calls)])
.range([margin.bottom, height - margin.top])

// Select and generate rectangle elements
svg.selectAll( "rect" )
.data( bosData )
.enter()
.append("rect")
.attr( "x", (d,i) => (i*(x_axisLength/arrayLength) + margin.left))
// Set x coordinate of each bar to index of data value (i) times dynamically calculated bar width.
// Add left margin to account for our left margin.
.attr( "y", d => (height - yScale(d.calls)) )
// Set y coordinate using yScale.
.attr( "width", (x_axisLength/arrayLength) - 1 )
// Set bar width using length of array, with 1px gap between each bar.
.attr( "height", d => yScale(d.calls) - yScale(0))
// Set height of rectangle to data value, accounting for bottom margin.
.attr( "fill", "steelblue");

// Create y-axis, beginning at the top margin and ending at the bottom margin
svg.append("line")
.attr("x1", margin.left)
.attr("y1", margin.top)
.attr("x2", margin.left)
.attr("y2", height - margin.bottom)
.attr("stroke-width", 2)
.attr("stroke", "black");

// Create x-axis beginning at the left margin, and ending at the right margin
svg.append("line")
.attr("x1", margin.left)
.attr("y1", height - margin.bottom)
.attr("x2", width - margin.right)
.attr("y2", height - margin.bottom)
.attr("stroke-width", 2)
.attr("stroke", "black");

// Add a Label
// y-axis label
svg.append("text")
.attr("class", "y label")
.attr("text-anchor", "end")
.text("No. of 311 Calls")
.attr("transform", "translate(20, 20) rotate(-90)");

return svg.node();
}
Insert cell
Insert cell
md `### 作为一组表达式的图表
有什么不同???请记住,我们不能事先声明变量,我们只需要传递它们的名称,并记住,我们不能重新定义它们沿途!!!
`
Insert cell
margin = ({top: 15, right: 10, bottom: 25, left: 30})
Insert cell
// Initialize SVG object (using our pre-defined width and height)
svg = d3.select(DOM.svg(width, height));
Insert cell
// Get length of dataset
arrayLength = bosData.length; // length of dataset
Insert cell
maxValue = d3.max(bosData, d=> d.calls); // get max value of our dataset
Insert cell
x_axisLength = (width - margin.right - margin.left); // length of x-axis in our layout
Insert cell
y_axisLength = (height - margin.top - margin.bottom); // length of y-axis in our layout
Insert cell
// Use a scale for the height of the visualization
yScale = d3.scaleLinear()
.domain([0, d3.max(bosData, d=> d.calls)])
.range([margin.bottom, height - margin.top])

Insert cell
// Select and generate rectangle elements
svg.selectAll( "rect" )
.data( bosData )
.enter()
.append("rect")
.attr( "x", (d,i) => (i*(x_axisLength/arrayLength) + margin.left))
// Set x coordinate of each bar to index of data value (i) times dynamically calculated bar width.
// Add left margin to account for our left margin.
.attr( "y", d => (height - yScale(d.calls)) )
// Set y coordinate using yScale.
.attr( "width", (x_axisLength/arrayLength) - 1 )
// Set bar width using length of array, with 1px gap between each bar.
.attr( "height", d => yScale(d.calls) - yScale(0))
// Set height of rectangle to data value, accounting for bottom margin.
.attr( "fill", "steelblue");
Insert cell
// Create y-axis, beginning at the top margin and ending at the bottom margin
svg.append("line")
.attr("x1", margin.left)
.attr("y1", margin.top)
.attr("x2", margin.left)
.attr("y2", height - margin.bottom)
.attr("stroke-width", 2)
.attr("stroke", "black");
Insert cell
// Create x-axis beginning at the left margin, and ending at the right margin
svg.append("line")
.attr("x1", margin.left)
.attr("y1", height - margin.bottom)
.attr("x2", width - margin.right)
.attr("y2", height - margin.bottom)
.attr("stroke-width", 2)
.attr("stroke", "black");
Insert cell
// Add a Label
// y-axis label
svg.append("text")
.attr("class", "y label")
.attr("text-anchor", "end")
.text("No. of 311 Calls")
.attr("transform", "translate(20, 20) rotate(-90)");
Insert cell
svg.node();

Insert cell
Insert cell
md `### 内嵌在HTML文档中的图表
有什么不同???我们只使用 **var** 关键字定义变量...不是很多浏览器支持 ES6 !此外,一切都在**script**标签内! `
Insert cell
Insert cell
Insert cell
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more