Skip to content

Instantly share code, notes, and snippets.

@moetelo
Last active December 28, 2020 16:02
Show Gist options
  • Save moetelo/3b982391a6df56514367b444cad31756 to your computer and use it in GitHub Desktop.
Save moetelo/3b982391a6df56514367b444cad31756 to your computer and use it in GitHub Desktop.
<template>
<div ref="root" class="chart-root"></div>
</template>
<script lang="ts">
// https://gist.github.com/vinicius73/d08d775b184c02097e5eca0a7bea2eda
// @ts-ignore
import * as c3 from 'c3';
// @ts-ignore
import { debounce, cloneDeep, defaultsDeep } from 'lodash';
import { Vue, Prop, Component, Ref, Watch } from 'vue-property-decorator';
@Component({})
export default class BaseChart extends Vue {
$chart: any = null;
@Ref()
readonly root!: HTMLDivElement;
@Prop({ type: Object, default: () => ({}) })
readonly config!: any;
@Prop({ type: Object, default: () => ({}) })
readonly data!: any;
@Prop({ type: String, default: 'bar' })
readonly type!: string;
@Prop({ type: String, default: '' })
readonly text!: string;
get title(): string {
if (!this.root)
return '';
const titleElement = this.root.querySelector('.c3-chart-arcs-title');
if (titleElement)
return titleElement.innerHTML;
return '';
}
set title(val: string) {
if (!this.root)
return;
const titleElement = this.root.querySelector('.c3-chart-arcs-title');
if (!titleElement)
return;
titleElement.innerHTML = val;
}
@Watch('text', {immediate: true})
onTextChanged(text: string): void {
this.title = text;
}
mounted() {
this.initChart();
}
beforeDestroy() {
this.$chart = this.$chart.destroy();
}
initChart(): any {
const args = this.getArgs();
this.$chart = c3.generate({
bindto: this.root,
...args
});
if (this.text)
this.title = this.text;
this.$emit('init', args);
}
getArgs(): any {
const data = this.getData();
const config = this.getConfig();
return defaultsDeep({ data }, config);
}
getData(): any {
const { type } = this;
const data = cloneDeep(this.data);
return defaultsDeep({ type }, data);
}
getConfig(): any {
const config = cloneDeep(this.config);
const color = {
pattern: [
// '#000048',
// '#072974',
// '#4751a3',
// '#4e95cb',
// '#83c5fe',
// '#b7f8ff',
'#E1B07E',
'#E2EB98',
'#93A392',
'#ADBF97',
'#9DC4B5',
]
};
const axis = {
x: {
type: 'category',
padding: {
left: 0,
right: 0
},
tick: {
multiline: true
}
}
};
// , color
return defaultsDeep({ axis, color }, config);
}
reload(): void {
console.log('reload');
this.$emit('reloading');
this.$chart.unload();
this.$nextTick(() => {
this.updateDebounce();
})
}
update(): void {
const data = this.getData();
this.$chart.load(data);
this.$emit('update', data);
}
@Watch('data', { deep: true })
readonly reloadDebounce = debounce(() => this.reload(), 50);
readonly updateDebounce = debounce(() => this.update(), 50);
}
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment