/** * Created by michaelbessey on 10/15/16. */ // declare let d3; import * as d3 from "d3"; import {Component} from "./component"; export class ScatterComponentSvg extends Component { shapeOrderArray; constructor(parentSelector: string, selector: string = ".points") { super(parentSelector, selector); this.shapeOrderArray = ["circle", "rect", "triangle"]; } /** * Add circle shaped points to the pointGroup mapped according to data in the dataArray. * @param dataArray - data to map to circle points * @param keyMap - maps each data in the dataArray to a unique key * @param pointGroup - SVG group to contain the point elements */ addCirclePoints(dataArray, keyMap, pointGroup){ let points, shape = "circle"; pointGroup.selectAll(shape) .data(dataArray, keyMap) .enter() .append(shape) .attr("class", (d, i) => { return "point " + d.categoryAttr; }); pointGroup.selectAll(shape) .data(dataArray, keyMap) .exit().remove(); points = pointGroup.selectAll(shape) .data(dataArray, keyMap) .attr("cx", (d) => { return d.x0; }) .attr("cy", (d) => { return d.y0; }) .attr("r", (d) => { return d.radius.value; }) .attr("fill", (d) => { return d.color.value; }); if (this.doAnimate){ points .transition() .duration(this.animationDuration) .attr("cx", (d) => { return d.x; }) .attr("cy", (d) => { return d.y; }); } else { points .attr("cx", (d) => { return d.x; }) .attr("cy", (d) => { return d.y; }); } return points; } /** * Add rectangle shaped points to the pointGroup mapped according to data in the dataArray. * @param dataArray - data to map to rectangle points * @param keyMap - maps each data in the dataArray to a unique key * @param pointGroup - SVG group to contain the point elements */ addRectanglePoints(dataArray, keyMap, pointGroup){ let points, shape = "rect"; pointGroup.selectAll(shape) .data(dataArray, keyMap) .enter() .append(shape) .attr("class", (d, i) => { return "point " + d.categoryAttr; }); pointGroup.selectAll(shape) .data(dataArray, keyMap) .exit().remove(); points = pointGroup.selectAll(shape) .data(dataArray, keyMap) .attr("x", (d) => { return d.x0; }) .attr("y", (d) => { return d.y0; }) .attr("width", (d) => { return 2 * d.radius.value; }) .attr("height", (d) => { return 2 * d.radius.value; }) .attr("fill", (d) => { return d.color.value; }); if (this.doAnimate){ points .transition() .duration(this.animationDuration) .attr("x", (d) => { return d.x - d.radius.value; }) .attr("y", (d) => { return d.y - d.radius.value; }); } else { points .attr("x", (d) => { return d.x - d.radius.value; }) .attr("y", (d) => { return d.y - d.radius.value; }); } return points; } /** * Add triangle shaped points to the pointGroup mapped according to data in the dataArray. * @param dataArray - data to map to triangle points * @param keyMap - maps each data in the dataArray to a unique key * @param pointGroup - SVG group to contain the point elements */ addTrianglePoints(dataArray, keyMap, pointGroup){ let points, shape = "polyline"; pointGroup.selectAll(shape) .data(dataArray, keyMap) .enter() .append(shape) .attr("points", "0 -1 0.75 0 -0.75 0") .attr("class", (d, i) => { return "point " + d.categoryAttr; }); pointGroup.selectAll(shape) .data(dataArray, keyMap) .exit().remove(); points = pointGroup.selectAll(shape) .data(dataArray, keyMap) .attr("transform", (d) => { return `translate(${d.x} ${d.y + d.radius.value}) scale(${d.radius.value * 2})`; }) .attr("fill", (d) => { return d.color.value; }); return points; } updateView(parent, viewModel): ScatterComponentSvg { let pointGroup = parent.select("g" + this.selector), points; if (pointGroup.empty()) { pointGroup = parent.append("g").attr("class", super.getClassName()); } const circleDataArray = viewModel.dataArray.filter((d) => d.shape.value === "circle" ), rectDataArray = viewModel.dataArray.filter((d) => d.shape.value === "rect" ), triangleDataArray = viewModel.dataArray.filter((d) => d.shape.value === "triangle" ) ; for (let shapeOrder of this.shapeOrderArray){ if (shapeOrder === "circle" && circleDataArray){ points = this.addCirclePoints(circleDataArray, viewModel.keyMap, pointGroup); this.addBehavior(points, "mouseover"); this.addBehavior(points, "mouseout"); this.addBehavior(points, "click"); } else if (shapeOrder === "rect" && rectDataArray){ points = this.addRectanglePoints(rectDataArray, viewModel.keyMap, pointGroup); this.addBehavior(points, "mouseover"); this.addBehavior(points, "mouseout"); this.addBehavior(points, "click"); } else if (shapeOrder === "triangle" && triangleDataArray){ points = this.addTrianglePoints(triangleDataArray, viewModel.keyMap, pointGroup); this.addBehavior(points, "mouseover"); this.addBehavior(points, "mouseout"); this.addBehavior(points, "click"); } } return this; } getEventPayload(d, i: number){ let payload: any = super.getEventPayload(d, i); payload.location = {x: d.x, y: d.y}; return payload; } }