freeCodeCamp 旅途17 - D3

D3

D3.js,也叫 D3,表示数据驱动文档。 D3 是一个在浏览器里创建动态可视化数据的 JavaScript 库。它基于 web 标准,即 HTML、CSS 和 SVG 技术。

D3 获取输入数据并且映射到相应的可视化内容里。它支持不同的数据格式。D3 允许将数据绑定到 DOM 上。你可以使用 D3 的内建方法通过 HMTL 或者 SVG 元素实现数据可视化。以下例子中的 d3 是 D3 的引用

用 D3 实现数据可视化:用 D3 给文档添加元素

D3 有多种方法可以用来在文档中增加元素、修改元素。

select()方法用来从文档中选择元素,它以你查询的元素名称作为参数,返回第一个符合条件的 HTML 节点。以下是一个例子:const anchor = d3.select("a");

append()方法以你想添加到文档中的元素作为参数,给选中的元素添加一个 HTML 节点,返回那个节点的句柄。

text()方法既可以给节点设置新的文本,也可以获取节点的当前文本。 如果要设置文字内容,需要在圆括号中传入一个 string(字符串)类型的参数。

// 选择无序列表、添加列表项和文字
d3.select("ul")
  .append("li")
  .text("Very important item");

d3.select('body')
  .append('h1')
  .text('Learning D3');

用 D3 实现数据可视化:用 D3 选择一组元素

selectAll()方法选择一组元素。它以 HTML 节点数组的形式返回该文本中所有匹配所输入字符串的对象。选择文本中所有锚标签: const anchors = d3.selectAll("a");;选择所有 li 标签并设置内容: d3.selectAll('li').text('list item');

用 D3 实现数据可视化:使用 D3 中的数据

第一步是让 D3 知道数据。data()方法选择连接着数据的 DOM 元素,数据集作为参数传递给该方法。

常见的方法是在文档中为数据集中的每一个数据创建一个元素,为此,你可以使用 D3 的enter()方法。

enter()data()方法一起使用时,它把从页面中选择的元素和数据集中的元素作比较。如果页面中选择的元素较少则创建缺少的元素。

// enter()方法发现页面中没有 li 元素,但是需要 3 个
<body>
  <ul></ul>
  <script>
    const dataset = ["a", "b", "c"];
    d3.select("ul").selectAll("li")
      .data(dataset)
      .enter()
      .append("li")
      .text("New item");
  </script>
</body>

// 没有元素就创建元素
<body>
  <script>
    const dataset = [12, 31, 22, 17, 25, 18, 29, 14, 9];
    d3.select('body')
      .selectAll('h2')
      .data(dataset)
      .enter()
      .append('h2')
      .text('New Title');
  </script>
</body>

用 D3 实现数据可视化:使用 D3 中的动态数据

text()方法以字符串或者回调函数作为参数:selection.text((d) => d)

const dataset = [12, 31, 22, 17, 25, 18, 29, 14, 9];
    d3.select("body").selectAll("h2")
      .data(dataset)
      .enter()
      .append("h2")
      .text((d) => d + ' ' +  'USD');

用 D3 实现数据可视化:给元素添加内联样式

D3 可以使用style()方法为动态元素添加内联 CSS 样式表。style()方法以用逗号分隔的键值对作为参数: selection.style("color","blue");

const dataset = [12, 31, 22, 17, 25, 18, 29, 14, 9];    
    d3.select("body").selectAll("h2")
      .data(dataset)
      .enter()
      .append("h2")
      .text((d) => (d + " USD"))
      .style("font-family", "verdana")

用 D3 实现数据可视化:根据数据更改样式

style()方法中使用回调函数为不同元素改变样式。例如,你想将值小于 20 的数据点设置为蓝色,其余设置为红色。你可以在style()方法中使用包含条件逻辑的回调函数。回调函数以d作为参数来表示一个数据点:

// style()方法不仅仅可以设置color——它也适用于其他 CSS 属性
selection.style("color", (d) => {
  return d < 20 ? "blue" : "red"
});

const dataset = [12, 31, 22, 17, 25, 18, 29, 14, 9];
    d3.select("body").selectAll("h2")
      .data(dataset)
      .enter()
      .append("h2")
      .text((d) => (d + " USD"))
      .style("color", d => d < 20 ? "red" : "green")

用 D3 实现数据可视化:用 D3 添加 Class

D3 中的attr()方法可以给元素添加任何 HTML 属性,包括类名称。attr()方法和style()的使用方法一样。它以逗号分隔的键值对为参数使用回调函数。

<style>
  .bar {
    width: 25px;
    height: 100px;
    display: inline-block;
    background-color: blue;
  }
</style>
<body>
  <script>
    const dataset = [12, 31, 22, 17, 25, 18, 29, 14, 9];
    d3.select("body").selectAll("div")
      .data(dataset)
      .enter()
      .append("div")
      .attr("class", "bar");
  </script>
</body>

用 D3 实现数据可视化:动态更新元素的高度

只需两步创建一个简单的条形图:

  1. 为每一个数组中的数据点都创建一个div

  2. 为每个div动态分配高度值,在style()方法中使用回调函数将高度值设置为数据大小

<style>
  .bar {
    width: 25px;
    height: 100px;
    display: inline-block;
    background-color: blue;
  }
</style>
<body>
  <script>
    const dataset = [12, 31, 22, 17, 25, 18, 29, 14, 9];
    d3.select("body").selectAll("div")
      .data(dataset)
      .enter()
      .append("div")
      .attr("class", "bar")
      .style("height", d => d);
  </script>
</body>

用 D3 实现数据可视化:更改条形图的显示方式

<style>
  .bar {
    width: 25px;
    height: 100px;
    margin: 2px;
    display: inline-block;
    background-color: blue;
  }
</style>
<body>
  <script>
    const dataset = [12, 31, 22, 17, 25, 18, 29, 14, 9];
    d3.select("body").selectAll("div")
      .data(dataset)
      .enter()
      .append("div")
      .attr("class", "bar")
      .style("height", (d) => (d * 10 + "px"))
  </script>
</body>

用 D3 实现数据可视化:了解 D3 中的 SVG

当使用相对单位(例如vhvw或者百分比)时,CSS 是可伸缩的。但是在实现数据可视化的时候 SVG 更加的灵活。

<style>
  svg {
    background-color: pink;
  }
</style>
<body>
  <script>
    const dataset = [12, 31, 22, 17, 25, 18, 29, 14, 9];    
    const w = 500;
    const h = 100;    
    const svg = d3.select("body")
      .append("svg")
      .attr("width", w)
      .attr("height", h)              
  </script>
</body>

用 D3 实现数据可视化:用 SVG 显示形状

<body>
  <script>
    const dataset = [12, 31, 22, 17, 25, 18, 29, 14, 9];    
    const w = 500;
    const h = 100;    
    const svg = d3.select("body")
        .append("svg")
        .attr("width", w)
        .attr("height", h)
        .append('rect')
         .attr("width", 25)        
        .attr("height", 100)     
        .attr("x", 0)                 
        .attr("y", 0) 
  </script>
</body>

用 D3 实现数据可视化:为集合中的每个数据点创建一个 Bar

<body>
  <script>
    const dataset = [12, 31, 22, 17, 25, 18, 29, 14, 9];    
    const w = 500;
    const h = 100;    
    const svg = d3.select("body")
                  .append("svg")
                  .attr("width", w)
                  .attr("height", h);   
    svg.selectAll("rect")
       .data(dataset)
       .enter()
       .append("rect")
       .attr("x", 0)
       .attr("y", 0)
       .attr("width", 25)
       .attr("height", 100);
  </script>
</body>

用 D3 实现数据可视化:动态设置每个 Bar 的坐标

<body>
  <script>
    const dataset = [12, 31, 22, 17, 25, 18, 29, 14, 9];    
    const w = 500;
    const h = 100;    
    const svg = d3.select("body")
                  .append("svg")
                  .attr("width", w)
                  .attr("height", h);    
    svg.selectAll("rect")
       .data(dataset)
       .enter()
       .append("rect")
        // i 表示索引
       .attr("x", (d, i) => {
         return i * 30
       })
       .attr("y", 0)
       .attr("width", 25)
       .attr("height", 100);
  </script>
</body>

用 D3 实现数据可视化:动态更改每个条的高度

<body>
  <script>
    const dataset = [12, 31, 22, 17, 25, 18, 29, 14, 9];
    const w = 500;
    const h = 100;
    const svg = d3.select("body")
                  .append("svg")
                  .attr("width", w)
                  .attr("height", h);
    svg.selectAll("rect")
       .data(dataset)
       .enter()
       .append("rect")
       .attr("x", (d, i) => i * 30)
       .attr("y", 0)
       .attr("width", 25)
       .attr("height", (d, i) => {
         return d * 3
       });
  </script>
</body>

用 D3 实现数据可视化:反转 SVG 元素

<body>
  <script>
    const dataset = [12, 31, 22, 17, 25, 18, 29, 14, 9];
    const w = 500;
    const h = 100;
    const svg = d3.select("body")
                  .append("svg")
                  .attr("width", w)
                  .attr("height", h);
    svg.selectAll("rect")
       .data(dataset)
       .enter()
       .append("rect")
       .attr("x", (d, i) => i * 30)
       .attr("y", (d, i) => {
        // 高度关系为 y = h - m * d,其中m是对数据点进行缩放的比例
         return 100 - d * 3
       })
       .attr("width", 25)
       .attr("height", (d, i) => 3 * d);
  </script>
</body>

用 D3 实现数据可视化:更改 SVG 元素的颜色

在 SVG 中,rect图形用fill属性着色,它支持十六进制代码、颜色名称、rgb 值以及更复杂的选项,比如渐变和透明。

<body>
  <script>
    const dataset = [12, 31, 22, 17, 25, 18, 29, 14, 9];
    const w = 500;
    const h = 100;
    const svg = d3.select("body")
                  .append("svg")
                  .attr("width", w)
                  .attr("height", h);
    svg.selectAll("rect")
       .data(dataset)
       .enter()
       .append("rect")
       .attr("x", (d, i) => i * 30)
       .attr("y", (d, i) => h - 3 * d)
       .attr("width", 25)
       .attr("height", (d, i) => 3 * d)
       .attr("fill", "navy")
  </script>
</body>

用 D3 实现数据可视化:给 D3 元素添加标签

D3 允许使用 SVG 的text元素给图形元素贴标签,例如给条形图中的各组都贴上标签。text元素也需要xy属性来指定其放置在 SVG 画布上的位置,它也需要能够获取数据来显示数据值。

<body>
  <script>
    const dataset = [12, 31, 22, 17, 25, 18, 29, 14, 9];
    const w = 500;
    const h = 100;
    const svg = d3.select("body")
                  .append("svg")
                  .attr("width", w)
                  .attr("height", h);
    svg.selectAll("rect")
       .data(dataset)
       .enter()
       .append("rect")
       .attr("x", (d, i) => i * 30)
       .attr("y", (d, i) => h - 3 * d)
       .attr("width", 25)
       .attr("height", (d, i) => 3 * d)
       .attr("fill", "navy");
    svg.selectAll("text")
       .data(dataset)
       .enter()
       .append("text")
       .attr("x", (d, i) => i * 30)
       .attr("y", (d, i) => h - 3 * d - 3)
       .text((d, i) => d)
  </script>
<body>

用 D3 实现数据可视化:给 D3 标签添加样式

<body>
  <script>
    const dataset = [12, 31, 22, 17, 25, 18, 29, 14, 9];
    const w = 500;
    const h = 100;
    const svg = d3.select("body")
                  .append("svg")
                  .attr("width", w)
                  .attr("height", h);
    svg.selectAll("rect")
       .data(dataset)
       .enter()
       .append("rect")
       .attr("x", (d, i) => i * 30)
       .attr("y", (d, i) => h - 3 * d)
       .attr("width", 25)
       .attr("height", (d, i) => d * 3)
       .attr("fill", "navy");
    svg.selectAll("text")
       .data(dataset)
       .enter()
       .append("text")
       .text((d) => d)
       .attr("x", (d, i) => i * 30)
       .attr("y", (d, i) => h - (3 * d) - 3)
       .attr("font-size", "25px")
       .attr("fill", "red") 
  </script>
</body>

用 D3 实现数据可视化:给 D3 元素添加悬停效果

<style>
  .bar:hover {
    fill: brown;
  }
</style>
<body>
  <script>
    const dataset = [12, 31, 22, 17, 25, 18, 29, 14, 9];  
    const w = 500;
    const h = 100;
    const svg = d3.select("body")
                  .append("svg")
                  .attr("width", w)
                  .attr("height", h);
    svg.selectAll("rect")
       .data(dataset)
       .enter()
       .append("rect")
       .attr("x", (d, i) => i * 30)
       .attr("y", (d, i) => h - 3 * d)
       .attr("width", 25)
       .attr("height", (d, i) => 3 * d)
       .attr("fill", "navy")
       .attr("class", "bar")
    svg.selectAll("text")
       .data(dataset)
       .enter()
       .append("text")
       .text((d) => d)
       .attr("x", (d, i) => i * 30)
       .attr("y", (d, i) => h - (3 * d) - 3);
  </script>
</body>

用 D3 实现数据可视化:给 D3 元素添加工具提示

<style>
  .bar:hover {
    fill: brown;
  }
</style>
<body>
  <script>
    const dataset = [12, 31, 22, 17, 25, 18, 29, 14, 9];
    const w = 500;
    const h = 100;
    const svg = d3.select("body")
                  .append("svg")
                  .attr("width", w)
                  .attr("height", h);
    svg.selectAll("rect")
       .data(dataset)
       .enter()
       .append("rect")
       .attr("x", (d, i) => i * 30)
       .attr("y", (d, i) => h - 3 * d)
       .attr("width", 25)
       .attr("height", (d, i) => d * 3)
       .attr("fill", "navy")
       .attr("class", "bar")
       .append("title")
       .text(d => d)
    svg.selectAll("text")
       .data(dataset)
       .enter()
       .append("text")
       .text((d) => d)
       .attr("x", (d, i) => i * 30)
       .attr("y", (d, i) => h - (d * 3 + 3))   
  </script>
</body>

用 D3 实现数据可视化:使用 SVG Circles 创建散点图

SVG 用circle标签来创建圆形,它和之前用来构建条形图的rect非常相像。

<body>
  <script>
    const dataset = [
                  [ 34,    78 ],
                  [ 109,   280 ],
                  [ 310,   120 ],
                  [ 79,    411 ],
                  [ 420,   220 ],
                  [ 233,   145 ],
                  [ 333,   96 ],
                  [ 222,   333 ],
                  [ 78,    320 ],
                  [ 21,    123 ]
                ];
    const w = 500;
    const h = 500;
    const svg = d3.select("body")
                  .append("svg")
                  .attr("width", w)
                  .attr("height", h);
    svg.selectAll("circle")
       .data(dataset)
       .enter()
       .append("circle")
  </script>
</body>

用 D3 实现数据可视化:给 Circle 元素添加属性

在 SVG 中circle有三个主要的属性。cxcy属性是坐标,它们告诉 D3 将图形的中心放在 SVG 画布的何处。半径(r属性)给出circle的大小。

<body>
  <script>
    const dataset = [
                  [ 34,    78 ],
                  [ 109,   280 ],
                  [ 310,   120 ],
                  [ 79,    411 ],
                  [ 420,   220 ],
                  [ 233,   145 ],
                  [ 333,   96 ],
                  [ 222,   333 ],
                  [ 78,    320 ],
                  [ 21,    123 ]
                ];
    const w = 500;
    const h = 500;
    const svg = d3.select("body")
                  .append("svg")
                  .attr("width", w)
                  .attr("height", h);
    svg.selectAll("circle")
       .data(dataset)
       .enter()
       .append("circle")
       .attr("cx", d => d[0])
       .attr("cy", d => h - d[1])
       .attr("r", 5)
  </script>
</body>

用 D3 实现数据可视化:向散点图的 Circles 添加标签

text节点需要xy属性来指定放置在 SVG 画布中的位置。

<body>
  <script>
    const dataset = [
                  [ 34,    78 ],
                  [ 109,   280 ],
                  [ 310,   120 ],
                  [ 79,    411 ],
                  [ 420,   220 ],
                  [ 233,   145 ],
                  [ 333,   96 ],
                  [ 222,   333 ],
                  [ 78,    320 ],
                  [ 21,    123 ]
                ];
    const w = 500;
    const h = 500;
    const svg = d3.select("body")
                  .append("svg")
                  .attr("width", w)
                  .attr("height", h);
    svg.selectAll("circle")
       .data(dataset)
       .enter()
       .append("circle")
       .attr("cx", (d, i) => d[0])
       .attr("cy", (d, i) => h - d[1])
       .attr("r", 5);
    svg.selectAll("text")
       .data(dataset)
       .enter()
       .append("text")
       .attr("x", d => d[0] + 5)
       .attr("y", d => h - d[1])
       .text(d => d[0]+", "+d[1])
  </script>
</body>

用 D3 实现数据可视化:用 D3 创建线性比例

D3 中,比例尺可帮助布局数据。Scales是告诉程序如何将一组原始数据点映射到 SVG 画布上像素的函数。D3 有几种缩放类型。对于线性缩放(通常使用于定量数据),使用 D3 的scaleLinear()方法:const scale = d3.scaleLinear()

<body>
  <script>
    const scale = d3.scaleLinear(); 
    const output = scale(50); 
    d3.select("body")
      .append("h2")
      .text(output);
  </script>
</body>

用 D3 实现数据可视化:按比例设置域和范围

默认情况下,比例尺使用同一关系(identity relationship),即输入值直接映射为输出值。但是比例尺可以更灵活更有趣。

假设有一个数据集范围为 50 到 480,这是缩放的输入信息,也被称为域(domain)。你想沿着 10 个单位到 500 个单位的x轴映射这些点到 SVG 画布上。这是输出信息,也被称为范围(range)。

domain()range()方法设置缩放的值,它们都以至少有两个元素的数组为参数。下面是一个例子:

// 设置域
// 域覆盖了一组输入值
scale.domain([50, 480]);
// 设置范围
// 范围覆盖了一组输出值
scale.range([10, 500]);
scale(50) // 返回 10
scale(480) // 返回 500
scale(325) // 返回 323.37
scale(750) // 返回 807.67
d3.scaleLinear()

<body>
  <script>
    const scale = d3.scaleLinear();
    scale.domain([250, 500]);
    scale.range([10, 150])
    const output = scale(50);
    d3.select("body")
      .append("h2")
      .text(output);
  </script>
</body>

使用 d3.max 和 d3.min 函数在数据集中查找最小值和最大值

D3 有两个方法——min()和max()来返回这些值:

const exampleData = [34, 234, 73, 90, 6, 52];
d3.min(exampleData) // 返回 6
d3.max(exampleData) // 返回 234

const locationData = [[1, 7],[6, 3],[8, 3]];
// 返回第一个元素中的最小值s
const minX = d3.min(locationData, (d) => d[0]);
// 在 1,6,8 中 minX 为 1

<body>
  <script>
    const positionData = [[1, 7, -4],[6, 3, 8],[2, 8, 3]]
    const output = d3.max(positionData, d => d[2]);    // 8
    d3.select("body")
      .append("h2")
      .text(output)
  </script>
</body>

用 D3 实现数据可视化:使用动态比例

const dataset = [
  [ 34, 78 ],
  [ 109, 280 ],
  [ 310, 120 ],
  [ 79, 411 ],
  [ 420, 220 ],
  [ 233, 145 ],
  [ 333, 96 ],
  [ 222, 333 ],
  [ 78, 320 ],
  [ 21, 123 ]
];
const w = 500;
const h = 500;
// SVG 画布边缘和散点图之间的 padding
const padding = 30;
const xScale = d3.scaleLinear()
  .domain([0, d3.max(dataset, (d) => d[0])])
  .range([padding, w - padding]);

<body>
  <script>
    const dataset = [
                  [ 34,    78 ],
                  [ 109,   280 ],
                  [ 310,   120 ],
                  [ 79,    411 ],
                  [ 420,   220 ],
                  [ 233,   145 ],
                  [ 333,   96 ],
                  [ 222,   333 ],
                  [ 78,    320 ],
                  [ 21,    123 ]
                ];
    const w = 500;
    const h = 500;
    // SVG 画布边缘和图形之间的padding
    const padding = 30;
    // 创建 x 和 y 的比例尺
    const xScale = d3.scaleLinear()
                    .domain([0, d3.max(dataset, (d) => d[0])])
                    .range([padding, w - padding]);
    const yScale = d3.scaleLinear()
                    .domain([0, d3.max(dataset, d => d[1])])
                    .range([h - padding, padding])               
    const output = yScale(411); // 返回 30
    d3.select("body")
      .append("h2")
      .text(output)
  </script>
</body>
// 正向布局,当你为 y 坐标设置 range 时,
// 大的值(height 减去 padding)是第一个参数,小的值是第二个参数。

用 D3 实现数据可视化:使用预定义的比例放置元素

用比例尺函数为 SVG 图形设置坐标属性值。这包括rect或者text元素的xy属性,或者circlescxcy。以下是一个例子:

shape
  .attr("x", (d) => xScale(d[0]))

<body>
  <script>
    const dataset = [
                  [ 34,     78 ],
                  [ 109,   280 ],
                  [ 310,   120 ],
                  [ 79,   411 ],
                  [ 420,   220 ],
                  [ 233,   145 ],
                  [ 333,   96 ],
                  [ 222,    333 ],
                  [ 78,    320 ],
                  [ 21,   123 ]
                ];
    const w = 500;
    const h = 500;
    const padding = 60;
    const xScale = d3.scaleLinear()
                     .domain([0, d3.max(dataset, (d) => d[0])])
                     .range([padding, w - padding]);
    const yScale = d3.scaleLinear()
                     .domain([0, d3.max(dataset, (d) => d[1])])
                     .range([h - padding, padding]);
    const svg = d3.select("body")
                  .append("svg")
                  .attr("width", w)
                  .attr("height", h);
    // 创建离散的圆点
    svg.selectAll("circle")
       .data(dataset)
       .enter()
       .append("circle")
       .attr("cx", d => xScale(d[0]))
       .attr("cy", d => yScale(d[1]))  
       .attr("r", 5)
    // 创建文本
    svg.selectAll("text")
       .data(dataset)
       .enter()
       .append("text")
       .text((d) =>  (d[0] + ", "
 + d[1]))
       .attr("x", d => xScale(d[0] + 10))
       .attr("y", d => yScale(d[1]))     
  </script>
</body>

用 D3 实现数据可视化:添加坐标轴到可视化中

另一种改进散点图的方法是添加 x 轴和 y 轴。D3 有两种方法来渲染 y 轴和 x 轴,分别是axisLeftaxisBottomconst xAxis = d3.axisBottom(xScale);

第一步,在 SVG 画布上渲染 x 轴。为此,你可以使用一个常见的 SVG 组件,g元素,g是英文中组(group)的缩写。不同于rectcircletext,在渲染时,轴只是一条直线。因为它是一个简单的图形,所以可以用g

第二步,使用transforms属性将轴放置在 SVG 画布的正确位置上。否则,轴将会沿着 SVG 画布的边缘渲染,从而不可见。SVG 支持多种transforms,但是放置轴需要translate。当它应用在g元素上时,它根据给出的总量移动整组。下面是一个例子:

const xAxis = d3.axisBottom(xScale);
svg.append("g")
   .attr("transform", "translate(0, " + (h - padding) + ")")
   .call(xAxis);

<body>
  <script>
    const dataset = [
                  [ 34,     78 ],
                  [ 109,   280 ],
                  [ 310,   120 ],
                  [ 79,   411 ],
                  [ 420,   220 ],
                  [ 233,   145 ],
                  [ 333,   96 ],
                  [ 222,    333 ],
                  [ 78,    320 ],
                  [ 21,   123 ]
                ];
    const w = 500;
    const h = 500;
    const padding = 60;
    const xScale = d3.scaleLinear()
                     .domain([0, d3.max(dataset, (d) => d[0])])
                     .range([padding, w - padding]);
    const yScale = d3.scaleLinear()
                     .domain([0, d3.max(dataset, (d) => d[1])])
                     .range([h - padding, padding]);
    const svg = d3.select("body")
                  .append("svg")
                  .attr("width", w)
                  .attr("height", h);
    svg.selectAll("circle")
       .data(dataset)
       .enter()
       .append("circle")
       .attr("cx", (d) => xScale(d[0]))
       .attr("cy",(d) => yScale(d[1]))
       .attr("r", (d) => 5);
    svg.selectAll("text")
       .data(dataset)
       .enter()
       .append("text")
       .text((d) =>  (d[0] + "," + d[1]))
       .attr("x", (d) => xScale(d[0] + 10))
       .attr("y", (d) => yScale(d[1]))
    const xAxis = d3.axisBottom(xScale);
    svg.append("g")
       .attr("transform", "translate(0," + (h - padding) + ")")
       .call(xAxis);
    const yAxis = d3.axisLeft(yScale);
    svg.append("g")
       .attr("transform", "translate("+padding+", 0")
       .call(yAxis)
  </script>
</body>
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,607评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,047评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,496评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,405评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,400评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,479评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,883评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,535评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,743评论 1 295
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,544评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,612评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,309评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,881评论 3 306
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,891评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,136评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,783评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,316评论 2 342

推荐阅读更多精彩内容

  • d3 (核心部分)选择集d3.select - 从当前文档中选择一系列元素。d3.selectAll - 从当前文...
    谢大见阅读 3,419评论 1 4
  • 1.发现故事 本课讲述可视化用到的:叙事结构数据收集过程数据处理 2.新闻方法 给可视化添加语境围绕数据进行叙事 ...
    esskeetit阅读 2,777评论 0 2
  • Data Visualization with D3 D3: SVG中的jQurey 1. Add Documen...
    王策北阅读 751评论 0 2
  • 一、简介 1. D3是什么? D3(或D3.js) 是一个用来使用Web标准做数据可视化的JavaScript库。...
    朝朝_c53e阅读 813评论 0 2
  • 数据可视化是指使用图表、图形等可视化对象以更清晰、更有效的方式进行数据通信的技术。 在web上,有许多库可用来可视...
    天行无迹阅读 14,284评论 1 5