async _load_table(table, resolve) {
        this.shadowRoot.querySelector("#app").classList.add("hide_message");

        this._clear_state();
        this._table = table;

        let [cols, schema] = await Promise.all([table.columns(), table.schema(true)]);

        // Initial col order never contains expressions
        this._initial_col_order = cols.slice();

        // Grab expressions from the viewer and validate them so that
        // expressions do not crash the viewer/table.
        const expressions = this._get_view_expressions();
        const valid_expressions = [];

        let expression_schema = {};

        if (expressions.length > 0) {
            const valid_expression_alias = [];
            const validate_results = await table.validate_expressions(expressions);
            expression_schema = validate_results.expression_schema;

            for (const expression of expressions) {
                const alias = getExpressionAlias(expression);

                if (alias === undefined) {
                    console.warn(`Not applying expression ${expression} as it does not have an alias set.`);
                    continue;
                }

                if (expression_schema[alias]) {
                    valid_expressions.push(expression);
                    valid_expression_alias.push(alias);
                } else {
                    console.error(`Could not validate expression "${alias}": ${validate_results.errors[alias]}`);
                }
            }

            cols = cols.concat(valid_expression_alias);
        }

        if (!this.hasAttribute("columns")) {
            this.setAttribute("columns", JSON.stringify(this._initial_col_order));
        }

        cols.sort(column_sorter(schema));

        // Update aggregates
        const aggregate_attribute = this.get_aggregate_attribute();
        const aggregates = get_aggregates_with_defaults(aggregate_attribute, cols, schema, expression_schema);

        let shown = JSON.parse(this.getAttribute("columns")); //.filter(x => all_cols.indexOf(x) > -1);

        // At this point, cols contains both the table columns and the
        // validated expressions, so this should only filter on columns
        // that don't exist in either.
        const shown_is_invalid = shown.filter(x => cols.indexOf(x) > -1).length === 0;

        if (shown_is_invalid) {
            shown = this._initial_col_order;
        }

        this._aggregate_defaults = get_aggregate_defaults(cols, schema, expression_schema);

        // Clear the columns in the DOM before adding new ones
        this._clear_columns();

        for (const name of cols) {
            let aggregate = aggregates.find(a => a.column === name).op;
            let type = schema[name];
            if (!type) {
                type = expression_schema[name];
            }
            const expression = findExpressionByAlias(name, valid_expressions);
            const row = this._new_row(name, type, aggregate, null, null, expression);
            this._inactive_columns.appendChild(row);
            if (shown.includes(name)) {
                row.classList.add("active");
            }
        }

        while (shown.length < this._plugin.initial?.names?.length) {
            shown.push(null);
        }

        for (const x of shown) {
            let type = schema[x];
            if (!type) {
                type = expression_schema[x];
            }
            const expression = findExpressionByAlias(x, valid_expressions);
            const active_row = this._new_row(x, type, undefined, undefined, undefined, expression);
            this._active_columns.appendChild(active_row);
        }

        if (cols.length === shown.filter(x => cols.indexOf(x) > -1).length) {
            this._columns_container.classList.add("collapse");
        } else {
            this._columns_container.classList.remove("collapse");
        }

        this._show_column_container();
        this._show_side_panel_actions();

        // Filters need type information to populate e.g. the operator dropdown,
        // so reset them.
        if (this.hasAttribute("filters")) {
            this.filters = this.getAttribute("filters");
        }

        // Get an edit port from the table, and set it on the viewer so that
        // all grid edits use the specified port.
        this._edit_port = await table.make_port();

        // Resolve the edit port lock, which allows for `get_edit_port` to be
        // called in arbitary order without ever returning a null value.
        this._edit_port_lock.resolve(this._edit_port);

        try {
            await this._debounce_update({force_update: true});
        } catch (e) {
            console.warn("Initial view failed, resetting UI state");
            await this.reset();
            throw e;
        }

        resolve();
    }
/**
     * Given a {@link module:perspective~table}, load it into the
     * {@link module:perspective_viewer~PerspectiveViewer} and set the viewer's
     * state. If the `expressions` attribute is set on the viewer, this
     * method attempts to validate the expressions with the `Table` and
     * reconcile state.
     *
     * @param {*} table
     */
Given a  module:perspective~table, load it into the
module:perspective_viewer~PerspectiveViewer and set the viewer's
state. If the `expressions` attribute is set on the viewer, this
method attempts to validate the expressions with the `Table` and
reconcile state.

@param {*} table
Given a module : perspective~table load it into the module : perspective_viewer~PerspectiveViewer and set the viewer ' s state . If the ` expressions ` attribute is set on the viewer this method attempts to validate the expressions with the ` Table ` and reconcile state . @param { * } table
async _load_table(table, resolve) {
        this.shadowRoot.querySelector("#app").classList.add("hide_message");
        this._clear_state();
        this._table = table;
        let [cols, schema] = await Promise.all([table.columns(), table.schema(true)]);
        this._initial_col_order = cols.slice();
        const expressions = this._get_view_expressions();
        const valid_expressions = [];
        let expression_schema = {};
        if (expressions.length > 0) {
            const valid_expression_alias = [];
            const validate_results = await table.validate_expressions(expressions);
            expression_schema = validate_results.expression_schema;
            for (const expression of expressions) {
                const alias = getExpressionAlias(expression);
                if (alias === undefined) {
                    console.warn(`Not applying expression ${expression} as it does not have an alias set.`);
                    continue;
                }
                if (expression_schema[alias]) {
                    valid_expressions.push(expression);
                    valid_expression_alias.push(alias);
                } else {
                    console.error(`Could not validate expression "${alias}": ${validate_results.errors[alias]}`);
                }
            }
            cols = cols.concat(valid_expression_alias);
        }
        if (!this.hasAttribute("columns")) {
            this.setAttribute("columns", JSON.stringify(this._initial_col_order));
        }
        cols.sort(column_sorter(schema));
        const aggregate_attribute = this.get_aggregate_attribute();
        const aggregates = get_aggregates_with_defaults(aggregate_attribute, cols, schema, expression_schema);
        let shown = JSON.parse(this.getAttribute("columns")); 
        const shown_is_invalid = shown.filter(x => cols.indexOf(x) > -1).length === 0;
        if (shown_is_invalid) {
            shown = this._initial_col_order;
        }
        this._aggregate_defaults = get_aggregate_defaults(cols, schema, expression_schema);
        this._clear_columns();
        for (const name of cols) {
            let aggregate = aggregates.find(a => a.column === name).op;
            let type = schema[name];
            if (!type) {
                type = expression_schema[name];
            }
            const expression = findExpressionByAlias(name, valid_expressions);
            const row = this._new_row(name, type, aggregate, null, null, expression);
            this._inactive_columns.appendChild(row);
            if (shown.includes(name)) {
                row.classList.add("active");
            }
        }
        while (shown.length < this._plugin.initial?.names?.length) {
            shown.push(null);
        }
        for (const x of shown) {
            let type = schema[x];
            if (!type) {
                type = expression_schema[x];
            }
            const expression = findExpressionByAlias(x, valid_expressions);
            const active_row = this._new_row(x, type, undefined, undefined, undefined, expression);
            this._active_columns.appendChild(active_row);
        }
        if (cols.length === shown.filter(x => cols.indexOf(x) > -1).length) {
            this._columns_container.classList.add("collapse");
        } else {
            this._columns_container.classList.remove("collapse");
        }
        this._show_column_container();
        this._show_side_panel_actions();
        if (this.hasAttribute("filters")) {
            this.filters = this.getAttribute("filters");
        }
        this._edit_port = await table.make_port();
        this._edit_port_lock.resolve(this._edit_port);
        try {
            await this._debounce_update({force_update: true});
        } catch (e) {
            console.warn("Initial view failed, resetting UI state");
            await this.reset();
            throw e;
        }
        resolve();
    }
async _load_table ( table , resolve ) { this . shadowRoot . querySelector ( "#app" ) . classList . add ( "hide_message" ) ; this . _clear_state ( ) ; this . _table = table ; let [ cols , schema ] = await Promise . all ( [ table . columns ( ) , table . schema ( true ) ] ) ; this . _initial_col_order = cols . slice ( ) ; const expressions = this . _get_view_expressions ( ) ; const valid_expressions = [ ] ; let expression_schema = { } ; if ( expressions . length > 0 ) { const valid_expression_alias = [ ] ; const validate_results = await table . validate_expressions ( expressions ) ; expression_schema = validate_results . expression_schema ; for ( const expression of expressions ) { const alias = getExpressionAlias ( expression ) ; if ( alias === undefined ) { console . warn ( ` ${ expression } ` ) ; continue ; } if ( expression_schema [ alias ] ) { valid_expressions . push ( expression ) ; valid_expression_alias . push ( alias ) ; } else { console . error ( ` ${ alias } ${ validate_results . errors [ alias ] } ` ) ; } } cols = cols . concat ( valid_expression_alias ) ; } if ( ! this . hasAttribute ( "columns" ) ) { this . setAttribute ( "columns" , JSON . stringify ( this . _initial_col_order ) ) ; } cols . sort ( column_sorter ( schema ) ) ; const aggregate_attribute = this . get_aggregate_attribute ( ) ; const aggregates = get_aggregates_with_defaults ( aggregate_attribute , cols , schema , expression_schema ) ; let shown = JSON . parse ( this . getAttribute ( "columns" ) ) ; const shown_is_invalid = shown . filter ( x => cols . indexOf ( x ) > - 1 ) . length === 0 ; if ( shown_is_invalid ) { shown = this . _initial_col_order ; } this . _aggregate_defaults = get_aggregate_defaults ( cols , schema , expression_schema ) ; this . _clear_columns ( ) ; for ( const name of cols ) { let aggregate = aggregates . find ( a => a . column === name ) . op ; let type = schema [ name ] ; if ( ! type ) { type = expression_schema [ name ] ; } const expression = findExpressionByAlias ( name , valid_expressions ) ; const row = this . _new_row ( name , type , aggregate , null , null , expression ) ; this . _inactive_columns . appendChild ( row ) ; if ( shown . includes ( name ) ) { row . classList . add ( "active" ) ; } } while ( shown . length < this . _plugin . initial ?. names ?. length ) { shown . push ( null ) ; } for ( const x of shown ) { let type = schema [ x ] ; if ( ! type ) { type = expression_schema [ x ] ; } const expression = findExpressionByAlias ( x , valid_expressions ) ; const active_row = this . _new_row ( x , type , undefined , undefined , undefined , expression ) ; this . _active_columns . appendChild ( active_row ) ; } if ( cols . length === shown . filter ( x => cols . indexOf ( x ) > - 1 ) . length ) { this . _columns_container . classList . add ( "collapse" ) ; } else { this . _columns_container . classList . remove ( "collapse" ) ; } this . _show_column_container ( ) ; this . _show_side_panel_actions ( ) ; if ( this . hasAttribute ( "filters" ) ) { this . filters = this . getAttribute ( "filters" ) ; } this . _edit_port = await table . make_port ( ) ; this . _edit_port_lock . resolve ( this . _edit_port ) ; try { await this . _debounce_update ( { force_update : true } ) ; } catch ( e ) { console . warn ( "Initial view failed, resetting UI state" ) ; await this . reset ( ) ; throw e ; } resolve ( ) ; }
Given a {@link module:perspective~table}, load it into the
 {@link module:perspective_viewer~PerspectiveViewer} and set the viewer's
 state.
Given a { @link module : perspective~table } load it into the { @link module : perspective_viewer~PerspectiveViewer } and set the viewer ' s state .
// Initial col order never contains expressions // Grab expressions from the viewer and validate them so that // expressions do not crash the viewer/table. // Update aggregates //.filter(x => all_cols.indexOf(x) > -1); // At this point, cols contains both the table columns and the // validated expressions, so this should only filter on columns // that don't exist in either. // Clear the columns in the DOM before adding new ones // Filters need type information to populate e.g. the operator dropdown, // so reset them. // Get an edit port from the table, and set it on the viewer so that // all grid edits use the specified port. // Resolve the edit port lock, which allows for `get_edit_port` to be // called in arbitary order without ever returning a null value.