SciChart.js JavaScript 2D Charts API > Subcharts API > What is the SubCharts API?
What is the SubCharts API?

The SubCharts API allows to place 1..N child SciChartSurfaces within a parent chart (Charts within charts). It is possible to have multiple sub-charts within the main SciChartSurface.

What is the Benefit of the SubCharts API?

SubCharts is an extremely powerful API that allows you to create dashboards or chart groups that share a single SciChartSurface, single WebGL canvas and engine instance.

  • With the SubCharts API you can create a single chart with several nested chart panels, enabling you to create components of single dashboards with one SciChartSurface parent that you can re-use throughout your app.
  • It's possible to dynamically position and resize SubCharts on the main SciChartSurface, so you could create dynamic multi-panel charts such as in the financial industry or industrial process monitoring industry.
  • SubCharts are a huge performance boost when many charts are used. For example, 100 charts created using SciChartSurface.create() will be far slower than 100 charts added to a single SciChartSurfaces using SubCharts.

It's possible with SubCharts to create very dashboards and re-usable multi-chart configurations, multi-chart groups while maintaining very high performance due to the WebGL canvas & context sharing nature of this API.

SubCharts API could be applied to display separate charts simultaneously on a single root element. The API allows to set a position, size , and styling of a sub-chart. Additionally it is possible to add custom HTML elements to the chart, which would be positioned accordingly to the chart layout flow.

Overview of the SubCharts API

A sub-chart is represented by the SciChartSubSurface class, which inherits SciChartSurface. Similarly to SciChartSurface it has its own Axes, Modifiers, Renderable Series and Annotations.

You can add a sub-chart to a SciChartSurface by calling sciChartSurface.addSubChart(options: I2DSubSurfaceOptions). This returns a SciChartSubSurface instance.

In v4 and above, this api has changed to SciChartSubSurface.createSubSurface.  See breaking changes in v4
addSubChart function
Copy Code
sciChartSurface.addSubChart(options?: I2DSubSurfaceOptions): SciChartSubSurface

I2DSubSurfaceOptions may be passed to addSubChart. This type has the following properties:

I2DSubSurfaceOptions type
Copy Code
export interface I2DSubSurfaceOptions extends I2DSurfaceOptions {
    /**
     * A rectangle defining the position and size of a subchart.
     * If {@link coordinateMode} is Relative (the default) then the values give the size as a proportion of the parent div, and all properties must be between 0 and 1 inclusive.
     * If {@link coordinateMode} is DataValue, values will be converted to coordinates using {@link parentXAxisId} and {@link parentYAxisId}. Subchart will be clpped to the parent SeriesViewRect
     * Can only be set if this is a subChart.  See {@link addSubChart}
     */
    position?: Rect;
    /** An id or div element that will wrap the subchart.  This can contain top, left, bottom and right section divs.  The chart will shrink to fit the sections  */
    subChartContainerId?: string | HTMLDivElement;
    /** Whether other surfaces, including the parent, will be visible underneath this surface  */
    isTransparent?: boolean;
    /** Sets if the subchart is visible, allowing you to hide a subchart without removing it from the parent surface */
    isVisible?: boolean;
    /**
     * Sets additional absolute padding between the SciChartSubSurface and its parent, in order top, right, bottom, left
     * {@link subPosition} is applied first, then this padding is added.
     */
    subChartPadding?: Thickness;
    /**
     * Gets or sets the {@link ECoordinateMode} used when calculating the actual position based on the {@link subPosition}
     * Default Relative
     */
    coordinateMode?: ECoordinateMode;
    /**
     * Sets the AxisId used to determing which X Axis should be used when calculating the actual position based on the {@link subPosition}
     * if {@link coordinateMode} is DataValue
     */
    parentXAxisId?: string;
    /**
     * Sets the AxisId used to determing which Y Axis should be used when calculating the actual position based on the {@link subPosition}
     * if {@link coordinateMode} is DataValue
     */
    parentYAxisId?: string;
    /**
     * Gets or sets scale property for all sections
     */
    sectionScale?: number;
}

The return value of addSubChart is a SciChartSubSurface class. This inherits SciChartSurface but has additional properties, which can be found below.

SciChartSubSurface type
Copy Code
/**
 * @summary The {@link SciChartSubSurface} is the surface created within another surface
 * @description
 * It can be added using {@link SciChartSurface.addSubChart} method.
 *
 * To update the positioning of the {@link SciChartSubSurface}, use {@link SciChartSubSurface.subPosition};
 * also you can call {@link SciChartSubSurface.updateSubLayout} to refresh the layout of the sub-surface.
 * @remarks
 * It is not possible to have more than one level of nested sub-surfaces.
 */
export class SciChartSubSurface extends SciChartSurface {
    public readonly isSubSurface: boolean = true;
    public readonly subChartContainer: HTMLDivElement;
    public topSectionClass = "top-section";
    public leftSectionClass = "left-section";
    public bottomSectionClass = "bottom-section";
    public rightSectionClass = "right-section";
    /**
     * Creates an instance of the {@link SciChartSubSurface}
     * @param webAssemblyContext The {@link TSciChart | SciChart 2D WebAssembly Context} containing native methods and
     * access to our WebGL2 Engine and WebAssembly numerical methods
     * @param options optional parameters of type {@link ISciChartSubSurfaceOptions} used to configure the {@link SciChartSubSurface}
     */
    constructor(webAssemblyContext: TSciChart, options?: ISciChartSubSurfaceOptions) {
        super(webAssemblyContext, options);
    }
    /** Whether other surfaces, including the parent, will be visible underneath this surface */
    public isTransparent: boolean;
    /** Gets or sets additional absolute padding between the SciChartSubSurface and its parent, in order top, right, bottom, left
     * {@link subPosition} is applied first, then this padding is added */
    public subChartPadding: Thickness;
    /** Gets or sets the {@link ECoordinateMode} used when calculating the actual position based on the {@link subPosition} */
    public coordinateMode: ECoordinateMode;
    /** Gets or sets the parent chart XAxisId used to determine which X Axis should be used when calculating the actual position */
    public parentXAxisId: string;
    /** Gets or sets the parent chart YAxisId used to determine which Y Axis should be used when calculating the actual position */
    public parentYAxisId: string;
    /** A rectangle defining the position and size of a subchart.
    * If {@link coordinateMode} is Relative (the default) then the values give the size as a proportion of the parent div, and all properties must be between 0 and 1 inclusive.
    * If {@link coordinateMode} is DataValue, values will be converted to coordinates using {@link parentXAxisId} and {@link parentYAxisId}. Subchart will be clpped to the parent SeriesViewRect
    * Can only be set if this is a subChart.  See {@link addSubChart} */
    public subPosition: Rect;
    /** Gets or sets if the subchart is visible, allowing you to hide a subchart without removing it from the parent surface */
    public isVisible: boolean;
    /** Gets or sets scale property for all sections
     * It is necessary if the scale transformation is being used for html areas around the subchart
     * For example, style = { width: "50%", transform: scale(2), transformOrigin: 'left top' } */
    public sectionScale: number;
    /** Recalculate the position of the subChart. Call if you update the size of html elements in the wrapper */
    public updateSubLayout(isDrawing = false): void {}
    /** The parent SciChartSurface, if this is a subChart. */
    public get parentSurface(): SciChartSurface {
        return this.parentSurfaceProperty;
    }
    /** Gets the Surface Type. See {@link ESurfaceType} for list of values  */
    public get surfaceType(): ESurfaceType {
        return ESurfaceType.SciChartSurfaceType;
    }
    /** Changes the Viewport Size of the {@link SciChartSurfaceBase} */
    public changeViewportSize(pixelWidth: number, pixelHeight: number): void {}
    /** Gets the sub-chart container */
    public getSubChartContainer(): HTMLDivElement {
        return this.subChartContainer;
    }
    /** Gets the sub-chart rect on the parent surface, accounting for viewport size and padding */
    public getSubChartRect(): Rect {
        return new Rect(0, 0, 1, 1);
    }
    /** Deletes native (WebAssembly) memory used by this type, after which it cannot be used */
    public delete(clearHtml: boolean = true): void {}
    /** Serializes the current {@link SciChartSubSurface} to a JSON definition. See {@link ISubChartDefinition} */
    public toJSON(excludeData = false): ISubChartDefinition {
        return {} as ISubChartDefinition;
    }
}

Basic Subchart Example (Charts within Charts)

Let's demonstrate a simple setup, where we define a sub-chart on a surface. For this we will start from defining a surface with some axes on it. On the surface we will create a sub-chart on a specified area.

// Demonstrates how to use the Sub-Charts API to create child charts in a parent chart
const {
  SciChartSurface,
  NumericAxis,
  FastLineRenderableSeries,
  XyDataSeries,
  SciChartJsNavyTheme,
  Rect,
  ECoordinateMode,
  ZoomPanModifier,
  ZoomExtentsModifier,
  MouseWheelZoomModifier,
  BoxAnnotation,
  NumberRange,
} = SciChart;

// or, for npm, import { SciChartSurface, ... } from "scichart"

// Function to add series to chart. This will be re-used for the parent and sub-charts
const addSeries = (sciChartSurface, stroke, x, y) => {
  sciChartSurface.renderableSeries.add(
    new FastLineRenderableSeries(wasmContext, {
      stroke,
      strokeThickness: 5,
      dataSeries: new XyDataSeries(wasmContext, {
        xValues: x,
        yValues: y,
      }),
      opacity: sciChartSurface.isSubSurface ? 0.5 : 1,
    })
  );
};

// Create a parent (regular) SciChartSurface which will contain the sub-chart
const { wasmContext, sciChartSurface } = await SciChartSurface.create(
  divElementId,
  {
    theme: new SciChartJsNavyTheme(),
  }
);

// Create X,Y axis on the parent chart and programmatically zoom into part of the data
sciChartSurface.xAxes.add(
  new NumericAxis(wasmContext, {
    growBy: new NumberRange(0.1, 0.1),
  })
);
sciChartSurface.yAxes.add(
  new NumericAxis(wasmContext, {
    growBy: new NumberRange(0.1, 0.1),
  })
);

// Create a series on the parent chart
addSeries(sciChartSurface, "#FF6600", xValues, yValues);
addSeries(sciChartSurface, "#ae418d", xValues, yValues1);
addSeries(sciChartSurface, "#47bde6", xValues, yValues2);

// Add some interactivity to the parent chart
sciChartSurface.chartModifiers.add(new ZoomPanModifier());
sciChartSurface.chartModifiers.add(new MouseWheelZoomModifier());
sciChartSurface.chartModifiers.add(new ZoomExtentsModifier());

// Add a Sub-Charts to the main surface. This will display a rectangle showing the current zoomed in area on the parent chart
const subChart1 = sciChartSurface.addSubChart({
  // Properties from I2DSubSurfaceOptions affect positioning and rendering of the subchart
  position: new Rect(0.02, 0.02, 0.4, 0.4),
  isTransparent: false,
  isVisible: true,
  coordinateMode: ECoordinateMode.Relative,
  // However all properties from I2DSurfaceOptions are available
  viewportBorder: { border: 3, color: "#77777777" },
  backgroundColor: "#333",
  title: "2D Overview with Sub-Charts",
  titleStyle: { fontSize: 16, color: "#eeeeee77" },
});

// Add x,y axis to the subchart
subChart1.xAxes.add(new NumericAxis(wasmContext, { isVisible: false }));
subChart1.yAxes.add(new NumericAxis(wasmContext, { isVisible: false }));

addSeries(subChart1, "#FF6600", xValues, yValues);
addSeries(subChart1, "#ae418d", xValues, yValues1);
addSeries(subChart1, "#47bde6", xValues, yValues2);

// Add a BoxAnnotation to the SubChart
const boxAnnotation = new BoxAnnotation({
  fill: "#FF660033",
  stroke: "#FF6600",
  strokeThickness: 2,
  opacity: 0.5,
});
subChart1.annotations.add(boxAnnotation);

// On parent chart zoom, pan, update the box annotation on the subchart
sciChartSurface.xAxes.get(0).visibleRangeChanged.subscribe((args) => {
  boxAnnotation.x1 = args.visibleRange.min;
  boxAnnotation.x2 = args.visibleRange.max;
});
sciChartSurface.yAxes.get(0).visibleRangeChanged.subscribe((args) => {
  boxAnnotation.y1 = args.visibleRange.min;
  boxAnnotation.y2 = args.visibleRange.max;
});

// On the parent chart, programmatically zoom into a region
setTimeout(() => {
  sciChartSurface.xAxes
    .get(0)
    .animateVisibleRange(new NumberRange(30, 70), 1000);
  sciChartSurface.yAxes
    .get(0)
    .animateVisibleRange(new NumberRange(-0.4, 0.4), 1000);
}, 1000);

In the example above we create a SciChartSurface as normal and add some series to it. Then, we call SciChartSurface.addSubChart function, which contains a position property. The property defines a structure for specifying coordinates and sizes of a sub-chart. By default, the coordinates and size are treated as ratio values in range from 0 to 1, with a canvas viewport used as a base.

Next, we add some series to both the parent SciChartSurface and the SciChartSubSurface. We subscribe to visibleRangeChanged on the parent SciChartSurface x, y axis and use that to update a BoxAnnotation in the SciChartSubSurface.

By creating this example, we have created a 2D viewport overview using the Sub-charts API, placing a child SciChartSubSurface inside a parent SciChartSurface, and subscribed to interactivity on the parent chart. The Sub-chart shows all the data and where you have zoomed in on the parent chart, allowing you to get a view into your current position (zoom level and range) on the chart.

<div id="scichart-root"></div>

  
body {
  margin: 0;
}
#scichart-root {
  width: 100%;
  height: 100vh;
}

  
const xValues = [];
const yValues = [];
const yValues1 = [];
const yValues2 = [];
for (let i = 0; i < 100; i++) {
  xValues.push(i);
  yValues.push(0.2 * Math.sin(i * 0.1) - Math.cos(i * 0.01));
  yValues1.push(0.1 * Math.sin(i * 0.3) - Math.cos(i * 0.02));
  yValues2.push(0.1 * Math.sin(i * 0.7) - Math.cos(i * 0.03));
}

async function simpleSubChart(divElementId) {
  // #region ExampleA
  // Demonstrates how to use the Sub-Charts API to create child charts in a parent chart
  const {
    SciChartSurface,
    NumericAxis,
    FastLineRenderableSeries,
    XyDataSeries,
    SciChartJsNavyTheme,
    Rect,
    ECoordinateMode,
    ZoomPanModifier,
    ZoomExtentsModifier,
    MouseWheelZoomModifier,
    BoxAnnotation,
    NumberRange,
  } = SciChart;

  // or, for npm, import { SciChartSurface, ... } from "scichart"

  // Function to add series to chart. This will be re-used for the parent and sub-charts
  const addSeries = (sciChartSurface, stroke, x, y) => {
    sciChartSurface.renderableSeries.add(
      new FastLineRenderableSeries(wasmContext, {
        stroke,
        strokeThickness: 5,
        dataSeries: new XyDataSeries(wasmContext, {
          xValues: x,
          yValues: y,
        }),
        opacity: sciChartSurface.isSubSurface ? 0.5 : 1,
      })
    );
  };

  // Create a parent (regular) SciChartSurface which will contain the sub-chart
  const { wasmContext, sciChartSurface } = await SciChartSurface.create(
    divElementId,
    {
      theme: new SciChartJsNavyTheme(),
    }
  );

  // Create X,Y axis on the parent chart and programmatically zoom into part of the data
  sciChartSurface.xAxes.add(
    new NumericAxis(wasmContext, {
      growBy: new NumberRange(0.1, 0.1),
    })
  );
  sciChartSurface.yAxes.add(
    new NumericAxis(wasmContext, {
      growBy: new NumberRange(0.1, 0.1),
    })
  );

  // Create a series on the parent chart
  addSeries(sciChartSurface, "#FF6600", xValues, yValues);
  addSeries(sciChartSurface, "#ae418d", xValues, yValues1);
  addSeries(sciChartSurface, "#47bde6", xValues, yValues2);

  // Add some interactivity to the parent chart
  sciChartSurface.chartModifiers.add(new ZoomPanModifier());
  sciChartSurface.chartModifiers.add(new MouseWheelZoomModifier());
  sciChartSurface.chartModifiers.add(new ZoomExtentsModifier());

  // Add a Sub-Charts to the main surface. This will display a rectangle showing the current zoomed in area on the parent chart
  const subChart1 = sciChartSurface.addSubChart({
    // Properties from I2DSubSurfaceOptions affect positioning and rendering of the subchart
    position: new Rect(0.02, 0.02, 0.4, 0.4),
    isTransparent: false,
    isVisible: true,
    coordinateMode: ECoordinateMode.Relative,
    // However all properties from I2DSurfaceOptions are available
    viewportBorder: { border: 3, color: "#77777777" },
    backgroundColor: "#333",
    title: "2D Overview with Sub-Charts",
    titleStyle: { fontSize: 16, color: "#eeeeee77" },
  });

  // Add x,y axis to the subchart
  subChart1.xAxes.add(new NumericAxis(wasmContext, { isVisible: false }));
  subChart1.yAxes.add(new NumericAxis(wasmContext, { isVisible: false }));

  addSeries(subChart1, "#FF6600", xValues, yValues);
  addSeries(subChart1, "#ae418d", xValues, yValues1);
  addSeries(subChart1, "#47bde6", xValues, yValues2);

  // Add a BoxAnnotation to the SubChart
  const boxAnnotation = new BoxAnnotation({
    fill: "#FF660033",
    stroke: "#FF6600",
    strokeThickness: 2,
    opacity: 0.5,
  });
  subChart1.annotations.add(boxAnnotation);

  // On parent chart zoom, pan, update the box annotation on the subchart
  sciChartSurface.xAxes.get(0).visibleRangeChanged.subscribe((args) => {
    boxAnnotation.x1 = args.visibleRange.min;
    boxAnnotation.x2 = args.visibleRange.max;
  });
  sciChartSurface.yAxes.get(0).visibleRangeChanged.subscribe((args) => {
    boxAnnotation.y1 = args.visibleRange.min;
    boxAnnotation.y2 = args.visibleRange.max;
  });

  // On the parent chart, programmatically zoom into a region
  setTimeout(() => {
    sciChartSurface.xAxes
      .get(0)
      .animateVisibleRange(new NumberRange(30, 70), 1000);
    sciChartSurface.yAxes
      .get(0)
      .animateVisibleRange(new NumberRange(-0.4, 0.4), 1000);
  }, 1000);
  // #endregion

  const { TextAnnotation, EHorizontalAnchorPoint } = SciChart; // Add a watermark to explain what's going on
  sciChartSurface.annotations.add(
    new TextAnnotation({
      x1: 0.5,
      y1: 0.5,
      text: "Mousewheel/Drag the parent chart to update the subchart view rect",
      horizontalAnchorPoint: EHorizontalAnchorPoint.Center,
      xCoordinateMode: ECoordinateMode.Relative,
      yCoordinateMode: ECoordinateMode.Relative,
      opacity: 0.5,
      fontSize: 20,
    })
  );
}

simpleSubChart("scichart-root");

async function builderExample(divElementId) {
  // #region ExampleB
  // Demonstrates how to create a line chart with SciChart.js using the Builder API
  const {
    chartBuilder,
    ESeriesType,
    EAxisType,
    EThemeProviderType,
    Rect,
    ECoordinateMode,
    EAnnotationType,
    NumberRange,
    EChart2DModifierType,
  } = SciChart;

  // or, for npm, import { chartBuilder, ... } from "scichart"

  const { wasmContext, sciChartSurface } = await chartBuilder.build2DChart(
    divElementId,
    {
      surface: { theme: { type: EThemeProviderType.Dark } },
      // Main chart definition is here
      xAxes: { type: EAxisType.NumericAxis },
      yAxes: { type: EAxisType.NumericAxis },
      series: [
        {
          type: ESeriesType.LineSeries,
          xyData: {
            xValues,
            yValues: yValues1,
          },
          options: {
            stroke: "#0066FF",
            strokeThickness: 5,
          },
        },
      ],
      modifiers: [
        { type: EChart2DModifierType.ZoomPan },
        { type: EChart2DModifierType.ZoomExtents },
        { type: EChart2DModifierType.MouseWheelZoom },
      ],
      // Subchart definition is here
      subCharts: [
        {
          surface: {
            // Properties from I2DSubSurfaceOptions affect positioning and rendering of the subchart
            position: new Rect(0.02, 0.02, 0.4, 0.4),
            isTransparent: false,
            isVisible: true,
            coordinateMode: ECoordinateMode.Relative,
            // However all properties from I2DSurfaceOptions are available
            viewportBorder: { border: 3, color: "#77777777" },
            backgroundColor: "#333",
            title: "2D Overview with Sub-Charts",
            titleStyle: { fontSize: 16, color: "#eeeeee77" },
          },
          // Define the x,y axis on Subchart
          xAxes: { type: EAxisType.NumericAxis, options: { isVisible: false } },
          yAxes: { type: EAxisType.NumericAxis, options: { isVisible: false } },
          // Define the series on Subchart
          series: [
            {
              type: ESeriesType.LineSeries,
              xyData: {
                xValues,
                yValues: yValues1,
              },
              options: {
                stroke: "#0066FF",
                strokeThickness: 5,
              },
            },
          ],
          annotations: [
            {
              type: EAnnotationType.RenderContextBoxAnnotation,
              options: {
                fill: "#FF660033",
                stroke: "#FF6600",
                strokeThickness: 2,
                opacity: 0.5,
              },
            },
          ],
        },
      ],
    }
  );

  // On parent chart zoom, pan, update the box annotation on the subchart
  const subChartBoxAnnotation = sciChartSurface.subCharts
    .at(0)
    .annotations.get(0);
  sciChartSurface.xAxes.get(0).visibleRangeChanged.subscribe((args) => {
    subChartBoxAnnotation.x1 = args.visibleRange.min;
    subChartBoxAnnotation.x2 = args.visibleRange.max;
  });
  sciChartSurface.yAxes.get(0).visibleRangeChanged.subscribe((args) => {
    subChartBoxAnnotation.y1 = args.visibleRange.min;
    subChartBoxAnnotation.y2 = args.visibleRange.max;
  });

  // On the parent chart, programmatically zoom into a region
  setTimeout(() => {
    sciChartSurface.xAxes
      .get(0)
      .animateVisibleRange(new NumberRange(30, 70), 1000);
    sciChartSurface.yAxes
      .get(0)
      .animateVisibleRange(new NumberRange(-0.4, 0.4), 1000);
  }, 1000);
  // #endregion
}

// Uncomment this to use the builder example //builderExample("scichart-root");

  

Try zooming the example with mouse-drag, panning, mousewheel and double-click to reset zoom to see the effect on the BoxAnnotation in the SciChartSubSurface.

SubCharts with the Builder API

It is also possible to create a sub-chart via Builder API. For this pass an array of ISubChartDefinition via ISciChart2DDefinition.subCharts property.

For example, the following snippet will give us the same result as Basic Example setup:

// Demonstrates how to create a line chart with SciChart.js using the Builder API
const {
  chartBuilder,
  ESeriesType,
  EAxisType,
  EThemeProviderType,
  Rect,
  ECoordinateMode,
  EAnnotationType,
  NumberRange,
  EChart2DModifierType,
} = SciChart;

// or, for npm, import { chartBuilder, ... } from "scichart"

const { wasmContext, sciChartSurface } = await chartBuilder.build2DChart(
  divElementId,
  {
    surface: { theme: { type: EThemeProviderType.Dark } },
    // Main chart definition is here
    xAxes: { type: EAxisType.NumericAxis },
    yAxes: { type: EAxisType.NumericAxis },
    series: [
      {
        type: ESeriesType.LineSeries,
        xyData: {
          xValues,
          yValues: yValues1,
        },
        options: {
          stroke: "#0066FF",
          strokeThickness: 5,
        },
      },
    ],
    modifiers: [
      { type: EChart2DModifierType.ZoomPan },
      { type: EChart2DModifierType.ZoomExtents },
      { type: EChart2DModifierType.MouseWheelZoom },
    ],
    // Subchart definition is here
    subCharts: [
      {
        surface: {
          // Properties from I2DSubSurfaceOptions affect positioning and rendering of the subchart
          position: new Rect(0.02, 0.02, 0.4, 0.4),
          isTransparent: false,
          isVisible: true,
          coordinateMode: ECoordinateMode.Relative,
          // However all properties from I2DSurfaceOptions are available
          viewportBorder: { border: 3, color: "#77777777" },
          backgroundColor: "#333",
          title: "2D Overview with Sub-Charts",
          titleStyle: { fontSize: 16, color: "#eeeeee77" },
        },
        // Define the x,y axis on Subchart
        xAxes: { type: EAxisType.NumericAxis, options: { isVisible: false } },
        yAxes: { type: EAxisType.NumericAxis, options: { isVisible: false } },
        // Define the series on Subchart
        series: [
          {
            type: ESeriesType.LineSeries,
            xyData: {
              xValues,
              yValues: yValues1,
            },
            options: {
              stroke: "#0066FF",
              strokeThickness: 5,
            },
          },
        ],
        annotations: [
          {
            type: EAnnotationType.RenderContextBoxAnnotation,
            options: {
              fill: "#FF660033",
              stroke: "#FF6600",
              strokeThickness: 2,
              opacity: 0.5,
            },
          },
        ],
      },
    ],
  }
);

// On parent chart zoom, pan, update the box annotation on the subchart
const subChartBoxAnnotation = sciChartSurface.subCharts
  .at(0)
  .annotations.get(0);
sciChartSurface.xAxes.get(0).visibleRangeChanged.subscribe((args) => {
  subChartBoxAnnotation.x1 = args.visibleRange.min;
  subChartBoxAnnotation.x2 = args.visibleRange.max;
});
sciChartSurface.yAxes.get(0).visibleRangeChanged.subscribe((args) => {
  subChartBoxAnnotation.y1 = args.visibleRange.min;
  subChartBoxAnnotation.y2 = args.visibleRange.max;
});

// On the parent chart, programmatically zoom into a region
setTimeout(() => {
  sciChartSurface.xAxes
    .get(0)
    .animateVisibleRange(new NumberRange(30, 70), 1000);
  sciChartSurface.yAxes
    .get(0)
    .animateVisibleRange(new NumberRange(-0.4, 0.4), 1000);
}, 1000);
The Builder API demo of SubCharts works very similarly to the javascript-API version. A SubChart is declared via the subCharts property of the chart ISciChart2DDefinition, and axis, series, interactions can be added to it as before. You can access the SubChart and any of it's created properties via the SciChartSurface.subCharts property.
See Also