Skip to content

Commit

Permalink
Move samples in docs and make them editable
Browse files Browse the repository at this point in the history
Samples are now integrated in the docs, which provides a better user
experience and allows to link samples and guides together. Implement
a Vuepress plugin that displays markdown `js chart-editor` code block
in a Chart editor, in which the user can preview the chart, trigger
actions and edit the source code which is exposed in named "blocks".
  • Loading branch information
simonbrunel committed Dec 5, 2020
1 parent 8572a7b commit 202cc79
Show file tree
Hide file tree
Showing 62 changed files with 3,203 additions and 3,330 deletions.
1 change: 0 additions & 1 deletion .codeclimate.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ plugins:
exclude_patterns:
- "coverage/"
- "docs/"
- "samples/"
- "scripts/"
- "test/"
- "*.js"
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ The following commands will then be available from the repository root:
> gulp test --watch // run all tests and watch for changes
> gulp test --coverage // run all tests and generate code coverage
> gulp lint // perform code linting
> gulp package // create an archive with dist files and samples
> gulp package // create an archive with dist files
> gulp docs // generate documentation (`dist/docs`)
> gulp docs --watch // generate documentation and watch for changes

Expand Down
87 changes: 76 additions & 11 deletions docs/.vuepress/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,28 @@ module.exports = {
plugins: [
['@vuepress/google-analytics', {
ga: 'UA-99068522-2'
}]
}],
['redirect', {
redirectors: [
// Default sample page when accessing /samples.
{ base: '/samples', alternative: ['charts/line'] },
],
}],
[require('./plugins/chart-editor'), {
defaults: {
global: {
legend: {
display: false
},
title: {
display: false
},
tooltips: {
enabled: false
}
}
}
}],
],
themeConfig: {
repo: 'chartjs/chartjs-plugin-datalabels',
Expand All @@ -22,16 +43,60 @@ module.exports = {
nav: [
{ text: 'Home', link: '/' },
{ text: 'Guide', link: '/guide/' },
{ text: 'Samples', link: 'https://chartjs-plugin-datalabels.netlify.com/samples/' }
{ text: 'Samples', link: '/samples/' },
],
sidebar: [
'/guide/',
'/guide/getting-started',
'/guide/options',
'/guide/labels',
'/guide/positioning',
'/guide/formatting',
'/guide/events'
]
sidebar: {
'/guide/': [
'',
'getting-started',
'options',
'labels',
'positioning',
'formatting',
'events',
],
'/samples/': [
{
title: 'Charts',
collapsable: false,
children: [
'charts/line',
'charts/bar',
'charts/doughnut',
'charts/polar',
'charts/radar',
'charts/bubble',
],
},
{
title: 'Scriptable',
collapsable: false,
children: [
'scriptable/interactions',
'scriptable/data',
'scriptable/dataset',
'scriptable/indices',
'scriptable/mirror',
],
},
{
title: 'Events',
collapsable: false,
children: [
'events/listeners',
'events/highlight',
'events/selection',
],
},
{
title: 'Advanced',
collapsable: false,
children: [
'advanced/multiple-labels',
'advanced/custom-labels',
],
}
]
}
}
}
55 changes: 55 additions & 0 deletions docs/.vuepress/plugins/chart-editor/components/ChartActions.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
<template>
<div class="chart-actions">
<a v-for="action in actions" class="chart-action" @click="onClick(action)">
{{ action.name }}
</a>
</div>
</template>

<script>
export default {
props: {
actions: Array,
default: () => [],
},
methods: {
onClick(action) {
this.$emit('action', action);
}
},
}
</script>

<style lang="stylus" scoped>
@import '../styles/palette.styl'
.chart-actions
align-items center
display flex
flex-wrap wrap
.chart-action
transition background .25s, border-color .25s
background rgba($codeBgColor, 0.05)
border 1px solid transparent
border-radius $border-radius
color $accentColor
text-decoration none !important
display inline-block
font-size 0.8rem
padding 8px 16px
margin 0 8px 8px 0
cursor pointer
user-select none
&:hover
background rgba($accentColor, 0.15)
border-color rgba($accentColor, 0.2)
color $accentColor
&:active
background rgba($accentColor, 0.3)
border-color rgba($accentColor, 0.4)
color $accentColor
</style>
111 changes: 111 additions & 0 deletions docs/.vuepress/plugins/chart-editor/components/ChartEditor.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
<template>
<div class="chart-editor">
<chart-view ref="chart-view" :config="config"/>
<chart-actions :actions="actions" @action="execute"/>
<code-editor
:error.sync="error"
:messages="messages"
:output="output"
:value="code"
@input="update"
/>
</div>
</template>

<script>
import Chart from 'chart.js';
import * as Utils from '../utils';
// Components
import ChartActions from './ChartActions.vue';
import ChartView from './ChartView.vue';
import CodeEditor from './CodeEditor.vue';
const CHART_DEFAULTS = Chart.helpers.merge({}, Chart.defaults);
export default {
components: {
ChartActions,
ChartView,
CodeEditor,
},
props: {
code: {
type: String,
required: true,
},
},
data: () => ({
actions: null,
config: null,
error: null,
messages: [],
output: false,
}),
watch: {
code: {
immediate: true,
handler(code) {
this.update(code);
},
},
},
methods: {
update(code) {
this.error = null;
if (!code) {
this.config = null;
return;
}
const script = `
'use strict';
const Chart = arguments[0].Chart;
const Utils = arguments[0].Utils;
const module = {exports: {}};
(function(){ ${code} })();
return module.exports;
`;
const me = this;
const context = {
Chart: Chart,
Utils: {
...Utils,
log(...args) {
me.messages = [...me.messages, args.join(' ')].slice(-50);
},
},
};
Chart.helpers.merge(Chart.defaults, CHART_DEFAULTS);
try {
const exports = new Function(script)(context);
this.output = exports.output || false;
this.config = exports.config;
if (!this.actions) {
this.actions = exports.actions || null;
}
} catch(error) {
this.error = error;
}
},
execute(action) {
action.handler(this.$refs['chart-view'].chart());
},
},
}
</script>

<style lang="stylus" scoped>
.chart-view,
.chart-actions
margin 16px 0
</style>
51 changes: 51 additions & 0 deletions docs/.vuepress/plugins/chart-editor/components/ChartView.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
<template>
<div class="chart-view">
<canvas ref="canvas" />
</div>
</template>

<script>
import Chart from 'chart.js';
import '../../../../../dist/chartjs-plugin-datalabels.js';
export default {
props: {
config: {
type: Object,
default: null,
},
},
watch: {
config() {
this.update();
},
},
mounted() {
this.update();
},
methods: {
chart() {
return this._chart;
},
update() {
const config = this.config;
const canvas = this.$refs.canvas;
if (!canvas || !config) {
return;
}
if (!this._chart) {
this._chart = new Chart(canvas, config);
} else {
this._chart.stop();
this._chart.data = config.data || {};
this._chart.options = config.options || {};
this._chart.update();
}
}
},
}
</script>
Loading

0 comments on commit 202cc79

Please sign in to comment.