V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐关注
Meteor
JSLint - a JavaScript code quality tool
jsFiddle
D3.js
WebStorm
推荐书目
JavaScript 权威指南第 5 版
Closure: The Definitive Guide
Mascdo
V2EX  ›  JavaScript

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

  •  
  •   Mascdo · 2018-09-02 10:57:27 +08:00 · 3631 次点击
    这是一个创建于 2282 天前的主题,其中的信息可能已经有所发展或是发生改变。

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

    一开始看的 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");
    
          });
        }
    

    }

    1 条回复    2018-09-02 11:29:53 +08:00
    oswuhan
        1
    oswuhan  
       2018-09-02 11:29:53 +08:00
    提供两种常见思路。
    一是是在全局作用域提供“画图”的访问方法,例如定义一个对象或者数组字面量保存对画图对象的引用;
    二是使用 promise 与 async/await 处理事件;
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2576 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 03:30 · PVG 11:30 · LAX 19:30 · JFK 22:30
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.