public addObject()

in src/app/template/index.ts [165:353]


  public addObject(table: string, objectClass: Prototypes.ObjectClass) {
    // Visit a object only once
    if (this.objectVisited[objectClass.object._id]) {
      return;
    }
    this.objectVisited[objectClass.object._id] = true;

    const template = this.template;

    // Get template inference data
    const params = objectClass.getTemplateParameters();
    if (params && params.inferences) {
      for (const inference of params.inferences) {
        if (inference.axis) {
          this.addColumnsFromExpression(
            inference.dataSource.table,
            inference.axis.expression
          );
        }
        if (inference.scale) {
          // Find all objects that use the scale
          const expressions = new Set<string>();
          let table: string = null;
          let groupBy: Specification.Types.GroupBy = null;
          for (const item of Prototypes.forEachObject(
            this.template.specification
          )) {
            for (const [, mapping] of Prototypes.forEachMapping(
              item.object.mappings
            )) {
              if (mapping.type == MappingType.scale) {
                const scaleMapping = mapping as Specification.ScaleMapping;
                if (scaleMapping.scale == inference.objectID) {
                  expressions.add(scaleMapping.expression);
                  if (item.kind == "glyph" || item.kind == "mark") {
                    table = item.glyph.table;
                    // Find the plot segment
                    for (const ps of Prototypes.forEachObject(
                      this.template.specification
                    )) {
                      if (
                        ps.kind == "chart-element" &&
                        Prototypes.isType(ps.object.classID, "plot-segment") &&
                        item.glyph._id === (ps.chartElement as any).glyph
                      ) {
                        groupBy = (ps.chartElement as Specification.PlotSegment)
                          .groupBy;
                        break; // TODO: for now, we assume it's the first one
                      }
                    }
                  } else if (
                    item.kind == "chart-element" &&
                    Prototypes.isType(
                      item.chartElement.classID,
                      "legend.custom"
                    )
                  ) {
                    // don't add column names legend expression into inferences
                    expressions.delete(scaleMapping.expression);
                  } else if (
                    item.kind == "chart-element" &&
                    Prototypes.isType(item.chartElement.classID, "links")
                  ) {
                    const linkTable = item.object.properties.linkTable as any;
                    const defaultTable = this.dataset.tables[0];
                    table = (linkTable && linkTable.table) || defaultTable.name;
                  } else {
                    table = this.dataset.tables.find(
                      (table) => table.type === TableType.Main
                    ).name;
                  }
                }
              }
            }
          }
          if (expressions.size == 0) {
            // Scale not used
            continue;
          }
          inference.scale.expressions = Array.from(expressions);
          if (!inference.dataSource) {
            inference.dataSource = {
              table,
              groupBy,
            };
          }
        }
        if (inference.expression) {
          this.addColumnsFromExpression(
            inference.dataSource.table,
            inference.expression.expression
          );
        }
        if (inference.nestedChart) {
          const { nestedChart } = inference;
          Object.keys(nestedChart.columnNameMap).forEach((key) => {
            this.addColumn(inference.dataSource.table, key);
          });
        }
        if (inference.axis) {
          const templateObject = Prototypes.findObjectById(
            this.chart,
            inference.objectID
          );

          if (
            (templateObject.properties[
              inference.axis.property as string
            ] as any).autoDomainMin !== "undefined"
          ) {
            inference.autoDomainMin = (templateObject.properties[
              inference.axis.property as string
            ] as any).autoDomainMin as boolean;
          }
          if (
            (templateObject.properties[
              inference.axis.property as string
            ] as any).autoDomainMax !== "undefined"
          ) {
            inference.autoDomainMax = (templateObject.properties[
              inference.axis.property as string
            ] as any).autoDomainMax as boolean;
          }
          if (inference.autoDomainMax === undefined) {
            inference.autoDomainMax = true;
          }
          if (inference.autoDomainMax === undefined) {
            inference.autoDomainMax = true;
          }
        }
        template.inference.push(inference);
      }
    }
    if (params && params.properties) {
      for (const property of params.properties) {
        // Make a default display name
        let pn = "";
        if (property.target.property) {
          pn = this.propertyToString(property.target.property);
        } else if (property.target.attribute) {
          pn = property.target.attribute;
        }
        property.displayName = objectClass.object.properties.name + "/" + pn;
        template.properties.push(property);
      }
    }

    // Add filter
    const plotSegmentObj = objectClass.object as Specification.PlotSegment<any>;
    if (Prototypes.isType(plotSegmentObj.classID, "plot-segment")) {
      this.addTable(plotSegmentObj.table);
      const filter = plotSegmentObj.filter;
      if (filter) {
        const { categories, expression } = filter;
        if (expression) {
          this.addColumnsFromExpression(table, expression);
        }
        if (categories) {
          this.addColumnsFromExpression(table, categories.expression);
        }
      }

      const groupBy = plotSegmentObj.groupBy;
      if (groupBy && groupBy.expression) {
        this.addColumnsFromExpression(table, groupBy.expression);
      }
    }

    // Get mappings
    for (const [, mapping] of Prototypes.forEachMapping(
      objectClass.object.mappings
    )) {
      if (mapping.type == MappingType.scale) {
        const scaleMapping = mapping as Specification.ScaleMapping;
        this.addColumnsFromExpression(
          scaleMapping.table,
          scaleMapping.expression
        );
      }
      if (mapping.type == MappingType.text) {
        const textMapping = mapping as Specification.TextMapping;
        this.addColumnsFromExpression(
          textMapping.table,
          textMapping.textExpression,
          true
        );
      }
    }
  }