Skip to content

CodeCharta City Visualization Research

Status: Research Document Created: March 2026 Scope: Forma 3D Connect — Code-as-a-City Visualization with SonarCloud + Git History

Table of Contents

  1. Executive Summary
  2. What Is CodeCharta
  3. Data Sources & Metrics
  4. Option A — Local Developer Workstation
  5. Option B — CI-Generated Artifacts (No Serving)
  6. Option C — Hosted Web Studio + Docs-Served Data (Recommended)
  7. Option D — CI-Generated + Self-Hosted Visualization Container
  8. Architecture Diagrams
  9. SonarCloud Integration Details
  10. Git History Integration Details
  11. Merging Sonar + Git Metrics
  12. Pipeline Integration (Azure DevOps)
  13. Cost & Resource Analysis
  14. Security Considerations
  15. Comparison Matrix
  16. Recommended Approach
  17. Implementation Roadmap
  18. References

1. Executive Summary

CodeCharta is an open-source tool by MaibornWolff that transforms code metrics into an interactive 3D city visualization. Each file becomes a building — its footprint represents size (lines of code), height represents complexity, and color represents quality indicators. The result is an immediately comprehensible view of hotspots, tech debt, and change frequency across the entire codebase.

CodeCharta can ingest metrics from SonarCloud (which we already run in our Azure DevOps pipeline) and git history (which we already have). No additional scanning infrastructure is needed.

Key Findings

Aspect A: Local B: CI Artifact C: Hosted Studio + Docs Data D: Self-Hosted Container
Setup effort 10 min 2–4 hrs 2–4 hrs 4–8 hrs
Ongoing maintenance None Minimal Minimal Low
Team access Single developer Download artifact Shareable URL Shareable URL
Freshness On-demand Per-pipeline run Per-pipeline run Per-pipeline run
Infrastructure cost $0 $0 $0 ~$0 (extra container)
Extra container needed No No No Yes
Recommended for Exploration / POC Small teams Team-wide adoption Full self-hosting

Recommendation

Start with Option A (local) for immediate validation, then move to Option C — generate the .cc.json in CI and serve it from the existing docs container; use the publicly hosted CodeCharta Web Studio at codecharta.com for visualization. No extra Docker image, no extra DNS record — just a shareable URL. The CI pipeline already has a Code Quality stage; the CodeCharta generation step slots in after it.


2. What Is CodeCharta

CodeCharta consists of two components:

Component Purpose Distribution
CCSH (CodeCharta Shell) CLI that imports, parses, and merges metrics into .cc.json files npm i -g codecharta-analysis or codecharta/codecharta-analysis Docker image
Web Studio Browser-based 3D visualization that renders .cc.json files codecharta/codecharta-visualization Docker image or hosted instance

The data flow is straightforward:

Source (Sonar API / git repo) → CCSH → .cc.json → Web Studio → 3D City Map

Key features relevant to us:

  • SonarCloud importer — pulls all metrics via the SonarCloud Web API using a user token
  • Git log parser — extracts commit history metrics (authors, churn, coupling, age)
  • Merge filter — combines multiple .cc.json files into one enriched map
  • URL parameter loading — Web Studio can auto-load .cc.json files from a URL
  • Delta mode — compare two snapshots to see what changed between sprints/releases
  • Runs entirely client-side — no metrics ever leave the browser once loaded

3. Data Sources & Metrics

3.1 SonarCloud Metrics (via sonarimport)

These are already computed by our SonarCloud analysis. CodeCharta pulls them via API:

Metric City Dimension Value
ncloc (lines of code) Building footprint (area) File size
complexity / cognitive_complexity Building height Complexity hotspots
code_smells Building color (red) Quality issues
bugs Building color (red) Defects
vulnerabilities Building color (red) Security issues
coverage Building color (green→red) Test coverage
duplicated_lines_density Alternative color metric Code duplication
sqale_index (tech debt) Alternative height Debt in minutes

3.2 Git History Metrics (via gitlogparser)

These are extracted directly from the git repository:

Metric Insight
number_of_authors Knowledge distribution — single-author files are bus-factor risks
number_of_commits Change frequency — frequently changed files deserve more attention
weeks_with_commits Sustained activity vs. burst edits
age_in_weeks File age — old + complex = likely tech debt
highly_coupled_files Files that always change together (hidden dependencies)
number_of_renames Refactoring churn
fix_commits / hotfix_commits Bug-prone files

3.3 Combined View (Merged)

The real power comes from merging both sources:

  • Area = ncloc (lines of code) → big buildings are big files
  • Height = cognitive_complexity (from Sonar) → tall buildings are complex
  • Color = number_of_commits (from git) → red buildings change often
  • Edge metric = temporal_coupling → lines connect files that always change together

This immediately highlights hotspots: large, complex files that change frequently — the prime candidates for refactoring.


4. Option A — Local Developer Workstation

The fastest way to validate CodeCharta's value. Run everything on your MacBook.

Prerequisites

  • Node.js >= 20 (already available)
  • Java >= 11 (brew install openjdk@21)
  • SonarCloud user token (generate at sonarcloud.io → My Account → Security)

Steps

# 1. Install CodeCharta CLI
npm i -g codecharta-analysis

# 2. Import SonarCloud metrics
ccsh sonarimport \
  https://sonarcloud.io \
  devgem_forma-3d-connect \
  --user-token=<YOUR_SONARCLOUD_TOKEN> \
  --output-file=sonar.cc.json

# 3. Parse git history (repo-scan mode — no manual log extraction)
ccsh gitlogparser repo-scan \
  --repo-path /Users/jeankedotcom/devgem/forma-3d-connect \
  --add-author \
  -o git.cc.json

# 4. Merge both into a single enriched map
ccsh merge --leaf sonar.cc.json git.cc.json -o forma3d.cc.json

# 5. Open in Web Studio (Docker)
docker run -d -p 9100:80 codecharta/codecharta-visualization

# 6. Open browser → localhost:9100 → Import → upload forma3d.cc.json

macOS note: When using the Docker analysis container, add --user=501:dialout before the image name to avoid git permission issues.

Alternative: All-in-Docker (No npm Install)

# Run analysis entirely in Docker
docker run --rm \
  -v $(pwd):/src \
  --user=501:dialout \
  -w /src \
  codecharta/codecharta-analysis bash -c '
    git config --global --add safe.directory /src &&
    ccsh sonarimport https://sonarcloud.io devgem_forma-3d-connect \
      --user-token=<TOKEN> -o sonar.cc.json -nc &&
    ccsh gitlogparser repo-scan --repo-path /src --add-author -o git.cc.json -nc &&
    ccsh merge --leaf sonar.cc.json git.cc.json -o forma3d.cc.json -nc
  '

Effort & Outcome

Aspect Detail
Setup time ~10 minutes
Output forma3d.cc.json file on disk + local Web Studio
Who can access Developer who ran the command
When to refresh Manually, whenever desired

5. Option B — CI-Generated Artifacts (No Serving)

Generate the .cc.json in the Azure DevOps pipeline as a build artifact. Team members download and open it in the hosted Web Studio.

How It Works

uml diagram

Pipeline YAML Fragment

- stage: CodeCharta
  displayName: 'CodeCharta City Map'
  dependsOn: CodeQuality
  condition: and(succeeded(), eq(variables['Build.SourceBranch'], 'refs/heads/main'))
  jobs:
    - job: GenerateCityMap
      displayName: 'Generate CodeCharta Map'
      pool:
        vmImage: 'ubuntu-latest'
      container:
        image: codecharta/codecharta-analysis
      steps:
        - checkout: self
          fetchDepth: 0  # Full history for gitlogparser

        - script: |
            git config --global --add safe.directory $(Build.SourcesDirectory)
            ccsh sonarimport \
              https://sonarcloud.io \
              devgem_forma-3d-connect \
              --user-token=$(SONARCLOUD_TOKEN) \
              -o sonar.cc.json -nc
            ccsh gitlogparser repo-scan \
              --repo-path $(Build.SourcesDirectory) \
              --add-author \
              -o git.cc.json -nc
            ccsh merge --leaf sonar.cc.json git.cc.json \
              -o $(Build.ArtifactStagingDirectory)/forma3d.cc.json -nc
          displayName: 'Generate city map from SonarCloud + Git'

        - publish: $(Build.ArtifactStagingDirectory)/forma3d.cc.json
          artifact: codecharta-map
          displayName: 'Publish CodeCharta artifact'

Effort & Outcome

Aspect Detail
Setup time 2–4 hours (pipeline + token setup)
Output Downloadable artifact per main build
Who can access Anyone with Azure DevOps access
When to refresh Every main branch build

The simplest path to team-wide access: generate the .cc.json in CI, bake it into the existing docs container, and use the publicly hosted CodeCharta Web Studio at codecharta.com for visualization. No extra Docker image, no extra DNS, no extra docker-compose entry.

The key insight: CodeCharta's Web Studio runs entirely in the browser. It can load .cc.json files from any URL via the ?file= query parameter, as long as the server responds with the correct CORS header.

Architecture

uml diagram

What Changes

Only two files need modification — no new containers:

1. Nginx config — add a CORS-enabled location for /codecharta/:

# Added to deployment/docs/nginx.conf inside the server block
location /codecharta/ {
    add_header Access-Control-Allow-Origin "https://codecharta.com" always;
    add_header Access-Control-Allow-Methods "GET, OPTIONS" always;
    add_header Access-Control-Allow-Headers "Range" always;
    add_header Cache-Control "no-cache";
    try_files $uri =404;
}

2. Docs Dockerfile — copy the pipeline-generated .cc.json into the image:

# Added to deployment/docs/Dockerfile in the production stage
# The cc.json is generated by the CodeCharta pipeline stage and placed
# in the build context before the Docker build runs.
COPY codecharta/forma3d.cc.json /usr/share/nginx/html/codecharta/forma3d.cc.json

Shareable URLs

Users receive a single link. The CodeCharta Web Studio handles everything in the browser:

Link View
codecharta.com/visualization/app/index.html?file=https://staging-connect-docs.forma3d.be/codecharta/forma3d.cc.json&area=ncloc&height=cognitive_complexity&color=code_smells Complexity hotspots
...&area=ncloc&height=number_of_commits&color=number_of_authors Change frequency & knowledge silos
...&area=ncloc&height=sqale_index&color=coverage Tech debt vs. coverage
...&file=.../sprint-42.cc.json&file=.../sprint-43.cc.json&mode=Delta Sprint-over-sprint delta

Why This Works

  • CodeCharta Web Studio is a static JavaScript app — all rendering happens client-side
  • The ?file= parameter triggers an XHR fetch to the provided URL
  • As long as the Nginx serving the .cc.json responds with Access-Control-Allow-Origin: https://codecharta.com, the fetch succeeds
  • No source code is ever sent anywhere — the .cc.json only contains file paths and numeric metrics

Effort & Outcome

Aspect Detail
Setup time 2–4 hours (pipeline stage + Nginx tweak + Dockerfile tweak)
Output Shareable URL that opens a pre-loaded 3D city map
Who can access Anyone with the link
When to refresh Every main branch build (map updates with docs image)
Extra infrastructure None — reuses existing docs container

7. Option D — CI-Generated + Self-Hosted Visualization Container

A heavier alternative if you want full control over the visualization (e.g., to customize the UI, run offline, or avoid any dependency on codecharta.com).

Custom Dockerfile

# deployment/codecharta/Dockerfile
FROM codecharta/codecharta-visualization:latest

COPY forma3d.cc.json /usr/share/nginx/html/data/forma3d.cc.json

RUN sed -i 's|<head>|<head><script>if(!location.search)location.search="file=data/forma3d.cc.json\&area=ncloc\&height=cognitive_complexity\&color=number_of_commits";</script>|' \
    /usr/share/nginx/html/index.html

Docker Compose Addition

codecharta:
  image: registry.digitalocean.com/forma-3d/forma3d-connect-codecharta:${BUILD_NUMBER:-latest}
  restart: unless-stopped
  labels:
    - "traefik.enable=true"
    - "traefik.http.routers.codecharta.rule=Host(`codecharta.forma3d.be`)"
    - "traefik.http.routers.codecharta.entrypoints=websecure"
    - "traefik.http.routers.codecharta.tls.certresolver=letsencrypt"
    - "traefik.http.services.codecharta.loadbalancer.server.port=80"
  networks:
    - web

Effort & Outcome

Aspect Detail
Setup time 4–8 hours (Dockerfile, pipeline, DNS, docker-compose)
Output Self-hosted visualization at codecharta.forma3d.be
Who can access Anyone with the URL
Extra infrastructure New container (~15 MB / ~20 MB RAM), new DNS record

8. Architecture Diagrams

8.1 Data Flow — End to End

uml diagram

uml diagram

8.3 Option C vs Option D — No Extra Container Needed

uml diagram


9. SonarCloud Integration Details

8.1 API Access

CodeCharta's sonarimport communicates with the same Web API that SonarCloud exposes. The command syntax is identical for SonarCloud and SonarQube — only the URL and authentication differ.

Parameter Our Value
URL https://sonarcloud.io
Project Key devgem_forma-3d-connect
Organization devgem (implicit in project key)
Token SonarCloud user token (generate under My Account → Security)

8.2 Command

ccsh sonarimport \
  https://sonarcloud.io \
  devgem_forma-3d-connect \
  --user-token=$SONARCLOUD_TOKEN \
  --output-file=sonar.cc.json

8.3 Metric Selection

By default, sonarimport pulls all available metrics. To limit to the most useful ones:

ccsh sonarimport \
  https://sonarcloud.io \
  devgem_forma-3d-connect \
  --user-token=$SONARCLOUD_TOKEN \
  --metrics=ncloc,complexity,cognitive_complexity,code_smells,bugs,vulnerabilities,coverage,duplicated_lines_density,sqale_index \
  --output-file=sonar.cc.json

8.4 SonarCloud Token Management

Environment Storage
Local ~/.codecharta/sonarcloud-token or environment variable
Azure DevOps Secret variable in forma3d-staging variable group

10. Git History Integration Details

The simplest approach — point the parser at the repo and it handles everything:

ccsh gitlogparser repo-scan \
  --repo-path . \
  --add-author \
  -o git.cc.json

Important for CI: The pipeline checkout step must use fetchDepth: 0 (full clone) instead of the default shallow clone, otherwise git history will be incomplete.

9.2 log-scan Mode (Alternative)

For environments where direct repo access is awkward:

git log --numstat --raw --topo-order --reverse -m > git.log
git ls-files > file-list.txt
ccsh gitlogparser log-scan \
  --git-log git.log \
  --repo-files file-list.txt \
  -o git.cc.json

9.3 Edge Metrics

The git log parser produces edge metrics (temporal coupling between files). These appear as connecting lines in the city map, revealing hidden dependencies — files that always change together but may not have explicit import relationships.


11. Merging Sonar + Git Metrics

10.1 Merge Strategy

Use --leaf merging to fit git metrics into the Sonar project structure:

ccsh merge --leaf sonar.cc.json git.cc.json -o forma3d.cc.json

The --leaf strategy matches files by name (leaf node) rather than full path, which handles cases where SonarCloud and git may have slightly different path structures.

10.2 Pipe-Through Alternative

Some importers support piping, avoiding the need for intermediate files:

ccsh sonarimport https://sonarcloud.io devgem_forma-3d-connect \
  --user-token=$TOKEN -o sonar.cc.json -nc | \
ccsh gitlogparser repo-scan --repo-path . --add-author -o forma3d.cc.json -nc

10.3 Delta Maps

For sprint-over-sprint comparison, generate maps at two points in time and load both in Delta mode:

codecharta.forma3d.be/?file=data/sprint-42.cc.json&file=data/sprint-43.cc.json&mode=Delta

This highlights what grew, shrank, or changed quality between sprints.


12. Pipeline Integration (Azure DevOps)

12.1 Where It Fits

The CodeCharta stage runs after Code Quality (SonarCloud) and before Build & Package. It depends on SonarCloud completion because it needs the analysis results available via the SonarCloud API.

uml diagram

12.2 Full Pipeline YAML

# Addition to azure-pipelines.yml
- stage: CodeCharta
  displayName: 'CodeCharta City Map'
  dependsOn: CodeQuality
  condition: and(succeeded(), eq(variables['Build.SourceBranch'], 'refs/heads/main'))
  jobs:
    - job: GenerateCityMap
      displayName: 'Generate CodeCharta Map'
      pool:
        vmImage: 'ubuntu-latest'
      steps:
        - checkout: self
          fetchDepth: 0

        - task: DockerInstaller@0
          inputs:
            dockerVersion: '24.0'

        - script: |
            docker run --rm \
              -v $(Build.SourcesDirectory):/src \
              -w /src \
              codecharta/codecharta-analysis bash -c '
                git config --global --add safe.directory /src &&
                ccsh sonarimport \
                  https://sonarcloud.io \
                  devgem_forma-3d-connect \
                  --user-token=$(SONARCLOUD_CODECHARTA_TOKEN) \
                  -o sonar.cc.json -nc &&
                ccsh gitlogparser repo-scan \
                  --repo-path /src \
                  --add-author \
                  -o git.cc.json -nc &&
                ccsh merge --leaf sonar.cc.json git.cc.json \
                  -o /src/forma3d.cc.json -nc
              '
          displayName: 'Generate city map'

        - publish: $(Build.SourcesDirectory)/forma3d.cc.json
          artifact: codecharta-map
          displayName: 'Publish CodeCharta artifact'

12.3 Token Configuration

Add a secret variable SONARCLOUD_CODECHARTA_TOKEN to the forma3d-staging variable group. This is a read-only SonarCloud user token — separate from the existing SonarCloud service connection token used for analysis.


13. Cost & Resource Analysis

Cost Category Option A (Local) Option B (CI Artifact) Option C (Hosted + Docs) Option D (Self-Hosted)
Infrastructure $0 $0 $0 $0 (shared droplet)
CI compute $0 ~2 min MS-hosted ~2 min MS-hosted ~2 min MS-hosted
Docker registry storage $0 $0 $0 (reuses docs image) ~15 MB (negligible)
SonarCloud Existing plan Existing plan Existing plan Existing plan
DNS N/A N/A N/A (reuses docs domain) New CNAME record
Extra container No No No Yes (~20 MB RAM)
Total incremental cost $0 ~$0 $0 ~$0

The codecharta-analysis Docker image (~1.2 GB) is pulled during CI only. On Microsoft-hosted agents, this is cached across builds.


14. Security Considerations

Concern Mitigation
SonarCloud token in CI Store as secret variable in forma3d-staging variable group; use a read-only user token
Metrics data exposure CodeCharta Web Studio is client-side only — no server-side processing; metrics stay in the browser
.cc.json public access The file contains file paths and numeric metrics — no source code. Low sensitivity, but restrict access via Nginx allow/deny or Traefik IP whitelist if desired
Dependency on codecharta.com The hosted Web Studio is a static JavaScript app. If it goes down, fall back to the Docker image (codecharta/codecharta-visualization) locally or use Option D

15. Comparison Matrix

Criterion A: Local B: CI Artifact C: Hosted + Docs (Rec.) D: Self-Hosted Container
Setup complexity Low Medium Medium Medium-High
Team accessibility Single user Download required Shareable URL Shareable URL
Freshness Manual Per main build Per main build Per main build
Bookmarkable views No No Yes (URL params) Yes (URL params)
Extra container No No No Yes
Extra DNS record No No No Yes
Infrastructure cost $0 $0 $0 ~$0
Maintenance None Pipeline config Pipeline + Nginx tweak Pipeline + container
Sprint demo friendly No No Yes Yes
Works if codecharta.com is down Yes Yes No (fallback: local Docker) Yes
CI pipeline changes None New stage New stage New stage + Dockerfile

Phase 1: Validate (Week 1)

Option A — Local exploration

  1. Install CCSH: npm i -g codecharta-analysis
  2. Generate a merged map from SonarCloud + git
  3. Open in Web Studio (either docker run -p 9100:80 codecharta/codecharta-visualization or at codecharta.com)
  4. Evaluate whether the city view provides actionable insights for the team

Phase 2: Automate (Week 2)

Option C — Hosted Web Studio + Docs-served data

  1. Add SONARCLOUD_CODECHARTA_TOKEN (read-only) to pipeline variables
  2. Add the CodeCharta generation stage to azure-pipelines.yml
  3. Add CORS location block to deployment/docs/nginx.conf
  4. Add COPY line to deployment/docs/Dockerfile for the .cc.json
  5. Test end-to-end: pipeline generates map → docs image includes it → codecharta.com loads it

Phase 3: Operationalize (Week 3+)

  • Share bookmarked URLs for different views (complexity, churn, coverage)
  • Add delta maps for sprint comparison
  • Integrate link into the docs site sidebar
  • Consider historical map archiving for trend analysis

Implementation Checklist

uml diagram


17. Implementation Roadmap

uml diagram


18. References

Resource URL
CodeCharta Introduction https://codecharta.com/docs/overview/introduction
CodeCharta Getting Started https://codecharta.com/docs/overview/getting-started
Sonar Importer Docs https://codecharta.com/docs/importer/sonar
Git Log Parser Docs https://codecharta.com/docs/parser/git-log
Merge Filter Docs https://codecharta.com/docs/filter/merge-filter
Docker Containers https://codecharta.com/docs/overview/dockerized
Load Maps from URL https://codecharta.com/docs/how-to/load-map-using-url
SonarCloud + Git How-To https://codecharta.com/docs/how-to/analyze-with-sonar-git-and-svn
Docker Hub — Analysis https://hub.docker.com/r/codecharta/codecharta-analysis
Docker Hub — Visualization https://hub.docker.com/r/codecharta/codecharta-visualization
Automated Sonar Analysis https://codecharta.com/docs/how-to/automated-sonar-analysis
Existing SonarCloud Research sonarqube-code-quality-research.md