or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

animations.mdchart-runtime.mdcomponents.mdcompositions.mdcoordinates.mddata-transforms.mdencoding-scales.mdextensions.mdindex.mdinteractions.mdmarks.mdthemes.md
tile.json

interactions.mddocs/

Interactions and Events

Interactive behavior system providing hover effects, selection, brushing, and custom interaction patterns.

Capabilities

Element Interactions

Interactions that target individual chart elements.

/**
 * Highlights elements on hover
 * @param options - Highlight interaction options
 */
interaction(type: "elementHighlight", options?: ElementHighlightOptions): Chart;

/**
 * Highlights elements by X value
 */
interaction(type: "elementHighlightByX", options?: ElementHighlightByXOptions): Chart;

/**
 * Highlights elements by color encoding
 */
interaction(type: "elementHighlightByColor", options?: ElementHighlightByColorOptions): Chart;

/**
 * Selects elements on click
 */
interaction(type: "elementSelect", options?: ElementSelectOptions): Chart;

/**
 * Selects elements by X value
 */
interaction(type: "elementSelectByX", options?: ElementSelectByXOptions): Chart;

/**
 * Selects elements by color encoding
 */
interaction(type: "elementSelectByColor", options?: ElementSelectByColorOptions): Chart;

interface ElementHighlightOptions {
  /** Grouping field for related elements */
  by?: string;
  /** Link highlighting across multiple charts */
  link?: boolean;
  /** Highlight style */
  style?: {
    fill?: string;
    stroke?: string;
    strokeWidth?: number;
    opacity?: number;
  };
  /** Unhighlighted element style */
  unselectedStyle?: {
    opacity?: number;
    fill?: string;
  };
}

interface ElementSelectOptions extends ElementHighlightOptions {
  /** Allow multiple selection */
  multiple?: boolean;
  /** Selection behavior */
  toggle?: boolean;
  /** Callback for selection changes */
  onSelect?: (selected: any[]) => void;
}

Usage Examples:

// Basic element highlighting
chart
  .point()
  .data(scatterData)
  .encode("x", "height")
  .encode("y", "weight")
  .encode("color", "gender")
  .interaction("elementHighlight", {
    style: {
      strokeWidth: 3,
      stroke: "black"
    },
    unselectedStyle: {
      opacity: 0.3
    }
  });

// Selection by category
chart
  .interval()
  .data(salesData)
  .encode("x", "category")
  .encode("y", "sales")
  .interaction("elementSelectByX", {
    multiple: true,
    onSelect: (selected) => {
      console.log("Selected categories:", selected);
    }
  });

// Linked highlighting across series
chart
  .line()
  .data(multiSeriesData)
  .encode("x", "date")
  .encode("y", "value")
  .encode("color", "series")
  .interaction("elementHighlightByColor", {
    link: true,
    by: "series"
  });

Chart-Level Interactions

Interactions that affect the entire chart or visualization area.

/**
 * Adds tooltip functionality
 * @param options - Tooltip configuration
 */
interaction(type: "tooltip", options?: TooltipOptions): Chart;

/**
 * Adds fisheye lens distortion on hover
 * @param options - Fisheye interaction options
 */
interaction(type: "fisheye", options?: FisheyeOptions): Chart;

/**
 * Adds chart indexing for temporal data
 * @param options - Chart index options
 */
interaction(type: "chartIndex", options?: ChartIndexOptions): Chart;

interface TooltipOptions {
  /** Tooltip title */
  title?: string | ((data: any) => string);
  /** Tooltip items to display */
  items?: string[] | ((data: any) => string[]);
  /** Tooltip position */
  position?: "auto" | "top" | "bottom" | "left" | "right";
  /** Share tooltip across multiple elements */
  shared?: boolean;
  /** Custom tooltip renderer */
  render?: (data: any) => HTMLElement | string;
  /** Tooltip style */
  style?: {
    backgroundColor?: string;
    border?: string;
    borderRadius?: number;
    padding?: number;
    fontSize?: number;
    color?: string;
  };
}

interface FisheyeOptions {
  /** Distortion strength */
  strength?: number;
  /** Focus radius */
  radius?: number;
  /** Animation duration */
  duration?: number;
}

Usage Examples:

// Custom tooltip
chart
  .point()
  .data(bubbleData)
  .encode("x", "gdp")
  .encode("y", "lifeExpectancy")
  .encode("size", "population")
  .encode("color", "continent")
  .interaction("tooltip", {
    title: (d) => d.country,
    items: ["gdp", "lifeExpectancy", "population"],
    position: "auto",
    style: {
      backgroundColor: "rgba(0,0,0,0.8)",
      color: "white",
      borderRadius: 4,
      padding: 8
    }
  });

// Fisheye interaction for large datasets
chart
  .point()
  .data(largeDataset)
  .encode("x", "x")
  .encode("y", "y")
  .interaction("fisheye", {
    strength: 2.5,
    radius: 100
  });

// Chart index for time series
chart
  .line()
  .data(timeSeriesData)
  .encode("x", "date")
  .encode("y", "value")
  .interaction("chartIndex", {
    showCrosshair: true,
    snapToData: true
  });

Brush Interactions

Brush interactions for selecting regions of data.

/**
 * Highlights data within brushed area
 */
interaction(type: "brushHighlight", options?: BrushHighlightOptions): Chart;

/**
 * Highlights data within horizontal brush
 */
interaction(type: "brushXHighlight", options?: BrushXHighlightOptions): Chart;

/**
 * Highlights data within vertical brush
 */
interaction(type: "brushYHighlight", options?: BrushYHighlightOptions): Chart;

/**
 * Filters data within brushed area
 */
interaction(type: "brushFilter", options?: BrushFilterOptions): Chart;

/**
 * Filters data within horizontal brush
 */
interaction(type: "brushXFilter", options?: BrushXFilterOptions): Chart;

/**
 * Filters data within vertical brush
 */
interaction(type: "brushYFilter", options?: BrushYFilterOptions): Chart;

interface BrushHighlightOptions {
  /** Brush area style */
  maskStyle?: {
    fill?: string;
    opacity?: number;
    stroke?: string;
    strokeWidth?: number;
  };
  /** Highlighted element style */
  highlightStyle?: StyleOptions;
  /** Unhighlighted element style */
  unselectedStyle?: StyleOptions;
  /** Callback for brush events */
  onBrush?: (selection: any) => void;
}

interface BrushFilterOptions {
  /** Filter behavior */
  persistent?: boolean;
  /** Animation duration for filter transitions */
  duration?: number;
  /** Callback for filter changes */
  onFilter?: (filtered: any[]) => void;
}

Usage Examples:

// 2D brush selection
chart
  .point()
  .data(scatterData)
  .encode("x", "height")
  .encode("y", "weight")
  .interaction("brushHighlight", {
    maskStyle: {
      fill: "rgba(0,0,255,0.1)",
      stroke: "blue",
      strokeWidth: 2
    },
    onBrush: (selection) => {
      console.log("Brushed data:", selection);
    }
  });

// Horizontal brush for time series
chart
  .line()
  .data(timeSeriesData)
  .encode("x", "date")
  .encode("y", "value")
  .interaction("brushXFilter", {
    persistent: true,
    onFilter: (filtered) => {
      updateLinkedCharts(filtered);
    }
  });

// Vertical brush for value filtering
chart
  .interval()
  .data(histogramData)
  .encode("x", "bin")
  .encode("y", "count")
  .interaction("brushYHighlight", {
    highlightStyle: {
      fill: "orange",
      opacity: 0.8
    }
  });

Component Interactions

Interactions that work with chart components like legends and axes.

/**
 * Filters data based on legend selection
 */
interaction(type: "legendFilter", options?: LegendFilterOptions): Chart;

/**
 * Highlights data based on legend hover
 */
interaction(type: "legendHighlight", options?: LegendHighlightOptions): Chart;

/**
 * Filters data based on slider position
 */
interaction(type: "sliderFilter", options?: SliderFilterOptions): Chart;

/**
 * Filters data based on scrollbar position
 */
interaction(type: "scrollbarFilter", options?: ScrollbarFilterOptions): Chart;

interface LegendFilterOptions {
  /** Allow multiple selection */
  multiple?: boolean;
  /** Default selected items */
  defaultSelected?: string[];
  /** Animation duration */
  duration?: number;
  /** Callback for filter changes */
  onFilter?: (selected: string[]) => void;
}

interface LegendHighlightOptions {
  /** Highlight style for matching elements */
  highlightStyle?: StyleOptions;
  /** Style for non-matching elements */
  unselectedStyle?: StyleOptions;
}

Usage Examples:

// Interactive legend filtering
chart
  .point()
  .data(categoricalData)
  .encode("x", "value1")
  .encode("y", "value2")
  .encode("color", "category")
  .component("legendCategory")
  .interaction("legendFilter", {
    multiple: true,
    defaultSelected: ["A", "B"],
    onFilter: (selected) => {
      console.log("Active categories:", selected);
    }
  });

// Legend highlighting
chart
  .line()
  .data(multiSeriesData)
  .encode("x", "x")
  .encode("y", "y")
  .encode("color", "series")
  .component("legendCategory")
  .interaction("legendHighlight", {
    highlightStyle: {
      strokeWidth: 3,
      opacity: 1
    },
    unselectedStyle: {
      opacity: 0.2
    }
  });

Specialized Interactions

Domain-specific interactions for specialized visualizations.

/**
 * Provides drill-down functionality for treemaps
 */
interaction(type: "treemapDrillDown", options?: TreemapDrillDownOptions): Chart;

/**
 * Enables point movement for interactive scatter plots
 */
interaction(type: "elementPointMove", options?: ElementPointMoveOptions): Chart;

/**
 * Shows contextual popups on hover
 */
interaction(type: "poptip", options?: PoptipOptions): Chart;

interface TreemapDrillDownOptions {
  /** Maximum drill depth */
  maxDepth?: number;
  /** Animation duration */
  duration?: number;
  /** Breadcrumb navigation */
  showBreadcrumb?: boolean;
  /** Callback for navigation events */
  onNavigate?: (path: string[]) => void;
}

interface ElementPointMoveOptions {
  /** Constrain movement to chart area */
  constrain?: boolean;
  /** Update data on move */
  updateData?: boolean;
  /** Callback for position changes */
  onMove?: (data: any, position: [number, number]) => void;
}

Usage Examples:

// Treemap drill-down
chart
  .treemap()
  .data(hierarchicalData)
  .encode("value", "size")
  .encode("color", "category")
  .interaction("treemapDrillDown", {
    maxDepth: 3,
    showBreadcrumb: true,
    onNavigate: (path) => {
      console.log("Navigation path:", path.join(" > "));
    }
  });

// Draggable scatter plot points
chart
  .point()
  .data(editableData)
  .encode("x", "x")
  .encode("y", "y")
  .interaction("elementPointMove", {
    updateData: true,
    onMove: (data, position) => {
      // Update data with new position
      data.x = position[0];
      data.y = position[1];
      console.log("Point moved:", data);
    }
  });

Custom Events

Custom event system for advanced interaction patterns.

/**
 * Chart event handling
 */
interface ChartEvents {
  /** Element click */
  "element:click": (event: ElementEvent) => void;
  /** Element hover */
  "element:hover": (event: ElementEvent) => void;
  /** Chart click */
  "plot:click": (event: PlotEvent) => void;
  /** Brush start */
  "brush:start": (event: BrushEvent) => void;
  /** Brush end */
  "brush:end": (event: BrushEvent) => void;
  /** Legend click */
  "legend:click": (event: LegendEvent) => void;
}

interface ElementEvent {
  type: string;
  data: any;
  element: any;
  x: number;
  y: number;
}

interface PlotEvent {
  type: string;
  x: number;
  y: number;
  data: any;
}

Custom Event Examples:

// Custom event handling
chart
  .point()
  .data(data)
  .encode("x", "x")
  .encode("y", "y")
  .on("element:click", (event) => {
    console.log("Element clicked:", event.data);
    // Custom click behavior
    showDetailModal(event.data);
  })
  .on("plot:click", (event) => {
    console.log("Chart clicked at:", event.x, event.y);
    // Add new point at click location
    addNewDataPoint(event.x, event.y);
  });

// Brush event handling
chart
  .point()
  .data(data)
  .encode("x", "x")
  .encode("y", "y")
  .interaction("brushHighlight")
  .on("brush:end", (event) => {
    const selectedData = getDataInBrush(event.selection);
    updateLinkedVisualization(selectedData);
  });

Interaction State Management

Managing interaction state across multiple charts and components.

interface InteractionState {
  /** Currently selected elements */
  selected: any[];
  /** Currently highlighted elements */
  highlighted: any[];
  /** Active brush selection */
  brushSelection?: {
    x: [number, number];
    y: [number, number];
  };
  /** Legend filter state */
  legendFilters: { [key: string]: boolean };
}

// State management methods
getInteractionState(): InteractionState;
setInteractionState(state: Partial<InteractionState>): Chart;
clearInteractionState(): Chart;

State Management Examples:

// Synchronize state across multiple charts
const chart1 = new Chart({ container: "chart1" })
  .point()
  .data(data)
  .interaction("elementSelect");

const chart2 = new Chart({ container: "chart2" })
  .interval()
  .data(aggregatedData)
  .interaction("elementHighlight");

// Sync selection between charts
chart1.on("element:click", (event) => {
  const selectedIds = chart1.getInteractionState().selected.map(d => d.id);
  
  chart2.setInteractionState({
    highlighted: aggregatedData.filter(d => selectedIds.includes(d.id))
  });
});