简体   繁体   中英

Cannot set scale type to custom scale in ChartJS

I followed the ChartJS documentation for creating a custom scale: https://www.chartjs.org/docs/master/samples/advanced/derived-axis-type.html

First I defined the custom scale as its own class extending the base Scale interface:

import { Scale, LinearScale, BubbleDataPoint, Chart, ChartTypeRegistry, ScatterDataPoint} from 'chart.js';



export default class SquareRootAxis extends Scale {
    static defaults: {} = {};
    _startValue: any;
    _valueRange: number;
    constructor(cfg: { id: string; type: string; ctx: CanvasRenderingContext2D; chart: Chart<keyof ChartTypeRegistry, (number | ScatterDataPoint | BubbleDataPoint)[], unknown>; }) {
      super(cfg);
      this._startValue = undefined;
      this._valueRange = 0;
    }
  
    parse(raw: any, index: number) {
      const value = LinearScale.prototype.parse.apply(this, [raw, index]);
      return isFinite(value) && value > 0 ? value : null;
    }
  
    determineDataLimits() {
      this.min = 0.5
      this.max=31
    }

    buildTicks() {
        const userDefinedTicks = [1, 2, 3, 5, 7, 10, 15, 20, 25, 30];
        const ticks = [];
        for (const tick of userDefinedTicks) {
            ticks.push({
                value: tick
            });
        }
        return ticks;
    }
  
    /**
     * @protected]
     */
    configure() {
      const start = this.min;
  
      super.configure();
      this._startValue = Math.pow(start, 1/2);
      this._valueRange = Math.pow(this.max, 1/2) - Math.pow(start, 1/2);
    }
  
    getPixelForValue(value: number | undefined) {
      if (value === undefined ) {
        value = this.min;
      }
  
      return this.getPixelForDecimal(value === this.min ? 0 :
        (Math.pow(value, 1/2) - this._startValue) / this._valueRange);
    }
  
    getValueForPixel(pixel: number) {
      const decimal = this.getDecimalForPixel(pixel);
      return Math.pow(this._startValue + decimal * this._valueRange, 2);
    }
  }

I then imported the custom scale Class and used it below:

import {
  Chart as ChartJS,
  CategoryScale,
  LinearScale,
  PointElement,
  LineElement,
  Title,
  Tooltip,
  Legend,
} from 'chart.js';
import { Scatter } from 'react-chartjs-2';
import SquareRootAxis from './sqaureRootAxis';

ChartJS.register(
  CategoryScale,
  LinearScale,
  PointElement,
  LineElement,
  Title,
  Tooltip,
  Legend,
  CubeRootAxis
);

SquareRootAxis.id = 'squareRoot';

export function Chart(props: { chartData: ChartData }) {
  return <Scatter
    data={props.chartData}
    options={{
      responsive: true,
      scales: {
        x: {
          type: 'squareRoot',
        },
      },
    }}
  />;
}

But when I set my chart to the custom scale name, I get the following TS error:

Type '"squareRoot"' is not assignable to type '"time" | "linear" | "logarithmic" | "category" | "timeseries"'.ts(2322) index.esm.d.ts(3618, 27): The expected type comes from property 'type' which is declared here on type '_DeepPartialObject<{ type: "time"; } & Omit<CartesianScaleOptions

It seems despite following the docs, the ChartJS scale type only recognizes the built-in scales. What am I doing wrong?

First in the sample code it looks like you have a typo in your import:
import SquareRootAxis from './sqaureRootAxis .

Then it seems you need to register the new scale, which I cannot see in your code, as follows:

chart.register(SquareRootAxis);

For some reason this is commented at the bottom of the code in your link, and is also explained here:
https://www.chartjs.org/docs/latest/developers/axes.html

在此处输入图像描述

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM