!!!###!!!title=character——VisActor/VStory tutorial documents!!!###!!!!!!###!!!description=Please read the definition of [DSL](./DSL) first, and then read the content of this section.Character is the most basic element in VStory, it can be a chart, component, table, etc. It can be a simple text or a very complex chart. Character can be configured through DSL or added dynamically through API. Characters need to be predefined, if you need to use a specific Character in your work, you need to define this Character in the `characters` array in DSL.!!!###!!!

Character

Please read the definition of DSL first, and then read the content of this section.

Character is the most basic element in VStory, it can be a chart, component, table, etc. It can be a simple text or a very complex chart. Character can be configured through DSL or added dynamically through API. Characters need to be predefined, if you need to use a specific Character in your work, you need to define this Character in the characters array in DSL.

Definition of Character

All characters can be defined by some common configurations and some special configurations. Common configurations include:

  • id: The id of the character, used to uniquely identify this character, which will be used in defining specific behaviors (actions) later
  • type: The type of the character, the types of characters supported by VStory include but are not limited to: VChart, Text, Image, etc.
  • position: The position and size of the character, as well as rotation anchor information
  • zIndex: The layer of the character, default is 0, characters with higher layers will overlay characters with lower layers

All special configurations are in the options, for example:

const textConfig = {
  type: 'Text', // Indicates it is a text type
  id: 'title1',
  zIndex: 1,
  position: {
    top: 100,
    left: 200
  },
  // Define the text configuration here
  options: {
    graphic: {
      text: 'A BRIEF HISTORY',
      fontSize: 12,
      fill: 'red'
    }
  }
};

const imageConfig = {
  type: 'Image', // Indicates it is an image type
  id: 'image1',
  zIndex: 1,
  position: {
    top: 100,
    left: 200
  },
  // Define the image configuration here
  options: {
    graphic: {
      image: 'url'
    }
  }
};

Regarding the accurate interface definition, it is as follows:

type ICharacterConfig = IChartCharacterConfig | IComponentCharacterConfig;

// Definition of position, describing the position, size, and rotation anchor of the element
type IWidgetData = {
  left?: number;
  top?: number;
  x?: number;
  y?: number;
  angle?: number;
  anchor?: [number, number];
} & (
  | {
      bottom?: number;
      right?: number;
    }
  | {
      width?: number;
      height?: number;
    }
);

interface ICharacterConfigBase {
  id: string;
  type: string; // Type
  position: IWidgetData; // Position description
  zIndex: number;
  extra?: any; // Extra information carried
  options: any; // Special configuration, each different Character can pass its own special configuration here
}

Built-in Character Types

VChart

VChart is the most commonly used Character type in VStory, it can be various types of charts, such as line charts, bar charts, pie charts, etc. VChart can be defined by directly passing in the Spec of VChart, for how to define the specific spec, please refer to the vchart site. The interface definition of VChart is as follows:

interface IChartCharacterConfig extends ICharacterConfigBase {
  options: {
    // Chart spec
    spec?: any;
    // Initialization parameters
    initOption?: IInitOption;
    // Padding
    padding?: { left: number; top: number; right: number; bottom: number };
    // Chart container
    panel?: any;
    // Data source
    data?: any;
    // Title
    title?: {
      [key in ModelSelector]: Partial<ElementType<ISpec['title']>>;
    };
    // Legends
    legends?: {
      [key in ModelSelector]: Partial<ElementType<ISpec['legends']>>;
    };
    // Axes
    axes?: {
      [key in ModelSelector]: Partial<ElementType<ISpec['axes']>>;
    };
    // Color palette
    color?: any;
    // Mark single element style
    markStyle?: {
      [key: string]: IMarkStyle;
    };
    // Label single element style, different from mark, completely different runtime logic
    labelStyle?: {
      [key: string]: IMarkStyle;
    };
    // Data group style configuration
    dataGroupStyle?: {
      [StroyAllDataGroup]: IDataGroupStyle; // Styles for all groups
      [key: string]: IDataGroupStyle; // Styles for a specific group
    };
    // Directly merged configuration, using VChart's spec
    rootConfig?: Record<string, any>;
  };
}

Let's look at an example of VChart:

VTable

VTable is a Character type table in VStory, which can be various types of tables. VTable can be defined by directly passing in the Spec of VTable. For specific definitions of the spec, please refer to the vtable site. The interface definition of VTable is as follows:

interface ITableCharacterConfigOptionsType {
  // 表格spec
  spec?: any;
  records: any;
  columns: any;
  widthMode?: 'standard' | 'adaptive' | 'autoWidth';
  defaultRowHeight: number;
  showHeader?: boolean;
  theme: any;
  // 数据源
  data?: any;

  panel?: any;
  padding?: number | [number, number] | [number, number, number, number];

  // 单个单元格样式,框选也会应用到这里
  // 使用 map 不用数组的原因。减少写入是的反复遍历
  cellStyle?: {
    // col_row
    [key: string]: {
      col: number;
      row: number;
      style?: any;
    };
  };

  // 列宽
  colWidth?: {
    [key: number]: number;
  };
  // 行高
  rowHeight?: {
    [key: number]: number;
  };
  // 列样式(包括列头)
  colStyle?: {
    [key: number]: any;
  };
  // 行样式(包括行头)
  rowStyle?: {
    [key: number]: any;
  };
  // 列隐藏
  colVisible?: {
    [key: number]: boolean;
  };
  // 行隐藏
  rowVisible?: {
    [key: number]: boolean;
  };
  // 内容列样式
  contentColStyle?: {
    [key: number]: any;
  };
  // 内容行样式
  contentRowStyle?: {
    [key: number]: any;
  };
}

export interface ITableCharacterConfig extends ICharacterConfigBase {
  options: ITableCharacterConfigOptionsType;
}

Let's look at an example of VTable:

Basic Components (Image, Line, Rect, Shape, Text, Arc, Polygon)

The interface definition of component types is as follows, where basic components (Image, Line, Rect, Shape, Text, Arc, Polygon) are configured directly based on the corresponding elements of VRender, configured in the graphic property:

The panel is an additional panel of the component, actually a Rect element of VRender, you can refer to the configuration of Rect element of VRender. The text configuration is an additional configuration that each component has, it is a Text element of VRender, you can refer to the configuration of Text element of VRender. Padding represents the padding between the panel and the content, representing the top, right, bottom, and left padding.

interface IComponentCharacterConfig extends ICharacterConfigBase {
  options: {
    // Configuration of the main element
    graphic: any;
    // Panel configuration
    panel?: any;
    // Text configuration
    text?: any;
    // Padding
    padding?: { left: number; top: number; right: number; bottom: number };
  };
}

An example of usage is as follows:

Timeline Component

The Timeline component is a timeline component that displays a complete sequence of time, as well as the flow of time. Its interface definition is as follows:

interface TimelineAttrs extends IGroupGraphicAttribute {
  width: number; // Width
  // height?: number;
  times: { label: string; desc?: string }[]; // Specific time sequence
  labelSpace?: number; // Spacing between labels
  symbolStyle?: Partial<ISymbolGraphicAttribute>; // Style of time points
  activeSymbolStyle?: Partial<ISymbolGraphicAttribute>; // Style of active time points
  lineStyle?: Partial<ILineGraphicAttribute>; // Style of timeline
  activeLineStyle?: Partial<ILineGraphicAttribute>; // Style of active timeline
  labelStyle?: Partial<ITextGraphicAttribute>; // Style of labels
  activeLabelStyle?: Partial<ITextGraphicAttribute>; // Style of active labels
  pointLayoutMode?: 'space-around' | 'space-between'; // Layout mode
  // Current progress
  clipRange?: number;
  animation?: boolean; // Whether to enable animation
}

interface ITimelineComponentAttributes extends IGroupGraphicAttribute {
  // Text configuration combined with rich text textConfig
  textStyle?: Partial<ITextGraphicAttribute & { textConfig: IRichTextAttribute['textConfig'] }>;
  graphic?: TimelineAttrs;
  /**
   * Inner padding
   */
  padding?: {
    top?: number;
    bottom?: number;
    left?: number;
    right?: number;
  };
}

Usage example:

Unit Component

The unit visualization component is a narrative way of transforming data into visual elements, allowing complex information to be intuitively displayed. By individualizing each data point, the audience can gain a deeper understanding of the real stories behind each data point. This method vividly depicts the process of data change through animation and time progression, while conveying multidimensional information through visual elements such as color and shape, enhancing emotional resonance. It not only enhances the readability of data but also makes it easy to share on social media, helping to increase public awareness of important social issues.

The interface definition of the Unit component is as follows:

interface IUnitGraphicAttributes extends IGroupAttribute {
  /**
   * The width of the container.
   * Defaults to the width defined by the position of the character.
   */
  width: number;

  /**
   * The height of the container.
   * Defaults to the height defined by the position of the character.
   */
  height: number;

  /**
   * The padding inside the container, specifying space between the container border and its content.
   * @default { top: 50, bottom: 50, right: 50, left: 50 }
   */
  padding?: {
    top?: number;
    bottom?: number;
    right?: number;
    left?: number;
  };

  /**
   * The total number of units to be rendered within the container.
   * @default 250
   */
  count?: number;

  /**
   * Number of units represented by each symbol
   * @default 1
   */
  countPerSymbol?: number;

  /**
   * The gap between units, represented as a percentage of the unit's width and height.
   * The first value specifies the horizontal gap, and the second value specifies the vertical gap.
   * @default [0.5, 0.5]
   */
  gap?: [number, number];

  // Defines what style is from what range to what range
  units: {
    style: ISymbolGraphicAttribute;
    range: [number, number];
  }[];

  /**
   * The aspect ratio of the units, defined as width divided by height.
   * @default 1
   */
  aspect?: number;

  /**
   * The direction in which units are laid out within the container.
   * @default 'horizontal'
   */
  direction?: 'horizontal' | 'vertical';

  duration?: number;
}

Usage example: