Visual Console Client: added the color cloud item

Former-commit-id: 2a3f0675b1ba5dd067b0f0dae70c8e19dd68f89c
This commit is contained in:
Alejandro Gallardo Escobar 2019-02-22 14:48:09 +01:00
parent f7eeb2478e
commit 86a7981331
2 changed files with 178 additions and 0 deletions

View File

@ -0,0 +1,52 @@
import ColorCloud, { colorCloudPropsDecoder } from "./ColorCloud";
const genericRawProps = {
id: 1,
type: 20, // COlor cloud item = 20
label: null,
isLinkEnabled: false,
isOnTop: false,
parentId: null,
aclGroupId: null
};
const positionRawProps = {
x: 100,
y: 50
};
const sizeRawProps = {
width: 100,
height: 100
};
const colorCloudProps = {
color: "rgb(100, 50, 245)"
};
const linkedModuleProps = {
// Agent props.
agentId: null,
agentName: null,
// Module props.
moduleId: null,
moduleName: null
};
describe("Color cloud item", () => {
const groupInstance = new ColorCloud(
colorCloudPropsDecoder({
...genericRawProps,
...positionRawProps,
...sizeRawProps,
...linkedModuleProps,
...colorCloudProps
})
);
it("should have the color-cloud class", () => {
expect(
groupInstance.elementRef.getElementsByClassName("color-cloud").length
).toBeGreaterThan(0);
});
});

View File

@ -0,0 +1,126 @@
import {
WithModuleProps,
LinkedVisualConsoleProps,
UnknownObject
} from "../types";
import { modulePropsDecoder, linkedVCPropsDecoder } from "../lib";
import VisualConsoleItem, {
VisualConsoleItemProps,
itemBasePropsDecoder,
VisualConsoleItemType
} from "../VisualConsoleItem";
export type ColorCloudProps = {
type: VisualConsoleItemType.COLOR_CLOUD;
color: string;
// TODO: Add the rest of the color cloud values?
} & VisualConsoleItemProps &
WithModuleProps &
LinkedVisualConsoleProps;
/**
* Build a valid typed object from a raw object.
* This will allow us to ensure the type safety.
*
* @param data Raw object.
* @return An object representing the static graph props.
* @throws Will throw a TypeError if some property
* is missing from the raw object or have an invalid type.
*/
export function colorCloudPropsDecoder(
data: UnknownObject
): ColorCloudProps | never {
// TODO: Validate the color.
if (typeof data.color !== "string" || data.color.length === 0) {
throw new TypeError("invalid color.");
}
return {
...itemBasePropsDecoder(data), // Object spread. It will merge the properties of the two objects.
type: VisualConsoleItemType.COLOR_CLOUD,
color: data.color,
...modulePropsDecoder(data), // Object spread. It will merge the properties of the two objects.
...linkedVCPropsDecoder(data) // Object spread. It will merge the properties of the two objects.
};
}
const svgNS = "http://www.w3.org/2000/svg";
export default class ColorCloud extends VisualConsoleItem<ColorCloudProps> {
createDomElement(): HTMLElement {
const container: HTMLDivElement = document.createElement("div");
container.className = "color-cloud";
// Add the SVG.
container.append(this.createSvgElement());
return container;
}
createSvgElement(): SVGSVGElement {
const gradientId = `grad_${this.props.id}`;
// SVG container.
const svg = document.createElementNS(svgNS, "svg");
// Resize SVG. Use only the width, cause this element only needs a diameter.
svg.setAttribute("width", `${this.props.width}px`);
svg.setAttribute("height", `${this.props.width}px`);
// Defs.
const defs = document.createElementNS(svgNS, "defs");
// Radial gradient.
const radialGradient = document.createElementNS(svgNS, "radialGradient");
radialGradient.setAttribute("id", gradientId);
radialGradient.setAttribute("cx", "50%");
radialGradient.setAttribute("cy", "50%");
radialGradient.setAttribute("r", "50%");
radialGradient.setAttribute("fx", "50%");
radialGradient.setAttribute("fy", "50%");
// Stops.
const stop0 = document.createElementNS(svgNS, "stop");
stop0.setAttribute("offset", "0%");
stop0.setAttribute(
"style",
`stop-color:${this.props.color};stop-opacity:0.9`
);
const stop100 = document.createElementNS(svgNS, "stop");
stop100.setAttribute("offset", "100%");
stop100.setAttribute(
"style",
`stop-color:${this.props.color};stop-opacity:0`
);
// Circle.
const circle = document.createElementNS(svgNS, "circle");
circle.setAttribute("fill", `url(#${gradientId})`);
circle.setAttribute("cx", "50%");
circle.setAttribute("cy", "50%");
circle.setAttribute("r", "50%");
// Append elements.
radialGradient.append(stop0, stop100);
defs.append(radialGradient);
svg.append(defs, circle);
return svg;
}
/**
* @override VisualConsoleItem.resize
* To resize the item.
* @param width Width.
* @param height Height.
*/
resize(width: number, height: number): void {
// Resize parent. Use only the width, cause this element only needs a diameter.
super.resize(width, width);
// Get SVG element.
const svgElement = this.elementRef.getElementsByTagName("svg").item(0);
if (svgElement === null) return;
// Resize SVG. Use only the width, cause this element only needs a diameter.
svgElement.setAttribute("width", `${this.props.width}px`);
svgElement.setAttribute("height", `${this.props.width}px`);
}
}