{
  "$schema": "https://ai.syncfusion.com/schema/registry-item.json",
  "name": "chart-live-stock-data",
  "framework": "react",
  "type": "registry:component",
  "component": "Chart",
  "variant": "live-stock-data",
  "dependencies": [
    "@syncfusion/ej2-react-charts"
  ],
  "description": "Live AAPL stock chart that refreshes prices with zooming, crosshair, and tooltip tools.",
  "meta": {
    "essentialStudioRelease": "2026 Volume 2 (v34.1.29)",
    "license": "commercial-or-community",
    "licenseNote": "The Syncfusion package is licensed. The composition in this file is source you own and edit. See https://ai.syncfusion.com/licensing.md",
    "requiresLicenseKey": true,
    "requiresServerEndpoint": false,
    "platformIndex": "https://ai.syncfusion.com/react/llms.txt",
    "skillPack": "syncfusion/react-ui-components-skills",
    "docs": "https://ai.syncfusion.com/gallery/react/ts/chart-live-stock-data.md"
  },
  "files": [
    {
      "target": "src/components/chart-live-stock-data/chart.tsx",
      "content": "/**\n * Sample for Candle Series\n */\nimport { useState, useRef } from \"react\";\nimport { ChartComponent, SeriesCollectionDirective, LastValueLabel, CandleSeries, Category, Tooltip, type ILoadedEventArgs, DateTime, Zoom, Logarithmic, ColumnSeries, Crosshair, StripLine, SeriesDirective, Inject, type IAxisRangeCalculatedEventArgs, Series, type IPointRenderEventArgs, ChartAnnotation } from '@syncfusion/ej2-react-charts';\nimport { Browser } from '@syncfusion/ej2-base';\n\nlet value: number = 180;\nlet getData = (): { series: Candlestick[] } => {\n    let series: Candlestick[] = [];\n    let point: Candlestick;\n    for (let i: number = 0; i < 30; i++) {\n        value = 180 + (Math.random() * 25) * Math.sin(i * Math.PI / 8); // Adjust the function as needed\n        value = Math.max(140, Math.min(260, value));\n        if (value > 260) {\n            value = 260;\n        }\n        if (value < 140) {\n            value = 140;\n        }\n        value += Math.random() * 0.1;\n        let open = value + Math.round(Math.random() * 18);\n        let low = Math.min(value, open) - Math.round(Math.random() * 6);\n        let high = Math.min(220, Math.max(value, open) + Math.round(Math.random() * 15));\n        point = {\n            x: new Date(2000, 5, 2, 2, 0, i),\n            close: value,\n            open: open,\n            low: low,\n            high: high\n        };\n        series.push(point);\n    }\n    return { series: series };\n};\nlet data: Candlestick[] = getData().series;\nlet incVal: number = 0;\nlet updateVal: number = data.length;\nlet pointAdded: boolean = false;\ninterface Candlestick {\n    open: number;\n    close: number;\n    high: number;\n    low: number;\n    x: Date;\n}\n\nconst SAMPLE_CSS = `\n    .control-fluid {\n        padding: 0px !important;\n    }`;\n/**\n * Candle sample\n */\n\nconst LiveStock = () => {\n    let[intervalId, setIntervalId] = useState<NodeJS.Timeout | null>(null);\n    let chartInstance = useRef<ChartComponent>(null);\n    const load = (args: ILoadedEventArgs): void => {\n\n        clearIntervalFn();\n        intervalId = setInterval(function () {\n            var container = document.getElementById('stock');\n            if (container && container.id === args.chart.element.id) {\n                let newData1: Candlestick[] = [];\n                let value: number = 180;\n                pointAdded = true;\n                for (let i: number = 0; i < (args.chart.series[0].dataSource as Object[]).length; i++) {\n                    newData1.push(Object.assign({}, (args.chart.series[0] as Series).dataSource[i]));\n                }\n                if (newData1.length > 0) {\n                    const lastIndex: number = newData1.length - 1;\n                    const previousClose: number = newData1[lastIndex].close;\n                    newData1[lastIndex].close += (Math.random() < 0.5 ? 1 : -1) * Math.random() * 25;\n                    newData1[lastIndex].close = Math.min(Math.min(Math.max(newData1[lastIndex].close, newData1[lastIndex].low + 5), newData1[lastIndex].high - 5), newData1[lastIndex].open - 2);\n                    if (previousClose === newData1[lastIndex].close) {\n                        newData1[lastIndex].close -= 5;\n                    }\n                }\n                if (incVal < 10) {\n                    if (args.chart.series.length > 0) {\n                        (args.chart.series[0] as Series).setData(newData1);\n                        incVal++;\n                    }\n                }\n                else {\n                    let change: number = (Math.random() < 0.49 ? 1 : -1) * Math.random() * 10;\n                    value += change;\n                    if (value > 260) {\n                        value = 260;\n                    }\n                    if (value < 140) {\n                        value = 140;\n                    }\n                    value += Math.random() * 0.1;\n                    let open: number = value + Math.round(Math.random() * 12);\n                    let low: number = Math.min(value, open) - Math.round(Math.random() * 8);\n                    let high: number = Math.max(value, open) + Math.round(Math.random() * 15);\n                    if (args.chart.series.length > 0) {\n                        var lastDataPointIndex: number = ((args.chart.series[0] as Series).dataSource as []).length - 1;\n                        if (lastDataPointIndex >= 0) {\n                            var timestamp = (args.chart.series[0] as Series).dataSource[lastDataPointIndex].x;\n                            var lastTimestamp = new Date(timestamp).getTime();\n                            (args.chart.series[0] as Series).addPoint({ x: new Date(lastTimestamp + 1000), high: high, low: low, open: open, close: value });\n                        }\n                    }\n                    incVal = 0;\n                    updateVal++;\n                }\n            }\n            else {\n                clearIntervalFn();\n            }\n        }, 1000);\n        if (intervalId) setIntervalId(intervalId);\n    };\n    const clearIntervalFn = () => {\n        if (intervalId) {\n            clearInterval(intervalId);\n            setIntervalId(null);\n        }\n    };\n    const axisRangeCalculated = (args: IAxisRangeCalculatedEventArgs): void  => {\n        if (args.axis.name === 'primaryXAxis') {\n            let lastPoint = args.axis.series[0].points[args.axis.series[0].points.length - 1].x;\n            args.maximum = new Date(Number(lastPoint)).getTime() + 2500;\n            let firstPoint = args.axis.series[0].points[0].x;\n            args.minimum = new Date(Number(firstPoint)).getTime() + 500;\n        }\n    };\n    const pointRender = (args: IPointRenderEventArgs): void => {\n        args.series.lastValueLabel.background = args.fill;\n    }\n    return (\n        <div className='control-pane'>\n            <style>{SAMPLE_CSS}</style>\n            <div className='control-section'>\n                <div className=\"row\">\n                    <ChartComponent id='stock' ref={chartInstance} style={{ textAlign: \"center\" }} load={load.bind(this)} primaryXAxis={{ valueType: 'DateTime', interval: Browser.isDevice ? 8 : 4, edgeLabelPlacement: Browser.isDevice ? 'None' : 'Shift',  crosshairTooltip: { enable: true }, majorGridLines: { width: 0 }, labelIntersectAction: 'Hide' }} primaryYAxis={{ interval: 20, minimum: 120, opposedPosition: true, crosshairTooltip: { enable: true }, lineStyle: { width: 0 }, majorGridLines: { width: 1 }, majorTickLines: { width: 0 } }} width={Browser.isDevice ? '100%' : '90%'} chartArea={{ border: { width: 0 } }} title=\"AAPL Historical\" crosshair={{ enable: true, dashArray: '5,5' }} pointRender={pointRender.bind(this)}  axisRangeCalculated={axisRangeCalculated.bind(this)}>\n                        <Inject services={[CandleSeries, StripLine, Category, Tooltip, DateTime, Zoom, ColumnSeries, Logarithmic, Crosshair, ChartAnnotation, LastValueLabel]} />\n                        <SeriesCollectionDirective>\n                            <SeriesDirective type='Candle' bearFillColor='#2ecd71' bullFillColor='#e74c3d' dataSource={data} columnWidth={0.4}  xName='x' low='low' high='high' open='open' close='close' lastValueLabel={{enable: true, background: 'red', dashArray: '3,2', lineWidth: 0.5, font: {size: '10px'}}}/>\n                        </SeriesCollectionDirective>\n                    </ChartComponent>\n                </div>\n            </div>\n        </div >\n    )\n    \n   \n}\nexport default LiveStock;"
    }
  ]
}