/** * Created by michaelbessey on 10/15/16. */ // declare let d3; // import {select as d3_select} from 'd3-select'; import * as d3 from "d3"; import {ChartDrawArea, Theme} from "../mmviz-common/index"; import {ChartWidthSizeEnum, getChartWidthSize} from "../mmviz-common/util"; export class ChartView { //padding top: number; right: number; bottom: number; left: number; constructor(public selector) { this.top = 0; this.right = 0; this.bottom = 0; this.left = 0; } get view(){ return d3.select(this.selector); } addContentTypeClass(contentTypeClass: string){ this.content.classed(contentTypeClass, true); } showLegend() { this.content.classed('content-legend',true); this.legends.classed('legends-open',true); } hideLegend() { this.content.classed('content-legend',false); this.legends.classed('legends-open',false); } syncViewBoxDimension(){ let stageDimension = this.stageDimension; this.viewBox = {x: 0, y: 0, width: stageDimension.width, height: stageDimension.height}; } get isSmallViewBox(){ let drawArea = this.drawArea, viewBox = this.viewBox, viewBoxArea = (viewBox.width - viewBox.x) * (viewBox.height - viewBox.y); return drawArea.area > viewBoxArea; } syncSmallViewBox(){ if(this.isSmallViewBox){ this.syncViewBoxDimension(); } } computeTextLength(text: string){ let length, stageDimension = this.stageDimension, textElement = this.stage .append("text") .attr("x", stageDimension.width) .attr("y", stageDimension.height) .text(text); length = textElement.node().getComputedTextLength(); textElement.remove(); return length; } computeTextBBox(text: string){ let bbox, stageDimension = this.stageDimension, textElement = this.stage .append("text") .attr("x", stageDimension.width) .attr("y", stageDimension.height) .text(text); bbox = textElement.node().getBBox(); textElement.remove(); return bbox; } set contentAspectRatio(ratio){ //ratio of height to width var contentWidth = this.content.node().getBoundingClientRect().width; this.content.style('height', `${contentWidth * ratio}px`); } set padding(p){ this.top = (p.top !== undefined) ? p.top : this.top; this.right = (p.right !== undefined) ? p.right : this.right; this.bottom = (p.bottom !== undefined) ? p.bottom : this.bottom; this.left = (p.left !== undefined) ? p.left : this.left; } get padding(){ return { top: this.top, right: this.right, left: this.left, bottom: this.bottom }; } set contentDimensions(dim){ if(dim.width){ this.content.style("width", dim.width + "px"); } if(dim.height){ this.content.style("height", dim.height + "px"); } } set viewBox(vBox){ this.stage.attr("viewBox", `${vBox.x} ${vBox.y} ${vBox.width} ${vBox.height}`); } get viewBox(){ let viewBoxStr = this.stage.attr("viewBox"), viewBoxArray = viewBoxStr.split(' '); return { x: viewBoxArray[0], y: viewBoxArray[1], width: viewBoxArray[2], height: viewBoxArray[3] }; } set preserveAspectRatio(aspectRatio){ if(!aspectRatio.scaling){ aspectRatio.scaling = "meet"; } this.stage.attr("preserveAspectRatio", `${aspectRatio.alignment} ${aspectRatio.scaling}`); } get content() { return this.view.select(".chart-content"); } get stage() { return this.view.select("svg"); } get main() { return this.view.select(".chart-main"); } get dimension() { let dim, v = this.view; if(v.size() > 0){ dim = v.node().getBoundingClientRect(); } return dim; } get stageDimension() { let sDim, s = this.stage; if(s.size() > 0){ sDim = s.node().getBoundingClientRect(); } return sDim; } get drawArea(){ let drawArea, sDim = this.stageDimension; if(sDim){ drawArea = new ChartDrawArea(sDim, this.padding); } return drawArea; } get legends() { return this.view.select(".chart-legends"); } get legendsContainer() { return this.view.select(".chart-legend-container"); } get legendColor() { return this.view.select(".chart-legends .chart-legend-color"); } setLegendItemState(legend, valueattr, state){ let isOff = (state === "off"); if(legend === "color"){ this.legendColor.select("." + valueattr).classed("legend-item-off", isOff); } } get legendFill() { return this.view.select(".chart-legends .chart-legend-fill"); } get legendArea() { return this.view.select(".chart-legends .chart-legend-area"); } get details() { return this.view.select(".chart-details"); } get annotation(){ return this.view.select(".chart-annotation"); } applyChartAnnotation(domNode){ this.annotation.node().innerHTML = domNode; } get isViewable() { return (this.drawArea !== undefined && this.drawArea.drawArea > 0); } get widthSize() : ChartWidthSizeEnum { let width = this.stageDimension.width; return getChartWidthSize(width); } applyResponsiveBehavior(){ let chartWidthSize = this.widthSize, main = this.main; switch(chartWidthSize){ case ChartWidthSizeEnum.SMALL: main.classed("chart-small", true); main.classed("chart-medium", false); main.classed("chart-large", false); break; case ChartWidthSizeEnum.MEDIUM: main.classed("chart-small", false); main.classed("chart-medium", true); main.classed("chart-large", false); break; case ChartWidthSizeEnum.LARGE: main.classed("chart-small", false); main.classed("chart-medium", false); main.classed("chart-large", true); break; default: main.classed("chart-small", false); main.classed("chart-medium", false); main.classed("chart-large", false); break; } } }