Skip to content

Commit

Permalink
[sigma] mouse event and shadowdom
Browse files Browse the repository at this point in the history
Fix #1400
  • Loading branch information
sim51 authored and jacomyal committed Aug 22, 2024
1 parent 7a341c3 commit 2698eac
Show file tree
Hide file tree
Showing 4 changed files with 164 additions and 1 deletion.
2 changes: 1 addition & 1 deletion packages/sigma/src/core/captors/mouse.ts
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,7 @@ export default class MouseCaptor<
// Only trigger the "mousemove" event when the mouse is actually hovering
// the container, to avoid weirdly hovering nodes and/or edges when the
// mouse is not hover the container:
if (e.target === this.container) {
if (e.target === this.container || e.composedPath()[0] === this.container) {
this.emit("mousemove", mouseCoords);
}

Expand Down
30 changes: 30 additions & 0 deletions packages/storybook/stories/events-shadowdom/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<style>
html,
body,
#storybook-root,
#sigma-container {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
overflow: hidden;
font-family: sans-serif;
}
#sigma-container .sigma-mouse {
z-index: 100;
}
#sigma-logs {
position: absolute;
top:0;
max-height: 20%;
overflow: hidden;
}
#sigma-logs > div {
padding: 3px;
}
#sigma-logs > div > span {
background: #ffffff99;
}
</style>
<sigma-shadow></sigma-shadow>
<div id="sigma-logs"></div>
109 changes: 109 additions & 0 deletions packages/storybook/stories/events-shadowdom/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
import Graph from "graphology";
import Sigma from "sigma";
import { MouseCoords } from "sigma/types";

import data from "../_data/data.json";

/**
* This is a minimal example of sigma. You can use it as a base to write new
* examples, or reproducible test cases for new issues, for instance.
*/
export default () => {
const logsDOM = document.getElementById("sigma-logs") as HTMLElement;
const graph = new Graph();
graph.import(data);

function logEvent(event: string, itemType: "node" | "edge" | "positions", item: string | MouseCoords): void {
const div = document.createElement("div");
let message = `Event "${event}"`;
if (item && itemType) {
if (itemType === "positions") {
item = item as MouseCoords;
message += `, x ${item.x}, y ${item.y}`;
} else {
const label =
itemType === "node" ? graph.getNodeAttribute(item, "label") : graph.getEdgeAttribute(item, "label");
message += `, ${itemType} ${label || "with no label"} (id "${item}")`;

if (itemType === "edge") {
message += `, source ${graph.getSourceAttribute(item, "label")}, target: ${graph.getTargetAttribute(
item,
"label",
)}`;
}
}
}
div.innerHTML = `<span>${message}</span>`;
logsDOM.appendChild(div);
logsDOM.scrollTo({ top: logsDOM.scrollHeight });

if (logsDOM.children.length > 50) logsDOM.children[0].remove();
}

window.customElements.define(
"sigma-shadow",
class extends HTMLElement {
_container: HTMLDivElement | null = null;

constructor() {
super();
}

connectedCallback() {
const shadowRoot = this.attachShadow({ mode: "open" });
const container = document.createElement("div");
container.style.cssText = `
width: 100%;
height: 100%;
margin: 0;
padding: 0;
overflow: hidden;
`;
this._container = container;
shadowRoot.appendChild(container);

let hoveredEdge: null | string = null;
const renderer = new Sigma(graph, this._container, {
enableEdgeEvents: true,
edgeReducer(edge, data) {
const res = { ...data };
if (edge === hoveredEdge) res.color = "#cc0000";
return res;
},
});

const nodeEvents = [
"enterNode",
"leaveNode",
"downNode",
"clickNode",
"rightClickNode",
"doubleClickNode",
"wheelNode",
] as const;
const edgeEvents = ["downEdge", "clickEdge", "rightClickEdge", "doubleClickEdge", "wheelEdge"] as const;
const stageEvents = ["downStage", "clickStage", "doubleClickStage", "wheelStage"] as const;

nodeEvents.forEach((eventType) => renderer.on(eventType, ({ node }) => logEvent(eventType, "node", node)));
edgeEvents.forEach((eventType) => renderer.on(eventType, ({ edge }) => logEvent(eventType, "edge", edge)));

renderer.on("enterEdge", ({ edge }) => {
logEvent("enterEdge", "edge", edge);
hoveredEdge = edge;
renderer.refresh();
});
renderer.on("leaveEdge", ({ edge }) => {
logEvent("leaveEdge", "edge", edge);
hoveredEdge = null;
renderer.refresh();
});

stageEvents.forEach((eventType) => {
renderer.on(eventType, ({ event }) => {
logEvent(eventType, "positions", event);
});
});
}
},
);
};
24 changes: 24 additions & 0 deletions packages/storybook/stories/events-shadowdom/stories.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { Meta, StoryObj } from "@storybook/html";

import play from ".";
import template from "./index.html?raw";
import source from "./index?raw";

const meta: Meta = {
id: "events-shadowdom",
title: "Examples",
};
export default meta;

type Story = StoryObj;

export const story: Story = {
name: "Events ShadowDom",
render: () => template,
play: play,
parameters: {
storySource: {
source: source,
},
},
};

0 comments on commit 2698eac

Please sign in to comment.