Browse Source

render metric container

merge-requests/7/head
vargburz 3 years ago
parent
commit
1bd674cb40
  1. 36
      src/index.ts
  2. 1
      src/state.ts

36
src/index.ts

@ -107,13 +107,13 @@ const DEFAULT_OPTIONS: Options = {
abstract class ChartwerkPod<T extends TimeSerie, O extends Options> { abstract class ChartwerkPod<T extends TimeSerie, O extends Options> {
protected d3Node?: d3.Selection<HTMLElement, unknown, null, undefined>; protected d3Node?: d3.Selection<HTMLElement, unknown, null, undefined>;
protected chartContainer?: d3.Selection<SVGGElement, unknown, null, undefined>;
protected customOverlay?: d3.Selection<SVGRectElement, unknown, null, undefined>; protected customOverlay?: d3.Selection<SVGRectElement, unknown, null, undefined>;
protected crosshair?: d3.Selection<SVGGElement, unknown, null, undefined>; protected crosshair?: d3.Selection<SVGGElement, unknown, null, undefined>;
protected brush?: d3.BrushBehavior<unknown>; protected brush?: d3.BrushBehavior<unknown>;
protected zoom?: any; protected zoom?: any;
protected svg?: d3.Selection<SVGElement, unknown, null, undefined>; protected svg?: d3.Selection<SVGElement, unknown, null, undefined>;
protected state?: PodState<T, O>; protected state: PodState<T, O>;
protected pan?: any; // TODO: not any;
protected clipPath?: any; protected clipPath?: any;
protected isPanning = false; protected isPanning = false;
protected isBrushing = false; protected isBrushing = false;
@ -131,7 +131,10 @@ abstract class ChartwerkPod<T extends TimeSerie, O extends Options> {
protected readonly d3: typeof d3; protected readonly d3: typeof d3;
protected deltaYTransform = 0; protected deltaYTransform = 0;
protected debouncedRender = debounce(this.render.bind(this), 100); protected debouncedRender = debounce(this.render.bind(this), 100);
// containers
// TODO: add better names
protected chartContainer: d3.Selection<SVGGElement, unknown, null, undefined>;
protected metricContainer: d3.Selection<SVGGElement, unknown, null, undefined>;
// components // components
protected grid: Grid; protected grid: Grid;
@ -175,6 +178,7 @@ abstract class ChartwerkPod<T extends TimeSerie, O extends Options> {
this.addEvents(); this.addEvents();
this.renderCrosshair(); this.renderCrosshair();
this.renderMetricsContainer();
this.renderMetrics(); this.renderMetrics();
this.renderLegend(); this.renderLegend();
@ -201,7 +205,7 @@ abstract class ChartwerkPod<T extends TimeSerie, O extends Options> {
let options = cloneDeep(newOptions); let options = cloneDeep(newOptions);
defaultsDeep(options, DEFAULT_OPTIONS); defaultsDeep(options, DEFAULT_OPTIONS);
this.options = options; this.options = options;
// TODO: update state if axis ranges were changed
} }
protected updateSeries(newSeries: T[]): void { protected updateSeries(newSeries: T[]): void {
@ -240,6 +244,22 @@ abstract class ChartwerkPod<T extends TimeSerie, O extends Options> {
this.grid = new Grid(this.d3, this.chartContainer, svgElParams, this.options.grid); this.grid = new Grid(this.d3, this.chartContainer, svgElParams, this.options.grid);
} }
protected renderMetricsContainer(): void {
this.d3.select('.metrics-container').remove();
// TODO: it should be a class with svgElParams as fields
// container for clip path
const clipContatiner = this.chartContainer
.append('g')
.attr('clip-path', `url(#${this.rectClipId})`)
.attr('class', 'metrics-container');
// container for panning
this.metricContainer = clipContatiner
.append('g')
.attr('class', 'metrics-rect');
}
protected createSvg(): void { protected createSvg(): void {
this.d3Node.select('svg').remove(); this.d3Node.select('svg').remove();
this.svg = this.d3Node this.svg = this.d3Node
@ -329,6 +349,8 @@ abstract class ChartwerkPod<T extends TimeSerie, O extends Options> {
} }
protected renderCrosshair(): void { protected renderCrosshair(): void {
this.d3.selectAll('#crosshair-container').remove();
this.crosshair = this.chartContainer.append('g') this.crosshair = this.chartContainer.append('g')
.attr('id', 'crosshair-container') .attr('id', 'crosshair-container')
.style('display', 'none'); .style('display', 'none');
@ -463,11 +485,11 @@ abstract class ChartwerkPod<T extends TimeSerie, O extends Options> {
if(this.options.axis.y1.isActive === true) { if(this.options.axis.y1.isActive === true) {
this.initScaleY1 = this.y1Scale.copy(); this.initScaleY1 = this.y1Scale.copy();
} }
const pan = this.d3.zoom() this.pan = this.d3.zoom()
.on('zoom', this.onPanning.bind(this)) .on('zoom', this.onPanning.bind(this))
.on('end', this.onPanningEnd.bind(this)); .on('end', this.onPanningEnd.bind(this));
this.chartContainer.call(pan); this.chartContainer.call(this.pan);
} }
protected renderClipPath(): void { protected renderClipPath(): void {
@ -592,13 +614,11 @@ abstract class ChartwerkPod<T extends TimeSerie, O extends Options> {
public rescaleMetricAndAxis(event: d3.D3ZoomEvent<any, any>): void { public rescaleMetricAndAxis(event: d3.D3ZoomEvent<any, any>): void {
this.isPanning = true; this.isPanning = true;
this.onMouseOut(); this.onMouseOut();
this.onPanningRescale(event); this.onPanningRescale(event);
// TODO: check clear state for necessity // TODO: check clear state for necessity
this.renderYAxis(); this.renderYAxis();
this.renderXAxis(); this.renderXAxis();
// metrics-rect wrapper is required for panning // metrics-rect wrapper is required for panning
this.chartContainer.select('.metrics-rect') this.chartContainer.select('.metrics-rect')
.attr('transform', `translate(${this.state.transform.x},${this.state.transform.y}), scale(${this.state.transform.k})`); .attr('transform', `translate(${this.state.transform.x},${this.state.transform.y}), scale(${this.state.transform.k})`);

1
src/state.ts

@ -22,6 +22,7 @@ const DEFAULT_TRANSFORM = {
// TODO: replace all getters with fields. Because getters will be recalculated on each call. Use scales as example. // TODO: replace all getters with fields. Because getters will be recalculated on each call. Use scales as example.
// TODO: remove duplicates in max/min values. // TODO: remove duplicates in max/min values.
// TODO: PodState can be divided in two classes, but it is hard now. // TODO: PodState can be divided in two classes, but it is hard now.
// TODO: PodState.transform has conflicts with d3.zoom.event.transform. It should be synchronized.
export class PodState<T extends TimeSerie, O extends Options> { export class PodState<T extends TimeSerie, O extends Options> {
private _xValueRange: [number, number]; private _xValueRange: [number, number];
private _yValueRange: [number, number]; private _yValueRange: [number, number];

Loading…
Cancel
Save