import { render } from "@testing-library/react";
import { scaleLinear, scaleTime } from "@visx/scale";
import maxBy from "lodash-es/maxBy";
import minBy from "lodash-es/minBy";
import MomentPointsChart from "../../../../lib/ReactViews/Custom/Chart/MomentPointsChart";
function parseGlyphPositions(container: HTMLElement) {
const glyphs = container.querySelectorAll("g.visx-glyph");
return Array.from(glyphs).map((g) => {
const transform = g.getAttribute("transform") || "";
const match = transform.match(/translate\(\s*([^,\s]+)\s*,\s*([^)]+)\s*\)/);
return {
left: parseFloat(match?.[1] ?? "0"),
top: parseFloat(match?.[2] ?? "0")
};
});
}
describe("MomentPointsChart", function () {
const chartItem = {
id: "chartitem",
item: {} as never,
categoryName: "Points chart",
key: "key-chartitem",
name: "chartitem",
type: "momentPoints" as const,
xAxis: { name: "xAxis", scale: "time" as const },
points: [
{ x: new Date("2020-05-25"), y: 0.5 },
{ x: new Date("2020-05-26"), y: 0.5 },
{ x: new Date("2020-05-27"), y: 0.5 },
{ x: new Date("2020-05-28"), y: 0.5 },
{ x: new Date("2020-05-29"), y: 0.5 },
{ x: new Date("2020-05-30"), y: 0.5 }
],
domain: {
x: [new Date("2020-05-25").valueOf(), new Date("2020-05-30").valueOf()],
y: [0.5, 0.5]
},
getColor: () => "red",
onClick: () => {},
showInChartPanel: true,
isSelectedInWorkbench: true,
updateIsSelectedInWorkbench: () => {}
};
const scales = getScales(chartItem.points);
const props = {
id: "testid",
chartItem,
scales: { x: scales.x, y: scales.y.domain([0, 1]) }
};
it("renders all points", function () {
const { container } = render(
);
const glyphs = container.querySelectorAll("g.visx-glyph");
expect(glyphs.length).toBe(6);
});
it("renders the points at the correct positions", function () {
const { container } = render(
);
const positions = parseGlyphPositions(container);
const xs = [0, 2, 4, 6, 8, 10];
positions.forEach((pos, i) => {
expect(pos.left).toEqual(xs[i]);
expect(pos.top).toEqual(5);
});
});
it("renders the correct type of glyph", function () {
const { container } = render(
);
const glyphs = container.querySelectorAll("g.visx-glyph");
expect(glyphs.length).toBe(6);
});
describe("when a basis item is provided", function () {
it("renders the points on the basis item", function () {
const basisItem = {
...chartItem,
name: "basisitem",
points: chartItem.points.map(({ x }, i) => ({
x,
y: [0, 10, 2, 5, 8, 6][i]
}))
};
const basisItemScales = getScales(basisItem.points);
const propsWithBasisItem = {
...props,
basisItem,
basisItemScales
};
const { container } = render(
);
const positions = parseGlyphPositions(container);
const xs = [0, 2, 4, 6, 8, 10];
const ys = [0, 10, 2, 5, 8, 6];
positions.forEach((pos, i) => {
expect(pos.left).toEqual(xs[i]);
expect(pos.top).toEqual(ys[i]);
});
});
});
});
function getScales(points: { x: Date; y: number }[]) {
const xs = points.map((p) => p.x);
const ys = points.map((p) => p.y);
const xDomain = [
minBy(xs, (d) => d.getTime())!,
maxBy(xs, (d) => d.getTime())!
];
const yDomain = [Math.min(...ys), Math.max(...ys)];
return {
x: scaleTime({ domain: xDomain, range: [0, 10] }),
y: scaleLinear({ domain: yDomain, range: [0, 10] })
};
}