vccs
Vue 3용 차트 컴포넌트 모음, Recharts에서 포팅
아직 감지된 업데이트가 없습니다. GitHub 릴리스가 나오면 여기에 보입니다.
개인 계정의 공개 저장소 소유자는 GitHub로 로그인해 운영자를 확인하고 소개를 직접 관리할 수 있습니다. 관리자 승인은 필요하지 않습니다.
로그인한 뒤 확인 파일을 만들어 이 저장소의 기본 브랜치에 30분 안에 커밋해 주세요. 다른 브랜치나 포크의 파일은 인정하지 않습니다. 파일을 올린 뒤 아래에서 확인하면 관리자 승인 없이 관리할 수 있습니다. 자격을 유지하려면 파일을 남겨 두세요.
로그인이 필요하면 로그인 화면으로 이동합니다. 로그인 후 이곳으로 돌아와 원하는 확인 버튼을 다시 눌러 주세요.
프로젝트 폴더에서 /nomorevibe verify를 실행하면 소유권을 확인하고 소개를 직접 관리할 수 있습니다.
1분 만에 확인하기README 전체를 불러오는 중입니다. 아래는 저장된 발췌입니다.
Colormeris is a set of static web pages that turn colors in scientific figures back into numbers. You load a PDF, PNG or JPG and click to mark the colorbar. The page reads values out of the colors and exports them as CSV. It can also save a project zip, which you can load again later to review or re-run the extraction.README 전문 보기 ↗Colormeris is a set of static web pages that turn colors in scientific figures back into numbers. You load a PDF, PNG or JPG and click to mark the colorbar. The page reads values out of the colors and exports them as CSV. It can also save a project zip, which you can load again later to review or re-run the extraction.
There are three pages:
index.html is the landing page.extract.html turns figure colors into numbers. It has three tools, which share the loaded file, viewer, colorbar calibration and project:
extract.html#heatmap) gives one value per cell of a gridded heatmap.extract.html#roi) measures signal inside regions of interest drawn on an image, such as an IVIS luminescence image.extract.html#map) reads near-continuous images, such as spectroscopy maps with many bins or fluorescence images, as a dense value matrix with axis coordinates, plus line profiles.colormaps.html browses, compares and identifies colormaps (see Colormaps).In extract.html, switch tools at any time with the Heatmap | ROI | Map control in the top bar. The file, the PDF page and each tool's panels stay. One project zip holds the work of every tool.
Everything runs in the browser. Files are never uploaded anywhere, except when you run the heatmap agent: it sends page images and extracted values to OpenRouter and the models you pick.
G). Click the outer top-left corner of the heatmap, then the outer bottom-right corner. Colormeris guesses the number of rows and columns from where the colors change and fills them in. Correct them if needed, or press Detect to guess again. Then paste the row and column labels, or open Row and column labels and press Read labels with AI: a vision LLM (OpenAI GPT-6.1 Sol by default; change it in the Model field below the button) reads them from the current view for this panel only. Zoom so the grid and its labels are visible. It uses the Agent's OpenRouter key or proxy, costs about a cent, and Undo reverts it. You can drag the corner handles to adjust. Uncheck Keep rectangular for skewed or rotated scans.
Dot plots (e.g. scRNA-seq), which have no cell borders and dots of different sizes: set Click on to Dot centers before placing, then click the centers of the top-left and bottom-right dots and type the rows and columns (Detect needs cell borders). The grid is drawn through the dot centers. Each dot is sampled inside a circle of 70 % of its own radius, found from where its color meets the background; a cell without a dot is left blank. Shape (Square / Circle) and Sampled area are under Options in both modes.B) and click both ends of the bar along its middle. Lines within 3° of vertical or horizontal snap straight; hold Alt to turn snapping off. Next, click at least two labelled ticks on the bar and type their values (T). Values between ticks are interpolated linearly, and values beyond the outer ticks are extrapolated. If the tick labels are raw numbers on a logarithmic bar, choose Log₁₀. If the tick values are uneven along the bar (for example a binned bar labelled 1e4, 2e4, 2e5, 5e5 at its steps), choose Piecewise, or Piecewise log10 for positive values over decades: values are then interpolated between neighbouring ticks only. A binned bar (flat colors with steps between them) is found by itself: each cell gets the middle value of its bin, and a bin past the outermost tick gets that tick's value as a bound (at most or at least). Cells whose color is not on the colormap, such as gray "ND" cells or a black diagonal, get no value. Cells past an end of the bar (paler or darker in the bar's own colors) read as that end. Drag an end handle to adjust the bar: under When dragging an end, ticks, choose whether the ticks move with the bar (keeping their proportions) or stay in place on their printed marks. Drag the line itself to move the whole calibration, ticks included. To place a tick exactly, type its position in % along the bar (0 at the start, 100 at the end) in the tick table. Under the sampled strip, the card suggests the Matplotlib, CMasher, Crameri, cmocean, colorcet, seaborn, CarbonPlan, NCL, SciVisColor, CARTOColors, MATLAB or R packages colormap the bar matches (for example jet or viridis_r, with its ΔE2000 score and a link to the colormap viewer). With two ticks the direction follows the values; this works in the ROI tool too.
Known colormap. When the figure's colorbar is missing, tiny or badly compressed, set Colors to Known colormap and pick the map with the same search field as the colormap viewer (any of the 1063 maps; type name_r or tick Reversed for the reversed map). Two ticks appear at 0% and 100% of the colormap, valued 0 and 1 (1 and 10 on a log scale): type the figure's values at its ends, or keep them for values relative to the colormap. Type a tick adds more by value and position in % along the colormap, and every tick's position can be edited in the table. Placing the colorbar ends is then optional; if you do, ticks clicked on the bar count too. When a figure's bar matches a known map, the suggestion under the strip has Use its colors to switch to that map's exact colors. This works the same in the ROI and Map tools.status (ok, flagged, clamped, off-map, empty), a bound (<= or >= for values that are only bounds) and a reason for off-map cells (gray, hue, far).Navigation: scroll to zoom and drag to pan. Space-drag or middle-drag always pans. F fits the image to the view, Esc cancels the current tool, and Ctrl/⌘+Z undoes.
B-a11, B-a16, …. Remove drops the grid.1.4e9.E), Rectangle (R) or Polygon (P).Measurements for each region copy:
| Column | Meaning |
|---|---|
area_px | pixels inside the region |
signal_px | pixels with colormap color (not gray) |
sum | total of the colorbar values over the region (gray = 0), like total flux in pixel units |
mean | sum / area_px, like average radiance |
mean_signal | sum / signal_px |
max | highest value |
flagged_px | colored pixels that match no colorbar color (ΔE above the limit), e.g. colored text. They are still counted as signal with their nearest colorbar value. |
area_<unit>2, signal_area_<unit>2, sum_x_area | with a scale bar: areas in real units, and sum × pixel area |
Background: a pixel whose CIELAB chroma is at or below the gray threshold is the photograph, i.e. no signal. The default is 20, which removes the JPEG color noise seen in published IVIS figures while keeping the dimmest overlay colors. Adjust it under Settings → Matching and check with Show signal.
For figures whose pixels are the data: spectroscopy maps with so many bins that they look continuous, or false-color fluorescence images with a calibration bar.
G) and click the top-left and bottom-right corners of the image area, inside the axes.X), click two or more labelled ticks on the x axis and type their values. Do the same for y (Y). Ticks stay on the plot area's edges (x on the bottom, y on the left), so only their position along the axis counts; drag them along the edge to adjust, or type a position in % across the plot area in the tick table (0 at the left or top, 100 at the right or bottom), for example for a tick exactly at the plot's corner. Each axis can be linear or Log₁₀. Without ticks, coordinates are pixels from the plot's top-left corner.L) and click both ends of a line, for example a spectrum at one delay or a line scan across a cell. X axis picks what the plot's horizontal axis shows: Axis (the calibrated axis the line mostly runs along), px (distance from the line's start in pixels) or the scale-bar unit (distance from the line's start in real length, for example µm). It is the same setting as Coordinates in the Results card. When a choice is not available it falls back to the axis, then the scale bar, then pixels. Length sets how long the line is, in the same units; the start and direction stay. Width averages ± pixels across the line. Shift- or Cmd-click profiles (chips or lines) to overlay several in the plot, each in its own color; Select all overlays every profile. Scale plots the values as they are, so signal levels compare directly, or divides each profile by its own maximum or mean, so their shapes compare. Hover the plot or a line on the image to trace it: both show the same sample, with its position and value. Drag the ends or the line to move it; hold Shift to move it only horizontally or vertically. Hold Ctrl (⌘ on a Mac) when you start dragging a line to drag a copy and leave the original in place. Ctrl+C / Ctrl+V (⌘ on a Mac) copy and paste the selected profiles, also into another panel or page: there a copy keeps its place within the plot area, so the same line scan lands in the same spot of a panel of another size. () moves the edited profile across the plot area, perpendicular to itself, and back at each edge, so the plot plays like an animation. sets how fast, in page pixels per second. With the line keeps going until no part of it is left in the plot area, which covers more of a slanted line's corners. Parts of any profile outside the plot area are left out of the plot and the CSV. The value axis stays fixed during the sweep, so heights compare between frames. leaves the line where it is; one undo puts it back where it started.What the numbers can and cannot tell you:
Large maps take a moment: a 600 × 400 px map at bin 1 takes about 1–2 s with CIEDE2000, and CIE76 (in Settings) is about 10× faster.
The Agent card in the heatmap tool calibrates every heatmap on the chosen pages by itself:
OPENROUTER_API_KEY=… in .env (ignored by git), run npm run proxy, and set API base URL to http://localhost:8787/api/v1 with the key field empty.typesafe/jev-1.14) locates its cells and colorbar, one heatmap per request. Colormeris snaps those boxes to the pixels and counts the rows and columns itself. The LLM then reads the numbered tick labels and the row and column labels from one image per heatmap. When it is unclear which colorbar belongs to a heatmap (several colorbars, or one far away), the LLM picks it from lettered candidates, or copies another panel's colorbar when several blocks share one. Strips of cells with their own colorbar (such as a -log10(p) row) are extracted as panels of their own. This takes fewer LLM steps and images: on the example PDF's page 5 (10 heatmaps), 3 steps and about $0.19, of which the decision model cost half a cent.anthropic/claude-sonnet-5.5. Requests use prompt caching, and the card shows the share of prompt tokens read from the cache. Then choose the pages and press Run agent.The agent retries a failing tool at most 3 times per panel, then skips that step and reports it. It stops after 8 failed calls in a row or after Max. steps. The log shows every step and the cost so far.
Page images and extracted values are sent to OpenRouter and the model providers you pick.
Settings (top right) holds what belongs to you rather than to a figure. It is saved in the browser as you change it.
colormeris-settings.zip (one settings.json); Import settings reads it back, or a bare settings.json. The API key is left out unless you tick Include the API key; importing a file without a key keeps the current one.extract.html exposes typed actions as window.colormeris, so any program can drive the tools without clicking pixels:
await colormeris.run('set_grid', { topLeft: { x: 40, y: 60 }, bottomRight: { x: 520, y: 400 } });
await colormeris.run('add_tick', { at: { x: 560, y: 400 }, value: 0 });
await colormeris.run('get_results'); // → { ok, result } or { ok: false, error }
docs/agent.md is the full reference: every action and argument, typed questions and reviews, the heatmap agent's tools, limits and system prompt. It is generated from the code with node scripts/agent-docs.mjs, and a test fails when it is out of date.
colormaps.html is a viewer for 1063 colormaps: the 87 of Matplotlib, 53 from CMasher (cmr.amber), 36 from Crameri's Scientific colour maps (cmc.batlow) 21 from cmocean (cmo.thermal) 80 from colorcet (cet_fire) and 12 from seaborn (rocket, vlag, and the qualitative deep to colorblind), named as matplotlib registers them, 58 from CarbonPlan (carbonplan.fire_light, carbonplan.fire_dark: one version for light and one for dark backgrounds; rainbow and sinebow are the same in both, so only _light is listed), 162 of NCAR's NCL color tables (ncl.BlueRed; stepped tables such as ncl.precip_11lev are shown as steps, as matplotlib draws them, and NCL has no types, so their groups are ours), 107 from SciVisColor (sciviz.yg1; non-sequential ones sorted by eye into diverging, multi-sequential, outlier-range and discrete), and 34 from CARTOColors (carto.Burg) and 2 from MATLAB (matlab.parula, matlab.lines; MATLAB's other maps, such as jet and hot, are Matplotlib's) and 411 from R packages, as listed by R Charts from the collection (, , , , and others from ggpomological, ggthemr, tidyquant, tvthemes, vapoRwave, colorBlindness, dichromat and cartography; R Charts shows continuous palettes as 30 samples, which are interpolated linearly, and discrete ones as steps; the groups are ours, sorted by lightness; RColorBrewer and viridis are already Matplotlib's, copies of maps listed earlier are left out, and so is , which has 51 colors). CARTOColors are palettes of up to 7 steps; their continuous versions interpolate the 7 colors in sRGB. Maps with the same colors as one already listed are left out: the shifted cyclic CMasher maps (), Crameri's categorical maps (), berlin, managua and vanimo, which ship with Matplotlib, and , which is . colorcet registers most maps three times (, , ); only the short name is kept, and its rotated cyclic maps (, ) and 256-color Glasbey palettes are left out, as are seaborn's 6-color palettes (), which are subsets of the 10-color ones, and NCL's copies of other maps (, , an older ), test tables and 170-class tables (). in can show the maps of one source; the Python packages and the R packages are each a group of sources, and sub-headings read or . Every sub-heading shows how many maps it holds. Within each sub-heading, maps are ordered by similarity, so families sit together. Each row has a reverse button (⇄). In sequential sections, maps that run the other way than most of their neighbors start reversed (the button is then on), so a section reads one way; under ⋯ still flips everything. It has five tabs: , , , and . The tab, the open map and the comparison are kept in the page link, so any view can be shared.
colormaps.html?compare=viridis,cividis#compare).project.json per panel: tool (heatmap, roi or map), page, grid, colorbar,
labels, settings, review (accepted/rejected), for ROI
the regions and scale bar, and for maps the bin size,
axis ticks and profiles
README.txt
source/<original file> the uploaded PDF/image
source/page-<n>.png the rendered image of each page that has panels
data/<panel>.csv heatmap: matrix of values
data/<panel>_long.csv heatmap: per-cell values with page, RGB and ΔE
data/<panel>_rois.csv ROI: measurements per region copy
data/<panel>_map.csv map: matrix of values with x and y at bin centres
data/<panel>_map_long.csv map: one row per value with ΔE and flags
data/<panel>_profile_<name>.csv map: values along each profile
agent/actions.json changes made through the agent API, in order
agent/decisions.json typed decisions (answer, confidence, source, applied)
The agent logs are written but not read back when a zip is reopened; panel reviews are (they live in project.json). Each panel records its page. Its coordinates are pixels in that page's source/page-<n>.png. Regions copied into every box are stored relative to a box, where a box spans 0–1 in each direction, with per-box nudges. A zip opens in either tool with everything in it. Version 1 zips load too; one without a tool is a heatmap project. Zips saved before the ROI tool was renamed (tool ivis) are refused with an error rather than opened as heatmaps.
More documentation: docs/agent.md (agent reference, generated), docs/research.md (prior work, novelty, experiment plan), and CLAUDE.md (architecture, conventions, status and next steps for Claude sessions).
The app is written in TypeScript (strict) and built with Vite. extract.html and colormaps.html each load one module entry from src/pages/; index.html is static. pdf.js, JSZip and the OpenRouter TypeScript SDK (loaded only when the agent runs) come from npm. Node 22.18 or newer:
npm install
npm run dev # dev server on http://localhost:8000 with hot reload
npm run check # lint (Biome), typecheck (tsc) and unit tests (Vitest); run before every commit
npm run build # production build in dist/ (npm run preview serves it)
npm run format # format with Biome
npm run proxy # optional: OpenRouter proxy on :8787 using the key in .env
npm run docs # regenerate docs/agent.md after changing the agent
npm run fixtures # regenerate the synthetic calibration heatmaps in src/testing/fixtures/
CI (.github/workflows/ci.yml) runs lint, typecheck, tests and the build on every push and pull request. Pushes to main that pass CI are deployed to GitHub Pages by .github/workflows/pages.yml (repository settings → Pages → Source: GitHub Actions). docs/typescript.md has the coding conventions.
The code is grouped by feature. Files without DOM code have unit tests next to them (grid.ts and grid.test.ts).
| Folder | Purpose |
|---|---|
src/pages/ | one entry per page: extract.ts starts the extraction app, colormaps.ts the colormap viewer |
src/types/ | shared domain types: project, panels, grids, colorbars, results, settings, workspace, agent, colormaps |
src/core/ | shared by both apps: color spaces and ΔE (color.ts), CVD simulation (cvd.ts), grid geometry and cell sampling (grid.ts), colorbar calibration (colorbar.ts), snapping rough boxes to cells, colorbars and tick labels (locate.ts), the colormap library (colormap-library.ts, data in src/generated/) and matching a bar to a known colormap (colormap-match.ts) |
src/extract/ | extract.html: project model and files (project/), settings (settings/), PDF loading, the canvas viewer and the scale bar |
src/extract/workspace/ | the shell the tools share: workspace.ts (state, modes, tool switching) and one file each for undo, overlay drawing, pointer input, the Grid, Colorbar and Panels cards, opening files and pages, export and hotkeys |
src/extract/heatmap/, roi/, map/ | the three tools: pure extraction (sampling.ts, geometry.ts and quantify.ts, field.ts) and the tool UI |
src/agent/ | agent API and heatmap agent: action schema (schema.ts), window.colormeris (api.ts), prompt, tools and retry guard (llm.ts), decision mode (decide.ts, decision-tools.ts), the loop (runner.ts); the Agent card and label reader in ui/ |
src/colormaps/ | colormaps.html: viewer.ts (state, tabs, page) with one file per tab in tabs/, plus strips, plots, footer, URL routing (route.ts), ratings (metrics.ts), references and recoloring |
src/styles/ | base.css for every page, plus , and |
Kx_px), or scale-bar lengths from that corner (x_µm). It is saved with the panel and shared with the profile plot's X axis. Download CSV saves the matrix, with x of each column in the header and y of each row in the first column. Long CSV saves one row per value with ΔE and flags. Download profile CSV saves the selected profile; with several selected it saves them in one table with a profile column. With a scale bar, the profile CSV adds a d_<unit> column (for example d_µm) after d_px. When Scale divides the values, the CSV adds a value_per_max or value_per_mean column. The project zip includes all of them.paletteerggthemes::Tableau_10ggsci::nrc_npggrDevices::Blue-Redwesanderson::Zissou1ggsci::default_igv_sScmo.graycmr.neutralcet_firecet_linear_kryw_0_100_c71cet_CET_L3_s25CET_C1sdeep6GMT_graymatlab_hotcividislithologyPython packages: MatplotlibR packages: ggthemesname_r turns on Reversed). Every pixel with a color of the bar gets the new map's color at the same place on the bar, so a jet figure can be seen in viridis, for example. Pixels farther than Match within (ΔE) from the bar keep their color, so the background, text and axes stay as they are. When the background or other parts share colors with the bar, press Draw regions and drag rectangles on the original around the parts to recolor (the plot, the colorbar); only pixels inside them change. Press it again or Esc to stop drawing; Whole image removes the regions. When the old map is a known one and the line runs from its high end, the bar is read the other way, so low stays low. Hover a color in the figure, or a place on the strips under it, and every pixel with a similar value (Similar within, 2% of the bar by default) flashes quickly between its own color and its complementary color. With reduced motion turned on, the rest of the figure is dimmed instead. Press and hold the figure to see the other version (original or recolored); release to go back. Original / Recolored switch for good. Download PNG saves the recolored figure at full size.colormaps package (CarbonPlan, NCL, SciVisColor) the cartocolor npm package (fetched from unpkg) MATLAB's parula (values embedded in the script) and R palettes (scripts/fetch-r-palettes.py saves them from R Charts to scripts/data/r-palettes.json) by uv run --with matplotlib --with cmasher --with cmcrameri --with cmocean --with colorcet --with seaborn --with colormaps python scripts/export-mpl-colormaps.py. The CVD views use the Machado et al. (2009) model. Methods and references are in the fold at the bottom of the page.landing.cssextract.csscolormaps.csssrc/testing/ | test helpers and the synthetic calibration fixtures |
public/ | files served as they are: examples/ (example.pdf, example-jet.png) and, copied from node_modules before dev and build, pdfjs/ |
scripts/ | generators and tools: agent-docs.ts (docs/agent.md), export-mpl-colormaps.py (colormap data), make-calibration.mjs (synthetic test heatmaps), copy-pdfjs-assets.mjs, openrouter-proxy.mjs |