D3-Exploration Step2

创建一个BarChart

普通的做法:

const rects = d3.select('svg')
    .selectAll('rect')
    .data([100, 200, 300])
    .enter()
    .append('rect');
const BAR_WIDTH = 10;
const COLORS = ['red', 'yellow', 'green'];
rects.attr('x', (d, i) => {
    return i * BAR_WIDTH * (5/4);
}).attr('y', (d, i) => {

}).attr('width', BAR_WIDTH)
.attr('height', d => d)
.attr('fill', (d, i) => COLORS[i] );

D3-Exploration Step2_第1张图片

CodePen

我们可以看到添加属性的时候都需要attr(name, value)这样的操作,所以我尝试将其封装了一下:

BaseChart

用法

  1. 实现我们的具体Chart类,实现initChart方法

    class BarChart extends BaseChart {
    
      constructor(opts: IBaseChartOpts) {
        super(opts);
      }
    
      initChart() {
        this.d3Svg = this.d3Svg
          .selectAll("rect")
          .data(this.data)
          .enter()
          .append("rect");
      }
    }
  2. 使用BarChart创建我们的Bar图表

      const bar = new BarChart({
        container: svgContainer, // 这里是上一篇创建的svgContainer
        data: [{Count: 100, Name: 'a' }, {Count: 200, Name: 'b' }],
      });
    
      bar
        .x((d, i: number) => {
          return (i + 1) * 40 + 10;
        })
        .y(0)
        .width(BAR_WIDTH)
        .height(d => d.Count)
        .fill((d, i) => COLORS[i]);
    
      bar
        .text(d => {
          return d.Name;
        })
        .x((d, i: number) => {
          return (i + 1) * 40 + 10;
        })
        .y(0);

    注: 这里的代码都是示范

BaseChart 源码

/**
 * @class d3-base-chart
 */
abstract class BaseChart extends AbstractChart {

  d3Svg: ID3Svg;
  data: any[];

  constructor(opts: IBaseChartOpts) {
    super();
    this.d3Svg = opts.container;
    this.data = opts.data || [];
    this.initChart();
  }

 abstract initChart(): void;

  x(fn: Function | Primitive) {
    this.d3Svg = this.d3Svg.attr("x", (d, i: number) => {
      return mormalizeToFn(fn)(d, i);
    });
    return this;
  }

  y(fn: Function | Primitive) {
    this.d3Svg = this.d3Svg.attr("y", (d, i: number) => {
      return mormalizeToFn(fn)(d, i);
    });
    return this;
  }

  width(fn: Function | Primitive) {
    this.d3Svg = this.d3Svg.attr("width", (d, i: number) => {
      return mormalizeToFn(fn)(d, i);
    });
    return this;
  }

  height(fn: Function | Primitive) {
    this.d3Svg = this.d3Svg.attr("height", (d, i: number) => {
      return mormalizeToFn(fn)(d, i);
    });
    return this;
  }

  fill(fn: Function | string) {
    this.d3Svg = this.d3Svg.attr("fill", (d, i: number) => {
      return mormalizeToFn(fn)(d, i);
    });
    return this;
  }

  text(fn: Function | string) {
    this.d3Svg = this.d3Svg
    .select("text")
    .data(this.data)
    .enter()
    .append("text")
    .text((d, i: number) => {
      return mormalizeToFn(fn)(d, i);
    });

    // 默认text位置
    this.x((d, i: number) => {
      return (i + 1) * 40 + 10;
    })
    .y(d => {
      return 5;
    })
    .fill(d => {
      return "#999";
    });;
    return this;
  }
}

/**
 * @class isFunction
 * @desc determined whether the fn is a Funciton,
 *        - if true return fn, 
 *        - else transform to a function return fn;
 */
function mormalizeToFn(fn: Function|Primitive): Function {
  if (typeof fn === "function") {
    return fn;
  } else {
    return () => {
      return fn; 
    };
  }
}

详细代码: Github

你可能感兴趣的:(d3)