UNPKG

@hpcc-js/composite

Version:
505 lines (447 loc) 21.9 kB
import { Database, Text, Utility } from "@hpcc-js/common"; import { Button, Input, Select } from "@hpcc-js/form"; import { Border, Grid, Toolbar } from "@hpcc-js/layout"; import { Html, Legend } from "@hpcc-js/other"; import { select as d3Select } from "d3-selection"; import "d3-transition"; import { MultiChart } from "./MultiChart.ts"; import "../src/MegaChart.css"; export class MegaChart extends Border { _chart = new MultiChart(); _toolbar = new Toolbar(); _valueTitle = new Text(); _domainTitle = new Text(); _legend: Legend = new Legend(); _csvButton; _infoButton; _maximizeButton; _legendButton; _chartTypeSelect; _prevLegendPosition; _prevShowToolbar; _1DChartTypes; _2DChartTypes; _NDChartTypes; _anyChartTypes; _allChartTypes; _contentClasses; _dataCount; constructor() { super(); this._tag = "div"; const context = this; this._chart.click = function () { context.click.apply(context, arguments); }; this._chart.dblclick = function () { context.dblclick.apply(context, arguments); }; this._chart.vertex_click = function () { context.vertex_click.apply(context, arguments); }; this._chart.vertex_dblclick = function () { context.vertex_dblclick.apply(context, arguments); }; this._chart.edge_click = function () { context.edge_click.apply(context, arguments); }; this._chart.edge_dblclick = function () { context.edge_dblclick.apply(context, arguments); }; } toolbarWidgets(_?) { if (!arguments.length) return this._toolbar.widgets(); this._toolbar.widgets(_); return this; } chartTypeDefaults(_?) { if (!arguments.length) return this._chart.chartTypeDefaults(); this._chart.chartTypeDefaults(_); return this; } chartTypeProperties(_?) { if (!arguments.length) return this._chart.chartTypeProperties(); this._chart.chartTypeProperties(_); return this; } fields(): Database.Field[]; fields(_: Database.Field[]): this; fields(_?: Database.Field[]): Database.Field[] | this { if (!arguments.length) return this._chart.fields(); this._chart.fields(_); return this; } columns(): string[]; columns(_: string[], asDefault?: boolean): this; columns(_?: string[], asDefault?: boolean): string[] | this { if (!arguments.length) return this._chart.columns(); this._chart.columns(_, asDefault); return this; } data(_?) { if (!arguments.length) return this._chart.data(); this._chart.data(_); return this; } downloadCSV() { Utility.downloadString("CSV", this._chart.export("CSV")); return this; } enter(domNode, element) { super.enter(domNode, element); const context = this; this.topShrinkWrap(false).topPercentage(0).topSize(30); this._dataCount = new Html() .classed({ "composite_MegaChart-dataCount": true }) .id(this.id() + "_dataCount") .html('<span class="MegaChart-dataCount-label">Count:</span>&nbsp;<span class="MegaChart-dataCount-value">' + (this.data() ? this.data().length : "0") + "</span>") .overflowX("visible") .overflowY("visible") ; this._csvButton = new Button() .classed({ "composite_MegaChart-CSV": true }) .id(this.id() + "_csv") .value("CSV") ; this._csvButton.click = function (a) { context.downloadCSV(); }; this._infoButton = new Button() .classed({ "composite_MegaChart-Info": true }) .id(this.id() + "_info") .value(this.infoIcon()) ; this._maximizeButton = new Button() .classed({ "composite_MegaChart-Maximize": true }) .id(this.id() + "_maximize") .value("\uf2d0") ; this._maximizeButton.click = function (buttonWidget) { const target = context.target() as any; let node = target; const isMaximized = d3Select(target).classed("__hpccisMaximized"); // Find the layout_Grid ancestor const parentGrid = context.locateAncestor("layout_Grid"); if (parentGrid) { node = parentGrid.element().node(); } else { node = document.body; } const targetElement = d3Select(context.target()) as any; if (isMaximized) { // Restore from maximized to natural size/position const targetParentBox = target.parentElement.getBoundingClientRect(); const targetPaddingTop = parseInt(getComputedStyle(target, null).getPropertyValue("padding-top").replace("px", "")); const targetPaddingLeft = parseInt(getComputedStyle(target, null).getPropertyValue("padding-left").replace("px", "")); const targetPaddingRight = parseInt(getComputedStyle(target, null).getPropertyValue("padding-right").replace("px", "")); const targetPaddingBottom = parseInt(getComputedStyle(target, null).getPropertyValue("padding-bottom").replace("px", "")); context.contentDiv.style("opacity", 0).transition(100); targetElement.transition()// .duration(3000) .style("top", targetParentBox.top + "px") .style("left", targetParentBox.left + "px") .style("width", (targetParentBox.width - targetPaddingLeft - targetPaddingRight) + "px") .style("height", (targetParentBox.height - targetPaddingTop - targetPaddingBottom) + "px") .each("end", function () { targetElement.style("position", target.__old_position); targetElement.style("z-index", target.__old_zindex); targetElement.style("background-color", target.__old_backgroundColor); targetElement.style("box-shadow", target.__old_boxshadow); context .resize({ width: targetParentBox.width - targetPaddingLeft - targetPaddingRight, height: targetParentBox.height - targetPaddingTop - targetPaddingBottom }) .render(function () { context.contentDiv.transition() .style("opacity", 1); }); buttonWidget.value("\uf2d0").render(); }); } else { // Maximize this MegaChart target.__old_position = target.style.position; target.__old_zindex = target.style.zIndex; target.__old_boxshadow = target.style.boxShadow; target.__old_backgroundColor = context.element().style("background-color"); const grid = d3Select(node).datum() as Grid; const gridTarget = grid.target(); const gridBox = grid ? gridTarget.getBoundingClientRect() : node.getBoundingClientRect(); const gridPaddingTop = parseInt(getComputedStyle(gridTarget, null).getPropertyValue("padding-top").replace("px", "")); const gridPaddingLeft = parseInt(getComputedStyle(gridTarget, null).getPropertyValue("padding-left").replace("px", "")); const gridPaddingRight = parseInt(getComputedStyle(gridTarget, null).getPropertyValue("padding-right").replace("px", "")); const gridPaddingBottom = parseInt(getComputedStyle(gridTarget, null).getPropertyValue("padding-bottom").replace("px", "")); context.contentDiv.style("opacity", 0).transition(100); targetElement .style("position", "fixed") .style("z-index", 999999) .style("box-shadow", "0 8px 8px 0 rgba(0,0,0,.14),0 12px 4px -8px rgba(0,0,0,.2),0 4px 20px 0 rgba(0,0,0,.12)") .style("background-color", target.__old_backgroundColor) .transition()// .duration(3000) .style("top", (gridBox.top + gridPaddingTop) + "px") .style("left", (gridBox.left + gridPaddingLeft) + "px") .style("width", (gridBox.width - gridPaddingLeft - gridPaddingRight) + "px") .style("height", (gridBox.height - gridPaddingTop - gridPaddingBottom) + "px") .each("end", function () { targetElement.style("background-color", context.maximizedBackgroundColor()); context .resize({ width: (gridBox.width - gridPaddingLeft - gridPaddingRight), height: (gridBox.height - gridPaddingTop - gridPaddingBottom) }) .render(function () { context.contentDiv.transition() .style("opacity", 1); }); buttonWidget.value("\uf2d1").render(); }); } d3Select(target).classed("__hpccisMaximized", !isMaximized); }; this._legendButton = new Input() .classed({ "composite_MegaChart-legend": true }) .id(this.id() + "_legend") .type("checkbox") .inlineLabel("Legend: ") ; this._legendButton.click = function (a) { context.render(); }; this._chartTypeSelect = new Select() .classed({ "composite_MegaChart-chartType": true }) .id(this.id() + "_chartType") .selectOptions(this._allChartTypes.map(function (a) { return [a.id, a.display]; })) .value(this.chartType()) ; this._chartTypeSelect.change = function (a) { context.chartType(a.value()).render(); }; this.setContent("center", this._chart); this._legend .targetWidget(this._chart) .orientation(["top", "bottom"].indexOf(this.legendPosition()) !== -1 ? "horizontal" : "vertical") .fixedSize(true) ; this._prevLegendPosition = this.legendPosition(); if (this.valueAxisTitle()) { this.setContent("left", this._valueTitle.rotation(-90)).leftShrinkWrap(true); } if (this.domainAxisTitle()) { this.setContent("bottom", this._domainTitle).bottomShrinkWrap(true); } if (this.legendPosition() !== "none") { this.setContent(this.legendPosition(), this._legend)[this.legendPosition() + "ShrinkWrap"](true); } } update(domNode, element) { function showHideButton(twArr2, button, show) { if (show && twArr2.indexOf(button) === -1) { twArr2.push(button); } else if (!show) { const idx = twArr2.indexOf(button); if (idx >= 0) { twArr2.splice(idx, 1); } } } if (this._chart && typeof this._chart.hideRowOnLegendClick === "function") { this._chart.hideRowOnLegendClick(this.hideRowOnLegendClick()); } this._dataCount.html('<span class="MegaChart-dataCount-label">Count:</span>&nbsp;<span class="MegaChart-dataCount-value">' + (this.data() ? this.data().length : "0") + "</span>"); this._chartTypeSelect.value(this.chartType()); const twArr = this.toolbarWidgets(); showHideButton(twArr, this._csvButton, this.showCSV()); showHideButton(twArr, this._maximizeButton, this.showMaximize()); showHideButton(twArr, this._legendButton, this.toolbarShowLegend()); showHideButton(twArr, this._chartTypeSelect, this.showChartSelect()); showHideButton(twArr, this._infoButton, this.showInfoButton()); showHideButton(twArr, this._dataCount, this.showCount()); this.toolbarWidgets(twArr); if (this._prevShowToolbar !== this.showToolbar()) { this.setContent("top", this.showToolbar() ? this._toolbar : null); this._prevShowToolbar = this.showToolbar(); } // TODO: Proxy + themes not working... this._toolbar .fontSize(this.titleFontSize()) .fontColor(this.titleFontColor()) .fontFamily(this.titleFontFamily()) .fontBold(this.titleFontBold()) .backgroundColor(this.titleBackgroundColor()) ; this._chart .data(this.data()); if (this._chart.chartType() !== this.chartType()) { this._chart.chartType(this.chartType()); } let legendPosition = this.legendPosition(); if (this.toolbarShowLegend() && !this._legendButton.checked()) { legendPosition = "none"; } if (this._prevLegendPosition !== legendPosition) { if (this._prevLegendPosition !== "none") { this.clearContent(this._prevLegendPosition); } this._prevLegendPosition = legendPosition; if (legendPosition !== "none") { this._legend = new Legend().targetWidget(this.getContent("center").fixedSize(true)); this.setContent(legendPosition, this._legend); this._legend.orientation(["top", "bottom"].indexOf(legendPosition) !== -1 ? "horizontal" : "vertical"); } } this._contentClasses = this.getContentClasses(); if (this.valueAxisTitle() && this._contentClasses.left !== "common_Text") { if (legendPosition !== "left") { this.setContent("left", this._valueTitle.rotation(-90)); } } if (this.domainAxisTitle() && this._contentClasses.bottom !== "common_Text") { if (legendPosition !== "bottom") { this.setContent("bottom", this._domainTitle).bottomShrinkWrap(true); } } this._legend.dataFamily(this._chart.getChartDataFamily()); super.update(domNode, element); } exit(domNode, element) { super.exit(domNode, element); } getContentClasses() { const obj: any = {}; const t = this.getContent("top"); const r = this.getContent("right"); const b = this.getContent("bottom"); const l = this.getContent("left"); obj.top = t !== null ? t.classID() : undefined; obj.right = r !== null ? r.classID() : undefined; obj.bottom = b !== null ? b.classID() : undefined; obj.left = l !== null ? l.classID() : undefined; return obj; } serializeState() { const state: any = { title: this.title(), data: this.data() }; const chart = this.chart(); if (chart) { if (chart.serializeState) { state.chart = chart.serializeState(); delete state.chart.data; } } return state; } deserializeState(state) { if (state) { this .title(state.title) .data(state.data) ; const chart = this.chart(); if (chart && state.chart) { if (chart.serializeState) { chart.deserializeState(state.chart); } } } return this; } // Events --- click(row, column, selected) { } dblclick(row, column, selected) { } vertex_click(row, col, sel, more) { if (more && more.vertex) { // console.log("Vertex click: " + more.vertex.id()); } } vertex_dblclick(row, col, sel, more) { if (more && more.vertex) { // console.log("Vertex double click: " + more.vertex.id()); } } edge_click(row, col, sel, more) { if (more && more.edge) { // console.log("Edge click: " + more.edge.id()); } } edge_dblclick(row, col, sel, more) { if (more && more.edge) { // console.log("Edge double click: " + more.edge.id()); } } hideRowOnLegendClick: { (): boolean; (_: boolean): MegaChart }; hideRowOnLegendClick_exists: () => boolean; showToolbar: { (): boolean; (_: boolean): MegaChart }; showToolbar_exists: () => boolean; titleFontSize: { (): number; (_: number): MegaChart }; titleFontSize_exists: () => boolean; titleFontColor: { (): string; (_: string): MegaChart }; titleFontColor_exists: () => boolean; titleFontFamily: { (): string; (_: string): MegaChart }; titleFontFamily_exists: () => boolean; titleFontBold: { (): boolean; (_: boolean): MegaChart }; titleFontBold_exists: () => boolean; titleBackgroundColor: { (): string; (_: string): MegaChart }; titleBackgroundColor_exists: () => boolean; maximizedBackgroundColor: { (): string; (_: string): MegaChart }; maximizedBackgroundColor_exists: () => boolean; showChartSelect: { (): boolean; (_: boolean): MegaChart }; showChartSelect_exists: () => boolean; showCSV: { (): boolean; (_: boolean): MegaChart }; showCSV_exists: () => boolean; showCount: { (): boolean; (_: boolean): MegaChart }; showCount_exists: () => boolean; showMaximize: { (): boolean; (_: boolean): MegaChart }; showMaximize_exists: () => boolean; toolbarShowLegend: { (): boolean; (_: boolean): MegaChart }; toolbarShowLegend_exists: () => boolean; showInfoButton: { (): boolean; (_: boolean): MegaChart }; showInfoButton_exists: () => boolean; infoIcon: { (): string; (_: string): MegaChart }; infoIcon_exists: () => boolean; legendPosition: { (): string; (_: string): MegaChart }; legendPosition_exists: () => boolean; title: { (): string; (_: string): MegaChart }; title_exists: () => boolean; domainAxisTitle: { (): string; (_: string): MegaChart }; domainAxisTitle_exists: () => boolean; valueAxisTitle: { (): string; (_: string): MegaChart }; valueAxisTitle_exists: () => boolean; chartType: { (): string; (_: string): MegaChart }; chartType_exists: () => boolean; chart: { (): any; (_: any): MegaChart }; chart_exists: () => boolean; } MegaChart.prototype._class += " composite_MegaChart"; MegaChart.prototype._1DChartTypes = MultiChart.prototype._1DChartTypes; MegaChart.prototype._2DChartTypes = MultiChart.prototype._2DChartTypes; MegaChart.prototype._NDChartTypes = MultiChart.prototype._NDChartTypes; MegaChart.prototype._anyChartTypes = MultiChart.prototype._anyChartTypes; MegaChart.prototype._allChartTypes = MultiChart.prototype._allChartTypes; MegaChart.prototype.publishReset(); MegaChart.prototype.publish("hideRowOnLegendClick", false, "boolean", "Enable/Disable hiding row on legend clicks", null, { tags: ["Basic"] }); MegaChart.prototype.publish("showToolbar", true, "boolean", "Enable/Disable Toolbar widget", null, { tags: ["Basic"] }); MegaChart.prototype.publishProxy("title", "_toolbar", "title"); MegaChart.prototype.publish("ddlParamsFormat", "", "string", "DDL Param Format '{fname}, {lname}'", null, { tags: ["Advanced"], optional: true }); MegaChart.prototype.publish("titleFontSize", null, "number", "Title Font Size (px)", null, { tags: ["Advanced"], optional: true }); MegaChart.prototype.publish("titleFontColor", null, "html-color", "Title Font Color", null, { tags: ["Advanced"], optional: true }); MegaChart.prototype.publish("titleFontFamily", null, "string", "Title Font Family", null, { tags: ["Advanced"], optional: true }); MegaChart.prototype.publish("titleFontBold", true, "boolean", "Enable Bold Title Font", null, { tags: ["Advanced"], optional: true }); MegaChart.prototype.publish("titleBackgroundColor", null, "html-color", "Background Color", null, { tags: ["Intermediate"], optional: true }); MegaChart.prototype.publish("maximizedBackgroundColor", "#FFFFFF", "html-color", "Background Color while maximized", null, { tags: ["Intermediate"], optional: true }); MegaChart.prototype.publish("showChartSelect", true, "boolean", "Show/Hide the chartType dropdown in the toolbar", null, { tags: ["Basic"] }); MegaChart.prototype.publish("showCSV", true, "boolean", "Show/Hide CSV button", null, { tags: ["Basic"] }); MegaChart.prototype.publish("showCount", false, "boolean", "Show/Hide Data Count", null, { tags: ["Basic"] }); MegaChart.prototype.publish("showMaximize", false, "boolean", "Show/Hide Maximize button", null, { tags: ["Basic"] }); MegaChart.prototype.publish("toolbarShowLegend", false, "boolean", "Show/Hide Legend button", null, { tags: ["Basic"] }); MegaChart.prototype.publish("showInfoButton", false, "boolean", "Show/Hide Info button in toolbar", null, { tags: ["Basic"] }); MegaChart.prototype.publish("infoIcon", "\uf05a", "string", "Help Icon", null, { tags: ["Basic"] }); MegaChart.prototype.publish("legendPosition", "none", "set", "Position of the Legend widget", ["none", "top", "right", "bottom", "left"], { tags: ["Basic"] }); MegaChart.prototype.publishProxy("legendFormat", "_legend", "rainbowFormat"); MegaChart.prototype.publishProxy("legendBins", "_legend", "rainbowBins"); MegaChart.prototype.publishProxy("domainAxisTitle", "_domainTitle", "text"); MegaChart.prototype.publishProxy("valueAxisTitle", "_valueTitle", "text"); MegaChart.prototype.publishProxy("chartType", "_chart", "chartType"); MegaChart.prototype.publishProxy("chart", "_chart", "chart");