组件样式

组件的外观由一组 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 / sizestoolbar 高度、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、-xlradius
--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-radiuscomponents
--tcw-toolbar-h、--tcw-control-h、--tcw-control-h-sm、--tcw-icon、--tcw-sidebar-w、--tcw-menu-item-hsizes
--tcw-font、--tcw-font-mono、--tcw-font-size(以及 -sm、-xs、-lg)、--tcw-weight、--tcw-weight-strong、--tcw-label-case、--tcw-label-trackingfont
--tcw-border-w、--tcw-sep-wborders
--tcw-menu-shadow、--tcw-dialog-shadow、--tcw-tooltip-shadowshadows
--tcw-blur、--tcw-surface-opacityblur

布局开关是同一批元素上的 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'),
})