Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,14 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]

### Added

- Save button in CustomControls with export dialog for PNG and JSON formats
- Modal dialog for choosing export format (PNG image or JSON data)
- Automatic filename generation based on uploaded file or default name

## [1.0.2] - 2024-10-20

### Added
Expand Down
20 changes: 14 additions & 6 deletions docs/JSON_FORMAT.md
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ Defines semantic mappings for edge styling based on tags.
"Network": { "line-pattern": "dashed", "animation": "animated" }
},
"OrderingGroup": {
"TotalOrder": { "waviness": "straight" },
"TotalOrder": { "waviness": "none" },
"NoOrder": { "waviness": "wavy" }
},
"BoundednessGroup": {
Expand All @@ -219,9 +219,12 @@ Defines semantic mappings for edge styling based on tags.
"Keyed": { "line-style": "double" }
},
"CollectionGroup": {
"Stream": { "color": "#2563eb", "arrowhead": "triangle-filled" },
"Singleton": { "color": "#000000", "arrowhead": "circle-filled" },
"Optional": { "color": "#6b7280", "arrowhead": "diamond-open" }
"Stream": {
"color-token": "highlight-1",
"arrowhead": "triangle-filled"
},
"Singleton": { "color-token": "default", "arrowhead": "circle-filled" },
"Optional": { "color-token": "muted", "arrowhead": "diamond-open" }
}
}
}
Expand All @@ -232,11 +235,15 @@ Defines semantic mappings for edge styling based on tags.

- **`line-pattern`**: "solid" or "dashed"
- **`line-style`**: "single" (plain line) or "hash-marks" (line with vertical hash marks for keyed streams)
- **`waviness`**: "straight" or "wavy" (for ordering information)
- **`waviness`**: "none" or "wavy" (for ordering information)
- **`animation`**: "static" or "animated"
- **`arrowhead`**: "triangle-filled", "circle-filled", "diamond-open"
- **`halo`**: "none", "light-blue" (transparent halo for unbounded streams)
- **`color`**: Hex color code for the edge (e.g., "#001f3f" for navy blue)
- **`color-token`**: Semantic color token for the edge's stroke color. Resolution is theme-aware at runtime (light/dark). Supported tokens:
- `default`, `muted`, `light`
- `highlight-1`, `highlight-2`, `highlight-3`
- `success`, `warning`, `danger`
- Legacy: **`color`** (hex) is still supported for backward compatibility but is deprecated. Prefer tokens for theme-aware palettes.

## Legend Configuration

Expand Down Expand Up @@ -307,6 +314,7 @@ See the [README](../README.md) for examples of loading JSON files in your applic
## Sample Files

Example JSON files are available in the `test-data/` directory:

- `test-data/paxos.json` - Complex distributed system (543 nodes, 581 edges)
- `test-data/chat.json` - Simpler chat application example

Expand Down
82 changes: 82 additions & 0 deletions docs/UI_SCALING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
# UI Scaling for Hydroscope

## Overview

Hydroscope now supports scaling the UI panels (InfoPanel, StyleTuner, and toggle buttons) to better fit constrained spaces like IDE extensions.

## Usage

Add the `uiScale` prop to the `Hydroscope` component:

```tsx
<Hydroscope
data={graphData}
uiScale={0.85} // Scale panels to 85% of original size
// ... other props
/>
```

## Scale Values

- **1.0** (default): Full size panels - ideal for standalone web applications
- **0.85**: Recommended for IDE extensions - provides better fit in limited space
- **0.7-0.9**: Acceptable range for most use cases
- **< 0.7**: Not recommended - text becomes too small to read comfortably

## What Gets Scaled

The `uiScale` prop applies CSS `transform: scale()` to:

1. **InfoPanel** - The information and hierarchy panel on the right
2. **StyleTuner** - The style configuration panel on the right
3. **Panel Toggle Buttons** - The buttons in the top-right corner

The transform origin is set to `top right` to ensure panels scale from their anchor point.

## What Doesn't Get Scaled

- The main ReactFlow graph visualization
- ReactFlow controls (zoom, fit view, etc.)
- The minimap
- Background patterns

## Implementation Details

The scaling is applied using CSS transforms:

```tsx
<div
style={{
transform: `scale(${uiScale})`,
transformOrigin: "top right",
}}
>
{/* Panel content */}
</div>
```

This approach:
- Maintains all interactive functionality
- Preserves layout calculations
- Doesn't affect ReactFlow's internal coordinate system
- Works consistently across browsers

## Example: IDE Integration

```tsx
// hydro-ide/webview/index.tsx
<Hydroscope
data={graphData}
showFileUpload={false}
showInfoPanel={true}
showStylePanel={true}
responsive={true}
uiScale={0.85} // Scale down for IDE
/>
```

## Notes

- The scaling is purely visual - all click targets and interactions work normally
- Font sizes in the panels are already optimized for readability
- If you need more aggressive scaling, consider also adjusting `PANEL_CONSTANTS` in `hydroscope/src/shared/config/ui.ts`
72 changes: 71 additions & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 4 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,8 @@
"dependencies": {
"@xyflow/react": "^12.8.2",
"antd": "^5.27.5",
"elkjs": "^0.11.0"
"elkjs": "^0.11.0",
"html-to-image": "^1.11.13"
},
"devDependencies": {
"@rollup/plugin-commonjs": "^28.0.8",
Expand Down Expand Up @@ -122,9 +123,9 @@
"vitest": "^3.2.4"
},
"optionalDependencies": {
"@rollup/rollup-linux-x64-gnu": "^4.52.4",
"@rollup/rollup-darwin-x64": "^4.52.4",
"@rollup/rollup-darwin-arm64": "^4.52.4",
"@rollup/rollup-darwin-x64": "^4.52.4",
"@rollup/rollup-linux-x64-gnu": "^4.52.4",
"@rollup/rollup-win32-x64-msvc": "^4.52.4"
},
"engines": {
Expand Down
51 changes: 31 additions & 20 deletions rollup.config.js
Original file line number Diff line number Diff line change
@@ -1,33 +1,44 @@
import resolve from '@rollup/plugin-node-resolve';
import commonjs from '@rollup/plugin-commonjs';
import typescript from '@rollup/plugin-typescript';
import postcss from 'rollup-plugin-postcss';
import resolve from "@rollup/plugin-node-resolve";
import commonjs from "@rollup/plugin-commonjs";
import typescript from "@rollup/plugin-typescript";
import postcss from "rollup-plugin-postcss";

export default {
input: 'src/index.ts',
external: ['react', 'react-dom', 'react/jsx-runtime', '@xyflow/react', 'elkjs', 'elkjs/lib/elk.bundled.js', 'antd'],
input: "src/index.ts",
external: [
"react",
"react-dom",
"react/jsx-runtime",
"@xyflow/react",
"elkjs",
"elkjs/lib/elk.bundled.js",
"antd",
],
onwarn(warning, warn) {
// Suppress "use client" directive warnings from Ant Design
if (warning.code === 'MODULE_LEVEL_DIRECTIVE' && warning.message.includes('use client')) {
if (
warning.code === "MODULE_LEVEL_DIRECTIVE" &&
warning.message.includes("use client")
) {
return;
}
warn(warning);
},
output: [
{
file: 'dist/index.cjs',
format: 'cjs',
file: "dist/index.cjs",
format: "cjs",
sourcemap: true,
inlineDynamicImports: true,
globals: {
'react': 'React',
'react-dom': 'ReactDOM',
'react/jsx-runtime': 'jsxRuntime'
}
react: "React",
"react-dom": "ReactDOM",
"react/jsx-runtime": "jsxRuntime",
},
},
{
file: 'dist/index.esm.js',
format: 'esm',
file: "dist/index.esm.js",
format: "esm",
sourcemap: true,
inlineDynamicImports: true,
},
Expand All @@ -39,14 +50,14 @@ export default {
}),
commonjs(),
typescript({
tsconfig: './tsconfig.build.json',
tsconfig: "./tsconfig.build.json",
declaration: true,
declarationDir: 'dist',
rootDir: 'src',
declarationDir: "dist",
rootDir: "src",
}),
postcss({
extract: 'style.css',
extract: "style.css",
minimize: true,
}),
],
};
};
Loading