or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

carto.mdcore-engine.mdeffects.mdextensions.mdindex.mdjson-config.mdlayers.mdmap-integration.mdreact.mdviews.mdwidgets.md
tile.json

json-config.mddocs/

JSON Configuration

Declarative JSON-based layer and visualization configuration system enabling dynamic deck.gl applications that can be configured without code changes.

Capabilities

JSONConverter

Main class for converting JSON configurations into deck.gl objects.

/**
 * Converts JSON configurations to deck.gl objects
 * Enables declarative, data-driven visualization setup
 */
class JSONConverter {
  constructor(configuration?: JSONConfiguration);
  /** Convert JSON object to deck.gl objects */
  convert(json: any, options?: ConvertOptions): any;
  /** Update converter configuration */
  setConfiguration(configuration: JSONConfiguration): void;
  /** Get current configuration */
  getConfiguration(): JSONConfiguration;
}

interface ConvertOptions {
  /** Relative path for resolving resources */
  relativePath?: string;
  /** Custom context for expression evaluation */
  context?: any;
  /** Enable strict mode */
  strict?: boolean;
}

Basic Usage:

import { JSONConverter } from '@deck.gl/json';

const jsonConverter = new JSONConverter();

const deckConfig = {
  "layers": [
    {
      "@@type": "ScatterplotLayer",
      "id": "scatter",
      "data": "https://example.com/data.json",
      "getPosition": "@@=properties.coordinates",
      "getRadius": 100,
      "getFillColor": [255, 0, 0]
    }
  ],
  "initialViewState": {
    "longitude": -122.4,
    "latitude": 37.8,
    "zoom": 10
  }
};

const deckProps = jsonConverter.convert(deckConfig);
// Use deckProps with Deck constructor

JSONConfiguration

Configuration object defining how JSON should be converted to deck.gl objects.

/**
 * Configuration for JSON conversion
 * Defines classes, functions, and enums available in JSON
 */
class JSONConfiguration {
  constructor(options?: JSONConfigurationOptions);
  /** Merge with another configuration */
  merge(configuration: JSONConfiguration): JSONConfiguration;
  /** Get available classes */
  getClasses(): {[key: string]: any};
  /** Get available functions */
  getFunctions(): {[key: string]: Function};
  /** Get available enums */
  getEnums(): {[key: string]: any};
}

interface JSONConfigurationOptions {
  /** Available classes for @@type */
  classes?: {[key: string]: any};
  /** Available functions for @@= expressions */
  functions?: {[key: string]: Function};
  /** Available enums */
  enums?: {[key: string]: any};
  /** Constants */
  constants?: {[key: string]: any};
}

Transport

Base class for loading remote data and resources.

/**
 * Base transport class for loading resources
 * Handles data fetching for JSON configurations
 */
abstract class Transport {
  constructor(options?: TransportOptions);
  /** Load resource by URL */
  abstract load(url: string, options?: LoadOptions): Promise<any>;
  /** Check if URL is supported */
  abstract supports(url: string): boolean;
}

interface TransportOptions {
  /** Request timeout in milliseconds */
  timeout?: number;
  /** Custom headers */
  headers?: {[key: string]: string};
  /** Credentials mode */
  credentials?: 'same-origin' | 'include' | 'omit';
}

interface LoadOptions {
  /** Response type */
  responseType?: 'json' | 'text' | 'arrayBuffer';
  /** Transform response */
  transform?: (data: any) => any;
}

JSON Configuration Format

Layer Configuration

Define layers using JSON with special syntax:

{
  "layers": [
    {
      "@@type": "ScatterplotLayer",
      "id": "points",
      "data": "https://api.example.com/points.json",
      "getPosition": "@@=coordinates",
      "getRadius": "@@=Math.sqrt(population) * 10",
      "getFillColor": {
        "@@function": "colorScale",
        "@@arguments": ["@@=properties.category"]
      },
      "pickable": true
    },
    {
      "@@type": "GeoJsonLayer", 
      "id": "polygons",
      "data": {
        "@@type": "FeatureCollection",
        "features": "@@=polygonFeatures"
      },
      "filled": true,
      "getFillColor": [128, 200, 255, 100]
    }
  ]
}

Expression Syntax

JSON configurations support expression evaluation:

{
  "getRadius": "@@=Math.max(10, properties.size * 2)",
  "getFillColor": "@@=properties.value > 100 ? [255, 0, 0] : [0, 255, 0]",
  "data": "@@=context.dataUrl + '?filter=' + encodeURIComponent(filters.category)"
}

Function Calls

Call predefined functions with arguments:

{
  "getFillColor": {
    "@@function": "interpolateColor",
    "@@arguments": [
      "@@=properties.value",
      {"domain": [0, 100], "range": [[255, 0, 0], [0, 255, 0]]}
    ]
  }
}

Conditional Logic

Use conditional expressions for dynamic behavior:

{
  "visible": "@@=zoom > 8",
  "getRadius": "@@=zoom < 10 ? 5 : 10",
  "layers": {
    "@@if": "showHeatmap",
    "@@then": [
      {"@@type": "HeatmapLayer", "id": "heat", "data": "@@=heatmapData"}
    ],
    "@@else": [
      {"@@type": "ScatterplotLayer", "id": "scatter", "data": "@@=scatterData"}
    ]
  }
}

Advanced Usage

Custom Configuration

Create custom configurations with your own classes and functions:

import { JSONConverter, JSONConfiguration } from '@deck.gl/json';
import { ScatterplotLayer, HeatmapLayer } from 'deck.gl';

const customConfig = new JSONConfiguration({
  classes: {
    ScatterplotLayer,
    HeatmapLayer,
    CustomLayer: MyCustomLayer
  },
  
  functions: {
    // Custom color scaling function
    colorScale: (value, domain, range) => {
      const normalized = (value - domain[0]) / (domain[1] - domain[0]);
      return range.map((color, i) => 
        color.map((channel, j) => 
          range[0][j] + normalized * (range[1][j] - range[0][j])
        )
      )[0];
    },
    
    // Custom data filtering
    filterData: (data, predicate) => {
      return data.filter(predicate);
    }
  },
  
  enums: {
    COORDINATE_SYSTEM: {
      LNGLAT: 1,
      CARTESIAN: 0
    }
  }
});

const converter = new JSONConverter(customConfig);

Dynamic Data Loading

Load and transform data dynamically:

const deckConfig = {
  "layers": [
    {
      "@@type": "ScatterplotLayer",
      "id": "dynamic-points",
      "data": {
        "@@type": "RemoteData",
        "url": "https://api.example.com/points",
        "transform": "@@=response.features.map(f => ({...f.properties, coordinates: f.geometry.coordinates}))"
      },
      "getPosition": "@@=coordinates",
      "getRadius": 50
    }
  ]
};

Template System

Use templates for reusable configurations:

{
  "templates": {
    "defaultScatter": {
      "@@type": "ScatterplotLayer",
      "radiusMinPixels": 3,
      "radiusMaxPixels": 30,
      "pickable": true
    }
  },
  
  "layers": [
    {
      "@@template": "defaultScatter",
      "id": "cities",
      "data": "cities.json",
      "getPosition": "@@=coordinates",
      "getRadius": "@@=population / 1000"
    },
    {
      "@@template": "defaultScatter", 
      "id": "airports",
      "data": "airports.json",
      "getPosition": "@@=location",
      "getFillColor": [255, 165, 0]
    }
  ]
}

Real-time Updates

Update configurations dynamically:

import { JSONConverter } from '@deck.gl/json';

class DynamicVisualization {
  private converter: JSONConverter;
  private deck: Deck;
  
  constructor() {
    this.converter = new JSONConverter();
    this.deck = new Deck({
      container: 'map',
      controller: true
    });
  }
  
  updateConfig(newConfig: any) {
    const deckProps = this.converter.convert(newConfig, {
      context: {
        timestamp: Date.now(),
        userPreferences: this.getUserPreferences()
      }
    });
    
    this.deck.setProps(deckProps);
  }
  
  private getUserPreferences() {
    return {
      colorScheme: 'dark',
      showLabels: true,
      animationSpeed: 1.0
    };
  }
}

Utility Functions

Helper functions for JSON configuration:

/**
 * Convert JavaScript functions to JSON expressions
 */
function _convertFunctions(obj: any): any;

/**
 * Parse expression strings into executable functions
 */
function _parseExpressionString(expression: string): Function;

/**
 * Shallow comparison of objects for optimization
 */
function _shallowEqualObjects(obj1: any, obj2: any): boolean;

Error Handling

Handle JSON configuration errors:

import { JSONConverter } from '@deck.gl/json';

const converter = new JSONConverter();

try {
  const deckProps = converter.convert(jsonConfig, {
    strict: true // Enable strict validation
  });
} catch (error) {
  if (error.message.includes('Unknown class')) {
    console.error('Layer type not found:', error.message);
  } else if (error.message.includes('Expression error')) {
    console.error('Invalid expression:', error.message);
  } else {
    console.error('Configuration error:', error.message);
  }
}

Performance Considerations

Optimization Strategies

  1. Pre-compile expressions for frequently used configs
  2. Cache converted objects to avoid re-conversion
  3. Lazy load data using async data sources
  4. Minimize expression complexity for better performance
// Cache converted configurations
const configCache = new Map();

function getCachedDeckProps(jsonConfig: any) {
  const configHash = JSON.stringify(jsonConfig);
  
  if (!configCache.has(configHash)) {
    const deckProps = converter.convert(jsonConfig);
    configCache.set(configHash, deckProps);
  }
  
  return configCache.get(configHash);
}