fixed broken mounting hook

This commit is contained in:
Nate Kelley 2025-04-19 00:14:26 -06:00
parent 76ee025e01
commit 55e81fc155
No known key found for this signature in database
GPG Key ID: FD90372AB8D98B4F
11 changed files with 57 additions and 88 deletions

View File

@ -2,7 +2,7 @@
import './ChartJSTheme'; import './ChartJSTheme';
import React, { useRef, useState } from 'react'; import React, { useCallback, useRef, useState } from 'react';
import { DEFAULT_CHART_CONFIG, DEFAULT_COLUMN_METADATA } from '@/api/asset_interfaces/metric'; import { DEFAULT_CHART_CONFIG, DEFAULT_COLUMN_METADATA } from '@/api/asset_interfaces/metric';
import { BusterChartJSLegendWrapper } from './BusterChartJSLegendWrapper'; import { BusterChartJSLegendWrapper } from './BusterChartJSLegendWrapper';
import { ChartJSOrUndefined } from './core/types'; import { ChartJSOrUndefined } from './core/types';
@ -37,9 +37,9 @@ export const BusterChartJS: React.FC<BusterChartComponentProps> = ({
onChartMounted?.(); onChartMounted?.();
}); });
const onInitialAnimationEndPreflight = useMemoizedFn(() => { const onInitialAnimationEndPreflight = useCallback(() => {
onInitialAnimationEnd?.(); if (chartRef.current?.attached) onInitialAnimationEnd?.();
}); }, [onInitialAnimationEnd]);
return ( return (
<BusterChartJSLegendWrapper <BusterChartJSLegendWrapper

View File

@ -1,4 +1,6 @@
import React, { useMemo } from 'react'; 'use client';
import React, { useMemo, useState } from 'react';
import { import {
Chart, Chart,
ChartHoverBarPlugin, ChartHoverBarPlugin,
@ -184,10 +186,6 @@ export const BusterChartJSComponent = React.memo(
return []; return [];
}, [selectedChartType]); }, [selectedChartType]);
useMount(() => {
console.log('chartOptions', options);
});
return ( return (
<Chart <Chart
className={className} className={className}

View File

@ -20,8 +20,7 @@ import {
BubbleController, BubbleController,
PieController, PieController,
ScatterController, ScatterController,
DoughnutController, DoughnutController
registry
} from 'chart.js'; } from 'chart.js';
import { ChartMountedPlugin } from './core/plugins'; import { ChartMountedPlugin } from './core/plugins';
import ChartDeferred from 'chartjs-plugin-deferred'; import ChartDeferred from 'chartjs-plugin-deferred';
@ -34,8 +33,6 @@ import { truncateText } from '@/lib/text';
import './core/plugins/chartjs-scale-tick-duplicate'; import './core/plugins/chartjs-scale-tick-duplicate';
// Register the scale properly
const fontFamily = isServer const fontFamily = isServer
? 'Roobert_Pro' ? 'Roobert_Pro'
: getComputedStyle(document.documentElement).getPropertyValue('--font-sans'); : getComputedStyle(document.documentElement).getPropertyValue('--font-sans');

View File

@ -9,20 +9,27 @@ declare module 'chart.js' {
interface PluginOptionsByType<TType extends ChartType> { interface PluginOptionsByType<TType extends ChartType> {
chartMounted?: ChartMountedPluginOptions; chartMounted?: ChartMountedPluginOptions;
} }
interface Chart {
$mountedPlugin: boolean;
}
} }
export const ChartMountedPlugin: Plugin<ChartType, ChartMountedPluginOptions> = { export const ChartMountedPlugin: Plugin<ChartType, ChartMountedPluginOptions> = {
id: 'chartMounted', id: 'chartMounted',
afterInit: (chart, args, options) => { afterInit: (chart, args, options) => {
if (!chart || !options) return;
options?.onMounted?.(chart); options?.onMounted?.(chart);
chart.$mountedPlugin = true;
}, },
afterRender: (chart, args, options) => { afterRender: (chart, args, options) => {
if (chart.$mountedPlugin || !chart || !options) return;
const hasLabels = !!chart.data?.labels?.length; const hasLabels = !!chart.data?.labels?.length;
if (hasLabels) { if (hasLabels && options?.onInitialAnimationEnd) {
options?.onInitialAnimationEnd?.(chart); options?.onInitialAnimationEnd?.(chart);
chart.$mountedPlugin = true;
} }
}, },
defaults: { defaults: {
onMounted: () => {}, onMounted: () => {},
onInitialAnimationEnd: () => {} onInitialAnimationEnd: () => {}

View File

@ -21,43 +21,43 @@ declare module 'chart.js' {
} }
} }
// const originalBuildTicks = TimeScale.prototype.buildTicks; const originalBuildTicks = TimeScale.prototype.buildTicks;
// // // Override buildTicks // // // Override buildTicks
// TimeScale.prototype.buildTicks = function () { TimeScale.prototype.buildTicks = function () {
// // Generate default ticks // Generate default ticks
// const defaultTicks = originalBuildTicks.call(this); const defaultTicks = originalBuildTicks.call(this);
// // Access tick callback and display format // Access tick callback and display format
// const tickCallback = this.options.ticks?.callback; const tickCallback = this.options.ticks?.callback;
// const displayFormat = const displayFormat =
// this.options.time?.displayFormats?.[this._unit] || this.options.time?.displayFormats?.[this._unit] ||
// this.options.time?.displayFormats?.month || this.options.time?.displayFormats?.month ||
// 'MMM'; 'MMM';
// const format = this._adapter.format.bind(this._adapter); const format = this._adapter.format.bind(this._adapter);
// // Deduplicate ticks // Deduplicate ticks
// const seen = new Set(); const seen = new Set();
// const uniqueTicks = []; const uniqueTicks = [];
// for (let i = 0; i < defaultTicks.length; i++) { for (let i = 0; i < defaultTicks.length; i++) {
// const tick = defaultTicks[i]; const tick = defaultTicks[i];
// let label = tickCallback let label = tickCallback
// ? tickCallback.call(this, tick.value, i, defaultTicks) ? tickCallback.call(this, tick.value, i, defaultTicks)
// : format(tick.value, displayFormat); : format(tick.value, displayFormat);
// const stringLabel = String(label ?? ''); const stringLabel = String(label ?? '');
// if (!seen.has(stringLabel)) { if (!seen.has(stringLabel)) {
// seen.add(stringLabel); seen.add(stringLabel);
// uniqueTicks.push({ uniqueTicks.push({
// ...tick, ...tick,
// label: stringLabel label: stringLabel
// }); });
// } }
// } }
// // Set the filtered ticks on the axis instance // Set the filtered ticks on the axis instance
// this.ticks = uniqueTicks; this.ticks = uniqueTicks;
// return uniqueTicks; return uniqueTicks;
// }; };

View File

@ -160,7 +160,7 @@ export const useOptions = ({
const chartMounted = useMemo(() => { const chartMounted = useMemo(() => {
return { return {
onMounted: onChartReady, onMounted: onChartReady,
onInitialAnimationEnd: onInitialAnimationEnd onInitialAnimationEnd
}; };
}, [onChartReady, onInitialAnimationEnd]); }, [onChartReady, onInitialAnimationEnd]);

View File

@ -165,18 +165,6 @@ export const useXAxis = ({
return DEFAULT_X_AXIS_TICK_CALLBACK.call(this, value, index, this.getLabels() as any); return DEFAULT_X_AXIS_TICK_CALLBACK.call(this, value, index, this.getLabels() as any);
}); });
const tickCallback = useMemo(() => {
if (type === 'time') {
const isSingleXAxis = selectedAxis.x.length === 1;
const columnLabelFormat = xAxisColumnFormats[selectedAxis.x[0]];
const isDate = columnLabelFormat?.columnType === 'date';
const isAutoDate = columnLabelFormat?.dateFormat === 'auto' || !columnLabelFormat?.dateFormat;
const useAutoDate = isSingleXAxis && isDate && isAutoDate;
if (useAutoDate) return customTickCallback;
}
return customTickCallback;
}, [customTickCallback, type, selectedAxis.x, xAxisColumnFormats]);
const rotation = useMemo(() => { const rotation = useMemo(() => {
if (xAxisLabelRotation === 'auto' || xAxisLabelRotation === undefined) return undefined; if (xAxisLabelRotation === 'auto' || xAxisLabelRotation === undefined) return undefined;
return { return {
@ -230,7 +218,7 @@ export const useXAxis = ({
maxTicksLimit: type === 'time' ? (timeUnit === 'month' ? 12 : 18) : undefined, maxTicksLimit: type === 'time' ? (timeUnit === 'month' ? 12 : 18) : undefined,
sampleSize: type === 'time' ? 24 : undefined, sampleSize: type === 'time' ? 24 : undefined,
display: xAxisShowAxisLabel, display: xAxisShowAxisLabel,
callback: tickCallback as any, //I need to use null for auto date callback: customTickCallback as any, //I need to use null for auto date
//@ts-ignore //@ts-ignore
time: { time: {
unit: timeUnit unit: timeUnit
@ -244,14 +232,13 @@ export const useXAxis = ({
title, title,
isScatterChart, isScatterChart,
isPieChart, isPieChart,
tickCallback, customTickCallback,
xAxisShowAxisLabel, xAxisShowAxisLabel,
stacked, stacked,
type, type,
grid, grid,
timeUnit, timeUnit,
rotation, rotation
tickCallback
]); ]);
return memoizedXAxisOptions; return memoizedXAxisOptions;

View File

@ -388,7 +388,7 @@ const newRowPreflight = (newRows: BusterResizeableGridRow[]) => {
newRowsCopy = newRowsCopy.map((row, index) => { newRowsCopy = newRowsCopy.map((row, index) => {
const numberOfColumns = row.columnSizes?.length || 0; const numberOfColumns = row.columnSizes?.length || 0;
const numberOfItems = row.items.length; const numberOfItems = row.items.length;
// row.id = `${index + 1}`; //we use this instead of uuid because the api likes it better this way row.id = `${index + 1}`; //we use this instead of uuid because the api likes it better this way
if ( if (
numberOfItems !== numberOfColumns || numberOfItems !== numberOfColumns ||
row.columnSizes?.reduce((a, b) => a + b, 0) !== NUMBER_OF_COLUMNS row.columnSizes?.reduce((a, b) => a + b, 0) !== NUMBER_OF_COLUMNS

View File

@ -1,7 +1,7 @@
'use client'; 'use client';
import React, { useRef } from 'react'; import React, { useRef } from 'react';
import { useMemoizedFn, useWhyDidYouUpdate } from '@/hooks'; import { useMemoizedFn } from '@/hooks';
import { BusterListProps } from '../BusterList'; import { BusterListProps } from '../BusterList';
import { getAllIdsInSection } from '../BusterList/helpers'; import { getAllIdsInSection } from '../BusterList/helpers';
import { useEffect, useMemo } from 'react'; import { useEffect, useMemo } from 'react';

View File

@ -6,14 +6,7 @@ import { motion } from 'framer-motion';
import { cn } from '@/lib/classMerge'; import { cn } from '@/lib/classMerge';
import { useEffect, useState, useLayoutEffect, useTransition } from 'react'; import { useEffect, useState, useLayoutEffect, useTransition } from 'react';
import { cva } from 'class-variance-authority'; import { cva } from 'class-variance-authority';
import { import { useMemoizedFn, useMount, useSize } from '@/hooks';
useMemoizedFn,
useMergedRefs,
useMount,
useSize,
useThrottleFn,
useWhyDidYouUpdate
} from '@/hooks';
import { Tooltip } from '../tooltip/Tooltip'; import { Tooltip } from '../tooltip/Tooltip';
import Link from 'next/link'; import Link from 'next/link';
import { useRouter } from 'next/navigation'; import { useRouter } from 'next/navigation';

View File

@ -3,7 +3,7 @@
import React, { useEffect, useMemo, useState } from 'react'; import React, { useEffect, useMemo, useState } from 'react';
import isEmpty from 'lodash/isEmpty'; import isEmpty from 'lodash/isEmpty';
import { BusterResizeableGrid, BusterResizeableGridRow } from '@/components/ui/grid'; import { BusterResizeableGrid, BusterResizeableGridRow } from '@/components/ui/grid';
import { useDebounceFn, useMemoizedFn, useWhyDidYouUpdate } from '@/hooks'; import { useDebounceFn, useMemoizedFn } from '@/hooks';
import { import {
hasRemovedMetrics, hasRemovedMetrics,
hasUnmappedMetrics, hasUnmappedMetrics,
@ -73,7 +73,6 @@ export const DashboardContentController: React.FC<{
}, [draggingId, dashboard?.id, numberOfMetrics, metrics]); }, [draggingId, dashboard?.id, numberOfMetrics, metrics]);
const dashboardRows = useMemo(() => { const dashboardRows = useMemo(() => {
console.log('dashboardRows! rerender', rows);
return rows return rows
.filter((row) => row.items.length > 0) .filter((row) => row.items.length > 0)
.map((row) => { .map((row) => {
@ -130,18 +129,6 @@ export const DashboardContentController: React.FC<{
} }
}, [dashboard?.id, remapMetrics]); }, [dashboard?.id, remapMetrics]);
useWhyDidYouUpdate('DashboardContentController', {
remapMetrics,
dashboard,
metrics,
readOnly,
numberOfMetrics,
rows,
chatId,
dashboardConfig,
configRows
});
return ( return (
<div className="dashboard-content-controller"> <div className="dashboard-content-controller">
{hasMetrics && !!dashboardRows.length && !!dashboard ? ( {hasMetrics && !!dashboardRows.length && !!dashboard ? (