/** * Created by michaelbessey on 10/15/16. */ // declare let d3; import * as d3 from "d3"; import {createAxis} from "../mmviz-common"; import {AxisLocationEnum} from "../mmviz-layout/index"; import {ScaleTypeEnum} from "../mmviz-layout/scale_container"; export class AxisComponentSvg { ticks; tickValues; tickSize; tickPadding; tickFormat; label; displayLabel; useDefaultFormatConfig; constructor(public parentSelector: string, public selector: string = ".axis", label: string = null) { this.label = label; this.displayLabel = (label !== undefined && label !== null && label !== ""); this.tickPadding = 5; } set config(c){ if(c){ if(c.ticks){ this.ticks = c.ticks; } else if(c.tickValues){ this.tickValues = c.tickValues; } if(c.tickSize){ this.tickSize = c.tickSize; } if(c.tickPadding){ this.tickPadding = c.tickPadding; } if(c.tickFormat){ this.tickFormat = c.tickFormat; } } } updateView(parent, viewModel): AxisComponentSvg { let axis, axisConfig: any = {}, view = parent.select("g" + this.selector), x = viewModel.x, y = viewModel.y, translation = `translate(${x}, ${y})`, labelViewModel = viewModel.labelViewModel; axisConfig.ticks = (viewModel.ticks !== undefined) ? viewModel.ticks : this.ticks; axisConfig.tickValues = (viewModel.tickValues !== undefined) ? viewModel.tickValues : this.tickValues; axisConfig.tickSize = (viewModel.tickSize !== undefined) ? viewModel.tickSize : this.tickSize; axisConfig.tickPadding = (viewModel.tickPadding !== undefined) ? viewModel.tickPadding : this.tickPadding; axisConfig.tickFormat = (viewModel.tickFormat !== undefined) ? viewModel.tickFormat : this.tickFormat; axis = createAxis(viewModel.locationEnum, viewModel.scale, axisConfig); if (view.empty()) { // Create X axis parent.append("g") .attr("class", this.selector.replace(/^\./, "") + " axis") .attr("transform", translation) .call(axis); } else { view.attr("transform", translation) .call(axis); } if (labelViewModel && this.displayLabel){ this.updateLabelView(parent, labelViewModel, viewModel.locationEnum); } return this; } private updateLabelView(parent, viewModel, locationEnum: AxisLocationEnum){ let selector = this.getLabelSelector(locationEnum), labelGroup = parent.select("g" + selector), label = this.label, x = viewModel.x, y = viewModel.y, rotation = viewModel.rotation; if (labelGroup.empty()) { labelGroup = parent.append("g").attr("class", "axis-label " + selector.replace(/^\./, "")); } else { labelGroup.selectAll("*").remove(); } labelGroup.append("text") .attr("text-anchor", viewModel.textAnchor) .attr("transform", `translate(${x}, ${y}) rotate(${rotation})`) .text(label); } private getLabelSelector(locationEnum: AxisLocationEnum): string { let selector = ".axis-label"; switch (locationEnum) { case AxisLocationEnum.TOP: selector = ".axis-top-label"; break; case AxisLocationEnum.RIGHT: selector = ".axis-right-label"; break; case AxisLocationEnum.BOTTOM: selector = ".axis-bottom-label"; break; case AxisLocationEnum.LEFT: selector = ".axis-left-label"; break; default: break; } return selector; } get axisLabelBBoxs(){ let axisLabelBBox, axisLabelBBoxs = []; d3.select(this.parentSelector).select("g" + this.selector).selectAll("text").each(function(d, i) { axisLabelBBox = this.getBBox(); axisLabelBBoxs.push({ d: d, i: i, bbox: axisLabelBBox }); }); return axisLabelBBoxs; } get maxWidthAxisLabel(){ let maxWidth = 0, maxAxisLabelBBox, axisLabelBBox, axisLabelBBoxs = this.axisLabelBBoxs; for(let i = 0; i < axisLabelBBoxs.length; i++){ axisLabelBBox = axisLabelBBoxs[i]; if(axisLabelBBox.bbox.width > maxWidth){ maxAxisLabelBBox = axisLabelBBox; maxWidth = axisLabelBBox.bbox.width; } } return maxAxisLabelBBox; } get maxHeightAxisLabel(){ let maxHeight = 0, maxAxisLabelBBox, axisLabelBBox, axisLabelBBoxs = this.axisLabelBBoxs; for(let i = 0; i < axisLabelBBoxs.length; i++){ axisLabelBBox = axisLabelBBoxs[i]; if(axisLabelBBox.bbox.height > maxHeight){ maxAxisLabelBBox = axisLabelBBox; maxHeight = axisLabelBBox.bbox.height; } } return maxAxisLabelBBox; } }