Reference Source Test

src/charts/chart.js

export default class Chart {

	/**
	 * Creates an instance of the Chart class
	 * @param {string} data - JSON string containing the data columns.
	 */
	constructor(data) {
		this._data = data

		// Define output JSON
		this._outputJson = {
			'size': {
				'height': undefined,
				'width': undefined
			},
			'data': {
				'x': undefined,
				'xs': {},
				'columns': [],
				'names': {},
				'types': {},
				'groups': [],
				'type': undefined,
				'labels': false
			},
			'point': {
				'show': true
			},
			'axis': {
				'rotated': false,
				'x': {
					'label': undefined,
					'max': undefined,
					'min': undefined
				},
				'y': {
					'label': undefined,
					'max': undefined,
					'min': undefined
				}
			},
			'grid': {
				'x': {
					'show': false,
					'lines': []
				},
				'y': {
					'show': false,
					'lines': []
				}
			},
			'legend': {
				'show': true,
				'position': 'bottom'
			},
			'tooltip': {
				'show': true,
				'grouped': true
			},
			'subchart': {
				'show': false
			},
			'zoom': {
				'enabled': false
			},
			'bar': {
				'width': {
					'ratio': undefined
				}
			},
			'donut': {
				'title': undefined
			}
		}

		// Add _data
		let dataJson = JSON.parse(this._data)
		for (let i in dataJson) {
			this._outputJson.data.columns.push([i, ...dataJson[i]])
		}
	}

	/**
	 * Alter the parameters of the charts using the provided grammar.
	 * @param {string} grammar - Simple grammar string describing the charts.
	 * @returns {boolean} - Returns true if the grammar is parsed.
	 */
	do(grammar) {
		if (grammar.match(new RegExp('(show|hide) grid [xXyY]'))) {
			let option = grammar.match(new RegExp('(show|hide)'))[0]
			let axis = grammar.match(new RegExp('[xXyY]'))[0]
			if (axis.toLowerCase() === 'x') {
				this._outputJson.grid.x.show = (option === 'show')
			} else {
				this._outputJson.grid.y.show = (option === 'show')
			}
			return true
		} else if (grammar.match(new RegExp('set gridline [xXyY] at [\\d]+ as [0-9a-zA-Z\\-]+'))) {
			let axis = grammar.match(new RegExp('gridline [xXyY] at'))[0].split(' ')[1]
			let position = grammar.match(new RegExp('at [\\d]+ as'))[0].split(' ')[1]
			let label = grammar.match(new RegExp('as [0-9a-zA-Z\\-]+'))[0].split(' ')[1]
			if (axis.toLowerCase() === 'x') {
				this._outputJson.grid.x.lines.push({
					'value': Number(position),
					'text': label
				})
			} else {
				this._outputJson.grid.y.lines.push({
					'value': Number(position),
					'text': label
				})
			}
			return true
		} else if (grammar.match(new RegExp('set [0-9a-zA-Z\\-]+ data label as [0-9a-zA-Z\\-]+'))) {
			let dataColumn = grammar.match(new RegExp('set [0-9a-zA-Z\\-]+ data'))[0].split(' ')[1]
			let label = grammar.match(new RegExp('as [0-9a-zA-Z\\-]+'))[0].split(' ')[1]
			this._outputJson.data.names[dataColumn] = label
			return true
		} else if (grammar.match(new RegExp('set [xXyY] axis label as [0-9a-zA-Z\\-]+'))) {
			let axis = grammar.match(new RegExp('[xXyY]'))[0]
			let label = grammar.match(new RegExp('as [0-9a-zA-Z\\-]+'))[0].split(' ')[1]
			if (axis.toLowerCase() === 'x') {
				this._outputJson.axis.x.label = label
			} else {
				this._outputJson.axis.y.label = label
			}
			return true
		} else if (grammar.match(new RegExp('set [xXyY] axis (max|min) as [-]?[\\d]+'))) {
			let axis = grammar.match(new RegExp('[xXyY]'))[0]
			let margin = grammar.match(new RegExp('axis (max|min) as'))[0].split(' ')[1]
			let value = grammar.match(new RegExp('as [-]?[\\d]+'))[0].split(' ')[1]
			if (axis.toLowerCase() === 'x') {
				if (margin.toLowerCase() === 'max') {
					this._outputJson.axis.x.max = Number(value)
				} else {
					this._outputJson.axis.x.min = Number(value)
				}
			} else {
				if (margin.toLowerCase() === 'max') {
					this._outputJson.axis.y.max = Number(value)
				} else {
					this._outputJson.axis.y.min = Number(value)
				}
			}
			return true
		} else if (grammar.match(new RegExp('(show|hide) tooltip'))) {
			let option = grammar.match(new RegExp('(show|hide)'))[0]
			this._outputJson.tooltip.show = (option === 'show')
			return true
		} else if (grammar.match(new RegExp('(group|ungroup) tooltip'))) {
			let option = grammar.match(new RegExp('(group|ungroup)'))[0]
			this._outputJson.tooltip.grouped = (option === 'group')
			return true
		} else if (grammar.match(new RegExp('(show|hide) points'))) {
			let option = grammar.match(new RegExp('(show|hide)'))[0]
			this._outputJson.point.show = (option === 'show')
			return true
		} else if (grammar.match(new RegExp('(show|hide) data labels'))) {
			let option = grammar.match(new RegExp('(show|hide)'))[0]
			this._outputJson.data.labels = (option === 'show')
			return true
		} else if (grammar.match(new RegExp('(show|hide) legend'))) {
			let option = grammar.match(new RegExp('(show|hide)'))[0]
			this._outputJson.legend.show = (option === 'show')
			return true
		} else if (grammar.match(new RegExp('(show|hide) subchart'))) {
			let option = grammar.match(new RegExp('(show|hide)'))[0]
			this._outputJson.subchart.show = (option === 'show')
			return true
		} else if (grammar.match(new RegExp('(enable|disable) zoom'))) {
			let option = grammar.match(new RegExp('(enable|disable)'))[0]
			this._outputJson.zoom.enabled = (option === 'enable')
			return true
		} else if (grammar.match(new RegExp('(enable|disable) rotate'))) {
			let option = grammar.match(new RegExp('(enable|disable)'))[0]
			this._outputJson.axis.rotated = (option === 'enable')
			return true
		} else if (grammar.match(new RegExp('move legend to (right|bottom)'))) {
			let option = grammar.match(new RegExp('(left|right|top|bottom)'))[0]
			this._outputJson.legend.position = option
			return true
		} else if (grammar.match(new RegExp('set (height|width) as [\\d]+'))) {
			let option = grammar.match(new RegExp('(height|width)'))[0]
			let value = grammar.match(new RegExp('as [\\d]+'))[0].split(' ')[1]
			if (option.toLowerCase() === 'height') {
				this._outputJson.size.height = Number(value)
			} else {
				this._outputJson.size.width = Number(value)
			}
			return true
		}
		else {
			return false
		}
	}

	/**
	 * Return the JSON output string of the constructed charts.
	 * @returns {string}
	 */
	generateJson() {
		return this._outputJson
	}
}