freeCodeCamp旅途

freeCodeCamp 旅途17 - D3

2019-10-20  本文已影响0人  HJSD

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>
上一篇下一篇

猜你喜欢

热点阅读