Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

关于折线图上的原点平滑移动的实现 #91

Open
ckinmind opened this issue May 31, 2018 · 0 comments
Open

关于折线图上的原点平滑移动的实现 #91

ckinmind opened this issue May 31, 2018 · 0 comments

Comments

@ckinmind
Copy link
Owner

ckinmind commented May 31, 2018

参考资料

核心代码部分

function mousemove() {
      const x0 = x.invert(d3.mouse(this)[0]) // x轴坐标, 时间值
      const i = bisectDate(data, x0, 1) // 使用访问器和比较器二分查找, 判断当前的落点距离那个实际值更加接近,并且有限选择左边的值
      const d0 = data[i - 1] // 测试发现i从1开始(上面第三个参数是0是1都一样), bisectDate方法的第三个参数可以指定开始index
      const d1 = data[i]  // d0 d1是要插入的前后数据



      // 根据鼠标位置控制tooltip显示在左边还是右边
      if (d3.mouse(this)[0] < (width / 2)) {
        svgTooltips
          .transition()
          .duration(150)
          .ease(d3.easeLinear)
          .style('left', 'auto')
          .style('right', '0')
      } else {
        svgTooltips.transition()
          .duration(150)
          .ease(d3.easeLinear)
          .style('left', '0')
          .style('right', 'auto')
      }


      // 到最右边之后d1会是undefined
      if (d1) {
        const d = x0 - d0.date > d1.date - x0 ? d1 : d0
        const formatDate = d3.timeFormat("%d %b %Y")
        svgTooltips.select("text.tiptxt1").text(formatDate(d.date))
        svgTooltips.select("text.tiptxt2").text(`${Math.round(d.value / 10)}%`)

        // 这里这个path就是上面不知道干嘛用隐藏起来的path
        const pathEl = path.node()
//         console.log(pathEl)
        const pathLength = pathEl.getTotalLength() // 这个是用来获取路径长度的,只适用于path,在path动画里用过这个
        const BBox = pathEl.getBBox()  // 返回给定元素的边界框描述,这里是返回path元素的水平距离
        const scale = pathLength / BBox.width
        const offsetLeft = document.getElementById("cc").offsetLeft // 获取相对于父对象的左边距,这里基本是指导页面左边距了,因为父对象是body

        console.log('-----pathLength', pathLength)
        console.log('-----BBox', BBox)
//        console.log('-----scale', scale)
        console.log('-----offsetLeft', offsetLeft)
        console.log('-----d3.event.pageX', d3.event.pageX)

        // pageX距离页面左边的距离,所以这里的xc应该是鼠标位置距离图左边的距离
        const xc = d3.event.pageX - (offsetLeft)
        let beginning = xc
        let end = pathLength
        let target

        console.log('--------xc', xc)

        // 没看懂这的平滑移动的算法
        while (true) {
          target = Math.floor((beginning + end) / 2)
          pos = pathEl.getPointAtLength(target) // 获取给定长度length在path的坐标 (x, y)
          // 如果target是末端/开始或者鼠标位置则break, why
          if ((target === end || target === beginning) && pos.x !== xc) {
            break
          }
          if (pos.x > xc) {
            end = target
          } else if (pos.x < xc) {
            beginning = target
          } else {
            break
          } //position found
        }

        // 选中移动的circe改变其位置
        focus.select("circle.y").attr("transform", `translate(${pos.x},${pos.y})`)

        // 改变移动circle下面线的位置
        focus.select(".x")
          .attr("transform", `translate(${pos.x},${pos.y})`)
          .attr("y2", height - y(d.value))

      }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant