Packages
noora
0.86.0
0.86.0
0.85.0
0.84.1
0.84.0
0.83.2
0.83.1
0.83.0
0.82.7
0.82.6
0.82.5
0.82.4
0.82.3
0.82.2
0.82.1
0.82.0
0.81.4
0.81.3
0.81.2
0.81.1
0.81.0
0.80.1
0.80.0
0.79.1
0.79.0
0.78.1
0.78.0
0.77.4
0.77.3
0.77.2
0.77.1
0.77.0
0.76.0
0.75.0
0.74.0
0.73.0
0.72.0
0.71.0
0.70.0
0.69.1
0.69.0
0.68.0
0.67.0
0.66.0
0.65.0
0.64.2
0.64.1
0.64.0
0.63.2
0.63.1
0.63.0
0.62.0
0.61.0
0.60.0
0.59.0
0.58.0
0.57.0
0.56.1
0.56.0
0.55.0
0.54.0
0.53.1
0.53.0
0.52.1
0.52.0
0.51.0
0.50.1
0.50.0
0.49.0
0.48.0
0.47.0
0.46.0
0.45.0
0.44.3
0.44.2
0.44.1
0.44.0
0.43.0
0.42.0
0.41.0
0.40.6
0.40.5
0.40.4
0.40.3
0.40.2
0.40.1
0.40.0
0.39.1
0.39.0
0.38.0
0.37.0
0.36.0
0.35.0
0.34.0
0.33.0
0.32.1
0.32.0
0.31.0
0.30.0
0.29.2
0.29.1
0.29.0
0.28.5
0.28.4
0.28.3
0.28.2
0.28.1
0.28.0
0.27.0
0.26.1
0.26.0
0.25.0
0.24.0
0.23.1
0.23.0
0.22.1
0.22.0
0.21.0
0.20.0
0.19.0
0.18.0
0.17.0
0.16.0
0.15.0
0.14.0
0.13.0
0.12.1
0.12.0
0.11.2
0.11.1
0.11.0
0.10.0
0.9.0
0.8.0
0.7.0
0.6.1
0.6.0
0.5.1
0.5.0
0.4.0
0.3.2
0.3.1
0.3.0
0.2.2
0.2.0
0.1.0
0.1.0-rc.2
0.1.0-rc.1
0.1.0-alpha.6
0.1.0-alpha.5
0.1.0-alpha.4
0.1.0-alpha.3
0.1.0-alpha.2
0.1.0-alpha.1
A component library for Phoenix LiveView applications
Current section
Files
Jump to
Current section
Files
js/web-components/Chart.test.js
// @vitest-environment happy-dom
import { afterEach, beforeAll, describe, expect, it, vi } from "vitest";
const echarts = vi.hoisted(() => ({
init: vi.fn(),
registerTheme: vi.fn(),
}));
vi.mock("echarts", () => echarts);
import {
registerNooraChart,
registerNooraChartAxis,
registerNooraChartCategory,
registerNooraChartGrid,
registerNooraChartPoint,
registerNooraChartSeries,
} from "./Remaining.js";
beforeAll(() => {
registerNooraChart();
registerNooraChartAxis();
registerNooraChartCategory();
registerNooraChartGrid();
registerNooraChartPoint();
registerNooraChartSeries();
});
afterEach(() => {
document.body.replaceChildren();
vi.clearAllMocks();
});
describe("NooraChart", () => {
it("initializes the drawing surface with its renderer and options", async () => {
const instance = {
dispose: vi.fn(),
on: vi.fn(),
resize: vi.fn(),
setOption: vi.fn(),
};
echarts.init.mockReturnValue(instance);
const chart = document.createElement("noora-chart");
chart.renderer = "svg";
const options = {
xAxis: { type: "category", data: ["Mon", "Tue"] },
yAxis: {},
series: [{ type: "line", data: [2, 5] }],
};
chart.options = options;
document.body.append(chart);
await chart.updateComplete;
const drawingSurface = chart.shadowRoot.querySelector(
'[data-part="chart"]',
);
expect(echarts.registerTheme).toHaveBeenCalledWith(
"noora",
expect.any(Object),
);
expect(echarts.init).toHaveBeenCalledWith(drawingSurface, "noora", {
renderer: "svg",
});
expect(chart.options).toEqual(options);
expect(instance.setOption).toHaveBeenCalledWith(options, {
notMerge: true,
});
chart.remove();
expect(instance.dispose).toHaveBeenCalledOnce();
});
it("exposes options as a property without observing an options attribute", async () => {
const instance = {
dispose: vi.fn(),
on: vi.fn(),
resize: vi.fn(),
setOption: vi.fn(),
};
echarts.init.mockReturnValue(instance);
const chart = document.createElement("noora-chart");
chart.setAttribute("options", '{"series":[{"type":"bar","data":[1]}]}');
document.body.append(chart);
await chart.updateComplete;
expect(chart.options).toEqual({});
expect(instance.setOption).toHaveBeenCalledWith({}, { notMerge: true });
});
it("allows navigation from an interactive point to be cancelled", async () => {
const instance = {
dispose: vi.fn(),
on: vi.fn(),
resize: vi.fn(),
setOption: vi.fn(),
};
echarts.init.mockReturnValue(instance);
const chart = document.createElement("noora-chart");
const selection = vi.fn((event) => event.preventDefault());
chart.addEventListener("noora-chart-select", selection);
document.body.append(chart);
await chart.updateComplete;
const clickHandler = instance.on.mock.calls.find(
([eventName]) => eventName === "click",
)[1];
clickHandler({ data: { url: "/projects" } });
expect(selection).toHaveBeenCalledOnce();
expect(selection.mock.calls[0][0].cancelable).toBe(true);
expect(selection.mock.calls[0][0].defaultPrevented).toBe(true);
});
it("applies a changed color palette without recreating the chart", async () => {
const instance = {
dispose: vi.fn(),
on: vi.fn(),
resize: vi.fn(),
setOption: vi.fn(),
};
echarts.init.mockReturnValue(instance);
const chart = document.createElement("noora-chart");
chart.options = { colors: ["#111111"], series: [] };
document.body.append(chart);
await chart.updateComplete;
chart.options = { colors: ["#222222"], series: [] };
await chart.updateComplete;
expect(echarts.init).toHaveBeenCalledOnce();
expect(instance.setOption.mock.lastCall[0].color).toEqual(["#222222"]);
});
it("builds chart options from declarative configuration children", async () => {
const instance = {
dispose: vi.fn(),
on: vi.fn(),
resize: vi.fn(),
setOption: vi.fn(),
};
echarts.init.mockReturnValue(instance);
const chart = document.createElement("noora-chart");
chart.tooltipTrigger = "axis";
chart.innerHTML = `
<noora-chart-grid contain-label height="76" width="400"></noora-chart-grid>
<noora-chart-axis dimension="x" type="category">
<noora-chart-category>Mon</noora-chart-category>
<noora-chart-category>Tue</noora-chart-category>
</noora-chart-axis>
<noora-chart-axis
dimension="y"
type="value"
min="0"
max="100"
label-format="{value}%"
hide-line
hide-ticks
dashed-grid
></noora-chart-axis>
<noora-chart-series name="Effectiveness" type="line" symbol="none">
<noora-chart-point value="2"></noora-chart-point>
<noora-chart-point value="5"></noora-chart-point>
</noora-chart-series>
`;
document.body.append(chart);
await Promise.all(
[...chart.querySelectorAll("*")].map((child) => child.updateComplete),
);
await chart.updateComplete;
expect(instance.setOption).toHaveBeenLastCalledWith(
{
colors: [
"var:noora-chart-primary",
"var:noora-chart-secondary",
"var:noora-chart-tertiary",
"var:noora-chart-quaternary",
],
series: [
{
label: { show: false },
name: "Effectiveness",
stack: null,
type: "line",
symbol: "none",
data: [2, 5],
},
],
yAxis: {
type: "value",
min: 0,
max: 100,
axisLabel: { fontSize: 10, formatter: "{value}%" },
axisLine: { show: false },
axisTick: { show: false },
splitLine: { lineStyle: { type: "dashed" } },
},
xAxis: {
type: "category",
data: ["Mon", "Tue"],
axisLabel: { fontSize: 10 },
axisLine: { show: false },
axisTick: { show: false },
splitLine: { lineStyle: { type: "dashed" } },
},
tooltip: { show: true, trigger: "axis" },
grid: { containLabel: true, height: 76, width: 400 },
legend: { left: "center", top: "0" },
textStyle: { fontFamily: "Geist Mono" },
},
{ notMerge: true },
);
});
it("matches the LiveView horizontal bar configuration", async () => {
const instance = {
dispose: vi.fn(),
on: vi.fn(),
resize: vi.fn(),
setOption: vi.fn(),
};
echarts.init.mockReturnValue(instance);
const chart = document.createElement("noora-chart");
chart.innerHTML = `
<noora-chart-grid contain-label height="76" width="400"></noora-chart-grid>
<noora-chart-axis
dimension="x"
type="value"
label-format="{value}h"
label-size="10"
label-margin="25"
></noora-chart-axis>
<noora-chart-axis dimension="y" type="category" no-boundary-gap>
<noora-chart-category>Selective Test</noora-chart-category>
<noora-chart-category>Build Cache</noora-chart-category>
</noora-chart-axis>
<noora-chart-series type="bar" bar-gap="-100%" bar-width="24" border-radius="7">
<noora-chart-point value="19"></noora-chart-point>
<noora-chart-point value="22"></noora-chart-point>
</noora-chart-series>
<noora-chart-series type="bar" bar-width="24" border-radius="7">
<noora-chart-point value="7.2"></noora-chart-point>
<noora-chart-point value="9"></noora-chart-point>
</noora-chart-series>
`;
document.body.append(chart);
await Promise.all(
[...chart.querySelectorAll("*")].map((child) => child.updateComplete),
);
await chart.updateComplete;
const options = instance.setOption.mock.lastCall[0];
expect(options).toEqual({
colors: [
"var:noora-chart-primary",
"var:noora-chart-secondary",
"var:noora-chart-tertiary",
"var:noora-chart-quaternary",
],
series: [
{
data: [19, 22],
label: { show: false },
name: "",
type: "bar",
stack: null,
barGap: "-100%",
itemStyle: { borderRadius: 7 },
barWidth: 24,
},
{
data: [7.2, 9],
label: { show: false },
name: "",
type: "bar",
stack: null,
itemStyle: { borderRadius: 7 },
barWidth: 24,
},
],
yAxis: {
data: ["Selective Test", "Build Cache"],
type: "category",
axisLabel: { fontSize: 10 },
splitLine: { lineStyle: { type: "dashed" } },
boundaryGap: false,
axisLine: { show: false },
axisTick: { show: false },
},
xAxis: {
type: "value",
axisLabel: {
formatter: "{value}h",
margin: 25,
fontSize: 10,
},
splitLine: { lineStyle: { type: "dashed" } },
axisLine: { show: false },
axisTick: { show: false },
},
tooltip: { show: true, trigger: "axis" },
grid: { width: 400, height: 76, containLabel: true },
legend: { left: "center", top: "0" },
textStyle: { fontFamily: "Geist Mono" },
});
});
});