Backport 6.x tagcloud hashcode (#17642)

* Change hashing algo of tagcloud rotations (#17597)

pulls in TimR's changes (#17594) to the hashing algorithm. This also replaces the reference screenshots to match the new rotations.

* Revert screenshot comparison tests to old threshold parameters (#17626)

Applies to Tagcloud. https://github.com/elastic/kibana/pull/17597 made them too strict, causing them to fail in CI.
This commit is contained in:
Thomas Neirynck 2018-04-11 10:30:00 -04:00 committed by GitHub
parent e83388fd3e
commit d9c72db7a7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 26 additions and 27 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9 KiB

After

Width:  |  Height:  |  Size: 8.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.4 KiB

After

Width:  |  Height:  |  Size: 10 KiB

View file

@ -390,7 +390,7 @@ describe('tag cloud tests', function () {
});
it('should test', async function () {
it('should render simple image', async function () {
tagCloud = new TagCloud(domNode);
tagCloud.setData(baseTest.data);

View file

@ -65,6 +65,7 @@ describe('TagCloudVisualizationTest', function () {
it('simple draw', async function () {
const tagcloudVisualization = new TagCloudVisualization(domNode, vis);
await tagcloudVisualization.render(dummyTableGroup, {
resize: false,
params: true,
@ -72,7 +73,9 @@ describe('TagCloudVisualizationTest', function () {
data: true,
uiState: false
});
const mismatchedPixels = await imageComparator.compareDOMContents(domNode.innerHTML, 512, 512, basicdrawPng, THRESHOLD);
const svgNode = domNode.querySelector('svg');
const mismatchedPixels = await imageComparator.compareDOMContents(svgNode.outerHTML, 512, 512, basicdrawPng, THRESHOLD);
expect(mismatchedPixels).to.be.lessThan(PIXEL_DIFF);
});
@ -97,14 +100,13 @@ describe('TagCloudVisualizationTest', function () {
uiState: false
});
const mismatchedPixels = await imageComparator.compareDOMContents(domNode.innerHTML, 256, 368, afterresizePng, THRESHOLD);
const svgNode = domNode.querySelector('svg');
const mismatchedPixels = await imageComparator.compareDOMContents(svgNode.outerHTML, 256, 368, afterresizePng, THRESHOLD);
expect(mismatchedPixels).to.be.lessThan(PIXEL_DIFF);
});
it('with param change', async function () {
const tagcloudVisualization = new TagCloudVisualization(domNode, vis);
await tagcloudVisualization.render(dummyTableGroup, {
resize: false,
@ -126,8 +128,8 @@ describe('TagCloudVisualizationTest', function () {
uiState: false
});
const mismatchedPixels = await imageComparator.compareDOMContents(domNode.innerHTML, 256, 368, afterparamChange, THRESHOLD);
const svgNode = domNode.querySelector('svg');
const mismatchedPixels = await imageComparator.compareDOMContents(svgNode.outerHTML, 256, 368, afterparamChange, THRESHOLD);
expect(mismatchedPixels).to.be.lessThan(PIXEL_DIFF);
});

View file

@ -6,11 +6,10 @@ import { EventEmitter } from 'events';
const ORIENTATIONS = {
'single': () => 0,
'right angled': (tag) => {
return hashCode(tag.text) % 2 * 90;
return hashWithinRange(tag.text, 2) * 90;
},
'multiple': (tag) => {
const hashcode = Math.abs(hashCode(tag.text));
return ((hashcode % 12) * 15) - 90;//fan out 12 * 15 degrees over top-right and bottom-right quadrant (=-90 deg offset)
return ((hashWithinRange(tag.text, 12)) * 15) - 90;//fan out 12 * 15 degrees over top-right and bottom-right quadrant (=-90 deg offset)
}
};
const D3_SCALING_FUNCTIONS = {
@ -397,23 +396,13 @@ function getFill(tag) {
return colorScale(tag.text);
}
/**
* Hash a string to a number. Ensures there is no random element in positioning strings
* Retrieved from http://stackoverflow.com/questions/26057572/string-to-unique-hash-in-javascript-jquery
* @param string
*/
function hashCode(string) {
string = JSON.stringify(string);
function hashWithinRange(str, max) {
str = JSON.stringify(str);
let hash = 0;
if (string.length === 0) {
return hash;
for (const ch of str) {
hash = ((hash * 31) + ch.charCodeAt(0)) % max;
}
for (let i = 0; i < string.length; i++) {
const char = string.charCodeAt(i);
hash = ((hash << 5) - hash) + char;
hash = hash & hash; // Convert to 32bit integer
}
return hash;
return Math.abs(hash) % max;
}
export default TagCloud;

View file

@ -52,13 +52,16 @@ export class ImageComparator {
</svg>`;
const sourceImage = new Image();
return new Promise((resolve) => {
return new Promise((resolve, reject) => {
sourceImage.onload = async () => {
sourceContext2d.drawImage(sourceImage, 0, 0);
const mismatch = await this.compareImage(sourceCanvas, expectedImageSourcePng, threshold);
document.body.removeChild(sourceCanvas);
resolve(mismatch);
};
sourceImage.onerror = (e) => {
reject(e.message);
};
sourceImage.src = 'data:image/svg+xml;base64,' + btoa(sourceData);
});
}
@ -72,7 +75,7 @@ export class ImageComparator {
*/
async compareImage(actualCanvasFromUser, expectedImageSourcePng, threshold) {
return new Promise((resolve) => {
return new Promise((resolve, reject) => {
window.setTimeout(() => {
@ -113,6 +116,11 @@ export class ImageComparator {
resolve(mismatchedPixels);
};
expectedImage.onerror = (e) => {
reject(e.message);
};
expectedImage.src = expectedImageSourcePng;
});
});