vargburz
3 years ago
2 changed files with 111 additions and 10 deletions
@ -0,0 +1,100 @@
|
||||
import { GridOptions } from '../types'; |
||||
|
||||
|
||||
// we import only d3 types here
|
||||
import * as d3 from 'd3'; |
||||
|
||||
import defaultsDeep from 'lodash/defaultsDeep'; |
||||
|
||||
const DEFAULT_GRID_TICK_COUNT = 5; |
||||
const DEFAULT_GRID_OPTIONS = { |
||||
x: { |
||||
isActive: true, |
||||
ticksCount: DEFAULT_GRID_TICK_COUNT, |
||||
}, |
||||
y: { |
||||
isActive: true, |
||||
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)
|
||||
// All components have construcor with required args: svg element which will be filled with this component and options for it.
|
||||
// All compoтents have a reqiured method "render", which will be called in core costructor. <- this solution is temporary.
|
||||
// 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; |
||||
|
||||
constructor( |
||||
private _d3: typeof d3, |
||||
private _svgEl: d3.Selection<SVGElement, unknown, null, undefined>, |
||||
private _svgElOptions: SvgElOptions, |
||||
gridOptions: GridOptions, |
||||
) { |
||||
this._gridOptions = this.setOptionDefaults(gridOptions); |
||||
|
||||
this.render(); |
||||
} |
||||
|
||||
protected setOptionDefaults(gridOptions: GridOptions): GridOptions { |
||||
return defaultsDeep(gridOptions, DEFAULT_GRID_OPTIONS); |
||||
} |
||||
|
||||
render(): void { |
||||
// TODO: temporary. Move out of here
|
||||
this._svgEl.selectAll('.grid').remove(); |
||||
|
||||
this.renderGridLinesX(); |
||||
this.renderGridLinesY(); |
||||
this.updateStylesOfTicks(); |
||||
} |
||||
|
||||
renderGridLinesX(): void { |
||||
if(!this._gridOptions.x.isActive) { |
||||
return; |
||||
} |
||||
this._svgEl |
||||
.append('g') |
||||
.attr('transform', `translate(0,${this._svgElOptions.height})`) |
||||
.attr('class', 'grid x-grid') |
||||
.style('pointer-events', 'none') |
||||
.call( |
||||
this._d3.axisBottom(this._svgElOptions.xScale) |
||||
.ticks(this._gridOptions.x.ticksCount) |
||||
.tickSize(-this._svgElOptions.height) |
||||
.tickFormat(() => '') |
||||
); |
||||
} |
||||
|
||||
renderGridLinesY(): void { |
||||
if(!this._gridOptions.y.isActive) { |
||||
return; |
||||
} |
||||
this._svgEl |
||||
.append('g') |
||||
.attr('class', 'grid y-grid') |
||||
.style('pointer-events', 'none') |
||||
.call( |
||||
this._d3.axisLeft(this._svgElOptions.yScale) |
||||
.ticks(this._gridOptions.y.ticksCount) |
||||
.tickSize(-this._svgElOptions) |
||||
.tickFormat(() => '') |
||||
); |
||||
} |
||||
|
||||
updateStylesOfTicks(): void { |
||||
// TODO: add options for these actions
|
||||
this._svgEl.selectAll('.grid').selectAll('.tick') |
||||
.attr('opacity', '0.5'); |
||||
this._svgEl.selectAll('.grid').select('.domain') |
||||
.style('pointer-events', 'none'); |
||||
} |
||||
} |
Loading…
Reference in new issue