diff --git a/src/lib/common/utils.ts b/src/lib/common/utils.ts
index 899eea84..e76d6e91 100644
--- a/src/lib/common/utils.ts
+++ b/src/lib/common/utils.ts
@@ -225,6 +225,30 @@ export function isValueTypeOfArray(value: any) {
return retVal;
}
+/** are all values in one array present in the comparison array with no extra members
+ * present in either.
+*/
+export function areArrayMembersEqual(value1: any[], value2: any[]) {
+ let _tempArr1ValsMap = new Map( (value1 as unknown as string[]).map((val) => { return [val.toString(), val]; }));
+ let _tempAllValsMap = new Map(_tempArr1ValsMap);
+ // add existing entityId's to hashmap
+ if(value2 && value2.forEach) {
+ value2.forEach((value) => {
+ _tempAllValsMap.set(value as string, value);
+ });
+ // now remove all entity id's that are identical to the values in input values
+ // if there is a remaining value then the id sets are different
+ if((value1 as unknown as string[]) && (value1 as unknown as string[]).forEach) {
+ (value1 as unknown as string[]).forEach((valStr) => {
+ if(_tempAllValsMap.has(valStr.toString())) { _tempAllValsMap.delete(valStr.toString()); }
+ });
+ }
+
+ }
+ let noRemainder = _tempAllValsMap.size <= 0;
+ return noRemainder;
+}
+
export function interpolateTemplate(template, args) {
return Object.entries(args).reduce(
(result, [arg, val]) => result.replace(`$\{${arg}}`, `${val}`),
diff --git a/src/lib/graph/sz-graph-filter.component.html b/src/lib/graph/sz-graph-filter.component.html
index 5ab04bbd..80c17e11 100644
--- a/src/lib/graph/sz-graph-filter.component.html
+++ b/src/lib/graph/sz-graph-filter.component.html
@@ -163,7 +163,6 @@
{{ sectionTitles[4] }}
Active/Focused Enitity
The color of the current entity or entities
- (*note overrides datasource member color if selected)
diff --git a/src/lib/graph/sz-graph-filter.component.ts b/src/lib/graph/sz-graph-filter.component.ts
index 1da30fc0..fcf1f2a0 100644
--- a/src/lib/graph/sz-graph-filter.component.ts
+++ b/src/lib/graph/sz-graph-filter.component.ts
@@ -206,7 +206,7 @@ export class SzGraphFilterComponent implements OnInit, AfterViewInit, OnDestroy
// assume it's already cast correctly
this._matchKeyTokenSelectionScope = (value as SzMatchKeyTokenFilterScope);
}
- console.log(`@senzing/sdk-components-ng/sz-graph-filter.matchKeyTokenSelectionScope(${value} | ${(this._matchKeyTokenSelectionScope as unknown as string)})`, this._matchKeyTokenSelectionScope);
+ //console.log(`@senzing/sdk-components-ng/sz-graph-filter.matchKeyTokenSelectionScope(${value} | ${(this._matchKeyTokenSelectionScope as unknown as string)})`, this._matchKeyTokenSelectionScope);
}
/**
* get the value of match key token filterings scope. possible values are
@@ -225,7 +225,7 @@ export class SzGraphFilterComponent implements OnInit, AfterViewInit, OnDestroy
private _showCoreMatchKeyTokenChips: boolean = false;
@Input() public set showCoreMatchKeyTokenChips(value: boolean) {
this._showCoreMatchKeyTokenChips = value;
- console.log(`@senzing/sdk-components-ng/sz-graph-filter.showCoreMatchKeyTokenChips(${value})`, this._showCoreMatchKeyTokenChips);
+ //console.log(`@senzing/sdk-components-ng/sz-graph-filter.showCoreMatchKeyTokenChips(${value})`, this._showCoreMatchKeyTokenChips);
}
public get showCoreMatchKeyTokenChips(): boolean {
return this._showCoreMatchKeyTokenChips;
@@ -582,19 +582,36 @@ export class SzGraphFilterComponent implements OnInit, AfterViewInit, OnDestroy
}
/** handler for when a color value for a source in the "colorsByDataSourcesForm" has changed */
onDsColorChange(dsValue: string, src?: any, evt?) {
+ // first check if color is 000 or fff
+ // if so this is a remove not an update
+ let _isRemoveOp = false;
+ //console.log(`changed color for "${dsValue}" to "${src.value}"`);
+ if(['#ffffff','#000000'].includes(src.value)) {
+ _isRemoveOp = true;
+ }
// update color value in array
if(this._dataSources) {
let _dsIndex = this._dataSources.findIndex((dsVal: SzDataSourceComposite) => {
return dsVal.name === dsValue;
});
if(_dsIndex && this._dataSources && this._dataSources[ _dsIndex ]) {
- this._dataSources[ _dsIndex ].color = src.value;
+ if(_isRemoveOp) {
+ this._dataSources[ _dsIndex ].color = undefined;
+ //delete this._dataSources[ _dsIndex ].color;
+ } else {
+ this._dataSources[ _dsIndex ].color = src.value;
+ }
}
}
// update color swatch bg color(for prettier boxes)
if(src && src.style && src.style.setProperty){
- src.style.setProperty('background-color', src.value);
+ if(_isRemoveOp) {
+ src.style.removeProperty('background-color');
+ } else {
+ src.style.setProperty('background-color', src.value);
+ }
}
+
// update colors pref
if( this.prefs && this.prefs.graph) {
// there is some sort of mem reference clone issue
diff --git a/src/lib/graph/sz-graph.component.ts b/src/lib/graph/sz-graph.component.ts
index 141cfaad..a879891e 100644
--- a/src/lib/graph/sz-graph.component.ts
+++ b/src/lib/graph/sz-graph.component.ts
@@ -896,7 +896,8 @@ export class SzGraphComponent implements OnInit, OnDestroy {
/** proxy handler for when prefs have changed externally */
private onPrefsChange(prefs: SzGraphPrefs) {
//console.log('@senzing/sdk-components-ng/sz-graph-component.onPrefsChange(): ', prefs, this.prefs.graph.toJSONObject());
- let queryParamChanged = false;
+ let queryParamChanged = false;
+ let queryParametersChanged = [];
let _oldQueryParams = {maxDegrees: this.maxDegrees, maxEntities: this.maxEntities, buildOut: this.buildOut, unlimitedMaxEntities: this.unlimitedMaxEntities, unlimitedMaxScope: this.unlimitedMaxScope};
let _newQueryParams = {maxDegrees: prefs.maxDegreesOfSeparation, maxEntities: prefs.maxEntities, buildOut: prefs.buildOut, unlimitedMaxEntities: prefs.unlimitedMaxEntities, unlimitedMaxScope: prefs.unlimitedMaxScope};
if(
@@ -910,8 +911,23 @@ export class SzGraphComponent implements OnInit, OnDestroy {
!this.unlimitedMaxEntities
)
) ||
- this.buildOut != prefs.buildOut
+ (this.buildOut != prefs.buildOut && !prefs.unlimitedMaxScope)
){
+ if(this.maxDegrees != prefs.maxDegreesOfSeparation) {
+ queryParametersChanged.push('maxDegrees');
+ }
+ if(this.maxEntities != prefs.maxEntities && ((this.unlimitedMaxEntities != prefs.unlimitedMaxEntities) || !this.unlimitedMaxEntities)) {
+ queryParametersChanged.push('maxEntities');
+ }
+ if(this.unlimitedMaxEntities != prefs.unlimitedMaxEntities) {
+ queryParametersChanged.push('unlimitedMaxEntities');
+ }
+ if(this.graphNetworkComponent && this.graphNetworkComponent.noMaxEntitiesLimit != prefs.unlimitedMaxEntities) {
+ queryParametersChanged.push('noMaxEntitiesLimit');
+ }
+ if(this.buildOut != prefs.buildOut && !prefs.unlimitedMaxScope) {
+ queryParametersChanged.push(`buildOut`);
+ }
// only params that factor in to the API call
// should trigger full redraw
queryParamChanged = true;
@@ -947,21 +963,25 @@ export class SzGraphComponent implements OnInit, OnDestroy {
}
if(prefs.dataSourceColors && prefs.dataSourceColors.sort) {
let sorted = Array.from(prefs.dataSourceColors)
- .filter((dsColorEntry: SzDataSourceComposite) => {
- return dsColorEntry.color !== undefined;
- })
.sort((dsColorEntry1: SzDataSourceComposite, dsColorEntry2: SzDataSourceComposite) => {
let retVal = dsColorEntry1.index > dsColorEntry2.index ? -1 : (dsColorEntry1.index < dsColorEntry2.index) ? 1 : 0 ;
return retVal;
})
.forEach((dsColorEntry: SzDataSourceComposite) => {
- this.graphContainerEle.nativeElement.style.setProperty(
- `--sz-graph-node-ds-${dsColorEntry.name.toLowerCase()}-fill`,
- dsColorEntry.color
- );
- //this.cssClassesService.setStyle(`.sz-node-ds-${dsColorEntry.name.toLowerCase()}`, "fill", dsColorEntry.color);
- this.cssClassesService.setStyle(`body .sz-relationship-network-graph .sz-node-ds-${dsColorEntry.name.toLowerCase()} .sz-graph-node-icon .sz-node-ds-${dsColorEntry.name.toLowerCase()}-fill`, "fill", `var(--sz-graph-node-ds-${dsColorEntry.name.toLowerCase()}-fill)`);
- this.cssClassesService.setStyle(`body .sz-relationship-network-graph .sz-node-ds-${dsColorEntry.name.toLowerCase()} .sz-graph-node-icon .sz-graph-node-icon-fill`, "fill", `var(--sz-graph-node-ds-${dsColorEntry.name.toLowerCase()}-fill)`);
+ if(dsColorEntry.color !== undefined) {
+ this.graphContainerEle.nativeElement.style.setProperty(
+ `--sz-graph-node-ds-${dsColorEntry.name.toLowerCase()}-fill`,
+ dsColorEntry.color
+ );
+ //this.cssClassesService.setStyle(`.sz-node-ds-${dsColorEntry.name.toLowerCase()}`, "fill", dsColorEntry.color);
+ this.cssClassesService.setStyle(`body .sz-relationship-network-graph .sz-node-ds-${dsColorEntry.name.toLowerCase()} .sz-graph-node-icon .sz-node-ds-${dsColorEntry.name.toLowerCase()}-fill`, "fill", `var(--sz-graph-node-ds-${dsColorEntry.name.toLowerCase()}-fill)`);
+ this.cssClassesService.setStyle(`body .sz-relationship-network-graph .sz-node-ds-${dsColorEntry.name.toLowerCase()} .sz-graph-node-icon .sz-graph-node-icon-fill`, "fill", `var(--sz-graph-node-ds-${dsColorEntry.name.toLowerCase()}-fill)`);
+ } else {
+ // try removing value of variable so we can unset any previous values
+ this.graphContainerEle.nativeElement.style.removeProperty(`--sz-graph-node-ds-${dsColorEntry.name.toLowerCase()}-fill`);
+ this.cssClassesService.removeStyle(`body .sz-relationship-network-graph .sz-node-ds-${dsColorEntry.name.toLowerCase()} .sz-graph-node-icon .sz-node-ds-${dsColorEntry.name.toLowerCase()}-fill`, "fill");
+ this.cssClassesService.removeStyle(`body .sz-relationship-network-graph .sz-node-ds-${dsColorEntry.name.toLowerCase()} .sz-graph-node-icon .sz-graph-node-icon-fill`, "fill");
+ }
})
}
}
@@ -990,11 +1010,21 @@ export class SzGraphComponent implements OnInit, OnDestroy {
}
if(this.graphNetworkComponent && queryParamChanged) {
// update graph with new properties
- this.graphNetworkComponent.maxDegrees = this.maxDegrees;
- this.graphNetworkComponent.maxEntities = this.maxEntities;
- this.graphNetworkComponent.buildOut = this.buildOut;
- this.graphNetworkComponent.noMaxEntitiesLimit = this.unlimitedMaxEntities;
- this.graphNetworkComponent.noMaxScopeLimit = this.unlimitedMaxScope;
+ if(queryParametersChanged.includes('maxDegrees')){
+ this.graphNetworkComponent.maxDegrees = this.maxDegrees;
+ }
+ if(queryParametersChanged.includes('maxEntities')){
+ this.graphNetworkComponent.maxEntities = this.maxEntities;
+ }
+ if(queryParametersChanged.includes('buildOut')){
+ this.graphNetworkComponent.buildOut = this.buildOut;
+ }
+ if(queryParametersChanged.includes('unlimitedMaxEntities')){
+ this.graphNetworkComponent.noMaxEntitiesLimit = this.unlimitedMaxEntities;
+ }
+ if(queryParametersChanged.includes('unlimitedMaxScope')){
+ this.graphNetworkComponent.noMaxScopeLimit = this.unlimitedMaxScope;
+ }
if(this._graphComponentRendered){
console.log('re-rendering graph');
this.reload( this._graphIds );
@@ -1092,12 +1122,12 @@ export class SzGraphComponent implements OnInit, OnDestroy {
const _ret = this.entityNodecolorsByDataSource;
if( this.queriedEntitiesColor && this.queriedEntitiesColor !== undefined && this.queriedEntitiesColor !== null){
// add special color for active/primary nodes
- _ret.push( {
+ /* _ret.push( {
selectorFn: this.isEntityNodeInQuery.bind(this),
modifierFn: this.setEntityNodeFillColor.bind(this, this.queriedEntitiesColor),
selectorArgs: this.graphIds,
modifierArgs: this.queriedEntitiesColor
- } );
+ } );*/
}
return _ret;
}
diff --git a/src/lib/graph/sz-relationship-network/sz-relationship-network.component.ts b/src/lib/graph/sz-relationship-network/sz-relationship-network.component.ts
index f9103ffc..82a4d230 100644
--- a/src/lib/graph/sz-relationship-network/sz-relationship-network.component.ts
+++ b/src/lib/graph/sz-relationship-network/sz-relationship-network.component.ts
@@ -18,7 +18,7 @@ import {
} from '@senzing/rest-api-client-ng';
import { map, tap, first, takeUntil, take, filter } from 'rxjs/operators';
import { Subject, Observable, BehaviorSubject, forkJoin } from 'rxjs';
-import { parseSzIdentifier, parseBool, isValueTypeOfArray } from '../../common/utils';
+import { parseSzIdentifier, parseBool, isValueTypeOfArray, areArrayMembersEqual } from '../../common/utils';
import { SzNetworkGraphInputs, SzGraphTooltipEntityModel, SzGraphTooltipLinkModel, SzGraphNodeFilterPair, SzEntityNetworkMatchKeyTokens } from '../../../lib/models/graph';
import { SzSearchService } from '../../services/sz-search.service';
@@ -426,12 +426,15 @@ export class SzRelationshipNetworkComponent implements AfterViewInit, OnDestroy
this._entityIds = [ value.toString() ];
} else if(value && isValueTypeOfArray(value)) {
// passed string[] or number[].
- // we need to always convert to "string[]" or else the
- // result wont be what we expect
- let _tempArr = (value as unknown as string[]).map((val) => { return val.toString(); });
- _changed = this._entityIds != _tempArr;
- this._entityIds = _tempArr;
- //console.log(`entityIds = ${value}(any[]) | ${_changed}`, this._entityIds, value, (value as unknown as []));
+ _changed = !areArrayMembersEqual((value as unknown as string[]), this._entityIds);
+ this._entityIds = (value as unknown as string[]).map((val) => { return val.toString(); });
+
+ /*console.log(`entityIds = ${value}(any[]) | ${_changed} from "${_oldIds && _oldIds.join ? _oldIds.join(',') : ''}"`,
+ _oldIds,
+ this._entityIds,
+ new Map( (value as unknown as string[]).map((val) => { return [val.toString(), val]; })),
+ (value as unknown as [])
+ );*/
} else if(value) {
// unknown type of value
// I guess we just.... guess??
@@ -444,7 +447,7 @@ export class SzRelationshipNetworkComponent implements AfterViewInit, OnDestroy
return this._focalEntities.indexOf(parseSzIdentifier(eId)) <= -1;
}).map(parseSzIdentifier) : [];
this._focalEntities = this._focalEntities.concat(uniqueEntityIds);
- if(this.reloadOnIdChange && this._entityIds && this._entityIds.some( (eId) => { return _oldIds && _oldIds.indexOf(eId) < 0; })) {
+ if(this.reloadOnIdChange && _changed && this._entityIds && this._entityIds.some( (eId) => { return _oldIds && _oldIds.indexOf(eId) < 0; })) {
this.reload( this._entityIds.map((eId) => { return parseInt(eId); }) );
}
//console.log('sdk-graph-components/sz-relationship-network.component: entityIds setter( '+_changed+' )', this._entityIds);
diff --git a/src/lib/scss/graph.scss b/src/lib/scss/graph.scss
index 6a1350c2..6e2015d8 100644
--- a/src/lib/scss/graph.scss
+++ b/src/lib/scss/graph.scss
@@ -130,6 +130,12 @@ body {
fill: var(--sz-graph-node-icon-color);
}
+ &.sz-graph-primary-node {
+ .sz-graph-icon-enclosure {
+ fill: var(--sz-graph-primary-entity-color);
+ }
+ }
+
&.graph-node-rel-primary {
.sz-graph-node-icon-colored {
fill: var(--sz-graph-node-icon-color);
diff --git a/src/lib/services/sz-css-class.service.ts b/src/lib/services/sz-css-class.service.ts
index 7af9891c..e971cb9a 100644
--- a/src/lib/services/sz-css-class.service.ts
+++ b/src/lib/services/sz-css-class.service.ts
@@ -65,7 +65,7 @@ export class SzCSSClassService {
this.headElement.appendChild(cssEle);
return cssEle.sheet as CSSStyleSheet;
}
- /** dynamicall set/create a css class and it's values */
+ /** dynamically set/create a css class and it's values */
public setStyle(selectorText: string, styleName: string, value: string): void {
let rules: CSSRuleList = this.styleSheet.cssRules.length > 0 || this.styleSheet.rules.length == 0 ? this.styleSheet.cssRules : this.styleSheet.rules;
let ruleIndex: number = Array.from(rules).findIndex(r => r instanceof CSSStyleRule && r.selectorText.toLowerCase() == selectorText.toLowerCase());
@@ -78,10 +78,27 @@ export class SzCSSClassService {
let newRuleIndex = this.styleSheet.insertRule(selectorText + `{ ${styleName}: ${value}}`, rules.length);
return;
} else {
- this.styleSheet.deleteRule(ruleIndex);
+ if(ruleIndex >= 0) {
+ this.styleSheet.deleteRule(ruleIndex);
+ }
this.styleSheet.insertRule(selectorText + `{ ${styleName}: ${value}}`, rules.length);
}
}
+ /** dynamically remove a css class by selector and */
+ public removeStyle(selectorText: string, styleName?: string) {
+ if(!this.styleSheet){ return; }
+ let rules: CSSRuleList = this.styleSheet.cssRules.length > 0 || this.styleSheet.rules.length == 0 ? this.styleSheet.cssRules : this.styleSheet.rules;
+ let ruleIndex: number = Array.from(rules).findIndex(r => r instanceof CSSStyleRule && r.selectorText.toLowerCase() == selectorText.toLowerCase());
+ if(ruleIndex >= 0){
+ //try{
+ if(!styleName) {
+ this.styleSheet.deleteRule(ruleIndex);
+ } else {
+ (this.styleSheet.cssRules[ruleIndex] as CSSStyleRule).style.removeProperty(styleName);
+ }
+ //} catch(err) {}
+ }
+ }
/** dynamically set a css variable on the body element */
public setVariable(variableName: string, value: string) {
if(this.bodyElement && this.bodyElement.style && this.bodyElement.style.setProperty) {