### Initialize Equicharts Chart Source: https://github.com/alenjohn05/equicharts/blob/master/index.html Basic initialization of the Equicharts ChartMain component with container, locale, and symbol information. This is the starting point for rendering a chart. ```typescript import * as kline from '/src/index.ts'; let locale = 'en-US'; const chart = new kline.ChartMain({ container: document.getElementById('container'), locale, watermark: '', symbol: { exchange: 'XNYS', market: 'stocks', name: 'Nvidia Corp', shortName: 'NVDA', ticker: 'NVDA', priceCurrency: 'usd', type: 'CS', }, styles: { grid: { show: true, horizontal: { show: true, size: 1, style: 'stroke_fill', dashedValue: [1, 1], color: '#1F1F1F8A', }, vertical: { show: true, size: 1, style: 'stroke_fill', dashedValue: [1, 1], color: '#1F1F1F8A', }, }, candle: { priceMark: { show: true, high: { show: true, color: '#FFFFFF', textMargin: 5, textSize: 10, textFamily: '"Roboto", sans-serif', textWeight: 'normal', }, low: { show: true, color: '#FFFFFF', textMargin: 5, textSize: 10, textFamily: '"Roboto", sans-serif', textWeight: 'normal', }, last: { show: true, upColor: '#399068', downColor: '#DE4646', noChangeColor: '#1F1F1F8A', line: { show: true, style: 'dashed', dashedValue: [1, 3], size: 1, }, text: { show: true, style: 'fill', size: 12, paddingLeft: 4, paddingTop: 4, paddingRight: 4, paddingBottom: 4, borderStyle: 'solid', borderSize: 0, borderColor: 'transparent', borderDashedValue: [2, 2], color: '#FFFFFF', family: '"Roboto", sans-serif', weight: 'normal', borderRadius: 2, }, }, }, tooltip: { offsetLeft: 4, offsetTop: 6, offsetRight: 4, offsetBottom: 6, showRule: 'always', showType: 'standard', custom: [ { title: 'time', value: { text: '{time}', color: '#FCB900' } }, { title: 'O ', value: { text: '{open}', color: '#FCB900' } }, { title: 'H ', value: { text: '{high}', color: '#FCB900' } }, { title: 'L ', value: { text: '{low}', color: '#FCB900' } }, { title: 'C ', value: { text: '{close}', color: '#FCB900' } }, { title: 'Vol ', value: { text: '{volume}', color: '#FCB900' } }, ], defaultValue: 'n/a', rect: { position: 'fixed', paddingLeft: 4, paddingRight: 4, paddingTop: 4, paddingBottom: 4, offsetLeft: 4, offsetTop: 4, offsetRight: 4, offsetBottom: 4, borderRadius: 4, borderSize: 1, borderColor: '#2a2e39', color: '#FEFEFE', }, text: { size: 10, family: '"Roboto", sans-serif', weight: 'normal', color: '#FFFFFF8A', marginLeft: 1, marginTop: 4, marginRight: 8, marginBottom: 4, }, icons: [], }, }, xAxis: { show: true, size: 'auto', axisLine: { show: true, color: '#1F1F1F8A', size: 1, }, tickText: { show: true, color: '#FFFFFF', family: '"Roboto", sans-serif', weight: 'normal', size: 12, marginStart: 4, marginEnd: 4, }, tickLine: { show: true, size: 1, length: 3, color: '#1F1F1F8A', }, }, yAxis: { show: true, size: 'auto', position: 'right', type: 'normal', inside: false, reverse: false, axisLine: { show: true, color: '#1F1F1F8A', size: 1, }, tickText: { show: true, color: '#FFFFFF', family: '"Roboto", sans-serif', weight: 'normal', size: 12, marginStart: 4, marginEnd: 4, }, tickLine: { show: true, size: 1, length: 1, color: '#1F1F1F8A', }, }, separator: { size: 3, color: '#1F1F1F8A', fill: true, activeBackgroundColor: '#1F1F1F8A', }, crosshair: { show: true, horizontal: { show: true, line: { show: true, style: 'dashed', dashedValue: [6, 6], size: 1, color: '#2a2e39', }, text: { show: true, style: 'fill', color: '#FFFFFF', size: 12, family: '"Roboto", sans-serif', weight: 'normal', borderStyle: 'solid', borderDashedValue: [2, 2], borderSize: 1, borderColor: '#2a2e39', borderRadius: 1, paddingLeft: 4, paddingRight: 4, paddingTop: 4, paddingBottom: 4, backgroundColor: '#2a2e39', }, }, vertical: { show: true, line: { show: true, style: 'dashed', dashedValue: [6, 6], size: 1, color: '#2a2e39', }, text: { show: true, style: 'fill', color: '#FFFFFF', size: 12, family: '"Roboto", sans-serif', weight: 'normal', borderStyle: 'solid', borderDashedValue: [2, 2], borderSize: 1, borderColor: '#2a2e39', borderRadius: 1, paddingLeft: 4, paddingRight: 4, paddingTop: 4, paddingBottom: 4, backgroundColor: '#2a2e39', }, }, }, indicator: { lastValueMark: { show: false, text: { show: false, style: 'fill', color: '#FFFFFF', size: 12, family: '"Roboto", sans-serif', weight: 'normal', borderStyle: 'solid', borderSize: 1, borderDashedValue: [2, 2], paddingLeft: 4, paddingRight: 4, paddingTop: 4, paddingBottom: 4, borderRadius: 2, }, }, tooltip: { offsetLeft: 4, offsetTop: 6, offsetRight: 4, offsetBottom: 6, showRule: 'always', showType: 'standard', showName: true, showParams: true, defaultValue: 'n/a', text: { size: 12, family: '"Roboto", sans-se' } } } } }); ``` -------------------------------- ### Initialize Equicharts Chart Source: https://github.com/alenjohn05/equicharts/blob/master/equicharts/index.html Initializes a new Equicharts chart with specified options. This is the first step to creating any chart. ```javascript const chart = equicharts.init('k-line-chart', options) ``` -------------------------------- ### Create and Apply Indicators Source: https://github.com/alenjohn05/equicharts/blob/master/equicharts/index.html Creates an Exponential Moving Average (EMA) indicator and a candle volume indicator on the 'candle_pane'. This demonstrates how to add standard and custom indicators to a chart. ```javascript chart.createIndicator('EMA', true, { id: 'candle_pane' }) chart.createIndicator('candle_volume', false, { id: 'candle_pane' }) ``` -------------------------------- ### Create and Manage Chart Overlay on Hover Source: https://github.com/alenjohn05/equicharts/blob/master/src/base/sampleHtmlHoverExample.txt This snippet illustrates creating a custom overlay with a price line, polygon, and text label that appears when hovering over a specific timestamp. It also includes logic for updating a tooltip and cleaning up the overlay after a delay. ```typescript const handleMoveToATimeStamp = (timeData: number) => { widget?.scrollToTimestamp(addPeriodsToTimestamp(period(), timeData, 100), 2) widget?.setYScrolling(yScrolling()) // const tooltip = document.getElementById('date-tooltip') registerOverlay({ name: 'priceLine2', totalStep: 2, needDefaultPointFigure: false, needDefaultXAxisFigure: false, needDefaultYAxisFigure: false, styles: { line: { style: LineType.Dashed } }, createPointFigures: ({ coordinates, bounding, precision, overlay, thousandsSeparator, decimalFoldThreshold, yAxis, xAxis }: OverlayCreateFiguresCallbackParams) => { if (!xAxis || !yAxis || !timeData) return [] const x = xAxis?.convertTimestampToPixel(timeData) const data: Nullable | undefined = xAxis?.convertTimestampToData(timeData) if (data) { const y = yAxis?.convertToPixel(data.high) const startX = x const startY = y - 6 const lineEndY = startY - 50 const arrowEndY = lineEndY - 5 // if (tooltip) { // tooltip.style.left = `${x + 10}px` // tooltip.style.top = `${y + 50}px` // tooltip.innerHTML = formatDate(timeData) // tooltip.style.display = 'block' // } return [ { type: 'line', attrs: { coordinates: [{ x: startX, y: startY }, { x: startX, y: lineEndY }] }, ignoreEvent: true }, { type: 'polygon', attrs: { coordinates: [{ x: startX, y: lineEndY }, { x: startX - 4, y: arrowEndY }, { x: startX + 4, y: arrowEndY }] }, ignoreEvent: true }, { type: 'text', attrs: { x: startX, y: arrowEndY, text: formatDate(timeData), align: 'center', baseline: 'bottom' }, ignoreEvent: true } ] } return [] } }) widget?.createOverlay('priceLine2', 'candle_pane') function sayHello() { widget?.removeIndicator('candle_pane', 'tick') if (tooltip) { tooltip.style.display = "none"; } } setTimeout(sayHello, 2000); } ``` -------------------------------- ### Create Overlay Buttons Source: https://github.com/alenjohn05/equicharts/blob/master/equicharts/index.html Generates buttons to create chart overlays. Supports built-in 'priceLine' and the custom 'circle' overlay. ```javascript function createOverlay(name) { chart.createOverlay(name) } const buttonContainer3 = document.createElement('div') buttonContainer3.className = 'button-container' const items3 = [ { key: 'priceLine', text: '价格线(内置)-Price line(built-in)' }, { key: 'circle', text: '圆(自定义)-Circle(custom)' } ] items3.forEach(({ key, text }) => { const button = document.createElement('button') button.innerText = text button.addEventListener('click', () => { createOverlay(key) }) buttonContainer3.appendChild(button) }) container.appendChild(buttonContainer3) container.appendChild(buttonContainer) ``` -------------------------------- ### Create Theme Switcher Buttons Source: https://github.com/alenjohn05/equicharts/blob/master/equicharts/index.html Generates buttons for switching chart themes. Each button is associated with a specific theme key and text label. ```javascript // 以下仅仅是为了协助代码演示,在实际项目中根据情况进行调整。 // The following is only for the purpose of assisting in code demonstration, and adjustments will be made according to the actual situation in the project. const container = document.getElementById('container') const buttonContainer = document.createElement('div') buttonContainer.className = 'button-container' const items = [ { key: 'light', text: 'Light' }, { key: 'dark', text: 'Dark' }, { key: 'green_rise_red_fall', text: 'Green rise and red fall' }, { key: 'red_rise_green_fall', text: 'Red rise and green fall' } ] items.forEach(({ key, text }) => { const button = document.createElement('button') button.innerText = text button.addEventListener('click', () => { setTheme(key) }) buttonContainer.appendChild(button) }) ``` -------------------------------- ### Generate Sample Financial Chart Data Source: https://github.com/alenjohn05/equicharts/blob/master/equicharts/index.html Generates an array of sample financial data points, including timestamp, open, high, low, close, volume, and turnover. This function is useful for populating charts with realistic data. ```javascript function genData(timestamp = new Date().getTime(), length = 800) { let basePrice = 5000 timestamp = Math.floor(timestamp / 1000 / 60) * 60 * 1000 - length * 60 * 1000 const dataList = [] for (let i = 0; i < length; i++) { const prices = [] for (let j = 0; j < 4; j++) { prices.push(basePrice + Math.random() * 60 - 30) } prices.sort() const open = +(prices[Math.round(Math.random() * 3)].toFixed(2)) const high = +(prices[3].toFixed(2)) const low = +(prices[0].toFixed(2)) const close = +(prices[Math.round(Math.random() * 3)].toFixed(2)) const volume = Math.round(Math.random() * 100) + 10 const turnover = (open + high + low + close) / 4 * volume dataList.push({ timestamp, open, high, low, close, volume, turnover }) basePrice = close timestamp += 60 * 1000 } return dataList } ``` -------------------------------- ### Initialize Default Datafeed Source: https://github.com/alenjohn05/equicharts/blob/master/index.html Initializes the default datafeed for Equicharts using an API key. This is essential for loading chart data. ```javascript new kline.DefaultDatafeed("R8F_9kQRGZZ87CUuO0bNpybcPWith5RL") ``` -------------------------------- ### Register Custom Circle Overlay Source: https://github.com/alenjohn05/equicharts/blob/master/equicharts/index.html Registers a custom overlay named 'circle' that draws a circle based on two coordinate points. It calculates the radius from the distance between the points. ```javascript equicharts.registerOverlay({ name: 'circle', needDefaultPointFigure: true, needDefaultXAxisFigure: true, needDefaultYAxisFigure: true, totalStep: 3, createPointFigures: ({ coordinates }) => { if (coordinates.length === 2) { const xDis = Math.abs(coordinates[0].x - coordinates[1].x) const yDis = Math.abs(coordinates[0].y - coordinates[1].y) const radius = Math.sqrt(xDis * xDis + yDis * yDis) return { key: 'circle', type: 'circle', attrs: { ...coordinates[0], r: radius }, styles: { style: 'stroke_fill' } } } return [] } }) ``` -------------------------------- ### Equicharts Configuration Options Source: https://github.com/alenjohn05/equicharts/blob/master/equicharts/index.html Defines the configuration options for an Equicharts chart, including styles for grid, candles, price markers, tooltips, and axes. This object is used to customize the chart's appearance and behavior. ```javascript const red = '#DE4646' const green = '#399068' const alphaRed = '#DE46468A' const alphaGreen = '#3990688A' const color = '#76808F' const options = { styles: { grid: { show: true, horizontal: { show: true, size: 1, color: '#1F1F1F69', style: 'stroke_fill', dashedValue: [1, 1] }, vertical: { show: true, size: 1, color: '#1F1F1F69', style: 'stroke_fill', dashedValue: [1, 1] } }, candle: { type: "candle_solid", bar: { upColor: red, downColor: green, upBorderColor: red, downBorderColor: green, upWickColor: alphaRed, downWickColor: alphaGreen, }, priceMark: { show: true, high: { show: true, color: '#FFFFFF', textMargin: 5, textSize: 10, textFamily: '"Onest", sans-serif', textWeight: 'normal' }, low: { show: true, color: '#FFFFFF', textMargin: 5, textSize: 10, textFamily: '"Onest", sans-serif', textWeight: 'normal', }, last: { show: true, upColor: '#089981', downColor: '#DE4646', noChangeColor: '#1F1F1F69', line: { show: true, style: 'dashed', dashedValue: [1, 1], size: 1 }, text: { show: true, style: 'fill', size: 12, paddingLeft: 4, paddingTop: 4, paddingRight: 4, paddingBottom: 4, borderStyle: 'solid', borderSize: 0, borderColor: 'transparent', borderDashedValue: [2, 2], color: '#FFFFFF', family: '"Onest", sans-serif', weight: 'normal', borderRadius: 2 } } }, tooltip: { offsetLeft: 9, offsetTop: 10, offsetRight: 4, offsetBottom: 6, showRule: 'always', showType: 'standard', custom: [ { title: 'time', value: { text: '{time}', color: "#2a2e39" } }, { title: 'open', value: { text: '{open}', color: "#2a2e39" } }, { title: 'high', value: { text: '{high}', color: "#2a2e39" } }, { title: 'low', value: { text: '{low}', color: "#2a2e39" } }, { title: 'close', value: { text: '{close}', color: "#2a2e39" } }, { title: 'volume', value: { text: '{volume}', color: "#2a2e39" } }, ], defaultValue: 'n/a', rect: { position: 'fixed', paddingLeft: 4, paddingRight: 4, paddingTop: 4, paddingBottom: 4, offsetLeft: 4, offsetTop: 4, offsetRight: 4, offsetBottom: 4, borderRadius: 4, borderSize: 1, borderColor: '#f2f3f5', color: '#2a2e39' }, text: { size: 12, family: '"Onest", sans-serif', weight: 'normal', color: '#2a2e39', marginLeft: 8, marginTop: 4, marginRight: 8, marginBottom: 4 }, icons: [] } }, xAxis: { show: true, size: 'auto', axisLine: { show: true, color: '#1F1F1F69', size: 1 }, tickText: { show: true, color: '#FFFFFF', family: '"Onest", sans-serif', weight: 'normal', size: 11, marginStart: 4, marginEnd: 4 }, tictView: { show: true, size: 1, length: 1, color: '#1F1F1F69' } }, yAxis: { show: true, size: 'auto', position: 'right', type: 'normal', inside: false, reverse: false, axisLine: { show: true, color: '#1F1F1F69', size: 1 }, tickText: { show: true, color: '#FFFFFF', family: '"Onest", sans-serif', weight: 'normal', size: 11, marginStart: 4, marginEnd: 4 }, tictView: { show: true, size: 1, length: 1, color: '#1F1F1F69' } }, separator: { size: 1, color: '#1F1F1F69', fill: true, activeBackgroundColor: '#1F1F1F69' }, crosshair: { show: true, horizontal: { show: true, line: { show: true, style: 'dashed', dashedValue: [6, 6], size: 1, color: '#5f5b5b80' }, text: { show: true, style: 'fill', color: '#FFFFFF', size: 12, family: '"Onest", sans-serif', weight: 'normal', borderStyle: 'solid', borderDashedValue: [2, 2], borderSize: 1, borderColor: '#686D76', borderRadius: 1, paddingLeft: 4, paddingRight: 4, paddingTop: 4, paddingBottom: 4, backgroundColor: '#686D76' } }, vertical: { show: true, line: { show: true, style: 'dashed', dashedValue: [6, 6], size: 1, color: '#5f5b5b80' }, text: { show: true, style: 'fill', color: '#FFFFFF', size: 12, family: '"Onest" ``` -------------------------------- ### Load More Data Source: https://github.com/alenjohn05/equicharts/blob/master/equicharts/index.html Initiates loading more data for the chart, typically used for infinite scrolling or pagination. It takes a timestamp as an argument. ```javascript chart.loadMore((timestamp) => { const loadMo ``` -------------------------------- ### Set Chart Theme Source: https://github.com/alenjohn05/equicharts/blob/master/equicharts/index.html Applies a specified theme to the chart and updates the background color of the chart container accordingly. Supports 'light', 'dark', 'green_rise_red_fall', and 'red_rise_green_fall' themes. ```javascript const ticks = [ { "text": "5,450.00", "coord": 721, "value": "5450" }, { "text": "5,500.00", "coord": 619, "value": "5500" }, { "text": "5,550.00", "coord": 517, "value": "5550" }, { "text": "5,600.00", "coord": 414, "value": "5600" }, { "text": "5,650.00", "coord": 312, "value": "5650" }, { "text": "5,700.00", "coord": 210, "value": "5700" }, { "text": "5,750.00", "coord": 108, "value": "5750" } ] console.log(equicharts) function setTheme(theme) { chart.setStyles(theme) if (theme === 'light') { document.getElementById('k-line-chart').style.backgroundColor = '#ffffff' } else if (theme === 'dark') { document.getElementById('k-line-chart').style.backgroundColor = '#030507' } } ``` -------------------------------- ### Register Custom X-Axis Source: https://github.com/alenjohn05/equicharts/blob/master/equicharts/index.html Registers a custom X-axis with a specified name and tick creation function. Use this to define custom axis behaviors. ```javascript equicharts.registerXAxis({ name: 'nAxis', createTicks: (params) => ticks }); ``` -------------------------------- ### Apply New Data to Chart Source: https://github.com/alenjohn05/equicharts/blob/master/equicharts/index.html Applies new data to the chart. This function is typically called after initializing the chart and its indicators to populate it with data. ```javascript chart.applyNewData(genData()) ``` -------------------------------- ### Register Candle Volume Indicator Source: https://github.com/alenjohn05/equicharts/blob/master/equicharts/index.html Registers a custom 'candle_volume' indicator. This indicator calculates and draws volume bars based on the provided data. It includes logic for tooltip display and drawing based on price changes. ```javascript equicharts.registerIndicator({ name: 'candle_volume', shortName: 'Volume', calc: (TViewDataList) => { return TViewDataList.map(TViewData => TViewData.volume) }, createTooltipDataSource: ({ TViewDataList, crosshair, indicator, defaultStyles }) => { const { dataIndex } = crosshair const result = indicator.result const styles = indicator.styles || defaultStyles let color const TViewData = TViewDataList[dataIndex] if (TViewData.close > TViewData.open) { color = "#08998140" } else if (TViewData.close < TViewData.open) { color = "#DE464640" } else { color = "#1F1F1F69" } return { name: 'Volume', values: [{ title: '', value: { text: result[dataIndex] || 'n/a', color } }] } }, draw: ({ctx, TViewDataList, bounding, visibleRange, barSpace, defaultStyles, indicator, xAxis, yAxis}) => { const { from, to } = visibleRange const result = indicator.result let maxVolume = Number.MIN_SAFE_INTEGER for (let i = from; i < to; i++) { const volume = result[i] maxVolume = Math.max(volume, maxVolume) } const height = bounding.height const maxBarHeight = height / 4 ctx.globalCompositeOperation = 'destination-over' const styles = indicator.styles || defaultStyles for (let i = from; i < to; i++) { const TViewData = TViewDataList[i] const volume = result[i] let color if (TViewData.close > TViewData.open) { color = "#08998140" } else if (TViewData.close < TViewData.open) { color = "#DE464640" } else { color = "#1F1F1F69" } const x = xAxis.convertToPixel(i) ctx.fillStyle = color const barStartY = height - (volume / maxVolume) * maxBarHeight ctx.fillRect(x - barSpace.halfGapBar, barStartY, barSpace.gapBar, height - barStartY) } return false } }) ``` -------------------------------- ### Update Chart Data Dynamically Source: https://github.com/alenjohn05/equicharts/blob/master/equicharts/index.html Continuously updates chart data by modifying the last data point and applying it. This function is called recursively using setTimeout. ```javascript reTimer = setTimeout(() => { chart.applyMoreData(genData(timestamp), true) }, 2000) }) updateData() function updateData() { setTimeout(() => { const dataList = chart.getDataList() const lastData = dataList[dataList.length - 1] const newData = { ...lastData } newData.close += (Math.random() * 20 - 10) newData.high = Math.max(newData.high, newData.close) newData.low = Math.min(newData.low, newData.close) newData.volume += Math.round(Math.random() * 10) chart.updateData(newData) updateData() }, 600) } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.