Browse Source

better handling of labels from multiple structures

- intruduced group hash
Alexander Rose 5 years ago
parent
commit
691571ec39

+ 13 - 11
src/mol-model-props/common/custom-element-property.ts

@@ -112,18 +112,20 @@ namespace CustomElementProperty {
         }
     }
 
-    function createLabelProvider<T>(modelProperty: CustomModelProperty.Provider<{}, Value<T>>, getLabel: (p: T) => string | undefined) {
-        return function(loci: Loci): string | undefined {
-            if (loci.kind === 'element-loci') {
-                const e = loci.elements[0];
-                if (!e || !e.unit.model.customProperties.hasReference(modelProperty.descriptor)) return
-                const data = modelProperty.get(e.unit.model).value
-                const element = e.unit.elements[OrderedSet.start(e.indices)]
-                const value = data?.get(element)
-                if (value === undefined) return
-                return getLabel(value);
+    function createLabelProvider<T>(modelProperty: CustomModelProperty.Provider<{}, Value<T>>, getLabel: (p: T) => string | undefined): LociLabelProvider {
+        return {
+            label: (loci: Loci) => {
+                if (loci.kind === 'element-loci') {
+                    const e = loci.elements[0];
+                    if (!e || !e.unit.model.customProperties.hasReference(modelProperty.descriptor)) return
+                    const data = modelProperty.get(e.unit.model).value
+                    const element = e.unit.elements[OrderedSet.start(e.indices)]
+                    const value = data?.get(element)
+                    if (value === undefined) return
+                    return getLabel(value);
+                }
+                return
             }
-            return
         }
     }
 }

+ 25 - 16
src/mol-plugin-state/manager/loci-label.ts

@@ -11,8 +11,11 @@ import { Representation } from '../../mol-repr/representation';
 import { MarkerAction } from '../../mol-util/marker-action';
 import { arrayRemoveAtInPlace } from '../../mol-util/array';
 
-export type LociLabelEntry = JSX.Element | string
-export type LociLabelProvider = (info: Loci, repr?: Representation<any>) => LociLabelEntry | undefined
+export type LociLabel = JSX.Element | string
+export type LociLabelProvider = {
+    label: (loci: Loci, repr?: Representation<any>) => LociLabel | undefined
+    group?: (entry: LociLabel) => string
+}
 
 export class LociLabelManager {
     providers: LociLabelProvider[] = [];
@@ -43,34 +46,40 @@ export class LociLabelManager {
     }
 
     private isDirty = false
-    private entries: LociLabelEntry[] = []
-    private entriesCounts = new Map<LociLabelEntry, number>()
+    private labels: LociLabel[] = []
+    private groupedLabels = new Map<string, LociLabel[]>()
 
     private showLabels() {
-        this.ctx.behaviors.labels.highlight.next({ entries: this.getEntries() })
+        this.ctx.behaviors.labels.highlight.next({ labels: this.getLabels() })
     }
 
-    private getEntries() {
+    private getLabels() {
         if (this.isDirty) {
-            this.entriesCounts.clear()
-            this.entries.length = 0
+            this.groupedLabels.clear()
+            this.labels.length = 0
             for (const provider of this.providers) {
                 for (const loci of this.locis) {
                     if (Loci.isEmpty(loci.loci)) continue
-                    const entry = provider(loci.loci, loci.repr)
-                    if (entry) {
-                        const count = this.entriesCounts.get(entry) || 0
-                        this.entriesCounts.set(entry, count + 1)
+                    const label = provider.label(loci.loci, loci.repr)
+                    if (label) {
+                        const hash = provider.group ? provider.group(label) : label.toString()
+                        const group = this.groupedLabels.get(hash)
+                        if (group) group.push(label)
+                        else this.groupedLabels.set(hash, [label])
                     }
                 }
             }
-            this.entries.length = 0
-            this.entriesCounts.forEach((count, entry) => {
-                this.entries.push(count === 1 ? entry : `${entry} (\u00D7 ${count})`)
+            this.labels.length = 0
+            this.groupedLabels.forEach((group, hash) => {
+                const count = group.length
+                const entry = count > 1 && group[0] !== group[1]
+                    ? hash : group[0]
+
+                this.labels.push(count === 1 ? entry : `${entry} <small>|| \u00D7 ${count}</small>`)
             })
             this.isDirty = false
         }
-        return this.entries
+        return this.labels
     }
 
     constructor(public ctx: PluginContext) {

+ 6 - 6
src/mol-plugin-ui/controls.tsx

@@ -9,7 +9,7 @@ import * as React from 'react';
 import { PluginCommands } from '../mol-plugin/commands';
 import { UpdateTrajectory } from '../mol-plugin-state/actions/structure';
 import { PluginUIComponent } from './base';
-import { LociLabelEntry } from '../mol-plugin-state/manager/loci-label';
+import { LociLabel } from '../mol-plugin-state/manager/loci-label';
 import { IconButton } from './controls/common';
 import { PluginStateObject } from '../mol-plugin-state/objects';
 import { StateTransforms } from '../mol-plugin-state/transforms';
@@ -246,20 +246,20 @@ export class AnimationViewportControls extends PluginUIComponent<{}, { isEmpty:
     }
 }
 
-export class LociLabels extends PluginUIComponent<{}, { entries: ReadonlyArray<LociLabelEntry> }> {
-    state = { entries: [] }
+export class LociLabels extends PluginUIComponent<{}, { labels: ReadonlyArray<LociLabel> }> {
+    state = { labels: [] }
 
     componentDidMount() {
-        this.subscribe(this.plugin.behaviors.labels.highlight, e => this.setState({ entries: e.entries }));
+        this.subscribe(this.plugin.behaviors.labels.highlight, e => this.setState({ labels: e.labels }));
     }
 
     render() {
-        if (this.state.entries.length === 0) {
+        if (this.state.labels.length === 0) {
             return null;
         }
 
         return <div className='msp-highlight-info'>
-            {this.state.entries.map((e, i) => <div key={'' + i} dangerouslySetInnerHTML={{ __html: e }} />)}
+            {this.state.labels.map((e, i) => <div key={'' + i} dangerouslySetInnerHTML={{ __html: e }} />)}
         </div>;
     }
 }

+ 12 - 12
src/mol-plugin-ui/structure/components.tsx

@@ -165,8 +165,8 @@ class AddComponentControls extends PurePluginUIComponent<AddComponentControlsPro
     render() {
         return <>
             <ParameterControls params={this.state.params} values={this.state.values} onChangeValues={this.paramsChanged} />
-            <Button icon='plus' className='msp-btn-commit msp-btn-commit-on' onClick={this.apply} style={{ marginTop: '1px' }}>
-                Create Selection
+            <Button icon='plus' title='Use Selection and optional Representation to create a new Component.' className='msp-btn-commit msp-btn-commit-on' onClick={this.apply} style={{ marginTop: '1px' }}>
+                Create Component
             </Button>
         </>;
     }
@@ -298,7 +298,7 @@ class StructureComponentGroup extends PurePluginUIComponent<{ group: StructureCo
 
     highlight = (e: React.MouseEvent<HTMLElement>) => {
         e.preventDefault();
-        if (this.props.group[0].cell.parent) return;
+        if (!this.props.group[0].cell.parent) return;
         PluginCommands.Interactivity.Object.Highlight(this.plugin, { state: this.props.group[0].cell.parent!, ref: this.props.group.map(c => c.cell.transform.ref) });
     }
 
@@ -326,24 +326,24 @@ class StructureComponentGroup extends PurePluginUIComponent<{ group: StructureCo
         });
     }
 
-    // get reprLabel() {
-    //     // TODO: handle generic reprs.
-    //     const pivot = this.pivot;
-    //     if (pivot.representations.length === 0) return 'No repr.';
-    //     if (pivot.representations.length === 1) return pivot.representations[0].cell.obj?.label;
-    //     return `${pivot.representations.length} reprs`;
-    // }
+    get reprLabel() {
+        // TODO: handle generic reprs.
+        const pivot = this.pivot;
+        if (pivot.representations.length === 0) return 'No repr.';
+        if (pivot.representations.length === 1) return pivot.representations[0].cell.obj?.label;
+        return `${pivot.representations.length} reprs`;
+    }
 
     render() {
         const component = this.pivot;
         const cell = component.cell;
         const label = cell.obj?.label;
-        // const reprLabel = this.reprLabel;
+        const reprLabel = this.reprLabel;
         return <>
             <div className='msp-flex-row'>
                 <Button noOverflow className='msp-control-button-label' title={`${label}. Click to focus.`} onClick={this.focus} onMouseEnter={this.highlight} onMouseLeave={this.clearHighlight} style={{ textAlign: 'left' }}>
                     {label}
-                    {/* <small className='msp-25-lower-contrast-text' style={{ float: 'right' }}>{reprLabel}</small> */}
+                    <small className='msp-25-lower-contrast-text' style={{ float: 'right' }}>{reprLabel}</small>
                 </Button>
                 <IconButton onClick={this.toggleVisible} icon='visual-visibility' toggleState={!cell.state.isHidden} title={`${cell.state.isHidden ? 'Show' : 'Hide'} component`} small className='msp-form-control' flex />
                 <IconButton onClick={this.toggleRemove} icon='remove' title='Remove' small toggleState={this.state.action === 'remove'} className='msp-form-control' flex />

+ 7 - 5
src/mol-plugin/behavior/dynamic/custom-props/computed/accessible-surface-area.ts

@@ -22,9 +22,11 @@ export const AccessibleSurfaceArea = PluginBehavior.create<{ autoAttach: boolean
     ctor: class extends PluginBehavior.Handler<{ autoAttach: boolean, showTooltip: boolean }> {
         private provider = AccessibleSurfaceAreaProvider
 
-        private label = (loci: Loci): string | undefined => {
-            if (!this.params.showTooltip) return
-            return accessibleSurfaceAreaLabel(loci)
+        private labelProvider = {
+            label: (loci: Loci): string | undefined => {
+                if (!this.params.showTooltip) return
+                return accessibleSurfaceAreaLabel(loci)
+            }
         }
 
         update(p: { autoAttach: boolean, showTooltip: boolean }) {
@@ -43,7 +45,7 @@ export const AccessibleSurfaceArea = PluginBehavior.create<{ autoAttach: boolean
 
             this.ctx.customStructureProperties.register(this.provider, this.params.autoAttach);
             this.ctx.representation.structure.themes.colorThemeRegistry.add(AccessibleSurfaceAreaColorThemeProvider)
-            this.ctx.managers.lociLabels.addProvider(this.label);
+            this.ctx.managers.lociLabels.addProvider(this.labelProvider);
             this.ctx.query.structure.registry.add(isBuried)
             this.ctx.query.structure.registry.add(isAccessible)
         }
@@ -54,7 +56,7 @@ export const AccessibleSurfaceArea = PluginBehavior.create<{ autoAttach: boolean
 
             this.ctx.customStructureProperties.unregister(this.provider.descriptor.name);
             this.ctx.representation.structure.themes.colorThemeRegistry.remove(AccessibleSurfaceAreaColorThemeProvider)
-            this.ctx.managers.lociLabels.removeProvider(this.label);
+            this.ctx.managers.lociLabels.removeProvider(this.labelProvider);
             this.ctx.query.structure.registry.remove(isBuried)
             this.ctx.query.structure.registry.remove(isAccessible)
         }

+ 46 - 44
src/mol-plugin/behavior/dynamic/custom-props/computed/interactions.ts

@@ -38,51 +38,53 @@ export const Interactions = PluginBehavior.create<{ autoAttach: boolean, showToo
             return structures
         }
 
-        private label = (loci: Loci): string | undefined => {
-            if (!this.params.showTooltip) return void 0;
-
-            switch (loci.kind) {
-                case 'element-loci':
-                    if (loci.elements.length === 0) return void 0;
-
-                    const labels: string[] = []
-                    const structures = this.getStructures(loci.structure)
-
-                    for (const s of structures) {
-                        const interactions = this.provider.get(s).value
-                        if (!interactions) continue;
-
-                        const l = StructureElement.Loci.remap(loci, s)
-                        if (l.elements.length !== 1) continue
-
-                        const e = l.elements[0]
-                        if (OrderedSet.size(e.indices) !== 1) continue
-
-                        const features = interactions.unitsFeatures.get(e.unit.id)
-                        if (!features) continue;
-
-                        const typeLabels: string[] = []
-                        const groupLabels: string[] = []
-                        const label: string[] = []
-
-                        const idx = OrderedSet.start(e.indices)
-                        const { types, groups, elementsIndex: { indices, offsets } } = features
-                        for (let i = offsets[idx], il = offsets[idx + 1]; i < il; ++i) {
-                            const f = indices[i]
-                            const type = types[f]
-                            const group = groups[f]
-                            if (type) typeLabels.push(featureTypeLabel(type))
-                            if (group) groupLabels.push(featureGroupLabel(group))
+        private labelProvider = {
+            label: (loci: Loci): string | undefined => {
+                if (!this.params.showTooltip) return void 0;
+
+                switch (loci.kind) {
+                    case 'element-loci':
+                        if (loci.elements.length === 0) return void 0;
+
+                        const labels: string[] = []
+                        const structures = this.getStructures(loci.structure)
+
+                        for (const s of structures) {
+                            const interactions = this.provider.get(s).value
+                            if (!interactions) continue;
+
+                            const l = StructureElement.Loci.remap(loci, s)
+                            if (l.elements.length !== 1) continue
+
+                            const e = l.elements[0]
+                            if (OrderedSet.size(e.indices) !== 1) continue
+
+                            const features = interactions.unitsFeatures.get(e.unit.id)
+                            if (!features) continue;
+
+                            const typeLabels: string[] = []
+                            const groupLabels: string[] = []
+                            const label: string[] = []
+
+                            const idx = OrderedSet.start(e.indices)
+                            const { types, groups, elementsIndex: { indices, offsets } } = features
+                            for (let i = offsets[idx], il = offsets[idx + 1]; i < il; ++i) {
+                                const f = indices[i]
+                                const type = types[f]
+                                const group = groups[f]
+                                if (type) typeLabels.push(featureTypeLabel(type))
+                                if (group) groupLabels.push(featureGroupLabel(group))
+                            }
+
+                            if (typeLabels.length) label.push(`<small>Types</small> ${typeLabels.join(', ')}`)
+                            if (groupLabels.length) label.push(`<small>Groups</small> ${groupLabels.join(', ')}`)
+                            if (label.length) labels.push(`Interaction Feature: ${label.join(' | ')}`)
                         }
 
-                        if (typeLabels.length) label.push(`<small>Types</small> ${typeLabels.join(', ')}`)
-                        if (groupLabels.length) label.push(`<small>Groups</small> ${groupLabels.join(', ')}`)
-                        if (label.length) labels.push(`Interaction Feature: ${label.join(' | ')}`)
-                    }
+                        return labels.length ? labels.join('<br/>') : undefined;
 
-                    return labels.length ? labels.join('<br/>') : undefined;
-
-                default: return void 0;
+                    default: return void 0;
+                }
             }
         }
 
@@ -100,14 +102,14 @@ export const Interactions = PluginBehavior.create<{ autoAttach: boolean, showToo
         register(): void {
             this.ctx.customStructureProperties.register(this.provider, this.params.autoAttach);
             this.ctx.representation.structure.themes.colorThemeRegistry.add(InteractionTypeColorThemeProvider)
-            this.ctx.managers.lociLabels.addProvider(this.label);
+            this.ctx.managers.lociLabels.addProvider(this.labelProvider);
             this.ctx.representation.structure.registry.add(InteractionsRepresentationProvider)
         }
 
         unregister() {
             this.ctx.customStructureProperties.unregister(this.provider.descriptor.name);
             this.ctx.representation.structure.themes.colorThemeRegistry.remove(InteractionTypeColorThemeProvider)
-            this.ctx.managers.lociLabels.removeProvider(this.label);
+            this.ctx.managers.lociLabels.removeProvider(this.labelProvider);
             this.ctx.representation.structure.registry.remove(InteractionsRepresentationProvider)
         }
     },

+ 29 - 27
src/mol-plugin/behavior/dynamic/custom-props/computed/valence-model.ts

@@ -35,41 +35,43 @@ export const ValenceModel = PluginBehavior.create<{ autoAttach: boolean, showToo
             return structures
         }
 
-        private label = (loci: Loci): string | undefined => {
-            if (!this.params.showTooltip) return void 0;
+        private labelProvider = {
+            label: (loci: Loci): string | undefined => {
+                if (!this.params.showTooltip) return void 0;
 
-            switch (loci.kind) {
-                case 'element-loci':
-                    if (loci.elements.length === 0) return void 0;
+                switch (loci.kind) {
+                    case 'element-loci':
+                        if (loci.elements.length === 0) return void 0;
 
-                    const labels: string[] = []
-                    const structures = this.getStructures(loci.structure)
+                        const labels: string[] = []
+                        const structures = this.getStructures(loci.structure)
 
-                    for (const s of structures) {
-                        const valenceModel = this.provider.get(s).value
-                        if (!valenceModel) continue;
+                        for (const s of structures) {
+                            const valenceModel = this.provider.get(s).value
+                            if (!valenceModel) continue;
 
-                        const l = StructureElement.Loci.remap(loci, s)
-                        if (l.elements.length !== 1) continue
+                            const l = StructureElement.Loci.remap(loci, s)
+                            if (l.elements.length !== 1) continue
 
-                        const e = l.elements[0]
-                        if (OrderedSet.size(e.indices) !== 1) continue
+                            const e = l.elements[0]
+                            if (OrderedSet.size(e.indices) !== 1) continue
 
-                        const vm = valenceModel.get(e.unit.id)
-                        if (!vm) continue;
+                            const vm = valenceModel.get(e.unit.id)
+                            if (!vm) continue;
 
-                        const idx = OrderedSet.start(e.indices)
-                        const charge = vm.charge[idx]
-                        const idealGeometry = vm.idealGeometry[idx]
-                        const implicitH = vm.implicitH[idx]
-                        const totalH = vm.totalH[idx]
+                            const idx = OrderedSet.start(e.indices)
+                            const charge = vm.charge[idx]
+                            const idealGeometry = vm.idealGeometry[idx]
+                            const implicitH = vm.implicitH[idx]
+                            const totalH = vm.totalH[idx]
 
-                        labels.push(`Valence Model: <small>Charge</small> ${charge} | <small>Ideal Geometry</small> ${geometryLabel(idealGeometry)} | <small>Implicit H</small> ${implicitH} | <small>Total H</small> ${totalH}`)
-                    }
+                            labels.push(`Valence Model: <small>Charge</small> ${charge} | <small>Ideal Geometry</small> ${geometryLabel(idealGeometry)} | <small>Implicit H</small> ${implicitH} | <small>Total H</small> ${totalH}`)
+                        }
 
-                    return labels.length ? labels.join('<br/>') : undefined;
+                        return labels.length ? labels.join('<br/>') : undefined;
 
-                default: return void 0;
+                    default: return void 0;
+                }
             }
         }
 
@@ -86,12 +88,12 @@ export const ValenceModel = PluginBehavior.create<{ autoAttach: boolean, showToo
 
         register(): void {
             this.ctx.customStructureProperties.register(this.provider, this.params.autoAttach);
-            this.ctx.managers.lociLabels.addProvider(this.label);
+            this.ctx.managers.lociLabels.addProvider(this.labelProvider);
         }
 
         unregister() {
             this.ctx.customStructureProperties.unregister(this.provider.descriptor.name);
-            this.ctx.managers.lociLabels.removeProvider(this.label);
+            this.ctx.managers.lociLabels.removeProvider(this.labelProvider);
         }
     },
     params: () => ({

+ 15 - 13
src/mol-plugin/behavior/dynamic/custom-props/pdbe/structure-quality-report.ts

@@ -23,22 +23,24 @@ export const PDBeStructureQualityReport = PluginBehavior.create<{ autoAttach: bo
 
         private provider = StructureQualityReportProvider
 
-        private labelPDBeValidation = (loci: Loci): string | undefined => {
-            if (!this.params.showTooltip) return void 0;
+        private labelPDBeValidation = {
+            label: (loci: Loci): string | undefined => {
+                if (!this.params.showTooltip) return void 0;
 
-            switch (loci.kind) {
-                case 'element-loci':
-                    if (loci.elements.length === 0) return void 0;
-                    const e = loci.elements[0];
-                    const u = e.unit;
-                    if (!u.model.customProperties.hasReference(StructureQualityReportProvider.descriptor)) return void 0;
+                switch (loci.kind) {
+                    case 'element-loci':
+                        if (loci.elements.length === 0) return void 0;
+                        const e = loci.elements[0];
+                        const u = e.unit;
+                        if (!u.model.customProperties.hasReference(StructureQualityReportProvider.descriptor)) return void 0;
 
-                    const se = StructureElement.Location.create(loci.structure, u, u.elements[OrderedSet.getAt(e.indices, 0)]);
-                    const issues = StructureQualityReport.getIssues(se);
-                    if (issues.length === 0) return 'Validation: No Issues';
-                    return `Validation: ${issues.join(', ')}`;
+                        const se = StructureElement.Location.create(loci.structure, u, u.elements[OrderedSet.getAt(e.indices, 0)]);
+                        const issues = StructureQualityReport.getIssues(se);
+                        if (issues.length === 0) return 'Validation: No Issues';
+                        return `Validation: ${issues.join(', ')}`;
 
-                default: return void 0;
+                    default: return void 0;
+                }
             }
         }
 

+ 11 - 9
src/mol-plugin/behavior/dynamic/custom-props/rcsb/validation-report.ts

@@ -32,13 +32,15 @@ export const RCSBValidationReport = PluginBehavior.create<{ autoAttach: boolean,
     ctor: class extends PluginBehavior.Handler<{ autoAttach: boolean, showTooltip: boolean }> {
         private provider = ValidationReportProvider
 
-        private label = (loci: Loci): string | undefined => {
-            if (!this.params.showTooltip) return
-            return [
-                geometryQualityLabel(loci),
-                densityFitLabel(loci),
-                randomCoilIndexLabel(loci)
-            ].filter(l => !!l).join('</br>')
+        private labelProvider = {
+            label: (loci: Loci): string | undefined => {
+                if (!this.params.showTooltip) return
+                return [
+                    geometryQualityLabel(loci),
+                    densityFitLabel(loci),
+                    randomCoilIndexLabel(loci)
+                ].filter(l => !!l).join('</br>')
+            }
         }
 
         register(): void {
@@ -46,7 +48,7 @@ export const RCSBValidationReport = PluginBehavior.create<{ autoAttach: boolean,
 
             this.ctx.customModelProperties.register(this.provider, this.params.autoAttach);
 
-            this.ctx.managers.lociLabels.addProvider(this.label);
+            this.ctx.managers.lociLabels.addProvider(this.labelProvider);
 
             this.ctx.representation.structure.themes.colorThemeRegistry.add(DensityFitColorThemeProvider)
             this.ctx.representation.structure.themes.colorThemeRegistry.add(GeometryQualityColorThemeProvider)
@@ -74,7 +76,7 @@ export const RCSBValidationReport = PluginBehavior.create<{ autoAttach: boolean,
 
             this.ctx.customStructureProperties.unregister(this.provider.descriptor.name);
 
-            this.ctx.managers.lociLabels.removeProvider(this.label);
+            this.ctx.managers.lociLabels.removeProvider(this.labelProvider);
 
             this.ctx.representation.structure.themes.colorThemeRegistry.remove(DensityFitColorThemeProvider)
             this.ctx.representation.structure.themes.colorThemeRegistry.remove(GeometryQualityColorThemeProvider)

+ 5 - 1
src/mol-plugin/behavior/dynamic/representation.ts

@@ -19,6 +19,7 @@ import { EmptyLoci, Loci, isEmptyLoci } from '../../../mol-model/loci';
 import { Structure } from '../../../mol-model/structure';
 import { arrayMax } from '../../../mol-util/array';
 import { Representation } from '../../../mol-repr/representation';
+import { LociLabel } from '../../../mol-plugin-state/manager/loci-label';
 
 const B = ButtonsType
 const M = ModifiersKeys
@@ -173,7 +174,10 @@ export const DefaultLociLabelProvider = PluginBehavior.create({
     name: 'default-loci-label-provider',
     category: 'interaction',
     ctor: class implements PluginBehavior<undefined> {
-        private f = (loci: Loci) => lociLabel(loci);
+        private f = {
+            label: (loci: Loci) => lociLabel(loci),
+            group: (label: LociLabel) => label.toString().replace(/Model [0-9]+/g, 'Models')
+        };
         register() { this.ctx.managers.lociLabels.addProvider(this.f); }
         unregister() { this.ctx.managers.lociLabels.removeProvider(this.f); }
         constructor(protected ctx: PluginContext) { }

+ 2 - 2
src/mol-plugin/context.ts

@@ -18,7 +18,7 @@ import { TrajectoryFormatRegistry } from '../mol-plugin-state/formats/trajectory
 import { StructureSelectionQueryRegistry } from '../mol-plugin-state/helpers/structure-selection-query';
 import { CameraManager } from '../mol-plugin-state/manager/camera';
 import { InteractivityManager } from '../mol-plugin-state/manager/interactivity';
-import { LociLabelEntry, LociLabelManager } from '../mol-plugin-state/manager/loci-label';
+import { LociLabel, LociLabelManager } from '../mol-plugin-state/manager/loci-label';
 import { StructureComponentManager } from '../mol-plugin-state/manager/structure/component';
 import { StructureFocusManager } from '../mol-plugin-state/manager/structure/focus';
 import { StructureHierarchyManager } from '../mol-plugin-state/manager/structure/hierarchy';
@@ -99,7 +99,7 @@ export class PluginContext {
             click: this.ev.behavior<InteractivityManager.ClickEvent>({ current: Representation.Loci.Empty, modifiers: ModifiersKeys.None, buttons: 0, button: 0 })
         },
         labels: {
-            highlight: this.ev.behavior<{ entries: ReadonlyArray<LociLabelEntry> }>({ entries: [] })
+            highlight: this.ev.behavior<{ labels: ReadonlyArray<LociLabel> }>({ labels: [] })
         },
         layout: {
             leftPanelTabName: this.ev.behavior<LeftPanelTabName>('root')