Skip to content

Рецепты ​

Данные ​

Объект-карта (рекомендуется) ​

Пн
Вт
Ср
Чт
Пт
Сб
Вс
vue
<script setup lang="ts">
const data = {
  '2025-01-14': 3,
  '2025-01-15': 7,
  '2025-03-22': 1,
}
</script>
<template>
  <CalendarHeatmap :data="data" />
</template>

Массив { date, value } ​

vue
<script setup lang="ts">
import type { HeatmapDataArray } from 'vue-calendar-activity'

const data: HeatmapDataArray = [
  { date: '2025-01-14', value: 3 },
  { date: '2025-01-15', value: 7 },
]
</script>
<template>
  <CalendarHeatmap :data="data" />
</template>

Диапазон дат ​

Пресеты диапазона ​

Пн
Вт
Ср
Чт
Пт
Сб
Вс
vue
<CalendarHeatmap :data="data" range="year" />
<CalendarHeatmap :data="data" range="6months" />
<CalendarHeatmap :data="data" range="3months" />
<CalendarHeatmap :data="data" range="month" />

Произвольный диапазон ​

Пн
Вт
Ср
Чт
Пт
Сб
Вс
vue
<CalendarHeatmap
  :data="data"
  start-date="2025-01-01"
  end-date="2025-06-30"
/>

Цвета ​

Встроенные пресеты ​

Пн
Вт
Ср
Чт
Пт
Сб
Вс
Пн
Вт
Ср
Чт
Пт
Сб
Вс
Пн
Вт
Ср
Чт
Пт
Сб
Вс
Пн
Вт
Ср
Чт
Пт
Сб
Вс
Пн
Вт
Ср
Чт
Пт
Сб
Вс
Пн
Вт
Ср
Чт
Пт
Сб
Вс
vue
<!-- github (по умолчанию), blue, orange, red, purple, teal -->
<CalendarHeatmap :data="data" color-preset="blue" />
<CalendarHeatmap :data="data" color-preset="purple" />
<CalendarHeatmap :data="data" color-preset="teal" />

Авто-палитра из одного цвета ​

Пн
Вт
Ср
Чт
Пт
Сб
Вс
vue
<CalendarHeatmap :data="data" color-to="#0ea5e9" />

Градиентная шкала ​

Пн
Вт
Ср
Чт
Пт
Сб
Вс
vue
<CalendarHeatmap
  :data="data"
  scale-mode="gradient"
  color-from="#fef9c3"
  color-to="#854d0e"
/>

Явные цвета для каждого уровня ​

Пн
Вт
Ср
Чт
Пт
Сб
Вс
vue
<!-- индекс 0 = пустой день -->
<CalendarHeatmap
  :data="data"
  :colors="['#f1f5f9', '#bae6fd', '#38bdf8', '#0284c7', '#0c4a6e']"
/>

Свой цвет пустого дня ​

Пн
Вт
Ср
Чт
Пт
Сб
Вс
vue
<CalendarHeatmap :data="data" color-preset="blue" empty-color="#f8fafc" />

Больше или меньше уровней ​

Пн
Вт
Ср
Чт
Пт
Сб
Вс
Пн
Вт
Ср
Чт
Пт
Сб
Вс
vue
<CalendarHeatmap :data="data" :levels="3" />
<CalendarHeatmap :data="data" :levels="8" />

Внешний вид ​

Вертикальная ориентация ​

Пн
Вт
Ср
Чт
Пт
Сб
Вс
vue
<CalendarHeatmap :data="data" orientation="vertical" range="3months" />

Размер и отступ ячеек ​

Пн
Вт
Ср
Чт
Пт
Сб
Вс
vue
<CalendarHeatmap :data="data" :cell-size="16" :cell-gap="4" />

Круглые ячейки (в стиле Duolingo) ​

Пн
Вт
Ср
Чт
Пт
Сб
Вс
vue
<CalendarHeatmap :data="data" :cell-size="14" :cell-gap="4" :cell-radius="50" />

Тёмная тема ​

Пн
Вт
Ср
Чт
Пт
Сб
Вс
vue
<CalendarHeatmap :data="data" theme="dark" />

Без подписей и легенды ​

vue
<CalendarHeatmap
  :data="data"
  :show-months="false"
  :show-weekdays="false"
  :show-legend="false"
  :tooltip-enabled="false"
/>

Неделя начинается с воскресенья ​

Вс
Пн
Вт
Ср
Чт
Пт
Сб
vue
<CalendarHeatmap :data="data" :week-start="0" />

Локализация ​

Встроенный русский язык ​

Пн
Вт
Ср
Чт
Пт
Сб
Вс
vue
<CalendarHeatmap :data="data" locale="ru" />

Произвольная локаль (французский) ​

Lun
Mar
Mer
Jeu
Ven
Sam
Dim
vue
<script setup lang="ts">
import type { HeatmapLocale } from 'vue-calendar-activity'

const locale: HeatmapLocale = {
  monthsShort: ['Jan','Fév','Mar','Avr','Mai','Jun',
                'Jul','Aoû','Sep','Oct','Nov','Déc'],
  weekdaysShort: ['Dim','Lun','Mar','Mer','Jeu','Ven','Sam'],
  noDataLabel: 'Aucune activité',
  on: 'le',
}
</script>
<template>
  <CalendarHeatmap :data="data" :locale="locale" :week-start="1" />
</template>

Свой формат даты в тултипе ​

Пн
Вт
Ср
Чт
Пт
Сб
Вс
vue
<!-- токены: YYYY, MM, DD -->
<CalendarHeatmap :data="data" date-format="DD.MM.YYYY" />

Взаимодействие ​

Клик по дню ​

Пн
Вт
Ср
Чт
Пт
Сб
Вс
vue
<script setup lang="ts">
import { ref } from 'vue'
import type { HeatmapDay } from 'vue-calendar-activity'

const selected = ref<HeatmapDay | null>(null)
</script>
<template>
  <CalendarHeatmap :data="data" @cell-click="(day) => selected = day" />
  <p v-if="selected">{{ selected.date }} — {{ selected.value }}</p>
</template>

Реактивные данные ​

Пн
Вт
Ср
Чт
Пт
Сб
Вс
vue
<script setup lang="ts">
import { ref } from 'vue'

const data = ref<Record<string, number>>({})

function addToday() {
  const today = new Date().toISOString().slice(0, 10)
  data.value = { ...data.value, [today]: (data.value[today] ?? 0) + 1 }
}
</script>
<template>
  <CalendarHeatmap :data="data" />
  <button @click="addToday">+1 сегодня</button>
</template>

Тултип ​

Свой текст (проп) ​

Пн
Вт
Ср
Чт
Пт
Сб
Вс
vue
<script setup lang="ts">
import type { HeatmapDay } from 'vue-calendar-activity'

function formatter(day: HeatmapDay): string {
  if (day.value === 0) return `Нет активности — ${day.date}`
  return `${day.value} действий — ${day.date}`
}
</script>
<template>
  <CalendarHeatmap :data="data" :tooltip-formatter="formatter" />
</template>

Кастомный слот (полный HTML) ​

Пн
Вт
Ср
Чт
Пт
Сб
Вс
vue
<CalendarHeatmap :data="data">
  <template #tooltip="{ day }">
    <div style="text-align:center">
      <strong>{{ day.date }}</strong><br />
      <span>{{ day.value }} активностей</span>
    </div>
  </template>
</CalendarHeatmap>

Подсветка сегодня ​

По умолчанию (ring) ​

Пн
Вт
Ср
Чт
Пт
Сб
Вс
vue
<CalendarHeatmap :data="data" today />

Оба стиля ​

Пн
Вт
Ср
Чт
Пт
Сб
Вс
Пн
Вт
Ср
Чт
Пт
Сб
Вс
vue
<!-- ring — рамка внутри ячейки -->
<CalendarHeatmap :data="data" :today="{ style: 'ring', color: '#0969da', size: 2 }" />

<!-- fill — перекрывает цвет активности -->
<CalendarHeatmap :data="data" :today="{ style: 'fill', color: '#0969da' }" />

Свой цвет ​

Пн
Вт
Ср
Чт
Пт
Сб
Вс
vue
<CalendarHeatmap :data="data" :today="{ style: 'ring', color: '#f97316', size: 2 }" />

Легенда ​

С подписью ​

Пн
Вт
Ср
Чт
Пт
Сб
Вс
vue
<CalendarHeatmap :data="data" :show-legend="true" legend-label="Коммиты" />

Шкала ​

Общий максимум для нескольких графиков ​

Пн
Вт
Ср
Чт
Пт
Сб
Вс
Пн
Вт
Ср
Чт
Пт
Сб
Вс
vue
<!-- оба графика используют одну шкалу -->
<CalendarHeatmap :data="teamA" :max-value="100" legend-label="Команда А" />
<CalendarHeatmap :data="teamB" :max-value="100" legend-label="Команда Б" />