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 // we import only d3 types here
@ -17,12 +17,6 @@ const DEFAULT_GRID_OPTIONS = {
ticksCount: DEFAULT_GRID_TICK_COUNT, 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) // 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. // 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. // We have a general problem with passing d3 as argument everywhere. Fix it, and remove from arg in constructor here.
export class Grid { export class Grid {
_gridOptions: GridOptions; protected gridOptions: GridOptions;
constructor( constructor(
private _d3: typeof d3, private _d3: typeof d3,
private _svgEl: d3.Selection<SVGElement, unknown, null, undefined>, private _svgEl: d3.Selection<SVGElement, unknown, null, undefined>,
private _svgElOptions: SvgElOptions, private _svgElOptions: SvgElOptions,
gridOptions: GridOptions, _gridOptions: GridOptions,
) { ) {
this._gridOptions = this.setOptionDefaults(gridOptions); this.gridOptions = this.setOptionDefaults(_gridOptions);
// TODO: or public method that will be called outside
this.render();
} }
protected setOptionDefaults(gridOptions: GridOptions): GridOptions { protected setOptionDefaults(gridOptions: GridOptions): GridOptions {
return defaultsDeep(gridOptions, DEFAULT_GRID_OPTIONS); return defaultsDeep(gridOptions, DEFAULT_GRID_OPTIONS);
} }
render(): void { public render(): void {
// TODO: temporary. Move out of here // TODO: temporary. Move out of here
this._svgEl.selectAll('.grid').remove(); this._svgEl.selectAll('.grid').remove();
@ -59,7 +50,7 @@ export class Grid {
} }
renderGridLinesX(): void { renderGridLinesX(): void {
if(!this._gridOptions.x.isActive) { if(!this.gridOptions.x.isActive) {
return; return;
} }
this._svgEl this._svgEl
@ -69,14 +60,14 @@ export class Grid {
.style('pointer-events', 'none') .style('pointer-events', 'none')
.call( .call(
this._d3.axisBottom(this._svgElOptions.xScale) this._d3.axisBottom(this._svgElOptions.xScale)
.ticks(this._gridOptions.x.ticksCount) .ticks(this.gridOptions.x.ticksCount)
.tickSize(-this._svgElOptions.height) .tickSize(-this._svgElOptions.height)
.tickFormat(() => '') .tickFormat(() => '')
); );
} }
renderGridLinesY(): void { renderGridLinesY(): void {
if(!this._gridOptions.y.isActive) { if(!this.gridOptions.y.isActive) {
return; return;
} }
this._svgEl this._svgEl
@ -85,7 +76,7 @@ export class Grid {
.style('pointer-events', 'none') .style('pointer-events', 'none')
.call( .call(
this._d3.axisLeft(this._svgElOptions.yScale) this._d3.axisLeft(this._svgElOptions.yScale)
.ticks(this._gridOptions.y.ticksCount) .ticks(this.gridOptions.y.ticksCount)
.tickSize(-this._svgElOptions) .tickSize(-this._svgElOptions)
.tickFormat(() => '') .tickFormat(() => '')
); );

72
src/index.ts

@ -1,5 +1,6 @@
import VueChartwerkPodMixin from './VueChartwerkPodMixin'; import VueChartwerkPodMixin from './VueChartwerkPodMixin';
import { PodState } from './state'; import { PodState } from './state';
import { Grid } from './components/grid';
import styles from './css/style.css'; import styles from './css/style.css';
@ -17,7 +18,8 @@ import {
PanOrientation, PanOrientation,
yAxisOrientation, yAxisOrientation,
ScrollPanOrientation, ScrollPanOrientation,
AxisOption AxisOption,
SvgElOptions,
} from './types'; } from './types';
import { uid } from './utils'; import { uid } from './utils';
import { palette } from './colors'; import { palette } from './colors';
@ -101,16 +103,6 @@ const DEFAULT_OPTIONS: Options = {
format: AxisFormat.NUMERIC format: AxisFormat.NUMERIC
} }
}, },
grid: {
x: {
isActive: true,
ticksCount: 5,
},
y: {
isActive: true,
ticksCount: 5,
},
},
crosshair: { crosshair: {
orientation: CrosshairOrientation.VERTICAL, orientation: CrosshairOrientation.VERTICAL,
color: 'red' color: 'red'
@ -146,6 +138,9 @@ abstract class ChartwerkPod<T extends TimeSerie, O extends Options> {
protected deltaYTransform = 0; protected deltaYTransform = 0;
protected debouncedRender = debounce(this.render.bind(this), 100); protected debouncedRender = debounce(this.render.bind(this), 100);
// components
protected grid: Grid;
// TODO: test variables instead of functions with cache // TODO: test variables instead of functions with cache
private _xScale: d3.ScaleLinear<number, number> | null = null; private _xScale: d3.ScaleLinear<number, number> | null = null;
private _yScale: 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.d3Node = this.d3.select(this.el);
this.addEventListeners(); this.addEventListeners();
this.createSvg();
this.initComponents();
} }
protected addEventListeners(): void { protected addEventListeners(): void {
@ -185,7 +183,6 @@ abstract class ChartwerkPod<T extends TimeSerie, O extends Options> {
public render(): void { public render(): void {
this.clearScaleCache(); this.clearScaleCache();
this.renderSvg();
this.renderAxes(); this.renderAxes();
this.renderGrid(); 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 renderSharedCrosshair(values: { x?: number, y?: number }): void;
public abstract hideSharedCrosshair(): void; public abstract hideSharedCrosshair(): void;
protected initPodState() { protected initPodState(): void {
this.state = new PodState(this.options); 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.d3Node.select('svg').remove();
this.svg = this.d3Node this.svg = this.d3Node
.append('svg') .append('svg')
@ -254,40 +263,7 @@ abstract class ChartwerkPod<T extends TimeSerie, O extends Options> {
} }
protected renderGrid(): void { protected renderGrid(): void {
this.chartContainer.selectAll('.grid').remove(); this.grid.render();
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');
} }
protected renderAxes(): void { protected renderAxes(): void {

6
src/types.ts

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

Loading…
Cancel
Save