d3#scaleLinear TypeScript Examples

The following examples show how to use d3#scaleLinear. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: AniCreator.ts    From anichart.js with MIT License 6 votes vote down vote up
export function createAni<T extends Component>(
  keyFrames: T[],
  keyTimes: number[] = [0, 1],
  ease: (n: number) => number = easeLinear
): Ani {
  const scale = scaleLinear(keyTimes, keyFrames)
    .interpolate(easeInterpolate(ease))
    .clamp(true);
  const ani = new Ani();
  ani.getComponent = (i) => {
    return scale(i);
  };
  return ani;
}
Example #2
Source File: BarChart.ts    From anichart.js with MIT License 6 votes vote down vote up
getScaleX(currentData: any[]) {
    let scaleX: ScaleLinear<number, number, never>;
    let domain: number[];
    if (this.domain != undefined) {
      domain = this.domain(currentData);
    } else if (this.visualRange != "history") {
      const [_, max] = extent(currentData, (d) => d[this.valueField]);
      domain = [0, max];
    } else {
      domain = [0, max(this.data, (d) => d[this.valueField])];
    }
    scaleX = scaleLinear(domain, [
      0,
      this.shape.width -
        this.margin.left -
        this.barPadding -
        this.labelPlaceholder -
        this.totalRankPlaceHolder -
        this.margin.right -
        this.valuePlaceholder,
    ]);
    return scaleX;
  }
Example #3
Source File: Ease.ts    From anichart.js with MIT License 6 votes vote down vote up
export function customInOut(
  time: [number, number, number, number],
  range: [number, number] = [0, 1],
  interruption = [easeCubicOut, easeCubicOut]
) {
  const scaleIn = scaleLinear([time[0], time[1]], range).interpolate(
    easeInterpolate(interruption[0])
  );
  const scaleOut = scaleLinear([time[3], time[2]], range).interpolate(
    easeInterpolate(interruption[1])
  );

  return (normalizedTime: number) => {
    if (normalizedTime < time[0]) {
      return range[0];
    } else if (normalizedTime > time[3]) {
      return range[0];
    } else if (normalizedTime < time[1]) {
      return scaleIn(normalizedTime);
    } else if (normalizedTime > time[2]) {
      return scaleOut(normalizedTime);
    } else {
      return range[1];
    }
  };
}
Example #4
Source File: MapChart.ts    From anichart.js with MIT License 6 votes vote down vote up
constructor(options: MapChartOptions = {}) {
    super(options);
    this.margin = options?.margin ?? {
      top: 20,
      left: 20,
      right: 20,
      bottom: 20,
    };
    this.visualMap = options.visualMap ?? interpolateInferno;
    this.getMapId = options.getMapId ?? ((id) => id);
    this.mapIdField = options.mapIdField ?? "alpha3Code";
    this.strokeStyle = options.strokeStyle ?? "#FFF";
    this.defaultFill = options.defaultFill ?? "#FFF1";
    this.projectionType = options.projectionType ?? "natural";
    this.useShadow = options.useShadow ?? false;
    this.pathShadowColor = options.pathShadowColor;
    this.pathShadowBlur = options.pathShadowBlur ?? 100;
    this.showGraticule = options.showGraticule ?? false;
    this.showLabel = options.showLabel ?? false;
    this.noDataLabel = options.noDataLabel ?? undefined;
    this.labelPadding = options.labelPadding ?? 8;
    this.labelSize = options.labelSize ?? 12;
    if (options.labelFormat) this.labelFormat = options.labelFormat;
    this.labelAlphaScale =
      options.labelAlphaScale ?? scaleLinear([400, 560], [0, 1]).clamp(true);
  }
Example #5
Source File: MapChart.ts    From anichart.js with MIT License 6 votes vote down vote up
updateScale(sec: number) {
    [this.currentMin, this.currentMax] = extent(
      this.getCurrentData(sec),
      (d) => d[this.valueField]
    );
    if (this.currentMax > this.historyMax) {
      this.historyMax = this.currentMax;
    }
    if (this.historyMin > this.currentMin) {
      this.historyMin = this.currentMax;
    }
    if (!this.visualRange || typeof this.visualRange === "string") {
      switch (this.visualRange) {
        case "total":
          this.scale = scaleLinear(
            [this.totallyMin, this.totallyMax],
            [0, 1]
          ).clamp(true);
          break;
        case "history":
          this.scale = scaleLinear(
            [this.historyMin, this.historyMax],
            [0, 1]
          ).clamp(true);
        default:
          this.scale = scaleLinear(
            [this.currentMin, this.currentMax],
            [0, 1]
          ).clamp(true);
          break;
      }
    } else {
      this.scale = scaleLinear(this.visualRange, [0, 1]).clamp(true);
    }
  }
Example #6
Source File: BaseChart.ts    From anichart.js with MIT License 6 votes vote down vote up
protected getScalesBySec(sec: number) {
    const currentData = this.getCurrentData(sec);
    let [minValue, maxValue] = extent(currentData, (d) => d[this.valueField]);

    if (this.historyMax > maxValue) {
      maxValue = this.historyMax;
    }
    if (this.historyMin < minValue) {
      minValue = this.historyMin;
    }
    const trueSec =
      sec < this.aniTime[0]
        ? this.aniTime[0]
        : sec > this.aniTime[1]
        ? this.aniTime[1]
        : sec;
    const scales = {
      x: scaleLinear(
        [this.aniTime[0], trueSec],
        [0, this.shape.width - this.margin.left - this.margin.right]
      ),
      y: scaleLinear(
        [minValue, maxValue],
        [this.shape.height - this.margin.top - this.margin.bottom, 0]
      ),
    };
    return scales;
  }
Example #7
Source File: BaseChart.ts    From anichart.js with MIT License 6 votes vote down vote up
private setAlphaScale() {
    this.alphaScale = scaleLinear(
      [
        this.aniTime[0] - this.freezeTime[0] - this.fadeTime[0],
        this.aniTime[0] - this.freezeTime[0],
        this.aniTime[1] + this.freezeTime[1],
        this.aniTime[1] + this.freezeTime[1] + this.fadeTime[1],
      ],
      [this.fadeTime[0] ? 0 : 1, 1, 1, this.fadeTime[1] ? 0 : 1]
    ).clamp(true);
  }
Example #8
Source File: AniCreator.ts    From anichart.js with MIT License 6 votes vote down vote up
getComponent(sec: number): Component | null {
    // [0, 3, 6]
    let rIdx = bisectLeft(this.keyTimes, sec);
    if (rIdx >= this.keyFrames.length) {
      rIdx = this.keyFrames.length - 1;
    }
    const lIdx = rIdx - 1;
    if (lIdx < 0) {
      return null;
    }
    const eIdx = lIdx >= this.eases.length ? this.eases.length - 1 : lIdx;
    const scale = scaleLinear(
      [this.keyTimes[lIdx], this.keyTimes[rIdx]],
      [this.keyFrames[lIdx], this.keyFrames[rIdx]]
    )
      .interpolate(easeInterpolate(this.eases[eIdx]))
      .clamp(true);
    return scale(sec);
  }
Example #9
Source File: BarChart.ts    From anichart.js with MIT License 6 votes vote down vote up
getScaleX(currentData: any[]) {
    let scaleX: ScaleLinear<number, number, never>;
    let domain: number[];
    if (this.domain != undefined) {
      domain = this.domain(currentData);
    } else if (this.visualRange != "history") {
      const [_, max] = extent(currentData, (d) => d[this.valueField]);
      domain = [0, max];
    } else {
      domain = [0, max(this.data, (d) => d[this.valueField])];
    }
    scaleX = scaleLinear(domain, [
      0,
      this.shape.width -
        this.margin.left -
        this.barPadding -
        this.labelPlaceholder -
        this.totalRankPlaceHolder -
        this.margin.right -
        this.valuePlaceholder,
    ]);
    return scaleX;
  }
Example #10
Source File: BaseChart.ts    From anichart.js with MIT License 6 votes vote down vote up
private setDataScales() {
    // 整体日期范围
    const dateExtent = extent(this.data, (d) => d[this.dateField]);
    // 播放进度到日期的映射
    this.secToDate = scaleLinear(this.aniTime, dateExtent).clamp(true);
    const g = group(this.data, (d) => d[this.idField]);
    const dataScales = new Map();
    g.forEach((dataList, k) => {
      dataList.sort(
        (a, b) => a[this.dateField].getTime() - b[this.dateField].getTime()
      );
      // 插入 NaN
      this.insertNaN(dataList, dateExtent);
      // 可优化: 删掉连续的重复值
      // FIXME: 此处有BUG。目前的实现,会干掉连续两个重复值的后一个。
      // 然而只有出现连续的三个重复值,才能忽略了中间的一个重复值。
      // if (true) {
      //   let temp: any[] = [];
      //   temp.push(dataList[0]);
      //   for (let i = 1; i < dataList.length; i++) {
      //     if (
      //       dataList[i][this.valueField] != dataList[i - 1][this.valueField]
      //     ) {
      //       temp.push(dataList[i]);
      //     }
      //   }
      //   temp.push(dataList[dataList.length - 1]);
      //   dataList = temp;
      // }
      const dateList = dataList.map((d) => d[this.dateField]);
      const secList = dateList.map((d) => this.secToDate.invert(d));
      // 线性插值
      const dataScale = scaleLinear(secList, dataList).clamp(true);
      dataScales.set(k, dataScale);
    });
    this.dataScales = dataScales;
  }
Example #11
Source File: TextAni.ts    From anichart.js with MIT License 6 votes vote down vote up
getComponent(sec: number) {
    const scale = scaleLinear(
      [
        this.time,
        this.time + this.fade,
        this.time + this.last - this.fade,
        this.time + this.last,
      ],
      [0, 1, 1, 0]
    ).clamp(true);
    this.component.alpha = scale(sec);
    switch (this.type) {
      case "blur":
        this.component.filter = `blur(${(1 - scale(sec)) * this.blur}px)`;
        break;
      case "rise":
        this.component.offset = { x: 0, y: (1 - scale(sec)) * this.rise };
        break;
    }
    return this.component;
  }
Example #12
Source File: Progress.ts    From anichart.js with MIT License 6 votes vote down vote up
getComponent(sec: number) {
    const val = scaleLinear(this.aniTime, [0, 100])
      .clamp(true)
      .interpolate(easeInterpolate(easePolyOut.exponent(5)))(sec);

    const label = format("d")(val);
    const res = this.ani.getComponent(sec);
    const textLabel = new Text({
      text: val === 100 ? `` : `Loading ${label} %`,
      font,
      fontSize: 24,
      textAlign: "center",
      textBaseline: "top",
      position: { x: 0, y: this.shape.height },
      fillStyle: "#fff",
    });
    res?.children.push(textLabel);
    return res;
  }
Example #13
Source File: AniCreator.ts    From anichart.js with MIT License 6 votes vote down vote up
export function getFadeAni(
  obj: Component | Ani,
  options?: { startSec?: number; durationSec?: number; fadeSec?: number }
) {
  const startSec = options?.startSec ?? 0;
  const durationSec = options?.durationSec ?? 3;
  const fadeSec = options?.fadeSec ?? 1;
  const alphaScale = scaleLinear(
    [
      startSec,
      startSec + fadeSec,
      startSec + durationSec - fadeSec,
      startSec + durationSec,
    ],
    [0, 1, 1, 0]
  ).clamp(true);
  return getFadeWrapped(obj, alphaScale);
}
Example #14
Source File: MapChart.ts    From anichart.js with MIT License 5 votes vote down vote up
scale: ScaleLinear<number, number, never>;
Example #15
Source File: MapChart.ts    From anichart.js with MIT License 5 votes vote down vote up
labelAlphaScale: ScaleLinear<number, number, never>;
Example #16
Source File: BarChart.d.ts    From anichart.js with MIT License 5 votes vote down vote up
getScaleX(currentData: any[]): ScaleLinear<number, number, never>;
Example #17
Source File: BaseChart.d.ts    From anichart.js with MIT License 5 votes vote down vote up
protected getScalesBySec(sec: number): {
        x: ScaleLinear<number, number, never>;
        y: ScaleLinear<number, number, never>;
    };
Example #18
Source File: MapChart.d.ts    From anichart.js with MIT License 5 votes vote down vote up
labelAlphaScale: ScaleLinear<number, number, never>;
Example #19
Source File: BaseChart.d.ts    From anichart.js with MIT License 5 votes vote down vote up
protected getAxisComponent(format: (v: number | {
        valueOf(): number;
    }) => string, scale0: ScaleLinear<number, number, never>, scale1: ScaleLinear<number, number, never>, pos: number, count: number, text: TextOptions, type: "x" | "y", sec: number, secRange: [number, number], scale: ScaleLinear<number, number, never>): Component;
Example #20
Source File: BaseChart.d.ts    From anichart.js with MIT License 5 votes vote down vote up
alphaScale: ScaleLinear<number, number, never>;
Example #21
Source File: BaseChart.d.ts    From anichart.js with MIT License 5 votes vote down vote up
secToDate: ScaleLinear<any, any, never>;
Example #22
Source File: LineChart.d.ts    From anichart.js with MIT License 5 votes vote down vote up
protected getScalesBySec(sec: number): {
        x: ScaleLinear<number, number, never>;
        y: ScaleLinear<number, number, never>;
    };
Example #23
Source File: LineChart.d.ts    From anichart.js with MIT License 5 votes vote down vote up
scales: {
        x: ScaleLinear<number, number, never>;
        y: ScaleLinear<number, number, never>;
    };
Example #24
Source File: MapChart.d.ts    From anichart.js with MIT License 5 votes vote down vote up
scale: ScaleLinear<number, number, never>;
Example #25
Source File: LineChart.ts    From anichart.js with MIT License 5 votes vote down vote up
scales: {
    x: ScaleLinear<number, number, never>;
    y: ScaleLinear<number, number, never>;
  };
Example #26
Source File: BaseChart.ts    From anichart.js with MIT License 5 votes vote down vote up
secToDate: ScaleLinear<any, any, never>;
Example #27
Source File: BaseChart.ts    From anichart.js with MIT License 5 votes vote down vote up
alphaScale: ScaleLinear<number, number, never>;
Example #28
Source File: BaseChart.ts    From anichart.js with MIT License 5 votes vote down vote up
protected getAxisComponent(
    format: (v: number | { valueOf(): number }) => string,
    scale0: ScaleLinear<number, number, never>,
    scale1: ScaleLinear<number, number, never>,
    pos: number,
    count: number,
    text: TextOptions,
    type: "x" | "y",
    sec: number,
    secRange: [number, number],
    scale: ScaleLinear<number, number, never>
  ) {
    const alpha = (sec - secRange[0]) / (secRange[1] - secRange[0]);
    const ticks0 = scale0.ticks(count);
    const ticks1 = scale1.ticks(count);
    const ticks: { v: number; a: number; init: number }[] = [
      ...ticks0.map((t) => {
        if (ticks1.find((d) => d === t)) {
          return { v: t, a: 1, init: 0 };
        } else {
          return { v: t, a: 1 - alpha, init: 0 };
        }
      }),
    ];

    ticks1.forEach((tickVal) => {
      const tick = ticks.find((d) => d.v === tickVal);
      if (tick) {
        tick.a = 1;
      } else {
        ticks.push({ v: tickVal, a: alpha, init: 1 });
      }
    });
    const res = new Component({
      position: {
        x: this.margin.left + this.yAxisWidth + this.yAxisPadding,
        y: this.margin.top + this.xAxisHeight + this.xAxisPadding,
      },
    });
    res.children = ticks.map((tick) => {
      const t = new Text(text);
      if (type === "y") {
        t.position = { y: scale(tick.v), x: -this.yAxisPadding };
        t.textAlign = "right";
        t.textBaseline = "middle";
      } else {
        t.position = { x: scale(tick.v), y: -this.xAxisPadding };
        t.textBaseline = "bottom";
        t.textAlign = "center";
      }
      // t.children.push(
      //   new Rect({
      //     shape: { width: 10, height: 1 },
      //     fillStyle: "#Fff",
      //   })
      // );
      t.text = format(tick.v);
      t.alpha = tick.a;
      return t;
    });
    return res;
  }
Example #29
Source File: BarChart.ts    From anichart.js with MIT License 5 votes vote down vote up
private getBarOptions(
    data: any,
    scaleX: ScaleLinear<number, number, never>,
    count: number
  ): BarOptions {
    const cFrame = this.stage!.frame;
    const hisIndex = this.getTotalHistoryByID(data[this.idField]);
    let idx = this.getBarIdx(hisIndex, cFrame);

    // 判断这一帧,柱状条是否在上升
    let isUp = this.barIsUp(cFrame, hisIndex);
    let alpha = scaleLinear([-1, 0, count - 1, count], [0, 1, 1, 0]).clamp(
      true
    )(idx);
    if (Number.isNaN(data[this.valueField])) {
      alpha = 0;
    }
    // 保存非 NaN 数据
    if (!Number.isNaN(data[this.valueField])) {
      this.lastValue.set(data[this.idField], data[this.valueField]);
    } else {
      // 如果当前数据就是 NaN,则使用上次的数据
      data[this.valueField] = this.lastValue.get(data[this.idField]);
    }
    data[this.valueField] = this.lastValue.get(data[this.idField]);
    let color: string;
    if (typeof this.colorField === "string") {
      color = data[this.colorField];
    } else {
      color = this.colorField(
        data[this.idField],
        this.meta,
        this.dataGroupByID
      );
    }
    const image =
      typeof this.imageField === "string"
        ? data[this.imageField]
        : this.imageField(data[this.idField], this.meta, this.dataGroupByID);
    return {
      id: data[this.idField],
      pos: {
        x: this.getBarX(),
        y: this.getBarY(idx),
      },
      alpha,
      data,
      image,
      isUp,
      value: data[this.valueField],
      shape: { width: scaleX(data[this.valueField]), height: this.barHeight },
      color: colorPicker.getColor(color),
      radius: 4,
    };
  }