├── .babelrc.json ├── .eslintignore ├── .eslintrc.cjs ├── .github └── workflows │ ├── deploy-docs.yml │ └── npm-publish.yml ├── .gitignore ├── .vscode └── settings.json ├── LICENSE ├── README.md ├── docs ├── .vitepress │ ├── config.ts │ └── theme │ │ ├── index.ts │ │ └── style.css ├── api.md ├── data-access.md ├── data-description.md ├── en-US │ ├── api.md │ ├── data-access.md │ ├── data-description.md │ ├── getting-started.md │ ├── i18n.md │ ├── index.md │ ├── introduction.md │ └── theme.md ├── getting-started.md ├── i18n.md ├── index.md ├── introduction.md ├── public │ ├── CNAME │ └── logo.svg └── theme.md ├── logo.svg ├── package-lock.json ├── package.json ├── src ├── ChartProComponent.tsx ├── DefaultDatafeed.ts ├── KLineChartPro.tsx ├── base.less ├── component │ ├── button │ │ ├── index.less │ │ └── index.tsx │ ├── checkbox │ │ ├── index.less │ │ └── index.tsx │ ├── empty │ │ ├── index.less │ │ └── index.tsx │ ├── index.less │ ├── index.tsx │ ├── input │ │ ├── index.less │ │ └── index.tsx │ ├── list │ │ ├── index.less │ │ └── index.tsx │ ├── loading │ │ ├── index.less │ │ └── index.tsx │ ├── modal │ │ ├── index.less │ │ └── index.tsx │ ├── select │ │ ├── index.less │ │ └── index.tsx │ └── switch │ │ ├── index.less │ │ └── index.tsx ├── extension │ ├── abcd.ts │ ├── anyWaves.ts │ ├── arrow.ts │ ├── circle.ts │ ├── eightWaves.ts │ ├── fibonacciCircle.ts │ ├── fibonacciExtension.ts │ ├── fibonacciSegment.ts │ ├── fibonacciSpeedResistanceFan.ts │ ├── fibonacciSpiral.ts │ ├── fiveWaves.ts │ ├── gannBox.ts │ ├── index.ts │ ├── parallelogram.ts │ ├── rect.ts │ ├── threeWaves.ts │ ├── triangle.ts │ ├── utils.ts │ └── xabcd.ts ├── i18n │ ├── en-US.json │ ├── index.ts │ └── zh-CN.json ├── iconfonts │ ├── fonts │ │ ├── icomoon.eot │ │ ├── icomoon.svg │ │ ├── icomoon.ttf │ │ └── icomoon.woff │ └── style.css ├── index.less ├── index.ts ├── types.ts └── widget │ ├── drawing-bar │ ├── icons │ │ ├── abcd.tsx │ │ ├── anyWaves.tsx │ │ ├── arrow.tsx │ │ ├── circle.tsx │ │ ├── eightWaves.tsx │ │ ├── fibonacciCircle.tsx │ │ ├── fibonacciExtension.tsx │ │ ├── fibonacciLine.tsx │ │ ├── fibonacciSegment.tsx │ │ ├── fibonacciSpeedResistanceFan.tsx │ │ ├── fibonacciSpiral.tsx │ │ ├── fiveWaves.tsx │ │ ├── gannBox.tsx │ │ ├── horizontalRayLine.tsx │ │ ├── horizontalSegment.tsx │ │ ├── horizontalStraightLine.tsx │ │ ├── index.ts │ │ ├── invisible.tsx │ │ ├── lock.tsx │ │ ├── parallelStraightLine.tsx │ │ ├── parallelogram.tsx │ │ ├── priceChannelLine.tsx │ │ ├── priceLine.tsx │ │ ├── rayLine.tsx │ │ ├── rect.tsx │ │ ├── remove.tsx │ │ ├── segment.tsx │ │ ├── straightLine.tsx │ │ ├── strongMagnet.tsx │ │ ├── threeWaves.tsx │ │ ├── triangle.tsx │ │ ├── unlock.tsx │ │ ├── verticalRayLine.tsx │ │ ├── verticalSegment.tsx │ │ ├── verticalStraightLine.tsx │ │ ├── visible.tsx │ │ ├── weakMagnet.tsx │ │ └── xabcd.tsx │ ├── index.less │ └── index.tsx │ ├── index.less │ ├── index.tsx │ ├── indicator-modal │ ├── index.less │ └── index.tsx │ ├── indicator-setting-modal │ ├── data.ts │ ├── index.less │ └── index.tsx │ ├── period-bar │ ├── index.less │ └── index.tsx │ ├── screenshot-modal │ └── index.tsx │ ├── setting-modal │ ├── data.ts │ ├── index.less │ └── index.tsx │ ├── symbol-search-modal │ ├── index.less │ └── index.tsx │ └── timezone-modal │ ├── data.ts │ └── index.tsx ├── tsconfig.json ├── tsconfig.node.json └── vite.config.ts /.babelrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | "solid" 4 | ] 5 | } -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | /dist -------------------------------------------------------------------------------- /.eslintrc.cjs: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | env: { 3 | browser: true, 4 | es2021: true 5 | }, 6 | extends: 'standard-with-typescript', 7 | overrides: [ 8 | ], 9 | parserOptions: { 10 | ecmaVersion: 'latest', 11 | sourceType: 'module' 12 | }, 13 | rules: { 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /.github/workflows/deploy-docs.yml: -------------------------------------------------------------------------------- 1 | name: Deploy docs 2 | 3 | on: 4 | push: 5 | branches: [ "main" ] 6 | paths: 7 | - 'docs/**' 8 | 9 | jobs: 10 | build: 11 | runs-on: ubuntu-latest 12 | steps: 13 | - uses: actions/checkout@v3 14 | - uses: actions/setup-node@v3 15 | with: 16 | node-version: 16 17 | - run: npm install 18 | - run: npm run docs:build 19 | - uses: peaceiris/actions-gh-pages@v3 20 | with: 21 | github_token: ${{ secrets.DEPLOY_TOKEN }} 22 | publish_dir: ./website -------------------------------------------------------------------------------- /.github/workflows/npm-publish.yml: -------------------------------------------------------------------------------- 1 | name: Node.js Package 2 | 3 | on: 4 | release: 5 | types: [created] 6 | 7 | jobs: 8 | build: 9 | runs-on: ubuntu-latest 10 | steps: 11 | - uses: actions/checkout@v3 12 | - uses: actions/setup-node@v3 13 | with: 14 | node-version: 16 15 | - run: npm install && npm run build 16 | 17 | publish-npm: 18 | needs: build 19 | runs-on: ubuntu-latest 20 | steps: 21 | - uses: actions/checkout@v3 22 | - uses: actions/setup-node@v3 23 | with: 24 | node-version: 16 25 | registry-url: https://registry.npmjs.org/ 26 | - run: npm install && npm run build 27 | - run: npm publish --access=public 28 | env: 29 | NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}} 30 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /node_modules 2 | /dist 3 | /website 4 | /docs/.vitepress/cache -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "editor.tabSize": 2 3 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

KLineChart Pro

2 |

Financial chart built out of the box based on KLineChart.

3 | 4 |
5 | 6 | [![Version](https://badgen.net/npm/v/@klinecharts/pro)](https://www.npmjs.com/package/@klinecharts/pro) 7 | [![Size](https://badgen.net/bundlephobia/minzip/@klinecharts/pro@latest)](https://bundlephobia.com/package/@klinecharts/pro@latest) 8 | [![Typescript](https://badgen.net/npm/types/@klinecharts/pro)](dist/index.d.ts) 9 | [![LICENSE](https://badgen.net/github/license/klinecharts/pro)](LICENSE) 10 | 11 |
12 | 13 | ## Install 14 | ### Using npm or yarn 15 | ```bash 16 | # using npm 17 | npm install @klinecharts/pro --save 18 | 19 | # using yarn 20 | yarn add @klinecharts/pro 21 | ``` 22 | 23 | ### Using unpkg or jsDelivr 24 | ```html 25 | 26 | 27 | 28 | 29 | 30 | ``` 31 | 32 | ## Docs 33 | + [中文](https://pro.klinecharts.com) 34 | + [English](https://pro.klinecharts.com/en-US) 35 | 36 | ## ©️ License 37 | KLineChart Pro is available under the Apache License V2. 38 | -------------------------------------------------------------------------------- /docs/.vitepress/config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vitepress' 2 | 3 | // https://vitepress.dev/reference/site-config 4 | export default defineConfig({ 5 | title: 'KLineChart Pro', 6 | description: '基于KLineChart构建的开箱即用的金融图表', 7 | outDir: '../website', 8 | head: [ 9 | ['link', { rel: 'icon', type: 'image/svg+xml', href: '/logo.svg' }], 10 | ], 11 | markdown: { 12 | theme: { 13 | dark: 'material-theme-palenight', 14 | light: 'github-light' 15 | } 16 | }, 17 | locales: { 18 | root: { 19 | label: '简体中文', 20 | lang: 'zh-CN', 21 | link: '/', 22 | themeConfig: { 23 | nav: [{ text: '预览', link: 'https://preview.klinecharts.com' }], 24 | sidebar: [ 25 | { 26 | text: '介绍', 27 | link: '/introduction' 28 | }, 29 | { 30 | text: '快速开始', 31 | link: '/getting-started' 32 | }, 33 | { 34 | text: '数据说明', 35 | link: '/data-description' 36 | }, 37 | { 38 | text: '数据接入', 39 | link: '/data-access' 40 | }, 41 | { 42 | text: 'API', 43 | link: '/api' 44 | }, 45 | { 46 | text: '定制主题', 47 | link: '/theme' 48 | }, 49 | { 50 | text: '国际化', 51 | link: '/i18n' 52 | } 53 | ], 54 | docFooter: { 55 | prev: '上一篇', 56 | next: '下一篇' 57 | }, 58 | sidebarMenuLabel: '菜单', 59 | darkModeSwitchLabel: '主题', 60 | outlineTitle: '本页目录' 61 | } 62 | }, 63 | 'en-US': { 64 | label: 'English', 65 | lang: 'en-US', 66 | link: '/en-US/', 67 | themeConfig: { 68 | nav: [{ text: 'Preview', link: 'https://preview.klinecharts.com/#en-US' }], 69 | sidebar: [ 70 | { 71 | text: 'Introduction', 72 | link: '/en-US/introduction' 73 | }, 74 | { 75 | text: 'Getting Started', 76 | link: '/en-US/getting-started' 77 | }, 78 | { 79 | text: 'Data Description', 80 | link: '/en-US/data-description' 81 | }, 82 | { 83 | text: 'Data access', 84 | link: '/en-US/data-access' 85 | }, 86 | { 87 | text: 'API', 88 | link: '/en-US/api' 89 | }, 90 | { 91 | text: 'Theme', 92 | link: '/en-US/theme' 93 | }, 94 | { 95 | text: 'Internationalization', 96 | link: '/en-US/i18n' 97 | } 98 | ] 99 | } 100 | }, 101 | }, 102 | themeConfig: { 103 | // https://vitepress.dev/reference/default-theme-config 104 | logo: '/logo.svg', 105 | socialLinks: [ 106 | { icon: 'github', link: 'https://github.com/klinecharts/pro' } 107 | ], 108 | 109 | footer: { 110 | message: 'Released under the Apache License V2.', 111 | copyright: 'Copyright © 2018-present liihuu' 112 | } 113 | } 114 | }) 115 | -------------------------------------------------------------------------------- /docs/.vitepress/theme/index.ts: -------------------------------------------------------------------------------- 1 | // https://vitepress.dev/guide/custom-theme 2 | import { h } from 'vue' 3 | import Theme from 'vitepress/theme' 4 | 5 | 6 | import './style.css' 7 | 8 | export default { 9 | ...Theme, 10 | Layout: () => { 11 | return h(Theme.Layout, null, { 12 | // https://vitepress.dev/guide/extending-default-theme#layout-slots 13 | }) 14 | }, 15 | enhanceApp({ app, router, siteData }) { 16 | // ... 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /docs/.vitepress/theme/style.css: -------------------------------------------------------------------------------- 1 | /** 2 | * Customize default theme styling by overriding CSS variables: 3 | * https://github.com/vuejs/vitepress/blob/main/src/client/theme-default/styles/vars.css 4 | */ 5 | 6 | /** 7 | * Colors 8 | * -------------------------------------------------------------------------- */ 9 | 10 | :root { 11 | --vp-c-brand: #1677FF; 12 | --vp-c-brand-dark: #1677FF; 13 | --vp-c-brand-light: #3086ff; 14 | --vp-c-brand-lighter: #4995ff; 15 | --vp-c-brand-lightest: #afd0ff; 16 | /* --vp-c-brand-dark: #535bf2; 17 | --vp-c-brand-darker: #454ce1; */ 18 | --vp-c-brand-dimm: rgba(22, 119, 255, 0.08); 19 | } 20 | 21 | /** 22 | * Component: Button 23 | * -------------------------------------------------------------------------- */ 24 | 25 | :root { 26 | --vp-button-brand-border: var(--vp-c-brand-light); 27 | /* --vp-button-brand-text: var(--vp-c-white); */ 28 | --vp-button-brand-bg: var(--vp-c-brand); 29 | --vp-button-brand-hover-border: var(--vp-c-brand-light); 30 | /* --vp-button-brand-hover-text: var(--vp-c-white); */ 31 | --vp-button-brand-hover-bg: var(--vp-c-brand-light); 32 | --vp-button-brand-active-border: var(--vp-c-brand-light); 33 | /* --vp-button-brand-active-text: var(--vp-c-white); */ 34 | --vp-button-brand-active-bg: var(--vp-button-brand-bg); 35 | } 36 | 37 | /** 38 | * Component: Home 39 | * -------------------------------------------------------------------------- */ 40 | 41 | :root { 42 | --vp-home-hero-name-color: transparent; 43 | --vp-home-hero-name-background: -webkit-linear-gradient( 44 | 120deg, 45 | #2DC08E 30%, 46 | #F92855 47 | ); 48 | } 49 | 50 | /** 51 | * Component: Custom Block 52 | * -------------------------------------------------------------------------- */ 53 | 54 | :root { 55 | --vp-custom-block-tip-border: var(--vp-c-brand); 56 | --vp-custom-block-tip-text: var(--vp-c-brand-darker); 57 | --vp-custom-block-tip-bg: var(--vp-c-brand-dimm); 58 | } 59 | 60 | .dark { 61 | --vp-custom-block-tip-border: var(--vp-c-brand); 62 | --vp-custom-block-tip-text: var(--vp-c-brand-lightest); 63 | --vp-custom-block-tip-bg: var(--vp-c-brand-dimm); 64 | } 65 | 66 | .VPHomeHero .main { 67 | display: flex; 68 | flex-direction: column; 69 | align-items: center; 70 | } 71 | 72 | .VPHomeHero .main .name { 73 | margin-top: 6vh; 74 | } 75 | 76 | .VPHomeHero .main .text { 77 | margin-top: 12px; 78 | text-align: center; 79 | } 80 | 81 | 82 | /** 83 | * Component: Algolia 84 | * -------------------------------------------------------------------------- */ 85 | 86 | .DocSearch { 87 | --docsearch-primary-color: var(--vp-c-brand) !important; 88 | } 89 | 90 | /** 91 | * VitePress: Custom fix 92 | * -------------------------------------------------------------------------- */ 93 | 94 | /* 95 | Use lighter colors for links in dark mode for a11y. 96 | Also specify some classes twice to have higher specificity 97 | over scoped class data attribute. 98 | */ 99 | .dark .vp-doc a, 100 | .dark .vp-doc a > code, 101 | .dark .VPNavBarMenuLink.VPNavBarMenuLink:hover, 102 | .dark .VPNavBarMenuLink.VPNavBarMenuLink.active, 103 | .dark .link.link:hover, 104 | .dark .link.link.active, 105 | .dark .edit-link-button.edit-link-button, 106 | .dark .pager-link .title { 107 | color: var(--vp-c-brand-lighter); 108 | } 109 | 110 | .dark .vp-doc a:hover, 111 | .dark .vp-doc a > code:hover { 112 | color: var(--vp-c-brand-lightest); 113 | opacity: 1; 114 | } 115 | 116 | /* Transition by color instead of opacity */ 117 | .dark .vp-doc .custom-block a { 118 | transition: color 0.25s; 119 | } 120 | 121 | -------------------------------------------------------------------------------- /docs/api.md: -------------------------------------------------------------------------------- 1 | # API 2 | 3 | ## 创建图表对象 4 | ```typescript 5 | new KLineChartPro( 6 | options: { 7 | container: string | HTMLElement; 8 | styles?: DeepPartial; 9 | watermark?: string | Node; 10 | theme?: string; 11 | locale?: string; 12 | drawingBarVisible?: boolean; 13 | symbol: SymbolInfo; 14 | period: Period; 15 | periods?: Period[]; 16 | timezone?: string; 17 | mainIndicators?: string[]; 18 | subIndicators?: string[]; 19 | datafeed: Datafeed; 20 | } 21 | ) => KLineChartPro 22 | ``` 23 | + `container` 容器id或者容器 24 | + `styles` 核心图表样式 25 | + `watermark` 水印 26 | + `theme` 主题 27 | + `locale` 语言类型 28 | + `drawingBarVisible` 是否显示画线工具栏 29 | + `symbol` 标的 30 | + `period` 当前周期 31 | + `periods` 所以周期 32 | + `timezone` 时区 33 | + `mainIndicators` 主图指标 34 | + `subIndicators` 副图指标 35 | + `datafeed` 数据接入api实现 36 | 37 | ## 图表API 38 | ### setTheme(theme) 39 | ```typescript 40 | (theme: string) => void 41 | ``` 42 | 设置主题 43 | 44 | ### getTheme() 45 | ```typescript 46 | () => string 47 | ``` 48 | 获取主题 49 | 50 | ### setStyles(styles) 51 | ```typescript 52 | (styles: DeepPartial) => void 53 | ``` 54 | 设置核心图表样式 55 | 56 | ### getStyles() 57 | ```typescript 58 | () => Styles 59 | ``` 60 | 获取核心图表样式 61 | 62 | ### setLocale(locale) 63 | ```typescript 64 | (locale: string) => void 65 | ``` 66 | 设置语言 67 | 68 | ### getLocale() 69 | ```typescript 70 | () => string 71 | ``` 72 | 获取语言 73 | 74 | ### setTimezone(timezone) 75 | ```typescript 76 | (timezone: string) => void 77 | ``` 78 | 设置时区 79 | 80 | ### getTimezone() 81 | ```typescript 82 | () => string 83 | ``` 84 | 获取时区 85 | 86 | ### setSymbol(symbol) 87 | ```typescript 88 | (symbol: SymbolInfo) => void 89 | ``` 90 | 设置标的 91 | 92 | ### getSymbol() 93 | ```typescript 94 | () => SymbolInfo 95 | ``` 96 | 获取标的 97 | 98 | ### setPeriod(period) 99 | ```typescript 100 | (period: Period) => void 101 | ``` 102 | 设置周期 103 | 104 | ### getPeriod() 105 | ```typescript 106 | () => Period 107 | ``` 108 | 获取周期 109 | -------------------------------------------------------------------------------- /docs/data-access.md: -------------------------------------------------------------------------------- 1 | # 接入数据 2 | 可以使用默认的数据,和自定义数据完成数据接入。 3 | 4 | ## 使用默认数据 5 | 默认数据来源于 https://polygon.io/ ,在使用前需要去申请API key。申请完成后,通过内置`DefaultDatafeed`这个类完成数据接入。 6 | 示例: 7 | ```typescript 8 | import { KLineChartPro, DefaultDatafeed } from '@klinecharts/pro' 9 | const chart = new KLineChartPro({ 10 | container: document.getElementById('container'), 11 | datafeed: new DefaultDatafeed(`${polygonIoApiKey}`) 12 | }) 13 | ``` 14 | 15 | ## 使用自定义数据 16 | 需要使用自定义数据,只需要按如下步骤即可。 17 | 18 | ### 第一步,实现数据接入API 19 | ```typescript 20 | class CustomDatafeed { 21 | /** 22 | * 模糊搜索标的 23 | * 在搜索框输入的时候触发 24 | * 返回标的信息数组 25 | */ 26 | searchSymbols (search?: string): Promise { 27 | // 根据模糊字段远程拉取标的数据 28 | } 29 | 30 | /** 31 | * 获取历史k线数据 32 | * 当标的和周期发生变化的时候触发 33 | * 34 | * 返回标的k线数据数组 35 | */ 36 | getHistoryKLineData (symbol: SymbolInfo, period: Period, from: number, to: number): Promise { 37 | // 完成数据请求 38 | } 39 | 40 | /** 41 | * 订阅标的在某个周期的实时数据 42 | * 当标的和周期发生变化的时候触发 43 | * 44 | * 通过callback告知图表接收数据 45 | */ 46 | subscribe (symbol: SymbolInfo, period: Period, callback: DatafeedSubscribeCallback): void { 47 | // 完成ws订阅或者http轮询 48 | } 49 | 50 | /** 51 | * 取消订阅标的在某个周期的实时数据 52 | * 当标的和周期发生变化的时候触发 53 | * 54 | */ 55 | unsubscribe (symbol: SymbolInfo, period: Period): void { 56 | // 完成ws订阅取消或者http轮询取消 57 | } 58 | } 59 | ``` 60 | 61 | ### 第二步,接入自定义数据 62 | ```typescript 63 | import { KLineChartPro, DefaultDatafeed } from '@klinecharts/pro' 64 | const chart = new KLineChartPro({ 65 | container: document.getElementById('container'), 66 | datafeed: new CustomDatafeed() 67 | }) 68 | ``` -------------------------------------------------------------------------------- /docs/data-description.md: -------------------------------------------------------------------------------- 1 | # 数据说明 2 | 3 | ## 周期 4 | ```typescript 5 | interface Period { 6 | // 时间跨度乘数,如1,3,5 7 | multiplier: number; 8 | 9 | // 时间跨度,如'year','month' 10 | timespan: string; 11 | 12 | // 文字,用于显示,如'1H','5H' 13 | text: string; 14 | } 15 | ``` 16 | 17 | ## 标的信息 18 | ```typescript 19 | interface SymbolInfo { 20 | // 唯一标识 21 | ticker: string; 22 | 23 | // 标的名 24 | name?: string 25 | 26 | // 标的简短名 27 | shortName?: string 28 | 29 | // 交易所 30 | exchange?: string 31 | 32 | // 市场分类 33 | market?: string 34 | 35 | // 价格精度 36 | pricePrecision?: number 37 | 38 | // 数量精度 39 | volumePrecision?: number 40 | 41 | // 价格币种 42 | priceCurrency?: string 43 | 44 | // 类型 45 | type?: string 46 | 47 | // logo url 48 | logo?: string 49 | } 50 | ``` -------------------------------------------------------------------------------- /docs/en-US/api.md: -------------------------------------------------------------------------------- 1 | # API 2 | 3 | ## Creating chart 4 | ```typescript 5 | new KLineChartPro( 6 | options: { 7 | container: string | HTMLElement; 8 | styles?: DeepPartial; 9 | watermark?: string | Node; 10 | theme?: string; 11 | locale?: string; 12 | drawingBarVisible?: boolean; 13 | symbol: SymbolInfo; 14 | period: Period; 15 | periods?: Period[]; 16 | timezone?: string; 17 | mainIndicators?: string[]; 18 | subIndicators?: string[]; 19 | datafeed: Datafeed; 20 | } 21 | ) => KLineChartPro 22 | ``` 23 | + `container` Container id or container 24 | + `styles` Core chart styles 25 | + `watermark` Watermark 26 | + `theme` Theme 27 | + `locale` Language 28 | + `drawingBarVisible` Whether to display the drawing toolbar 29 | + `symbol` Symbol 30 | + `period` Period 31 | + `periods` All periods 32 | + `timezone` Timezone 33 | + `mainIndicators` Main indicators 34 | + `subIndicators` Sub indicators 35 | + `datafeed` Data access API implementation 36 | 37 | ## Chart API 38 | ### setTheme(theme) 39 | ```typescript 40 | (theme: string) => void 41 | ``` 42 | Set theme. 43 | 44 | ### getTheme() 45 | ```typescript 46 | () => string 47 | ``` 48 | Get theme. 49 | 50 | ### setStyles(styles) 51 | ```typescript 52 | (styles: DeepPartial) => void 53 | ``` 54 | Set core chart styles. 55 | 56 | ### getStyles() 57 | ```typescript 58 | () => Styles 59 | ``` 60 | Get core chart styles. 61 | 62 | ### setLocale(locale) 63 | ```typescript 64 | (locale: string) => void 65 | ``` 66 | Set language. 67 | 68 | ### getLocale() 69 | ```typescript 70 | () => string 71 | ``` 72 | Get language. 73 | 74 | ### setTimezone(timezone) 75 | ```typescript 76 | (timezone: string) => void 77 | ``` 78 | Set timezone. 79 | 80 | ### getTimezone() 81 | ```typescript 82 | () => string 83 | ``` 84 | Get timezone. 85 | 86 | ### setSymbol(symbol) 87 | ```typescript 88 | (symbol: SymbolInfo) => void 89 | ``` 90 | Set symbol 91 | 92 | ### getSymbol() 93 | ```typescript 94 | () => SymbolInfo 95 | ``` 96 | Get symbol. 97 | 98 | ### setPeriod(period) 99 | ```typescript 100 | (period: Period) => void 101 | ``` 102 | Set period. 103 | 104 | ### getPeriod() 105 | ```typescript 106 | () => Period 107 | ``` 108 | Get period. 109 | -------------------------------------------------------------------------------- /docs/en-US/data-access.md: -------------------------------------------------------------------------------- 1 | # Access data 2 | You can use default data and custom data to complete data access. 3 | 4 | ## Use default data 5 | The default data source is https://polygon.io/. You need to apply for an API key before using it. After the application is completed, data access is completed through the built-in `DefaultDatafeed` class. 6 | Sample, 7 | ```typescript 8 | import { KLineChartPro, DefaultDatafeed } from '@klinecharts/pro' 9 | const chart = new KLineChartPro({ 10 | container: document.getElementById('container'), 11 | datafeed: new DefaultDatafeed(`${polygonIoApiKey}`) 12 | }) 13 | ``` 14 | 15 | ## Use custom data 16 | To use custom data, just follow the steps below. 17 | 18 | ### Step 1: Implement the data access API 19 | ```typescript 20 | class CustomDatafeed { 21 | /** 22 | * Fuzzy search symbols 23 | * Triggered when the search box is entered 24 | * Returns an array of symbol information 25 | */ 26 | searchSymbols (search?: string): Promise { 27 | // Remote pull of symbol data based on fuzzy fields 28 | } 29 | 30 | /** 31 | * Pull historical k-line data 32 | * Triggered when the symbol and period change 33 | * 34 | * Returns the symbol k-line data array 35 | */ 36 | getHistoryKLineData (symbol: SymbolInfo, period: Period, from: number, to: number): Promise { 37 | // Complete data request 38 | } 39 | 40 | /** 41 | * Subscribe to real-time data of the symbol in a certain period 42 | * Triggered when the symbol and period change 43 | * 44 | * Notify chart to receive data through callback 45 | */ 46 | subscribe (symbol: SymbolInfo, period: Period, callback: DatafeedSubscribeCallback): void { 47 | // Complete ws subscription or http polling 48 | } 49 | 50 | /** 51 | * Unsubscribe to real-time data of the symbol in a certain period 52 | * Triggered when the symbol and period change 53 | * 54 | */ 55 | unsubscribe (symbol: SymbolInfo, period: Period): void { 56 | // Complete ws subscription cancellation or http polling cancellation 57 | } 58 | } 59 | ``` 60 | 61 | ### Step 2: Access custom data 62 | ```typescript 63 | import { KLineChartPro, DefaultDatafeed } from '@klinecharts/pro' 64 | const chart = new KLineChartPro({ 65 | container: document.getElementById('container'), 66 | datafeed: new CustomDatafeed() 67 | }) 68 | ``` -------------------------------------------------------------------------------- /docs/en-US/data-description.md: -------------------------------------------------------------------------------- 1 | # Data Description 2 | 3 | ## Period 4 | ```typescript 5 | interface Period { 6 | // Time span multiplier, such as 1, 3, 5 7 | multiplier: number; 8 | 9 | // Time span, such as 'year', 'month' 10 | timespan: string; 11 | 12 | // Text for display, such as '1H', '5H' 13 | text: string; 14 | } 15 | ``` 16 | 17 | ## Symbol information 18 | ```typescript 19 | interface SymbolInfo { 20 | // Unique identification 21 | ticker: string; 22 | 23 | // Name 24 | name?: string 25 | 26 | // Short name 27 | shortName?: string 28 | 29 | // Exchange 30 | exchange?: string 31 | 32 | // Market classification 33 | market?: string 34 | 35 | // Price precision 36 | pricePrecision?: number 37 | 38 | // Volume precision 39 | volumePrecision?: number 40 | 41 | // Price currency 42 | priceCurrency?: string 43 | 44 | // Type 45 | type?: string 46 | 47 | // logo url 48 | logo?: string 49 | } 50 | ``` -------------------------------------------------------------------------------- /docs/en-US/getting-started.md: -------------------------------------------------------------------------------- 1 | # Getting started 2 | 3 | ## Installing 4 | Use npm or yarn 5 | ```bash 6 | # npm 7 | npm install klinecharts @klinecharts/pro 8 | 9 | # yarn 10 | yarn install klinecharts @klinecharts/pro 11 | ``` 12 | If it is imported directly through a script tag, you can use either of the following two CDNs 13 | ::: warning Note 14 | For production environments, it is recommended to use a clear version number to avoid unexpected damage caused by new versions. 15 | ::: 16 | 17 | ```html 18 | 19 | 20 | 21 | 22 | 23 | ``` 24 | 25 | ## Usage 26 | ### Step 1: Create a container 27 | ```html 28 |
29 | ``` 30 | ### Step 2: Create an instance 31 | In projects using package managers such as npm and yarn 32 | ```javascript 33 | // Import js 34 | import { KLineChartPro, DefaultDatafeed } from '@klinecharts/pro' 35 | // Import css 36 | import '@klinecharts/pro/dist/klinecharts-pro.css' 37 | 38 | // Create Instance 39 | const chart = new KLineChartPro({ 40 | container: document.getElementById('container'), 41 | // Default symbol info 42 | symbol: { 43 | exchange: 'XNYS', 44 | market: 'stocks', 45 | name: 'Alibaba Group Holding Limited American Depositary Shares, each represents eight Ordinary Shares', 46 | shortName: 'BABA', 47 | ticker: 'BABA', 48 | priceCurrency: 'usd', 49 | type: 'ADRC', 50 | }, 51 | // Default period 52 | period: { multiplier: 15, timespan: 'minute', text: '15m' }, 53 | // The default data access is used here. If the default data is also used in actual use, you need to go to the https://polygon.io/ apply for API key 54 | datafeed: new DefaultDatafeed(`${polygonIoApiKey}`) 55 | }) 56 | ``` 57 | 58 | In projects introduced directly through script tags 59 | ```html 60 | 61 | 62 | 63 | 64 | 65 | 85 | ``` 86 | The first chart is created. Working example 87 | -------------------------------------------------------------------------------- /docs/en-US/i18n.md: -------------------------------------------------------------------------------- 1 | # Internationalization 2 | 3 | Currently, the chart has two built-in languages, `en-US` and `zh-CN`. The default language is `zh-CN`. If you need to use another language, you need to complete the language registration for the core chart and the language registration for the pro chart. 4 | 5 | ## Language register for core chart 6 | ```typescript 7 | import klinecharts from 'klinecharts' 8 | 9 | // See https://klinecharts.com/en-US/guide/i18n.html 10 | klinecharts.registerLocale(`${key}`, { 11 | ...... 12 | }) 13 | ``` 14 | 15 | ## Language register for pro 16 | ```typescript 17 | import { loadLocales } from '@klinecharts/pro' 18 | 19 | // For specific keys, see https://github.com/klinecharts/pro/blob/main/src/i18n/zh-CN.json 20 | loadLocales(`${key}`, { 21 | "indicator": "xxx", 22 | "main_indicator": "xxx", 23 | "sub_indicator": "xxx", 24 | ...... 25 | ...... 26 | }) 27 | ``` 28 | -------------------------------------------------------------------------------- /docs/en-US/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Financial chart built out of the box based on KLineChart 3 | 4 | layout: home 5 | 6 | hero: 7 | name: KLineChart Pro 8 | text: Financial chart built out of the box based on KLineChart 9 | tagline: Use KLineChart like a Pro 10 | actions: 11 | - theme: brand 12 | text: Getting Started 13 | link: /en-US/getting-started 14 | - theme: alt 15 | text: View on Github 16 | link: https://github.com/klinecharts/pro 17 | --- -------------------------------------------------------------------------------- /docs/en-US/introduction.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | ## What is KLineChart Pro? 4 | KLineChart Pro is a financial chart that encapsulates a layer of UI based on KLineChart. 5 | 6 | ## Why do I need KLineChart Pro? 7 | Among KLineChart users, some do not have front-end related knowledge reserves, making it difficult to use. KLineChart Pro is designed to help them quickly integrate charts and focus their energy and time on more important things. 8 | 9 | 10 | ## Applicable groups 11 | KLineChart users who have no reserves of front-end knowledge, insufficient reserves, and do not want to spend energy on the UI. For users with strong customization requirements, it is recommended to self package on the basis of KLineChart. 12 | 13 | 14 | -------------------------------------------------------------------------------- /docs/en-US/theme.md: -------------------------------------------------------------------------------- 1 | # Theme customization 2 | The chart has two built-in themes, `dark` and `light`, and the default is `light`. If you need to customize other topics, you need to complete the style customization of the core chart and the customization of the CSS. 3 | 4 | ## Customization of core chart 5 | Set through the API `setStyles(styles)`. 6 | 7 | ## CSS related styles 8 | The css style uses css variables to control the color, as follows, 9 | ```css 10 | .klinecharts-pro { 11 | /* Light theme colors */ 12 | --klinecharts-pro-primary-color: #1677ff; 13 | --klinecharts-pro-hover-background-color: rgba(22, 119, 255, 0.15); 14 | --klinecharts-pro-background-color: #FFFFFF; 15 | --klinecharts-pro-popover-background-color: #FFFFFF; 16 | --klinecharts-pro-text-color: #051441; 17 | --klinecharts-pro-text-second-color: #76808F; 18 | --klinecharts-pro-border-color: #ebedf1; 19 | --klinecharts-pro-selected-color: rgba(22, 119, 255, 0.15); 20 | } 21 | 22 | /* Dark theme colors */ 23 | .klinecharts-pro[data-theme="dark"] { 24 | --klinecharts-pro-hover-background-color: rgba(22, 119, 255, 0.15); 25 | --klinecharts-pro-background-color: #151517;; 26 | --klinecharts-pro-popover-background-color: #1c1c1f;; 27 | --klinecharts-pro-text-color: #F8F8F8; 28 | --klinecharts-pro-text-second-color: #929AA5; 29 | --klinecharts-pro-border-color: #292929; 30 | } 31 | ``` 32 | -------------------------------------------------------------------------------- /docs/getting-started.md: -------------------------------------------------------------------------------- 1 | # 快速开始 2 | ## 安装 3 | 通过 npm 或 yarn 命令安装 4 | ```bash 5 | # npm 6 | npm install klinecharts @klinecharts/pro 7 | 8 | # yarn 9 | yarn install klinecharts @klinecharts/pro 10 | ``` 11 | 如果是直接通过 script 标签引入,可以使用下面两个 CDN 中的任意一个即可 12 | ::: warning 注意 13 | 对于生产环境,推荐使用一个明确的版本号,以避免新版本造成的不可预期的破坏。 14 | ::: 15 | 16 | ```html 17 | 18 | 19 | 20 | 21 | 22 | ``` 23 | 24 | ## 使用 25 | ### 第一步,创建容器 26 | ```html 27 |
28 | ``` 29 | ### 第二步,创建实例 30 | 在使用npm, yarn等包管理器中项目中 31 | ```javascript 32 | // 引入js 33 | import { KLineChartPro, DefaultDatafeed } from '@klinecharts/pro' 34 | // 引入样式 35 | import '@klinecharts/pro/dist/klinecharts-pro.css' 36 | 37 | // 创建实例 38 | const chart = new KLineChartPro({ 39 | container: document.getElementById('container'), 40 | // 初始化标的信息 41 | symbol: { 42 | exchange: 'XNYS', 43 | market: 'stocks', 44 | name: 'Alibaba Group Holding Limited American Depositary Shares, each represents eight Ordinary Shares', 45 | shortName: 'BABA', 46 | ticker: 'BABA', 47 | priceCurrency: 'usd', 48 | type: 'ADRC', 49 | }, 50 | // 初始化周期 51 | period: { multiplier: 15, timespan: 'minute', text: '15m' }, 52 | // 这里使用默认的数据接入,如果实际使用中也使用默认数据,需要去 https://polygon.io/ 申请 API key 53 | datafeed: new DefaultDatafeed(`${polygonIoApiKey}`) 54 | }) 55 | ``` 56 | 57 | 在直接通过 script 标签引入的项目中 58 | ```html 59 | 60 | 61 | 62 | 63 | 64 | 84 | ``` 85 | 第一个图表就创建完成了. 这里的工作示例 86 | -------------------------------------------------------------------------------- /docs/i18n.md: -------------------------------------------------------------------------------- 1 | # 国际化 2 | 目前图表内置了`en-US`和`zh-CN`两种语言,默认语言是`zh-CN`。如果需要使用其他语言,需要完成核心图表的语言注册和pro图表的语言注册。 3 | 4 | ## 核心图表的语言注册 5 | ```typescript 6 | import klinecharts from 'klinecharts' 7 | 8 | // 可参阅 https://klinecharts.com/guide/i18n.html 9 | klinecharts.registerLocale(`${key}`, { 10 | ...... 11 | }) 12 | ``` 13 | 14 | ## Pro图表语言注册 15 | ```typescript 16 | import { loadLocales } from '@klinecharts/pro' 17 | 18 | // 具体的key参阅 https://github.com/klinecharts/pro/blob/main/src/i18n/zh-CN.json 19 | loadLocales(`${key}`, { 20 | "indicator": "xxx", 21 | "main_indicator": "xxx", 22 | "sub_indicator": "xxx", 23 | ...... 24 | ...... 25 | }) 26 | ``` 27 | -------------------------------------------------------------------------------- /docs/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 基于KLineChart构建的开箱即用的金融图表 3 | 4 | layout: home 5 | 6 | hero: 7 | name: KLineChart Pro 8 | text: 基于KLineChart构建的开箱即用的金融图表 9 | tagline: 像专业人士一样使用KLineChart 10 | actions: 11 | - theme: brand 12 | text: 快速开始 13 | link: /getting-started 14 | - theme: alt 15 | text: 在 Github 上查看 16 | link: https://github.com/klinecharts/pro 17 | --- -------------------------------------------------------------------------------- /docs/introduction.md: -------------------------------------------------------------------------------- 1 | # 介绍 2 | 3 | ## 什么是KLineChart Pro? 4 | KLineChart Pro是在KLineChart的基础上,封装了一层UI的金融图表。 5 | 6 | ## 为什么要有KLineChart Pro? 7 | 在KLineChart的用户中,有一部分没有前端相关的知识储备,使用起来困难。KLineChart Pro旨在帮助他们快速集成图表,将精力和时间放在更重要的事情上。 8 | 9 | ## 适用群体 10 | 前端知识无储备、储备不足和不想花精力在UI上的KLineChart用户。对于自定义要求极强的用户,建议在KLineChart的基础上自行封装。 11 | 12 | 13 | -------------------------------------------------------------------------------- /docs/public/CNAME: -------------------------------------------------------------------------------- 1 | pro.klinecharts.com -------------------------------------------------------------------------------- /docs/theme.md: -------------------------------------------------------------------------------- 1 | # 主题定制 2 | 图表内置了`dark`和`light`两种主题,默认是`light`。如果需要定制其它主题,需要完成核心图表的样式定制和css的定制。 3 | 4 | ## 核心图表的定制 5 | 通过api `setStyles(styles)`设置。 6 | 7 | ## css相关样式 8 | css样式采用css变量控制颜色,具体如下, 9 | ```css 10 | .klinecharts-pro { 11 | /* 亮色主题颜色 */ 12 | --klinecharts-pro-primary-color: #1677ff; 13 | --klinecharts-pro-hover-background-color: rgba(22, 119, 255, 0.15); 14 | --klinecharts-pro-background-color: #FFFFFF; 15 | --klinecharts-pro-popover-background-color: #FFFFFF; 16 | --klinecharts-pro-text-color: #051441; 17 | --klinecharts-pro-text-second-color: #76808F; 18 | --klinecharts-pro-border-color: #ebedf1; 19 | --klinecharts-pro-selected-color: rgba(22, 119, 255, 0.15); 20 | } 21 | 22 | /* 暗色主题颜色 */ 23 | .klinecharts-pro[data-theme="dark"] { 24 | --klinecharts-pro-hover-background-color: rgba(22, 119, 255, 0.15); 25 | --klinecharts-pro-background-color: #151517;; 26 | --klinecharts-pro-popover-background-color: #1c1c1f;; 27 | --klinecharts-pro-text-color: #F8F8F8; 28 | --klinecharts-pro-text-second-color: #929AA5; 29 | --klinecharts-pro-border-color: #292929; 30 | } 31 | ``` 32 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@klinecharts/pro", 3 | "version": "0.1.1", 4 | "description": "Financial chart built out of the box based on KLineChart.", 5 | "type": "module", 6 | "main": "./dist/klinecharts-pro.umd.js", 7 | "module": "./dist/klinecharts-pro.js", 8 | "types": "./dist/index.d.ts", 9 | "files": [ 10 | "LICENSE", 11 | "README.md", 12 | "dist/" 13 | ], 14 | "repository": { 15 | "type": "git", 16 | "url": "https://github.com/klinecharts/pro" 17 | }, 18 | "keywords": [ 19 | "klinecharts", 20 | "pro", 21 | "candlestick", 22 | "finance", 23 | "stock", 24 | "chart", 25 | "canvas" 26 | ], 27 | "author": "liihuu", 28 | "license": "Apache-2.0", 29 | "private": false, 30 | "scripts": { 31 | "build-core": "tsc && vite build", 32 | "build-dts": "dts-bundle-generator --no-banner true --umd-module-name klinechartspro -o dist/index.d.ts src/index.ts", 33 | "build": "npm run build-core && npm run build-dts", 34 | "docs:dev": "vitepress dev docs", 35 | "docs:build": "vitepress build docs", 36 | "docs:preview": "vitepress preview docs", 37 | "docs:deploy": "npm run docs:build && gh-pages -d website" 38 | }, 39 | "devDependencies": { 40 | "@solidjs/testing-library": "^0.6.0", 41 | "@testing-library/jest-dom": "^5.16.5", 42 | "@types/lodash": "^4.14.191", 43 | "@types/testing-library__jest-dom": "^5.14.5", 44 | "@typescript-eslint/eslint-plugin": "^5.54.0", 45 | "babel-preset-solid": "^1.6.10", 46 | "dts-bundle-generator": "^7.2.0", 47 | "eslint": "^8.35.0", 48 | "eslint-config-standard-with-typescript": "^34.0.0", 49 | "eslint-plugin-import": "^2.27.5", 50 | "eslint-plugin-n": "^15.6.1", 51 | "eslint-plugin-promise": "^6.1.1", 52 | "gh-pages": "^5.0.0", 53 | "less": "^4.1.3", 54 | "less-loader": "^11.1.0", 55 | "typescript": "^4.9.5", 56 | "vite": "^4.1.1", 57 | "vite-plugin-solid": "^2.6.1", 58 | "vitepress": "^1.0.0-alpha.75", 59 | "vitest": "^0.28.4" 60 | }, 61 | "dependencies": { 62 | "lodash": "^4.17.21", 63 | "solid-js": "^1.6.11" 64 | }, 65 | "peerDependencies": { 66 | "klinecharts": ">=9.0.0" 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /src/base.less: -------------------------------------------------------------------------------- 1 | @prefix-cls: klinecharts-pro; 2 | 3 | @period-bar-height: 38px; 4 | @drawing-bar-width: 52px; 5 | @widget-width: calc(100% - @drawing-bar-width); 6 | @widget-height: calc(100% - @period-bar-height); 7 | 8 | @c-primary: #1677ff; 9 | 10 | // @c-hover-background-light: fade(#353539, 10%); 11 | @c-hover-background-light: fade(#1677ff, 15%); 12 | @c-popover-background-light: #ffffff; 13 | @c-background-light: #ffffff; 14 | @c-text-light: #051441; 15 | @c-text-second-light: #76808F; 16 | @c-border-light: #ebedf1; 17 | 18 | @c-hover-background-dark: fade(#1677ff, 15%); 19 | // @c-hover-background-dark: fade(#a3a4d5, 10%); 20 | @c-background-dark: #151517; 21 | @c-popover-background-dark: #1c1c1f; 22 | @c-text-dark: #f8f8f8; 23 | @c-text-second-dark: #929AA5; 24 | @c-border-dark: #292929; -------------------------------------------------------------------------------- /src/component/button/index.less: -------------------------------------------------------------------------------- 1 | @import (reference) '../../base.less'; 2 | 3 | .@{prefix-cls}-button { 4 | display: flex; 5 | flex-direction: row; 6 | align-items: center; 7 | justify-content: center; 8 | outline: none; 9 | width: 90px; 10 | height: 36px; 11 | font-size: 14px; 12 | border-radius: 2px; 13 | border: solid 1px var(--klinecharts-pro-primary-color); 14 | cursor: pointer; 15 | background-color: transparent; 16 | margin-left: 20px; 17 | box-sizing: border-box; 18 | &.confirm { 19 | color: #ffffff; 20 | background-color: var(--klinecharts-pro-primary-color); 21 | } 22 | &.cancel { 23 | color: var(--klinecharts-pro-primary-color); 24 | border: solid 1px var(--klinecharts-pro-primary-color); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/component/button/index.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * Licensed under the Apache License, Version 2.0 (the "License"); 3 | * you may not use this file except in compliance with the License. 4 | * You may obtain a copy of the License at 5 | 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | * See the License for the specific language governing permissions and 12 | * limitations under the License. 13 | */ 14 | 15 | import { ParentComponent, ParentProps, JSX } from 'solid-js' 16 | 17 | export type ButtonType = 'confirm' | 'cancel' 18 | 19 | export interface ButtonProps extends ParentProps { 20 | class?: string 21 | style?: JSX.CSSProperties | string 22 | type?: ButtonType 23 | onClick?: () => void 24 | } 25 | 26 | const Button: ParentComponent = props => { 27 | return ( 28 | 34 | ) 35 | } 36 | 37 | export default Button 38 | -------------------------------------------------------------------------------- /src/component/checkbox/index.less: -------------------------------------------------------------------------------- 1 | @import (reference) '../../base.less'; 2 | 3 | .@{prefix-cls}-checkbox { 4 | display: flex; 5 | flex-direction: row; 6 | align-items: center; 7 | justify-content: center; 8 | font-size: 14px; 9 | color: var(--klinecharts-pro-text-color); 10 | fill: var(--klinecharts-pro-text-color); 11 | cursor: pointer; 12 | .icon { 13 | width: 20px; 14 | height: 20px; 15 | } 16 | 17 | .label { 18 | display: inline-block; 19 | margin-left: 6px; 20 | } 21 | &.checked { 22 | color: var(--klinecharts-pro-primary-color); 23 | fill: var(--klinecharts-pro-primary-color); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/component/checkbox/index.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * Licensed under the Apache License, Version 2.0 (the "License"); 3 | * you may not use this file except in compliance with the License. 4 | * You may obtain a copy of the License at 5 | 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | * See the License for the specific language governing permissions and 12 | * limitations under the License. 13 | */ 14 | 15 | import { Component, createSignal, JSX, createEffect } from 'solid-js' 16 | 17 | 18 | const CheckedIcon = () => { 19 | return ( 20 | 23 | 25 | 26 | ) 27 | } 28 | 29 | const NormalIcon = () => { 30 | return ( 31 | 34 | 36 | 37 | ) 38 | } 39 | 40 | export interface CheckboxProps { 41 | class?: string 42 | style?: JSX.CSSProperties | string 43 | checked?: boolean 44 | label?: JSX.Element 45 | onChange?: (checked: boolean) => void 46 | } 47 | 48 | const Checkbox: Component = props => { 49 | const [innerChecked, setInnderChecked] = createSignal(props.checked ?? false) 50 | 51 | createEffect(() => { 52 | if ('checked' in props) { 53 | setInnderChecked(props.checked as boolean) 54 | } 55 | }) 56 | 57 | return ( 58 |
{ 62 | const ck = !innerChecked(); 63 | props.onChange && props.onChange(ck); 64 | setInnderChecked(ck); 65 | }}> 66 | {innerChecked() ? : } 67 | { 68 | props.label && {props.label}} 69 |
70 | ) 71 | } 72 | 73 | export default Checkbox 74 | -------------------------------------------------------------------------------- /src/component/empty/index.less: -------------------------------------------------------------------------------- 1 | @import (reference) '../../base.less'; 2 | 3 | .@{prefix-cls}-empty { 4 | display: flex; 5 | flex-direction: column; 6 | align-items: center; 7 | justify-content: center; 8 | position: absolute; 9 | left: 0; 10 | top: 0; 11 | width: 100%; 12 | height: 100%; 13 | justify-content: center; 14 | align-items: center; 15 | z-index: 99; 16 | fill: var(--klinecharts-pro-text-second-color); 17 | color: var(--klinecharts-pro-text-second-color); 18 | .icon { 19 | width: 50px; 20 | height: 50px; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/component/empty/index.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * Licensed under the Apache License, Version 2.0 (the "License"); 3 | * you may not use this file except in compliance with the License. 4 | * You may obtain a copy of the License at 5 | 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | * See the License for the specific language governing permissions and 12 | * limitations under the License. 13 | */ 14 | 15 | 16 | import { VoidComponent } from 'solid-js' 17 | 18 | const Empty: VoidComponent = () => { 19 | return ( 20 |
22 | 25 | 27 | 28 |
29 | ) 30 | } 31 | 32 | export default Empty 33 | -------------------------------------------------------------------------------- /src/component/index.less: -------------------------------------------------------------------------------- 1 | @import './button/index.less'; 2 | @import './checkbox/index.less'; 3 | @import './list/index.less'; 4 | @import './modal/index.less'; 5 | @import './select/index.less'; 6 | @import './input/index.less'; 7 | @import './loading/index.less'; 8 | @import './empty/index.less'; 9 | @import './switch/index.less'; -------------------------------------------------------------------------------- /src/component/index.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * Licensed under the Apache License, Version 2.0 (the "License"); 3 | * you may not use this file except in compliance with the License. 4 | * You may obtain a copy of the License at 5 | 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | * See the License for the specific language governing permissions and 12 | * limitations under the License. 13 | */ 14 | 15 | import Button from './button' 16 | import Checkbox from './checkbox' 17 | import List from './list' 18 | import Modal from './modal' 19 | import Select, { SelectDataSourceItem } from './select' 20 | import Input from './input' 21 | import Loading from './loading' 22 | import Switch from './switch' 23 | 24 | export { 25 | Button, Checkbox, List, Modal, Select, Input, Loading, Switch 26 | } 27 | 28 | export type { SelectDataSourceItem } -------------------------------------------------------------------------------- /src/component/input/index.less: -------------------------------------------------------------------------------- 1 | @import (reference) '../../base.less'; 2 | 3 | .@{prefix-cls}-input { 4 | display: flex; 5 | flex-direction: row; 6 | align-items: center; 7 | position: relative; 8 | height: 34px; 9 | border: solid 1px var(--klinecharts-pro-border-color); 10 | border-radius: 2px; 11 | padding: 0 12px; 12 | font-size: 12px; 13 | color: var(--klinecharts-pro-text-color); 14 | box-sizing: border-box; 15 | cursor: pointer; 16 | &[data-status="focus"] { 17 | border-color: var(--klinecharts-pro-primary-color); 18 | } 19 | .prefix { 20 | display: flex; 21 | white-space: nowrap; 22 | padding-right: 10px; 23 | } 24 | .suffix { 25 | display: flex; 26 | white-space: nowrap; 27 | padding-left: 10px; 28 | } 29 | .value { 30 | width: 100%; 31 | border: none; 32 | outline: none; 33 | border: none; 34 | background: transparent; 35 | color: var(--klinecharts-pro-text-color); 36 | font-size: 14px; 37 | cursor: pointer; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/component/input/index.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * Licensed under the Apache License, Version 2.0 (the "License"); 3 | * you may not use this file except in compliance with the License. 4 | * You may obtain a copy of the License at 5 | 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | * See the License for the specific language governing permissions and 12 | * limitations under the License. 13 | */ 14 | 15 | import { JSX, Component, mergeProps, Show, createSignal } from 'solid-js' 16 | 17 | export interface InputProps { 18 | class?: string 19 | style?: JSX.CSSProperties 20 | prefix?: JSX.Element 21 | suffix?: JSX.Element 22 | precision?: number 23 | min?: number 24 | max?: number 25 | placeholder?: string 26 | value: string | number 27 | disabled?: boolean 28 | onChange?: (v: string | number) => void 29 | } 30 | 31 | const Input: Component = p => { 32 | const props = mergeProps({ min: Number.MIN_SAFE_INTEGER, max: Number.MAX_SAFE_INTEGER }, p) 33 | let input: HTMLInputElement 34 | 35 | const [status, setStatus] = createSignal('normal') 36 | 37 | return ( 38 |
{ input?.focus() }}> 43 | 44 | {props.prefix} 45 | 46 | { input = el }} 48 | class="value" 49 | placeholder={props.placeholder ?? ''} 50 | value={props.value} 51 | onFocus={() => { setStatus('focus') }} 52 | onBlur={() => { setStatus('normal') }} 53 | onChange={(e) => { 54 | // @ts-expect-error 55 | const v = e.target.value 56 | if ('precision' in props) { 57 | let reg 58 | const decimalDigit = Math.max(0, Math.floor(props.precision!)) 59 | if (decimalDigit <= 0) { 60 | reg = new RegExp(/^[1-9]\d*$/) 61 | } else { 62 | reg = new RegExp('^\\d+\\.?\\d{0,' + decimalDigit + '}$') 63 | } 64 | if (v === '' || (reg.test(v) && +v >= props.min && +v <= props.max)) { 65 | props.onChange?.(v === '' ? v : +v) 66 | } 67 | } else { 68 | props.onChange?.(v) 69 | } 70 | }}/> 71 | 72 | {props.suffix} 73 | 74 |
75 | ) 76 | } 77 | 78 | export default Input 79 | -------------------------------------------------------------------------------- /src/component/list/index.less: -------------------------------------------------------------------------------- 1 | @import (reference) '../../base.less'; 2 | 3 | .@{prefix-cls}-list { 4 | position: relative; 5 | list-style: none; 6 | margin: 0; 7 | padding: 0; 8 | overflow-y: auto; 9 | font-size: 14px; 10 | color: var(---klinecharts-pro-text-color); 11 | min-height: 200px; 12 | &::-webkit-scrollbar { 13 | width: 8px; 14 | height: 8px; 15 | } 16 | &::-webkit-scrollbar-thumb { 17 | width: 8px; 18 | height: 8px; 19 | border-radius: 4px; 20 | background-color: var(--klinecharts-pro-border-color); 21 | } 22 | li { 23 | display: flex; 24 | flex-direction: row; 25 | align-items: center; 26 | height: 40px; 27 | padding: 0 20px; 28 | box-sizing: border-box; 29 | cursor: pointer; 30 | &:hover { 31 | background-color: var(--klinecharts-pro-hover-background-color); 32 | } 33 | } 34 | } -------------------------------------------------------------------------------- /src/component/list/index.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * Licensed under the Apache License, Version 2.0 (the "License"); 3 | * you may not use this file except in compliance with the License. 4 | * You may obtain a copy of the License at 5 | 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | * See the License for the specific language governing permissions and 12 | * limitations under the License. 13 | */ 14 | 15 | import { ParentComponent, ParentProps, JSX, Show } from 'solid-js' 16 | 17 | import Loading from '../loading' 18 | import Empty from '../empty' 19 | 20 | export interface ListProps extends ParentProps { 21 | class?: string 22 | style?: JSX.CSSProperties | string 23 | loading?: boolean 24 | dataSource?: any[] 25 | renderItem?: (data: any) => JSX.Element 26 | } 27 | 28 | const List: ParentComponent = props => { 29 | return ( 30 |
    33 | 34 | 35 | 36 | 37 | 38 | 39 | 41 | {props.children} 42 | 43 | 45 | { 46 | props.dataSource?.map(data => ( 47 | props.renderItem?.(data) ??
  • 48 | )) 49 | } 50 |
    51 |
52 | ) 53 | } 54 | 55 | export default List 56 | -------------------------------------------------------------------------------- /src/component/loading/index.less: -------------------------------------------------------------------------------- 1 | @import (reference) '../../base.less'; 2 | 3 | .@{prefix-cls}-loading { 4 | display: flex; 5 | flex-direction: row; 6 | align-items: center; 7 | justify-content: center; 8 | position: absolute; 9 | left: 0; 10 | top: 0; 11 | width: 100%; 12 | height: 100%; 13 | z-index: 50; 14 | color: var(--klinecharts-pro-primary-color); 15 | .circle1, 16 | .circle2, 17 | .circle3 { 18 | display: inline-block; 19 | width: 10px; 20 | height: 10px; 21 | pointer-events: none; 22 | border-radius: 50%; 23 | background-color: currentColor; 24 | animation: loading-anim 0.8s ease-in-out alternate infinite; 25 | } 26 | .circle1 { 27 | animation-delay: 0.48s; 28 | } 29 | .circle2 { 30 | margin-left: 0.2em; 31 | margin-right: 0.2em; 32 | animation-delay: 0.32s; 33 | } 34 | .circle3 { 35 | animation-delay: 0.16s; 36 | } 37 | @keyframes loading-anim { 38 | 0% { 39 | top: 0em; 40 | } 41 | 100% { 42 | margin-top: -2.2em; 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/component/loading/index.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * Licensed under the Apache License, Version 2.0 (the "License"); 3 | * you may not use this file except in compliance with the License. 4 | * You may obtain a copy of the License at 5 | 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | * See the License for the specific language governing permissions and 12 | * limitations under the License. 13 | */ 14 | 15 | import { VoidComponent } from "solid-js"; 16 | 17 | const Loding: VoidComponent = () => { 18 | return ( 19 |
20 | 21 | 22 | 23 |
24 | ) 25 | } 26 | 27 | export default Loding 28 | -------------------------------------------------------------------------------- /src/component/modal/index.less: -------------------------------------------------------------------------------- 1 | @import (reference) '../../base.less'; 2 | 3 | .@{prefix-cls}-modal { 4 | position: absolute; 5 | display: flex; 6 | flex-direction: row; 7 | justify-content: center; 8 | align-items: center; 9 | width: 100%; 10 | height: 100%; 11 | left: 0; 12 | top: 0; 13 | background-color: rgba(0, 0, 0, .2); 14 | z-index: 99; 15 | .inner { 16 | background-color: var(--klinecharts-pro-popover-background-color); 17 | box-shadow: 0 6px 12px 0 rgba(0, 0, 0, .3); 18 | border-radius: 4px; 19 | .title-container { 20 | display: flex; 21 | flex-direction: row; 22 | align-items: center; 23 | justify-content: space-between; 24 | height: 52px; 25 | padding: 0 26px; 26 | font-size: 18px; 27 | font-weight: bold; 28 | color: var(--klinecharts-pro-text-color); 29 | position: relative; 30 | box-sizing: border-box; 31 | border-bottom: solid 1px var(--klinecharts-pro-border-color); 32 | .close-icon { 33 | width: 14px; 34 | height: 14px; 35 | cursor: pointer; 36 | fill: var(--klinecharts-pro-text-color); 37 | &:hover { 38 | fill: var(--klinecharts-pro-primary-color); 39 | } 40 | } 41 | } 42 | .content-container { 43 | padding: 0 26px; 44 | min-height: 140px; 45 | } 46 | .button-container { 47 | display: flex; 48 | flex-direction: row; 49 | justify-content: flex-end; 50 | padding: 20px 20px 26px 20px; 51 | } 52 | } 53 | } -------------------------------------------------------------------------------- /src/component/modal/index.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * Licensed under the Apache License, Version 2.0 (the "License"); 3 | * you may not use this file except in compliance with the License. 4 | * You may obtain a copy of the License at 5 | 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | * See the License for the specific language governing permissions and 12 | * limitations under the License. 13 | */ 14 | 15 | import { ParentComponent, ParentProps, JSX } from 'solid-js' 16 | 17 | import Button, { ButtonProps } from '../button' 18 | 19 | export interface ModalProps extends ParentProps { 20 | width?: number 21 | title?: JSX.Element 22 | buttons?: ButtonProps[] 23 | onClose?: () => void 24 | } 25 | 26 | const Modal: ParentComponent = (props) => { 27 | return ( 28 |
30 |
33 |
35 | {props.title} 36 | 40 | 42 | 43 |
44 |
46 | {props.children} 47 |
48 | { 49 | (props.buttons && props.buttons.length > 0) && ( 50 |
52 | { 53 | props.buttons.map(button => { 54 | return ( 55 | 58 | ) 59 | }) 60 | } 61 |
62 | ) 63 | } 64 |
65 |
66 | ) 67 | } 68 | 69 | export default Modal 70 | -------------------------------------------------------------------------------- /src/component/select/index.less: -------------------------------------------------------------------------------- 1 | @import (reference) '../../base.less'; 2 | 3 | .@{prefix-cls}-select { 4 | position: relative; 5 | display: flex; 6 | flex-direction: row; 7 | align-items: center; 8 | cursor: pointer; 9 | height: 34px; 10 | width: 100px; 11 | outline: none; 12 | color: var(--klinecharts-pro-text-color); 13 | font-size: 14px; 14 | .selector-container { 15 | display: flex; 16 | flex-direction: row; 17 | align-items: center; 18 | height: 100%; 19 | width: 100%; 20 | padding: 0 10px; 21 | justify-content: space-between; 22 | border: solid 1px var(--klinecharts-pro-border-color); 23 | border-radius: 2px; 24 | box-sizing: border-box; 25 | .arrow { 26 | display: inline; 27 | width: 0; 28 | height: 0; 29 | border-left: 5px solid transparent; 30 | border-right: 5px solid transparent; 31 | border-top: 6px solid var(--klinecharts-pro-text-color); 32 | transition: all .2s; 33 | } 34 | } 35 | .drop-down-container { 36 | background-color: var(--klinecharts-pro-popover-background-color); 37 | box-shadow: 0 6px 12px 0 rgba(0, 0, 0, .3); 38 | position: absolute; 39 | left: 0; 40 | width: 100%; 41 | top: calc(100% + 1px); 42 | transition: all .2s; 43 | transform: scaleY(0); 44 | transform-origin: top; 45 | opacity: 0; 46 | z-index: 100; 47 | border-radius: 2px; 48 | max-height: 200px; 49 | overflow-y: auto; 50 | ul { 51 | list-style: none; 52 | margin: 0; 53 | padding: 0; 54 | overflow: hidden; 55 | li { 56 | display: flex; 57 | flex-direction: row; 58 | align-items: center; 59 | height: 40px; 60 | padding: 0 10px; 61 | &:first-child { 62 | border-top-left-radius: 2px; 63 | border-top-right-radius: 2px; 64 | } 65 | &:last-child { 66 | border-bottom-left-radius: 2px; 67 | border-bottom-right-radius: 2px; 68 | } 69 | &:hover { 70 | background-color: var(--klinecharts-pro-hover-background-color); 71 | } 72 | } 73 | } 74 | } 75 | } 76 | 77 | .@{prefix-cls}-select-show { 78 | .selector-container { 79 | border-color: var(--klinecharts-pro-primary-color)!important; 80 | .value { 81 | color: var(--klinecharts-pro-primary-color); 82 | } 83 | .arrow { 84 | transform: rotate(180deg); 85 | } 86 | } 87 | .drop-down-container { 88 | transform: scaleY(1)!important; 89 | opacity: 1!important; 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /src/component/select/index.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * Licensed under the Apache License, Version 2.0 (the "License"); 3 | * you may not use this file except in compliance with the License. 4 | * You may obtain a copy of the License at 5 | 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | * See the License for the specific language governing permissions and 12 | * limitations under the License. 13 | */ 14 | 15 | import { createSignal, Component, JSX } from 'solid-js' 16 | 17 | export interface SelectDataSourceItem { 18 | key: string 19 | text: JSX.Element 20 | } 21 | 22 | export interface SelectProps { 23 | class?: string 24 | style?: JSX.CSSProperties | string 25 | value?: JSX.Element 26 | valueKey?: string 27 | dataSource?: SelectDataSourceItem[] | string[] 28 | onSelected?: (data: SelectDataSourceItem | string) => void 29 | } 30 | 31 | const Select: Component = props => { 32 | const [open, setOpen] = createSignal(false) 33 | 34 | return ( 35 |
{ setOpen(o => !o) }} 40 | onBlur={_ => { setOpen(false) }}> 41 |
43 | {props.value} 44 | 45 |
46 | { 47 | (props.dataSource && props.dataSource.length > 0) && 48 | 72 | } 73 |
74 | ) 75 | } 76 | 77 | export default Select 78 | -------------------------------------------------------------------------------- /src/component/switch/index.less: -------------------------------------------------------------------------------- 1 | @import (reference) '../../base.less'; 2 | 3 | .@{prefix-cls}-switch { 4 | display: flex; 5 | flex-direction: row; 6 | position: relative; 7 | width: 36px; 8 | height: 18px; 9 | border-radius: 9px; 10 | cursor: pointer; 11 | .thumb { 12 | display: inline-block; 13 | position: absolute; 14 | top: 2px; 15 | width: 14px; 16 | height: 14px; 17 | border-radius: 50%; 18 | z-index: 10; 19 | background-color: #ffffff; 20 | transition: all .2s; 21 | } 22 | 23 | &.turn-off { 24 | background-color: var(--klinecharts-pro-border-color); 25 | .thumb { 26 | left: 2px; 27 | } 28 | } 29 | &.turn-on { 30 | background-color: var(--klinecharts-pro-primary-color); 31 | .thumb { 32 | left: 20px; 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/component/switch/index.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * Licensed under the Apache License, Version 2.0 (the "License"); 3 | * you may not use this file except in compliance with the License. 4 | * You may obtain a copy of the License at 5 | 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | * See the License for the specific language governing permissions and 12 | * limitations under the License. 13 | */ 14 | 15 | import { Component, JSX } from 'solid-js' 16 | 17 | export interface SwitchProps { 18 | class?: string 19 | style?: JSX.CSSProperties | string 20 | open: boolean 21 | onChange: () => void 22 | } 23 | 24 | const Switch: Component = props => { 25 | return ( 26 |
{ 30 | props.onChange && props.onChange() 31 | }}> 32 | 34 |
35 | ) 36 | } 37 | 38 | export default Switch 39 | -------------------------------------------------------------------------------- /src/extension/abcd.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Licensed under the Apache License, Version 2.0 (the "License"); 3 | * you may not use this file except in compliance with the License. 4 | * You may obtain a copy of the License at 5 | 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | * See the License for the specific language governing permissions and 12 | * limitations under the License. 13 | */ 14 | 15 | import { OverlayTemplate, Coordinate } from 'klinecharts' 16 | 17 | const abcd: OverlayTemplate = { 18 | name: 'abcd', 19 | totalStep: 5, 20 | needDefaultPointFigure: true, 21 | needDefaultXAxisFigure: true, 22 | needDefaultYAxisFigure: true, 23 | createPointFigures: ({ coordinates }) => { 24 | let acLineCoordinates: Coordinate[] = [] 25 | let bdLineCoordinates: Coordinate[] = [] 26 | 27 | const tags = ['A', 'B', 'C', 'D'] 28 | const texts = coordinates.map((coordinate, i) => ({ 29 | ...coordinate, 30 | baseline: 'bottom', 31 | text: `(${tags[i]})` 32 | })) 33 | if (coordinates.length > 2) { 34 | acLineCoordinates = [coordinates[0], coordinates[2]] 35 | if (coordinates.length > 3) { 36 | bdLineCoordinates = [coordinates[1], coordinates[3]] 37 | } 38 | } 39 | return [ 40 | { 41 | type: 'line', 42 | attrs: { coordinates } 43 | }, 44 | { 45 | type: 'line', 46 | attrs: [{ coordinates: acLineCoordinates }, { coordinates: bdLineCoordinates }], 47 | styles: { style: 'dashed' } 48 | }, 49 | { 50 | type: 'text', 51 | ignoreEvent: true, 52 | attrs: texts 53 | } 54 | ] 55 | } 56 | } 57 | 58 | export default abcd 59 | -------------------------------------------------------------------------------- /src/extension/anyWaves.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Licensed under the Apache License, Version 2.0 (the "License"); 3 | * you may not use this file except in compliance with the License. 4 | * You may obtain a copy of the License at 5 | 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | * See the License for the specific language governing permissions and 12 | * limitations under the License. 13 | */ 14 | 15 | import { OverlayTemplate } from 'klinecharts' 16 | 17 | const anyWaves: OverlayTemplate = { 18 | name: 'anyWaves', 19 | totalStep: Number.MAX_SAFE_INTEGER, 20 | needDefaultPointFigure: true, 21 | needDefaultXAxisFigure: true, 22 | needDefaultYAxisFigure: true, 23 | createPointFigures: ({ coordinates }) => { 24 | const texts = coordinates.map((coordinate, i) => ({ 25 | ...coordinate, 26 | text: `(${i})`, 27 | baseline: 'bottom' 28 | })) 29 | return [ 30 | { 31 | type: 'line', 32 | attrs: { coordinates } 33 | }, 34 | { 35 | type: 'text', 36 | ignoreEvent: true, 37 | attrs: texts 38 | } 39 | ] 40 | } 41 | } 42 | 43 | export default anyWaves 44 | -------------------------------------------------------------------------------- /src/extension/arrow.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Licensed under the Apache License, Version 2.0 (the "License"); 3 | * you may not use this file except in compliance with the License. 4 | * You may obtain a copy of the License at 5 | 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | * See the License for the specific language governing permissions and 12 | * limitations under the License. 13 | */ 14 | 15 | import { OverlayTemplate, utils } from 'klinecharts' 16 | 17 | import { getRotateCoordinate } from './utils' 18 | 19 | const arrow: OverlayTemplate = { 20 | name: 'arrow', 21 | totalStep: 3, 22 | needDefaultPointFigure: true, 23 | needDefaultXAxisFigure: true, 24 | needDefaultYAxisFigure: true, 25 | createPointFigures: ({ coordinates }) => { 26 | if (coordinates.length > 1) { 27 | const flag = coordinates[1].x > coordinates[0].x ? 0 : 1 28 | const kb = utils.getLinearSlopeIntercept(coordinates[0], coordinates[1]) 29 | let offsetAngle 30 | if (kb) { 31 | offsetAngle = Math.atan(kb[0]) + Math.PI * flag 32 | } else { 33 | if (coordinates[1].y > coordinates[0].y) { 34 | offsetAngle = Math.PI / 2 35 | } else { 36 | offsetAngle = Math.PI / 2 * 3 37 | } 38 | } 39 | const rotateCoordinate1 = getRotateCoordinate({ x: coordinates[1].x - 8, y: coordinates[1].y + 4 }, coordinates[1], offsetAngle) 40 | const rotateCoordinate2 = getRotateCoordinate({ x: coordinates[1].x - 8, y: coordinates[1].y - 4 }, coordinates[1], offsetAngle) 41 | return [ 42 | { 43 | type: 'line', 44 | attrs: { coordinates } 45 | }, 46 | { 47 | type: 'line', 48 | ignoreEvent: true, 49 | attrs: { coordinates: [rotateCoordinate1, coordinates[1], rotateCoordinate2] } 50 | } 51 | ] 52 | } 53 | return [] 54 | } 55 | } 56 | 57 | export default arrow 58 | -------------------------------------------------------------------------------- /src/extension/circle.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Licensed under the Apache License, Version 2.0 (the "License"); 3 | * you may not use this file except in compliance with the License. 4 | * You may obtain a copy of the License at 5 | 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | * See the License for the specific language governing permissions and 12 | * limitations under the License. 13 | */ 14 | 15 | import { OverlayTemplate } from 'klinecharts' 16 | 17 | import { getDistance } from './utils' 18 | 19 | const circle: OverlayTemplate = { 20 | name: 'circle', 21 | totalStep: 3, 22 | needDefaultPointFigure: true, 23 | needDefaultXAxisFigure: true, 24 | needDefaultYAxisFigure: true, 25 | styles: { 26 | circle: { 27 | color: 'rgba(22, 119, 255, 0.15)' 28 | } 29 | }, 30 | createPointFigures: ({ coordinates }) => { 31 | if (coordinates.length > 1) { 32 | const radius = getDistance(coordinates[0], coordinates[1]) 33 | return { 34 | type: 'circle', 35 | attrs: { 36 | ...coordinates[0], 37 | r: radius 38 | }, 39 | styles: { style: 'stroke_fill' } 40 | } 41 | } 42 | return [] 43 | } 44 | } 45 | 46 | export default circle 47 | -------------------------------------------------------------------------------- /src/extension/eightWaves.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Licensed under the Apache License, Version 2.0 (the "License"); 3 | * you may not use this file except in compliance with the License. 4 | * You may obtain a copy of the License at 5 | 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | * See the License for the specific language governing permissions and 12 | * limitations under the License. 13 | */ 14 | 15 | import { OverlayTemplate } from 'klinecharts' 16 | 17 | const eightWaves: OverlayTemplate = { 18 | name: 'eightWaves', 19 | totalStep: 10, 20 | needDefaultPointFigure: true, 21 | needDefaultXAxisFigure: true, 22 | needDefaultYAxisFigure: true, 23 | createPointFigures: ({ coordinates }) => { 24 | const texts = coordinates.map((coordinate, i) => ({ 25 | ...coordinate, 26 | text: `(${i})`, 27 | baseline: 'bottom' 28 | })) 29 | return [ 30 | { 31 | type: 'line', 32 | attrs: { coordinates } 33 | }, 34 | { 35 | type: 'text', 36 | ignoreEvent: true, 37 | attrs: texts 38 | } 39 | ] 40 | } 41 | } 42 | 43 | export default eightWaves 44 | -------------------------------------------------------------------------------- /src/extension/fibonacciCircle.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Licensed under the Apache License, Version 2.0 (the "License"); 3 | * you may not use this file except in compliance with the License. 4 | * You may obtain a copy of the License at 5 | 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | * See the License for the specific language governing permissions and 12 | * limitations under the License. 13 | */ 14 | 15 | import { OverlayTemplate, CircleAttrs, TextAttrs } from 'klinecharts' 16 | 17 | const fibonacciCircle: OverlayTemplate = { 18 | name: 'fibonacciCircle', 19 | totalStep: 3, 20 | needDefaultPointFigure: true, 21 | needDefaultXAxisFigure: true, 22 | needDefaultYAxisFigure: true, 23 | createPointFigures: ({ coordinates }) => { 24 | if (coordinates.length > 1) { 25 | const xDis = Math.abs(coordinates[0].x - coordinates[1].x) 26 | const yDis = Math.abs(coordinates[0].y - coordinates[1].y) 27 | const radius = Math.sqrt(xDis * xDis + yDis * yDis) 28 | const percents = [0.236, 0.382, 0.5, 0.618, 0.786, 1] 29 | const circles: CircleAttrs[] = [] 30 | const texts: TextAttrs[] = [] 31 | percents.forEach(percent => { 32 | const r = radius * percent 33 | circles.push( 34 | { ...coordinates[0], r } 35 | ) 36 | texts.push({ 37 | x: coordinates[0].x, 38 | y: coordinates[0].y + r + 6, 39 | text: `${(percent * 100).toFixed(1)}%` 40 | }) 41 | }) 42 | return [ 43 | { 44 | type: 'circle', 45 | attrs: circles, 46 | styles: { style: 'stroke' } 47 | }, 48 | { 49 | type: 'text', 50 | ignoreEvent: true, 51 | attrs: texts 52 | } 53 | ] 54 | } 55 | return [] 56 | } 57 | } 58 | 59 | export default fibonacciCircle 60 | -------------------------------------------------------------------------------- /src/extension/fibonacciExtension.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Licensed under the Apache License, Version 2.0 (the "License"); 3 | * you may not use this file except in compliance with the License. 4 | * You may obtain a copy of the License at 5 | 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | * See the License for the specific language governing permissions and 12 | * limitations under the License. 13 | */ 14 | 15 | import { OverlayTemplate, LineAttrs, TextAttrs } from 'klinecharts' 16 | 17 | const fibonacciExtension: OverlayTemplate = { 18 | name: 'fibonacciExtension', 19 | totalStep: 4, 20 | needDefaultPointFigure: true, 21 | needDefaultXAxisFigure: true, 22 | needDefaultYAxisFigure: true, 23 | createPointFigures: ({ coordinates, overlay, precision }) => { 24 | const fbLines: LineAttrs[] = [] 25 | const texts: TextAttrs[] = [] 26 | if (coordinates.length > 2) { 27 | const points = overlay.points 28 | // @ts-expect-error 29 | const valueDif = points[1].value - points[0].value 30 | const yDif = coordinates[1].y - coordinates[0].y 31 | const percents = [0, 0.236, 0.382, 0.5, 0.618, 0.786, 1] 32 | const textX = coordinates[2].x > coordinates[1].x ? coordinates[1].x : coordinates[2].x 33 | percents.forEach(percent => { 34 | const y = coordinates[2].y + yDif * percent 35 | // @ts-expect-error 36 | const price = (points[2].value + valueDif * percent).toFixed(precision.price) 37 | fbLines.push({ coordinates: [{ x: coordinates[1].x, y }, { x: coordinates[2].x, y }] }) 38 | texts.push({ 39 | x: textX, 40 | y, 41 | text: `${price} (${(percent * 100).toFixed(1)}%)`, 42 | baseline: 'bottom' 43 | }) 44 | }) 45 | } 46 | return [ 47 | { 48 | type: 'line', 49 | attrs: { coordinates }, 50 | styles: { style: 'dashed' } 51 | }, 52 | { 53 | type: 'line', 54 | attrs: fbLines 55 | }, 56 | { 57 | type: 'text', 58 | ignoreEvent: true, 59 | attrs: texts 60 | } 61 | ] 62 | } 63 | } 64 | 65 | export default fibonacciExtension 66 | -------------------------------------------------------------------------------- /src/extension/fibonacciSegment.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Licensed under the Apache License, Version 2.0 (the "License"); 3 | * you may not use this file except in compliance with the License. 4 | * You may obtain a copy of the License at 5 | 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | * See the License for the specific language governing permissions and 12 | * limitations under the License. 13 | */ 14 | 15 | import { OverlayTemplate, LineAttrs, TextAttrs } from 'klinecharts' 16 | 17 | const fibonacciSegment: OverlayTemplate = { 18 | name: 'fibonacciSegment', 19 | totalStep: 3, 20 | needDefaultPointFigure: true, 21 | needDefaultXAxisFigure: true, 22 | needDefaultYAxisFigure: true, 23 | createPointFigures: ({ coordinates, overlay, precision }) => { 24 | const lines: LineAttrs[] = [] 25 | const texts: TextAttrs[] = [] 26 | if (coordinates.length > 1) { 27 | const textX = coordinates[1].x > coordinates[0].x ? coordinates[0].x : coordinates[1].x 28 | const percents = [1, 0.786, 0.618, 0.5, 0.382, 0.236, 0] 29 | const yDif = coordinates[0].y - coordinates[1].y 30 | const points = overlay.points 31 | // @ts-expect-error 32 | const valueDif = points[0].value - points[1].value 33 | percents.forEach(percent => { 34 | const y = coordinates[1].y + yDif * percent 35 | // @ts-expect-error 36 | const price = (points[1].value + valueDif * percent).toFixed(precision.price) 37 | lines.push({ coordinates: [{ x: coordinates[0].x, y }, { x: coordinates[1].x, y }] }) 38 | texts.push({ 39 | x: textX, 40 | y, 41 | text: `${price} (${(percent * 100).toFixed(1)}%)`, 42 | baseline: 'bottom' 43 | }) 44 | }) 45 | } 46 | return [ 47 | { 48 | type: 'line', 49 | attrs: lines 50 | }, { 51 | type: 'text', 52 | ignoreEvent: true, 53 | attrs: texts 54 | } 55 | ] 56 | } 57 | } 58 | 59 | export default fibonacciSegment 60 | -------------------------------------------------------------------------------- /src/extension/fibonacciSpeedResistanceFan.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Licensed under the Apache License, Version 2.0 (the "License"); 3 | * you may not use this file except in compliance with the License. 4 | * You may obtain a copy of the License at 5 | 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | * See the License for the specific language governing permissions and 12 | * limitations under the License. 13 | */ 14 | 15 | import { OverlayTemplate, LineAttrs, TextAttrs } from 'klinecharts' 16 | 17 | import { getRayLine } from './utils' 18 | 19 | const fibonacciSpeedResistanceFan: OverlayTemplate = { 20 | name: 'fibonacciSpeedResistanceFan', 21 | totalStep: 3, 22 | needDefaultPointFigure: true, 23 | needDefaultXAxisFigure: true, 24 | needDefaultYAxisFigure: true, 25 | createPointFigures: ({ coordinates, bounding }) => { 26 | const lines1: LineAttrs[] = [] 27 | let lines2: LineAttrs[] = [] 28 | const texts: TextAttrs[] = [] 29 | if (coordinates.length > 1) { 30 | const xOffset = coordinates[1].x > coordinates[0].x ? -38 : 4 31 | const yOffset = coordinates[1].y > coordinates[0].y ? -2 : 20 32 | const xDistance = coordinates[1].x - coordinates[0].x 33 | const yDistance = coordinates[1].y - coordinates[0].y 34 | const percents = [1, 0.75, 0.618, 0.5, 0.382, 0.25, 0] 35 | percents.forEach(percent => { 36 | const x = coordinates[1].x - xDistance * percent 37 | const y = coordinates[1].y - yDistance * percent 38 | lines1.push({ coordinates: [{ x, y: coordinates[0].y }, { x, y: coordinates[1].y }] }) 39 | lines1.push({ coordinates: [{ x: coordinates[0].x, y }, { x: coordinates[1].x, y }] }) 40 | lines2 = lines2.concat(getRayLine([coordinates[0], { x, y: coordinates[1].y }], bounding)) 41 | lines2 = lines2.concat(getRayLine([coordinates[0], { x: coordinates[1].x, y }], bounding)) 42 | texts.unshift({ 43 | x: coordinates[0].x + xOffset, 44 | y: y + 10, 45 | text: `${percent.toFixed(3)}` 46 | }) 47 | texts.unshift({ 48 | x: x - 18, 49 | y: coordinates[0].y + yOffset, 50 | text: `${percent.toFixed(3)}` 51 | }) 52 | }) 53 | } 54 | return [ 55 | { 56 | type: 'line', 57 | attrs: lines1 58 | }, 59 | { 60 | type: 'line', 61 | attrs: lines2 62 | }, 63 | { 64 | type: 'text', 65 | ignoreEvent: true, 66 | attrs: texts 67 | } 68 | ] 69 | } 70 | } 71 | 72 | export default fibonacciSpeedResistanceFan 73 | -------------------------------------------------------------------------------- /src/extension/fibonacciSpiral.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Licensed under the Apache License, Version 2.0 (the "License"); 3 | * you may not use this file except in compliance with the License. 4 | * You may obtain a copy of the License at 5 | 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | * See the License for the specific language governing permissions and 12 | * limitations under the License. 13 | */ 14 | 15 | import { OverlayTemplate, utils, registerFigure } from 'klinecharts' 16 | 17 | import { getDistance, getRotateCoordinate, getRayLine } from './utils' 18 | 19 | const fibonacciSpiral: OverlayTemplate = { 20 | name: 'fibonacciSpiral', 21 | totalStep: 3, 22 | needDefaultPointFigure: true, 23 | needDefaultXAxisFigure: true, 24 | needDefaultYAxisFigure: true, 25 | createPointFigures: ({ coordinates, bounding }) => { 26 | if (coordinates.length > 1) { 27 | const startRadius = getDistance(coordinates[0], coordinates[1]) / Math.sqrt(24) 28 | const flag = coordinates[1].x > coordinates[0].x ? 0 : 1 29 | const kb = utils.getLinearSlopeIntercept(coordinates[0], coordinates[1]) 30 | let offsetAngle 31 | if (kb) { 32 | offsetAngle = Math.atan(kb[0]) + Math.PI * flag 33 | } else { 34 | if (coordinates[1].y > coordinates[0].y) { 35 | offsetAngle = Math.PI / 2 36 | } else { 37 | offsetAngle = Math.PI / 2 * 3 38 | } 39 | } 40 | const rotateCoordinate1 = getRotateCoordinate( 41 | { x: coordinates[0].x - startRadius, y: coordinates[0].y }, 42 | coordinates[0], 43 | offsetAngle 44 | ) 45 | const rotateCoordinate2 = getRotateCoordinate( 46 | { x: coordinates[0].x - startRadius, y: coordinates[0].y - startRadius }, 47 | coordinates[0], 48 | offsetAngle 49 | ) 50 | const arcs = [{ 51 | ...rotateCoordinate1, 52 | r: startRadius, 53 | startAngle: offsetAngle, 54 | endAngle: offsetAngle + Math.PI / 2 55 | }, { 56 | ...rotateCoordinate2, 57 | r: startRadius * 2, 58 | startAngle: offsetAngle + Math.PI / 2, 59 | endAngle: offsetAngle + Math.PI 60 | }] 61 | let x = coordinates[0].x - startRadius 62 | let y = coordinates[0].y - startRadius 63 | for (let i = 2; i < 9; i++) { 64 | const r = arcs[i - 2].r + arcs[i - 1].r 65 | let startAngle = 0 66 | switch (i % 4) { 67 | case 0: { 68 | startAngle = offsetAngle 69 | x -= (arcs[i - 2].r) 70 | break 71 | } 72 | case 1: { 73 | startAngle = offsetAngle + Math.PI / 2 74 | y -= arcs[i - 2].r 75 | break 76 | } 77 | case 2: { 78 | startAngle = offsetAngle + Math.PI 79 | x += (arcs[i - 2].r) 80 | break 81 | } 82 | case 3: { 83 | startAngle = offsetAngle + Math.PI / 2 * 3 84 | y += arcs[i - 2].r 85 | break 86 | } 87 | } 88 | const endAngle = startAngle + Math.PI / 2 89 | const rotateCoordinate = getRotateCoordinate({ x, y }, coordinates[0], offsetAngle) 90 | arcs.push({ 91 | ...rotateCoordinate, 92 | r, 93 | startAngle, 94 | endAngle 95 | }) 96 | } 97 | return [ 98 | { 99 | type: 'arc', 100 | attrs: arcs 101 | }, 102 | { 103 | type: 'line', 104 | attrs: getRayLine(coordinates, bounding) 105 | } 106 | ] 107 | } 108 | return [] 109 | } 110 | } 111 | 112 | export default fibonacciSpiral 113 | -------------------------------------------------------------------------------- /src/extension/fiveWaves.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Licensed under the Apache License, Version 2.0 (the "License"); 3 | * you may not use this file except in compliance with the License. 4 | * You may obtain a copy of the License at 5 | 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | * See the License for the specific language governing permissions and 12 | * limitations under the License. 13 | */ 14 | 15 | import { OverlayTemplate } from 'klinecharts' 16 | 17 | const fiveWaves: OverlayTemplate = { 18 | name: 'fiveWaves', 19 | totalStep: 7, 20 | needDefaultPointFigure: true, 21 | needDefaultXAxisFigure: true, 22 | needDefaultYAxisFigure: true, 23 | createPointFigures: ({ coordinates }) => { 24 | const texts = coordinates.map((coordinate, i) => ({ 25 | ...coordinate, 26 | text: `(${i})`, 27 | baseline: 'bottom' 28 | })) 29 | return [ 30 | { 31 | type: 'line', 32 | attrs: { coordinates } 33 | }, 34 | { 35 | type: 'text', 36 | ignoreEvent: true, 37 | attrs: texts 38 | } 39 | ] 40 | } 41 | } 42 | 43 | export default fiveWaves 44 | -------------------------------------------------------------------------------- /src/extension/gannBox.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Licensed under the Apache License, Version 2.0 (the "License"); 3 | * you may not use this file except in compliance with the License. 4 | * You may obtain a copy of the License at 5 | 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | * See the License for the specific language governing permissions and 12 | * limitations under the License. 13 | */ 14 | 15 | import { OverlayTemplate } from 'klinecharts' 16 | 17 | const gannBox: OverlayTemplate = { 18 | name: 'gannBox', 19 | totalStep: 3, 20 | needDefaultPointFigure: true, 21 | needDefaultXAxisFigure: true, 22 | needDefaultYAxisFigure: true, 23 | styles: { 24 | polygon: { 25 | color: 'rgba(22, 119, 255, 0.15)' 26 | } 27 | }, 28 | createPointFigures: ({ coordinates }) => { 29 | if (coordinates.length > 1) { 30 | const quarterYDis = (coordinates[1].y - coordinates[0].y) / 4 31 | const xDis = coordinates[1].x - coordinates[0].x 32 | const dashedLines = [ 33 | { coordinates: [coordinates[0], { x: coordinates[1].x, y: coordinates[1].y - quarterYDis }] }, 34 | { coordinates: [coordinates[0], { x: coordinates[1].x, y: coordinates[1].y - quarterYDis * 2 }] }, 35 | { coordinates: [{ x: coordinates[0].x, y: coordinates[1].y }, { x: coordinates[1].x, y: coordinates[0].y + quarterYDis }] }, 36 | { coordinates: [{ x: coordinates[0].x, y: coordinates[1].y }, { x: coordinates[1].x, y: coordinates[0].y + quarterYDis * 2 }] }, 37 | 38 | { coordinates: [{ ...coordinates[0] }, { x: coordinates[0].x + xDis * 0.236, y: coordinates[1].y }] }, 39 | { coordinates: [{ ...coordinates[0] }, { x: coordinates[0].x + xDis * 0.5, y: coordinates[1].y }] }, 40 | 41 | { coordinates: [{ x: coordinates[0].x, y: coordinates[1].y }, { x: coordinates[0].x + xDis * 0.236, y: coordinates[0].y }]}, 42 | { coordinates: [{ x: coordinates[0].x, y: coordinates[1].y }, { x: coordinates[0].x + xDis * 0.5, y: coordinates[0].y }] } 43 | ] 44 | const solidLines = [ 45 | { coordinates: [coordinates[0], coordinates[1]] }, 46 | { coordinates: [{ x: coordinates[0].x, y: coordinates[1].y }, { x: coordinates[1].x, y: coordinates[0].y }] } 47 | ] 48 | return [ 49 | { 50 | type: 'line', 51 | attrs: [ 52 | { coordinates: [coordinates[0], { x: coordinates[1].x, y: coordinates[0].y }] }, 53 | { coordinates: [{ x: coordinates[1].x, y: coordinates[0].y }, coordinates[1]] }, 54 | { coordinates: [coordinates[1], { x: coordinates[0].x, y: coordinates[1].y }] }, 55 | { coordinates: [{ x: coordinates[0].x, y: coordinates[1].y }, coordinates[0]] } 56 | ] 57 | }, 58 | { 59 | type: 'polygon', 60 | ignoreEvent: true, 61 | attrs: { 62 | coordinates: [ 63 | coordinates[0], 64 | { x: coordinates[1].x, y: coordinates[0].y }, 65 | coordinates[1], 66 | { x: coordinates[0].x, y: coordinates[1].y } 67 | ] 68 | }, 69 | styles: { style: 'fill' } 70 | }, 71 | { 72 | type: 'line', 73 | attrs: dashedLines, 74 | styles: { style: 'dashed' } 75 | }, 76 | { 77 | type: 'line', 78 | attrs: solidLines 79 | } 80 | ] 81 | } 82 | return [] 83 | } 84 | } 85 | 86 | export default gannBox 87 | -------------------------------------------------------------------------------- /src/extension/index.ts: -------------------------------------------------------------------------------- 1 | import arrow from './arrow' 2 | 3 | import circle from './circle' 4 | import rect from './rect' 5 | import parallelogram from './parallelogram' 6 | import triangle from './triangle' 7 | import fibonacciCircle from './fibonacciCircle' 8 | import fibonacciSegment from './fibonacciSegment' 9 | import fibonacciSpiral from './fibonacciSpiral' 10 | import fibonacciSpeedResistanceFan from './fibonacciSpeedResistanceFan' 11 | import fibonacciExtension from './fibonacciExtension' 12 | import gannBox from './gannBox' 13 | import threeWaves from './threeWaves' 14 | import fiveWaves from './fiveWaves' 15 | import eightWaves from './eightWaves' 16 | import anyWaves from './anyWaves' 17 | import abcd from './abcd' 18 | import xabcd from './xabcd' 19 | 20 | const overlays = [ 21 | arrow, 22 | circle, rect, triangle, parallelogram, 23 | fibonacciCircle, fibonacciSegment, fibonacciSpiral, 24 | fibonacciSpeedResistanceFan, fibonacciExtension, gannBox, 25 | threeWaves, fiveWaves, eightWaves, anyWaves, abcd, xabcd 26 | ] 27 | 28 | export default overlays 29 | -------------------------------------------------------------------------------- /src/extension/parallelogram.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Licensed under the Apache License, Version 2.0 (the "License"); 3 | * you may not use this file except in compliance with the License. 4 | * You may obtain a copy of the License at 5 | 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | * See the License for the specific language governing permissions and 12 | * limitations under the License. 13 | */ 14 | 15 | import { OverlayTemplate } from 'klinecharts' 16 | 17 | const parallelogram: OverlayTemplate = { 18 | name: 'parallelogram', 19 | totalStep: 4, 20 | needDefaultPointFigure: true, 21 | needDefaultXAxisFigure: true, 22 | needDefaultYAxisFigure: true, 23 | styles: { 24 | polygon: { 25 | color: 'rgba(22, 119, 255, 0.15)' 26 | } 27 | }, 28 | createPointFigures: ({ coordinates }) => { 29 | if (coordinates.length === 2) { 30 | return [ 31 | { 32 | type: 'line', 33 | ignoreEvent: true, 34 | attrs: { coordinates } 35 | } 36 | ] 37 | } 38 | if (coordinates.length === 3) { 39 | const coordinate = { x: coordinates[0].x + (coordinates[2].x - coordinates[1].x), y: coordinates[2].y } 40 | return [ 41 | { 42 | type: 'polygon', 43 | attrs: { coordinates: [coordinates[0], coordinates[1], coordinates[2], coordinate] }, 44 | styles: { style: 'stroke_fill' } 45 | } 46 | ] 47 | } 48 | return [] 49 | }, 50 | performEventPressedMove: ({ points, performPointIndex, performPoint }) => { 51 | if (performPointIndex < 2) { 52 | // @ts-expect-error 53 | points[0].price = performPoint.price 54 | // @ts-expect-error 55 | points[1].price = performPoint.price 56 | } 57 | }, 58 | performEventMoveForDrawing: ({ currentStep, points, performPoint }) => { 59 | if (currentStep === 2) { 60 | // @ts-expect-error 61 | points[0].price = performPoint.price 62 | } 63 | } 64 | } 65 | 66 | export default parallelogram 67 | -------------------------------------------------------------------------------- /src/extension/rect.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Licensed under the Apache License, Version 2.0 (the "License"); 3 | * you may not use this file except in compliance with the License. 4 | * You may obtain a copy of the License at 5 | 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | * See the License for the specific language governing permissions and 12 | * limitations under the License. 13 | */ 14 | 15 | import { OverlayTemplate } from 'klinecharts' 16 | 17 | const rect: OverlayTemplate = { 18 | name: 'rect', 19 | totalStep: 3, 20 | needDefaultPointFigure: true, 21 | needDefaultXAxisFigure: true, 22 | needDefaultYAxisFigure: true, 23 | styles: { 24 | polygon: { 25 | color: 'rgba(22, 119, 255, 0.15)' 26 | } 27 | }, 28 | createPointFigures: ({ coordinates }) => { 29 | if (coordinates.length > 1) { 30 | return [ 31 | { 32 | type: 'polygon', 33 | attrs: { 34 | coordinates: [ 35 | coordinates[0], 36 | { x: coordinates[1].x, y: coordinates[0].y }, 37 | coordinates[1], 38 | { x: coordinates[0].x, y: coordinates[1].y } 39 | ] 40 | }, 41 | styles: { style: 'stroke_fill' } 42 | } 43 | ] 44 | } 45 | return [] 46 | } 47 | } 48 | 49 | export default rect 50 | -------------------------------------------------------------------------------- /src/extension/threeWaves.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Licensed under the Apache License, Version 2.0 (the "License"); 3 | * you may not use this file except in compliance with the License. 4 | * You may obtain a copy of the License at 5 | 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | * See the License for the specific language governing permissions and 12 | * limitations under the License. 13 | */ 14 | 15 | import { OverlayTemplate } from 'klinecharts' 16 | 17 | const threeWaves: OverlayTemplate = { 18 | name: 'threeWaves', 19 | totalStep: 5, 20 | needDefaultPointFigure: true, 21 | needDefaultXAxisFigure: true, 22 | needDefaultYAxisFigure: true, 23 | createPointFigures: ({ coordinates }) => { 24 | const texts = coordinates.map((coordinate, i) => ({ 25 | ...coordinate, 26 | text: `(${i})`, 27 | baseline: 'bottom' 28 | })) 29 | return [ 30 | { 31 | type: 'line', 32 | attrs: { coordinates } 33 | }, 34 | { 35 | type: 'text', 36 | ignoreEvent: true, 37 | attrs: texts 38 | } 39 | ] 40 | } 41 | } 42 | 43 | export default threeWaves 44 | -------------------------------------------------------------------------------- /src/extension/triangle.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Licensed under the Apache License, Version 2.0 (the "License"); 3 | * you may not use this file except in compliance with the License. 4 | * You may obtain a copy of the License at 5 | 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | * See the License for the specific language governing permissions and 12 | * limitations under the License. 13 | */ 14 | 15 | import { OverlayTemplate } from 'klinecharts' 16 | 17 | const triangle: OverlayTemplate = { 18 | name: 'triangle', 19 | totalStep: 4, 20 | needDefaultPointFigure: true, 21 | needDefaultXAxisFigure: true, 22 | needDefaultYAxisFigure: true, 23 | styles: { 24 | polygon: { 25 | color: 'rgba(22, 119, 255, 0.15)' 26 | } 27 | }, 28 | createPointFigures: ({ coordinates }) => { 29 | return [ 30 | { 31 | type: 'polygon', 32 | attrs: { coordinates }, 33 | styles: { style: 'stroke_fill' } 34 | } 35 | ] 36 | } 37 | } 38 | 39 | export default triangle 40 | -------------------------------------------------------------------------------- /src/extension/utils.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Licensed under the Apache License, Version 2.0 (the "License"); 3 | * you may not use this file except in compliance with the License. 4 | * You may obtain a copy of the License at 5 | 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | * See the License for the specific language governing permissions and 12 | * limitations under the License. 13 | */ 14 | 15 | import { Coordinate, Bounding, LineAttrs, utils } from 'klinecharts' 16 | 17 | export function getRotateCoordinate (coordinate: Coordinate, targetCoordinate: Coordinate, angle: number): Coordinate { 18 | const x = (coordinate.x - targetCoordinate.x) * Math.cos(angle) - (coordinate.y - targetCoordinate.y) * Math.sin(angle) + targetCoordinate.x 19 | const y = (coordinate.x - targetCoordinate.x) * Math.sin(angle) + (coordinate.y - targetCoordinate.y) * Math.cos(angle) + targetCoordinate.y 20 | return { x, y } 21 | } 22 | 23 | export function getRayLine (coordinates: Coordinate[], bounding: Bounding): LineAttrs | LineAttrs[] { 24 | if (coordinates.length > 1) { 25 | let coordinate: Coordinate 26 | if (coordinates[0].x === coordinates[1].x && coordinates[0].y !== coordinates[1].y) { 27 | if (coordinates[0].y < coordinates[1].y) { 28 | coordinate = { 29 | x: coordinates[0].x, 30 | y: bounding.height 31 | } 32 | } else { 33 | coordinate = { 34 | x: coordinates[0].x, 35 | y: 0 36 | } 37 | } 38 | } else if (coordinates[0].x > coordinates[1].x) { 39 | coordinate = { 40 | x: 0, 41 | y: utils.getLinearYFromCoordinates(coordinates[0], coordinates[1], { x: 0, y: coordinates[0].y }) 42 | } 43 | } else { 44 | coordinate = { 45 | x: bounding.width, 46 | y: utils.getLinearYFromCoordinates(coordinates[0], coordinates[1], { x: bounding.width, y: coordinates[0].y }) 47 | } 48 | } 49 | return { coordinates: [coordinates[0], coordinate] } 50 | } 51 | return [] 52 | } 53 | 54 | export function getDistance (coordinate1: Coordinate, coordinate2: Coordinate,): number { 55 | const xDis = Math.abs(coordinate1.x - coordinate2.x) 56 | const yDis = Math.abs(coordinate1.y - coordinate2.y) 57 | return Math.sqrt(xDis * xDis + yDis * yDis) 58 | } -------------------------------------------------------------------------------- /src/extension/xabcd.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Licensed under the Apache License, Version 2.0 (the "License"); 3 | * you may not use this file except in compliance with the License. 4 | * You may obtain a copy of the License at 5 | 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | * See the License for the specific language governing permissions and 12 | * limitations under the License. 13 | */ 14 | 15 | import { OverlayTemplate, PolygonAttrs, LineAttrs } from 'klinecharts' 16 | 17 | const xabcd: OverlayTemplate = { 18 | name: 'xabcd', 19 | totalStep: 6, 20 | needDefaultPointFigure: true, 21 | needDefaultXAxisFigure: true, 22 | needDefaultYAxisFigure: true, 23 | styles: { 24 | polygon: { 25 | color: 'rgba(22, 119, 255, 0.15)' 26 | } 27 | }, 28 | createPointFigures: ({ coordinates, overlay }) => { 29 | const dashedLines: LineAttrs[] = [] 30 | const polygons: PolygonAttrs[] = [] 31 | const tags = ['X', 'A', 'B', 'C', 'D'] 32 | const texts = coordinates.map((coordinate, i) => ({ 33 | ...coordinate, 34 | baseline: 'bottom', 35 | text: `(${tags[i]})` 36 | })) 37 | if (coordinates.length > 2) { 38 | dashedLines.push({ coordinates: [coordinates[0], coordinates[2]] }) 39 | polygons.push({ coordinates: [coordinates[0], coordinates[1], coordinates[2]] }) 40 | if (coordinates.length > 3) { 41 | dashedLines.push({ coordinates: [coordinates[1], coordinates[3]] }) 42 | if (coordinates.length > 4) { 43 | dashedLines.push({ coordinates: [coordinates[2], coordinates[4]] }) 44 | polygons.push({ coordinates: [coordinates[2], coordinates[3], coordinates[4]] }) 45 | } 46 | } 47 | } 48 | return [ 49 | { 50 | type: 'line', 51 | attrs: { coordinates } 52 | }, 53 | { 54 | type: 'line', 55 | attrs: dashedLines, 56 | styles: { style: 'dashed' } 57 | }, 58 | { 59 | type: 'polygon', 60 | ignoreEvent: true, 61 | attrs: polygons 62 | }, 63 | { 64 | type: 'text', 65 | ignoreEvent: true, 66 | attrs: texts 67 | } 68 | ] 69 | } 70 | } 71 | 72 | export default xabcd 73 | -------------------------------------------------------------------------------- /src/i18n/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Licensed under the Apache License, Version 2.0 (the "License"); 3 | * you may not use this file except in compliance with the License. 4 | * You may obtain a copy of the License at 5 | 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | * See the License for the specific language governing permissions and 12 | * limitations under the License. 13 | */ 14 | 15 | import zhCN from './zh-CN.json' 16 | import enUS from './en-US.json' 17 | 18 | const locales = { 19 | 'zh-CN': zhCN, 20 | 'en-US': enUS 21 | } 22 | 23 | export function load (key: string, ls: any) { 24 | // @ts-expect-error 25 | locales[key] = ls 26 | } 27 | 28 | export default (key: string, locale: string) => { 29 | // @ts-expect-error 30 | return locales[locale]?.[key] ?? key 31 | } 32 | -------------------------------------------------------------------------------- /src/i18n/zh-CN.json: -------------------------------------------------------------------------------- 1 | { 2 | "indicator": "指标", 3 | "main_indicator": "主图指标", 4 | "sub_indicator": "副图指标", 5 | "setting": "设置", 6 | "timezone": "时区", 7 | "screenshot": "截屏", 8 | "full_screen": "全屏", 9 | "exit_full_screen": "退出全屏", 10 | "save": "保存", 11 | "confirm": "确定", 12 | "cancel": "取消", 13 | 14 | "ma": "MA(移动平均线)", 15 | "ema": "EMA(指数平滑移动平均线)", 16 | "sma": "SMA", 17 | "boll": "BOLL(布林线)", 18 | "bbi": "BBI(多空指数)", 19 | "sar": "SAR(停损点指向指标)", 20 | "vol": "VOL(成交量)", 21 | "macd": "MACD(指数平滑异同移动平均线)", 22 | "kdj": "KDJ(随机指标)", 23 | "rsi": "RSI(相对强弱指标)", 24 | "bias": "BIAS(乖离率)", 25 | "brar": "BRAR(情绪指标)", 26 | "cci": "CCI(顺势指标)", 27 | "dmi": "DMI(动向指标)", 28 | "cr": "CR(能量指标)", 29 | "psy": "PSY(心理线)", 30 | "dma": "DMA(平行线差指标)", 31 | "trix": "TRIX(三重指数平滑平均线)", 32 | "obv": "OBV(能量潮指标)", 33 | "vr": "VR(成交量变异率)", 34 | "wr": "WR(威廉指标)", 35 | "mtm": "MTM(动量指标)", 36 | "emv": "EMV(简易波动指标)", 37 | "roc": "ROC(变动率指标)", 38 | "pvt": "PVT(价量趋势指标)", 39 | "ao": "AO(动量震荡指标)", 40 | 41 | "utc": "世界统一时间", 42 | "honolulu": "(UTC-10) 檀香山", 43 | "juneau": "(UTC-8) 朱诺", 44 | "los_angeles": "(UTC-7) 洛杉矶", 45 | "chicago": "(UTC-5) 芝加哥", 46 | "toronto": "(UTC-4) 多伦多", 47 | "sao_paulo": "(UTC-3) 圣保罗", 48 | "london": "(UTC+1) 伦敦", 49 | "berlin": "(UTC+2) 柏林", 50 | "bahrain": "(UTC+3) 巴林", 51 | "dubai": "(UTC+4) 迪拜", 52 | "ashkhabad": "(UTC+5) 阿什哈巴德", 53 | "almaty": "(UTC+6) 阿拉木图", 54 | "bangkok": "(UTC+7) 曼谷", 55 | "shanghai": "(UTC+8) 上海", 56 | "tokyo": "(UTC+9) 东京", 57 | "sydney": "(UTC+10) 悉尼", 58 | "norfolk": "(UTC+12) 诺福克岛", 59 | 60 | "horizontal_straight_line": "水平直线", 61 | "horizontal_ray_line": "水平射线", 62 | "horizontal_segment": "水平线段", 63 | "vertical_straight_line": "垂直直线", 64 | "vertical_ray_line": "垂直射线", 65 | "vertical_segment": "垂直线段", 66 | "straight_line": "直线", 67 | "ray_line": "射线", 68 | "segment": "线段", 69 | "arrow": "箭头", 70 | "price_line": "价格线", 71 | "price_channel_line": "价格通道线", 72 | "parallel_straight_line": "平行直线", 73 | "fibonacci_line": "斐波那契回调直线", 74 | "fibonacci_segment": "斐波那契回调线段", 75 | "fibonacci_circle": "斐波那契圆环", 76 | "fibonacci_spiral": "斐波那契螺旋", 77 | "fibonacci_speed_resistance_fan": "斐波那契速度阻力扇", 78 | "fibonacci_extension": "斐波那契趋势扩展", 79 | "gann_box": "江恩箱", 80 | "rect": "矩形", 81 | "parallelogram": "平行四边形", 82 | "circle": "圆", 83 | "triangle": "三角形", 84 | "three_waves": "三浪", 85 | "five_waves": "五浪", 86 | "eight_waves": "八浪", 87 | "any_waves": "任意浪", 88 | "abcd": "ABCD形态", 89 | "xabcd": "XABCD形态", 90 | 91 | "weak_magnet": "弱磁模式", 92 | "strong_magnet": "强磁模式", 93 | 94 | "symbol_search": "商品搜索", 95 | "symbol_code": "商品代码", 96 | "params_1": "参数1", 97 | "params_2": "参数2", 98 | "params_3": "参数3", 99 | "params_4": "参数4", 100 | "params_5": "参数5", 101 | "period": "周期", 102 | "standard_deviation": "标准差", 103 | 104 | "candle_type": "蜡烛图类型", 105 | "candle_solid": "全实心", 106 | "candle_stroke": "全空心", 107 | "candle_up_stroke": "涨空心", 108 | "candle_down_stroke": "跌空心", 109 | "ohlc": "OHLC", 110 | "area": "面积图", 111 | 112 | "last_price_show": "最新价显示", 113 | "high_price_show": "最高价显示", 114 | "low_price_show": "最低价显示", 115 | "indicator_last_value_show": "指标最新值显示", 116 | "price_axis_type": "价格轴类型", 117 | "normal": "线性轴", 118 | "percentage": "百分比轴", 119 | "log": "对数轴", 120 | "reverse_coordinate": "倒置坐标", 121 | "grid_show": "网格线显示", 122 | "restore_default": "恢复默认" 123 | } -------------------------------------------------------------------------------- /src/iconfonts/fonts/icomoon.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/klinecharts/pro/4234b79f0bcfc26734d0a721c38cbd6d23aa38f5/src/iconfonts/fonts/icomoon.eot -------------------------------------------------------------------------------- /src/iconfonts/fonts/icomoon.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/klinecharts/pro/4234b79f0bcfc26734d0a721c38cbd6d23aa38f5/src/iconfonts/fonts/icomoon.ttf -------------------------------------------------------------------------------- /src/iconfonts/fonts/icomoon.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/klinecharts/pro/4234b79f0bcfc26734d0a721c38cbd6d23aa38f5/src/iconfonts/fonts/icomoon.woff -------------------------------------------------------------------------------- /src/iconfonts/style.css: -------------------------------------------------------------------------------- 1 | @font-face { 2 | font-family: 'icomoon'; 3 | src: url('fonts/icomoon.eot?f4efml'); 4 | src: url('fonts/icomoon.eot?f4efml#iefix') format('embedded-opentype'), 5 | url('fonts/icomoon.ttf?f4efml') format('truetype'), 6 | url('fonts/icomoon.woff?f4efml') format('woff'), 7 | url('fonts/icomoon.svg?f4efml#icomoon') format('svg'); 8 | font-weight: normal; 9 | font-style: normal; 10 | font-display: block; 11 | } 12 | 13 | [class^="icon-"], [class*=" icon-"] { 14 | /* use !important to prevent issues with browser extensions that change fonts */ 15 | font-family: 'icomoon' !important; 16 | speak: never; 17 | font-style: normal; 18 | font-weight: normal; 19 | font-variant: normal; 20 | text-transform: none; 21 | line-height: 1; 22 | 23 | /* Better Font Rendering =========== */ 24 | -webkit-font-smoothing: antialiased; 25 | -moz-osx-font-smoothing: grayscale; 26 | } 27 | 28 | .icon-icon-close:before { 29 | content: "\e900"; 30 | color: #fff; 31 | } 32 | .icon-icon-invisible:before { 33 | content: "\e901"; 34 | color: #fff; 35 | } 36 | .icon-icon-setting:before { 37 | content: "\e902"; 38 | color: #fff; 39 | } 40 | .icon-icon-visible:before { 41 | content: "\e903"; 42 | color: #fff; 43 | } 44 | -------------------------------------------------------------------------------- /src/index.less: -------------------------------------------------------------------------------- 1 | @import (reference) './base.less'; 2 | @import './component/index.less'; 3 | @import './widget/index.less'; 4 | @import './iconfonts/style.css'; 5 | 6 | .@{prefix-cls} { 7 | --klinecharts-pro-primary-color: @c-primary; 8 | --klinecharts-pro-hover-background-color: @c-hover-background-light; 9 | --klinecharts-pro-background-color: @c-background-light; 10 | --klinecharts-pro-popover-background-color: @c-popover-background-light; 11 | --klinecharts-pro-text-color: @c-text-light; 12 | --klinecharts-pro-text-second-color: @c-text-second-light; 13 | --klinecharts-pro-border-color: @c-border-light; 14 | --klinecharts-pro-selected-color: fade(@c-primary, 15%); 15 | &[data-theme="dark"] { 16 | --klinecharts-pro-hover-background-color: @c-hover-background-dark; 17 | --klinecharts-pro-background-color: @c-background-dark; 18 | --klinecharts-pro-popover-background-color: @c-popover-background-dark; 19 | --klinecharts-pro-text-color: @c-text-dark; 20 | --klinecharts-pro-text-second-color: @c-text-second-dark; 21 | --klinecharts-pro-border-color: @c-border-dark; 22 | } 23 | position: relative; 24 | display: flex; 25 | flex-direction: column; 26 | color: var(--klinecharts-pro-text-color); 27 | background-color: var(--klinecharts-pro-background-color); 28 | font-size: 14px; 29 | height: 80vh; 30 | &-watermark { 31 | position: absolute; 32 | left: 50%; 33 | top: 50%; 34 | z-index: 1; 35 | transform: translateX(-50%) translateY(-50%); 36 | .logo { 37 | width: 160px; 38 | height: 184px; 39 | fill: var(--klinecharts-pro-border-color); 40 | } 41 | } 42 | &-price-unit { 43 | display: none; 44 | position: absolute; 45 | left: 50%; 46 | top: 50%; 47 | z-index: 30; 48 | top: 4px; 49 | left: 50%; 50 | transform: translateX(-50%); 51 | border-radius: 4px; 52 | font-size: 10px; 53 | font-weight: bold; 54 | padding: 1px 4px; 55 | color: var(--klinecharts-pro-text-second-color); 56 | box-shadow: 0 3px 3px 0 rgba(50, 50, 50, .3); 57 | border: solid 1px var(--klinecharts-pro-border-color); 58 | background-color: var(--klinecharts-pro-background-color); 59 | } 60 | &-load-icon { 61 | position: absolute; 62 | left: 0; 63 | height: 0; 64 | z-index: -1; 65 | opacity: 0; 66 | } 67 | &-content { 68 | position: relative; 69 | display: flex; 70 | flex-direction: row; 71 | width: 100%; 72 | height: @widget-height; 73 | } 74 | &-widget { 75 | width: @widget-width; 76 | height: 100%; 77 | margin-left: 0; 78 | &[data-drawing-bar-visible="false"] { 79 | width: 100%; 80 | } 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Licensed under the Apache License, Version 2.0 (the "License"); 3 | * you may not use this file except in compliance with the License. 4 | * You may obtain a copy of the License at 5 | 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | * See the License for the specific language governing permissions and 12 | * limitations under the License. 13 | */ 14 | 15 | import { registerOverlay } from 'klinecharts' 16 | 17 | import overlays from './extension' 18 | 19 | import DefaultDatafeed from './DefaultDatafeed' 20 | import KLineChartPro from './KLineChartPro' 21 | 22 | import { load } from './i18n' 23 | 24 | import { Datafeed, SymbolInfo, Period, DatafeedSubscribeCallback, ChartProOptions, ChartPro } from './types' 25 | 26 | import './index.less' 27 | 28 | overlays.forEach(o => { registerOverlay(o) }) 29 | 30 | export { 31 | DefaultDatafeed, 32 | KLineChartPro, 33 | load as loadLocales 34 | } 35 | 36 | export type { 37 | Datafeed, SymbolInfo, Period, DatafeedSubscribeCallback, ChartProOptions, ChartPro 38 | } 39 | -------------------------------------------------------------------------------- /src/types.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Licensed under the Apache License, Version 2.0 (the "License"); 3 | * you may not use this file except in compliance with the License. 4 | * You may obtain a copy of the License at 5 | 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | * See the License for the specific language governing permissions and 12 | * limitations under the License. 13 | */ 14 | 15 | import { KLineData, Styles, DeepPartial } from 'klinecharts' 16 | 17 | export interface SymbolInfo { 18 | ticker: string 19 | name?: string 20 | shortName?: string 21 | exchange?: string 22 | market?: string 23 | pricePrecision?: number 24 | volumePrecision?: number 25 | priceCurrency?: string 26 | type?: string 27 | logo?: string 28 | } 29 | 30 | export interface Period { 31 | multiplier: number 32 | timespan: string 33 | text: string 34 | } 35 | 36 | export type DatafeedSubscribeCallback = (data: KLineData) => void 37 | 38 | export interface Datafeed { 39 | searchSymbols (search?: string): Promise 40 | getHistoryKLineData (symbol: SymbolInfo, period: Period, from: number, to: number): Promise 41 | subscribe (symbol: SymbolInfo, period: Period, callback: DatafeedSubscribeCallback): void 42 | unsubscribe (symbol: SymbolInfo, period: Period): void 43 | } 44 | 45 | export interface ChartProOptions { 46 | container: string | HTMLElement 47 | styles?: DeepPartial 48 | watermark?: string | Node 49 | theme?: string 50 | locale?: string 51 | drawingBarVisible?: boolean 52 | symbol: SymbolInfo 53 | period: Period 54 | periods?: Period[] 55 | timezone?: string 56 | mainIndicators?: string[] 57 | subIndicators?: string[] 58 | datafeed: Datafeed 59 | } 60 | 61 | export interface ChartPro { 62 | setTheme(theme: string): void 63 | getTheme(): string 64 | setStyles(styles: DeepPartial): void 65 | getStyles(): Styles 66 | setLocale(locale: string): void 67 | getLocale(): string 68 | setTimezone(timezone: string): void 69 | getTimezone(): string 70 | setSymbol(symbol: SymbolInfo): void 71 | getSymbol(): SymbolInfo 72 | setPeriod(period: Period): void 73 | getPeriod(): Period 74 | } 75 | -------------------------------------------------------------------------------- /src/widget/drawing-bar/icons/abcd.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * Licensed under the Apache License, Version 2.0 (the "License"); 3 | * you may not use this file except in compliance with the License. 4 | * You may obtain a copy of the License at 5 | 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | * See the License for the specific language governing permissions and 12 | * limitations under the License. 13 | */ 14 | 15 | export default () => ( 16 | 17 | 18 | 19 | ) 20 | -------------------------------------------------------------------------------- /src/widget/drawing-bar/icons/arrow.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * Licensed under the Apache License, Version 2.0 (the "License"); 3 | * you may not use this file except in compliance with the License. 4 | * You may obtain a copy of the License at 5 | 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | * See the License for the specific language governing permissions and 12 | * limitations under the License. 13 | */ 14 | 15 | export default () => ( 16 | 17 | 18 | 19 | ) 20 | -------------------------------------------------------------------------------- /src/widget/drawing-bar/icons/circle.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * Licensed under the Apache License, Version 2.0 (the "License"); 3 | * you may not use this file except in compliance with the License. 4 | * You may obtain a copy of the License at 5 | 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | * See the License for the specific language governing permissions and 12 | * limitations under the License. 13 | */ 14 | 15 | export default () => ( 16 | 17 | 18 | 19 | 20 | 21 | ) 22 | -------------------------------------------------------------------------------- /src/widget/drawing-bar/icons/fibonacciCircle.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * Licensed under the Apache License, Version 2.0 (the "License"); 3 | * you may not use this file except in compliance with the License. 4 | * You may obtain a copy of the License at 5 | 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | * See the License for the specific language governing permissions and 12 | * limitations under the License. 13 | */ 14 | 15 | export default () => ( 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | ) 24 | -------------------------------------------------------------------------------- /src/widget/drawing-bar/icons/fibonacciExtension.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * Licensed under the Apache License, Version 2.0 (the "License"); 3 | * you may not use this file except in compliance with the License. 4 | * You may obtain a copy of the License at 5 | 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | * See the License for the specific language governing permissions and 12 | * limitations under the License. 13 | */ 14 | 15 | export default () => ( 16 | 17 | 18 | 19 | ) 20 | 21 | -------------------------------------------------------------------------------- /src/widget/drawing-bar/icons/fibonacciLine.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * Licensed under the Apache License, Version 2.0 (the "License"); 3 | * you may not use this file except in compliance with the License. 4 | * You may obtain a copy of the License at 5 | 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | * See the License for the specific language governing permissions and 12 | * limitations under the License. 13 | */ 14 | 15 | export default () => ( 16 | 17 | 18 | 19 | ) 20 | 21 | 22 | -------------------------------------------------------------------------------- /src/widget/drawing-bar/icons/fibonacciSegment.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * Licensed under the Apache License, Version 2.0 (the "License"); 3 | * you may not use this file except in compliance with the License. 4 | * You may obtain a copy of the License at 5 | 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | * See the License for the specific language governing permissions and 12 | * limitations under the License. 13 | */ 14 | 15 | export default () => ( 16 | 17 | 18 | 19 | ) 20 | 21 | 22 | -------------------------------------------------------------------------------- /src/widget/drawing-bar/icons/fibonacciSpeedResistanceFan.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * Licensed under the Apache License, Version 2.0 (the "License"); 3 | * you may not use this file except in compliance with the License. 4 | * You may obtain a copy of the License at 5 | 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | * See the License for the specific language governing permissions and 12 | * limitations under the License. 13 | */ 14 | 15 | export default () => ( 16 | 17 | 18 | 19 | ) 20 | -------------------------------------------------------------------------------- /src/widget/drawing-bar/icons/fibonacciSpiral.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * Licensed under the Apache License, Version 2.0 (the "License"); 3 | * you may not use this file except in compliance with the License. 4 | * You may obtain a copy of the License at 5 | 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | * See the License for the specific language governing permissions and 12 | * limitations under the License. 13 | */ 14 | 15 | export default () => ( 16 | 17 | 18 | 19 | ) 20 | 21 | -------------------------------------------------------------------------------- /src/widget/drawing-bar/icons/fiveWaves.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * Licensed under the Apache License, Version 2.0 (the "License"); 3 | * you may not use this file except in compliance with the License. 4 | * You may obtain a copy of the License at 5 | 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | * See the License for the specific language governing permissions and 12 | * limitations under the License. 13 | */ 14 | 15 | export default () => ( 16 | 17 | 18 | 19 | ) 20 | -------------------------------------------------------------------------------- /src/widget/drawing-bar/icons/gannBox.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * Licensed under the Apache License, Version 2.0 (the "License"); 3 | * you may not use this file except in compliance with the License. 4 | * You may obtain a copy of the License at 5 | 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | * See the License for the specific language governing permissions and 12 | * limitations under the License. 13 | */ 14 | 15 | export default () => ( 16 | 17 | 18 | 19 | ) 20 | -------------------------------------------------------------------------------- /src/widget/drawing-bar/icons/horizontalRayLine.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * Licensed under the Apache License, Version 2.0 (the "License"); 3 | * you may not use this file except in compliance with the License. 4 | * You may obtain a copy of the License at 5 | 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | * See the License for the specific language governing permissions and 12 | * limitations under the License. 13 | */ 14 | 15 | export default () => ( 16 | 17 | 18 | 19 | ) 20 | -------------------------------------------------------------------------------- /src/widget/drawing-bar/icons/horizontalSegment.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * Licensed under the Apache License, Version 2.0 (the "License"); 3 | * you may not use this file except in compliance with the License. 4 | * You may obtain a copy of the License at 5 | 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | * See the License for the specific language governing permissions and 12 | * limitations under the License. 13 | */ 14 | 15 | export default () => ( 16 | 17 | 18 | 19 | ) 20 | -------------------------------------------------------------------------------- /src/widget/drawing-bar/icons/horizontalStraightLine.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * Licensed under the Apache License, Version 2.0 (the "License"); 3 | * you may not use this file except in compliance with the License. 4 | * You may obtain a copy of the License at 5 | 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | * See the License for the specific language governing permissions and 12 | * limitations under the License. 13 | */ 14 | 15 | export default () => ( 16 | 17 | 18 | 19 | ) 20 | -------------------------------------------------------------------------------- /src/widget/drawing-bar/icons/invisible.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * Licensed under the Apache License, Version 2.0 (the "License"); 3 | * you may not use this file except in compliance with the License. 4 | * You may obtain a copy of the License at 5 | 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | * See the License for the specific language governing permissions and 12 | * limitations under the License. 13 | */ 14 | 15 | export default () => ( 16 | 17 | 18 | 19 | ) 20 | -------------------------------------------------------------------------------- /src/widget/drawing-bar/icons/lock.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * Licensed under the Apache License, Version 2.0 (the "License"); 3 | * you may not use this file except in compliance with the License. 4 | * You may obtain a copy of the License at 5 | 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | * See the License for the specific language governing permissions and 12 | * limitations under the License. 13 | */ 14 | 15 | export default () => ( 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | ) 27 | -------------------------------------------------------------------------------- /src/widget/drawing-bar/icons/parallelStraightLine.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * Licensed under the Apache License, Version 2.0 (the "License"); 3 | * you may not use this file except in compliance with the License. 4 | * You may obtain a copy of the License at 5 | 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | * See the License for the specific language governing permissions and 12 | * limitations under the License. 13 | */ 14 | 15 | export default () => ( 16 | 17 | 18 | 19 | ) 20 | -------------------------------------------------------------------------------- /src/widget/drawing-bar/icons/parallelogram.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * Licensed under the Apache License, Version 2.0 (the "License"); 3 | * you may not use this file except in compliance with the License. 4 | * You may obtain a copy of the License at 5 | 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | * See the License for the specific language governing permissions and 12 | * limitations under the License. 13 | */ 14 | 15 | export default () => ( 16 | 17 | 18 | 19 | ) 20 | -------------------------------------------------------------------------------- /src/widget/drawing-bar/icons/priceChannelLine.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * Licensed under the Apache License, Version 2.0 (the "License"); 3 | * you may not use this file except in compliance with the License. 4 | * You may obtain a copy of the License at 5 | 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | * See the License for the specific language governing permissions and 12 | * limitations under the License. 13 | */ 14 | 15 | export default () => ( 16 | 17 | 18 | 19 | ) 20 | -------------------------------------------------------------------------------- /src/widget/drawing-bar/icons/priceLine.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * Licensed under the Apache License, Version 2.0 (the "License"); 3 | * you may not use this file except in compliance with the License. 4 | * You may obtain a copy of the License at 5 | 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | * See the License for the specific language governing permissions and 12 | * limitations under the License. 13 | */ 14 | 15 | export default () => ( 16 | 17 | 18 | 19 | ) 20 | -------------------------------------------------------------------------------- /src/widget/drawing-bar/icons/rayLine.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * Licensed under the Apache License, Version 2.0 (the "License"); 3 | * you may not use this file except in compliance with the License. 4 | * You may obtain a copy of the License at 5 | 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | * See the License for the specific language governing permissions and 12 | * limitations under the License. 13 | */ 14 | 15 | export default () => ( 16 | 17 | 18 | 19 | ) 20 | -------------------------------------------------------------------------------- /src/widget/drawing-bar/icons/rect.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * Licensed under the Apache License, Version 2.0 (the "License"); 3 | * you may not use this file except in compliance with the License. 4 | * You may obtain a copy of the License at 5 | 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | * See the License for the specific language governing permissions and 12 | * limitations under the License. 13 | */ 14 | 15 | export default () => ( 16 | 17 | 18 | 19 | ) 20 | -------------------------------------------------------------------------------- /src/widget/drawing-bar/icons/remove.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * Licensed under the Apache License, Version 2.0 (the "License"); 3 | * you may not use this file except in compliance with the License. 4 | * You may obtain a copy of the License at 5 | 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | * See the License for the specific language governing permissions and 12 | * limitations under the License. 13 | */ 14 | 15 | export default () => ( 16 | 17 | 18 | 19 | ) 20 | -------------------------------------------------------------------------------- /src/widget/drawing-bar/icons/segment.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * Licensed under the Apache License, Version 2.0 (the "License"); 3 | * you may not use this file except in compliance with the License. 4 | * You may obtain a copy of the License at 5 | 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | * See the License for the specific language governing permissions and 12 | * limitations under the License. 13 | */ 14 | 15 | export default () => ( 16 | 17 | 18 | 19 | ) 20 | -------------------------------------------------------------------------------- /src/widget/drawing-bar/icons/straightLine.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * Licensed under the Apache License, Version 2.0 (the "License"); 3 | * you may not use this file except in compliance with the License. 4 | * You may obtain a copy of the License at 5 | 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | * See the License for the specific language governing permissions and 12 | * limitations under the License. 13 | */ 14 | 15 | export default () => ( 16 | 17 | 18 | 19 | ) 20 | 21 | -------------------------------------------------------------------------------- /src/widget/drawing-bar/icons/strongMagnet.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * Licensed under the Apache License, Version 2.0 (the "License"); 3 | * you may not use this file except in compliance with the License. 4 | * You may obtain a copy of the License at 5 | 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | * See the License for the specific language governing permissions and 12 | * limitations under the License. 13 | */ 14 | 15 | export default (className?: string) => ( 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | ) 27 | -------------------------------------------------------------------------------- /src/widget/drawing-bar/icons/triangle.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * Licensed under the Apache License, Version 2.0 (the "License"); 3 | * you may not use this file except in compliance with the License. 4 | * You may obtain a copy of the License at 5 | 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | * See the License for the specific language governing permissions and 12 | * limitations under the License. 13 | */ 14 | 15 | export default () => ( 16 | 17 | 18 | 19 | ) 20 | -------------------------------------------------------------------------------- /src/widget/drawing-bar/icons/unlock.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * Licensed under the Apache License, Version 2.0 (the "License"); 3 | * you may not use this file except in compliance with the License. 4 | * You may obtain a copy of the License at 5 | 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | * See the License for the specific language governing permissions and 12 | * limitations under the License. 13 | */ 14 | 15 | export default () => ( 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | ) 27 | -------------------------------------------------------------------------------- /src/widget/drawing-bar/icons/verticalRayLine.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * Licensed under the Apache License, Version 2.0 (the "License"); 3 | * you may not use this file except in compliance with the License. 4 | * You may obtain a copy of the License at 5 | 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | * See the License for the specific language governing permissions and 12 | * limitations under the License. 13 | */ 14 | 15 | export default () => ( 16 | 17 | 18 | 19 | ) -------------------------------------------------------------------------------- /src/widget/drawing-bar/icons/verticalSegment.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * Licensed under the Apache License, Version 2.0 (the "License"); 3 | * you may not use this file except in compliance with the License. 4 | * You may obtain a copy of the License at 5 | 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | * See the License for the specific language governing permissions and 12 | * limitations under the License. 13 | */ 14 | 15 | export default () => ( 16 | 17 | 18 | 19 | ) 20 | -------------------------------------------------------------------------------- /src/widget/drawing-bar/icons/verticalStraightLine.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * Licensed under the Apache License, Version 2.0 (the "License"); 3 | * you may not use this file except in compliance with the License. 4 | * You may obtain a copy of the License at 5 | 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | * See the License for the specific language governing permissions and 12 | * limitations under the License. 13 | */ 14 | 15 | export default () => ( 16 | 17 | 18 | 19 | ) 20 | -------------------------------------------------------------------------------- /src/widget/drawing-bar/icons/visible.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * Licensed under the Apache License, Version 2.0 (the "License"); 3 | * you may not use this file except in compliance with the License. 4 | * You may obtain a copy of the License at 5 | 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | * See the License for the specific language governing permissions and 12 | * limitations under the License. 13 | */ 14 | 15 | export default () => ( 16 | 17 | 18 | 19 | ) -------------------------------------------------------------------------------- /src/widget/drawing-bar/icons/weakMagnet.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * Licensed under the Apache License, Version 2.0 (the "License"); 3 | * you may not use this file except in compliance with the License. 4 | * You may obtain a copy of the License at 5 | 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | * See the License for the specific language governing permissions and 12 | * limitations under the License. 13 | */ 14 | 15 | export default (className?: string) => ( 16 | 17 | 18 | 19 | ) 20 | -------------------------------------------------------------------------------- /src/widget/drawing-bar/icons/xabcd.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * Licensed under the Apache License, Version 2.0 (the "License"); 3 | * you may not use this file except in compliance with the License. 4 | * You may obtain a copy of the License at 5 | 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | * See the License for the specific language governing permissions and 12 | * limitations under the License. 13 | */ 14 | 15 | export default () => ( 16 | 17 | 18 | 19 | ) 20 | -------------------------------------------------------------------------------- /src/widget/drawing-bar/index.less: -------------------------------------------------------------------------------- 1 | @import (reference) '../../base.less'; 2 | 3 | @gap: 8px; 4 | 5 | .@{prefix-cls}-drawing-bar { 6 | width: @drawing-bar-width; 7 | height: 100%; 8 | box-sizing: border-box; 9 | border-right: solid 1px var(--klinecharts-pro-border-color); 10 | .item { 11 | display: flex; 12 | flex-direction: row; 13 | align-items: center; 14 | justify-content: center; 15 | position: relative; 16 | width: 100%; 17 | margin-top: @gap; 18 | cursor: pointer; 19 | color: var(--klinecharts-pro-text-second-color); 20 | fill: var(--klinecharts-pro-text-second-color); 21 | stroke: var(--klinecharts-pro-text-second-color); 22 | .icon-overlay { 23 | width: 32px; 24 | height: 32px; 25 | border-radius: 2px; 26 | transition: all 0.2s; 27 | &:hover { 28 | background-color: var(--klinecharts-pro-hover-background-color); 29 | } 30 | &.selected { 31 | background-color: var(--klinecharts-pro-selected-color)!important; 32 | fill: var(--klinecharts-pro-primary-color); 33 | stroke: var(--klinecharts-pro-primary-color); 34 | } 35 | } 36 | .icon-arrow { 37 | display: flex; 38 | flex-direction: row; 39 | align-items: center; 40 | justify-content: center; 41 | position: absolute; 42 | top: 0; 43 | right: 0; 44 | height: 32px; 45 | width: 10px; 46 | opacity: 0; 47 | transition: all .2s; 48 | border-top-left-radius: 2px; 49 | border-bottom-left-radius: 2px; 50 | z-index: 10; 51 | svg { 52 | width: 4px; 53 | height: 6px; 54 | transition: all .2s; 55 | &.rotate { 56 | transform: rotate(180deg); 57 | } 58 | } 59 | &:hover { 60 | background-color: var(--klinecharts-pro-hover-background-color); 61 | } 62 | } 63 | 64 | .list { 65 | position: absolute; 66 | top: 0; 67 | white-space: nowrap; 68 | left: calc(100% + 1px); 69 | background-color: var(--klinecharts-pro-popover-background-color); 70 | z-index: 99; 71 | box-shadow: 0 6px 12px 0 rgba(0, 0, 0, .3); 72 | min-height: auto; 73 | max-height: 320px; 74 | li { 75 | padding-left: 16px; 76 | .icon-overlay { 77 | &:hover { 78 | background-color: transparent; 79 | } 80 | } 81 | } 82 | } 83 | 84 | &:hover { 85 | .icon-arrow { 86 | opacity: 1; 87 | } 88 | } 89 | } 90 | 91 | .split-line { 92 | display: block; 93 | width: 100%; 94 | height: 1px; 95 | background-color: var(--klinecharts-pro-border-color); 96 | margin-top: @gap; 97 | } 98 | } -------------------------------------------------------------------------------- /src/widget/index.less: -------------------------------------------------------------------------------- 1 | @import './period-bar/index.less'; 2 | @import './drawing-bar/index.less'; 3 | @import './indicator-modal/index.less'; 4 | @import './setting-modal/index.less'; 5 | @import './indicator-setting-modal/index.less'; 6 | @import './symbol-search-modal/index.less'; 7 | -------------------------------------------------------------------------------- /src/widget/index.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * Licensed under the Apache License, Version 2.0 (the "License"); 3 | * you may not use this file except in compliance with the License. 4 | * You may obtain a copy of the License at 5 | 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | * See the License for the specific language governing permissions and 12 | * limitations under the License. 13 | */ 14 | 15 | import PeriodBar from './period-bar' 16 | import DrawingBar from './drawing-bar' 17 | import IndicatorModal from './indicator-modal' 18 | import TimezoneModal from './timezone-modal' 19 | import SettingModal from './setting-modal' 20 | import ScreenshotModal from './screenshot-modal' 21 | import IndicatorSettingModal from './indicator-setting-modal' 22 | import SymbolSearchModal from './symbol-search-modal' 23 | 24 | export { 25 | PeriodBar, DrawingBar, IndicatorModal, 26 | TimezoneModal, SettingModal, ScreenshotModal, 27 | IndicatorSettingModal, SymbolSearchModal 28 | } -------------------------------------------------------------------------------- /src/widget/indicator-modal/index.less: -------------------------------------------------------------------------------- 1 | @import (reference) '../../base.less'; 2 | 3 | .@{prefix-cls}-indicator-modal-list { 4 | margin-left: -20px; 5 | margin-right: -20px; 6 | height: 440px; 7 | position: relative; 8 | .title { 9 | position: sticky; 10 | top: 0; 11 | background-color: var(--klinecharts-pro-popover-background-color); 12 | font-size: 16px; 13 | color: var(--klinecharts-pro-text-color); 14 | font-weight: 400; 15 | &:hover { 16 | background-color: var(--klinecharts-pro-popover-background-color); 17 | } 18 | } 19 | .row:hover { 20 | .checkbox { 21 | fill: var(--klinecharts-pro-primary-color); 22 | color: var(--klinecharts-pro-primary-color); 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/widget/indicator-modal/index.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * Licensed under the Apache License, Version 2.0 (the "License"); 3 | * you may not use this file except in compliance with the License. 4 | * You may obtain a copy of the License at 5 | 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | * See the License for the specific language governing permissions and 12 | * limitations under the License. 13 | */ 14 | 15 | import { Component, createMemo } from 'solid-js' 16 | 17 | import { Modal, List, Checkbox } from '../../component' 18 | 19 | import i18n from '../../i18n' 20 | 21 | type OnIndicatorChange = ( 22 | params: { 23 | name: string 24 | paneId: string 25 | added: boolean 26 | } 27 | ) => void 28 | 29 | export interface IndicatorModalProps { 30 | locale: string 31 | mainIndicators: string[] 32 | subIndicators: object 33 | onMainIndicatorChange: OnIndicatorChange 34 | onSubIndicatorChange: OnIndicatorChange 35 | onClose: () => void 36 | } 37 | 38 | const IndicatorModal: Component = props => { 39 | 40 | return ( 41 | 45 | 47 |
  • {i18n('main_indicator', props.locale)}
  • 48 | { 49 | [ 50 | 'MA', 'EMA', 'SMA', 'BOLL', 'SAR', 'BBI' 51 | ].map(name => { 52 | const checked = props.mainIndicators.includes(name) 53 | return ( 54 |
  • { 57 | props.onMainIndicatorChange({ name, paneId: 'candle_pane', added: !checked }) 58 | }}> 59 | 60 |
  • 61 | ) 62 | }) 63 | } 64 |
  • {i18n('sub_indicator', props.locale)}
  • 65 | { 66 | [ 67 | 'MA', 'EMA', 'VOL', 'MACD', 'BOLL', 'KDJ', 68 | 'RSI', 'BIAS', 'BRAR', 'CCI', 'DMI', 69 | 'CR', 'PSY', 'DMA', 'TRIX', 'OBV', 70 | 'VR', 'WR', 'MTM', 'EMV', 'SAR', 71 | 'SMA', 'ROC', 'PVT', 'BBI', 'AO' 72 | ].map(name => { 73 | const checked = name in props.subIndicators 74 | return ( 75 |
  • { 78 | // @ts-expect-error 79 | props.onSubIndicatorChange({ name, paneId: props.subIndicators[name] ?? '', added: !checked }); 80 | }}> 81 | 82 |
  • 83 | ) 84 | }) 85 | } 86 |
    87 |
    88 | ) 89 | } 90 | 91 | export default IndicatorModal 92 | -------------------------------------------------------------------------------- /src/widget/indicator-setting-modal/index.less: -------------------------------------------------------------------------------- 1 | @import (reference) '../../base.less'; 2 | 3 | .@{prefix-cls}-indicator-setting-modal-content { 4 | display: grid; 5 | grid-template-columns: auto auto; 6 | grid-row-gap: 20px; 7 | margin-top: 20px; 8 | align-items: center; 9 | } -------------------------------------------------------------------------------- /src/widget/indicator-setting-modal/index.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * Licensed under the Apache License, Version 2.0 (the "License"); 3 | * you may not use this file except in compliance with the License. 4 | * You may obtain a copy of the License at 5 | 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | * See the License for the specific language governing permissions and 12 | * limitations under the License. 13 | */ 14 | 15 | import { Component, createSignal } from 'solid-js' 16 | 17 | import { utils } from 'klinecharts' 18 | 19 | import { Modal, Input } from '../../component' 20 | 21 | import i18n from '../../i18n' 22 | 23 | import data from './data' 24 | 25 | export interface IndicatorSettingModalProps { 26 | locale: string 27 | params: { indicatorName: string, paneId: string, calcParams: any[] } 28 | onClose: () => void 29 | onConfirm: (calcParams: any) => void 30 | } 31 | 32 | const IndicatorSettingModal: Component = props => { 33 | const [calcParams, setCalcParams] = createSignal(utils.clone(props.params.calcParams)) 34 | 35 | const getConfig: (name: string) => any[] = (name: string) => { 36 | // @ts-expect-error 37 | return data[name] 38 | } 39 | 40 | return ( 41 | { 49 | const config = getConfig(props.params.indicatorName) 50 | const params: any[] = [] 51 | utils.clone(calcParams()).forEach((param: any, i: number) => { 52 | if (!utils.isValid(param) || param === '') { 53 | if ('default' in config[i]) { 54 | params.push(config[i]['default']) 55 | } 56 | } else { 57 | params.push(param) 58 | } 59 | }) 60 | props.onConfirm(params) 61 | props.onClose() 62 | } 63 | } 64 | ]} 65 | onClose={props.onClose}> 66 |
    67 | { 68 | getConfig(props.params.indicatorName).map((d, i) => { 69 | return ( 70 | <> 71 | {i18n(d.paramNameKey, props.locale)} 72 | { 78 | const params = utils.clone(calcParams()) 79 | params[i] = value 80 | setCalcParams(params) 81 | }}/> 82 | 83 | ) 84 | }) 85 | } 86 |
    87 | 88 |
    89 | ) 90 | } 91 | 92 | export default IndicatorSettingModal 93 | -------------------------------------------------------------------------------- /src/widget/period-bar/index.less: -------------------------------------------------------------------------------- 1 | @import (reference) '../../base.less'; 2 | 3 | .@{prefix-cls}-period-bar { 4 | display: flex; 5 | flex-direction: row; 6 | align-items: center; 7 | height: @period-bar-height; 8 | width: 100%; 9 | box-sizing: border-box; 10 | border-bottom: solid 1px var(--klinecharts-pro-border-color); 11 | .menu-container { 12 | display: flex; 13 | height: 100%; 14 | flex-direction: row; 15 | justify-content: center; 16 | align-items: center; 17 | width: @drawing-bar-width; 18 | box-sizing: border-box; 19 | border-right: solid 1px var(--klinecharts-pro-border-color); 20 | svg { 21 | fill: var(--klinecharts-pro-text-color); 22 | width: 28px; 23 | height: 28px; 24 | cursor: pointer; 25 | transition: all .2s; 26 | &.rotate { 27 | transform: rotate(180deg); 28 | transform-origin: center; 29 | } 30 | } 31 | } 32 | .symbol { 33 | display: flex; 34 | flex-direction: row; 35 | align-items: center; 36 | height: 100%; 37 | font-size: 18px; 38 | padding: 0 12px; 39 | font-weight: bold; 40 | box-sizing: border-box; 41 | border-right: solid 1px var(--klinecharts-pro-border-color); 42 | cursor: pointer; 43 | img { 44 | width: 20px; 45 | height: 20px; 46 | margin-right: 6px; 47 | } 48 | } 49 | .item { 50 | transition: all 0.2s; 51 | box-sizing: border-box; 52 | cursor: pointer; 53 | fill: var(--klinecharts-pro-text-color); 54 | &.selected { 55 | background-color: var(--klinecharts-pro-selected-color)!important; 56 | color: var(--klinecharts-pro-primary-color); 57 | } 58 | } 59 | .period { 60 | padding: 2px 6px; 61 | margin: 0 4px; 62 | border-radius: 2px; 63 | &:hover { 64 | background-color: var(--klinecharts-pro-hover-background-color); 65 | } 66 | &:first-child { 67 | margin-left: 8px; 68 | } 69 | } 70 | .symbol + .period, .menu-container + .period { 71 | margin-left: 12px; 72 | } 73 | .tools { 74 | display: flex; 75 | flex-direction: row; 76 | align-items: center; 77 | justify-content: center; 78 | height: 100%; 79 | padding: 0 12px; 80 | border-right: solid 1px var(--klinecharts-pro-border-color); 81 | &:hover { 82 | fill: var(--klinecharts-pro-primary-color); 83 | color: var(--klinecharts-pro-primary-color); 84 | } 85 | svg { 86 | width: 16px; 87 | height: 16px; 88 | margin-right: 4px; 89 | } 90 | } 91 | .period + .tools { 92 | border-left: solid 1px var(--klinecharts-pro-border-color); 93 | margin-left: 8px; 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /src/widget/screenshot-modal/index.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * Licensed under the Apache License, Version 2.0 (the "License"); 3 | * you may not use this file except in compliance with the License. 4 | * You may obtain a copy of the License at 5 | 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | * See the License for the specific language governing permissions and 12 | * limitations under the License. 13 | */ 14 | 15 | import { Component } from 'solid-js' 16 | 17 | import { Modal } from '../../component' 18 | 19 | import i18n from '../../i18n' 20 | 21 | export interface ScreenshotModalProps { 22 | locale: string 23 | url: string 24 | onClose: () => void 25 | } 26 | 27 | const ScreenshotModal: Component = props => { 28 | return ( 29 | { 37 | const a = document.createElement('a') 38 | a.download = 'screenshot' 39 | a.href = props.url 40 | document.body.appendChild(a) 41 | a.click() 42 | a.remove() 43 | } 44 | } 45 | ]} 46 | onClose={props.onClose}> 47 | 48 | 49 | ) 50 | } 51 | 52 | export default ScreenshotModal 53 | -------------------------------------------------------------------------------- /src/widget/setting-modal/data.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Licensed under the Apache License, Version 2.0 (the "License"); 3 | * you may not use this file except in compliance with the License. 4 | * You may obtain a copy of the License at 5 | 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | * See the License for the specific locale governing permissions and 12 | * limitations under the License. 13 | */ 14 | 15 | import i18n from '../../i18n' 16 | 17 | export function getOptions (locale: string) { 18 | return [ 19 | { 20 | key: 'candle.type', 21 | text: i18n('candle_type', locale), 22 | component: 'select', 23 | dataSource: [ 24 | { key: 'candle_solid', text: i18n('candle_solid', locale) }, 25 | { key: 'candle_stroke', text: i18n('candle_stroke', locale) }, 26 | { key: 'candle_up_stroke', text: i18n('candle_up_stroke', locale) }, 27 | { key: 'candle_down_stroke', text: i18n('candle_down_stroke', locale) }, 28 | { key: 'ohlc', text: i18n('ohlc', locale) }, 29 | { key: 'area', text: i18n('area', locale) } 30 | ] 31 | }, 32 | { 33 | key: 'candle.priceMark.last.show', 34 | text: i18n('last_price_show', locale), 35 | component: 'switch' 36 | }, 37 | { 38 | key: 'candle.priceMark.high.show', 39 | text: i18n('high_price_show', locale), 40 | component: 'switch' 41 | }, 42 | { 43 | key: 'candle.priceMark.low.show', 44 | text: i18n('low_price_show', locale), 45 | component: 'switch' 46 | }, 47 | { 48 | key: 'indicator.lastValueMark.show', 49 | text: i18n('indicator_last_value_show', locale), 50 | component: 'switch' 51 | }, 52 | { 53 | key: 'yAxis.type', 54 | text: i18n('price_axis_type', locale), 55 | component: 'select', 56 | dataSource: [ 57 | { key: 'normal', text: i18n('normal', locale) }, 58 | { key: 'percentage', text: i18n('percentage', locale) }, 59 | { key: 'log', text: i18n('log', locale) } 60 | ], 61 | }, 62 | { 63 | key: 'yAxis.reverse', 64 | text: i18n('reverse_coordinate', locale), 65 | component: 'switch', 66 | }, 67 | { 68 | key: 'grid.show', 69 | text: i18n('grid_show', locale), 70 | component: 'switch', 71 | } 72 | ] 73 | } 74 | -------------------------------------------------------------------------------- /src/widget/setting-modal/index.less: -------------------------------------------------------------------------------- 1 | @import (reference) '../../base.less'; 2 | 3 | .@{prefix-cls}-setting-modal-content { 4 | display: grid; 5 | grid-template-columns: auto auto auto auto; 6 | grid-row-gap: 20px; 7 | margin-top: 20px; 8 | margin-bottom: 30px; 9 | align-items: center; 10 | } 11 | -------------------------------------------------------------------------------- /src/widget/setting-modal/index.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * Licensed under the Apache License, Version 2.0 (the "License"); 3 | * you may not use this file except in compliance with the License. 4 | * You may obtain a copy of the License at 5 | 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | * See the License for the specific language governing permissions and 12 | * limitations under the License. 13 | */ 14 | 15 | import { Component, createEffect, For, createSignal } from 'solid-js' 16 | import { Styles, utils, DeepPartial } from 'klinecharts' 17 | 18 | import lodashSet from 'lodash/set' 19 | 20 | import { Modal, Select, Switch } from '../../component' 21 | import type { SelectDataSourceItem } from '../../component' 22 | 23 | import i18n from '../../i18n' 24 | import { getOptions } from './data' 25 | 26 | export interface SettingModalProps { 27 | locale: string 28 | currentStyles: Styles 29 | onClose: () => void 30 | onChange: (style: DeepPartial) => void 31 | onRestoreDefault: (options: SelectDataSourceItem[]) => void 32 | } 33 | 34 | const SettingModal: Component = props => { 35 | const [styles, setStyles] = createSignal(props.currentStyles) 36 | const [options, setOptions] = createSignal(getOptions(props.locale)) 37 | 38 | createEffect(() => { 39 | setOptions(getOptions(props.locale)) 40 | }) 41 | 42 | const update = (option: SelectDataSourceItem, newValue: any) => { 43 | const style = {} 44 | lodashSet(style, option.key, newValue) 45 | const ss = utils.clone(styles()) 46 | lodashSet(ss, option.key, newValue) 47 | setStyles(ss) 48 | setOptions(options().map(op => ({ ...op }))) 49 | props.onChange(style) 50 | } 51 | 52 | return ( 53 | { 60 | props.onRestoreDefault(options()) 61 | props.onClose() 62 | } 63 | } 64 | ]} 65 | onClose={props.onClose}> 66 |
    68 | 69 | { 70 | option => { 71 | let component 72 | const value = utils.formatValue(styles(), option.key) 73 | switch (option.component) { 74 | case 'select': { 75 | component = ( 76 | 45 | 46 | 47 | } 48 | value={value()} 49 | onChange={v => { 50 | const va = `${v}` 51 | setValue(va) 52 | }}/> 53 | ( 58 |
  • { 60 | props.onSymbolSelected(symbol) 61 | props.onClose() 62 | }}> 63 |
    64 | 65 | symbol 66 | 67 | {symbol.shortName ?? symbol.ticker}{`${symbol.name ? `(${symbol.name})` : ''}`} 68 |
    69 | {symbol.exchange ?? ''} 70 |
  • 71 | )}> 72 |
    73 | 74 | ) 75 | } 76 | 77 | export default SymbolSearchModal 78 | -------------------------------------------------------------------------------- /src/widget/timezone-modal/data.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Licensed under the Apache License, Version 2.0 (the "License"); 3 | * you may not use this file except in compliance with the License. 4 | * You may obtain a copy of the License at 5 | 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | * See the License for the specific language governing permissions and 12 | * limitations under the License. 13 | */ 14 | 15 | import i18n from '../../i18n' 16 | 17 | import { SelectDataSourceItem } from '../../component' 18 | 19 | export function translateTimezone (timezone: string, locale: string): string { 20 | switch (timezone) { 21 | case 'Etc/UTC': return i18n('utc', locale) 22 | case 'Pacific/Honolulu': return i18n('honolulu', locale) 23 | case 'America/Juneau': return i18n('juneau', locale) 24 | case 'America/Los_Angeles': return i18n('los_angeles', locale) 25 | case 'America/Chicago': return i18n('chicago', locale) 26 | case'America/Toronto': return i18n('toronto', locale) 27 | case 'America/Sao_Paulo': return i18n('sao_paulo', locale) 28 | case 'Europe/London': return i18n('london', locale) 29 | case 'Europe/Berlin': return i18n('berlin', locale) 30 | case 'Asia/Bahrain': return i18n('bahrain', locale) 31 | case 'Asia/Dubai': return i18n('dubai', locale) 32 | case 'Asia/Ashkhabad': return i18n('ashkhabad', locale) 33 | case 'Asia/Almaty': return i18n('almaty', locale) 34 | case 'Asia/Bangkok': return i18n('bangkok', locale) 35 | case 'Asia/Shanghai': return i18n('shanghai', locale) 36 | case 'Asia/Tokyo': return i18n('tokyo', locale) 37 | case 'Australia/Sydney': return i18n('sydney', locale) 38 | case 'Pacific/Norfolk': return i18n('norfolk', locale) 39 | } 40 | return timezone 41 | } 42 | 43 | export function createTimezoneSelectOptions (locale: string): SelectDataSourceItem[] { 44 | return [ 45 | { key: 'Etc/UTC', text: i18n('utc', locale) }, 46 | { key: 'Pacific/Honolulu', text: i18n('honolulu', locale) }, 47 | { key: 'America/Juneau', text: i18n('juneau', locale) }, 48 | { key: 'America/Los_Angeles', text: i18n('los_angeles', locale) }, 49 | { key: 'America/Chicago', text: i18n('chicago', locale) }, 50 | { key: 'America/Toronto', text: i18n('toronto', locale) }, 51 | { key: 'America/Sao_Paulo', text: i18n('sao_paulo', locale) }, 52 | { key: 'Europe/London', text: i18n('london', locale) }, 53 | { key: 'Europe/Berlin', text: i18n('berlin', locale) }, 54 | { key: 'Asia/Bahrain', text: i18n('bahrain', locale) }, 55 | { key: 'Asia/Dubai', text: i18n('dubai', locale) }, 56 | { key: 'Asia/Ashkhabad', text: i18n('ashkhabad', locale) }, 57 | { key: 'Asia/Almaty', text: i18n('almaty', locale) }, 58 | { key: 'Asia/Bangkok', text: i18n('bangkok', locale) }, 59 | { key: 'Asia/Shanghai', text: i18n('shanghai', locale) }, 60 | { key: 'Asia/Tokyo', text: i18n('tokyo', locale) }, 61 | { key: 'Australia/Sydney', text: i18n('sydney', locale) }, 62 | { key: 'Pacific/Norfolk', text: i18n('norfolk', locale) } 63 | ] 64 | } -------------------------------------------------------------------------------- /src/widget/timezone-modal/index.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * Licensed under the Apache License, Version 2.0 (the "License"); 3 | * you may not use this file except in compliance with the License. 4 | * You may obtain a copy of the License at 5 | 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | 8 | * Unless required by applicable law or agreed to in writing, software 9 | * distributed under the License is distributed on an "AS IS" BASIS, 10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | * See the License for the specific language governing permissions and 12 | * limitations under the License. 13 | */ 14 | 15 | import { Component, createSignal, createMemo } from 'solid-js' 16 | 17 | import { Modal, Select } from '../../component' 18 | import type { SelectDataSourceItem } from '../../component' 19 | import i18n from '../../i18n' 20 | 21 | import { createTimezoneSelectOptions } from './data' 22 | 23 | export interface TimezoneModalProps { 24 | locale: string 25 | timezone: SelectDataSourceItem 26 | onClose: () => void 27 | onConfirm: (timezone: SelectDataSourceItem) => void 28 | } 29 | 30 | const TimezoneModal: Component = props => { 31 | const [innerTimezone, setInnerTimezone] = createSignal(props.timezone) 32 | 33 | const timezoneOptions = createMemo(() => createTimezoneSelectOptions(props.locale)) 34 | 35 | return ( 36 | { 43 | props.onConfirm(innerTimezone()) 44 | props.onClose() 45 | } 46 | } 47 | ]} 48 | onClose={props.onClose}> 49 |