@neo4j-ndl/react-graph 1.5.5 → 2.0.0

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.
Files changed (81) hide show
  1. package/lib/cjs/graph-visualization-context.js.map +1 -1
  2. package/lib/cjs/graph-visualization.js +1 -1
  3. package/lib/cjs/graph-visualization.js.map +1 -1
  4. package/lib/cjs/index.js +5 -1
  5. package/lib/cjs/index.js.map +1 -1
  6. package/lib/cjs/stories/graph-visualization-range-styling.story.js +21 -16
  7. package/lib/cjs/stories/graph-visualization-range-styling.story.js.map +1 -1
  8. package/lib/cjs/stories/graph-visualization-rule-based-styling-advanced.story.js +105 -82
  9. package/lib/cjs/stories/graph-visualization-rule-based-styling-advanced.story.js.map +1 -1
  10. package/lib/cjs/stories/graph-visualization-rule-based-styling.story.js +15 -13
  11. package/lib/cjs/stories/graph-visualization-rule-based-styling.story.js.map +1 -1
  12. package/lib/cjs/stories/graph-visualization-simple-styling.story.js +12 -10
  13. package/lib/cjs/stories/graph-visualization-simple-styling.story.js.map +1 -1
  14. package/lib/cjs/stories/graph-visualization-unique-colors-styling.story.js +71 -0
  15. package/lib/cjs/stories/graph-visualization-unique-colors-styling.story.js.map +1 -0
  16. package/lib/cjs/stories/index.js +5 -1
  17. package/lib/cjs/stories/index.js.map +1 -1
  18. package/lib/cjs/styling/compile-graph-styles.js +143 -60
  19. package/lib/cjs/styling/compile-graph-styles.js.map +1 -1
  20. package/lib/cjs/styling/create-vis-data-structures.js.map +1 -1
  21. package/lib/cjs/styling/parse-style-rules.js +4 -4
  22. package/lib/cjs/styling/parse-style-rules.js.map +1 -1
  23. package/lib/cjs/styling/style-types.js +57 -16
  24. package/lib/cjs/styling/style-types.js.map +1 -1
  25. package/lib/cjs/styling/use-graph-data.js +1 -1
  26. package/lib/cjs/styling/use-graph-data.js.map +1 -1
  27. package/lib/esm/graph-visualization-context.js.map +1 -1
  28. package/lib/esm/graph-visualization.js +1 -1
  29. package/lib/esm/graph-visualization.js.map +1 -1
  30. package/lib/esm/index.js +2 -0
  31. package/lib/esm/index.js.map +1 -1
  32. package/lib/esm/stories/graph-visualization-range-styling.story.js +21 -16
  33. package/lib/esm/stories/graph-visualization-range-styling.story.js.map +1 -1
  34. package/lib/esm/stories/graph-visualization-rule-based-styling-advanced.story.js +105 -82
  35. package/lib/esm/stories/graph-visualization-rule-based-styling-advanced.story.js.map +1 -1
  36. package/lib/esm/stories/graph-visualization-rule-based-styling.story.js +15 -13
  37. package/lib/esm/stories/graph-visualization-rule-based-styling.story.js.map +1 -1
  38. package/lib/esm/stories/graph-visualization-simple-styling.story.js +12 -10
  39. package/lib/esm/stories/graph-visualization-simple-styling.story.js.map +1 -1
  40. package/lib/esm/stories/graph-visualization-unique-colors-styling.story.js +69 -0
  41. package/lib/esm/stories/graph-visualization-unique-colors-styling.story.js.map +1 -0
  42. package/lib/esm/stories/index.js +3 -0
  43. package/lib/esm/stories/index.js.map +1 -1
  44. package/lib/esm/styling/compile-graph-styles.js +141 -58
  45. package/lib/esm/styling/compile-graph-styles.js.map +1 -1
  46. package/lib/esm/styling/create-vis-data-structures.js.map +1 -1
  47. package/lib/esm/styling/parse-style-rules.js +5 -5
  48. package/lib/esm/styling/parse-style-rules.js.map +1 -1
  49. package/lib/esm/styling/style-types.js +56 -15
  50. package/lib/esm/styling/style-types.js.map +1 -1
  51. package/lib/esm/styling/use-graph-data.js +2 -2
  52. package/lib/esm/styling/use-graph-data.js.map +1 -1
  53. package/lib/types/graph-visualization-context.d.ts +2 -2
  54. package/lib/types/graph-visualization-context.d.ts.map +1 -1
  55. package/lib/types/graph-visualization.d.ts +3 -3
  56. package/lib/types/graph-visualization.d.ts.map +1 -1
  57. package/lib/types/index.d.ts +3 -1
  58. package/lib/types/index.d.ts.map +1 -1
  59. package/lib/types/stories/graph-visualization-range-styling.story.d.ts +2 -2
  60. package/lib/types/stories/graph-visualization-range-styling.story.d.ts.map +1 -1
  61. package/lib/types/stories/graph-visualization-rule-based-styling-advanced.story.d.ts +10 -10
  62. package/lib/types/stories/graph-visualization-rule-based-styling-advanced.story.d.ts.map +1 -1
  63. package/lib/types/stories/graph-visualization-rule-based-styling.story.d.ts +2 -2
  64. package/lib/types/stories/graph-visualization-rule-based-styling.story.d.ts.map +1 -1
  65. package/lib/types/stories/graph-visualization-simple-styling.story.d.ts +2 -2
  66. package/lib/types/stories/graph-visualization-simple-styling.story.d.ts.map +1 -1
  67. package/lib/types/stories/graph-visualization-unique-colors-styling.story.d.ts +23 -0
  68. package/lib/types/stories/graph-visualization-unique-colors-styling.story.d.ts.map +1 -0
  69. package/lib/types/stories/index.d.ts +2 -0
  70. package/lib/types/stories/index.d.ts.map +1 -1
  71. package/lib/types/styling/compile-graph-styles.d.ts +9 -8
  72. package/lib/types/styling/compile-graph-styles.d.ts.map +1 -1
  73. package/lib/types/styling/create-vis-data-structures.d.ts +2 -2
  74. package/lib/types/styling/create-vis-data-structures.d.ts.map +1 -1
  75. package/lib/types/styling/parse-style-rules.d.ts +5 -5
  76. package/lib/types/styling/parse-style-rules.d.ts.map +1 -1
  77. package/lib/types/styling/style-types.d.ts +113 -51
  78. package/lib/types/styling/style-types.d.ts.map +1 -1
  79. package/lib/types/styling/use-graph-data.d.ts +3 -3
  80. package/lib/types/styling/use-graph-data.d.ts.map +1 -1
  81. package/package.json +3 -3
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/stories/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,EAAE,OAAO,IAAI,2BAA2B,EAAE,MAAM,uCAAuC,CAAC;AAC/F,OAAO,EAAE,OAAO,IAAI,wBAAwB,EAAE,MAAM,oCAAoC,CAAC;AACzF,OAAO,EAAE,OAAO,IAAI,yBAAyB,EAAE,MAAM,qCAAqC,CAAC;AAC3F,OAAO,EAAE,OAAO,IAAI,8BAA8B,EAAE,MAAM,0CAA0C,CAAC;AACrG,OAAO,EAAE,OAAO,IAAI,4BAA4B,EAAE,MAAM,wCAAwC,CAAC;AACjG,OAAO,EAAE,OAAO,IAAI,8BAA8B,EAAE,MAAM,2CAA2C,CAAC;AACtG,OAAO,EAAE,OAAO,IAAI,0CAA0C,EAAE,MAAM,yDAAyD,CAAC;AAChI,OAAO,EAAE,OAAO,IAAI,kCAAkC,EAAE,MAAM,gDAAgD,CAAC;AAC/G,OAAO,EAAE,OAAO,IAAI,wBAAwB,EAAE,MAAM,oCAAoC,CAAC;AACzF,OAAO,EAAE,OAAO,IAAI,+BAA+B,EAAE,MAAM,4CAA4C,CAAC;AACxG,OAAO,EAAE,OAAO,IAAI,yBAAyB,EAAE,MAAM,qCAAqC,CAAC;AAE3F,OAAO,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAC;AAC/C,OAAO,iCAAiC,MAAM,2CAA2C,CAAC;AAC1F,OAAO,8BAA8B,MAAM,wCAAwC,CAAC;AACpF,OAAO,+BAA+B,MAAM,yCAAyC,CAAC;AACtF,OAAO,oCAAoC,MAAM,8CAA8C,CAAC;AAChG,OAAO,kCAAkC,MAAM,4CAA4C,CAAC;AAC5F,OAAO,iCAAiC,MAAM,+CAA+C,CAAC;AAC9F,OAAO,wCAAwC,MAAM,oDAAoD,CAAC;AAC1G,OAAO,gDAAgD,MAAM,6DAA6D,CAAC;AAC3H,OAAO,8BAA8B,MAAM,wCAAwC,CAAC;AACpF,OAAO,qCAAqC,MAAM,gDAAgD,CAAC;AACnG,OAAO,+BAA+B,MAAM,yCAAyC,CAAC;AAEtF,MAAM,CAAC,MAAM,4BAA4B,GAAG,mBAAmB,CAC7D,+BAA+B,CAChC,CAAC;AAEF,MAAM,CAAC,MAAM,8BAA8B,GAAG,mBAAmB,CAC/D,iCAAiC,CAClC,CAAC;AAEF,MAAM,CAAC,MAAM,+BAA+B,GAAG,mBAAmB,CAChE,kCAAkC,CACnC,CAAC;AAEF,MAAM,CAAC,MAAM,2BAA2B,GAAG,mBAAmB,CAC5D,8BAA8B,CAC/B,CAAC;AAEF,MAAM,CAAC,MAAM,iCAAiC,GAAG,mBAAmB,CAClE,oCAAoC,CACrC,CAAC;AAEF,MAAM,CAAC,MAAM,kCAAkC,GAAG,mBAAmB,CACnE,qCAAqC,CACtC,CAAC;AAEF,MAAM,CAAC,MAAM,qCAAqC,GAAG,mBAAmB,CACtE,wCAAwC,CACzC,CAAC;AAEF,MAAM,CAAC,MAAM,2BAA2B,GAAG,mBAAmB,CAC5D,8BAA8B,CAC/B,CAAC;AAEF,MAAM,CAAC,MAAM,6CAA6C,GACxD,mBAAmB,CAAC,gDAAgD,CAAC,CAAC;AAExE,MAAM,CAAC,MAAM,iCAAiC,GAAG,mBAAmB,CAClE,iCAAiC,CAClC,CAAC;AAEF,MAAM,CAAC,MAAM,4BAA4B,GAAG,mBAAmB,CAC7D,+BAA+B,CAChC,CAAC","sourcesContent":["/**\n *\n * Copyright (c) \"Neo4j\"\n * Neo4j Sweden AB [http://neo4j.com]\n *\n * This file is part of Neo4j.\n *\n * Neo4j is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\nexport { default as GraphVisualizationBarebones } from './graph-visualization-barebones.story';\nexport { default as GraphVisualizationCustom } from './graph-visualization-custom.story';\nexport { default as GraphVisualizationDefault } from './graph-visualization-default.story';\nexport { default as GraphVisualizationHighlighting } from './graph-visualization-highlighting.story';\nexport { default as GraphVisualizationMaximalist } from './graph-visualization-maximalist.story';\nexport { default as GraphVisualizationRangeStyling } from './graph-visualization-range-styling.story';\nexport { default as GraphVisualizationRuleBasedStylingAdvanced } from './graph-visualization-rule-based-styling-advanced.story';\nexport { default as GraphVisualizationRuleBasedStyling } from './graph-visualization-rule-based-styling.story';\nexport { default as GraphVisualizationSearch } from './graph-visualization-search.story';\nexport { default as GraphVisualizationSimpleStyling } from './graph-visualization-simple-styling.story';\nexport { default as PreviewGraphVisualization } from './preview-graph-visualization.story';\n\nimport { removeLicenseHeader } from '../utils';\nimport GraphVisualizationBarebonesSrcRaw from './graph-visualization-barebones.story?raw';\nimport GraphVisualizationCustomSrcRaw from './graph-visualization-custom.story?raw';\nimport GraphVisualizationDefaultSrcRaw from './graph-visualization-default.story?raw';\nimport GraphVisualizationHighlightingSrcRaw from './graph-visualization-highlighting.story?raw';\nimport GraphVisualizationMaximalistSrcRaw from './graph-visualization-maximalist.story?raw';\nimport GraphVisualizationRangeStylingRaw from './graph-visualization-range-styling.story?raw';\nimport GraphVisualizationRuleBasedStylingSrcRaw from './graph-visualization-rule-based-styling.story?raw';\nimport GraphVisualizationRuleBasedStylingAdvancedSrcRaw from './graph-visualization-rule-based-styling-advanced.story?raw';\nimport GraphVisualizationSearchSrcRaw from './graph-visualization-search.story?raw';\nimport GraphVisualizationSimpleStylingSrcRaw from './graph-visualization-simple-styling.story?raw';\nimport PreviewGraphVisualizationSrcRaw from './preview-graph-visualization.story?raw';\n\nexport const GraphVisualizationDefaultSrc = removeLicenseHeader(\n GraphVisualizationDefaultSrcRaw,\n);\n\nexport const GraphVisualizationBarebonesSrc = removeLicenseHeader(\n GraphVisualizationBarebonesSrcRaw,\n);\n\nexport const GraphVisualizationMaximalistSrc = removeLicenseHeader(\n GraphVisualizationMaximalistSrcRaw,\n);\n\nexport const GraphVisualizationCustomSrc = removeLicenseHeader(\n GraphVisualizationCustomSrcRaw,\n);\n\nexport const GraphVisualizationHighlightingSrc = removeLicenseHeader(\n GraphVisualizationHighlightingSrcRaw,\n);\n\nexport const GraphVisualizationSimpleStylingSrc = removeLicenseHeader(\n GraphVisualizationSimpleStylingSrcRaw,\n);\n\nexport const GraphVisualizationRuleBasedStylingSrc = removeLicenseHeader(\n GraphVisualizationRuleBasedStylingSrcRaw,\n);\n\nexport const GraphVisualizationSearchSrc = removeLicenseHeader(\n GraphVisualizationSearchSrcRaw,\n);\n\nexport const GraphVisualizationRuleBasedStylingAdvancedSrc =\n removeLicenseHeader(GraphVisualizationRuleBasedStylingAdvancedSrcRaw);\n\nexport const GraphVisualizationRangeStylingSrc = removeLicenseHeader(\n GraphVisualizationRangeStylingRaw,\n);\n\nexport const PreviewGraphVisualizationSrc = removeLicenseHeader(\n PreviewGraphVisualizationSrcRaw,\n);\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/stories/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,EAAE,OAAO,IAAI,2BAA2B,EAAE,MAAM,uCAAuC,CAAC;AAC/F,OAAO,EAAE,OAAO,IAAI,wBAAwB,EAAE,MAAM,oCAAoC,CAAC;AACzF,OAAO,EAAE,OAAO,IAAI,yBAAyB,EAAE,MAAM,qCAAqC,CAAC;AAC3F,OAAO,EAAE,OAAO,IAAI,8BAA8B,EAAE,MAAM,0CAA0C,CAAC;AACrG,OAAO,EAAE,OAAO,IAAI,4BAA4B,EAAE,MAAM,wCAAwC,CAAC;AACjG,OAAO,EAAE,OAAO,IAAI,8BAA8B,EAAE,MAAM,2CAA2C,CAAC;AACtG,OAAO,EAAE,OAAO,IAAI,0CAA0C,EAAE,MAAM,yDAAyD,CAAC;AAChI,OAAO,EAAE,OAAO,IAAI,kCAAkC,EAAE,MAAM,gDAAgD,CAAC;AAC/G,OAAO,EAAE,OAAO,IAAI,wBAAwB,EAAE,MAAM,oCAAoC,CAAC;AACzF,OAAO,EAAE,OAAO,IAAI,+BAA+B,EAAE,MAAM,4CAA4C,CAAC;AACxG,OAAO,EAAE,OAAO,IAAI,qCAAqC,EAAE,MAAM,mDAAmD,CAAC;AACrH,OAAO,EAAE,OAAO,IAAI,yBAAyB,EAAE,MAAM,qCAAqC,CAAC;AAE3F,OAAO,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAC;AAC/C,OAAO,iCAAiC,MAAM,2CAA2C,CAAC;AAC1F,OAAO,8BAA8B,MAAM,wCAAwC,CAAC;AACpF,OAAO,+BAA+B,MAAM,yCAAyC,CAAC;AACtF,OAAO,oCAAoC,MAAM,8CAA8C,CAAC;AAChG,OAAO,kCAAkC,MAAM,4CAA4C,CAAC;AAC5F,OAAO,iCAAiC,MAAM,+CAA+C,CAAC;AAC9F,OAAO,wCAAwC,MAAM,oDAAoD,CAAC;AAC1G,OAAO,gDAAgD,MAAM,6DAA6D,CAAC;AAC3H,OAAO,8BAA8B,MAAM,wCAAwC,CAAC;AACpF,OAAO,qCAAqC,MAAM,gDAAgD,CAAC;AACnG,OAAO,wCAAwC,MAAM,uDAAuD,CAAC;AAC7G,OAAO,+BAA+B,MAAM,yCAAyC,CAAC;AAEtF,MAAM,CAAC,MAAM,4BAA4B,GAAG,mBAAmB,CAC7D,+BAA+B,CAChC,CAAC;AAEF,MAAM,CAAC,MAAM,8BAA8B,GAAG,mBAAmB,CAC/D,iCAAiC,CAClC,CAAC;AAEF,MAAM,CAAC,MAAM,+BAA+B,GAAG,mBAAmB,CAChE,kCAAkC,CACnC,CAAC;AAEF,MAAM,CAAC,MAAM,2BAA2B,GAAG,mBAAmB,CAC5D,8BAA8B,CAC/B,CAAC;AAEF,MAAM,CAAC,MAAM,iCAAiC,GAAG,mBAAmB,CAClE,oCAAoC,CACrC,CAAC;AAEF,MAAM,CAAC,MAAM,kCAAkC,GAAG,mBAAmB,CACnE,qCAAqC,CACtC,CAAC;AAEF,MAAM,CAAC,MAAM,qCAAqC,GAAG,mBAAmB,CACtE,wCAAwC,CACzC,CAAC;AAEF,MAAM,CAAC,MAAM,2BAA2B,GAAG,mBAAmB,CAC5D,8BAA8B,CAC/B,CAAC;AAEF,MAAM,CAAC,MAAM,6CAA6C,GACxD,mBAAmB,CAAC,gDAAgD,CAAC,CAAC;AAExE,MAAM,CAAC,MAAM,iCAAiC,GAAG,mBAAmB,CAClE,iCAAiC,CAClC,CAAC;AAEF,MAAM,CAAC,MAAM,2CAA2C,GAAG,mBAAmB,CAC5E,wCAAwC,CACzC,CAAC;AAEF,MAAM,CAAC,MAAM,4BAA4B,GAAG,mBAAmB,CAC7D,+BAA+B,CAChC,CAAC","sourcesContent":["/**\n *\n * Copyright (c) \"Neo4j\"\n * Neo4j Sweden AB [http://neo4j.com]\n *\n * This file is part of Neo4j.\n *\n * Neo4j is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\nexport { default as GraphVisualizationBarebones } from './graph-visualization-barebones.story';\nexport { default as GraphVisualizationCustom } from './graph-visualization-custom.story';\nexport { default as GraphVisualizationDefault } from './graph-visualization-default.story';\nexport { default as GraphVisualizationHighlighting } from './graph-visualization-highlighting.story';\nexport { default as GraphVisualizationMaximalist } from './graph-visualization-maximalist.story';\nexport { default as GraphVisualizationRangeStyling } from './graph-visualization-range-styling.story';\nexport { default as GraphVisualizationRuleBasedStylingAdvanced } from './graph-visualization-rule-based-styling-advanced.story';\nexport { default as GraphVisualizationRuleBasedStyling } from './graph-visualization-rule-based-styling.story';\nexport { default as GraphVisualizationSearch } from './graph-visualization-search.story';\nexport { default as GraphVisualizationSimpleStyling } from './graph-visualization-simple-styling.story';\nexport { default as GraphVisualizationUniqueColorsStyling } from './graph-visualization-unique-colors-styling.story';\nexport { default as PreviewGraphVisualization } from './preview-graph-visualization.story';\n\nimport { removeLicenseHeader } from '../utils';\nimport GraphVisualizationBarebonesSrcRaw from './graph-visualization-barebones.story?raw';\nimport GraphVisualizationCustomSrcRaw from './graph-visualization-custom.story?raw';\nimport GraphVisualizationDefaultSrcRaw from './graph-visualization-default.story?raw';\nimport GraphVisualizationHighlightingSrcRaw from './graph-visualization-highlighting.story?raw';\nimport GraphVisualizationMaximalistSrcRaw from './graph-visualization-maximalist.story?raw';\nimport GraphVisualizationRangeStylingRaw from './graph-visualization-range-styling.story?raw';\nimport GraphVisualizationRuleBasedStylingSrcRaw from './graph-visualization-rule-based-styling.story?raw';\nimport GraphVisualizationRuleBasedStylingAdvancedSrcRaw from './graph-visualization-rule-based-styling-advanced.story?raw';\nimport GraphVisualizationSearchSrcRaw from './graph-visualization-search.story?raw';\nimport GraphVisualizationSimpleStylingSrcRaw from './graph-visualization-simple-styling.story?raw';\nimport GraphVisualizationUniqueColorsStylingRaw from './graph-visualization-unique-colors-styling.story?raw';\nimport PreviewGraphVisualizationSrcRaw from './preview-graph-visualization.story?raw';\n\nexport const GraphVisualizationDefaultSrc = removeLicenseHeader(\n GraphVisualizationDefaultSrcRaw,\n);\n\nexport const GraphVisualizationBarebonesSrc = removeLicenseHeader(\n GraphVisualizationBarebonesSrcRaw,\n);\n\nexport const GraphVisualizationMaximalistSrc = removeLicenseHeader(\n GraphVisualizationMaximalistSrcRaw,\n);\n\nexport const GraphVisualizationCustomSrc = removeLicenseHeader(\n GraphVisualizationCustomSrcRaw,\n);\n\nexport const GraphVisualizationHighlightingSrc = removeLicenseHeader(\n GraphVisualizationHighlightingSrcRaw,\n);\n\nexport const GraphVisualizationSimpleStylingSrc = removeLicenseHeader(\n GraphVisualizationSimpleStylingSrcRaw,\n);\n\nexport const GraphVisualizationRuleBasedStylingSrc = removeLicenseHeader(\n GraphVisualizationRuleBasedStylingSrcRaw,\n);\n\nexport const GraphVisualizationSearchSrc = removeLicenseHeader(\n GraphVisualizationSearchSrcRaw,\n);\n\nexport const GraphVisualizationRuleBasedStylingAdvancedSrc =\n removeLicenseHeader(GraphVisualizationRuleBasedStylingAdvancedSrcRaw);\n\nexport const GraphVisualizationRangeStylingSrc = removeLicenseHeader(\n GraphVisualizationRangeStylingRaw,\n);\n\nexport const GraphVisualizationUniqueColorsStylingRawSrc = removeLicenseHeader(\n GraphVisualizationUniqueColorsStylingRaw,\n);\n\nexport const PreviewGraphVisualizationSrc = removeLicenseHeader(\n PreviewGraphVisualizationSrcRaw,\n);\n"]}
@@ -33,6 +33,9 @@ import { calculateDefaultNodeColors } from '@neo4j-devtools/word-color';
33
33
  import { tokens } from '@neo4j-ndl/base';
34
34
  import { color, rgbToHex, validHex } from '@uiw/react-color';
35
35
  import { getWeight, lerpColor } from './color-interpolation';
36
+ export const DEFAULT_REL_COLOR = tokens.palette.neutral['40'];
37
+ const NO_LABEL_FALLBACK_COLOR = tokens.palette.neutral['40'];
38
+ export const UNIQUE_COLORS_PALETTE = Object.values(tokens.graph).filter(validHex);
36
39
  function compareByPriorityAscending(a, b) {
37
40
  return a.priority - b.priority;
38
41
  }
@@ -53,11 +56,11 @@ function collectStyleMatchers(styles) {
53
56
  const totalRules = styles.length;
54
57
  styles.forEach((style, index) => {
55
58
  var _a, _b, _c;
56
- if ((_a = style.disabled) !== null && _a !== void 0 ? _a : false) {
59
+ if ((_a = style.isDisabled) !== null && _a !== void 0 ? _a : false) {
57
60
  return;
58
61
  }
59
62
  if (style.priority !== undefined && style.priority < 0) {
60
- throw new Error(`StyleRule priority must be >= 0, got ${style.priority}. Negative values are reserved for internal use.`);
63
+ throw new Error(`GraphStyleRule priority must be >= 0, got ${style.priority}. Negative values are reserved for internal use.`);
61
64
  }
62
65
  // Fill in priority if not set (negative values preserve original order)
63
66
  const { priority } = style, rest = __rest(style, ["priority"]);
@@ -298,9 +301,57 @@ function evaluateWhere(node, where) {
298
301
  }
299
302
  return false;
300
303
  }
301
- function evaluateRelStyle(apply, rel) {
302
- var _a;
303
- const result = Object.assign(Object.assign({}, apply), { captions: (_a = apply.captions) === null || _a === void 0 ? void 0 : _a.map((caption) => {
304
+ /**
305
+ * Resolves a color for the given property value, using the uniqueColors object
306
+ * reference as the per-rule key in uniqueColorsCache. Assigns a new palette color
307
+ * on first encounter (first-come, first-served). Returns null if the property is
308
+ * missing or null.
309
+ */
310
+ function resolveUniqueColor(uniqueColors, properties, uniqueColorsCache) {
311
+ const prop = properties[uniqueColors.onProperty];
312
+ if (prop === undefined) {
313
+ return null;
314
+ }
315
+ const rawValue = extractPropertyValue(prop);
316
+ if (rawValue === null) {
317
+ return null;
318
+ }
319
+ const valueKey = String(rawValue);
320
+ let valueMap = uniqueColorsCache.get(uniqueColors);
321
+ if (valueMap === undefined) {
322
+ valueMap = new Map();
323
+ uniqueColorsCache.set(uniqueColors, valueMap);
324
+ }
325
+ let assignedColor = valueMap.get(valueKey);
326
+ if (assignedColor === undefined) {
327
+ assignedColor =
328
+ UNIQUE_COLORS_PALETTE[valueMap.size % UNIQUE_COLORS_PALETTE.length];
329
+ valueMap.set(valueKey, assignedColor);
330
+ }
331
+ return assignedColor;
332
+ }
333
+ function shouldUseProperty(prop) {
334
+ return prop !== undefined && prop.isDisabled !== true;
335
+ }
336
+ function evaluateStaticStyle(_a) {
337
+ var { overlayIcon } = _a, scalarStyle = __rest(_a, ["overlayIcon"]);
338
+ const result = {};
339
+ for (const [key, prop] of Object.entries(scalarStyle)) {
340
+ if (shouldUseProperty(prop)) {
341
+ result[key] = prop.value;
342
+ }
343
+ }
344
+ if (shouldUseProperty(overlayIcon)) {
345
+ const _b = overlayIcon, { isDisabled } = _b, overlayIconProps = __rest(_b, ["isDisabled"]);
346
+ result.overlayIcon = overlayIconProps;
347
+ }
348
+ return result;
349
+ }
350
+ function evaluateRelStyle(style, rel, uniqueColorsCache) {
351
+ const { captions, colorRange, widthRange, sizeRange, uniqueColors } = style, staticStyle = __rest(style, ["captions", "colorRange", "widthRange", "sizeRange", "uniqueColors"]);
352
+ const result = evaluateStaticStyle(staticStyle);
353
+ if (shouldUseProperty(captions) && captions.text) {
354
+ result.captions = captions.text.map((caption) => {
304
355
  const { value, styles } = caption;
305
356
  if (typeof value === 'string' || value === undefined) {
306
357
  return { styles, value };
@@ -319,20 +370,33 @@ function evaluateRelStyle(apply, rel) {
319
370
  return { styles, value: resolvedValue };
320
371
  }
321
372
  return { styles, value: rel.id };
322
- }) });
323
- if (apply.colorRange !== undefined) {
324
- const interpolated = getInterpolatedColor(apply.colorRange, rel);
373
+ });
374
+ if ((captions === null || captions === void 0 ? void 0 : captions.align) !== undefined) {
375
+ result.captionAlign = captions.align;
376
+ }
377
+ if ((captions === null || captions === void 0 ? void 0 : captions.size) !== undefined) {
378
+ result.captionSize = captions.size;
379
+ }
380
+ }
381
+ if (shouldUseProperty(colorRange)) {
382
+ const interpolated = getInterpolatedColor(colorRange, rel);
325
383
  if (interpolated !== null) {
326
384
  result.color = interpolated;
327
385
  }
328
386
  }
329
- if (apply.relWidthRange !== undefined) {
330
- const { onProperty, minValue, maxValue, minWidth, maxWidth } = apply.relWidthRange;
387
+ if (shouldUseProperty(widthRange)) {
388
+ const { onProperty, minValue, maxValue, minWidth, maxWidth } = widthRange;
331
389
  const interpolated = getInterpolatedSize(rel.properties[onProperty], minValue, maxValue, minWidth, maxWidth);
332
390
  if (interpolated !== null) {
333
391
  result.width = interpolated;
334
392
  }
335
393
  }
394
+ if (shouldUseProperty(uniqueColors)) {
395
+ const color = resolveUniqueColor(uniqueColors, rel.properties, uniqueColorsCache);
396
+ if (color !== null) {
397
+ result.color = color;
398
+ }
399
+ }
336
400
  return result;
337
401
  }
338
402
  /**
@@ -427,44 +491,63 @@ function getDefaultNodeCaption(node) {
427
491
  }
428
492
  return { value: node.id };
429
493
  }
430
- function evaluateNodeStyle(apply, node) {
431
- var _a;
432
- const result = Object.assign(Object.assign({}, apply), { captions: ((_a = apply.captions) !== null && _a !== void 0 ? _a : [getDefaultNodeCaption(node)]).map((caption) => {
433
- const { value, styles } = caption;
434
- if (typeof value === 'string' || value === undefined) {
435
- return { styles, value };
436
- }
437
- if ('useType' in value) {
438
- return { styles, value: node.labelsSorted[0] };
439
- }
440
- if ('property' in value) {
441
- const prop = node.properties[value.property];
442
- if (prop === undefined) {
443
- return { styles, value: '' };
444
- }
445
- const resolvedValue = prop.type === 'string'
446
- ? prop.stringified.slice(1, -1)
447
- : prop.stringified;
448
- return { styles, value: resolvedValue };
449
- }
494
+ function evaluateNodeStyle(style, node, uniqueColorsCache) {
495
+ const { captions, colorRange, sizeRange, widthRange, uniqueColors } = style, staticStyle = __rest(style, ["captions", "colorRange", "sizeRange", "widthRange", "uniqueColors"]);
496
+ const result = evaluateStaticStyle(staticStyle);
497
+ const captionSource = shouldUseProperty(captions) && captions.text
498
+ ? captions.text
499
+ : [getDefaultNodeCaption(node)];
500
+ result.captions = captionSource.map((caption) => {
501
+ const { value, styles } = caption;
502
+ if (typeof value === 'string' || value === undefined) {
503
+ return { styles, value };
504
+ }
505
+ if ('useType' in value) {
450
506
  return { styles, value: node.labelsSorted[0] };
451
- }) });
452
- if (apply.colorRange !== undefined) {
453
- const interpolated = getInterpolatedColor(apply.colorRange, node);
507
+ }
508
+ if ('property' in value) {
509
+ const prop = node.properties[value.property];
510
+ if (prop === undefined) {
511
+ return { styles, value: '' };
512
+ }
513
+ const resolvedValue = prop.type === 'string'
514
+ ? prop.stringified.slice(1, -1)
515
+ : prop.stringified;
516
+ return { styles, value: resolvedValue };
517
+ }
518
+ return { styles, value: node.labelsSorted[0] };
519
+ });
520
+ if (shouldUseProperty(captions)) {
521
+ if ((captions === null || captions === void 0 ? void 0 : captions.align) !== undefined) {
522
+ result.captionAlign = captions.align;
523
+ }
524
+ if ((captions === null || captions === void 0 ? void 0 : captions.size) !== undefined) {
525
+ result.captionSize = captions.size;
526
+ }
527
+ }
528
+ if (shouldUseProperty(colorRange)) {
529
+ const interpolated = getInterpolatedColor(colorRange, node);
454
530
  if (interpolated !== null) {
455
531
  result.color = interpolated;
456
532
  }
457
533
  }
458
- if (apply.nodeSizeRange !== undefined) {
459
- const { onProperty, minValue, maxValue, minSize, maxSize } = apply.nodeSizeRange;
534
+ if (shouldUseProperty(sizeRange)) {
535
+ const { onProperty, minValue, maxValue, minSize, maxSize } = sizeRange;
460
536
  const interpolated = getInterpolatedSize(node.properties[onProperty], minValue, maxValue, minSize, maxSize);
461
537
  if (interpolated !== null) {
462
538
  result.size = interpolated;
463
539
  }
464
540
  }
541
+ if (shouldUseProperty(uniqueColors)) {
542
+ const color = resolveUniqueColor(uniqueColors, node.properties, uniqueColorsCache);
543
+ if (color !== null) {
544
+ result.color = color;
545
+ }
546
+ }
465
547
  return result;
466
548
  }
467
549
  function createRelStyleFunction(rules) {
550
+ const uniqueColorsCache = new Map();
468
551
  return (rel) => {
469
552
  const style = {};
470
553
  // evaluateWhere uses Cypher-style three-valued logic (true/false/null).
@@ -479,23 +562,22 @@ function createRelStyleFunction(rules) {
479
562
  }
480
563
  }
481
564
  }
482
- return evaluateRelStyle(style, rel);
565
+ return evaluateRelStyle(style, rel, uniqueColorsCache);
483
566
  };
484
567
  }
485
- export const DEFAULT_REL_COLOR = tokens.palette.neutral['40'];
486
- const NO_LABEL_FALLBACK_COLOR = tokens.palette.neutral['40'];
487
568
  function createByLabelSetFunction(styleMatchers) {
488
569
  const defaultColorCache = new Map();
489
570
  const sortedRulesCache = new Map();
490
571
  const mergedStyleCache = new Map();
572
+ const uniqueColorsCache = new Map();
491
573
  return (node) => {
492
574
  var _a;
493
575
  const labelSetKey = node.labelsSorted.join('\0');
494
- // Fast path: if all rules for this label set are where-free,
495
- // the merged style is identical for every node with the same labels.
576
+ // Fast path: if all rules for this label set are where-free and none use
577
+ // uniqueColors, the merged style is identical for every node with the same labels.
496
578
  const cachedStyle = mergedStyleCache.get(labelSetKey);
497
579
  if (cachedStyle !== undefined) {
498
- return evaluateNodeStyle(cachedStyle, node);
580
+ return evaluateNodeStyle(cachedStyle, node, uniqueColorsCache);
499
581
  }
500
582
  // Memoize default color by first label
501
583
  const labelForDefaultColor = (_a = node.labelsSorted[0]) !== null && _a !== void 0 ? _a : null;
@@ -515,7 +597,9 @@ function createByLabelSetFunction(styleMatchers) {
515
597
  // Cache sorted rules by label set (avoids repeated allocation + sort)
516
598
  let sortedRules = sortedRulesCache.get(labelSetKey);
517
599
  if (sortedRules === undefined) {
518
- const matchingRules = [...styleMatchers.globalLabelRules];
600
+ const matchingRules = [
601
+ ...styleMatchers.globalLabelRules,
602
+ ];
519
603
  for (const label of node.labelsSorted) {
520
604
  const labelRules = styleMatchers.rulesByLabel.get(label);
521
605
  if (labelRules) {
@@ -525,36 +609,35 @@ function createByLabelSetFunction(styleMatchers) {
525
609
  sortedRules = matchingRules.toSorted(compareByPriorityAscending);
526
610
  sortedRulesCache.set(labelSetKey, sortedRules);
527
611
  }
528
- // Evaluate rules, tracking whether all are where-free
529
- const collectStyles = { color: defaultColor };
530
- let isAllWhereFree = true;
612
+ // Evaluate rules, tracking whether all are where-free and uniqueColors-free.
613
+ const collectStyles = { color: { value: defaultColor } };
614
+ let isCacheable = true;
531
615
  for (const rule of sortedRules) {
532
- if (rule.where !== undefined) {
533
- isAllWhereFree = false;
534
- if (evaluateWhere(node, rule.where) === true) {
535
- Object.assign(collectStyles, rule.apply);
536
- }
616
+ if (rule.where !== undefined || rule.apply.uniqueColors !== undefined) {
617
+ isCacheable = false;
537
618
  }
538
- else {
619
+ const shouldApplyRule = rule.where === undefined || evaluateWhere(node, rule.where) === true;
620
+ if (shouldApplyRule) {
539
621
  Object.assign(collectStyles, rule.apply);
540
622
  }
541
623
  }
542
- // When all rules are where-free, the merged style depends only on labels.
543
- // Cache it so subsequent nodes with the same label set skip rule iteration.
544
- if (isAllWhereFree) {
624
+ // When all rules are where-free and uniqueColors-free, the merged style
625
+ // depends only on labels. Cache it so subsequent nodes with the same label
626
+ // set skip rule iteration.
627
+ if (isCacheable) {
545
628
  mergedStyleCache.set(labelSetKey, collectStyles);
546
629
  }
547
- return evaluateNodeStyle(collectStyles, node);
630
+ return evaluateNodeStyle(collectStyles, node, uniqueColorsCache);
548
631
  };
549
632
  }
550
633
  const DEFAULT_REL_STYLE = {
551
634
  match: { reltype: null },
552
635
  apply: {
553
- color: DEFAULT_REL_COLOR,
554
- captions: [{ value: { useType: true } }],
636
+ color: { value: DEFAULT_REL_COLOR },
637
+ captions: { text: [{ value: { useType: true } }] },
555
638
  },
556
639
  };
557
- export function compileStyleRules(styleRules) {
640
+ export function compileGraphStyleRules(styleRules) {
558
641
  const styleMatchers = collectStyleMatchers(styleRules);
559
642
  // Lazily build and cache a style function per relationship type
560
643
  const cache = new Map();
@@ -1 +1 @@
1
- {"version":3,"file":"compile-graph-styles.js","sourceRoot":"","sources":["../../../src/styling/compile-graph-styles.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n *\n * Copyright (c) \"Neo4j\"\n * Neo4j Sweden AB [http://neo4j.com]\n *\n * This file is part of Neo4j.\n *\n * Neo4j is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\nimport { calculateDefaultNodeColors } from '@neo4j-devtools/word-color';\nimport { tokens } from '@neo4j-ndl/base';\nimport { color, type RgbColor, rgbToHex, validHex } from '@uiw/react-color';\n\nimport {\n type NodeData,\n type PortableProperty,\n type RelData,\n} from '../graph-visualization-context';\nimport { getWeight, lerpColor } from './color-interpolation';\nimport {\n type Caption,\n type ColorRange,\n type CypherValue,\n type EvaluatedNvlNodeStyle,\n type EvaluatedNvlRelationshipStyle,\n type Style,\n type StyleRule,\n type Value,\n type Where,\n} from './style-types';\n\ntype StyleMatchers = {\n globalLabelRules: StyleRule[];\n globalReltypeRules: StyleRule[];\n rulesByLabel: Map<string, StyleRule[]>;\n rulesByType: Map<string, StyleRule[]>;\n};\n\nfunction compareByPriorityAscending(a: StyleRule, b: StyleRule): number {\n return a.priority! - b.priority!;\n}\n\nfunction collectStyleMatchers(\n styles: StyleRule[] | null | undefined,\n): StyleMatchers {\n const rulesByLabel = new Map<string, StyleRule[]>();\n const rulesByType = new Map<string, StyleRule[]>();\n const globalLabelRules: StyleRule[] = [];\n const globalReltypeRules: StyleRule[] = [];\n\n // Handle null/undefined styles gracefully\n if (!styles || styles.length === 0) {\n return {\n globalLabelRules,\n globalReltypeRules,\n rulesByLabel,\n rulesByType,\n };\n }\n\n const totalRules = styles.length;\n\n styles.forEach((style, index) => {\n if (style.disabled ?? false) {\n return;\n }\n\n if (style.priority !== undefined && style.priority < 0) {\n throw new Error(\n `StyleRule priority must be >= 0, got ${style.priority}. Negative values are reserved for internal use.`,\n );\n }\n\n // Fill in priority if not set (negative values preserve original order)\n const { priority, ...rest } = style;\n const ruleWithPriority: StyleRule = {\n ...rest,\n priority: priority ?? index - totalRules,\n };\n\n // style for nodes\n if ('label' in style.match) {\n // if the label is null, it's a global rule (matches any node)\n if (style.match.label === null) {\n globalLabelRules.push(ruleWithPriority);\n } else {\n // Specific label rule\n const existing = rulesByLabel.get(style.match.label) ?? [];\n rulesByLabel.set(style.match.label, [...existing, ruleWithPriority]);\n }\n }\n\n // style for relationships\n if ('reltype' in style.match) {\n if (style.match.reltype === null) {\n // Global reltype rule (matches any relationship)\n globalReltypeRules.push(ruleWithPriority);\n } else {\n // Specific reltype rule\n const existing = rulesByType.get(style.match.reltype) ?? [];\n rulesByType.set(style.match.reltype, [...existing, ruleWithPriority]);\n }\n }\n });\n\n return {\n globalLabelRules,\n globalReltypeRules,\n rulesByLabel,\n rulesByType,\n };\n}\n\n/**\n * Interpolates a color from a ColorRange based on a graph item's property value.\n * Returns a #rrggbb hex string, or null if the colorRange config is invalid\n * (bad hex colors, invalid value range, missing/non-numeric property).\n */\nfunction getInterpolatedColor(\n colorRange: ColorRange,\n graphItem: NodeData | RelData,\n): string | null {\n const {\n onProperty,\n minValue,\n minColor,\n maxValue,\n maxColor,\n midValue,\n midColor,\n } = colorRange;\n\n if (!validHex(minColor) || !validHex(maxColor)) {\n return null;\n }\n const minRgb = color(minColor).rgb;\n const maxRgb = color(maxColor).rgb;\n // min/max can be inverted, we need to now which one is bigger\n const actualMinValue = Math.min(minValue, maxValue);\n const actualMaxValue = Math.max(minValue, maxValue);\n\n // Validate mid stop if provided\n let midRgb: RgbColor | undefined = undefined;\n if (midValue !== undefined && midColor !== undefined) {\n const isMidInRange =\n actualMinValue <= midValue && midValue <= actualMaxValue;\n if (!isMidInRange || !validHex(midColor)) {\n return null;\n }\n midRgb = color(midColor).rgb;\n }\n\n const prop = graphItem.properties[onProperty];\n if (prop === undefined) {\n return null;\n }\n const rawValue = extractPropertyValue(prop);\n if (typeof rawValue !== 'number') {\n return null;\n }\n\n const clampedValue = Math.max(\n actualMinValue,\n Math.min(actualMaxValue, rawValue),\n );\n\n let rgb: RgbColor;\n\n if (midRgb !== undefined && midValue !== undefined) {\n const t = getWeight(minValue, midValue, clampedValue);\n const isBetweenMinAndMid = t <= 1;\n if (isBetweenMinAndMid) {\n rgb = lerpColor(minRgb, midRgb, t);\n } else {\n const t = getWeight(midValue, maxValue, clampedValue);\n rgb = lerpColor(midRgb, maxRgb, t);\n }\n } else {\n const t = getWeight(minValue, maxValue, clampedValue);\n rgb = lerpColor(minRgb, maxRgb, t);\n }\n\n return rgbToHex(rgb);\n}\n\n/**\n * Interpolates a numeric size/width from a range based on a graph item's property value.\n * Returns the interpolated number, or null if the property is missing or non-numeric.\n */\nfunction getInterpolatedSize(\n prop: PortableProperty | undefined,\n minValue: number,\n maxValue: number,\n minOut: number,\n maxOut: number,\n): number | null {\n if (prop === undefined) {\n return null;\n }\n const rawValue = extractPropertyValue(prop);\n if (typeof rawValue !== 'number') {\n return null;\n }\n\n const actualMinValue = Math.min(minValue, maxValue);\n const actualMaxValue = Math.max(minValue, maxValue);\n const clampedValue = Math.max(\n actualMinValue,\n Math.min(actualMaxValue, rawValue),\n );\n const t = getWeight(minValue, maxValue, clampedValue);\n return minOut * (1 - t) + maxOut * t;\n}\n\nfunction extractPropertyValue(\n prop: PortableProperty,\n): string | number | boolean | null {\n switch (prop.type) {\n case 'string':\n return JSON.parse(prop.stringified);\n case 'number':\n case 'integer':\n case 'float':\n return Number(prop.stringified);\n case 'boolean':\n case 'Boolean':\n return prop.stringified === 'true';\n case 'null':\n return null;\n default:\n return prop.stringified;\n }\n}\n\n/**\n * Three-valued logic type matching Cypher/SQL semantics.\n * - `true`: condition is satisfied\n * - `false`: condition is not satisfied\n * - `null`: condition is unknown (e.g., comparing with null/missing property)\n *\n * @see https://neo4j.com/docs/cypher-manual/current/values-and-types/working-with-null/\n */\ntype Ternary = boolean | null;\n\n/**\n * Evaluates a WHERE clause using three-valued logic matching Cypher semantics.\n *\n * From Neo4j Cypher Manual:\n * - Comparing any value to `null` results in `null`, not `true` or `false`\n * - Accessing a non-existent property returns `null`\n * - In WHERE clauses, only `true` passes; both `false` and `null` exclude the row\n *\n * Three-valued logic rules:\n * - NOT null → null\n * - true AND null → null, false AND null → false\n * - true OR null → true, false OR null → null\n *\n * @see https://neo4j.com/docs/cypher-manual/current/values-and-types/working-with-null/\n */\nfunction evaluateWhere(node: NodeData | RelData, where?: Where): Ternary {\n if (!where) {\n return true;\n }\n\n if ('equal' in where) {\n const [left, right] = where.equal;\n const leftVal = evaluateValue(left, node);\n const rightVal = evaluateValue(right, node);\n // In Cypher, null = null → null (not true)\n if (leftVal === null || rightVal === null) {\n return null;\n }\n return leftVal === rightVal;\n }\n\n if ('not' in where) {\n // Cypher: NOT null → null\n const isMatch = evaluateWhere(node, where.not);\n return isMatch === null ? null : !isMatch;\n }\n\n if ('lessThan' in where) {\n const [left, right] = where.lessThan;\n return safeCompare(left, right, node, (a, b) => a < b);\n }\n\n if ('lessThanOrEqual' in where) {\n const [left, right] = where.lessThanOrEqual;\n return safeCompare(left, right, node, (a, b) => a <= b);\n }\n\n if ('greaterThan' in where) {\n const [left, right] = where.greaterThan;\n return safeCompare(left, right, node, (a, b) => a > b);\n }\n\n if ('greaterThanOrEqual' in where) {\n const [left, right] = where.greaterThanOrEqual;\n return safeCompare(left, right, node, (a, b) => a >= b);\n }\n\n if ('contains' in where) {\n const [left, right] = where.contains;\n return safeStringCompare(left, right, node, (a, b) => a.includes(b));\n }\n\n if ('startsWith' in where) {\n const [left, right] = where.startsWith;\n return safeStringCompare(left, right, node, (a, b) => a.startsWith(b));\n }\n\n if ('endsWith' in where) {\n const [left, right] = where.endsWith;\n return safeStringCompare(left, right, node, (a, b) => a.endsWith(b));\n }\n\n if ('isNull' in where) {\n // IS NULL returns true/false (never null)\n const value = evaluateValue(where.isNull, node);\n return value === null;\n }\n\n if ('and' in where) {\n // Cypher three-valued AND:\n // - If any is false → false\n // - Else if any is null → null\n // - Else → true\n let hasNull = false;\n for (const r of where.and) {\n const isMatch = evaluateWhere(node, r);\n if (isMatch === false) {\n return false;\n }\n if (isMatch === null) {\n hasNull = true;\n }\n }\n return hasNull ? null : true;\n }\n\n if ('or' in where) {\n // Cypher three-valued OR:\n // - If any is true → true\n // - Else if any is null → null\n // - Else → false\n let hasNull = false;\n for (const r of where.or) {\n const isMatch = evaluateWhere(node, r);\n if (isMatch === true) {\n return true;\n }\n if (isMatch === null) {\n hasNull = true;\n }\n }\n return hasNull ? null : false;\n }\n\n if ('label' in where) {\n if ('labelsSorted' in node) {\n return where.label === null || node.labelsSorted.includes(where.label);\n }\n return false;\n }\n\n if ('reltype' in where) {\n if ('type' in node) {\n return where.reltype === null || (node as RelData).type === where.reltype;\n }\n return false;\n }\n\n if ('property' in where) {\n return where.property === null || where.property in node.properties;\n }\n\n return false;\n}\n\nfunction evaluateRelStyle(\n apply: Style,\n rel: RelData,\n): EvaluatedNvlRelationshipStyle {\n const result: EvaluatedNvlRelationshipStyle = {\n ...apply,\n captions: apply.captions?.map((caption) => {\n const { value, styles } = caption;\n\n if (typeof value === 'string' || value === undefined) {\n return { styles, value };\n }\n\n if ('useType' in value) {\n return { styles, value: rel.type };\n }\n\n if ('property' in value) {\n const prop = rel.properties[value.property];\n if (prop === undefined) {\n return { styles, value: '' };\n }\n\n const resolvedValue =\n prop.type === 'string'\n ? prop.stringified.slice(1, -1)\n : prop.stringified;\n\n return { styles, value: resolvedValue };\n }\n\n return { styles, value: rel.id };\n }),\n };\n\n if (apply.colorRange !== undefined) {\n const interpolated = getInterpolatedColor(apply.colorRange, rel);\n if (interpolated !== null) {\n result.color = interpolated;\n }\n }\n\n if (apply.relWidthRange !== undefined) {\n const { onProperty, minValue, maxValue, minWidth, maxWidth } =\n apply.relWidthRange;\n const interpolated = getInterpolatedSize(\n rel.properties[onProperty],\n minValue,\n maxValue,\n minWidth,\n maxWidth,\n );\n if (interpolated !== null) {\n result.width = interpolated;\n }\n }\n\n return result;\n}\n\n/**\n * Safely compare two values using Cypher's three-valued logic.\n * Returns `null` if either operand is null (matching Cypher semantics).\n *\n * From Neo4j Cypher Manual:\n * \"Comparing any value to `null` using `=` or `<>` results in `null`\"\n *\n * @see https://neo4j.com/docs/cypher-manual/current/values-and-types/working-with-null/\n */\nfunction safeCompare(\n left: Value,\n right: Value,\n graphItem: NodeData | RelData,\n compareFn: (\n a: NonNullable<CypherValue>,\n b: NonNullable<CypherValue>,\n ) => boolean,\n): Ternary {\n const leftVal = evaluateValue(left, graphItem);\n const rightVal = evaluateValue(right, graphItem);\n if (leftVal === null || rightVal === null) {\n return null;\n }\n return compareFn(leftVal, rightVal);\n}\n\n/**\n * String comparison using Cypher semantics.\n * Returns `null` if either operand is null OR not a string.\n *\n * From Neo4j Cypher Manual:\n * \"When these operators are applied to non-string values, they return `null`\n * instead of attempting type coercion.\"\n *\n * @see https://neo4j.com/docs/cypher-manual/current/expressions/predicates/string-operators/\n */\nfunction safeStringCompare(\n left: Value,\n right: Value,\n graphItem: NodeData | RelData,\n compareFn: (a: string, b: string) => boolean,\n): Ternary {\n const leftVal = evaluateValue(left, graphItem);\n const rightVal = evaluateValue(right, graphItem);\n // Return null if either is null or not a string (no type coercion)\n if (\n leftVal === null ||\n rightVal === null ||\n typeof leftVal !== 'string' ||\n typeof rightVal !== 'string'\n ) {\n return null;\n }\n return compareFn(leftVal, rightVal);\n}\n\nfunction evaluateValue(\n value: Value,\n graphItem: NodeData | RelData,\n): CypherValue {\n if (typeof value === 'object' && value !== null) {\n if ('property' in value) {\n if (value.property === null) {\n return null;\n }\n const prop = graphItem.properties[value.property];\n if (prop === undefined) {\n return null;\n }\n return extractPropertyValue(prop);\n }\n if ('label' in value) {\n if ('labelsSorted' in graphItem) {\n return (\n value.label === null || graphItem.labelsSorted.includes(value.label)\n );\n }\n return false;\n }\n if ('reltype' in value) {\n if ('type' in graphItem) {\n return (\n value.reltype === null ||\n (graphItem as RelData).type === value.reltype\n );\n }\n return false;\n }\n }\n\n return value;\n}\n\n// Default caption selection logic\nconst captionPriorityOrder = [\n /^name$/i,\n /^title$/i,\n /^label$/i,\n /name$/i,\n /description$/i,\n /^.+/,\n];\n\nfunction getDefaultNodeCaption(node: NodeData): Caption {\n const propertyKeys = Object.keys(node.properties);\n\n for (const regex of captionPriorityOrder) {\n const matchingKey = propertyKeys.find((key) => regex.test(key));\n if (matchingKey !== undefined) {\n const prop = node.properties[matchingKey];\n if (prop !== undefined) {\n return { value: { property: matchingKey } };\n }\n }\n }\n\n if (node.labelsSorted[0] !== undefined) {\n return { value: { useType: true } };\n }\n\n return { value: node.id };\n}\n\nfunction evaluateNodeStyle(\n apply: Style,\n node: NodeData,\n): EvaluatedNvlNodeStyle {\n const result: EvaluatedNvlNodeStyle = {\n ...apply,\n captions: (apply.captions ?? [getDefaultNodeCaption(node)]).map(\n (caption) => {\n const { value, styles } = caption;\n\n if (typeof value === 'string' || value === undefined) {\n return { styles, value };\n }\n\n if ('useType' in value) {\n return { styles, value: node.labelsSorted[0] };\n }\n\n if ('property' in value) {\n const prop = node.properties[value.property];\n if (prop === undefined) {\n return { styles, value: '' };\n }\n\n const resolvedValue =\n prop.type === 'string'\n ? prop.stringified.slice(1, -1)\n : prop.stringified;\n\n return { styles, value: resolvedValue };\n }\n\n return { styles, value: node.labelsSorted[0] };\n },\n ),\n };\n\n if (apply.colorRange !== undefined) {\n const interpolated = getInterpolatedColor(apply.colorRange, node);\n if (interpolated !== null) {\n result.color = interpolated;\n }\n }\n\n if (apply.nodeSizeRange !== undefined) {\n const { onProperty, minValue, maxValue, minSize, maxSize } =\n apply.nodeSizeRange;\n const interpolated = getInterpolatedSize(\n node.properties[onProperty],\n minValue,\n maxValue,\n minSize,\n maxSize,\n );\n if (interpolated !== null) {\n result.size = interpolated;\n }\n }\n\n return result;\n}\n\nfunction createRelStyleFunction(\n rules: StyleRule[],\n): (rel: RelData) => EvaluatedNvlRelationshipStyle {\n return (rel: RelData) => {\n const style: Style = {};\n\n // evaluateWhere uses Cypher-style three-valued logic (true/false/null).\n // Only `true` passes; both `false` and `null` (unknown) skip the rule.\n for (const rule of rules) {\n // Check if the rule applies to this relationship\n if ('reltype' in rule.match) {\n const isReltypeMatch =\n rule.match.reltype === null || rel.type === rule.match.reltype;\n\n if (isReltypeMatch && evaluateWhere(rel, rule.where) === true) {\n // Merge the style properties (later rules override earlier ones)\n Object.assign(style, rule.apply);\n }\n }\n }\n\n return evaluateRelStyle(style, rel);\n };\n}\n\nexport type CompiledStyleRules = {\n byType: (type: string) => (rel: RelData) => EvaluatedNvlRelationshipStyle;\n styleMatchers: StyleMatchers;\n byLabelSet: (node: NodeData) => EvaluatedNvlNodeStyle;\n};\n\nexport const DEFAULT_REL_COLOR = tokens.palette.neutral['40'];\nconst NO_LABEL_FALLBACK_COLOR = tokens.palette.neutral['40'];\n\nfunction createByLabelSetFunction(\n styleMatchers: StyleMatchers,\n): (node: NodeData) => EvaluatedNvlNodeStyle {\n const defaultColorCache = new Map<string, string>();\n const sortedRulesCache = new Map<string, StyleRule[]>();\n const mergedStyleCache = new Map<string, Style>();\n\n return (node: NodeData) => {\n const labelSetKey = node.labelsSorted.join('\\0');\n\n // Fast path: if all rules for this label set are where-free,\n // the merged style is identical for every node with the same labels.\n const cachedStyle = mergedStyleCache.get(labelSetKey);\n if (cachedStyle !== undefined) {\n return evaluateNodeStyle(cachedStyle, node);\n }\n\n // Memoize default color by first label\n const labelForDefaultColor = node.labelsSorted[0] ?? null;\n let defaultColor: string;\n if (labelForDefaultColor === null) {\n defaultColor = NO_LABEL_FALLBACK_COLOR;\n } else {\n let cached = defaultColorCache.get(labelForDefaultColor);\n if (cached === undefined) {\n cached =\n calculateDefaultNodeColors(labelForDefaultColor).backgroundColor;\n defaultColorCache.set(labelForDefaultColor, cached);\n }\n defaultColor = cached;\n }\n\n // Cache sorted rules by label set (avoids repeated allocation + sort)\n let sortedRules = sortedRulesCache.get(labelSetKey);\n if (sortedRules === undefined) {\n const matchingRules: StyleRule[] = [...styleMatchers.globalLabelRules];\n for (const label of node.labelsSorted) {\n const labelRules = styleMatchers.rulesByLabel.get(label);\n if (labelRules) {\n matchingRules.push(...labelRules);\n }\n }\n sortedRules = matchingRules.toSorted(compareByPriorityAscending);\n sortedRulesCache.set(labelSetKey, sortedRules);\n }\n\n // Evaluate rules, tracking whether all are where-free\n const collectStyles: Style = { color: defaultColor };\n let isAllWhereFree = true;\n for (const rule of sortedRules) {\n if (rule.where !== undefined) {\n isAllWhereFree = false;\n if (evaluateWhere(node, rule.where) === true) {\n Object.assign(collectStyles, rule.apply);\n }\n } else {\n Object.assign(collectStyles, rule.apply);\n }\n }\n\n // When all rules are where-free, the merged style depends only on labels.\n // Cache it so subsequent nodes with the same label set skip rule iteration.\n if (isAllWhereFree) {\n mergedStyleCache.set(labelSetKey, collectStyles);\n }\n\n return evaluateNodeStyle(collectStyles, node);\n };\n}\n\nconst DEFAULT_REL_STYLE: StyleRule = {\n match: { reltype: null },\n apply: {\n color: DEFAULT_REL_COLOR,\n captions: [{ value: { useType: true } }],\n },\n};\n\nexport function compileStyleRules(\n styleRules: StyleRule[] | null | undefined,\n): CompiledStyleRules {\n const styleMatchers = collectStyleMatchers(styleRules);\n\n // Lazily build and cache a style function per relationship type\n const cache = new Map<\n string,\n (rel: RelData) => EvaluatedNvlRelationshipStyle\n >();\n const byType = (type: string) => {\n let fn = cache.get(type);\n if (fn === undefined) {\n const rules = styleMatchers.rulesByType.get(type) ?? [];\n fn = createRelStyleFunction([\n DEFAULT_REL_STYLE,\n ...styleMatchers.globalReltypeRules,\n ...rules,\n ]);\n cache.set(type, fn);\n }\n return fn;\n };\n\n const byLabelSet = createByLabelSetFunction(styleMatchers);\n\n return { byLabelSet, byType, styleMatchers };\n}\n"]}
1
+ {"version":3,"file":"compile-graph-styles.js","sourceRoot":"","sources":["../../../src/styling/compile-graph-styles.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n *\n * Copyright (c) \"Neo4j\"\n * Neo4j Sweden AB [http://neo4j.com]\n *\n * This file is part of Neo4j.\n *\n * Neo4j is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\nimport { calculateDefaultNodeColors } from '@neo4j-devtools/word-color';\nimport { tokens } from '@neo4j-ndl/base';\nimport { color, type RgbColor, rgbToHex, validHex } from '@uiw/react-color';\n\nimport {\n type NodeData,\n type PortableProperty,\n type RelData,\n} from '../graph-visualization-context';\nimport { getWeight, lerpColor } from './color-interpolation';\nimport {\n type Caption,\n type ColorRange,\n type CypherValue,\n type EvaluatedNvlNodeStyle,\n type EvaluatedNvlRelationshipStyle,\n type GraphStyleRule,\n type NonStaticStyles,\n type Style,\n type UniqueColors,\n type Value,\n type Where,\n} from './style-types';\n\nexport const DEFAULT_REL_COLOR = tokens.palette.neutral['40'];\nconst NO_LABEL_FALLBACK_COLOR = tokens.palette.neutral['40'];\n\nexport const UNIQUE_COLORS_PALETTE = Object.values(tokens.graph).filter(\n validHex,\n);\n\ntype StyleMatchers = {\n globalLabelRules: GraphStyleRule[];\n globalReltypeRules: GraphStyleRule[];\n rulesByLabel: Map<string, GraphStyleRule[]>;\n rulesByType: Map<string, GraphStyleRule[]>;\n};\n\nfunction compareByPriorityAscending(\n a: GraphStyleRule,\n b: GraphStyleRule,\n): number {\n return a.priority! - b.priority!;\n}\n\nfunction collectStyleMatchers(\n styles: GraphStyleRule[] | null | undefined,\n): StyleMatchers {\n const rulesByLabel = new Map<string, GraphStyleRule[]>();\n const rulesByType = new Map<string, GraphStyleRule[]>();\n const globalLabelRules: GraphStyleRule[] = [];\n const globalReltypeRules: GraphStyleRule[] = [];\n\n // Handle null/undefined styles gracefully\n if (!styles || styles.length === 0) {\n return {\n globalLabelRules,\n globalReltypeRules,\n rulesByLabel,\n rulesByType,\n };\n }\n\n const totalRules = styles.length;\n\n styles.forEach((style, index) => {\n if (style.isDisabled ?? false) {\n return;\n }\n\n if (style.priority !== undefined && style.priority < 0) {\n throw new Error(\n `GraphStyleRule priority must be >= 0, got ${style.priority}. Negative values are reserved for internal use.`,\n );\n }\n\n // Fill in priority if not set (negative values preserve original order)\n const { priority, ...rest } = style;\n const ruleWithPriority: GraphStyleRule = {\n ...rest,\n priority: priority ?? index - totalRules,\n };\n\n // style for nodes\n if ('label' in style.match) {\n // if the label is null, it's a global rule (matches any node)\n if (style.match.label === null) {\n globalLabelRules.push(ruleWithPriority);\n } else {\n // Specific label rule\n const existing = rulesByLabel.get(style.match.label) ?? [];\n rulesByLabel.set(style.match.label, [...existing, ruleWithPriority]);\n }\n }\n\n // style for relationships\n if ('reltype' in style.match) {\n if (style.match.reltype === null) {\n // Global reltype rule (matches any relationship)\n globalReltypeRules.push(ruleWithPriority);\n } else {\n // Specific reltype rule\n const existing = rulesByType.get(style.match.reltype) ?? [];\n rulesByType.set(style.match.reltype, [...existing, ruleWithPriority]);\n }\n }\n });\n\n return {\n globalLabelRules,\n globalReltypeRules,\n rulesByLabel,\n rulesByType,\n };\n}\n\n/**\n * Interpolates a color from a ColorRange based on a graph item's property value.\n * Returns a #rrggbb hex string, or null if the colorRange config is invalid\n * (bad hex colors, invalid value range, missing/non-numeric property).\n */\nfunction getInterpolatedColor(\n colorRange: ColorRange,\n graphItem: NodeData | RelData,\n): string | null {\n const {\n onProperty,\n minValue,\n minColor,\n maxValue,\n maxColor,\n midValue,\n midColor,\n } = colorRange;\n\n if (!validHex(minColor) || !validHex(maxColor)) {\n return null;\n }\n const minRgb = color(minColor).rgb;\n const maxRgb = color(maxColor).rgb;\n // min/max can be inverted, we need to now which one is bigger\n const actualMinValue = Math.min(minValue, maxValue);\n const actualMaxValue = Math.max(minValue, maxValue);\n\n // Validate mid stop if provided\n let midRgb: RgbColor | undefined = undefined;\n if (midValue !== undefined && midColor !== undefined) {\n const isMidInRange =\n actualMinValue <= midValue && midValue <= actualMaxValue;\n if (!isMidInRange || !validHex(midColor)) {\n return null;\n }\n midRgb = color(midColor).rgb;\n }\n\n const prop = graphItem.properties[onProperty];\n if (prop === undefined) {\n return null;\n }\n const rawValue = extractPropertyValue(prop);\n if (typeof rawValue !== 'number') {\n return null;\n }\n\n const clampedValue = Math.max(\n actualMinValue,\n Math.min(actualMaxValue, rawValue),\n );\n\n let rgb: RgbColor;\n\n if (midRgb !== undefined && midValue !== undefined) {\n const t = getWeight(minValue, midValue, clampedValue);\n const isBetweenMinAndMid = t <= 1;\n if (isBetweenMinAndMid) {\n rgb = lerpColor(minRgb, midRgb, t);\n } else {\n const t = getWeight(midValue, maxValue, clampedValue);\n rgb = lerpColor(midRgb, maxRgb, t);\n }\n } else {\n const t = getWeight(minValue, maxValue, clampedValue);\n rgb = lerpColor(minRgb, maxRgb, t);\n }\n\n return rgbToHex(rgb);\n}\n\n/**\n * Interpolates a numeric size/width from a range based on a graph item's property value.\n * Returns the interpolated number, or null if the property is missing or non-numeric.\n */\nfunction getInterpolatedSize(\n prop: PortableProperty | undefined,\n minValue: number,\n maxValue: number,\n minOut: number,\n maxOut: number,\n): number | null {\n if (prop === undefined) {\n return null;\n }\n const rawValue = extractPropertyValue(prop);\n if (typeof rawValue !== 'number') {\n return null;\n }\n\n const actualMinValue = Math.min(minValue, maxValue);\n const actualMaxValue = Math.max(minValue, maxValue);\n const clampedValue = Math.max(\n actualMinValue,\n Math.min(actualMaxValue, rawValue),\n );\n const t = getWeight(minValue, maxValue, clampedValue);\n return minOut * (1 - t) + maxOut * t;\n}\n\nfunction extractPropertyValue(\n prop: PortableProperty,\n): string | number | boolean | null {\n switch (prop.type) {\n case 'string':\n return JSON.parse(prop.stringified);\n case 'number':\n case 'integer':\n case 'float':\n return Number(prop.stringified);\n case 'boolean':\n case 'Boolean':\n return prop.stringified === 'true';\n case 'null':\n return null;\n default:\n return prop.stringified;\n }\n}\n\n/**\n * Three-valued logic type matching Cypher/SQL semantics.\n * - `true`: condition is satisfied\n * - `false`: condition is not satisfied\n * - `null`: condition is unknown (e.g., comparing with null/missing property)\n *\n * @see https://neo4j.com/docs/cypher-manual/current/values-and-types/working-with-null/\n */\ntype Ternary = boolean | null;\n\n/**\n * Evaluates a WHERE clause using three-valued logic matching Cypher semantics.\n *\n * From Neo4j Cypher Manual:\n * - Comparing any value to `null` results in `null`, not `true` or `false`\n * - Accessing a non-existent property returns `null`\n * - In WHERE clauses, only `true` passes; both `false` and `null` exclude the row\n *\n * Three-valued logic rules:\n * - NOT null → null\n * - true AND null → null, false AND null → false\n * - true OR null → true, false OR null → null\n *\n * @see https://neo4j.com/docs/cypher-manual/current/values-and-types/working-with-null/\n */\nfunction evaluateWhere(node: NodeData | RelData, where?: Where): Ternary {\n if (!where) {\n return true;\n }\n\n if ('equal' in where) {\n const [left, right] = where.equal;\n const leftVal = evaluateValue(left, node);\n const rightVal = evaluateValue(right, node);\n // In Cypher, null = null → null (not true)\n if (leftVal === null || rightVal === null) {\n return null;\n }\n return leftVal === rightVal;\n }\n\n if ('not' in where) {\n // Cypher: NOT null → null\n const isMatch = evaluateWhere(node, where.not);\n return isMatch === null ? null : !isMatch;\n }\n\n if ('lessThan' in where) {\n const [left, right] = where.lessThan;\n return safeCompare(left, right, node, (a, b) => a < b);\n }\n\n if ('lessThanOrEqual' in where) {\n const [left, right] = where.lessThanOrEqual;\n return safeCompare(left, right, node, (a, b) => a <= b);\n }\n\n if ('greaterThan' in where) {\n const [left, right] = where.greaterThan;\n return safeCompare(left, right, node, (a, b) => a > b);\n }\n\n if ('greaterThanOrEqual' in where) {\n const [left, right] = where.greaterThanOrEqual;\n return safeCompare(left, right, node, (a, b) => a >= b);\n }\n\n if ('contains' in where) {\n const [left, right] = where.contains;\n return safeStringCompare(left, right, node, (a, b) => a.includes(b));\n }\n\n if ('startsWith' in where) {\n const [left, right] = where.startsWith;\n return safeStringCompare(left, right, node, (a, b) => a.startsWith(b));\n }\n\n if ('endsWith' in where) {\n const [left, right] = where.endsWith;\n return safeStringCompare(left, right, node, (a, b) => a.endsWith(b));\n }\n\n if ('isNull' in where) {\n // IS NULL returns true/false (never null)\n const value = evaluateValue(where.isNull, node);\n return value === null;\n }\n\n if ('and' in where) {\n // Cypher three-valued AND:\n // - If any is false → false\n // - Else if any is null → null\n // - Else → true\n let hasNull = false;\n for (const r of where.and) {\n const isMatch = evaluateWhere(node, r);\n if (isMatch === false) {\n return false;\n }\n if (isMatch === null) {\n hasNull = true;\n }\n }\n return hasNull ? null : true;\n }\n\n if ('or' in where) {\n // Cypher three-valued OR:\n // - If any is true → true\n // - Else if any is null → null\n // - Else → false\n let hasNull = false;\n for (const r of where.or) {\n const isMatch = evaluateWhere(node, r);\n if (isMatch === true) {\n return true;\n }\n if (isMatch === null) {\n hasNull = true;\n }\n }\n return hasNull ? null : false;\n }\n\n if ('label' in where) {\n if ('labelsSorted' in node) {\n return where.label === null || node.labelsSorted.includes(where.label);\n }\n return false;\n }\n\n if ('reltype' in where) {\n if ('type' in node) {\n return where.reltype === null || (node as RelData).type === where.reltype;\n }\n return false;\n }\n\n if ('property' in where) {\n return where.property === null || where.property in node.properties;\n }\n\n return false;\n}\n\n/**\n * Resolves a color for the given property value, using the uniqueColors object\n * reference as the per-rule key in uniqueColorsCache. Assigns a new palette color\n * on first encounter (first-come, first-served). Returns null if the property is\n * missing or null.\n */\nfunction resolveUniqueColor(\n uniqueColors: UniqueColors,\n properties: Record<string, PortableProperty | undefined>,\n uniqueColorsCache: Map<UniqueColors, Map<string, string>>,\n): string | null {\n const prop = properties[uniqueColors.onProperty];\n if (prop === undefined) {\n return null;\n }\n const rawValue = extractPropertyValue(prop);\n if (rawValue === null) {\n return null;\n }\n const valueKey = String(rawValue);\n\n let valueMap = uniqueColorsCache.get(uniqueColors);\n if (valueMap === undefined) {\n valueMap = new Map();\n uniqueColorsCache.set(uniqueColors, valueMap);\n }\n\n let assignedColor = valueMap.get(valueKey);\n if (assignedColor === undefined) {\n assignedColor =\n UNIQUE_COLORS_PALETTE[valueMap.size % UNIQUE_COLORS_PALETTE.length]!;\n valueMap.set(valueKey, assignedColor);\n }\n\n return assignedColor;\n}\n\nfunction shouldUseProperty(\n prop: { isDisabled?: boolean } | undefined,\n): boolean {\n return prop !== undefined && prop.isDisabled !== true;\n}\n\nfunction evaluateStaticStyle({\n overlayIcon,\n ...scalarStyle\n}: Omit<Style, NonStaticStyles>) {\n const result: Record<string, unknown> = {};\n\n for (const [key, prop] of Object.entries(scalarStyle)) {\n if (shouldUseProperty(prop)) {\n result[key] = prop.value;\n }\n }\n\n if (shouldUseProperty(overlayIcon)) {\n const { isDisabled, ...overlayIconProps } = overlayIcon!;\n result.overlayIcon = overlayIconProps;\n }\n\n return result;\n}\n\nfunction evaluateRelStyle(\n style: Style,\n rel: RelData,\n uniqueColorsCache: Map<UniqueColors, Map<string, string>>,\n): EvaluatedNvlRelationshipStyle {\n const {\n captions,\n colorRange,\n widthRange,\n sizeRange,\n uniqueColors,\n ...staticStyle\n } = style;\n const result: EvaluatedNvlRelationshipStyle =\n evaluateStaticStyle(staticStyle);\n\n if (shouldUseProperty(captions) && captions!.text) {\n result.captions = captions!.text.map((caption) => {\n const { value, styles } = caption;\n\n if (typeof value === 'string' || value === undefined) {\n return { styles, value };\n }\n\n if ('useType' in value) {\n return { styles, value: rel.type };\n }\n\n if ('property' in value) {\n const prop = rel.properties[value.property];\n if (prop === undefined) {\n return { styles, value: '' };\n }\n\n const resolvedValue =\n prop.type === 'string'\n ? prop.stringified.slice(1, -1)\n : prop.stringified;\n\n return { styles, value: resolvedValue };\n }\n\n return { styles, value: rel.id };\n });\n\n if (captions?.align !== undefined) {\n result.captionAlign = captions.align;\n }\n if (captions?.size !== undefined) {\n result.captionSize = captions.size;\n }\n }\n\n if (shouldUseProperty(colorRange)) {\n const interpolated = getInterpolatedColor(colorRange!, rel);\n if (interpolated !== null) {\n result.color = interpolated;\n }\n }\n\n if (shouldUseProperty(widthRange)) {\n const { onProperty, minValue, maxValue, minWidth, maxWidth } = widthRange!;\n const interpolated = getInterpolatedSize(\n rel.properties[onProperty],\n minValue,\n maxValue,\n minWidth,\n maxWidth,\n );\n if (interpolated !== null) {\n result.width = interpolated;\n }\n }\n\n if (shouldUseProperty(uniqueColors)) {\n const color = resolveUniqueColor(\n uniqueColors!,\n rel.properties,\n uniqueColorsCache,\n );\n if (color !== null) {\n result.color = color;\n }\n }\n\n return result;\n}\n\n/**\n * Safely compare two values using Cypher's three-valued logic.\n * Returns `null` if either operand is null (matching Cypher semantics).\n *\n * From Neo4j Cypher Manual:\n * \"Comparing any value to `null` using `=` or `<>` results in `null`\"\n *\n * @see https://neo4j.com/docs/cypher-manual/current/values-and-types/working-with-null/\n */\nfunction safeCompare(\n left: Value,\n right: Value,\n graphItem: NodeData | RelData,\n compareFn: (\n a: NonNullable<CypherValue>,\n b: NonNullable<CypherValue>,\n ) => boolean,\n): Ternary {\n const leftVal = evaluateValue(left, graphItem);\n const rightVal = evaluateValue(right, graphItem);\n if (leftVal === null || rightVal === null) {\n return null;\n }\n return compareFn(leftVal, rightVal);\n}\n\n/**\n * String comparison using Cypher semantics.\n * Returns `null` if either operand is null OR not a string.\n *\n * From Neo4j Cypher Manual:\n * \"When these operators are applied to non-string values, they return `null`\n * instead of attempting type coercion.\"\n *\n * @see https://neo4j.com/docs/cypher-manual/current/expressions/predicates/string-operators/\n */\nfunction safeStringCompare(\n left: Value,\n right: Value,\n graphItem: NodeData | RelData,\n compareFn: (a: string, b: string) => boolean,\n): Ternary {\n const leftVal = evaluateValue(left, graphItem);\n const rightVal = evaluateValue(right, graphItem);\n // Return null if either is null or not a string (no type coercion)\n if (\n leftVal === null ||\n rightVal === null ||\n typeof leftVal !== 'string' ||\n typeof rightVal !== 'string'\n ) {\n return null;\n }\n return compareFn(leftVal, rightVal);\n}\n\nfunction evaluateValue(\n value: Value,\n graphItem: NodeData | RelData,\n): CypherValue {\n if (typeof value === 'object' && value !== null) {\n if ('property' in value) {\n if (value.property === null) {\n return null;\n }\n const prop = graphItem.properties[value.property];\n if (prop === undefined) {\n return null;\n }\n return extractPropertyValue(prop);\n }\n if ('label' in value) {\n if ('labelsSorted' in graphItem) {\n return (\n value.label === null || graphItem.labelsSorted.includes(value.label)\n );\n }\n return false;\n }\n if ('reltype' in value) {\n if ('type' in graphItem) {\n return (\n value.reltype === null ||\n (graphItem as RelData).type === value.reltype\n );\n }\n return false;\n }\n }\n\n return value;\n}\n\n// Default caption selection logic\nconst captionPriorityOrder = [\n /^name$/i,\n /^title$/i,\n /^label$/i,\n /name$/i,\n /description$/i,\n /^.+/,\n];\n\nfunction getDefaultNodeCaption(node: NodeData): Caption {\n const propertyKeys = Object.keys(node.properties);\n\n for (const regex of captionPriorityOrder) {\n const matchingKey = propertyKeys.find((key) => regex.test(key));\n if (matchingKey !== undefined) {\n const prop = node.properties[matchingKey];\n if (prop !== undefined) {\n return { value: { property: matchingKey } };\n }\n }\n }\n\n if (node.labelsSorted[0] !== undefined) {\n return { value: { useType: true } };\n }\n\n return { value: node.id };\n}\n\nfunction evaluateNodeStyle(\n style: Style,\n node: NodeData,\n uniqueColorsCache: Map<UniqueColors, Map<string, string>>,\n): EvaluatedNvlNodeStyle {\n const {\n captions,\n colorRange,\n sizeRange,\n widthRange,\n uniqueColors,\n ...staticStyle\n } = style;\n const result: EvaluatedNvlNodeStyle = evaluateStaticStyle(staticStyle);\n\n const captionSource =\n shouldUseProperty(captions) && captions!.text\n ? captions!.text\n : [getDefaultNodeCaption(node)];\n\n result.captions = captionSource.map((caption) => {\n const { value, styles } = caption;\n\n if (typeof value === 'string' || value === undefined) {\n return { styles, value };\n }\n\n if ('useType' in value) {\n return { styles, value: node.labelsSorted[0] };\n }\n\n if ('property' in value) {\n const prop = node.properties[value.property];\n if (prop === undefined) {\n return { styles, value: '' };\n }\n\n const resolvedValue =\n prop.type === 'string'\n ? prop.stringified.slice(1, -1)\n : prop.stringified;\n\n return { styles, value: resolvedValue };\n }\n\n return { styles, value: node.labelsSorted[0] };\n });\n\n if (shouldUseProperty(captions)) {\n if (captions?.align !== undefined) {\n result.captionAlign = captions.align;\n }\n if (captions?.size !== undefined) {\n result.captionSize = captions.size;\n }\n }\n\n if (shouldUseProperty(colorRange)) {\n const interpolated = getInterpolatedColor(colorRange!, node);\n if (interpolated !== null) {\n result.color = interpolated;\n }\n }\n\n if (shouldUseProperty(sizeRange)) {\n const { onProperty, minValue, maxValue, minSize, maxSize } = sizeRange!;\n const interpolated = getInterpolatedSize(\n node.properties[onProperty],\n minValue,\n maxValue,\n minSize,\n maxSize,\n );\n if (interpolated !== null) {\n result.size = interpolated;\n }\n }\n\n if (shouldUseProperty(uniqueColors)) {\n const color = resolveUniqueColor(\n uniqueColors!,\n node.properties,\n uniqueColorsCache,\n );\n if (color !== null) {\n result.color = color;\n }\n }\n\n return result;\n}\n\nfunction createRelStyleFunction(\n rules: GraphStyleRule[],\n): (rel: RelData) => EvaluatedNvlRelationshipStyle {\n const uniqueColorsCache = new Map<UniqueColors, Map<string, string>>();\n return (rel: RelData) => {\n const style: Style = {};\n\n // evaluateWhere uses Cypher-style three-valued logic (true/false/null).\n // Only `true` passes; both `false` and `null` (unknown) skip the rule.\n for (const rule of rules) {\n // Check if the rule applies to this relationship\n if ('reltype' in rule.match) {\n const isReltypeMatch =\n rule.match.reltype === null || rel.type === rule.match.reltype;\n\n if (isReltypeMatch && evaluateWhere(rel, rule.where) === true) {\n // Merge the style properties (later rules override earlier ones)\n Object.assign(style, rule.apply);\n }\n }\n }\n\n return evaluateRelStyle(style, rel, uniqueColorsCache);\n };\n}\n\nexport type CompiledGraphStyleRules = {\n byType: (type: string) => (rel: RelData) => EvaluatedNvlRelationshipStyle;\n styleMatchers: StyleMatchers;\n byLabelSet: (node: NodeData) => EvaluatedNvlNodeStyle;\n};\n\nfunction createByLabelSetFunction(\n styleMatchers: StyleMatchers,\n): (node: NodeData) => EvaluatedNvlNodeStyle {\n const defaultColorCache = new Map<string, string>();\n const sortedRulesCache = new Map<string, GraphStyleRule[]>();\n const mergedStyleCache = new Map<string, Style>();\n const uniqueColorsCache = new Map<UniqueColors, Map<string, string>>();\n\n return (node: NodeData) => {\n const labelSetKey = node.labelsSorted.join('\\0');\n\n // Fast path: if all rules for this label set are where-free and none use\n // uniqueColors, the merged style is identical for every node with the same labels.\n const cachedStyle = mergedStyleCache.get(labelSetKey);\n if (cachedStyle !== undefined) {\n return evaluateNodeStyle(cachedStyle, node, uniqueColorsCache);\n }\n\n // Memoize default color by first label\n const labelForDefaultColor = node.labelsSorted[0] ?? null;\n let defaultColor: string;\n if (labelForDefaultColor === null) {\n defaultColor = NO_LABEL_FALLBACK_COLOR;\n } else {\n let cached = defaultColorCache.get(labelForDefaultColor);\n if (cached === undefined) {\n cached =\n calculateDefaultNodeColors(labelForDefaultColor).backgroundColor;\n defaultColorCache.set(labelForDefaultColor, cached);\n }\n defaultColor = cached;\n }\n\n // Cache sorted rules by label set (avoids repeated allocation + sort)\n let sortedRules = sortedRulesCache.get(labelSetKey);\n if (sortedRules === undefined) {\n const matchingRules: GraphStyleRule[] = [\n ...styleMatchers.globalLabelRules,\n ];\n for (const label of node.labelsSorted) {\n const labelRules = styleMatchers.rulesByLabel.get(label);\n if (labelRules) {\n matchingRules.push(...labelRules);\n }\n }\n sortedRules = matchingRules.toSorted(compareByPriorityAscending);\n sortedRulesCache.set(labelSetKey, sortedRules);\n }\n\n // Evaluate rules, tracking whether all are where-free and uniqueColors-free.\n const collectStyles: Style = { color: { value: defaultColor } };\n let isCacheable = true;\n for (const rule of sortedRules) {\n if (rule.where !== undefined || rule.apply.uniqueColors !== undefined) {\n isCacheable = false;\n }\n const shouldApplyRule =\n rule.where === undefined || evaluateWhere(node, rule.where) === true;\n if (shouldApplyRule) {\n Object.assign(collectStyles, rule.apply);\n }\n }\n\n // When all rules are where-free and uniqueColors-free, the merged style\n // depends only on labels. Cache it so subsequent nodes with the same label\n // set skip rule iteration.\n if (isCacheable) {\n mergedStyleCache.set(labelSetKey, collectStyles);\n }\n\n return evaluateNodeStyle(collectStyles, node, uniqueColorsCache);\n };\n}\n\nconst DEFAULT_REL_STYLE: GraphStyleRule = {\n match: { reltype: null },\n apply: {\n color: { value: DEFAULT_REL_COLOR },\n captions: { text: [{ value: { useType: true } }] },\n },\n};\n\nexport function compileGraphStyleRules(\n styleRules: GraphStyleRule[] | null | undefined,\n): CompiledGraphStyleRules {\n const styleMatchers = collectStyleMatchers(styleRules);\n\n // Lazily build and cache a style function per relationship type\n const cache = new Map<\n string,\n (rel: RelData) => EvaluatedNvlRelationshipStyle\n >();\n const byType = (type: string) => {\n let fn = cache.get(type);\n if (fn === undefined) {\n const rules = styleMatchers.rulesByType.get(type) ?? [];\n fn = createRelStyleFunction([\n DEFAULT_REL_STYLE,\n ...styleMatchers.globalReltypeRules,\n ...rules,\n ]);\n cache.set(type, fn);\n }\n return fn;\n };\n\n const byLabelSet = createByLabelSetFunction(styleMatchers);\n\n return { byLabelSet, byType, styleMatchers };\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"create-vis-data-structures.js","sourceRoot":"","sources":["../../../src/styling/create-vis-data-structures.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n *\n * Copyright (c) \"Neo4j\"\n * Neo4j Sweden AB [http://neo4j.com]\n *\n * This file is part of Neo4j.\n *\n * Neo4j is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\nimport type {\n ColorCount,\n GraphItemMetaData,\n MetadataLookupTable,\n NeoNode,\n NeoRel,\n NodeData,\n NvlGraph,\n RelData,\n} from '../graph-visualization-context';\nimport { sortAlphabetically } from '../utils';\nimport type { CompiledStyleRules } from './compile-graph-styles';\nimport {\n pickConsumerNodeStyles,\n pickConsumerRelationshipStyles,\n} from './style-types';\n\nexport const NO_LABEL = '(no label)';\n\nfunction buildColorDistribution(\n colorCounts: Record<string, number>,\n): ColorCount[] {\n return Object.entries(colorCounts)\n .map(([color, count]) => ({ color, count }))\n .sort((a, b) => b.count - a.count);\n}\n\nexport function createVisualizationDataStructures(\n rawNodes: NeoNode[],\n rawRels: NeoRel[],\n compiledStyleRules: CompiledStyleRules,\n): {\n styledGraph: NvlGraph;\n metadataLookup: MetadataLookupTable;\n} {\n const nodeData: Record<string, NodeData> = {};\n const labelColorCounts: Record<string, Record<string, number>> = {};\n const labelTotalCounts: Record<string, number> = {};\n\n // Single pass: extract data, apply styles, count colors\n const styledNodes = rawNodes.map((rawNode) => {\n const data: NodeData = {\n id: rawNode.id,\n labelsSorted: [...rawNode.labels].sort(sortAlphabetically),\n properties: rawNode.properties,\n };\n nodeData[rawNode.id] = data;\n\n const appliedStyle = compiledStyleRules.byLabelSet(data);\n\n const styledNode = {\n ...rawNode,\n labels: undefined,\n properties: undefined,\n ...appliedStyle,\n // Consumer-set style properties on NeoNode take precedence over style rules\n ...pickConsumerNodeStyles(rawNode),\n };\n\n // Accumulate color distribution\n const labels =\n data.labelsSorted.length > 0 ? data.labelsSorted : [NO_LABEL];\n const color = styledNode.color;\n\n for (const label of labels) {\n labelTotalCounts[label] = (labelTotalCounts[label] ?? 0) + 1;\n\n if (color !== undefined) {\n const counts = labelColorCounts[label] ?? {};\n counts[color] = (counts[color] ?? 0) + 1;\n labelColorCounts[label] = counts;\n }\n }\n\n return styledNode;\n });\n\n const labels = Object.keys(labelTotalCounts).sort(sortAlphabetically);\n const labelMetaData: Record<string, GraphItemMetaData> = {};\n let hasMultipleColors = false;\n for (const label of labels) {\n const colorDistribution = buildColorDistribution(\n labelColorCounts[label] ?? {},\n );\n if (colorDistribution.length > 1) {\n hasMultipleColors = true;\n }\n labelMetaData[label] = {\n totalCount: labelTotalCounts[label]!,\n colorDistribution,\n };\n }\n\n const relData: Record<string, RelData> = {};\n const relTypeCounts: Record<string, number> = {};\n const relColorCounts: Record<string, Record<string, number>> = {};\n\n // Single pass: extract data, apply styles, count colors\n const styledRels = rawRels.map((rawRel) => {\n const data: RelData = {\n id: rawRel.id,\n properties: rawRel.properties,\n type: rawRel.type,\n };\n relData[rawRel.id] = data;\n\n const appliedStyle = compiledStyleRules.byType(data.type)(data);\n\n const styledRel = {\n ...rawRel,\n properties: undefined,\n type: undefined,\n ...appliedStyle,\n // Consumer-set style properties on NeoRel take precedence over style rules\n ...pickConsumerRelationshipStyles(rawRel),\n };\n\n // Accumulate color distribution and type counts\n relTypeCounts[data.type] = (relTypeCounts[data.type] ?? 0) + 1;\n const color = styledRel.color;\n if (color !== undefined) {\n const counts = relColorCounts[data.type] ?? {};\n counts[color] = (counts[color] ?? 0) + 1;\n relColorCounts[data.type] = counts;\n }\n\n return styledRel;\n });\n\n const reltypes = Object.keys(relTypeCounts).sort(sortAlphabetically);\n const reltypeMetaData: Record<string, GraphItemMetaData> = {};\n for (const type of reltypes) {\n const colorDistribution = buildColorDistribution(\n relColorCounts[type] ?? {},\n );\n if (colorDistribution.length > 1) {\n hasMultipleColors = true;\n }\n reltypeMetaData[type] = {\n totalCount: relTypeCounts[type]!,\n colorDistribution,\n };\n }\n\n return {\n metadataLookup: {\n hasMultipleColors,\n labelMetaData,\n labels,\n reltypeMetaData,\n reltypes,\n },\n styledGraph: {\n nodeData,\n nodes: styledNodes,\n relData,\n rels: styledRels,\n },\n };\n}\n"]}
1
+ {"version":3,"file":"create-vis-data-structures.js","sourceRoot":"","sources":["../../../src/styling/create-vis-data-structures.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n *\n * Copyright (c) \"Neo4j\"\n * Neo4j Sweden AB [http://neo4j.com]\n *\n * This file is part of Neo4j.\n *\n * Neo4j is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\n */\n\nimport type {\n ColorCount,\n GraphItemMetaData,\n MetadataLookupTable,\n NeoNode,\n NeoRel,\n NodeData,\n NvlGraph,\n RelData,\n} from '../graph-visualization-context';\nimport { sortAlphabetically } from '../utils';\nimport type { CompiledGraphStyleRules } from './compile-graph-styles';\nimport {\n pickConsumerNodeStyles,\n pickConsumerRelationshipStyles,\n} from './style-types';\n\nexport const NO_LABEL = '(no label)';\n\nfunction buildColorDistribution(\n colorCounts: Record<string, number>,\n): ColorCount[] {\n return Object.entries(colorCounts)\n .map(([color, count]) => ({ color, count }))\n .sort((a, b) => b.count - a.count);\n}\n\nexport function createVisualizationDataStructures(\n rawNodes: NeoNode[],\n rawRels: NeoRel[],\n compiledStyleRules: CompiledGraphStyleRules,\n): {\n styledGraph: NvlGraph;\n metadataLookup: MetadataLookupTable;\n} {\n const nodeData: Record<string, NodeData> = {};\n const labelColorCounts: Record<string, Record<string, number>> = {};\n const labelTotalCounts: Record<string, number> = {};\n\n // Single pass: extract data, apply styles, count colors\n const styledNodes = rawNodes.map((rawNode) => {\n const data: NodeData = {\n id: rawNode.id,\n labelsSorted: [...rawNode.labels].sort(sortAlphabetically),\n properties: rawNode.properties,\n };\n nodeData[rawNode.id] = data;\n\n const appliedStyle = compiledStyleRules.byLabelSet(data);\n\n const styledNode = {\n ...rawNode,\n labels: undefined,\n properties: undefined,\n ...appliedStyle,\n // Consumer-set style properties on NeoNode take precedence over style rules\n ...pickConsumerNodeStyles(rawNode),\n };\n\n // Accumulate color distribution\n const labels =\n data.labelsSorted.length > 0 ? data.labelsSorted : [NO_LABEL];\n const color = styledNode.color;\n\n for (const label of labels) {\n labelTotalCounts[label] = (labelTotalCounts[label] ?? 0) + 1;\n\n if (color !== undefined) {\n const counts = labelColorCounts[label] ?? {};\n counts[color] = (counts[color] ?? 0) + 1;\n labelColorCounts[label] = counts;\n }\n }\n\n return styledNode;\n });\n\n const labels = Object.keys(labelTotalCounts).sort(sortAlphabetically);\n const labelMetaData: Record<string, GraphItemMetaData> = {};\n let hasMultipleColors = false;\n for (const label of labels) {\n const colorDistribution = buildColorDistribution(\n labelColorCounts[label] ?? {},\n );\n if (colorDistribution.length > 1) {\n hasMultipleColors = true;\n }\n labelMetaData[label] = {\n totalCount: labelTotalCounts[label]!,\n colorDistribution,\n };\n }\n\n const relData: Record<string, RelData> = {};\n const relTypeCounts: Record<string, number> = {};\n const relColorCounts: Record<string, Record<string, number>> = {};\n\n // Single pass: extract data, apply styles, count colors\n const styledRels = rawRels.map((rawRel) => {\n const data: RelData = {\n id: rawRel.id,\n properties: rawRel.properties,\n type: rawRel.type,\n };\n relData[rawRel.id] = data;\n\n const appliedStyle = compiledStyleRules.byType(data.type)(data);\n\n const styledRel = {\n ...rawRel,\n properties: undefined,\n type: undefined,\n ...appliedStyle,\n // Consumer-set style properties on NeoRel take precedence over style rules\n ...pickConsumerRelationshipStyles(rawRel),\n };\n\n // Accumulate color distribution and type counts\n relTypeCounts[data.type] = (relTypeCounts[data.type] ?? 0) + 1;\n const color = styledRel.color;\n if (color !== undefined) {\n const counts = relColorCounts[data.type] ?? {};\n counts[color] = (counts[color] ?? 0) + 1;\n relColorCounts[data.type] = counts;\n }\n\n return styledRel;\n });\n\n const reltypes = Object.keys(relTypeCounts).sort(sortAlphabetically);\n const reltypeMetaData: Record<string, GraphItemMetaData> = {};\n for (const type of reltypes) {\n const colorDistribution = buildColorDistribution(\n relColorCounts[type] ?? {},\n );\n if (colorDistribution.length > 1) {\n hasMultipleColors = true;\n }\n reltypeMetaData[type] = {\n totalCount: relTypeCounts[type]!,\n colorDistribution,\n };\n }\n\n return {\n metadataLookup: {\n hasMultipleColors,\n labelMetaData,\n labels,\n reltypeMetaData,\n reltypes,\n },\n styledGraph: {\n nodeData,\n nodes: styledNodes,\n relData,\n rels: styledRels,\n },\n };\n}\n"]}
@@ -19,22 +19,22 @@
19
19
  * along with this program. If not, see <http://www.gnu.org/licenses/>.
20
20
  */
21
21
  import z from 'zod';
22
- import { StyleRuleSchema } from './style-types';
23
- const StyleRulesArraySchema = z.array(StyleRuleSchema);
22
+ import { GraphStyleRuleSchema } from './style-types';
23
+ const StyleRulesArraySchema = z.array(GraphStyleRuleSchema);
24
24
  /**
25
- * Parse and validate a JSON string as an array of StyleRules.
25
+ * Parse and validate a JSON string as an array of GraphStyleRules.
26
26
  *
27
27
  * Useful for importing style rules from JSON. Uses Zod for runtime validation and returns
28
28
  * a discriminated result:
29
29
  *
30
- * - On success: `{ success: true, data: StyleRule[] }`
30
+ * - On success: `{ success: true, data: GraphStyleRule[] }`
31
31
  * - On failure: `{ success: false, error: ZodError }`
32
32
  *
33
33
  * @example
34
34
  * ```ts
35
35
  * const result = parseStyleRules('[{"match": {"label": "Person"}, "apply": {"color": "red"}}]');
36
36
  * if (result.success) {
37
- * console.log(result.data); // StyleRule[]
37
+ * console.log(result.data); // GraphStyleRule[]
38
38
  * } else {
39
39
  * console.error(result.error.issues);
40
40
  * }