Commit 769bf50f authored by Almouhannad Hafez's avatar Almouhannad Hafez

Add chart abstract class

parent a8832ae2
import * as d3 from 'd3';
import { ChartConfiguration } from './chartConfiguration';
export abstract class Chart {
protected config: {
parentSVGElement: string;
containerWidth: number;
containerHeight: number;
margin: { top: number; right: number; bottom: number; left: number; };
};
protected data: any[];
protected width: number;
protected height: number;
protected svg: d3.Selection<d3.BaseType, unknown, HTMLElement, any>;
protected chart: any;
/**
* Class constructor with basic chart configuration
*/
constructor(_config: ChartConfiguration, _data: any[]) {
const vis = this;
// Configuration object with defaults
const { width, height } = _config.containerSize || vis.getDefaultContainerSize();
vis.config = {
parentSVGElement: _config.parentSVGElement,
containerWidth: width,
containerHeight: height,
margin: _config.margin || vis.getDefaultMargins()
};
vis.data = _data;
vis.initChart();
}
/**
* Returns default margin values.
*/
protected abstract getDefaultMargins(): { top: number; right: number; bottom: number; left: number };
/**
* Returns default container size (width and height).
*/
protected abstract getDefaultContainerSize(): { width: number; height: number };
/**
* Initialize chart element.
*/
private initChart() {
const vis = this;
// Calculate inner chart size.
vis.width = vis.config.containerWidth - vis.config.margin.left - vis.config.margin.right;
vis.height = vis.config.containerHeight - vis.config.margin.top - vis.config.margin.bottom;
// Define size of SVG drawing area
vis.svg = d3.select(vis.config.parentSVGElement)
.attr('width', vis.config.containerWidth)
.attr('height', vis.config.containerHeight);
// Append group element that will contain our actual chart
// and position it according to the given margin config
vis.chart = vis.svg.append('g')
.attr('transform', `translate(${vis.config.margin.left},${vis.config.margin.top})`);
}
/**
* Initialize scales/axes and append static elements, such as axis titles.
*/
protected abstract initVis(): void;
/**
* This function contains the D3 code for binding data to visual elements.
* We call this function every time the data or configurations change.
*/
protected abstract renderVis(): void;
/**
* This function contains all the code to prepare the data before we render it.
*/
public abstract updateVis(): void;
}
\ No newline at end of file
export class ChartConfiguration {
/**
* parentSVGElement
*/
public parentSVGElement: string;
public containerSize?: { width: number; height: number };
public margin?: { top: number; right: number; bottom: number; left: number };
constructor(parentSVGElement: string,
containerSize?: { width: number; height: number },
margin?: { top: number; right: number; bottom: number; left: number }) {
this.parentSVGElement = parentSVGElement;
this.containerSize = containerSize;
this.margin = margin;
}
}
\ No newline at end of file
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
"noEmit": true, "noEmit": true,
/* Linting */ /* Linting */
"strict": true, "strict": true,
"strictPropertyInitialization": false,
"noUnusedLocals": true, "noUnusedLocals": true,
"noUnusedParameters": true, "noUnusedParameters": true,
"noFallthroughCasesInSwitch": true, "noFallthroughCasesInSwitch": true,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment