组件样式
组件的外观由一组 token 构成:各类部件的圆角、控件与工具栏的尺寸、字体、边框、阴影、选中按钮的样式,
以及工具栏和画线工具是沿边停靠还是悬浮。从一套预设出发,想改哪里就改哪里。颜色仍由主题决定
(dark / light,参见 API 参考);任何外观都能与这两种主题搭配。
● 演示你自己的外观模拟行情数据,在你的浏览器中生成预设
| 预设 | 外观 |
|---|---|
studio(默认) | 控件圆角 7 px,菜单 11 px,对话框 16 px。分组之间用间距而非分隔线隔开,菜单浮在柔和的阴影之上, 周期按钮位于分段式轨道中,选中的按钮以浅色调填充。 |
terminal | 紧凑方正:2 px 圆角、26 px 高的控件、分组之间有分隔线、标签大写,选中的按钮下方有一条下划线。 图表上的价格标签为直角。 |
capsule | 处处都是胶囊形,价格标签也不例外。工具栏和画线工具像小岛一样悬浮,菜单是磨砂玻璃效果,选中的按钮是实心胶囊。 |
选择外观
import { ChartWidget, ChartWidgetGrid } from '@tradecanvas/chart/widget'
const widget = new ChartWidget(host, { ui: 'terminal' })
widget.setUI('capsule') // in place: nothing is rebuilt
widget.getUI() // every token, resolved
// A grid: every chart and the grid's bar, and the charts it adds later
const grid = new ChartWidgetGrid(host, { layout: '2x2', widget: { ui: 'terminal' } })
grid.setUI('studio')
grid.getUI() 自定义外观
自定义主题从一套预设开始(未指定时为 Studio),只修改其中写明的部分。在圆角刻度上设置的值会作用于所有跟随该刻度的部件, 除非你单独设置了该部件自己的圆角。
widget.setUI({
preset: 'studio',
radius: { xs: 3, sm: 5, md: 10, lg: 12, xl: 18 }, // the scale, px (999: pills)
components: { dialog: 20, tag: 0 }, // a part's own corners
density: 'compact', // compact · comfortable · spacious
sizes: { toolbar: 40 }, // px; wins over density
font: {
family: "'Manrope', system-ui, sans-serif",
mono: "'JetBrains Mono', monospace",
size: 13, weight: 500, strongWeight: 600,
labelCase: 'uppercase', labelTracking: 0.06, // small labels
},
borders: { width: 1, separators: true }, // rules between toolbar groups
shadows: { menu: '0 12px 30px rgba(0, 0, 0, 0.4)' },
blur: 12, // frosted floating surfaces, px
active: 'solid', // tint · solid · underline
toolbar: 'floating', // docked · floating
sidebar: 'floating',
intervals: 'segmented', // plain · segmented
tagRadius: 999, // the chart's price tags and pills
}) | 字段 | 设置内容 |
|---|---|
radius | 圆角刻度 xs、sm、md、lg、xl,单位 px(0–999)。 |
components | 单个部件自己的圆角:control(按钮)、input、menu、dialog、 panel(提醒、数据窗口、下单面板)、tooltip、tag、toast,
以及 toolbar 和 sidebar(它们自身的外框,悬浮时可见)。默认情况下,控件和输入框取 md,菜单和面板取 lg,对话框取 xl,提示框和标签取 sm。 |
density / sizes | toolbar 高度、control 与 controlSmall 高度、icon、 sidebar 宽度以及 menuItem 高度,单位 px。 |
font | 字体族(CSS 字体列表)、正文 size(11–20 px;较小的字号随之变化)、字重,以及小标签(如分区标题)的大小写和字间距(em)。 |
borders | 边框宽度,以及工具栏的分组之间、画线工具之间是否用分隔线隔开。 |
shadows | 菜单、对话框和提示框的 CSS 阴影。 |
blur | 磨砂菜单,单位 px:大于 0 时,菜单会透出部分经过模糊的图表。 |
active | 选中按钮的样式:浅色调填充、实心胶囊或下划线。 |
toolbar / sidebar | 沿边停靠,或像小岛一样悬浮。 |
intervals | 周期按钮保持原样,或放入分段式轨道中。 |
tagRadius | 图表绘制的价格标签、坐标轴胶囊标签和订单徽标的圆角。 |
无法使用的值(超出范围,或可能跳出其声明的 CSS)会被忽略,并沿用预设中的值。
字体
组件不会加载任何字体:它只写出字体名称,由浏览器按列表依次回退。Studio 指定 Manrope,其次是 Inter; Terminal 指定 IBM Plex Sans Condensed 和 IBM Plex Mono;Capsule 指定 Sora。请自行加载需要的字体:
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Manrope:wght@400;500;600;700&display=swap"> CSS 变量
这些 token 是组件根元素(以及其对话框)上的 CSS 变量。不设置 ui 选项时,它们沿用样式表中的值(即 Studio 的值),
因此你自己的 CSS 可以设置它们:组件会把自己的样式表放在页面最前面,所以你写在 .tcw-root 上的规则会生效。
设置 ui 后,组件会把它们直接写到元素上,并以这些值为准。
.tcw-root {
--tcw-radius: 4px; /* the md corner: buttons and fields follow it */
--tcw-dialog-radius: 12px;
--tcw-control-h: 28px;
--tcw-font: 'Inter', system-ui, sans-serif;
} | 变量 | 来源 |
|---|---|
--tcw-radius-xs、-sm、--tcw-radius、-lg、-xl | radius |
--tcw-control-radius、--tcw-input-radius、--tcw-menu-radius、--tcw-dialog-radius、--tcw-panel-radius、--tcw-tooltip-radius、--tcw-tag-radius、--tcw-toast-radius、--tcw-toolbar-radius、--tcw-sidebar-radius | components |
--tcw-toolbar-h、--tcw-control-h、--tcw-control-h-sm、--tcw-icon、--tcw-sidebar-w、--tcw-menu-item-h | sizes |
--tcw-font、--tcw-font-mono、--tcw-font-size(以及 -sm、-xs、-lg)、--tcw-weight、--tcw-weight-strong、--tcw-label-case、--tcw-label-tracking | font |
--tcw-border-w、--tcw-sep-w | borders |
--tcw-menu-shadow、--tcw-dialog-shadow、--tcw-tooltip-shadow | shadows |
--tcw-blur、--tcw-surface-opacity | blur |
布局开关是同一批元素上的 data 属性,可供你编写自己的 CSS: data-tcw-ui(预设)、data-tcw-active、data-tcw-toolbar、 data-tcw-sidebar、data-tcw-intervals 和 data-tcw-separators(on / off)。
输入框、列表与日历
组件中的每个输入框(提醒、设置、下单面板、跳转到日期、指标参数)都是同一种外观:淡淡的底色和细线边框,悬停时线条更清晰,聚焦时线条变为强调色,周围没有光圈。下拉框打开组件自带的列表:选中的行带勾号,分组显示为标题,支持方向键、Enter、Escape 和首字母输入;日期框打开组件自带的日历:每周从该语言习惯的那一天开始,今天带下划线,超出 min 和 max 的日期变灰。复选框、单选框、滑块和开关使用同一套变量,滚动条也一样:细而圆润,只有滑块,没有轨道。
这些输入框仍然是浏览器原生的 <select> 和 <input>:取值、事件和表单照常工作;在触屏上会打开手机自带的滚轮和日历,更适合手指操作。
外观来自以下变量,深色和浅色主题各有一套取值:
--tcw-field-bg, --tcw-field-bg-hover, --tcw-field-bg-focus, --tcw-field-line, --tcw-field-line-hover, --tcw-field-line-focus, --tcw-field-placeholder, --tcw-check-line, --tcw-scroll-thumb, --tcw-scroll-thumb-hover.
.tcw-root {
--tcw-field-bg: transparent; /* fields as lines, no fill */
--tcw-field-line: rgba(255, 255, 255, 0.12);
--tcw-field-line-focus: #5b8cff; /* focus in your brand colour */
} 图表的外观:样式覆盖
主题决定整个图表的颜色。图表所画的任何一部分都可以按键单独设置:每个方向的网格线、十字光标、坐标轴、 面板、图例、最新价、成交量、时段分隔线,以及每种图表类型下的主序列。没有设置的键沿用主题,所以切换主题时, 您没设置的部分仍会跟着变色。
import { Chart } from '@tradecanvas/chart'
const chart = new Chart(host, {
overrides: { 'grid.vertical.visible': false }, // 初始设置
})
chart.applyOverrides({
'series.candlestick.upColor': '#26a69a', // 所有涨跌类图表都回退到它
'series.candlestick.downColor': '#ef5350',
'grid.horizontal.style': 'dotted',
'crosshair.vertical.style': 'solid',
'crosshair.labelBackground': '#2962ff',
'lastPrice.style': 'solid',
'panes.background': '#0d1117',
'legend.textColor': '#c9d1d9',
})
chart.applyOverrides({ 'legend.textColor': null }) // null 移除一个键
chart.resetOverrides(['grid.horizontal.style']) // 或列出要移除的键
chart.setOverrides({ 'background.color': '#000' }) // 一次替换整个层
chart.getStyleValue('series.bar.upColor') // '#26a69a': 某个键最终的值
chart.getStyle().grid.vertical // { visible: false, color, style, width }
chart.on('styleChange', (e) => e.payload.layer) // 'host' | 'user' 键
| 键 | 设置内容 |
|---|---|
background.color | 图表背景(面板没有自己的背景时也用它)。 |
panes.background, .separatorColor, .titleColor | 指标面板:背景、顶部的分隔条、名称。 |
grid.horizontal.*, grid.vertical.* | visible、color、style(solid · dashed · dotted)、width,每个方向分别设置。 |
crosshair.horizontal.*, crosshair.vertical.* | 十字光标线的同样四项(默认为虚线)。 |
crosshair.labelBackground, .labelTextColor | 坐标轴以及面板刻度上的价格、时间标签。 |
axis.price.lineColor, .textColor, axis.time.* | 每个坐标轴的轴线和标签(面板刻度沿用价格轴的)。 |
legend.textColor, .labelColor | 图例中的数值,以及它的标签(O、H、L、Vol)。 |
lastPrice.visible, .upColor, .downColor, .style, .width | 最新价线和标签;未设置时颜色跟随主序列。 |
volume.upColor, .downColor | 成交量柱。 |
sessionBreaks.color, .style, .width | 日、周、月分隔线。 |
highLow.color, watermark.color | 最高价与最低价线、水印。 |
trading.buyColor, .sellColor, .profitColor, .lossColor, .entryColor | 订单(买、卖)和持仓(盈、亏、入场),包括图表上和价格轴上,覆盖交易配置里的颜色。 |
markers.longColor, .shortColor, .neutralColor | 信号标记,覆盖它们自己的样式。 |
tradeZones.profitColor, .lossColor, .activeColor | 交易区域:盈利、亏损和未平仓。 |
drawings.handleColor | 选中绘图的控制点(不设置时为白色)。 |
series.<type>.* | 主序列以该类型绘制时的样式:upColor、downColor、wickUpColor、 wickDownColor(K线、Heikin-Ashi、成交量K线、等量图),color / lineColor 和 lineWidth(折线、阶梯线、带点折线、面积图、HLC 面积图、基线图),topColor 和 bottomColor(面积图、HLC 面积图)。 |
CHART_STYLE_KEYS 列出了每个键及其取值类型,TypeScript 会在您编写时检查键和值。涨跌颜色回退到 series.candlestick.*,线条颜色和宽度回退到 series.line.*,面积填充回退到 series.area.*,然后是主题;设置了实体颜色后,影线也随之使用该颜色。未知的键和值会被忽略并给出警告。
应用的与用户的
覆盖分为两层。您的(layer: 'host',默认)在切换主题时保留,且从不保存。用户的
(layer: 'user')优先于您的,按设置时的主题保存——在深色主题上选的颜色会随深色主题回来——并随 saveState() 一起保存。组件的设置面板写入用户层,其“重置”会回到当前主题的颜色。
“样式”页按这些键设置图表的各个部分,包括当前图表类型的颜色;“交易”页设置订单、持仓、信号标记和交易区域的颜色。
交由该部分自己决定的颜色显示为“自动”,点“自动”即可恢复。
chart.applyOverrides({ 'background.color': '#0b0b0f' }, { layer: 'user' })
chart.getOverrides({ layer: 'user' }) // 当前主题下用户的覆盖
chart.getTheme() // 设置时的主题:覆盖单独存放 网格和十字光标选项(grid.hLineColor、crosshair.vLine.style…)是对应键的简写。多图表网格
会把覆盖应用到其所有图表:grid.applyOverrides(patch)。React、Vue 和 Svelte 组件通过 overrides 属性接收它们。
指标线条与面板
// 每条线各自的线型和显示与否,按键设置(颜色和宽度仍在 colors / lineWidths 中)
chart.updateIndicatorStyle(macdId, { plots: { signal: { lineStyle: 'dashed' }, histogram: { visible: false } } })
// 从现在起同类指标的初始样式
chart.setIndicatorDefaults('ema', { colors: ['#f5a623'], lineWidths: [2] })
// 面板自己的背景和分隔线,随其指标一起保存
chart.setPaneStyle(rsiId, { background: '#101418', separator: '#f5a623' }) 隐藏的线条没有数值标签,也不在图例中显示数值。所有指标都不绘制隐藏的线条,几乎所有指标也支持线条的线型; 少数绘制自有图形的指标(Parabolic SAR 点、Supertrend、Zig Zag、成交量分布)保持自己的笔触。
图表上的标签
组件会把 tagRadius 传给它的图表(写在 chartOptions.shapes 中的形状会一直保留,直到你调用 setUI)。直接使用 Chart 时,请自行设置形状;切换主题后该设置依然保留。价格标签、坐标轴和十字光标的胶囊标签、
委托、持仓和括号单的标签,以及前一周期高低点的标签都会采用这一形状。
const chart = new Chart(host, { shapes: { tagRadius: 4 } })
chart.setShapes({ tagRadius: 999 }) // pill price tags, axis pills and order badges
chart.getShapes() OHLCV 图例
图表顶部的图例显示指针下的 K 线(否则为最后一根):开、高、低、收、涨跌和成交量。每个数值在数字变化时保持位置,实时跳动时不会抖动。可以整个关闭,也可以只保留需要的行。在组件中它使用外观的字体,与其下方列出的指标行同样大小;setUI 会在你自己的 setLegend 之后再次设置它。
new Chart(host, { features: { legend: false } }) // no legend at all
chart.setLegend({ visible: false }) // or at any time
chart.setLegend({
showSymbol: false, showOHLC: true, showChange: true, showVolume: false,
position: 'top-right',
fontSize: 11,
fontFamily: 'Inter, sans-serif', // null: the theme's font
})
// The widget: start with it off (the user can still turn it on in Settings)
new ChartWidget(host, { chartOptions: { features: { legend: false } } }) 成交量颜色
成交量柱使用主题的 volumeUp 和 volumeDown (或 volume.* 键)。volumeColor(candleColor) 返回带成交量透明度的K线颜色,这样在你自己的主题里,成交量柱依然只是K线背后的衬底。在 widget 的设置里修改K线颜色时,它会自动这样处理;基于预设、只改了 candleUp / candleDown 的主题,成交量也会跟随这些颜色。
import { DARK_THEME, volumeColor } from '@tradecanvas/chart'
chart.setTheme({
...DARK_THEME,
candleUp: '#26a17b',
candleDown: '#e0525f',
volumeUp: volumeColor('#26a17b'),
volumeDown: volumeColor('#e0525f'),
})