用 ES6 重写原生 JS 写出的代码遇到的一个问题,请教一下思路。

2018-09-02 10:57:27 +08:00
 Mascdo

目标是做条形图,要带排序功能。

一开始看的 demo 全都是原生 JS 写出来的,所以就用原生 JS 写出来了效果,但是题目要求用 OOP 的思想,再加上本来就要 webpack 打包,就开始重新写,但是发现了一些问题,不知道怎么解决

原生 JS 代码内容

构建 d3 参数
构建比例尺(但没有定义域)——>坐标轴
取 csv 数据{
	给比例尺添加定义域
	根据 比例尺定义域坐标 添加矩形形成条形图
	
 给 checkbox 添加排序事件
 
 事件方法{
 修改构建比例尺的定义域降序排列添加动画
 }
}

我的解决思路是这样的,之前看到一个写彩票的 demo,是把所有功能都写成类,最后一个 Lottery 类继承自所有功能类,生成实例就能运行,我也开始封装,封装一个 Makegraph 类,里面三个方法

Base Calculate Interface Time

继承上面 Lottery new xxx = Lottery(); It works!

  1. 画图 2.初始化(绑定事件) 3.定义事件

但是发现这样的思路存在问题,修改原来已经画好的内容要获取定义域,进行修改,我这样封装似乎从 3.事件里获取不到 1.画图 里面的定义域,更别提修改了,而且肯定只能改动构建成坐标轴的定义域,用 selector 获取也没用啊

所以想请教一下应该用什么样的思想来构造,这个问题想了大半天解决不出来。

附上 demo 的代码,写原生的思路是按它的来的 https://bl.ocks.org/mbostock/3885705

自己写半天写不出来的

import * as d3 from "d3";


class Makegraph{


  // initSort(){
  //   d3.select("input").on("change", change);
  // }

  draw_bar(){
    let margin = {top:40, right:40, bottom:40, left:40};
    let drawarea = {width: 550, height: 500};
    let width = drawarea.width - margin.left - margin.right;
    let height = drawarea.height - margin.top - margin.bottom;

    let svg = d3.selectAll(".draw-left")
                            .append('svg')
                            .attr('width', drawarea.width)
                            .attr('height', drawarea.height)
                            .append("g")
                            .attr("transform", `translate(${margin.left}, ${margin.top})`);

    d3.csv("./public/data.csv").then(function(data) {
      data.forEach((d)=>{
        d.money = +d.money;
        return d;
      });

      let xdomain = (data.map(function(d) { return d.city; }))
      let ydomain = [0, d3.max(data, function(d) { return d.money; })]

      let xScale = d3.scaleBand()
            .domain(xdomain)
            .rangeRound([0, width]).padding(0.1);

      let yScale = d3.scaleLinear()
          .domain(ydomain)
          .range([height, 0]);

      let xAxis = d3.axisBottom(xScale);
      let yAxis = d3.axisLeft(yScale);

      svg.append("g")
            .attr("class", "x_axis")
            .attr("transform", `translate(0, ${height})`)
            .call(xAxis);

      svg.append("g")
              .attr("class", "axis")
              .call(yAxis)
              .append("text")
              .attr("transform", "rotate(-90)")
              .attr("y", 6)
              .attr("dy", "0.71em")
              .attr("text-anchor", "end")
              .text("money");

      svg.selectAll(".bar")
              .data(data)
              .enter().append("rect")
              .attr("class", "bar")
              .attr("x", (d) => xScale(d.city))
              .attr("y", (d) => yScale(d.money))
              .attr("width", xScale.bandwidth())
              .attr("height", (d)=> (height - yScale(d.money)))
              .attr("fill","steelblue");

      });
    }

}

3444 次点击
所在节点    JavaScript
1 条回复
oswuhan
2018-09-02 11:29:53 +08:00
提供两种常见思路。
一是是在全局作用域提供“画图”的访问方法,例如定义一个对象或者数组字面量保存对画图对象的引用;
二是使用 promise 与 async/await 处理事件;

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/485322

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX