Graflume · Alpha

문서

검증된 exact 스냅샷으로 첫 차트를 만드는 방법을 알아보세요. 데이터·ChartSpec·Scene·차트 생명주기 계약을 알아보세요.

빠른 시작

Graflume.create()

검증된 exact 스냅샷으로 첫 차트를 만드는 방법을 알아보세요.

  1. 1

    브라우저 스냅샷

    exact commit · SRI · CDN

  2. 2

    행 데이터

    row[] / TypedArray columns

  3. 3

    ChartSpec 0.1

    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

매뉴얼

Graflume · 매뉴얼

데이터·ChartSpec·Scene·차트 생명주기 계약을 알아보세요.

01row / structured data
02ChartSpec / SpatialSpec 0.1
03validate · normalize · compile
04Canvas 2D / WebGL
  1. 1

    차트 종류와 테마를 고른 뒤 새로 그리기를 눌러 같은 row 데이터가 다른 명세로 렌더링되는지 확인합니다.

  2. 2

    차트의 표시를 선택해 안전한 데이터 이벤트가 어떤 행을 가리키는지 상태 영역에서 확인합니다.

  3. 3

    표와 생성된 ChartSpec을 비교하고 PNG 내보내기를 사용한 뒤 페이지를 떠날 때 인스턴스를 정리합니다.

ChartSpec 0.1

이식 가능한 스키마

함수 없는 ChartSpec 0.1은 차트를 이식 가능하고 직렬화할 수 있게 유지합니다.

urn:graflume:schema:0.1 · function-free JSON
DataTable

행 데이터

행 데이터와 zero-copy TypedArray 열은 하나의 데이터 계약을 공유합니다.

row objects · zero-copy TypedArray columns
standard · large · ultra

성능

standard·large·ultra 프로필은 렌더링 작업량을 제한합니다.

bounded line · point · bar rendering · responsive resize
validate()

보안 기본값

함수·안전하지 않은 키·raw HTML·runtime evaluation을 거부합니다.

functions · unsafe keys · raw HTML · runtime evaluation

ChartSpec · 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

Transform dataflow & lineage

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().dataLineage
  • Scene.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

Encoding & scale registry

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.

  • encoding
  • createPositionScale()
  • 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

Analytic selection & domain navigation

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.selection
  • interaction.domainNavigation
  • getAnalyticSelection()
  • 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

Composition & resolve

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.

  • layer
  • facet
  • repeat
  • hconcat
  • vconcat
  • concat
  • inset
  • resolve

현재 경계: Facet virtualization, renderer mixing and Spatial composition remain separate boundaries; composition stays deterministic and bounded.

semantic-index-accessibility supported

Semantic accessibility mirror

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.table
  • accessibility.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

Mark-label layout & annotation authoring

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.

  • markLabels
  • getMarkLabelState()
  • getMarkLabelPositions()
  • setMarkLabelPositions()
  • undoMarkLabelEdit()
  • redoMarkLabelEdit()
  • marklabelchange
  • getAnnotations()
  • 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

Incremental streaming & worker adapter

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.

  • streaming
  • appendData()
  • 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 · timeZone

값 형식과 로케일

number · compact · currency · percent · date · time · datetime

labels.orientation · font

라벨 방향과 글꼴

auto · horizontal · vertical-up · vertical-down · angle · maxLength

ticks · grid · offset

눈금과 간격

count · values · spacing · padding · dash · opacity

x · y · x2 · y2 · axisId

이 예시는 왼쪽 기본 y축과 독립된 오른쪽 y2 보조축에 서로 다른 단위의 계층을 연결합니다.

axes: {
  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
색·선·기호가 나타내는 계열과 척도를 차트 안에서 바로 설명합니다.
highlights[]
데이터 한 점, 값 집합, 축 구간 또는 차트 영역을 원본 값을 바꾸지 않고 강조합니다.
annotations[] · placement: 'auto' · style.maxWidth
데이터, 축 범위 또는 화면 위치에 사용자가 작성한 안전한 텍스트 설명을 연결합니다. 자동 배치는 둘레 후보를 비교해 차트·범례·다른 말풍선과의 겹침을 가능한 한 피합니다. 명시한 위치는 필요한 안전 보정만 적용해 유지합니다. 말풍선 글자는 상자 안에서 안전하게 자동 줄바꿈됩니다. 끊어지지 않는 긴 토큰은 정해진 줄 수 안에서 시각적으로 축약하지만, 보조 기술에는 원문 전체를 유지합니다.
interaction.playback.transition
재생은 안정 키가 같은 요소를 600ms ease-in-out으로 부드럽게 보간합니다. 새로 나타나거나 사라지는 표식은 페이드하고, 형태가 호환되지 않으면 교차 페이드하며, 동작 줄이기 환경에서는 즉시 최종 상태를 표시합니다.
interaction.selection
표식을 클릭해 선택하고 Escape로 해제하며 선택 상태와 이벤트를 애플리케이션에서 이용합니다.
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

Graflume.create()

차트 종류와 테마를 고른 뒤 새로 그리기를 눌러 같은 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

Transform dataflow & lineage

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().dataLineage
  • Scene.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

Encoding & scale registry

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.

  • encoding
  • createPositionScale()
  • 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

Analytic selection & domain navigation

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.selection
  • interaction.domainNavigation
  • getAnalyticSelection()
  • 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

Composition & resolve

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.

  • layer
  • facet
  • repeat
  • hconcat
  • vconcat
  • concat
  • inset
  • resolve

현재 경계: Facet virtualization, renderer mixing and Spatial composition remain separate boundaries; composition stays deterministic and bounded.

semantic-index-accessibility supported

Semantic accessibility mirror

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.table
  • accessibility.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

Mark-label layout & annotation authoring

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.

  • markLabels
  • getMarkLabelState()
  • getMarkLabelPositions()
  • setMarkLabelPositions()
  • undoMarkLabelEdit()
  • redoMarkLabelEdit()
  • marklabelchange
  • getAnnotations()
  • 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

Incremental streaming & worker adapter

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.

  • streaming
  • appendData()
  • 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.x / axes.y
이 예시는 외부 Cartesian x/y축을 사용하며 아래 옵션이 실제 라이브 차트에 적용됩니다.
axes.x2 / axes.y2
이 예시는 왼쪽 기본 y축과 독립된 오른쪽 y2 보조축에 서로 다른 단위의 계층을 연결합니다.
AxisSpec | false
position · offset · line · ticks · labels · grid · title · format
legacy aliases
tickCount · format: string · labelAngle · grid: boolean · title: string
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

범례와 강조

계열을 구분하고 특정 데이터나 범위를 강조하며, 원하는 위치에 설명 말풍선을 놓고 독자가 표식을 선택하게 할 수 있습니다.

getLegendState() · setLegendItemVisible() · resetLegend()
색·선·기호가 나타내는 계열과 척도를 차트 안에서 바로 설명합니다.
getAnnotations() · setAnnotations() · addAnnotation() · updateAnnotation() · removeAnnotation()
데이터, 축 범위 또는 화면 위치에 사용자가 작성한 안전한 텍스트 설명을 연결합니다.
getAnnotationsVisible() · setAnnotationsVisible() · toggleAnnotations()
자동 배치는 둘레 후보를 비교해 차트·범례·다른 말풍선과의 겹침을 가능한 한 피합니다. 명시한 위치는 필요한 안전 보정만 적용해 유지합니다. 말풍선 글자는 상자 안에서 안전하게 자동 줄바꿈됩니다. 끊어지지 않는 긴 토큰은 정해진 줄 수 안에서 시각적으로 축약하지만, 보조 기술에는 원문 전체를 유지합니다.
interaction.playback.key · transition
재생은 안정 키가 같은 요소를 600ms ease-in-out으로 부드럽게 보간합니다. 새로 나타나거나 사라지는 표식은 페이드하고, 형태가 호환되지 않으면 교차 페이드하며, 동작 줄이기 환경에서는 즉시 최종 상태를 표시합니다.
getSelection() · setSelection() · clearSelection()
표식을 클릭해 선택하고 Escape로 해제하며 선택 상태와 이벤트를 애플리케이션에서 이용합니다.
getAnalyticSelection() · applyAnalyticSelection() · clearAnalyticSelection()
Serializable point, interval, rectangle, axis and lasso selection state.
domainToPixel() · pixelToDomain() · zoomDomainBy() · panDomainBy() · resetDomainView()
Resolved-scale round-trip and continuous Cartesian domain navigation.
getSemanticIndex() · toAccessibleRows() · getAccessibilityState()
Bounded semantic sidecar, native table rows and accessibility mirror state.
legendchange · annotationchange · annotationvisibilitychange · selectionchange · analyticselectionchange · domainviewchange
안전한 이벤트
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();