Skip to content

Scatter

Точечная серия; обе оси числовые по умолчанию (без axes создаются number + number).

ts
import { getData } from './data';
import type { ChartOptions } from 'grafit-charts';

export function createOptions(): ChartOptions {
  return {
    data: getData(),
    title: { text: 'Height and weight' },
    series: [{ type: 'scatter', xField: 'height', xName: 'Height', yField: 'weight', yName: 'Weight', name: 'People' }],
    axes: [
      { type: 'number', position: 'bottom', title: { text: 'Height, cm' }, nice: false },
      { type: 'number', position: 'left', title: { text: 'Weight, kg' } },
    ],
    legend: { enabled: false },
  };
}
ts
export function getData() {
  return [
    { height: 162, weight: 54 },
    { height: 168, weight: 61 },
    { height: 171, weight: 65 },
    { height: 175, weight: 71 },
    { height: 178, weight: 74 },
    { height: 180, weight: 82 },
    { height: 183, weight: 79 },
    { height: 186, weight: 88 },
    { height: 190, weight: 93 },
    { height: 167, weight: 58 },
    { height: 173, weight: 68 },
    { height: 181, weight: 77 },
  ];
}

Подписи точек

Подпись точки — это её имя и значение, нарисованные одним блоком: та же подпись, что у сектора круговой или стадии воронки. Имя точке даёт labelField; без него подпись — голое значение, как и раньше. layout ставит значение через разделитель ('inline' — по умолчанию) или на свою строку, и у каждой половины свой шрифт:

js
labelField: 'country',
label: { enabled: true, category: { fontWeight: 'bold' }, value: { type: 'percent' } },

Имя точки — значение поля, поэтому то, как оно превращается в текст, — свойство серии: labelName (format или formatter) проговаривает его и для заголовка тултипа, и для подписи, а label.category перекрывает там, где подписи нужно что-то короче.

value.type: 'percent' читает число как долю от суммы: для scatter — от значений y, для bubble — от sizeField, то есть от того, частью чего пузырь и является. label.formatter({ value, datum }) по-прежнему говорит за всю подпись, когда нужен один текст, и имеет приоритет над category/value:

ts
import { getData } from './data';
import type { ChartOptions } from 'grafit-charts';

export function createOptions(): ChartOptions {
  return {
    data: getData(),
    title: { text: 'Scatter with labels on the right' },
    series: [
      {
        type: 'scatter',
        xField: 'x',
        yField: 'y',
        name: 'Points',
        label: {
          enabled: true,
          placement: 'right',
          formatter: ({ value, datum }) => `(${datum.x}; ${value})`,
        },
      },
    ],
    legend: { enabled: false },
  };
}
ts
export function getData() {
  return [
    { x: 12, y: 30 },
    { x: 25, y: 48 },
    { x: 38, y: 22 },
    { x: 47, y: 61 },
    { x: 58, y: 41 },
    { x: 70, y: 72 },
    { x: 81, y: 55 },
  ];
}

Когда точек много

label.minShare оставляет без подписи точки ниже этой доли от суммы, а label.avoidOverlap скрывает те подписи, которым не хватило места. Пузырьковая серия раздаёт место по размеру — крупные пузыри сохраняют подписи, мелочь теряет; у scatter ранжировать нечем, поэтому там выигрывает более ранняя точка:

ts
import { getData } from './data';
import type { ChartOptions } from 'grafit-charts';

export function createOptions(): ChartOptions {
  return {
    data: getData(),
    title: { text: 'GDP vs Happiness Index' },
    subtitle: { text: 'labels go to the bubbles worth naming, biggest first' },
    series: [
      {
        type: 'bubble',
        xField: 'gdp',
        xName: 'GDP per capita',
        yField: 'happiness',
        yName: 'Happiness',
        labelField: 'country',
        name: 'Countries',
        sizeField: 'population',
        sizeName: 'Population, M',
        maxSize: 36,
        label: {
          enabled: true,
          minShare: 0.04,
          avoidOverlap: true,
          category: { fontWeight: 'bold' },
          value: { type: 'percent', color: '#8a8f98' },
        },
      },
    ],
    axes: [
      { type: 'number', position: 'bottom', title: { text: 'GDP per capita, $K' } },
      { type: 'number', position: 'left', title: { text: 'Happiness Index' } },
    ],
    legend: { enabled: false },
  };
}
ts
export function getData() {
  return [
    { country: 'Russia', gdp: 4.2, happiness: 5.9, population: 144 },
    { country: 'China', gdp: 12.6, happiness: 6.1, population: 1412 },
    { country: 'India', gdp: 2.4, happiness: 5.0, population: 1408 },
    { country: 'USA', gdp: 76.3, happiness: 6.9, population: 332 },
    { country: 'Germany', gdp: 48.7, happiness: 7.0, population: 84 },
    { country: 'Japan', gdp: 34.0, happiness: 6.5, population: 125 },
    { country: 'South Korea', gdp: 51.0, happiness: 6.4, population: 52 },
    { country: 'Brazil', gdp: 9.7, happiness: 6.3, population: 215 },
  ];
}

Формы маркеров

shape: circle, square, diamond, triangle, cross, plus:

ts
import { getData } from './data';
import type { ChartOptions } from 'grafit-charts';

export function createOptions(): ChartOptions {
  return {
    data: getData(),
    title: { text: 'Marker shapes' },
    series: [
      { type: 'scatter', xField: 'x', yField: 'alpha', name: 'Group A', shape: 'circle' },
      { type: 'scatter', xField: 'x', yField: 'beta', name: 'Group B', shape: 'diamond' },
      { type: 'scatter', xField: 'x', yField: 'gamma', name: 'Group C', shape: 'triangle' },
    ],
  };
}
ts
export function getData() {
  const data: Array<Record<string, number>> = [];
  const groups = [
    { key: 'alpha', cx: 30, cy: 40 },
    { key: 'beta', cx: 60, cy: 70 },
    { key: 'gamma', cx: 75, cy: 30 },
  ];
  groups.forEach((g, gi) => {
    for (let i = 0; i < 14; i++) {
      data.push({
        x: g.cx + (((i * 13 + gi * 7) % 21) - 10),
        [g.key]: g.cy + (((i * 17 + gi * 11) % 19) - 9),
      });
    }
  });
  return data;
}

Опции

Общие опции всех серий (name, showInLegend, tooltip.renderer, …) — в разделе Общие опции серий.

ОпцияТипПо умолчаниюОписание
xFieldstringчисловые ключи данных
yFieldstringчисловые ключи данных
labelFieldstringключ имени точки (подпись и заголовок тултипа)
labelName.formatstringкак поле имени точки становится текстом: заголовок тултипа и подпись
labelName.formatter({ datum, value }) => stringто же, когда строкой формата не выразить
xNamestringxFieldимя значения x в тултипе
yNamestringyFieldимя значения y в тултипе
shapeMarkerShape'circle'форма маркера
sizePixels8размер маркера
fillColorValueпалитразаливка
fillOpacityFraction0.85заливка
strokeColorValueфонобводка
strokeWidthPixels1обводка
itemStyler(params) => styleпер-точечные стили (fill/stroke/size) по datum
label.enabledbooleanfalseпоказать подписи значений
label.placement'top' | 'bottom' | 'left' | 'right' | 'inside''top'позиция подписи
label.formatter({ value, datum }) => stringвся подпись сразу; приоритет над category/value
label.layout'inline' | 'stacked''inline'значение через разделитель или на своей строке
label.separatorstring' · 'разделитель половин inline-подписи
label.category.enabledbooleantrue при заданном labelFieldимя точки как часть подписи
label.category.formatstringстрока формата для поля имени
label.category.formatter({ datum, label, value, share }) => …текст половины с именем
label.category.*FontOptionsшрифт подписишрифт имени
label.value.enabledbooleantrueзначение как часть подписи
label.value.type'value' | 'percent''value'само значение или его доля от суммы
label.value.formatstringстрока формата (',.0f', '.1%')
label.value.formatter({ datum, label, value, share }) => …текст половины со значением
label.value.*FontOptionsшрифт подписишрифт значения
label.minShareFraction0доля от суммы, начиная с которой точка достойна подписи
label.avoidOverlapbooleanfalseскрывать подписи, которым не хватило места
label.fontSizePixels11размер шрифта подписи
label.fontWeightstring | numbernormalнасыщенность
label.fontFamilystringшрифт темыгарнитура
label.colorColorValueforeground; внутри — автоконтрастцвет текста

itemStyler получает { datum, index, highlighted, fill, stroke, size } и возвращает частичные стили — так раскрашивают точки по условию без отдельных серий.

Тултип

У точечной серии обе оси — измерения, поэтому значения выводятся подписанными строками: xName: x, yName: y. В заголовке — имя точки, если его даёт labelField, иначе серия (маркер + name). Bubble добавляет строку sizeName: size с долей от суммы размеров — Население, млн: 1412 (37%), как читает свою долю сектор круговой.