Skip to content
Draft
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1,038 changes: 1,038 additions & 0 deletions FUNCTIONAL_COMPONENT_GENERATION_GUIDE.md

Large diffs are not rendered by default.

251 changes: 251 additions & 0 deletions FUNCTIONAL_REFACTORING_README.md

Large diffs are not rendered by default.

88 changes: 88 additions & 0 deletions index.functional.template.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
import React, {
//insert hooksImports
//end hooksImports
} from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';

//insert vmImports
//end vmImports
//insert modulesImports
//end modulesImports
//insert bindingImports
//end bindingImports
//insert descriptionImports
//end descriptionImports
//insert vmLibraryImports
//end vmLibraryImports
//insert handlersImports
//end handlersImports
//insert templateImports
//end templateImports

//ifdef webgrids
import 'igniteui-react-grids/grids/themes/light/bootstrap.css';
//endifdef webgrids
//ifdef editor
import 'igniteui-webcomponents/themes/light/bootstrap.css';
//endifdef editor

//ifdef modulesRegister
const mods: any[] = [
//insert modulesRegister
//end modulesRegister
];
mods.forEach((m) => m.register());
//endifdef modulesRegister

//ifdef moduleRegistrations
//insert moduleRegistrations
//end moduleRegistrations
//endifdef moduleRegistrations

//ifdef moduleConstants
//insert moduleConstants
//end moduleConstants
//endifdef moduleConstants

//ifdef moduleFunctions
//insert moduleFunctions
//end moduleFunctions
//endifdef moduleFunctions

export default function Sample() {

//ifdef useState
//insert useState
//end useState
//endifdef useState

//ifdef useRef
//insert useRef
//end useRef
//endifdef useRef

//ifdef useMemo
//insert useMemo
//end useMemo
//endifdef useMemo

//ifdef useEffect
//insert useEffect
//end useEffect
//endifdef useEffect

//ifdef useCallback
//insert useCallback
//end useCallback
//endifdef useCallback

return (
//insert render
//end render
);
}

// rendering above component to the React DOM
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<Sample/>);
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
import React, { useState, useRef, useEffect, useCallback } from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import { IgrCategoryChart } from 'igniteui-react-charts';
import { IgrCategoryChartModule } from 'igniteui-react-charts';
import { CategoryChartSharedData } from './CategoryChartSharedData';

IgrCategoryChartModule.register();

export default function CategoryChartHighFrequency() {
const INITIAL_DATA_POINTS = 500;

// Mutable values that must not trigger re-renders are kept in refs
const chartRef = useRef<IgrCategoryChart>(null);
const dataRef = useRef<any[]>(CategoryChartSharedData.generateItems(100, INITIAL_DATA_POINTS, false));
const dataIndexRef = useRef<number>(dataRef.current.length);
const dataPointsRef = useRef<number>(INITIAL_DATA_POINTS);
const refreshMsRef = useRef<number>(5);
const intervalRef = useRef<number>(-1);

const [state, setState] = useState({
dataFeedAction: 'Start',
dataInfo: CategoryChartSharedData.toShortString(INITIAL_DATA_POINTS),
dataPoints: INITIAL_DATA_POINTS,
dataSource: dataRef.current,
refreshInterval: 5,
refreshInfo: '5ms',
});

const mountedRef = useRef(true);

const setupInterval = useCallback(() => {
if (intervalRef.current >= 0) {
window.clearInterval(intervalRef.current);
intervalRef.current = -1;
}
intervalRef.current = window.setInterval(() => {
if (!mountedRef.current) return;
setState(prev => {
if (prev.dataFeedAction !== 'Stop') return prev;

const chart = chartRef.current;
if (!chart) return prev;

dataIndexRef.current++;
const oldItem = dataRef.current[0];
const newItem = CategoryChartSharedData.getNewItem(dataRef.current, dataIndexRef.current);

dataRef.current.push(newItem);
chart.notifyInsertItem(dataRef.current, dataRef.current.length - 1, newItem);
dataRef.current.shift();
chart.notifyRemoveItem(dataRef.current, 0, oldItem);

return prev; // no state change – data mutated imperatively on the chart
});
}, refreshMsRef.current);
}, []);

// Start interval after chart mounts; clear on unmount (replaces componentWillUnmount)
useEffect(() => {
if (chartRef.current) {
setupInterval();
}
return () => {
mountedRef.current = false;
if (intervalRef.current >= 0) {
window.clearInterval(intervalRef.current);
intervalRef.current = -1;
}
};
}, [setupInterval]);

const onChartRef = useCallback((chart: IgrCategoryChart) => {
if (!chart) return;
chartRef.current = chart;
setupInterval();
}, [setupInterval]);

const onDataGenerateClick = useCallback(() => {
dataRef.current = CategoryChartSharedData.generateItems(100, dataPointsRef.current, false);
dataIndexRef.current = dataRef.current.length;
setState(prev => ({ ...prev, dataSource: dataRef.current }));
}, []);

const onDataFeedClick = useCallback(() => {
setState(prev => ({
...prev,
dataFeedAction: prev.dataFeedAction === 'Start' ? 'Stop' : 'Start',
}));
}, []);

const onDataPointsChanged = useCallback((e: React.ChangeEvent<HTMLInputElement>) => {
let num = parseInt(e.target.value, 10);
if (isNaN(num)) num = 10000;
if (num < 100) num = 100;
if (num > 2000) num = 2000;
dataPointsRef.current = num;
setState(prev => ({
...prev,
dataPoints: num,
dataInfo: CategoryChartSharedData.toShortString(num),
}));
}, []);

const onRefreshFrequencyChanged = useCallback((e: React.ChangeEvent<HTMLInputElement>) => {
let num = parseInt(e.target.value, 10);
if (isNaN(num)) num = 10;
if (num < 10) num = 10;
if (num > 500) num = 500;
refreshMsRef.current = num;
setState(prev => ({
...prev,
refreshInterval: num,
refreshInfo: num + 'ms',
}));
setupInterval();
}, [setupInterval]);

return (
<div className="container sample">
<div className="options horizontal">
<button onClick={onDataFeedClick}>{state.dataFeedAction}</button>
<label className="options-label">Refresh: </label>
<label className="options-value">{state.refreshInfo}</label>
<input
className="options-slider"
type="range"
min="5"
max="250"
step="5"
value={state.refreshInterval}
onChange={onRefreshFrequencyChanged}
/>
<button onClick={onDataGenerateClick}>Generate</button>
<label className="options-label">Data Points: </label>
<label className="options-value">{state.dataInfo}</label>
<input
className="options-slider"
type="range"
min="100"
max="2000"
step="100"
value={state.dataPoints}
onChange={onDataPointsChanged}
/>
</div>
<div className="container" style={{ height: 'calc(100% - 45px)' }}>
<IgrCategoryChart
ref={onChartRef}
width="100%"
height="100%"
chartType="Line"
dataSource={state.dataSource}
yAxisExtent={40}
xAxisEnhancedIntervalPreferMoreCategoryLabels="false"
shouldConsiderAutoRotationForInitialLabels="false"
shouldAutoExpandMarginForInitialLabels="false"
crosshairsDisplayMode="None"
autoMarginAndAngleUpdateMode="None"
markerTypes="None"
/>
</div>
</div>
);
}

// rendering above component to the React DOM
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<CategoryChartHighFrequency/>);
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
import React, { useState, useRef, useCallback } from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import { IgrCategoryChart } from 'igniteui-react-charts';
import { IgrCategoryChartModule } from 'igniteui-react-charts';

IgrCategoryChartModule.register();

const CHART_DATA = [
{ Year: '2009', Europe: 31, China: 21, USA: 19 },
{ Year: '2010', Europe: 43, China: 26, USA: 24 },
{ Year: '2011', Europe: 66, China: 29, USA: 28 },
{ Year: '2012', Europe: 69, China: 32, USA: 26 },
{ Year: '2013', Europe: 58, China: 47, USA: 38 },
{ Year: '2014', Europe: 40, China: 46, USA: 31 },
{ Year: '2015', Europe: 78, China: 50, USA: 19 },
{ Year: '2016', Europe: 13, China: 90, USA: 52 },
{ Year: '2017', Europe: 78, China: 132, USA: 50 },
{ Year: '2018', Europe: 40, China: 134, USA: 34 },
{ Year: '2019', Europe: 80, China: 96, USA: 38 },
];

export default function CategoryChartLineChartWithAnimations() {
const chartRef = useRef<IgrCategoryChart>(null);

const [transitionLabel, setTransitionLabel] = useState('1000ms');
const [transitionInDuration, setTransitionInDuration] = useState(1000);
const [transitionInMode, setTransitionInMode] = useState('Auto');

const onTransitionInModeChanged = useCallback((e: React.ChangeEvent<HTMLSelectElement>) => {
setTransitionInMode(e.target.value);
}, []);

const onTransitionInDurationChanged = useCallback((e: React.ChangeEvent<HTMLInputElement>) => {
const val = parseInt(e.target.value, 10);
setTransitionInDuration(val);
setTransitionLabel(val + 'ms');
}, []);

const onReloadChartClick = useCallback(() => {
chartRef.current?.replayTransitionIn();
}, []);

return (
<div className="container sample">
<div className="options horizontal">
<span className="options-label">Transition Type </span>
<select onChange={onTransitionInModeChanged}>
<option>Auto</option>
<option>AccordionFromBottom</option>
<option>AccordionFromCategoryAxisMaximum</option>
<option>AccordionFromCategoryAxisMinimum</option>
<option>AccordionFromLeft</option>
<option>AccordionFromRight</option>
<option>AccordionFromTop</option>
<option>AccordionFromValueAxisMaximum</option>
<option>AccordionFromValueAxisMinimum</option>
<option>Expand</option>
<option>FromZero</option>
<option>SweepFromBottom</option>
<option>SweepFromCategoryAxisMaximum</option>
<option>SweepFromCategoryAxisMinimum</option>
<option>SweepFromCenter</option>
<option>SweepFromLeft</option>
<option>SweepFromRight</option>
<option>SweepFromTop</option>
<option>SweepFromValueAxisMaximum</option>
<option>SweepFromValueAxisMinimum</option>
</select>
<label className="options-value" style={{ width: '75px' }}>{transitionLabel}</label>
<input
className="options-slider"
type="range"
min="50"
max="2000"
step="50"
defaultValue="1000"
onChange={onTransitionInDurationChanged}
/>
<button onClick={onReloadChartClick}>Reload Chart</button>
</div>

<IgrCategoryChart
ref={chartRef}
width="100%"
height="calc(100% - 30px)"
dataSource={CHART_DATA}
chartType="Line"
isTransitionInEnabled={true}
isHorizontalZoomEnabled={false}
isVerticalZoomEnabled={false}
transitionInDuration={transitionInDuration}
transitionInMode={transitionInMode}
yAxisTitle="TWh"
yAxisTitleLeftMargin={10}
yAxisTitleRightMargin={5}
yAxisLabelLeftMargin={0}
computedPlotAreaMarginMode="Series"
/>
</div>
);
}

// rendering above component to the React DOM
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<CategoryChartLineChartWithAnimations/>);
Loading
Loading