polly-graph 0.1.10 → 0.1.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,5 +1,9 @@
1
1
  # polly-graph
2
2
 
3
+ [![npm version](https://img.shields.io/npm/v/polly-graph)](https://www.npmjs.com/package/polly-graph)
4
+ [![TypeScript](https://img.shields.io/badge/%3C%2F%3E-TypeScript-%230074c1.svg)](http://www.typescriptlang.org/)
5
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
6
+
3
7
  A framework-independent TypeScript-based D3 graph visualization SDK that provides a comprehensive, reusable solution for creating interactive network graphs. Designed to work seamlessly across React, Angular, Vue, Svelte, or vanilla JavaScript applications.
4
8
 
5
9
  ## Features
package/dist/index.cjs CHANGED
@@ -4816,7 +4816,17 @@ function renderLinks(ctx, links) {
4816
4816
 
4817
4817
  // src/renderer/nodes.ts
4818
4818
  function renderNodes(ctx, nodes) {
4819
- return ctx.root.select('[data-layer="nodes"]').selectAll("circle").data(nodes, (d) => d.id).join("circle").attr("r", (node) => node.style?.radius ?? 8).attr("fill", (node) => node.style?.fill ?? "#6c5ce7").attr("stroke", (node) => node.style?.stroke ?? "#ffffff").attr("stroke-width", (node) => node.style?.strokeWidth ?? 1.5).attr("opacity", (node) => node.style?.opacity ?? 1).style("cursor", "pointer");
4819
+ return ctx.root.select('[data-layer="nodes"]').selectAll("circle").data(nodes, (d) => d.id).join("circle").attr("r", (node) => node.style?.radius ?? 8).attr("fill", (node) => node.style?.fill ?? "#6c5ce7").call((selection2) => {
4820
+ selection2.each(function(node) {
4821
+ const element = this;
4822
+ if (node.style?.stroke !== void 0) {
4823
+ element.setAttribute("stroke", node.style.stroke);
4824
+ }
4825
+ if (node.style?.strokeWidth !== void 0) {
4826
+ element.setAttribute("stroke-width", String(node.style.strokeWidth));
4827
+ }
4828
+ });
4829
+ }).attr("opacity", (node) => node.style?.opacity ?? 1).style("cursor", "pointer");
4820
4830
  }
4821
4831
 
4822
4832
  // src/renderer/node-labels.ts
@@ -5112,37 +5122,29 @@ function createNodeHover(nodeSelection, hoverStyle) {
5112
5122
  const firstNode = nodeSelection.node();
5113
5123
  if (!firstNode) return;
5114
5124
  if (hoverStyle) {
5115
- nodeSelection.on("mouseenter.hover", function(_event, node) {
5125
+ nodeSelection.on("mouseenter.hover", function(_event, _node) {
5116
5126
  const circle = this;
5117
5127
  if (circle.dataset.selected === "true") {
5118
5128
  return;
5119
5129
  }
5120
- circle.setAttribute("stroke", hoverStyle.stroke ?? node.style?.stroke ?? "#ffffff");
5121
- circle.setAttribute("stroke-width", String(hoverStyle.strokeWidth ?? node.style?.strokeWidth ?? 1.5));
5122
- circle.setAttribute("opacity", String(hoverStyle.opacity ?? node.style?.opacity ?? 1));
5123
- }).on("mouseleave.hover", function(_event, node) {
5130
+ if (hoverStyle.stroke !== void 0) {
5131
+ circle.style.stroke = hoverStyle.stroke;
5132
+ }
5133
+ if (hoverStyle.strokeWidth !== void 0) {
5134
+ circle.style.strokeWidth = String(hoverStyle.strokeWidth);
5135
+ }
5136
+ if (hoverStyle.opacity !== void 0) {
5137
+ circle.style.opacity = String(hoverStyle.opacity);
5138
+ }
5139
+ }).on("mouseleave.hover", function(_event, _node) {
5124
5140
  const circle = this;
5141
+ clearAllHoverLayers();
5125
5142
  if (circle.dataset.selected === "true") {
5126
5143
  return;
5127
5144
  }
5128
5145
  circle.style.stroke = "";
5129
5146
  circle.style.strokeWidth = "";
5130
5147
  circle.style.opacity = "";
5131
- if (!node.style?.stroke) {
5132
- circle.setAttribute("stroke", "#ffffff");
5133
- } else {
5134
- circle.setAttribute("stroke", node.style.stroke);
5135
- }
5136
- if (!node.style?.strokeWidth) {
5137
- circle.setAttribute("stroke-width", "1.5");
5138
- } else {
5139
- circle.setAttribute("stroke-width", String(node.style.strokeWidth));
5140
- }
5141
- if (!node.style?.opacity) {
5142
- circle.setAttribute("opacity", "1");
5143
- } else {
5144
- circle.setAttribute("opacity", String(node.style.opacity));
5145
- }
5146
5148
  });
5147
5149
  }
5148
5150
  const svgElement = firstNode.ownerSVGElement;
@@ -6128,18 +6130,42 @@ var DEFAULT_NODE_HOVER_STYLE = {
6128
6130
  };
6129
6131
  function resolveNodeStyle(params) {
6130
6132
  if (params.isSelected) {
6131
- return mergeNodeStyle(DEFAULT_NODE_HOVER_STYLE, params.interaction?.selection?.nodeStyle);
6133
+ return mergeNodeStyleSmart(DEFAULT_NODE_HOVER_STYLE, params.interaction?.selection?.nodeStyle);
6132
6134
  }
6133
6135
  if (params.isHovered) {
6134
- return mergeNodeStyle(DEFAULT_NODE_HOVER_STYLE, params.interaction?.hover?.nodeStyle);
6136
+ return mergeNodeStyleSmart(DEFAULT_NODE_HOVER_STYLE, params.interaction?.hover?.nodeStyle);
6135
6137
  }
6136
6138
  return void 0;
6137
6139
  }
6138
- function mergeNodeStyle(base, override) {
6139
- return {
6140
- ...base,
6141
- ...override
6142
- };
6140
+ function mergeNodeStyleSmart(base, override) {
6141
+ if (!override) return base;
6142
+ const result = { ...override };
6143
+ if (override.strokeWidth !== void 0 && override.stroke === void 0 && base.stroke !== void 0) {
6144
+ result.stroke = base.stroke;
6145
+ }
6146
+ const baseKeys = Object.keys(base);
6147
+ baseKeys.forEach((key) => {
6148
+ if (key !== "stroke" && override[key] === void 0 && base[key] !== void 0) {
6149
+ switch (key) {
6150
+ case "fill":
6151
+ result.fill = base.fill;
6152
+ break;
6153
+ case "strokeWidth":
6154
+ result.strokeWidth = base.strokeWidth;
6155
+ break;
6156
+ case "opacity":
6157
+ result.opacity = base.opacity;
6158
+ break;
6159
+ case "radius":
6160
+ result.radius = base.radius;
6161
+ break;
6162
+ case "textColor":
6163
+ result.textColor = base.textColor;
6164
+ break;
6165
+ }
6166
+ }
6167
+ });
6168
+ return result;
6143
6169
  }
6144
6170
 
6145
6171
  // src/core/interaction-manager.ts
package/dist/index.js CHANGED
@@ -4784,7 +4784,17 @@ function renderLinks(ctx, links) {
4784
4784
 
4785
4785
  // src/renderer/nodes.ts
4786
4786
  function renderNodes(ctx, nodes) {
4787
- return ctx.root.select('[data-layer="nodes"]').selectAll("circle").data(nodes, (d) => d.id).join("circle").attr("r", (node) => node.style?.radius ?? 8).attr("fill", (node) => node.style?.fill ?? "#6c5ce7").attr("stroke", (node) => node.style?.stroke ?? "#ffffff").attr("stroke-width", (node) => node.style?.strokeWidth ?? 1.5).attr("opacity", (node) => node.style?.opacity ?? 1).style("cursor", "pointer");
4787
+ return ctx.root.select('[data-layer="nodes"]').selectAll("circle").data(nodes, (d) => d.id).join("circle").attr("r", (node) => node.style?.radius ?? 8).attr("fill", (node) => node.style?.fill ?? "#6c5ce7").call((selection2) => {
4788
+ selection2.each(function(node) {
4789
+ const element = this;
4790
+ if (node.style?.stroke !== void 0) {
4791
+ element.setAttribute("stroke", node.style.stroke);
4792
+ }
4793
+ if (node.style?.strokeWidth !== void 0) {
4794
+ element.setAttribute("stroke-width", String(node.style.strokeWidth));
4795
+ }
4796
+ });
4797
+ }).attr("opacity", (node) => node.style?.opacity ?? 1).style("cursor", "pointer");
4788
4798
  }
4789
4799
 
4790
4800
  // src/renderer/node-labels.ts
@@ -5080,37 +5090,29 @@ function createNodeHover(nodeSelection, hoverStyle) {
5080
5090
  const firstNode = nodeSelection.node();
5081
5091
  if (!firstNode) return;
5082
5092
  if (hoverStyle) {
5083
- nodeSelection.on("mouseenter.hover", function(_event, node) {
5093
+ nodeSelection.on("mouseenter.hover", function(_event, _node) {
5084
5094
  const circle = this;
5085
5095
  if (circle.dataset.selected === "true") {
5086
5096
  return;
5087
5097
  }
5088
- circle.setAttribute("stroke", hoverStyle.stroke ?? node.style?.stroke ?? "#ffffff");
5089
- circle.setAttribute("stroke-width", String(hoverStyle.strokeWidth ?? node.style?.strokeWidth ?? 1.5));
5090
- circle.setAttribute("opacity", String(hoverStyle.opacity ?? node.style?.opacity ?? 1));
5091
- }).on("mouseleave.hover", function(_event, node) {
5098
+ if (hoverStyle.stroke !== void 0) {
5099
+ circle.style.stroke = hoverStyle.stroke;
5100
+ }
5101
+ if (hoverStyle.strokeWidth !== void 0) {
5102
+ circle.style.strokeWidth = String(hoverStyle.strokeWidth);
5103
+ }
5104
+ if (hoverStyle.opacity !== void 0) {
5105
+ circle.style.opacity = String(hoverStyle.opacity);
5106
+ }
5107
+ }).on("mouseleave.hover", function(_event, _node) {
5092
5108
  const circle = this;
5109
+ clearAllHoverLayers();
5093
5110
  if (circle.dataset.selected === "true") {
5094
5111
  return;
5095
5112
  }
5096
5113
  circle.style.stroke = "";
5097
5114
  circle.style.strokeWidth = "";
5098
5115
  circle.style.opacity = "";
5099
- if (!node.style?.stroke) {
5100
- circle.setAttribute("stroke", "#ffffff");
5101
- } else {
5102
- circle.setAttribute("stroke", node.style.stroke);
5103
- }
5104
- if (!node.style?.strokeWidth) {
5105
- circle.setAttribute("stroke-width", "1.5");
5106
- } else {
5107
- circle.setAttribute("stroke-width", String(node.style.strokeWidth));
5108
- }
5109
- if (!node.style?.opacity) {
5110
- circle.setAttribute("opacity", "1");
5111
- } else {
5112
- circle.setAttribute("opacity", String(node.style.opacity));
5113
- }
5114
5116
  });
5115
5117
  }
5116
5118
  const svgElement = firstNode.ownerSVGElement;
@@ -6096,18 +6098,42 @@ var DEFAULT_NODE_HOVER_STYLE = {
6096
6098
  };
6097
6099
  function resolveNodeStyle(params) {
6098
6100
  if (params.isSelected) {
6099
- return mergeNodeStyle(DEFAULT_NODE_HOVER_STYLE, params.interaction?.selection?.nodeStyle);
6101
+ return mergeNodeStyleSmart(DEFAULT_NODE_HOVER_STYLE, params.interaction?.selection?.nodeStyle);
6100
6102
  }
6101
6103
  if (params.isHovered) {
6102
- return mergeNodeStyle(DEFAULT_NODE_HOVER_STYLE, params.interaction?.hover?.nodeStyle);
6104
+ return mergeNodeStyleSmart(DEFAULT_NODE_HOVER_STYLE, params.interaction?.hover?.nodeStyle);
6103
6105
  }
6104
6106
  return void 0;
6105
6107
  }
6106
- function mergeNodeStyle(base, override) {
6107
- return {
6108
- ...base,
6109
- ...override
6110
- };
6108
+ function mergeNodeStyleSmart(base, override) {
6109
+ if (!override) return base;
6110
+ const result = { ...override };
6111
+ if (override.strokeWidth !== void 0 && override.stroke === void 0 && base.stroke !== void 0) {
6112
+ result.stroke = base.stroke;
6113
+ }
6114
+ const baseKeys = Object.keys(base);
6115
+ baseKeys.forEach((key) => {
6116
+ if (key !== "stroke" && override[key] === void 0 && base[key] !== void 0) {
6117
+ switch (key) {
6118
+ case "fill":
6119
+ result.fill = base.fill;
6120
+ break;
6121
+ case "strokeWidth":
6122
+ result.strokeWidth = base.strokeWidth;
6123
+ break;
6124
+ case "opacity":
6125
+ result.opacity = base.opacity;
6126
+ break;
6127
+ case "radius":
6128
+ result.radius = base.radius;
6129
+ break;
6130
+ case "textColor":
6131
+ result.textColor = base.textColor;
6132
+ break;
6133
+ }
6134
+ }
6135
+ });
6136
+ return result;
6111
6137
  }
6112
6138
 
6113
6139
  // src/core/interaction-manager.ts
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "polly-graph",
3
- "version": "0.1.10",
3
+ "version": "0.1.12",
4
4
  "description": "Reusable D3-based graph visualization SDK with configurable nodes, links, labels, interactions, and layout behaviors.",
5
5
  "license": "MIT",
6
6
  "author": "Badal",