Skip to content

Latest commit

 

History

History
514 lines (425 loc) · 14.5 KB

File metadata and controls

514 lines (425 loc) · 14.5 KB

Documentation Guide

Cesium's reference documentation is one of the most popular sections of the Cesium website, and a critical resource for developers.

This guide describes best practices for writing reference doc.

Always include doc for new identifiers (classes, functions, properties, constants) in the public Cesium API.

Generally, just follow the patterns that are already in comparable parts of the code, e.g., if you are documenting a new utility function in Core, look at a function in Core such as binarySearch; likewise, if you are documenting a new class in Scene, look at a similar class such as Model.

Building the Doc

The reference doc is written in JavaScript code comments using JSDoc3 tags. At the command line, build the doc from the root Cesium directory by running the following:

npm run generateDocumentation

This creates a Build/Documentation directory with the built HTML files.

There is a link to the doc from Cesium's main index.html when running

npm start

Basics

Consider one of the simplest functions in Cesium, defined:

/**
 * @exports defined
 *
 * @param {Object} value The object.
 * @returns {Boolean} Returns true if the object is defined, returns false otherwise.
 *
 * @example
 * if (Cesium.defined(positions)) {
 *      doSomething();
 * } else {
 *      doSomethingElse();
 * }
 */
function defined(value) {
    return value !== undefined;
};
  • The doc for defined is in the comment starting with /**. JSDoc tags begin with @.
  • @exports describes the name of the function that is exported from the module.
  • @param describes the function's parameters, and @returns describes the function's return value.
  • @example describes a code sample.

The above reference doc is built into the following:

This guide describes best practices for writing doc. For complete details on JSDoc tags, see their documentation.

Parameters

  • Document all function parameters.
  • Use [] for optional parameters and include the default value, e.g.,
* @param {Number} [startingIndex=0] The index into the array at which to start packing the elements.

  • Omit the default value if it is undefined, e.g.,
* @param {Cartesian3} [result] The object on which to store the result.
  • If a parameter can be more than one type, use | to separate the types, e.g.,
* @param {GeometryInstance[]|GeometryInstance} [options.geometryInstances] The geometry instances - or a single geometry instance - to render.

As a complete example,

/**
 * Computes a Matrix4 instance from a Matrix3 representing the rotation
 * and a Cartesian3 representing the translation.
 *
 * @param {Matrix3} rotation The upper left portion of the matrix representing the rotation.
 * @param {Cartesian3} [translation=Cartesian3.ZERO] The upper right portion of the matrix representing the translation.
 * @param {Matrix4} [result] The object in which the result will be stored, if undefined a new instance will be created.
 * @returns {Matrix4} The modified result parameter, or a new Matrix4 instance if one was not provided.
 */
Matrix4.fromRotationTranslation = function(rotation, translation, result) {
    // ..

generates

The Cesium classes in the Type column are links to their doc.

options Parameters

Each property of an options parameter (see the Coding Guide) should be documented with a separate @param tag, e.g.,

 * @param {Object} [options] Object with the following properties:
 * @param {Number} [options.length=10000000.0] The length of the axes in meters.
 * @param {Number} [options.width=2.0] The width of the axes in pixels.
 * @param {Matrix4} [options.modelMatrix=Matrix4.IDENTITY] The 4x4 matrix that defines the reference frame, i.e., origin plus axes, to visualize.
 * @param {Boolean} [options.show=true] Determines if this primitive will be shown.
 * @param {Object} [options.id] A user-defined object to return when the instance is picked with {@link Scene#pick}

generates

If all options properties are optional, also mark the options object optional.

Exceptions

  • Document exceptions after the @param/@returns section using @exception, e.g.,
/**
 * ...
 *
 * @exception {DeveloperError} aspectRatio must be greater than zero.
 */
Matrix4.computePerspectiveFieldOfView = function(fovY, aspectRatio, near, far, result) {
    //>>includeStart('debug', pragmas.debug);
    if (aspectRatio <= 0.0) {
        throw new DeveloperError('aspectRatio must be greater than zero.');
    }
    // ...
  • Do not document exceptions for missing parameters; it is implicit in the @param tag because the parameter is not optional, e.g.,
/**
 * Computes a Matrix4 instance from a column-major order array.
 *
 * @param {Number[]} values The column-major order array.
 * @param {Matrix4} [result] The object in which the result will be stored. If undefined a new instance will be created.
 * @returns {Matrix4} The modified result parameter, or a new Matrix4 instance if one was not provided.
 */
Matrix4.fromColumnMajorArray = function(values, result) {
    //>>includeStart('debug', pragmas.debug);
    if (!defined(values)) {
        throw new DeveloperError('values is required.');
    }
    //>>includeEnd('debug');

    return Matrix4.clone(values, result);
};

Examples

Developers almost always jump to an example before reading the doc. Provide concise but instructive code examples with enough context whenever possible.

Useful examples:

/**
 * ...
 *
 * @example
 * var n = Cesium.Math.lerp(0.0, 2.0, 0.5); // returns 1.0
 */
CesiumMath.lerp = function(p, q, time) {
    // ...
/**
 * ...
 *
 * @example
 * // Apply non-uniform scale to node LOD3sp
 * var node = model.getNode('LOD3sp');
 * node.matrix = Cesium.Matrix4.fromScale(new Cesium.Cartesian3(5.0, 1.0, 1.0), node.matrix);
 */
Model.prototype.getNode = function(name) {
    // ...

Unnecessary example:

/**
 * ..
 *
 * @example
 * var f = Cesium.Math.EPSILON1;
 */
CesiumMath.EPSILON1 = 0.1;
  • Use the Cesium namespace (Cesium.) in examples.
  • Limit code in @example tags to 80 lines so it does not overflow.

References

  • Use @see sparingly to link to related classes, functions, and online resources., e.g.,
/**
 * Provides terrain or other geometry for the surface of an ellipsoid.  The surface geometry is
 * organized into a pyramid of tiles according to a {@link TilingScheme}.  This type describes an
 * interface and is not intended to be instantiated directly.
 *
 * @alias TerrainProvider
 * @constructor
 *
 * @see EllipsoidTerrainProvider
 * @see CesiumTerrainProvider
 * @see ArcGisImageServerTerrainProvider
 */
function TerrainProvider() { /* ... */ }
  • Use # to reference an instance member (e.g., one that is assigned to the prototype); use . to access a static member, e.g.,
@see Class
@see Class#instanceMember
@see Class.staticMember
  • Use {@link className} to link to another documented type. This is not required for @param tags when the type is provided.
  • Use <code> </code> tags when referring to parameters or other variable names and values within a description.
  • Use {@link URL|title} to link to external sites.

Classes

Define a class with @alias and @constructor tags on the constructor function, e.g.,

/**
 * A 3D Cartesian point.
 *
 * @alias Cartesian3
 * @constructor
 *
 * ...
 */
function Cartesian3(x, y, z) {
   // ...

Properties and Constants

  • Use @type and @default (whenever possible, except when the default is undefined) to document properties, e.g.,
function Cartesian3(x, y) {
    /**
     * The X component.
     *
     * @type {Number}
     * @default 0.0
     */
    this.x = defaultValue(x, 0.0);

    // ...
  • Use @memberOf when documenting property getter/setters, e.g.,
defineProperties(Entity.prototype, {
    /**
     * Gets or sets whether this entity should be displayed. When set to true,
     * the entity is only displayed if the parent entity's show property is also true.
     *
     * @memberof Entity.prototype
     * @type {Boolean}
     */
    show : {
        get : function() {
           // ...
        },
        set : function(value) {
           // ...
        }
    },
    // ...
  • Use @readonly to indicate read-only properties, e.g.,
defineProperties(Entity.prototype, {
    /**
     * Gets the unique ID associated with this object.
     *
     * @memberof Entity.prototype
     * @type {String}
     * @readonly
     */
    id : {
        get : function() {
            return this._id;
        }
    },
    // ...
  • The description for readonly properties should start with "Gets", and the description for read/write properties should start with "Gets or sets."
  • Document constants with @constant, e.g.,
/**
 * An immutable Cartesian3 instance initialized to (0.0, 0.0, 0.0).
 *
 * @type {Cartesian3}
 * @constant
 */
Cartesian3.ZERO = freezeObject(new Cartesian3(0.0, 0.0, 0.0));

Functions and Callbacks

  • Use @function when JSDoc can't infer that an identifier is a function because the JavaScript function keyword isn't used, e.g.,
/**
 * Creates a Cartesian4 from four consecutive elements in an array.
 * @function
 *
 * @param {Number[]} array The array whose four consecutive elements correspond to the x, y, z, and w components, respectively.
 * @param {Number} [startingIndex=0] The offset into the array of the first element, which corresponds to the x component.
 * @param {Cartesian4} [result] The object on which to store the result.
 * @returns {Cartesian4}  The modified result parameter or a new Cartesian4 instance if one was not provided.
 *
 * @example
 * // Create a Cartesian4 with (1.0, 2.0, 3.0, 4.0)
 * var v = [1.0, 2.0, 3.0, 4.0];
 * var p = Cesium.Cartesian4.fromArray(v);
 *
 * // Create a Cartesian4 with (1.0, 2.0, 3.0, 4.0) using an offset into an array
 * var v2 = [0.0, 0.0, 1.0, 2.0, 3.0, 4.0];
 * var p2 = Cesium.Cartesian4.fromArray(v2, 2);
 */
Cartesian4.fromArray = Cartesian4.unpack;
  • Use @callback to document a function signature, e.g.,
/**
 * Sort the items in the queue in-place.
 *
 * @param {Queue~Comparator} compareFunction A function that defines the sort order.
 */
Queue.prototype.sort = function(compareFunction) {
    if (this._offset > 0) {
        //compact array
        this._array = this._array.slice(this._offset);
        this._offset = 0;
    }

    this._array.sort(compareFunction);
};

/**
 * A function used to compare two items while sorting a queue.
 * @callback Queue~Comparator
 *
 * @param {Object} a An item in the array.
 * @param {Object} b An item in the array.
 * @returns {Number} Returns a negative value if <code>a</code> is less than <code>b</code>,
 *          a positive value if <code>a</code> is greater than <code>b</code>, or
 *          0 if <code>a</code> is equal to <code>b</code>.
 *
 * @example
 * function compareNumbers(a, b) {
 *     return a - b;
 * }
 */

Private

Documentation is not generated for private members that start with _. It is often useful to still write doc comments for them for maintainability (see the Coding Guide).

If a member or function doesn't start with _, but is intended to be private, use the @private tag at the bottom of the documentation, e.g.,

/**
 * A tween is an animation that interpolates the properties of two objects using an {@link EasingFunction}.  Create
 * one using {@link Scene#tweens} and {@link TweenCollection#add} and related add functions.
 *
 * @alias Tween
 * @constructor
 *
 * @private
 */
function Tween(/* ... */) { /* ... */ }

If no documentation comments are provided, the identifier will not be documented. In this case, @private is not strictly needed, but we use it anyway so it is clear that documentation was not forgotten, e.g.,

/**
 * @private
 */
function appendForwardSlash(url) { /* ... */ }

Layout Reference

There's a general flow to each documentation block that makes it easy to read. Tags are always in the same order with the same spacing.

Constructor Function

DESCRIPTION.

@alias NAME
@constructor

@param {TYPE} NAME DESCRIPTION.
@param {TYPE|OTHER_TYPE} NAME DESCRIPTION WITH LONG
       WRAPPING LINES.

@exception {TYPE} DESCRIPTION.

@see TYPE
@see TYPE#INSTANCE_MEMBER
@see TYPE.STATIC_MEMBER

@example

[@private]

Member Function

DESCRIPTION.

@param {TYPE} NAME DESCRIPTION.
@param {TYPE|OTHER_TYPE} NAME DESCRIPTION WITH LONG
       WRAPPING LINES.
@returns {TYPE} DESCRIPTION.

@exception {TYPE} DESCRIPTION.

@see TYPE
@see TYPE#INSTANCE_MEMBER
@see TYPE.STATIC_MEMBER

@example 

[@private]

Property

DESCRIPTION.

@type {TYPE}
[@constant]
[@default DEFAULT_VALUE]
[@readonly]

@exception {TYPE} DESCRIPTION.

@see TYPE
@see TYPE#INSTANCE_MEMBER
@see TYPE.STATIC_MEMBER

@example 

[@private]

Property Getter/Setter

DESCRIPTION.

@memberof CLASS_NAME.prototype
@type {TYPE}
[@default DEFAULT_VALUE]
[@readonly]

@exception {TYPE} DESCRIPTION.

@see TYPE
@see TYPE#INSTANCE_MEMBER
@see TYPE.STATIC_MEMBER

@example 

[@private]

Standalone Function

DESCRIPTION.

@exports NAME

@param {TYPE} NAME DESCRIPTION.
@param {TYPE|OTHER_TYPE} NAME DESCRIPTION WITH LONG
       WRAPPING LINES.
@returns {TYPE} DESCRIPTION.

@exception {TYPE} DESCRIPTION.

@see TYPE
@see TYPE#INSTANCE_MEMBER
@see TYPE.STATIC_MEMBER

@example 

[@private]