Introduction
Following the Learn D3: By Example , it is only an English translation. The part of the code that can be modified is replaced with a static image. If you want to interact in real time, please read the original text.
- Original: Learn D3: Data
- Version: Published Mar 24, 2020
- Origin
- My GitHub
text
There are several ways in Observable acquired data . But since we have just started, let's use the simplest: file attachment .
This notebook has a CSV file containing daily temperature readings. I use Shift-Command-U ⇧⌘U keyboard shortcut add it; you can also attach files by dragging and dropping files to the file attachment pane, which can be accessed through the notebook menu or click the paperclip icon above access.
FileAttachment
function only returns a handle that allows you to choose the desired representation, such as blob , buffer or (UTF-8 encoded) text. For CSV files, we can call file.text
to get the file content according to the desired string form.
Of course, a more useful method is to parse the text into date
and temperature
, which we can achieve by passing the text to d3.csvParse . (D3 is loaded in the appendix below and is available in every unit in the notebook.)
Click the array below to view the objects.
Although Observable implicitly waits for cross-unit promises, we must wait for the file.text
promise because we want to access the return value in the same unit.
By default, D3 does not perform type inference, so the date
and temperature
attributes are both strings. This makes them difficult to get along with. For example, if you try to add two temperatures, they will be connected. Oops! 😝
To convert these strings into dates and numbers, pass a function as the second parameter to d3.csvParse
. This function is called for each line, and the object of the line is manipulated as needed. A better approach is to automatically infer the type d3.autoType
If you look at the above array, you will see blue dates and numbers (instead of blue strings between double quotes), which indicates that the type conversion was successful.
Let's understand a little bit about the syntax of the Observable unit. So far, you have only seen the expression unit that can be named or anonymous. Both types of units can be checked, but only named units can be referenced from other units.
For more complex code than simple expressions, write a block consisting of one or more statements enclosed in curly braces. Block units are similar to functions and only produce values return or yield Like expression units, named block units can be referenced from other units.
Local variables, such as s
above, are not visible to the rest of the notebook; other units can only access the return value of the named unit. In this way, Observable is similar to a spreadsheet: each cell defines a unique value.
Back to the task at hand, in data , there are more explicit methods to obtain, parse, and type-convert CSV files. If your data is not compatible with d3.autoType, you can use this method (if you are not sure, do not rely on automatic type inference or consult the document .)
With data that can be easily represented, we can now start to work! For example, we can calculate the range of date and temperature to get the area value.
As we saw earlier, we can sample histogram to visually perceive the temperature distribution.
Mild climate! Ah, San Francisco. 🌤
When Observable processes data, an implicit consideration is whether to put the code in a single unit or separate units. A good rule of thumb is that a unit should define a named value that is referenced by other units (such as data
above), or it should show the reader some useful information (such as this article, the above chart or check the unit data).
A key implication of this rule is that you should avoid implicit dependencies between units: rely only on what you can name.
Why? The data stream of the notebook is constructed based on its unit reference. If the unit does not have a name, it cannot be referenced, and units that implicitly depend on its effects may run before it. (Units are run in topological order, not from top to bottom.) Implicit dependencies can cause uncertain behavior during development😱, and errors that may occur when the notebook is reloaded💥!
For example, if one unit defines an array and another unit modifies it, other units may see the array before or after the mutation. In order to avoid this uncertainty, you need to make the dependency relationship explicit, you can specify a name for the second unit and use array.from or array.map copy the array. Or merge two units so that other units can only see the modified array.
Our data is ready, let's turn to graphics!
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。