Я доволен экосистемой Vue. Как и положено, ты не городишь велосипеды, а пользуешься готовыми плагинами, которые за тебя написали умные дядьки. Когда твоя задача слишком мелкая и локальная, чтобы под неё написали плагин — ты идёшь и ищешь готовые компоненты, и только если не находишь ничего подходящего, чешешь репу и садишься писать своё решение. Таков порядок вещей, и я изрядно удивился, когда за вечер тестов не смог нормально отобразить ни одного подходящего мне графика. Пришлось немного подумать и переписать все примеры с Chart.js, чтобы разобраться с графиками раз и навсегда. Результаты ниже.
Chart.js
Chart.js давно стал одной из самых популярных чарт-библиотек из-за большого разнообразия графиков и глубокой кастомизации. Самый популярный и простой способ — воспользоваться популярной реализацией vue-chartjs:
# npm
npm install vue-chartjs chart.js --save
# или yarn
yarn add vue-chartjs chart.js
При подключении важно вынести график в отдельный компонент — несмотря на то, что vue-chartjs предлагает все типы графиков отдельными именованными компонентами, при подключении их напрямую, ломаются vuex и вычисляемые свойства.
Создадим отображение bar chart в дочернем компоненте:
// BarChart.vue
<script>
import { Bar } from 'vue-chartjs'
export default {
name: 'BarChart',
extends: Bar
}
</script>
В BarChart.vue нет тега template
, потому что он подтягивается из компонента Bar. Если попытаетесь указать его — правильный template
просто не появится, потому что его заменит написанный вами.
Подключаем Barchart в родительский компонент, здесь это App.vue:
// App.vue
<template>
<BarChart/>
</template>
<script>
import BarChart from 'components/BarChart.vue'
export default {
components: {
BarChart
}
}
</script>
Данные и конфигурацию графика будем передавать из родительского компонента через props. За отрисовку отвечает функция renderChart
, мы будем вызывать её при монтировании дочернего компонента:
// BarChart.vue
<script>
import Bar from 'vue-chartjs'
export default {
extends: Bar,
props: {
chartData: {
type: Object,
default: null
},
options: {
type: Object,
default: null
}
},
mounted () {
this.renderChart(this.chartData, this.options)
}
}
</script>
Передаём props внутрь:
// App.vue
<template>
<BarChart :chartdata="chartData" :options="chartOptions"/>
</template>
<script>
import BarChart from 'components/BarChart.vue'
export default {
components: {
BarChart
},
data () {
return {
chartData: {},
options: {}
}
}
}
</script>
Наконец, определим данные и конфиг:
// App.vue
/* ... */
chartData: {
labels: [
'January',
'February',
'March',
'April',
'May',
'June',
'July',
'August',
'September',
'October',
'November',
'December'
],
datasets: [
{
label: 'Data One',
data: [40, 20, 12, 39, 10, 40, 39, 80, 40, 20, 12, 11]
}
]
},
options: {
responsive: true,
maintainAspectRatio: false
}
/* ... */
У Chart.js вагон настроек как глобальных (в options
), так и локальных для отдельных датасетов (соответственно, в datasets
). Они раскиданы по разным частям документации, но в целом всё полезное лежит здесь.
Результат
Я умышленно опустил оформление, потому что это всё большая вкусовщина и в минимальный туториал по функционалу не вписывается. Но если что, вот мвой красивый конфиг для line chart с КДПВ:
// App.vue
/* ... */
data: {
labels: [...],
datasets: [
{
label: '...',
borderColor: '#77b7cd', // цвет линии
pointBackgroundColor: '#77b7cd',
// по умолчанию точки прозрачные, что не всегда красиво
pointRadius: 4,
data: [...]
}
]
},
options: {
responsive: true,
/* график действительно адаптируется под мобильные экраны, но для более точной
настройки приходится уточнить количество и точность подписей на осях */
maintainAspectRatio: false,
legend: {
display: false // отключает легенду, бесполезную когда на графике одна линия
},
scales: {
yAxes: [{
display: true,
ticks: {
precision: 2, // точность округления значений по оси y
maxTicksLimit: 4 // максимальное количество значений (и рёбер сетки) по оси y
}
}],
xAxes: [{
display: true,
ticks: {
maxTicksLimit: 5 // максимальное количество значений (и рёбер сетки) по оси x
}
}]
}
}
/* ... */
Градиент при желании можно добавить так:
// LineChart.vue
/* ... */
data () {
return {
gradient: null
}
},
mounted () {
this.gradient = this.$refs.canvas.getContext('2d').createLinearGradient(0, 0, 0, 450)
this.gradient.addColorStop(0, 'rgba(255, 0,0, 0.5)')
this.gradient.addColorStop(0.5, 'rgba(255, 0, 0, 0.25)');
this.gradient.addColorStop(1, 'rgba(255, 0, 0, 0)');
this.renderChart({
labels: this.labels,
datasets: [
{
label: '...',
borderColor: '#FC2525',
pointBackgroundColor: 'white',
borderWidth: 1,
pointBorderColor: 'white',
backgroundColor: this.gradient,
data: '...'
}
]
}, {responsive: true, maintainAspectRatio: false})
}
/* ... */
Заключение
Надеюсь, эти примеры помогут тому, кто столкнётся с многообразием библиотек и плагинов для построения графиков. Chart.js — очень мощная и довольно удобная штука, весь геморрой обычно заключается в приведении входных данных в правильный формат датасета. Если знать нюансы подключения и оформления, можно пользоваться ей очень быстро.
Ссылки:
→ Набор демок от разработчика
→ Гайд по vue-chartjs
→ Репо vue-chartjs
→ Доки Chart.js
На правах рекламы
Подыскиваете
Автор: Mikhail