d3#extent TypeScript Examples

The following examples show how to use d3#extent. 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: 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 #2
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 #3
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 #4
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 #5
Source File: LineChart.ts    From anichart.js with MIT License 5 votes vote down vote up
protected getScalesBySec(sec: number) {
    const currentData = this.getCurrentData(sec);
    let valueRange = extent(currentData, (d) => d[this.valueField] as number);
    if (valueRange[0] === undefined) {
      valueRange = [0, 0];
    }
    if (this.historyMax > valueRange[1]) {
      valueRange[1] = this.historyMax;
    }
    if (this.historyMin < valueRange[0]) {
      valueRange[0] = this.historyMin;
    }
    const delta = (valueRange[1] - valueRange[0]) * 0.1;
    valueRange[0] -= delta;
    valueRange[1] += delta;
    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 -
            this.yAxisWidth -
            this.yAxisPadding -
            this.labelPlaceholder -
            this.labelPadding -
            this.pointerR,
        ]
      ),
      y: scaleLinear(valueRange, [
        this.shape.height -
          this.margin.top -
          this.margin.bottom -
          this.xAxisHeight,
        this.xAxisPadding,
      ]),
    };
    return scales;
  }
Example #6
Source File: SleepChart.tsx    From nyxo-app with GNU General Public License v3.0 5 votes vote down vote up
SleepTimeChart: FC = () => {
  const data = useAppSelector(getNightsAsDays)
  const daysToShow = data.length
  const chartWidth = (barWidth + 10) * daysToShow + paddingLeft + paddingRight

  const xDomain: Date[] = extent(data, (date) => new Date(date.date)) as Date[]

  const yDomain: number[] = [
    min(data, (date) =>
      min(date.night, (night) =>
        subHours(new Date(night.startDate), 1).valueOf()
      )
    ) as number,
    max(data, (date) =>
      max(date.night, (night) => addHours(new Date(night.endDate), 1).valueOf())
    ) as number
  ]

  const scaleX = scaleTime()
    .domain(xDomain)
    .range([paddingLeft, chartWidth - paddingRight])

  const scaleY = scaleTime()
    .domain(yDomain)
    .nice()
    .range([10, chartHeight - 80])

  const yTicks = scaleY.ticks(5)
  const xTicks = scaleX.ticks(daysToShow)

  return (
    <Card>
      <Title>STAT.TREND</Title>

      <ScrollContainer>
        <YTicksContainer
          pointerEvents="auto"
          width={chartWidth}
          height={chartHeight}>
          <YTicks scaleY={scaleY} chartWidth={chartWidth} ticks={yTicks} />
        </YTicksContainer>
        <ScrollView
          style={{ transform: [{ scaleX: -1 }] }}
          horizontal
          showsHorizontalScrollIndicator={false}>
          <View style={{ transform: [{ scaleX: -1 }] }}>
            <Svg width={chartWidth} height={chartHeight}>
              {/* <TargetBars
                start={bedtimeWindow}
                onPress={select}
                barWidth={barWidth}
                scaleX={scaleX}
                scaleY={scaleY}
                data={normalizedSleepData}
              /> */}
              <SleepBars
                onPress={() => undefined}
                barWidth={barWidth}
                scaleX={scaleX}
                scaleY={scaleY}
                data={data}
              />

              <XTicks
                chartHeight={chartHeight}
                scaleX={scaleX}
                barWidth={barWidth}
                ticks={xTicks}
              />
            </Svg>
          </View>
        </ScrollView>
      </ScrollContainer>
    </Card>
  )
}
Example #7
Source File: SleepChart.tsx    From nyxo-website with MIT License 5 votes vote down vote up
SleepChart: FC<ChartProps> = ({ data }) => {
  const ref = useRef<HTMLDivElement>(null)

  useLayoutEffect(() => {
    ref.current?.scrollBy({ left: ref.current.offsetWidth })
  }, [])

  const { normalizedData } = useMemo(
    () => ({
      normalizedData: getNightAsDays(data),
    }),
    [data]
  )

  const daysToShow = normalizedData.length
  const chartWidth = (barWidth + 10) * daysToShow + paddingLeft + paddingRight

  const xDomain: Date[] = extent(
    normalizedData,
    (date) => new Date(date.date)
  ) as Date[]

  const yDomain: number[] = [
    min(normalizedData, (date) =>
      min(date.night, (night) =>
        subHours(new Date(night.startDate), 1).valueOf()
      )
    ) as number,
    max(normalizedData, (date) =>
      max(date.night, (night) => addHours(new Date(night.endDate), 1).valueOf())
    ) as number,
  ]

  const scaleX = scaleTime()
    .domain(xDomain)
    .range([paddingLeft, chartWidth - paddingRight])

  const scaleY = scaleTime()
    .domain(yDomain)
    .nice()
    .range([10, chartHeight - 80])

  const yTicks = scaleY.ticks(10)
  const xTicks = scaleX.ticks(daysToShow)

  return (
    <Container ref={ref}>
      <svg width={chartWidth} height={chartHeight}>
        <XTicks
          chartHeight={chartHeight}
          scaleX={scaleX}
          barWidth={barWidth}
          ticks={xTicks}
        />
        <SleepBars
          barWidth={barWidth}
          scaleX={scaleX}
          scaleY={scaleY}
          data={normalizedData}
        />

        <YTicks scaleY={scaleY} chartWidth={chartWidth} ticks={yTicks} />
      </svg>
    </Container>
  )
}