Estilos del widget

El aspecto del widget es un conjunto de tokens: las esquinas de cada tipo de pieza, el tamaño de los controles y las barras, la tipografía, los bordes, las sombras, cómo se ve un botón elegido y si la barra de herramientas y las herramientas de dibujo van pegadas a los bordes o flotan. Parte de un preajuste y cambia lo que quieras. Los colores siguen dependiendo del tema (dark / light; consulta la referencia de la API); cualquier aspecto funciona con ambos.

● DemosTu propio aspectoDatos de mercado simulados, generados en tu navegador

Preajustes

PreajusteAspecto
studio (predeterminado)Controles redondeados de 7 px, menús de 11 px y diálogos de 16 px. Los grupos se separan con espacio en lugar de líneas, los menús flotan sobre sombras suaves, los botones de temporalidad van en un carril segmentado y un botón elegido lleva un relleno tintado.
terminalDenso y cuadrado: esquinas de 2 px, controles de 26 px, líneas entre grupos, etiquetas en mayúsculas y una línea bajo el botón elegido. Las etiquetas de precio del gráfico son cuadradas.
capsulePíldoras por todas partes, también en las etiquetas de precio. La barra de herramientas y las herramientas de dibujo flotan como islas, los menús son de vidrio esmerilado y un botón elegido es una píldora sólida.

Elegir un aspecto

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()

Tu propio aspecto

Un tema parte de un preajuste (Studio si no indicas ninguno) y cambia solo lo que nombra. Las esquinas fijadas en la escala llegan a todas las piezas que la siguen, salvo que fijes las de esa pieza en concreto.

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
})
CampoQué ajusta
radiusLa escala de esquinas xs, sm, md, lg, xl, en px (0–999).
componentsLas esquinas propias de una pieza: control (botones), input, menu, dialog, panel (alertas, ventana de datos, ticket de orden), tooltip, tag, toast, toolbar y sidebar (su propia caja, visible cuando flotan). Por defecto, los controles y los campos toman md; los menús y los paneles, lg; los diálogos, xl; y los tooltips y las etiquetas, sm.
density / sizesAlto de toolbar, alto de control y controlSmall, icon, ancho de sidebar y alto de menuItem, en px.
fontFamilias (listas CSS), size del texto base (11–20 px; los tamaños pequeños lo siguen), pesos, y las mayúsculas y el espaciado entre letras (em) de las etiquetas pequeñas, como los títulos de sección.
bordersGrosor del borde, y si unas líneas separan los grupos de la barra de herramientas y las herramientas de dibujo.
shadowsSombras CSS de menús, diálogos y tooltips.
blurMenús esmerilados, en px: por encima de 0, los menús dejan ver algo del gráfico, desenfocado.
activeCómo se ve un botón elegido: un relleno tintado, una píldora sólida o un subrayado.
toolbar / sidebarPegada al borde, o flotando como una isla.
intervalsLos botones de temporalidad tal cual, o en un carril segmentado.
tagRadiusEsquinas de las etiquetas de precio, las píldoras del eje y las insignias de órdenes que dibuja el gráfico.

Los valores que no puede usar (fuera de rango, o CSS que podría salirse de su declaración) se ignoran y se conserva el del preajuste.

Fuentes

El widget no carga ninguna fuente: las nombra, y el navegador recorre cada lista hasta dar con una disponible. Studio nombra Manrope y después Inter; Terminal, IBM Plex Sans Condensed e IBM Plex Mono; Capsule, Sora. Carga las que quieras:

<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Manrope:wght@400;500;600;700&display=swap">

Variables CSS

Los tokens son variables CSS en la raíz del widget (y en sus diálogos). Sin la opción ui siguen siendo las de la hoja de estilos (las de Studio), así que tu propio CSS puede fijarlas: el widget coloca su hoja de estilos al principio de la página, de modo que una regla tuya sobre .tcw-root prevalece. Con ui, el widget las escribe en el elemento y son ellas las que prevalecen.

.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;
}
VariablesOrigen
--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 (y -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

Los interruptores de disposición son atributos data en esos mismos elementos, para tu propio CSS: data-tcw-ui (el preajuste), data-tcw-active, data-tcw-toolbar, data-tcw-sidebar, data-tcw-intervals y data-tcw-separators (on / off).

Campos, listas y el calendario

Todos los campos del widget (alertas, ajustes, el ticket de orden, ir a fecha, los parámetros de un indicador) tienen un mismo aspecto: un relleno tenue y una línea fina, una línea más firme al pasar el ratón y, con el foco, la línea toma el color de acento, sin anillo alrededor. Un select abre la lista propia del widget, con una marca en la fila elegida, los grupos como títulos, las flechas, Enter, Escape y la búsqueda por letra; un campo de fecha abre el calendario del widget, con las semanas desde el día en que las empieza el idioma, hoy subrayado y los días fuera del min y el max del campo en gris. Las casillas, los botones de opción, los deslizadores y los interruptores siguen los mismos tokens, igual que las barras de desplazamiento: finas y redondeadas, solo el pulgar, sin pista.

Los campos siguen siendo el <select> y el <input> del navegador: valores, eventos y formularios funcionan como antes, y en una pantalla táctil se abren la rueda y el calendario del propio teléfono, más cómodos para el dedo.

El aspecto sale de estas variables, con valores para el tema oscuro y el claro:

--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 */
}

El aspecto del gráfico: overrides de estilo

El tema fija los colores del gráfico en conjunto. Cualquier parte de lo que dibuja el gráfico se puede fijar aparte, por clave: las líneas de la cuadrícula en cada dirección, el crosshair, los ejes, los paneles, la leyenda, el último precio, el volumen, los cortes de sesión y la serie principal tal como la dibuja cada tipo de gráfico. Una clave que no toques sigue al tema, así que al cambiar de tema cambia todo lo que no fijaste.

import { Chart } from '@tradecanvas/chart'

const chart = new Chart(host, {
  overrides: { 'grid.vertical.visible': false },       // para empezar
})

chart.applyOverrides({
  'series.candlestick.upColor': '#26a69a',              // todos los tipos alcistas/bajistas vuelven a esta
  '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 quita una clave
chart.resetOverrides(['grid.horizontal.style'])         // o nombra las claves
chart.setOverrides({ 'background.color': '#000' })      // toda una capa de una vez

chart.getStyleValue('series.bar.upColor')               // '#26a69a': lo que resulta de una clave
chart.getStyle().grid.vertical                          // { visible: false, color, style, width }
chart.on('styleChange', (e) => e.payload.layer)         // 'host' | 'user'

Claves

ClavesQué fijan
background.colorEl fondo del gráfico (y el de los paneles, salvo que tengan el suyo).
panes.background, .separatorColor, .titleColorPaneles de indicadores: fondo, la barra de arriba, su nombre.
grid.horizontal.*, grid.vertical.*visible, color, style (solid · dashed · dotted), width, cada dirección aparte.
crosshair.horizontal.*, crosshair.vertical.*Las mismas cuatro para las líneas del crosshair (discontinuas por defecto).
crosshair.labelBackground, .labelTextColorLas etiquetas de precio y hora en los ejes, y en las escalas de los paneles.
axis.price.lineColor, .textColor, axis.time.*La línea y las etiquetas de cada eje (las escalas de los paneles siguen al eje de precios).
legend.textColor, .labelColorLos valores de la leyenda, y sus etiquetas (O, H, L, Vol).
lastPrice.visible, .upColor, .downColor, .style, .widthLa línea y la etiqueta del último precio; sus colores siguen a la serie si no se fijan.
volume.upColor, .downColorLas barras de volumen.
sessionBreaks.color, .style, .widthLos cortes de día, semana y mes.
highLow.color, watermark.colorLas líneas de máximo y mínimo, la marca de agua.
trading.buyColor, .sellColor, .profitColor, .lossColor, .entryColorÓrdenes (compra, venta) y posiciones (beneficio, pérdida, entrada), en el gráfico y en el eje de precios, por encima de los colores de la configuración de trading.
markers.longColor, .shortColor, .neutralColorLas marcas de señal, por encima de su propio estilo.
tradeZones.profitColor, .lossColor, .activeColorLas zonas de operación: ganadas, perdidas y abiertas.
drawings.handleColorLos tiradores del dibujo seleccionado (blancos si no se fija).
series.<type>.*La serie principal mientras se dibuja con ese tipo: upColor, downColor, wickUpColor, wickDownColor (velas, Heikin-Ashi, velas de volumen, equivolumen), color / lineColor y lineWidth (línea, línea escalonada, línea con marcadores, área, área HLC, línea base), topColor y bottomColor (área, área HLC).

CHART_STYLE_KEYS enumera cada clave con el tipo de valor que admite, y TypeScript revisa claves y valores mientras escribes. Los colores alcistas y bajistas vuelven a series.candlestick.*, los colores y grosores de línea a series.line.*, los rellenos a series.area.*, y luego al tema; una mecha toma el color de su cuerpo cuando este está fijado. Las claves y valores desconocidos se descartan con un aviso.

Los de tu app y los del usuario

Los overrides van en dos capas. Los tuyos (layer: 'host', por defecto) se mantienen al cambiar de tema y nunca se guardan. Los del usuario (layer: 'user') ganan a los tuyos, se guardan con el tema en que se hicieron —los colores elegidos en el tema oscuro vuelven con el tema oscuro— y se guardan con saveState(). Los Ajustes del widget escriben en la capa del usuario, y su Restablecer vuelve a los colores del tema, sea cual sea. Su pestaña Estilo ajusta cada parte del gráfico con estas claves, incluidos los colores del tipo de gráfico a la vista, y su pestaña Trading los colores de órdenes, posiciones, marcas de señal y zonas de operación. Un color que se deja a la propia parte aparece como Auto, y Auto lo devuelve allí.

chart.applyOverrides({ 'background.color': '#0b0b0f' }, { layer: 'user' })
chart.getOverrides({ layer: 'user' })                 // los del usuario, para el tema actual
chart.getTheme()                           // el tema tal como se fijó: los overrides van aparte

Las opciones de la cuadrícula y del crosshair (grid.hLineColor, crosshair.vLine.style…) son atajos de sus claves. Una cuadrícula de gráficos aplica overrides a todos sus gráficos: grid.applyOverrides(patch). Los componentes de React, Vue y Svelte los reciben en la prop overrides.

Plots de indicadores y paneles

// El trazo y la visibilidad de cada plot, por su clave (colores y grosores siguen en colors / lineWidths)
chart.updateIndicatorStyle(macdId, { plots: { signal: { lineStyle: 'dashed' }, histogram: { visible: false } } })

// Con qué empieza desde ahora cada indicador de un tipo
chart.setIndicatorDefaults('ema', { colors: ['#f5a623'], lineWidths: [2] })

// El fondo y el separador propios de un panel, guardados con su indicador
chart.setPaneStyle(rsiId, { background: '#101418', separator: '#f5a623' })

Un plot oculto no muestra etiqueta de valor ni valor en la leyenda. Todos los indicadores dejan fuera un plot oculto, y casi todos toman el trazo de sus plots; unos pocos que dibujan formas propias (los puntos del Parabolic SAR, Supertrend, Zig Zag, los perfiles de volumen) mantienen su propio trazo.

Las etiquetas del gráfico

El widget pasa tagRadius a su gráfico (una forma indicada en chartOptions.shapes se mantiene hasta que llames a setUI). Con un Chart sin widget, fija tú la forma; se mantiene al cambiar de tema. La adoptan las etiquetas de precio, las píldoras del eje y de la cruz, las etiquetas de órdenes, posiciones y órdenes bracket, y las de los niveles del periodo anterior.

const chart = new Chart(host, { shapes: { tagRadius: 4 } })
chart.setShapes({ tagRadius: 999 })   // pill price tags, axis pills and order badges
chart.getShapes()

La leyenda OHLCV

La leyenda en la parte superior del gráfico muestra la barra bajo el puntero (si no, la última): apertura, máximo, mínimo, cierre, el cambio y el volumen. Cada valor conserva su sitio mientras cambian sus dígitos, así que no tiembla con los ticks en vivo. Se puede apagar o dejar solo las filas que quiera. En el widget toma la fuente del aspecto, al tamaño de las filas de indicadores que lista debajo; setUI la vuelve a poner, después de un setLegend suyo.

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 } } })

Colores del volumen

Las barras de volumen toman volumeUp y volumeDown (o las claves volume.*) del tema. volumeColor(candleColor) devuelve el color de la vela con la opacidad del volumen, así en un tema propio las barras siguen siendo un fondo bajo las velas. El widget lo hace solo cuando sus ajustes cambian los colores de las velas, y un tema basado en un preajuste que solo cambia candleUp / candleDown también tiene el volumen en esos colores.

import { DARK_THEME, volumeColor } from '@tradecanvas/chart'

chart.setTheme({
  ...DARK_THEME,
  candleUp: '#26a17b',
  candleDown: '#e0525f',
  volumeUp: volumeColor('#26a17b'),
  volumeDown: volumeColor('#e0525f'),
})