ChartSpec 0.1이식 가능한 스키마
함수 없는 ChartSpec 0.1은 차트를 이식 가능하고 직렬화할 수 있게 유지합니다.
urn:graflume:schema:0.1 · function-free JSONGraflume · Alpha
검증된 exact 스냅샷으로 첫 차트를 만드는 방법을 알아보세요. 데이터·ChartSpec·Scene·차트 생명주기 계약을 알아보세요.
빠른 시작
검증된 exact 스냅샷으로 첫 차트를 만드는 방법을 알아보세요.
exact commit · SRI · CDN
row[] / TypedArray columns
create() · resize() · destroy()
<script defer
src="https://cdn.jsdelivr.net/gh/statground/graflume@4affa24255ec2145ef9983a7f0aea586d5189926/cdn/graflume.global.js"
integrity="sha384-5RM5TBHV62iDnvZKAHQFcMiZsT2ASkHua9qBVG6rwNuPIa3qABTKT3us0S26nITS"
crossorigin="anonymous"></script>
<div id="chart" style="height: 360px"></div>
<script>
const rows = [
{ month: 'Jan', sales: 42 },
{ month: 'Feb', sales: 51 },
{ month: 'Mar', sales: 49 }
];
const chart = Graflume.line('#chart', rows, {
x: { field: 'month', type: 'ordinal' },
y: { field: 'sales', type: 'quantitative' },
theme: 'graflume-light',
mark: { point: true }
});
</script>
npm · 미출시 · UNLICENSED
매뉴얼
데이터·ChartSpec·Scene·차트 생명주기 계약을 알아보세요.
차트 종류와 테마를 고른 뒤 새로 그리기를 눌러 같은 row 데이터가 다른 명세로 렌더링되는지 확인합니다.
차트의 표시를 선택해 안전한 데이터 이벤트가 어떤 행을 가리키는지 상태 영역에서 확인합니다.
표와 생성된 ChartSpec을 비교하고 PNG 내보내기를 사용한 뒤 페이지를 떠날 때 인스턴스를 정리합니다.
ChartSpec 0.1함수 없는 ChartSpec 0.1은 차트를 이식 가능하고 직렬화할 수 있게 유지합니다.
urn:graflume:schema:0.1 · function-free JSONDataTable행 데이터와 zero-copy TypedArray 열은 하나의 데이터 계약을 공유합니다.
row objects · zero-copy TypedArray columnsstandard · large · ultrastandard·large·ultra 프로필은 렌더링 작업량을 제한합니다.
bounded line · point · bar rendering · responsive resizevalidate()함수·안전하지 않은 키·raw HTML·runtime evaluation을 거부합니다.
functions · unsafe keys · raw HTML · runtime evaluationChartSpec · current runtime
Current executable foundations are ordered by the embedded Graflume catalog. Every statement below describes an enforced schema or runtime boundary.
transform-dataflow
supported
Ordered function-free transforms, top-level and layer pipelines, deterministic row lineage, parameters, seeded operations, aggregation counts, named sources, reusable branches and a shared transform DAG are supported.
transform[]compile().dataLineageScene.metadata.dataLineage현재 경계: The portable transform registry is closed and function-free: arbitrary executable transforms, host side effects and opaque callbacks are rejected.
encoding-scale-registry
supported
A closed portable encoding map, conditional mark channels, geographic and trading channels, 17 positional/categorical/probability/temporal scale types, four color scale types, and shared or independent multi-view domains, axes, legends and colorbars are supported.
encodingcreatePositionScale()createColorScale()Scale.map()Scale.invert()Scale.ticks()현재 경계: Channels and scales use a closed registered vocabulary; arbitrary executable accessors and unregistered mark/channel contracts fail validation.
analytic-interaction
supported
A closed immutable v1 store, union/intersection semantics, point/interval/rectangle/axis/lasso state, Canvas pointer/touch and keyboard-authored geometry, continuous and categorical pixel/domain navigation, linked multi-view state, and lineage-preserving selection-driven filtering are supported.
interaction.selectioninteraction.domainNavigationgetAnalyticSelection()applyAnalyticSelection()domainToPixel()pixelToDomain()zoomDomainBy()panDomainBy()현재 경계: Spatial analytic selection remains a separate renderer boundary; selection state and filtering stay inside the closed portable interaction contract.
composition-resolve
supported
Legacy flat layers and the closed layer/facet/repeat/hconcat/vconcat/concat/inset Canvas composition grammar are supported with deterministic bounded layout, scoped semantic and lineage identities, named axes, shared or independent multi-view domains/axes/legends/colorbars, linked view state, per-layer transforms, z-order and clipping.
layerfacetrepeathconcatvconcatconcatinsetresolve현재 경계: Facet virtualization, renderer mixing and Spatial composition remain separate boundaries; composition stays deterministic and bounded.
semantic-index-accessibility
supported
All Canvas families compile a bounded lineage-aware semantic index and expose a virtualized native explorer with full roving traversal, focus-ring, tooltip and selection synchronization. Spatial GPU views expose projected roving traversal and active-descendant synchronization, while a bounded stable-key focus store links Canvas and Spatial views through a portable authored contract.
getSemanticIndex()toAccessibleRows()getAccessibilityState()accessibility.tableaccessibility.navigation현재 경계: Accessibility explorers and focus stores are bounded, authored semantic projections rather than an unbounded DOM mirror of every rendered primitive.
label-layout-authoring
supported
All 41 Canvas families support function-free reusable markLabels with stable-key portable positions, deterministic automatic collision placement, connectors, editing handles, pointer drag, keyboard selection and nudging, grid/mark/plot snapping, bounded undo/redo, runtime import/export events and accessible instructions/live status. Annotation adds a closed data-coordinate point/rule/band/label/callout registry with drag, resize and history.
markLabelsgetMarkLabelState()getMarkLabelPositions()setMarkLabelPositions()undoMarkLabelEdit()redoMarkLabelEdit()marklabelchangegetAnnotations()setAnnotations()addAnnotation()removeAnnotation()annotationchange현재 경계: Authoring uses closed markLabels and data-coordinate annotation primitives; raw HTML, arbitrary event code, freehand drawing and image authoring are excluded.
incremental-worker-binary
supported
Stable-key append/upsert/replaceLast uses bounded ring storage, explicit reject/drop-oldest/coalesce queues, count/event-time retention and replay. Row-local transforms recompute changed keys with exact global fallback; the frame runtime adds RAF coalescing, cancellation, pause/follow-live and lazy bounded history. Automatic module Workers accept row, typed-column and Arrow-compatible binary envelopes, injected JavaScript/WASM adapters and worker-owned renderers with bounded work and cancellation.
streamingappendData()updateData()upsertData()replaceLastData()getStreamingState()exportStreamingReplay()replayData()createIncrementalDataStore()createTransformWorkerAdapter()installTransformWorker()현재 경계: Queues, histories and worker work remain explicitly bounded; JavaScript/WASM adapters must be installed by the host and cannot introduce opaque unbounded execution.
ChartSpec · axes
축 위치, 값 형식, 라벨 방향, 글꼴, 눈금, 격자와 간격을 함수 없는 ChartSpec으로 설정합니다.
format.type · dateStyle · timeStyle · timeZonenumber · compact · currency · percent · date · time · datetime
labels.orientation · fontauto · horizontal · vertical-up · vertical-down · angle · maxLength
ticks · grid · offsetcount · values · spacing · padding · dash · opacity
x · y · x2 · y2 · axisIdaxes: {
x: {
position: 'bottom',
format: { type: 'datetime', dateStyle: 'medium', timeStyle: 'short', timeZone: 'Asia/Seoul' },
labels: {
orientation: 'vertical-up', padding: 10,
font: { family: 'Inter', size: 11, weight: 'semibold' }
},
ticks: { count: 6, spacing: 48 }
},
y: { grid: { visible: true, dash: [4, 4], opacity: 0.7 } }
}
ChartSpec · SpatialSpec · storytelling
계열을 구분하고 특정 데이터나 범위를 강조하며, 원하는 위치에 설명 말풍선을 놓고 독자가 표식을 선택하게 할 수 있습니다.
legend: { mode: 'categories', field: 'series', position: 'bottom' },
highlights: [
{ id: 'focus', target: { type: 'datum', field: 'city', value: 'Seoul' } },
{ id: 'quarter', target: { type: 'range', x: { from: 'Apr', to: 'Jun' } } }
],
annotations: [{
id: 'note',
target: { type: 'datum', rowIndex: 3 },
text: 'Campaign started', detail: 'User-authored plain text',
placement: 'auto', style: { maxWidth: 220 }
}],
interaction: {
controls: { annotations: true },
playback: {
field: 'period', key: 'period', mode: 'cumulative',
transition: { duration: 600, easing: 'ease-in-out' }
},
selection: {
mode: 'multiple', toggle: true,
clearOnBackground: true, clearOnEscape: true
}
}
Canvas 대상 유형: datum · layer · range · normalized plot. Spatial 대상 유형: picked datum · layer · world point · world box. 공간 범주형·연속형 범례는 표시 전용이며, 레이어 범례에서는 레이어 표시를 전환할 수 있습니다.
자동 배치는 둘레 후보를 비교해 차트·범례·다른 말풍선과의 겹침을 가능한 한 피합니다. 명시한 위치는 필요한 안전 보정만 적용해 유지합니다. 말풍선 글자는 상자 안에서 안전하게 자동 줄바꿈됩니다. 끊어지지 않는 긴 토큰은 정해진 줄 수 안에서 시각적으로 축약하지만, 보조 기술에는 원문 전체를 유지합니다. 재생은 안정 키가 같은 요소를 600ms ease-in-out으로 부드럽게 보간합니다. 새로 나타나거나 사라지는 표식은 페이드하고, 형태가 호환되지 않으면 교차 페이드하며, 동작 줄이기 환경에서는 즉시 최종 상태를 표시합니다.
카메라를 따라가는 Spatial 설명 말풍선은 DOM 오버레이이며 현재 PNG 프레임버퍼 내보내기에 포함되지 않습니다.
브라우저 API
차트 종류와 테마를 고른 뒤 새로 그리기를 눌러 같은 row 데이터가 다른 명세로 렌더링되는지 확인합니다.
const chart = Graflume.create('#chart', {
specVersion: '0.1', data,
mark: { type: 'line', point: true },
x: { field: 'period', type: 'ordinal' },
y: { field: 'actual', type: 'quantitative' },
interaction: { hover: true, click: true }
});
chart.on('click', ({ hit }) => console.log(hit?.datum));
chart.setData(nextRows);
chart.appendData(nextBatch); // bounded streaming applies when spec.streaming is configured
chart.resize();
chart.toDataURL('image/png');
chart.destroy();Graflume.compile(spec)DOM-free validation · normalize · Scene
bar() · line() · combo()차트 계열 · Quick API
setSpec(spec)차트 종류와 테마를 고른 뒤 새로 그리기를 눌러 같은 row 데이터가 다른 명세로 렌더링되는지 확인합니다.
setData(rows)행 데이터
appendData(rows) · upsertData(rows) · replaceLastData(rows)legacy append · explicit streaming retention / replay
resize()반응형
on('click')차트의 표시를 선택해 안전한 데이터 이벤트가 어떤 행을 가리키는지 상태 영역에서 확인합니다.
toDataURL()표와 생성된 ChartSpec을 비교하고 PNG 내보내기를 사용한 뒤 페이지를 떠날 때 인스턴스를 정리합니다.
destroy()통합 체크리스트
브라우저 API
Portable specification fields and browser methods are shown together so that declarative and runtime contracts remain distinguishable.
transform-dataflow
supported
Ordered function-free transforms, top-level and layer pipelines, deterministic row lineage, parameters, seeded operations, aggregation counts, named sources, reusable branches and a shared transform DAG are supported.
transform[]compile().dataLineageScene.metadata.dataLineage현재 경계: The portable transform registry is closed and function-free: arbitrary executable transforms, host side effects and opaque callbacks are rejected.
encoding-scale-registry
supported
A closed portable encoding map, conditional mark channels, geographic and trading channels, 17 positional/categorical/probability/temporal scale types, four color scale types, and shared or independent multi-view domains, axes, legends and colorbars are supported.
encodingcreatePositionScale()createColorScale()Scale.map()Scale.invert()Scale.ticks()현재 경계: Channels and scales use a closed registered vocabulary; arbitrary executable accessors and unregistered mark/channel contracts fail validation.
analytic-interaction
supported
A closed immutable v1 store, union/intersection semantics, point/interval/rectangle/axis/lasso state, Canvas pointer/touch and keyboard-authored geometry, continuous and categorical pixel/domain navigation, linked multi-view state, and lineage-preserving selection-driven filtering are supported.
interaction.selectioninteraction.domainNavigationgetAnalyticSelection()applyAnalyticSelection()domainToPixel()pixelToDomain()zoomDomainBy()panDomainBy()현재 경계: Spatial analytic selection remains a separate renderer boundary; selection state and filtering stay inside the closed portable interaction contract.
composition-resolve
supported
Legacy flat layers and the closed layer/facet/repeat/hconcat/vconcat/concat/inset Canvas composition grammar are supported with deterministic bounded layout, scoped semantic and lineage identities, named axes, shared or independent multi-view domains/axes/legends/colorbars, linked view state, per-layer transforms, z-order and clipping.
layerfacetrepeathconcatvconcatconcatinsetresolve현재 경계: Facet virtualization, renderer mixing and Spatial composition remain separate boundaries; composition stays deterministic and bounded.
semantic-index-accessibility
supported
All Canvas families compile a bounded lineage-aware semantic index and expose a virtualized native explorer with full roving traversal, focus-ring, tooltip and selection synchronization. Spatial GPU views expose projected roving traversal and active-descendant synchronization, while a bounded stable-key focus store links Canvas and Spatial views through a portable authored contract.
getSemanticIndex()toAccessibleRows()getAccessibilityState()accessibility.tableaccessibility.navigation현재 경계: Accessibility explorers and focus stores are bounded, authored semantic projections rather than an unbounded DOM mirror of every rendered primitive.
label-layout-authoring
supported
All 41 Canvas families support function-free reusable markLabels with stable-key portable positions, deterministic automatic collision placement, connectors, editing handles, pointer drag, keyboard selection and nudging, grid/mark/plot snapping, bounded undo/redo, runtime import/export events and accessible instructions/live status. Annotation adds a closed data-coordinate point/rule/band/label/callout registry with drag, resize and history.
markLabelsgetMarkLabelState()getMarkLabelPositions()setMarkLabelPositions()undoMarkLabelEdit()redoMarkLabelEdit()marklabelchangegetAnnotations()setAnnotations()addAnnotation()removeAnnotation()annotationchange현재 경계: Authoring uses closed markLabels and data-coordinate annotation primitives; raw HTML, arbitrary event code, freehand drawing and image authoring are excluded.
incremental-worker-binary
supported
Stable-key append/upsert/replaceLast uses bounded ring storage, explicit reject/drop-oldest/coalesce queues, count/event-time retention and replay. Row-local transforms recompute changed keys with exact global fallback; the frame runtime adds RAF coalescing, cancellation, pause/follow-live and lazy bounded history. Automatic module Workers accept row, typed-column and Arrow-compatible binary envelopes, injected JavaScript/WASM adapters and worker-owned renderers with bounded work and cancellation.
streamingappendData()updateData()upsertData()replaceLastData()getStreamingState()exportStreamingReplay()replayData()createIncrementalDataStore()createTransformWorkerAdapter()installTransformWorker()현재 경계: Queues, histories and worker work remain explicitly bounded; JavaScript/WASM adapters must be installed by the host and cannot introduce opaque unbounded execution.
ChartSpec · AxisSpec
축 위치, 값 형식, 라벨 방향, 글꼴, 눈금, 격자와 간격을 함수 없는 ChartSpec으로 설정합니다.
axes: {
y: {
position: 'left',
format: { type: 'currency', currency: 'KRW', notation: 'compact' }
},
y2: {
position: 'right', offset: 8, grid: false,
format: { type: 'percent', fractionDigits: 1 }
}
},
layers: [
{ mark: { type: 'bar' }, x: { field: 'period', axisId: 'x' }, y: { field: 'revenue', axisId: 'y' } },
{ mark: { type: 'line', point: true }, x: { field: 'period', axisId: 'x' }, y: { field: 'marginRate', axisId: 'y2' } }
]
Runtime · legend · annotation · selection
계열을 구분하고 특정 데이터나 범위를 강조하며, 원하는 위치에 설명 말풍선을 놓고 독자가 표식을 선택하게 할 수 있습니다.
chart.on('selectionchange', ({ state }) => {
console.log(state.items);
});
const noteId = chart.addAnnotation({
target: { type: 'datum', rowIndex: 3 },
text: 'Reviewed by the analyst',
placement: 'auto'
});
chart.updateAnnotation(noteId, { placement: 'auto' });
chart.toggleAnnotations();
const legendItem = chart.getLegendState().items.find(item => item.toggleable);
if (legendItem) chart.setLegendItemVisible(legendItem.id, false);
chart.clearSelection();