Envisioning LogoEnvisioning App (6.4.0)
Configuration

Visualization

Configure the Radar and other data visualizations

Overview

Visualizations are interactive data displays configured in the settings.visualization array. Currently, the Radar visualization is the primary supported type.

import type { Config, Visualizations } from "@envisioning/app";

const Radar: Visualizations["radar"] = {
  type: "radar",
  label: { en: "Radar" },
  entityPageId: "technology",
  distance: [{ joinKey: "trl" }],
  group: [{ joinKey: "collection" }],
};

const settings: Config["settings"] = {
  visualization: [Radar],
  // ...
};

Radar Visualization

The Radar displays entities as dots arranged in a circular layout with configurable dimensions.

Core Properties

PropertyTypeRequiredDescription
type"radar"YesVisualization type
labelI18nYesDisplay label
entityPageIdstringYesTarget page for entity clicks
distancearrayYesRadial position metric(s)
grouparrayNoSlice grouping metric(s)
bubblearrayNoBubble size metric(s)
bararrayNoBar chart metric(s)
connectionsarrayNoConnection line metric(s)
sortarrayNoSort options for entities
settingsobjectNoVisual appearance settings
preferencesobjectNoUser preference toggles

Metric Dimensions

Each dimension (distance, group, bubble, bar, connections) accepts an array of metric configurations:

{
  distance: [
    {
      label: { en: "TRL" },
      joinKey: "trl",
      scale: { type: "linear" },
      ticksStep: 1,
    },
  ],
}

Dimension Properties

PropertyTypeDescription
labelI18nOptional override label
joinKeystringSchema join key for the metric
scaleobjectD3 scale configuration
ticksStepnumberStep for tick rendering
isInwardsbooleanWhen true, higher values map toward the center; when false, toward the edge (default true)
tickMarginnumberSymmetric padding before min and after max as tickMargin * ticksStep (0–1, default 0.5). Direction respects the distance option's isInwards.
addClosingRingbooleanRender closing ring at scale boundary on closing side (default true). When false, renders a ring at the metric domain boundary instead (if not already a tick). Does not affect scale range.
offsetnumberLabel displacement along tick band as a multiple of band width (-1 = outer edge, 0 = on tick value, 1 = toward center; range -1–1). Default 0. Direction respects the distance option's isInwards.
showOptionbooleanShow in secondary menu (default: true)
forceDomain[number, number]Override metric domain
overrideSettingsobjectDistance only. Optional per-distance overrides for entity, range, and bubble rendering (see below)

overrideSettings (distance only)

Optional object on a distance option. When that distance scale is active, any set keys override the chart-level settings for entity rendering only. The object and each key inside it are optional; unset keys fall back to chart settings.

KeyTypeDescription
hitRadiusnumberDot and range hit area radius
dotRadiusnumberEntity dot radius
dotPaddingnumberPadding around dot for current/hover ring
rangeStrokeWidthnumberRange line stroke width (min 0)
rangeOpacitynumberRange line opacity (0–1)
forceRangeColorstring | falseRange line color (false = follow dot color; or token, hex, template)
maxBubbleRadiusnumberMaximum bubble radius
bubbleOpacitynumberBubble fill opacity
distance: [
  { label: { en: "TRL" }, joinKey: "trl", ticksStep: 1 },
  {
    label: { en: "Cost" },
    joinKey: "cost",
    ticksStep: 1,
    overrideSettings: {
      dotRadius: 2,
      rangeStrokeWidth: 10,
    },
  },
],

Scale Types

// Linear scale (default)
scale: { type: "linear" }

// Symmetric log scale (supports zero)
scale: { type: "symlog", constant: 1 }

// Power scale
scale: { type: "pow", exponent: 2 }

// Square root scale
scale: { type: "sqrt" }

Distance (Radial Position)

Controls where entities appear from center to edge:

distance: [
  {
    label: { en: "NDC Impact Fit" },
    joinKey: "ndcImpact",
    ticksStep: 1,
  },
  {
    label: { en: "TRL" },
    joinKey: "trl",
    ticksStep: 1,
  },
],

Group (Slices)

Divides the radar into pie-like slices:

group: [
  {
    label: { en: "Collection" },
    joinKey: "collection",
  },
  {
    label: { en: "TRL" },
    joinKey: "trl",
  },
  {
    label: { en: "None" },
    joinKey: "",  // Empty string = no grouping
  },
],

Bubble (Size)

Controls entity dot size:

bubble: [
  {
    label: { en: "Funding Opportunities" },
    joinKey: "fundingOpportunities",
  },
  {
    label: { en: "Cost" },
    joinKey: "cost",
  },
],

Bar (Bar Charts)

Adds bar chart display for metrics:

bar: [
  {
    label: { en: "TRL" },
    joinKey: "trl",
    ticksStep: 1,
  },
  {
    label: { en: "Cost" },
    joinKey: "cost",
  },
],

Sort Options

Define how entities can be sorted:

sort: [
  {
    label: { en: "Title" },
    ascCriteria: { title: 1 },
  },
  {
    label: { en: "TRL" },
    ascCriteria: { "trl.value": 1 },
    descCriteria: null,  // null = hide asc/desc toggle
  },
],

Preferences

Configure user-toggleable features:

preferences: {
  magneticTitles: {
    default: true,
    showOption: true,
    label: { en: "Magnetic Titles" },
  },
  showTail: {
    default: true,
  },
  showNumber: {
    default: true,
  },
  showBubble: {
    default: true,
  },
  showBar: {
    default: true,
  },
  showOrigin: {
    default: true,
  },
  showConnections: {
    default: true,
    showOption: false,  // Hide from preferences menu
  },
},
PreferenceDescription
magneticTitlesLabels follow cursor
showTailShow connecting lines to dots
showNumberShow entity numbers
showBubbleShow bubble size
showBarShow bar charts
showOriginShow origin point
showConnectionsShow connection lines

Visual Settings

Fine-tune radar appearance:

settings: {
  // Layout
  innerRadius: 150,
  outerRadius: 400,
  outerPadding: 50,
  sliceGap: 0.02,

  // Badge (center logo)
  badgeSize: 180, 

  // Dots
  dotRadius: 6,
  hitRadius: 10,

  // Labels
  titleSize: 16,
  titlePadding: 10,
  hoverPadding: 5,

  // Ticks
  tickLabelSize: 12,
  tickLabelWeight: 400,
  tickStrokeWidth: 1,

  // Numbers
  numberPadding: 5,
  numberWeight: 500,

  // Bubbles
  maxBubbleRadius: 30,
  bubbleOpacity: 0.5,

  // Bars
  barSize: 20,
  barPadding: 2,
  barStrokeWidth: 1,

  // Tails
  tailGap: 2,
  tailOpacity: 0.5,
  tailStrokeWidth: 2,
},

Complete Example

import type { Visualizations } from "@envisioning/app";

export const Radar: Visualizations["radar"] = {
  type: "radar",
  label: { en: "Radar" },
  entityPageId: "technology",

  sort: [
    { label: { en: "Title" }, ascCriteria: { title: 1 } },
    { label: { en: "TRL" }, ascCriteria: { "trl.value": 1 } },
    { label: { en: "Cost" }, ascCriteria: { "cost.value": 1 } },
  ],

  group: [
    { label: { en: "Collection" }, joinKey: "collection" },
    { label: { en: "TRL" }, joinKey: "trl" },
    { label: { en: "None" }, joinKey: "" },
  ],

  distance: [
    { label: { en: "NDC Impact" }, joinKey: "ndcImpact", ticksStep: 1 },
    { label: { en: "TRL" }, joinKey: "trl", ticksStep: 1 },
  ],

  bubble: [
    { label: { en: "Funding" }, joinKey: "fundingOpportunities" },
    { label: { en: "Cost" }, joinKey: "cost" },
  ],

  bar: [
    { label: { en: "TRL" }, joinKey: "trl", ticksStep: 1 },
    { label: { en: "Cost" }, joinKey: "cost" },
  ],

  preferences: {
    magneticTitles: { default: true },
    showTail: { default: true },
    showNumber: { default: true },
    showBubble: { default: true },
    showBar: { default: true },
    showOrigin: { default: true },
    showConnections: { default: true, showOption: false },
  },

  settings: {
    innerRadius: 150,
    outerRadius: 400,
    badgeSize: 180,
    titleSize: 16,
    dotRadius: 6,
    tailStrokeWidth: 2,
    maxBubbleRadius: 30,
    tickLabelSize: 12,
    outerPadding: 50, 
  },
};

Validation

The configuration validates that:

  1. entityPageId exists in the pages array
  2. All joinKey values exist in the schema joins

If validation fails:

Page "technology" not found in pages. Check visualization: radar
Join key "trl" not found in the schema. Check: radar - distance, joinKey: trl

On this page