veritatisquam
Version:
Carbon charting components, lerna monorepo
252 lines (227 loc) • 6.07 kB
text/typescript
import { Chart } from './chart';
import { ChartModelCartesian } from './model-cartesian-charts';
import {
LayoutDirection,
LayoutGrowth,
LegendOrientations,
LegendPositions,
ChartConfig,
AxisChartOptions,
AxisPositions,
ScaleTypes,
} from './interfaces';
import {
ChartBrush,
ChartClip,
LayoutComponent,
Legend,
Title,
AxisChartsTooltip,
Spacer,
Toolbar,
ZoomBar,
} from './components';
import { Tools } from './tools';
import { CartesianScales, Curves, Zoom } from './services';
export class AxisChart extends Chart {
services: any = Object.assign(this.services, {
cartesianScales: CartesianScales,
curves: Curves,
zoom: Zoom,
});
model: ChartModelCartesian = new ChartModelCartesian(this.services);
constructor(holder: Element, chartConfigs: ChartConfig<AxisChartOptions>) {
super(holder, chartConfigs);
}
protected getAxisChartComponents(graphFrameComponents: any[]) {
const isZoomBarEnabled = Tools.getProperty(
this.model.getOptions(),
'zoomBar',
AxisPositions.TOP,
'enabled'
);
const toolbarEnabled = Tools.getProperty(
this.model.getOptions(),
'toolbar',
'enabled'
);
this.services.cartesianScales.determineAxisDuality();
this.services.cartesianScales.findDomainAndRangeAxes(); // need to do this before getMainXAxisPosition()
this.services.cartesianScales.determineOrientation();
const mainXAxisPosition = this.services.cartesianScales.getMainXAxisPosition();
const mainXScaleType = Tools.getProperty(
this.model.getOptions(),
'axes',
mainXAxisPosition,
'scaleType'
);
// @todo - Zoom Bar only supports main axis at BOTTOM axis and time scale for now
const zoomBarEnabled =
isZoomBarEnabled &&
mainXAxisPosition === AxisPositions.BOTTOM &&
mainXScaleType === ScaleTypes.TIME;
// @todo - should check if zoom bar in all axes are locked
const isZoomBarLocked = this.services.zoom.isZoomBarLocked(
AxisPositions.TOP
);
const titleAvailable = !!this.model.getOptions().title;
const titleComponent = {
id: 'title',
components: [new Title(this.model, this.services)],
growth: {
x: LayoutGrowth.STRETCH,
y: LayoutGrowth.FIXED,
},
};
const toolbarComponent = {
id: 'toolbar',
components: [new Toolbar(this.model, this.services)],
growth: {
x: LayoutGrowth.PREFERRED,
y: LayoutGrowth.FIXED,
},
};
const headerComponent = {
id: 'header',
components: [
new LayoutComponent(
this.model,
this.services,
[
// always add title to keep layout correct
titleComponent,
...(toolbarEnabled ? [toolbarComponent] : []),
],
{
direction: LayoutDirection.ROW,
}
),
],
growth: {
x: LayoutGrowth.PREFERRED,
y: LayoutGrowth.FIXED,
},
};
const legendComponent = {
id: 'legend',
components: [new Legend(this.model, this.services)],
growth: {
x: LayoutGrowth.PREFERRED,
y: LayoutGrowth.FIXED,
},
};
// if all zoom bars are locked, no need to add chart brush
if (zoomBarEnabled && !isZoomBarLocked) {
graphFrameComponents.push(
new ChartClip(this.model, this.services),
new ChartBrush(this.model, this.services)
);
}
const graphFrameComponent = {
id: 'graph-frame',
components: graphFrameComponents,
growth: {
x: LayoutGrowth.STRETCH,
y: LayoutGrowth.FIXED,
},
};
const isLegendEnabled =
this.model.getOptions().legend.enabled !== false;
// Decide the position of the legend in reference to the chart
let fullFrameComponentDirection = LayoutDirection.COLUMN;
if (isLegendEnabled) {
const legendPosition = Tools.getProperty(
this.model.getOptions(),
'legend',
'position'
);
if (legendPosition === LegendPositions.LEFT) {
fullFrameComponentDirection = LayoutDirection.ROW;
if (!this.model.getOptions().legend.orientation) {
this.model.getOptions().legend.orientation =
LegendOrientations.VERTICAL;
}
} else if (legendPosition === LegendPositions.RIGHT) {
fullFrameComponentDirection = LayoutDirection.ROW_REVERSE;
if (!this.model.getOptions().legend.orientation) {
this.model.getOptions().legend.orientation =
LegendOrientations.VERTICAL;
}
} else if (legendPosition === LegendPositions.BOTTOM) {
fullFrameComponentDirection = LayoutDirection.COLUMN_REVERSE;
}
}
const legendSpacerComponent = {
id: 'spacer',
components: [new Spacer(this.model, this.services)],
growth: {
x: LayoutGrowth.PREFERRED,
y: LayoutGrowth.FIXED,
},
};
const fullFrameComponent = {
id: 'full-frame',
components: [
new LayoutComponent(
this.model,
this.services,
[
...(isLegendEnabled ? [legendComponent] : []),
...(isLegendEnabled ? [legendSpacerComponent] : []),
graphFrameComponent,
],
{
direction: fullFrameComponentDirection,
}
),
],
growth: {
x: LayoutGrowth.STRETCH,
y: LayoutGrowth.FIXED,
},
};
const zoomBarComponent = {
id: 'zoom-bar',
components: [new ZoomBar(this.model, this.services)],
growth: {
x: LayoutGrowth.PREFERRED,
y: LayoutGrowth.FIXED,
},
};
const topLevelLayoutComponents = [];
// header component is required for either title or toolbar
if (titleAvailable || toolbarEnabled) {
topLevelLayoutComponents.push(headerComponent);
const titleSpacerComponent = {
id: 'spacer',
components: [
new Spacer(
this.model,
this.services,
toolbarEnabled ? { size: 15 } : undefined
),
],
growth: {
x: LayoutGrowth.PREFERRED,
y: LayoutGrowth.FIXED,
},
};
topLevelLayoutComponents.push(titleSpacerComponent);
}
if (zoomBarEnabled) {
topLevelLayoutComponents.push(zoomBarComponent);
}
topLevelLayoutComponents.push(fullFrameComponent);
return [
new AxisChartsTooltip(this.model, this.services),
new LayoutComponent(
this.model,
this.services,
topLevelLayoutComponents,
{
direction: LayoutDirection.COLUMN,
}
),
];
}
}