Reference Source Test

src/graph.js

import ChartType from './charts/chart-type'
import LineChart from './charts/types/line-chart'
import SimpleXYLineChart from './charts/types/simple-xy-line-chart'
import StepChart from './charts/types/step-chart'
import BarChart from './charts/types/bar-chart'
import PieChart from './charts/types/pie-chart'
import MultipleXYLineChart from './charts/types/multiple-xy-line-chart'
import AreaChart from './charts/types/area-chart'
import StackedBarChart from './charts/types/stacked-bar-chart'
import DonutChart from './charts/types/donut-chart'
import SplineChart from './charts/types/spline-chart'
import StackedAreaChart from './charts/types/stacked-area-chart'
import ScatterPlot from './charts/types/scatter-plot'
import InvalidGrammarError from './errors/invalid-grammar-error'
import InvalidOperationError from './errors/invalid-operation-error'

/**
 * Graph is the base class of all operations withing the GraphJS.
 * It acts as a factory-pattern for creating any types of charts.
 */
export default class Graph {

	/**
	 * Creates an instance of the class Graph
	 * @param {string} grammar - Initial grammar provided to initiate the class.
	 * This should be in the form of : generate <GRAPH_TYPE> for <DATASOURCE>
	 */
	constructor(grammar) {
		/**
		 * Holds the instance of the charts types that was created within the object with the initial grammar.
		 * @types {Chart}
		 * @private
		 */
		this._chart = undefined

		// Validate and parse the grammar
		let grammarParser = new GrammarParser(grammar)

		let chartType = grammarParser.chartType
		switch (ChartType.enumValueOf(chartType)) {
		case ChartType.LINE_CHART:
			this._chart = new LineChart(grammarParser.datasource)
			break
		case ChartType.SIMPLE_XY_LINE_CHART:
			this._chart = new SimpleXYLineChart(grammarParser.datasource)
			break
		case ChartType.STEP_CHART:
			this._chart = new StepChart(grammarParser.datasource)
			break
		case ChartType.BAR_CHART:
			this._chart = new BarChart(grammarParser.datasource)
			break
		case ChartType.PIE_CHART:
			this._chart = new PieChart(grammarParser.datasource)
			break
		case ChartType.COMBINATION_CHART:
			throw new InvalidOperationError()
			// this._chart = new CombinationChart(grammarParser.datasource)
			// break
		case ChartType.MULTIPLE_XY_LINE_CHART:
			this._chart = new MultipleXYLineChart(grammarParser.datasource)
			break
		case ChartType.AREA_CHART:
			this._chart = new AreaChart(grammarParser.datasource)
			break
		case ChartType.STACKED_BAR_CHART:
			this._chart = new StackedBarChart(grammarParser.datasource)
			break
		case ChartType.DONUT_CHART:
			this._chart = new DonutChart(grammarParser.datasource)
			break
		case ChartType.SPLINE_CHART:
			this._chart = new SplineChart(grammarParser.datasource)
			break
		case ChartType.LINE_CHART_WITH_REGIONS:
			throw new InvalidOperationError()
			// this._chart = new LineChartWithRegions(grammarParser.datasource)
			// break
		case ChartType.STACKED_AREA_CHART:
			this._chart = new StackedAreaChart(grammarParser.datasource)
			break
		case ChartType.SCATTER_PLOT:
			this._chart = new ScatterPlot(grammarParser.datasource)
			break
		case ChartType.GAUGE_CHART:
			throw new InvalidOperationError()
			// this._chart = new GaugeChart(grammarParser.datasource)
			// break
		}
	}

	/**
	 * Parse the grammar given by the user.
	 * @param grammar
	 * @returns {boolean}
	 */
	do(grammar) {
		return this._chart.do(grammar)
	}

	/**
	 * Return the JSON output string created by parsing the input grammar.
	 * @returns {string}
	 */
	generateJson() {
		return this._chart.generateJson()
	}
}

/**
 * Does the initial grammar parsing.
 */
class GrammarParser {

	/**
	 * Creates an instance of the class GrammarParser
	 * @param {string} grammar - Initial grammar provided to initiate the class.
	 * This should be in the form of : generate <GRAPH_TYPE> for <DATASOURCE>
	 */
	constructor(grammar) {
		this.grammar = grammar
		this.chartType = undefined
		this.datasource = undefined

		// Verify the basic structure of the grammar
		if (GrammarParser.verifyStructure(grammar)) {
			let chartTypeExtract = grammar.match(new RegExp('generate [A-Z_]+ for'))[0]
			this.chartType = chartTypeExtract.slice(9, chartTypeExtract.length - 4)
			this.datasource = grammar.match(new RegExp('for {.*}'))[0].slice(4)

			// Verify the charts types and the datasource
			if (!GrammarParser.verifyChartType(this.chartType) || !GrammarParser.verifyDatasource(this.datasource)) {
				throw new InvalidGrammarError()
			}
		} else {
			throw new InvalidGrammarError()
		}
	}

	/**
	 * Verify the syntactical and the symantic validity of the whole grammar sentence.
	 * @param grammar
	 * @returns {boolean}
	 */
	static verifyStructure(grammar) {
		return grammar.match(new RegExp('generate [A-Z_]+ for {.*}'))
	}

	/**
	 * Verify the vaidity of the charts types.
	 * @param chartType
	 * @returns {boolean}
	 */
	static verifyChartType(chartType) {
		return ChartType.enumValueOf(chartType) instanceof ChartType
	}

	/**
	 * Verify the validity of the datasource.
	 * @param grammar
	 * @returns {boolean}
	 */
	// eslint-disable-next-line no-unused-vars
	static verifyDatasource(grammar) {
		// TODO : Verify datasource
		return true
	}
}