Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fluid.plotter: correctly construct unique labels #412

Merged
merged 3 commits into from
Nov 16, 2023

Conversation

jamesb93
Copy link
Member

@jamesb93 jamesb93 commented Nov 6, 2023

This is something Rod found in the Max Beta and well it is certainly weird that it worked at all for so long... I think.

Old

function constructColorScheme() {
	if (labelDict) {
		const data = labelDict.get('data');
		const keys = data.getkeys();
		var uniques = new Array();

		// How many unique labels are there?
		keys.forEach(function(key) {
			var label = data.get(key);
			if (uniques.indexOf(label) == -1) {
				uniques.push(label)
			}
		})
		
		colorMap = {};
		var scheme = strChunk(_colorscheme, 6);
		uniques.sort();
		uniques.forEach(function(u, i) {
			i = i % scheme.length;
			var color = hexToRGB(scheme[i], 1.0);
			colorMap[u] = color;
		});

		// Strip any of the points from the pointColors if they have been assigned here
		keys.forEach(function(pt) {
			if (pointColors.hasOwnProperty(pt)) {
				delete pointColors[pt]
			}
		})
		
		mgraphics.redraw();
	}
}

New

function constructColorScheme() {
	if (labelDict) {
		var labelDictAsJson = JSON.parse(labelDict.stringify());
		var data = labelDictAsJson.data;
		var keys = Object.keys(data)
		var uniques = []

		// How many unique labels are there?
		keys.forEach(function(key) {
			var label = data[key]
			if (uniques.indexOf(label) == -1) {
				uniques.push(parseInt(label[0]))
			}
		})
		uniques = uniques.removeDuplicates()
		uniques.sort();

		var scheme = strChunk(_colorscheme, 6);
		colorMap = {}
		colorMap = uniques.reduce(function (map, u, i) {
			const color = hexToRGB(scheme[i % scheme.length], 1.0);
			map[u] = color;
			return map;
		}, {});

		// Strip any of the points from the pointColors if they have been assigned here
		keys.forEach(function(pt) {
			if (pointColors.hasOwnProperty(pt)) {
				delete pointColors[pt]
			}
		})
		
		mgraphics.redraw();
	}
}

Array.prototype.removeDuplicates = function() {
	var uniqueArray = [];
	for (var i = 0; i < this.length; i++) {
		if (uniqueArray.indexOf(this[i]) === -1) {
			uniqueArray.push(this[i]);
		}
	}
	return uniqueArray;
};

At first I suspected maybe I was treating dictionaries incorrectly (with .get() and friends) but that was quickly snuffed out when I changed everything to use JSON representations (and found it to produce exactly the same behaviour). I then stepped through the code manually with a small test case and was intrigued why the programmer (💀) initially wrote this bit of code...

		// How many unique labels are there?
		keys.forEach(function(key) {
			var label = data.get(key);
			if (uniques.indexOf(label) == -1) {
				uniques.push(label)
			}
		})

label is not a number or a string as I assumed it to be but is rather an object... Thus the sorting, sort of works accidentally in most cases but also there are duplicate uniques 🤦. When you get to constructing the colour map you are iterating over the colours and replacing them because the index is not necessarily any more tied to the instance of when the loop has first seen a colour. Durp.

@jamesb93 jamesb93 requested a review from weefuzzy November 6, 2023 12:02
@jamesb93 jamesb93 self-assigned this Nov 6, 2023
@jamesb93 jamesb93 added bug Something isn't working high priority this feels like it needs to be fixed sooner rather than later labels Nov 6, 2023
@jamesb93 jamesb93 added this to the 1.1 milestone Nov 6, 2023
@jamesb93 jamesb93 requested a review from tremblap November 6, 2023 12:02
@jamesb93 jamesb93 marked this pull request as ready for review November 6, 2023 12:03
Copy link
Member

@tremblap tremblap left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

there is a line I don't understand why it is there?


colorMap = {};
var scheme = strChunk(_colorscheme, 6);
uniques = uniques.removeDuplicates()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why do we need to run this here? the keys.forEach is not supposed to add anything that is found, right?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In theory you should not need it, but it makes for a good guard against the original problem emerging.

It is very cheap to run so I would opt to just keep it, even though it is redundant.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually yeah looking at that its very meaningless to put this into an array prototype function.

I did update the check to actually work, which is why I think I needed the removal of duplicates: a2f90e0

@tremblap
Copy link
Member

indeed high priority. I've removed the code that is redundant since the first iteration does not allow for duplicates. Please test on your side and let me know if that works as intended.

@jamesb93
Copy link
Member Author

I'll test again and then get back to you :)

@jamesb93 jamesb93 merged commit 30dc8b1 into main Nov 16, 2023
@tremblap tremblap deleted the fix/plotter-label-parsing branch February 29, 2024 10:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working high priority this feels like it needs to be fixed sooner rather than later
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants