Browse Source

Issue #643: region color can also be provided by CSS class's fill property

cycle20 1 year ago
parent
commit
10756128fc
2 changed files with 124 additions and 4 deletions
  1. 83 2
      src/apps/viewer/index.html
  2. 41 2
      src/apps/viewer/index.ts

File diff suppressed because it is too large
+ 83 - 2
src/apps/viewer/index.html


+ 41 - 2
src/apps/viewer/index.ts

@@ -78,8 +78,10 @@ export class Viewer {
     ////////////////////////////// UNITMP VIEWER PROTOTYPING SECTION
 
     private surfaceResidues: number[];
+    private regionColorMap = new Map();
 
     async loadWithUNITMPMembraneRepresentation(url: string, regionDescriptors: any) {
+        this.loadRegionColorsFromStyleSheets();
         this.surfaceResidues = regionDescriptors['surface_residues'] as number[];
 
         const membraneNormal: Vec3 = Vec3.fromObj(
@@ -145,7 +147,7 @@ export class Viewer {
 
     private createRegionRepresentation(chain: string, region: any, update: StateBuilder.To<any, any>) {
         const regionLabel: string = `${chain} | ${region.name}`;
-        const color: Color = Color.fromArray(region.color, 0);
+        const color: Color = this.getRegionColor(region);
         const query: Expression = this.getQuery(chain, region.auth_ids as number[]);
 
         // based on https://github.com/molstar/molstar/issues/209
@@ -158,6 +160,16 @@ export class Viewer {
         this.indicateSurfaceResidues(this.surfaceResidues, update);
     }
 
+    private getRegionColor(region: any): Color {
+        let color: Color = Color.fromRgb(0, 0, 0); // default is black
+        if (region.class && this.regionColorMap.has(region.class)) {
+            color = this.regionColorMap.get(region.class);
+        } else if (region.color) {
+            color = Color.fromArray(region.color, 0);
+        }
+        return color;
+    }
+
     private getQuery(chainId: string, auth_array: number[]): Expression {
         const query: Expression =
             MS.struct.generator.atomGroups({
@@ -168,7 +180,7 @@ export class Viewer {
     }
 
     public indicateSurfaceResidues(residues: number[], update: StateBuilder.To<any, any>) {
-        if (residues.length == 0) {
+        if (!residues || residues.length == 0) {
             // nothing to do
             return;
         }
@@ -227,6 +239,33 @@ export class Viewer {
         //requestAnimationFrame(() => this.plugin.canvas3d?.requestCameraReset({ snapshot: newSnapshot }));
     }
 
+    private loadRegionColorsFromStyleSheets(prefix: string = 'ult_'): void {
+        const sheets: CSSStyleSheet[] = Array.from(document.styleSheets);
+        sheets.forEach((sheet: CSSStyleSheet) => {
+            const rules: CSSRule[] = Array.from(sheet.cssRules);
+            rules.forEach((rule: CSSRule) => this.fetchRule(rule, prefix));
+        });
+    }
+
+    private fetchRule(rule: CSSRule, prefix: string) {
+        let styleRule = rule as CSSStyleRule;
+        if (styleRule.selectorText?.startsWith('.' + prefix)) {
+            const value = styleRule.style.getPropertyValue('fill');
+            const color: Color = this.getStyleColor(value);
+            const key = styleRule.selectorText.slice(1);
+            this.regionColorMap.set(key, color);
+        }
+    }
+
+    private getStyleColor(cssColorText: string): Color {
+        const values = cssColorText?.match(/\d+/g);
+        let intValues = values?.map(value => parseInt(value));
+        if (!intValues) {
+            intValues = [ 0, 0, 0 ];
+        }
+        return Color.fromArray(intValues, 0);
+    }
+
     ////////////////////////////// END OF PROTOTYPING SECTION
 
 

Some files were not shown because too many files changed in this diff