-
AnalysisStyle on multiple Decorators turns blackDescriptionI am new to the iTwin Platform and React. I started with the code in the Scientific Visualization Sample and encountered problems with multiple decorators. When visualizing more than one decorator, only the last decorator in the array has the correct The data in the JSON file follows the predefined structure. According to the console, the I am using an iTwin with an iModel not the sandbox. How should I handle React state when assigning multiple ExpectedI expected all decorators to have the correct ImagesImage 1 - Current Result Image 2 - Image 3 - Expected CodeScientificVizWidget.tsx //...
const initializeDecorator = useCallback(async () => {
if (!viewport) return;
if (ScientificVizDecorator.decorator) {
ScientificVizApi.setAnalysisStyle(viewport, undefined);
ScientificVizDecorator.decorator.dispose();
}
let polyfaces = await ScientificVizApi.createAllBuildings();
for (const polyface of polyfaces) {
ScientificVizDecorator.decorator = new ScientificVizDecorator(
viewport,
polyface
);
const thematicChannelNames = [
...getChannelsByType(polyface, AuxChannelDataType.Scalar).map(
(c) => c.name!
),
];
let defaultThematicChannel: string = "Lden";
setThematicChannelData({
currentChannelName: defaultThematicChannel,
channelNames: thematicChannelNames,
});
}
}, [viewport]);
//...
useEffect(() => {
if (!viewport || !ScientificVizDecorator.decorator) {
return;
}
const polyface = ScientificVizDecorator.decorator.polyface;
const thematicChannel = polyface.data.auxData?.channels.find(
(c) => thematicChannelData.currentChannelName === c.name
);
if (!thematicChannel) return;
const mapScalarToColor = (scalarValue: number): ColorDef => {
const colorRanges: [number, ColorDef][] = [
// Color definition
];
for (const [threshold, color] of colorRanges) {
if (scalarValue > threshold) {
return color;
}
}
return ColorDef.from(183, 206, 142); // Default color as ColorDef
};
let minScalar = Number.MAX_VALUE;
let maxScalar = Number.MIN_VALUE;
const mappings: Gradient.KeyColorProps[][] = [];
for (const dataElement of thematicChannel.data) {
const minValue = Math.min(...dataElement.values);
const maxValue = Math.max(...dataElement.values);
minScalar = Math.min(minScalar, minValue);
maxScalar = Math.max(maxScalar, maxValue);
const mapping: Gradient.KeyColorProps[] = new Array(256)
.fill(0)
.map((_, i) => {
const normalizedValue = i / 255;
const scalarValue =
minScalar + normalizedValue * (maxScalar - minScalar);
const colorDef = mapScalarToColor(scalarValue);
return {
value: normalizedValue,
color: colorDef.tbgr,
};
});
mappings.push(mapping);
}
for (const mapping of mappings) {
const thematicSettings: ThematicGradientSettingsProps = {
colorScheme: ThematicGradientColorScheme.Custom,
customKeys: mapping,
mode: ThematicGradientMode.Stepped,
stepCount: mapping.length,
};
const analysisStyle = ScientificVizApi.createAnalysisStyleForChannels(
thematicChannel,
thematicSettings
);
ScientificVizApi.setAnalysisStyle(viewport, analysisStyle);
setIsAnimated(false);
setCanBeAnimated(ScientificVizApi.styleSupportsAnimation(analysisStyle));
}
}, [viewport, thematicChannelData]);
//... ScientificVizApi.ts //...
export default class ScientificVizApi {
public static async createBuilding(buildingId: string): Promise<Polyface> {
const buildingData = (
jsonBuildings as Record<
string,
{
indexedMesh: {
auxData: {
channels: {
dataType: number;
inputName: string;
name: string;
data: { input: number; values: number[] }[];
}[];
indices: number[];
};
point: number[][];
pointIndex: number[];
};
}
>
)[buildingId];
const jsonString = JSON.stringify(buildingData);
const polyBuilding = IModelJson.Reader.parse(
JSON.parse(jsonString)
) as Polyface;
return polyBuilding;
}
public static async createAllBuildings(): Promise<Polyface[]> {
const buildingIds = Object.keys(jsonBuildings);
const polyfaces: Polyface[] = [];
for (const buildingId of buildingIds) {
const polyface = await this.createBuilding(buildingId);
if (polyface) {
polyfaces.push(polyface);
}
}
return polyfaces;
}
//... |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 3 replies
-
Hi, If you want in-depth debugging/diagnosis of your code, please narrow it down to a simple sandbox that illustrates the problem. A quick perusal of the snippets of code you provided suggest that you are basing the range of your gradient on the min+max values of a single polyface, then applying the analysis style to all of your polyfaces, causing values outside of that min+max range to display using the gradient's margin color. A view only has one AnalysisStyle at a time, applied to all of its contents. It's unclear to me from your code and screenshots what real-world data you're actually trying to visualize - maybe your example is just a prototype to help you work out how to do something real? Knowing the details of what you're trying to achieve (from a user perspective) will help. |
Beta Was this translation helpful? Give feedback.
-
I've experimented with treating all buildings as one polyface and applying a single Ideally, I intended to have multiple polyfaces in the viewport with their own The current behavior is one polyface, one In conclusion, while I obtained a satisfactory visualization by treating all buildings as one polyface, the current behavior does not align with my original goal of having multiple polyfaces with their own Thank you for your guidance. |
Beta Was this translation helpful? Give feedback.
Hi,
If you want in-depth debugging/diagnosis of your code, please narrow it down to a simple sandbox that illustrates the problem.
A quick perusal of the snippets of code you provided suggest that you are basing the range of your gradient on the min+max values of a single polyface, then applying the analysis style to all of your polyfaces, causing values outside of that min+max range to display using the gradient's margin color.
You can test this hypothesis by altering the margin color.
A view only has one AnalysisStyle at a time, applied to all of its contents. It's unclear to me from your code and screenshots what real-world data you're actually trying to visualize - maybe your example …