Skip to content
This repository has been archived by the owner on Jan 29, 2021. It is now read-only.

Commit

Permalink
Fix: selection in gantt chart is not surrounding event click(fixes #1…
Browse files Browse the repository at this point in the history
…70) (#219)
  • Loading branch information
AshishMotanamGurunadham authored Jun 3, 2020
1 parent 3122b18 commit 83ff51a
Show file tree
Hide file tree
Showing 7 changed files with 22,353 additions and 22,201 deletions.
44,396 changes: 22,214 additions & 22,182 deletions package-lock.json

Large diffs are not rendered by default.

44 changes: 43 additions & 1 deletion src/main/js/controls/Gantt/helpers/datapointHelpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { Shape } from "../../../core";
import { getDefaultSVGProps } from "../../../core/Shape";
import { getXAxisXPosition } from "../../../helpers/axis";
import constants, { SHAPES } from "../../../helpers/constants";
import { getSVGObject } from "../../../helpers/shapeSVG";
import { getSVGObjectForEvent, getSVGObject } from "../../../helpers/shapeSVG";
import styles from "../../../helpers/styles";
import utils from "../../../helpers/utils";
import { getXAxisYPosition } from "./creationHelpers";
Expand Down Expand Up @@ -82,6 +82,48 @@ export const renderSelectionPath = (scale, config, path, dataPoint, index) =>
)
);

/**
* Renders the circle svg element for event which shows up when clicked on the data point.
* It is hidden by default and toggled visible onClick.
*
* @param {object} scale - d3 scale for Graph
* @param {object} config - Graph config object derived from input JSON
* @param {SVGElement} path - svg circle element
* @param {object} dataPoint - data point properties such as shape, color and onClick callback function
* @param {number} index - data point index
* @returns {object} - d3 selection object
*/
export const renderSelectionPathForEvents = (
scale,
config,
path,
dataPoint,
index
) =>
path.append(() =>
new Shape(
getSVGObjectForEvent(
SHAPES.CIRCLE,
dataPoint.shape.options,
constants.DEFAULT_PLOT_SELECTION_SCALE_FOR_EVENTS
)
).getShapeElement(
getDefaultSVGProps({
svgClassNames: styles.dataPointSelection,
svgStyles: ``,
transformFn: transformPoint(scale, config)(dataPoint),
onClickFn() {
dataPointActionHandler(dataPoint, index, this);
},
a11yAttributes: {
"aria-hidden": true,
"aria-describedby": dataPoint.key,
"aria-disabled": !utils.isFunction(dataPoint.onClick)
}
})
)
);

/**
* Handler for the data point on click. If the content property is present for the data point
* then the callback is executed other wise it is NOP.
Expand Down
4 changes: 2 additions & 2 deletions src/main/js/controls/Gantt/helpers/eventHelpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import { validateEvent } from "../GanttConfig";
import {
dataPointActionHandler,
drawDataPoints,
renderSelectionPath
renderSelectionPathForEvents
} from "./datapointHelpers";
import { transformPoint } from "./translateHelpers";

Expand Down Expand Up @@ -74,7 +74,7 @@ const drawEventDataPoints = (scale, config, canvasSVG) => {
.each(function (dataPoint, index) {
const dataPointSVG = d3.select(this);
if (utils.isFunction(dataPoint.onClick)) {
renderSelectionPath(
renderSelectionPathForEvents(
scale,
config,
dataPointSVG,
Expand Down
1 change: 1 addition & 0 deletions src/main/js/helpers/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,7 @@ export default {
DEFAULT_HEIGHT: 250,
DEFAULT_PLOT_SCALE: 0.275,
DEFAULT_PLOT_SELECTION_SCALE: { posX: 1.95, posY: 1.95, scale: 2 },
DEFAULT_PLOT_SELECTION_SCALE_FOR_EVENTS: { posX: 9, posY: 7, scale: 1.3 },
DEFAULT_TIMELINE_PLOT_SELECTION_SCALE: { posX: 2, posY: 2, scale: 2.2 },
DEFAULT_TIMELINE_SCALE: { posX: 1.15, posY: 1.15, scale: 1.25 },
DEFAULT_TIMELINE_TICK_LENGTH: 12,
Expand Down
23 changes: 21 additions & 2 deletions src/main/js/helpers/shapeSVG.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,8 @@ import utils from "./utils";
/**
* Returns an object to create a svg circle for data point
*
* @private
* @param {object} shape - SHAPE object
* @param {number} scaleFactor - Scale factor for datapoint
* @param {object} scaleFactor - Scale factor for datapoint
* @returns {object} SVG Object
*/
export const getSVGObject = (shape, { posX, posY, scale }) => {
Expand All @@ -15,3 +14,23 @@ export const getSVGObject = (shape, { posX, posY, scale }) => {
d3Shape.options.scale = d3Shape.options.scale * scale;
return d3Shape;
};

/**
* Returns an object to create a svg circle for event data point
*
* @param {object} shape - SHAPE object
* @param {object} eventShape - properties of event
* @param {object} scaleFactor - Scale factor for datapoint
* @returns {object} SVG Object
*/
export const getSVGObjectForEvent = (
shape,
eventShape,
{ posX, posY, scale }
) => {
const d3Shape = utils.deepClone(shape);
d3Shape.options.x = eventShape.x - posX * eventShape.scale;
d3Shape.options.y = eventShape.y - posY * eventShape.scale;
d3Shape.options.scale = eventShape.scale * scale;
return d3Shape;
};
77 changes: 63 additions & 14 deletions src/test/unit/controls/Gantt/Event-spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,21 @@
import * as d3 from "d3";
import sinon from "sinon";
import Gantt from "../../../../main/js/controls/Gantt";
import { COLORS, SHAPES } from "../../../../main/js/helpers/constants";
import constants, {
COLORS,
SHAPES
} from "../../../../main/js/helpers/constants";
import errors from "../../../../main/js/helpers/errors";
import styles from "../../../../main/js/helpers/styles";
import { getSVGAnimatedTransformList } from "../../../../main/js/helpers/transformUtils";
import { TRANSITION_DELAY, triggerEvent } from "../../helpers/commonHelpers";
import { axisJSON, fetchElementByClass, getAxes, getData } from "./helpers";
import {
axisJSON,
fetchElementByClass,
getAxes,
getData,
getScaleFromSelectionPoint
} from "./helpers";

/**
* BF11272018.02 - Verify the system will allow consumers to utilize events within the Gantt Chart.
Expand Down Expand Up @@ -258,30 +267,70 @@ describe("Gantt -> Track -> Event", () => {
});
it("Renders selection data points correctly", () => {
loadData(gantt);
const selectionPointElement = fetchElementByClass(
styles.dataPointSelection
);
const groupElement = selectionPointElement.firstChild;
expect(selectionPointElement.tagName).toBe("svg");
expect(selectionPointElement.getAttribute("pointer-events")).toBe(
"auto"
const selectionPointElements = document.querySelectorAll(
`.${styles.dataPointSelection}`
);
const groupElement = selectionPointElements[0].firstChild;
const defaultPlot =
constants.DEFAULT_PLOT_SELECTION_SCALE_FOR_EVENTS;
expect(selectionPointElements[0].tagName).toBe("svg");
expect(
selectionPointElements[0].getAttribute("pointer-events")
).toBe("auto");
expect(groupElement.firstChild.nodeName).toBe("path");
expect(groupElement.firstChild.getAttribute("d")).toBe(
SHAPES.CIRCLE.path.d
);
expect(groupElement.firstChild.getAttribute("d")).toBe(
SHAPES.CIRCLE.path.d
);
expect(selectionPointElement.classList).toContain(
expect(selectionPointElements[0].classList).toContain(
styles.dataPointSelection
);
expect(selectionPointElement.getAttribute("aria-describedby")).toBe(
"uid_event_1"
);
expect(selectionPointElement.getAttribute("aria-hidden")).toBe(
expect(
selectionPointElements[0].getAttribute("aria-describedby")
).toBe("uid_event_1");
expect(selectionPointElements[0].getAttribute("aria-hidden")).toBe(
"true"
);

// verify if selection circle x-option is generated accurately.
expect(
parseFloat(selectionPointElements[0].getAttribute("x"))
).toBe(
SHAPES.CIRCLE.options.x -
defaultPlot.posX * SHAPES.CIRCLE.options.scale
);

// verify if selection circle y-option is generated accurately.
expect(
parseFloat(selectionPointElements[0].getAttribute("y"))
).toBe(
SHAPES.CIRCLE.options.y -
defaultPlot.posY * SHAPES.CIRCLE.options.scale
);

// verify if selection circle scale for circle event is generated accurately.
expect(
parseFloat(
getScaleFromSelectionPoint(
selectionPointElements[0].firstChild.getAttribute(
"transform"
)
)
)
).toBe(SHAPES.CIRCLE.options.scale * defaultPlot.scale);

// verify if selection circle scale for diamond is generated accurately.
expect(
parseFloat(
getScaleFromSelectionPoint(
selectionPointElements[1].firstChild.getAttribute(
"transform"
)
)
)
).toBe(SHAPES.DIAMOND.options.scale * defaultPlot.scale);
});
describe("When clicked on data point", () => {
it("Does not do anything if no onClick callback is provided", (done) => {
Expand Down
9 changes: 9 additions & 0 deletions src/test/unit/controls/Gantt/helpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -194,3 +194,12 @@ export const fetchElementByClass = (cls) => document.querySelector(`.${cls}`);
*/
export const fetchAllElementsByClass = (id, cls) =>
id.querySelectorAll(`.${cls}`);

/**
* Returns scale value from the html element
*
* @param {HTMLElement} id - Id attribute name
* @returns {string} scale
*/
export const getScaleFromSelectionPoint = (id) =>
id.split(" ")[1].split(/[()]/)[1];

0 comments on commit 83ff51a

Please sign in to comment.