Browse Source

use grid in core constructor

merge-requests/4/head
vargburz 3 years ago
parent
commit
c38263ed36
  1. 27
      src/components/grid.ts
  2. 72
      src/index.ts
  3. 6
      src/types.ts

27
src/components/grid.ts

@ -1,4 +1,4 @@
import { GridOptions } from '../types';
import { GridOptions, SvgElOptions } from '../types';
// we import only d3 types here
@ -17,12 +17,6 @@ const DEFAULT_GRID_OPTIONS = {
ticksCount: DEFAULT_GRID_TICK_COUNT,
},
}
export type SvgElOptions = {
height: number,
width: number,
xScale: d3.ScaleLinear<number, number>,
yScale: d3.ScaleLinear<number, number>,
}
// Grid Class - is a core component, which can be a separate Pod in the future. (but not in current Pod terminology)
@ -31,25 +25,22 @@ export type SvgElOptions = {
// svgElement should be a separate class with its own height, width, xScale, yScale params to avoid SvgElOptions as argument.
// We have a general problem with passing d3 as argument everywhere. Fix it, and remove from arg in constructor here.
export class Grid {
_gridOptions: GridOptions;
protected gridOptions: GridOptions;
constructor(
private _d3: typeof d3,
private _svgEl: d3.Selection<SVGElement, unknown, null, undefined>,
private _svgElOptions: SvgElOptions,
gridOptions: GridOptions,
_gridOptions: GridOptions,
) {
this._gridOptions = this.setOptionDefaults(gridOptions);
// TODO: or public method that will be called outside
this.render();
this.gridOptions = this.setOptionDefaults(_gridOptions);
}
protected setOptionDefaults(gridOptions: GridOptions): GridOptions {
return defaultsDeep(gridOptions, DEFAULT_GRID_OPTIONS);
}
render(): void {
public render(): void {
// TODO: temporary. Move out of here
this._svgEl.selectAll('.grid').remove();
@ -59,7 +50,7 @@ export class Grid {
}
renderGridLinesX(): void {
if(!this._gridOptions.x.isActive) {
if(!this.gridOptions.x.isActive) {
return;
}
this._svgEl
@ -69,14 +60,14 @@ export class Grid {
.style('pointer-events', 'none')
.call(
this._d3.axisBottom(this._svgElOptions.xScale)
.ticks(this._gridOptions.x.ticksCount)
.ticks(this.gridOptions.x.ticksCount)
.tickSize(-this._svgElOptions.height)
.tickFormat(() => '')
);
}
renderGridLinesY(): void {
if(!this._gridOptions.y.isActive) {
if(!this.gridOptions.y.isActive) {
return;
}
this._svgEl
@ -85,7 +76,7 @@ export class Grid {
.style('pointer-events', 'none')
.call(
this._d3.axisLeft(this._svgElOptions.yScale)
.ticks(this._gridOptions.y.ticksCount)
.ticks(this.gridOptions.y.ticksCount)
.tickSize(-this._svgElOptions)
.tickFormat(() => '')
);

72
src/index.ts

@ -1,5 +1,6 @@
import VueChartwerkPodMixin from './VueChartwerkPodMixin';
import { PodState } from './state';
import { Grid } from './components/grid';
import styles from './css/style.css';
@ -17,7 +18,8 @@ import {
PanOrientation,
yAxisOrientation,
ScrollPanOrientation,
AxisOption
AxisOption,
SvgElOptions,
} from './types';
import { uid } from './utils';
import { palette } from './colors';
@ -101,16 +103,6 @@ const DEFAULT_OPTIONS: Options = {
format: AxisFormat.NUMERIC
}
},
grid: {
x: {
isActive: true,
ticksCount: 5,
},
y: {
isActive: true,
ticksCount: 5,
},
},
crosshair: {
orientation: CrosshairOrientation.VERTICAL,
color: 'red'
@ -146,6 +138,9 @@ abstract class ChartwerkPod<T extends TimeSerie, O extends Options> {
protected deltaYTransform = 0;
protected debouncedRender = debounce(this.render.bind(this), 100);
// components
protected grid: Grid;
// TODO: test variables instead of functions with cache
private _xScale: d3.ScaleLinear<number, number> | null = null;
private _yScale: d3.ScaleLinear<number, number> | null = null;
@ -172,6 +167,9 @@ abstract class ChartwerkPod<T extends TimeSerie, O extends Options> {
this.d3Node = this.d3.select(this.el);
this.addEventListeners();
this.createSvg();
this.initComponents();
}
protected addEventListeners(): void {
@ -185,7 +183,6 @@ abstract class ChartwerkPod<T extends TimeSerie, O extends Options> {
public render(): void {
this.clearScaleCache();
this.renderSvg();
this.renderAxes();
this.renderGrid();
@ -237,11 +234,23 @@ abstract class ChartwerkPod<T extends TimeSerie, O extends Options> {
public abstract renderSharedCrosshair(values: { x?: number, y?: number }): void;
public abstract hideSharedCrosshair(): void;
protected initPodState() {
protected initPodState(): void {
this.state = new PodState(this.options);
}
protected renderSvg(): void {
protected initComponents(): void {
// TODO: make chartContainer a separate class with SvgElOptions inside to avoid duplication
const svgElOptions = {
height: this.height,
width: this.width,
xScale: this.xScale,
yScale: this.yScale,
}
this.grid = new Grid(this.d3, this.chartContainer, svgElOptions, this.options.grid);
}
protected createSvg(): void {
this.d3Node.select('svg').remove();
this.svg = this.d3Node
.append('svg')
@ -254,40 +263,7 @@ abstract class ChartwerkPod<T extends TimeSerie, O extends Options> {
}
protected renderGrid(): void {
this.chartContainer.selectAll('.grid').remove();
if(this.options.grid.x.isActive) {
this.chartContainer
.append('g')
.attr('transform', `translate(0,${this.height})`)
.attr('class', 'grid x-grid')
.style('pointer-events', 'none')
.call(
this.d3.axisBottom(this.xScale)
.ticks(this.options.grid.x.ticksCount)
.tickSize(-this.height)
.tickFormat(() => '')
);
}
if(this.options.grid.y.isActive) {
this.chartContainer
.append('g')
.attr('class', 'grid y-grid')
.style('pointer-events', 'none')
.call(
this.d3.axisLeft(this.yScale)
.ticks(this.options.grid.y.ticksCount)
.tickSize(-this.width)
.tickFormat(() => '')
);
}
this.chartContainer.selectAll('.grid').selectAll('.tick')
.attr('opacity', '0.5');
this.chartContainer.selectAll('.grid').select('.domain')
.style('pointer-events', 'none');
this.grid.render();
}
protected renderAxes(): void {

6
src/types.ts

@ -165,3 +165,9 @@ export enum yAxisOrientation {
RIGHT = 'right',
BOTH = 'both'
}
export type SvgElOptions = {
height: number,
width: number,
xScale: d3.ScaleLinear<number, number>,
yScale: d3.ScaleLinear<number, number>,
}

Loading…
Cancel
Save