{
  "$schema": "https://ai.syncfusion.com/schema/registry-item.json",
  "name": "chart-live-stock-data",
  "framework": "javascript",
  "type": "registry:component",
  "component": "Chart",
  "variant": "live-stock-data",
  "dependencies": [
    "@syncfusion/ej2-charts"
  ],
  "description": "Real-time Candlestick chart streaming live AAPL OHLC ticks with crosshair and last-value label.",
  "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/javascript/llms.txt",
    "skillPack": "syncfusion/javascript-ui-components-skills",
    "docs": "https://ai.syncfusion.com/gallery/javascript/chart-live-stock-data.md"
  },
  "files": [
    {
      "target": "src/components/chart-live-stock-data/live-stock-data.html",
      "content": "<div class=\"control-section\">\n    <div id=\"stock\" align=\"center\"></div>\n</div>\n\n<style>\n    #control-container {\n        padding: 0px !important;\n    }\n</style>"
    },
    {
      "target": "src/components/chart-live-stock-data/live-stock-data.ts",
      "content": "import { Chart, CandleSeries, DateTime, Crosshair, ChartAnnotation, type ILoadedEventArgs, type IAxisRangeCalculatedEventArgs } from '@syncfusion/ej2-charts';\nimport { LastValueLabel } from '@syncfusion/ej2-charts';\nChart.Inject(CandleSeries, DateTime, Crosshair, ChartAnnotation, LastValueLabel);\nimport { Browser } from '@syncfusion/ej2-base';\nimport { loadChartTheme } from '../theme-color';\n\n/**\n * Sample of candle updates for a few seconds.\n */\nlet value: number = 180;\nlet intervalId: ReturnType<typeof setTimeout> | number| null;\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);\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: number = value + Math.round(Math.random() * 18);\n        let low: number = Math.min(value, open) - Math.round(Math.random() * 6);\n        let high: number = 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};\n\nlet data: Candlestick[] = getData().series;\nlet incVal: number = 0;\nlet updateVal: number = data.length;\n\n(window as any).default = (): void => {\n    let chart: Chart = new Chart({\n        //Initializing Primary X and Y Axis\n        primaryXAxis: {\n            valueType: 'DateTime', interval: Browser.isDevice ? 8 : 4, crosshairTooltip: { enable: true }, edgeLabelPlacement: Browser.isDevice ? 'None' : 'Shift', majorGridLines: { width: 0 }, labelIntersectAction: 'Hide'\n        },\n        chartArea: { border: { width: 0 } },\n        primaryYAxis:\n        {\n            interval: 20, opposedPosition: true, minimum: 120, crosshairTooltip: { enable: true }, lineStyle: { width: 0 },\n            majorGridLines: { width: 1 }, majorTickLines: { width: 0 }\n        },\n        //Initializing Chart Series\n        series: [\n            {\n                type: 'Candle', bearFillColor: '#2ecd71', bullFillColor: '#e74c3d', columnWidth: 0.4,\n                dataSource: data, 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            }\n        ],\n        width: Browser.isDevice ? '100%' : '90%',\n        title: 'AAPL Historical',\n        crosshair: { enable: true, dashArray: '5,5' },\n        pointRender: function (args) {\n            args.series.lastValueLabel.background = args.fill;\n        },\n        load: (args: ILoadedEventArgs) => {\n            loadChartTheme(args);\n            stockClearInterval();\n            intervalId = setInterval(function () {\n                let container = document.getElementById('stock');\n                if (container && container.id === args.chart.element.id) {\n                    let newData1: Candlestick[] = [];\n                    let value: number = 180;\n                    for (let i: number = 0; i < data.length; i++) {\n                        newData1.push(Object.assign({}, data[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 (chart.series.length > 0) {\n                            chart.series[0].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 (chart.series.length > 0) {\n                            let lastDataPointIndex = data.length - 1;\n                            if (lastDataPointIndex >= 0) {\n                                let timestamp = (chart.series[0].dataSource as { x: unknown }[])[lastDataPointIndex].x as number;\n                                let lastTimestamp = new Date(timestamp).getTime();\n                                chart.series[0].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                    stockClearInterval();\n                }\n            }, 1000);\n        },\n        axisRangeCalculated: (args: IAxisRangeCalculatedEventArgs) => {\n            if (args.axis.name === 'primaryXAxis') {\n                let lastPoint: Object = 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: Object = args.axis.series[0].points[0].x;\n                args.minimum = new Date(Number(firstPoint)).getTime() + 500;\n            }\n        }\n    });\n    chart.appendTo('#stock');\n    function stockClearInterval() {\n        if (intervalId) {\n            clearInterval(intervalId);\n            intervalId = null;\n        }\n    }\n};\ninterface Candlestick {\n    open: number;\n    close: number;\n    high: number;\n    low: number;\n    x: Date;\n}"
    }
  ]
}