d3的学习与实践01

d3-study

Posted by EWL on December 11, 2018

内容要点

  • d3图表的一些更为复杂的操作,希望此次的学习内容可以在之后的分享里面为大家提供一些绘图和可视化操作上的思路,并且希望得到大家的指正和建议

内容详情这里

  1. 三种类型的图表绘制 image.png

image.png

image.png

三个图表对应的代码链接如下: 图1 图2 图3

  1. 相关的api记录(上一次学习总结中的api不再仔细介绍)
  • d3.extent(array[, accessor]) 用于求解范围,分别有两个参数,为数组array与读取数据的函数accessor,如果没有设置accessor,则直接从array中找到最大值最小值,作为输出范围,如果有accessor,则根据accessor函数自定义访问array中的数据。例如:
let x = d3.scaleTime()
  .domain(d3.extent(data, d => new Date(d.date)))
  .range([margin.left, width - margin.right]);

定义域domain函数中,d3.extent(data, d => new Date(d.date))表示我们需要从data数组中的读取每一个数组元素的date属性值,找出所有date中的最大值最小值作为最后输出的范围。

  • d3.max(array[, accessor]) 顾名思义,找到数组中的最大值,accessor同样是数据访问自定义方式。
  • pow.nice() 将输入范围扩展到漂亮的整数,如图一展示的纵坐标的范围就是通过nice调整到合适的范围,这个函数可以说是非常人性化了,不需要我们手动的计算合适的计数范围。
  • ticks 从比例尺的 domain 中返回具有代表性的日期刻度。但是此处还有一些细节的东西,需要详细描述,参考
  • tickSizeOuter 外侧刻度大小 image.png 在顶部的三个图中,外侧刻度均设置为0。

  • clone 复制元素。 图2可以看到在纵坐标处有一个我的步数的纵坐标图例。此处的图例text元素就是通过复制最顶部的纵坐标刻度14000得到的,重新设置xy位置,并填入新的文本,即可制作纵轴指示图例。此处参考了d3画廊observable上大师们的做法。大师的作品
  • defined 缺省访问器,使用方式如下图。在编写折线生成器的时候,过滤掉份非数字的坐标,可以有效的防止图线断裂或绘制失败的情况发生。
let line = d3.line()
  .defined(d => !isNaN(d.value)) // 防止出现非数字值导致的图线断裂
  .x(d => x(new Date(d.date)))
  .y(d => y(d.value));
  • call(熟悉的call/apply/bind)
  • tickFormat
  • d3.timeFormat (坐标的自定义显示格式,此处用在了横坐标时间的格式化上,可以看到顶部三个图的横轴时间格式是不同的)
// 图2
let xAxis = g => g
  .attr("transform", `translate(0,${height - margin.bottom})`)
  .call(d3.axisBottom(x)
    .ticks(width / 80)
    .tickSizeOuter(0)
    .tickFormat(d3.timeFormat('%Y-%m-%d'))
  )
  .call(g => g.selectAll('.tick text')
    .attr('y', 10)
    .attr('x', 30)
    .attr('transform', 'rotate(25)')
  );
// 图3
let xAxis = g => g
  .attr("transform", `translate(0,${height - margin.bottom})`)
  .call(d3.axisBottom(x)
    .ticks(width / 80)
    .tickSizeOuter(0)
    .tickFormat(d3.timeFormat('%Y年%m月%d日'))
  )
  .call(g => g.selectAll('.tick text')
    .attr('y', 10)
    .attr('x', 30)
    .attr('transform', 'rotate(25)')
  );