vue-google-charts
Version:
Reactive Vue.js wrapper for Google Charts lib
251 lines (245 loc) • 7.88 kB
JavaScript
const chartsScriptUrl = 'https://www.gstatic.com/charts/loader.js';
let chartsLoaderPromise = null;
const loadedPackages = new Map();
function getChartsLoader() {
// If already included in the page:
if (window.google !== undefined) {
return Promise.resolve(window.google.charts);
}
if (chartsLoaderPromise === null) {
chartsLoaderPromise = new Promise((resolve)=>{
// Find script tag with same src in DOM.
const foundScript = document.querySelector("script[src=\"".concat(chartsScriptUrl, "\"]"));
// Create or get existed tag.
const script = foundScript || document.createElement('script');
// Set src if no script was found.
if (!foundScript) {
script.src = chartsScriptUrl;
script.type = 'text/javascript';
document.head.append(script);
}
script.onload = ()=>{
if (window.google !== undefined) {
resolve(window.google.charts);
}
};
});
}
return chartsLoaderPromise;
}
/**
* Function to load Google Charts JS API.
* @param version - Chart version to load.
* @param packages - Packages to load.
* @param language - Languages to load.
* @param mapsApiKey - Google Maps api key.
* @returns
*/ async function loadGoogleCharts() {
let version = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : 'current', { packages =[
'corechart',
'controls'
] , language ='en' , mapsApiKey } = arguments.length > 1 ? arguments[1] : void 0;
const loader = await getChartsLoader();
const settingsKey = "".concat(version, "_").concat(packages.join('_'), "_").concat(language);
if (loadedPackages.has(settingsKey)) return loadedPackages.get(settingsKey);
const loaderPromise = new Promise((resolve)=>{
loader.load(version, {
packages,
language,
mapsApiKey
});
loader.setOnLoadCallback(()=>resolve(window.google)
);
});
loadedPackages.set(settingsKey, loaderPromise);
return loaderPromise;
}
function debounce(func) {
let waitMilliseconds = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : 50;
let timeoutId;
function nextInvokeTimeout() {
return waitMilliseconds;
}
const debouncedFunction = function() {
for(var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++){
args[_key] = arguments[_key];
}
const context = this;
const invokeFunction = function() {
timeoutId = undefined;
func.apply(context, args);
};
if (timeoutId !== undefined) {
clearTimeout(timeoutId);
}
timeoutId = setTimeout(invokeFunction, nextInvokeTimeout());
};
return debouncedFunction;
}
function getValidChartData(chartsLib, data, isFirstRowLabels) {
if (chartsLib !== null && data instanceof chartsLib.visualization.DataTable) {
return data;
}
if (chartsLib !== null && data instanceof chartsLib.visualization.DataView) {
return data;
}
if (chartsLib !== null && Array.isArray(data)) {
return chartsLib.visualization.arrayToDataTable(data, isFirstRowLabels);
}
if (chartsLib !== null && data !== null && typeof data === 'object') {
return new chartsLib.visualization.DataTable(data);
}
return null;
}
function createChartObject(chartsLib, chartObject, chartEl, chartType, chartEvents, createChartFunction) {
const createChart = (el, google, type)=>{
if (type === undefined) {
throw new Error('please, provide chart type property');
}
return new google.visualization[type](el);
};
if (chartsLib === null) {
throw new Error('please, provide charts lib property');
}
if (chartEl === null) {
throw new Error('please, provide chart element property');
}
const fn = createChartFunction || createChart;
chartObject = fn(chartEl, chartsLib, chartType);
attachListeners(chartsLib, chartObject, chartEvents);
return chartObject;
}
function attachListeners(chartsLib, chartObject, chartEvents) {
if (chartEvents === null) {
return;
}
for (const [event, listener] of Object.entries(chartEvents)){
if (chartsLib !== null && chartObject !== null) {
chartsLib.visualization.events.addListener(chartObject, event, listener);
}
}
}
let chartsLib = null;
var GChart = {
render: function() {
var _vm = this;
var _h = _vm.$createElement;
var _c = _vm._self._c || _h;
return _c('div', {
ref: "chart"
});
},
staticRenderFns: [],
name: 'GChart',
props: {
type: {
type: String,
required: true
},
data: {
type: [
Array,
Object
],
default: ()=>[]
},
isFirstRowLabels: {
type: Boolean,
default: false
},
options: {
type: Object,
default: ()=>({})
},
version: {
type: String,
default: 'current'
},
settings: {
type: Object,
default: ()=>({
packages: [
'corechart',
'table'
]
})
},
events: {
type: Object,
default: null
},
createChart: {
type: Function,
default: null
},
resizeDebounce: {
type: Number,
default: 200
}
},
data () {
return {
chartObject: null
};
},
watch: {
data: {
deep: true,
handler () {
this.drawChart();
}
},
options: {
deep: true,
handler () {
this.drawChart();
}
},
type () {
this.chartObject = createChartObject(chartsLib, this.chartObject, this.$refs.chart, this.type, this.events, this.createChart);
this.drawChart();
}
},
mounted () {
loadGoogleCharts(this.version, this.settings).then((api)=>{
chartsLib = api;
this.chartObject = createChartObject(chartsLib, this.chartObject, this.$refs.chart, this.type, this.events, this.createChart);
this.$emit('ready', this.chartObject, api);
this.drawChart();
});
if (this.resizeDebounce > 0) window.addEventListener('resize', debounce(this.drawChart, this.resizeDebounce));
},
beforeDestroy () {
if (this.chartObject !== null && typeof this.chartObject.clearChart === 'function') {
this.chartObject.clearChart();
}
},
methods: {
drawChart () {
if (!chartsLib || !this.chartObject) return;
const data = getValidChartData(chartsLib, this.data, this.isFirstRowLabels);
if (data) this.chartObject.draw(data, this.options);
}
}
};
// Install the components
function install(vue) {
vue.component('GChart', GChart);
}
/* -- Plugin definition & Auto-install -- */ /* You shouldn't have to modify the code below */ // Plugin
const plugin = {
version: "1.1.0",
install
};
// Auto-install
let GlobalVue = null;
if (typeof window !== 'undefined') {
GlobalVue = window.Vue;
} else if (typeof global !== 'undefined') {
GlobalVue = global.Vue;
}
if (GlobalVue) {
GlobalVue.use(plugin);
}
export { GChart, plugin as default, install, loadGoogleCharts };
//# sourceMappingURL=index.js.map