diff --git a/batchTestElectron/batchTest.html b/batchTestElectron/batchTest.html index ed8b76f..3e5d932 100644 --- a/batchTestElectron/batchTest.html +++ b/batchTestElectron/batchTest.html @@ -52,6 +52,9 @@ let canvasSize = 1400 ; + labelFontSize = "20pt"; + valueFontSize = "20pt"; + function initBatch() { // simple check for IE 8 or less @@ -66,8 +69,6 @@ var areaSpecificationText = gup('areaSpecification'); width = gup('width'); height = gup('height'); - setLabels = gup('setLabels'); - intersectionValues = gup('intersectionValues'); startingDiagram = gup('startingDiagram'); if(width === "") { @@ -82,16 +83,6 @@ document.getElementById("heightEntry").value = height; } - showSetLabels = true; - if(setLabels === "off") { - showSetLabels = false; - } - - showIntersectionValues = true; - if(intersectionValues === "off") { - showIntersectionValues = false; - } - testDirectories = []; // Read the directories in the testfiles directory. var scriptDir = path.dirname(require.main.filename) + "/../testfiles/" @@ -366,9 +357,12 @@ generateInitialLayout(); - globalLabelLengths = findLabelSizes().lengths; - globalValueLengths = findValueSizes().lengths; - globalValueHeights = findValueSizes().heights; + let labelSizes = findLabelSizes(); + globalLabelWidths = labelSizes.lengths; + globalLabelHeights = labelSizes.heights; + let valueSizes = findValueSizes(); + globalValueWidths = valueSizes.lengths; + globalValueHeights = valueSizes.heights; animationDelay = 0; animateOptimizer = false; @@ -1166,9 +1160,12 @@ */ } // svgString += ''; - globalLabelLengths = findLabelSizes().lengths; - globalValueLengths = findValueSizes().lengths; - globalValueHeights = findValueSizes().heights; + let labelSizes = findLabelSizes(); + globalLabelWidths = labelSizes.lengths; + globalLabelHeights = labelSizes.heights; + let valueSizes = findValueSizes(); + globalValueWidths = valueSizes.lengths; + globalValueHeights = valueSizes.heights; var width = canvasSize; var height = canvasSize; diff --git a/www/edeap.css b/www/edeap.css index 9a093a7..3cee0b7 100644 --- a/www/edeap.css +++ b/www/edeap.css @@ -30,7 +30,7 @@ p + ul { #ellipsesSVG { width: calc(100vw - 390px); - height: calc(100vh - 222px); + height: calc(100vh - 234px); position: absolute; z-index: -1; diff --git a/www/ellipses.js b/www/ellipses.js index 2724c71..5666f95 100644 --- a/www/ellipses.js +++ b/www/ellipses.js @@ -189,8 +189,9 @@ class EdeapAreas if (typeof globalArrays === "undefined") { globalArrays = ["globalZoneStrings", "globalProportions", - "globalValueLengths", "globalValueHeights", - "globalLabelLengths", "globalOriginalProportions", + "globalValueWidths", "globalValueHeights", + "globalLabelWidths", "globalLabelHeights", + "globalOriginalProportions", "ellipseLabel", "ellipseParams"]; } @@ -780,7 +781,7 @@ class EdeapAreas xMax++; } - var xMid = xMin + Math.round((xMax - xMin) / 2); + var xMid = xMin + Math.floor((xMax - xMin) / 2); if (x !== xMid) { movement = true; @@ -802,7 +803,7 @@ class EdeapAreas yMax++; } - var yMid = yMin + Math.round((yMax - yMin) / 2); + var yMid = yMin + Math.floor((yMax - yMin) / 2); if (y !== yMid) { movement = true; @@ -811,8 +812,8 @@ class EdeapAreas } // Calculate and return the actual point. - var xPos = oversizedBB.p1.x + x * areaSampleStep; - var yPos = oversizedBB.p1.y + y * areaSampleStep; + var xPos = startX + x * areaSampleStep; + var yPos = startY + y * areaSampleStep; zoneLabelPositions[zone] = { x: xPos, y: yPos diff --git a/www/index.html b/www/index.html index ed552ba..63ef0aa 100644 --- a/www/index.html +++ b/www/index.html @@ -16,6 +16,14 @@ function init() { + let palette = document.getElementById('palette'); + // Add colour palette options to HTML select element. + for (var paletteName in colourPalettes) { + var option = document.createElement("option"); + option.text = paletteName; + palette.add(option); + } + let filePickerRef = document.getElementById('areaSpecFilePicker'); filePickerRef.addEventListener("change", function(event) { @@ -49,10 +57,15 @@ var areaSpecificationText = gup('areaSpecification'); width = gup('width'); height = gup('height'); - setLabels = gup('setLabels'); - intersectionValues = gup('intersectionValues'); + setLabelSize = gup('setLabelSize'); + intersectionLabelSize = gup('intersectionLabelSize'); startingDiagram = gup('startingDiagram'); optimizationMethod = gup('optimizationMethod'); + colourPaletteName = gup('palette').replace("+", " "); + + if (colourPaletteName === "") { + colourPaletteName = "Tableau10"; + } if (optimizationMethod === "") { @@ -89,20 +102,32 @@ document.getElementById("heightEntry").value = height; } - if(setLabels === "off") { - document.getElementById('setLabelsOff').checked = true; - document.getElementById('setLabelsOn').checked = false; + if (setLabelSize === "") { + document.getElementById('setLabelSizeEntry').placeholder = defaultLabelFontSize; } else { - document.getElementById('setLabelsOff').checked = false; - document.getElementById('setLabelsOn').checked = true; + if (!isNaN(setLabelSize)) { + setLabelSize = Math.floor(setLabelSize); + } + else { + setLabelSize = ""; + } + document.getElementById('setLabelSizeEntry').value = setLabelSize; + labelFontSize = setLabelSize + "pt"; + showSetLabels = (setLabelSize > 0); } - if(intersectionValues === "off") { - document.getElementById('intersectionValuesOff').checked = true; - document.getElementById('intersectionValuesOn').checked = false; + if (intersectionLabelSize === "") { + document.getElementById('intersectionLabelSizeEntry').placeholder = defaultValueFontSize; } else { - document.getElementById('intersectionValuesOff').checked = false; - document.getElementById('intersectionValuesOn').checked = true; + if (!isNaN(intersectionLabelSize)) { + intersectionLabelSize = Math.floor(intersectionLabelSize); + } + else { + intersectionLabelSize = ""; + } + document.getElementById('intersectionLabelSizeEntry').value = intersectionLabelSize; + valueFontSize = intersectionLabelSize + "pt"; + showIntersectionValues = (intersectionLabelSize > 0); } if(startingDiagram === "random") { @@ -123,11 +148,24 @@ generateInitialLayout(); } - globalLabelLengths = findLabelSizes().lengths; - globalValueLengths = findValueSizes().lengths; - globalValueHeights = findValueSizes().heights; + let labelSizes = findLabelSizes(); + globalLabelWidths = labelSizes.lengths; + globalLabelHeights = labelSizes.heights; + let valueSizes = findValueSizes(); + globalValueWidths = valueSizes.lengths; + globalValueHeights = valueSizes.heights; + if (ellipseLabel.length > colourPalettes[colourPaletteName].length) { + console.log("More ellipses than supported by " + colourPaletteName + " colour palette. Using Tableau20 palette."); + colourPaletteName = "Tableau20"; + } + // Select the chosen colour palette. + for (let i = 0; i < palette.length; i++) { + if (colourPaletteName == palette.options[i].text) { + palette.selectedIndex = i; + } + } // reproducability logging code should go here @@ -156,17 +194,6 @@ document.getElementById('areaSpecification').innerHTML = decodeAbstractDescription(areaSpecificationText); - showSetLabels = true; - if(setLabels === "off") { - showSetLabels = false; - } - - showIntersectionValues = true; - if(intersectionValues === "off") { - showIntersectionValues = false; - } - - document.getElementById('ellipsesSVG').innerHTML = generateSVG(canvasWidth, canvasHeight, showSetLabels, showIntersectionValues, translateX, translateY, scaling); document.getElementById('downloadName').innerHTML = getDownloadName() + ".svg"; @@ -327,36 +354,43 @@

Area specification: - +

Edeap controls:

- - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
- Diagram width:
- Diagram height:
-
- Set labels:
- Intersection values:
- - [DEV] Optimization method:
- [DEV] Starting diagram:
-
-
- px
- px
-
-   -
-   -
- -   -
-   -
-
-
Diagram size: x + px
Colour palette:
Set labels: pt   (0 for none)
Intersection labels: pt   (0 for none)
[DEV] Optimization method:   +
[DEV] Starting diagram:   +
diff --git a/www/utils.js b/www/utils.js index 4d7639e..c8ce799 100644 --- a/www/utils.js +++ b/www/utils.js @@ -8,9 +8,13 @@ var canvasHeight; var translateX = 0; var translateY = 0; var scaling = 100; -var showSetLabels = false; -var showIntersectionValues = false; - +var showSetLabels = true; +var showIntersectionValues = true; +var colourPaletteName = "Tableau10"; +var defaultLabelFontSize = 12; +var defaultValueFontSize = 12; +var labelFontSize = "12pt"; +var valueFontSize = "12pt"; var globalContours = []; // size of number of ellipses var globalZones = []; // size of number of intersections @@ -19,8 +23,9 @@ var globalOriginalProportions = []; // proportions before scaling, size of numbe var globalProportions = []; // proportions after scaling, size of number of intersections var globalOriginalContourAreas = new Array(); // size of number of ellipses var globalContourAreas = []; // size of number of ellipses -var globalLabelLengths = []; // size of number of ellipses -var globalValueLengths = []; // size of number of intersections +var globalLabelWidths = []; // size of number of ellipses +var globalLabelHeights = []; // size of number of intersections +var globalValueWidths = []; // size of number of intersections var globalValueHeights = []; // size of number of intersections var globalAbstractDescription; @@ -36,8 +41,9 @@ var globalFinalFitness = -1; // access to fitness after optimizer has finished globalProportions = []; globalOriginalContourAreas = []; globalContourAreas = []; - globalLabelLengths = []; - globalValueLengths = []; + globalLabelWidths = []; + globalLabelHeights = []; + globalValueWidths = []; globalValueHeights = []; ellipseParams = []; @@ -493,8 +499,8 @@ var globalFinalFitness = -1; // access to fitness after optimizer has finished let angleRad = angle.toRadians(); let {x, y} = ellipseBoundaryPosition(eA, eB, eR, angleRad); - var textWidth = areas.globalLabelLengths[i]; - var textHeight = 15; + var textWidth = areas.globalLabelWidths[i]; + var textHeight = areas.globalLabelHeights[i]; if (LABEL_DEBUGGING) { nextSVG =''+"\n"; @@ -536,9 +542,8 @@ var globalFinalFitness = -1; // access to fitness after optimizer has finished y -= halfHeight; } - var textLength = areas.globalLabelLengths[i]; var color = findColor(i); - nextSVG =''+areas.ellipseLabel[i]+''+"\n"; + nextSVG =''+areas.ellipseLabel[i]+''+"\n"; svgString += nextSVG; } } @@ -547,19 +552,17 @@ var globalFinalFitness = -1; // access to fitness after optimizer has finished var generateLabelPositions = true; var areaInfo = areas.computeAreasAndBoundingBoxesFromEllipses(generateLabelPositions); - for(var i=0; i < areas.globalZoneStrings.length; i++) { + for (var i=0; i < areas.globalZoneStrings.length; i++) { var zoneLabel = areas.globalZoneStrings[i]; var labelPosition = areaInfo.zoneLabelPositions[zoneLabel]; - if(labelPosition !== undefined) { + if (labelPosition !== undefined) { //var labelPosition = computeLabelPosition(globalZones[i]); var labelX = (labelPosition.x+translateX)*scaling; var labelY = (labelPosition.y+translateY)*scaling; - var textLength = areas.globalValueLengths[i]; + var textWidth = areas.globalValueWidths[i]; var textHeight = areas.globalValueHeights[i]; - labelX = labelX-textLength/2; - labelY = labelY; - if(!isNaN(labelX)) { - nextSVG =''+areas.globalOriginalProportions[i]+''+"\n"; + if (!isNaN(labelX)) { + nextSVG =''+areas.globalOriginalProportions[i]+''+"\n"; svgString += nextSVG; } @@ -807,7 +810,6 @@ var globalFinalFitness = -1; // access to fitness after optimizer has finished } - function findContoursFromZones(zones) { var ret = new Array(); for(var i=0; i < zones.length; i++) { @@ -825,30 +827,81 @@ var globalFinalFitness = -1; // access to fitness after optimizer has finished } + let colourPalettes = { + "Tableau10": [ + 'rgb(78, 121, 167)', + 'rgb(242, 142, 43)', + 'rgb(225, 87, 89)', + 'rgb(118, 183, 178)', + 'rgb(89, 161, 79)', + 'rgb(237, 201, 72)', + 'rgb(176, 122, 161)', + 'rgb(255, 157, 167)', + 'rgb(156, 117, 95)', + 'rgb(186, 176, 172)' + ], + "Tableau20": [ + 'rgb(78, 121, 167)', + 'rgb(160, 203, 232)', + 'rgb(242, 142, 43)', + 'rgb(255, 190, 125)', + 'rgb(89, 161, 79)', + 'rgb(140, 209, 125)', + 'rgb(182, 153, 45)', + 'rgb(241, 206, 99)', + 'rgb(73, 152, 148)', + 'rgb(134, 188, 182)', + 'rgb(225, 87, 89)', + 'rgb(255, 157, 154)', + 'rgb(121, 112, 110)', + 'rgb(186, 176, 172)', + 'rgb(211, 114, 149)', + 'rgb(250, 191, 210)', + 'rgb(176, 122, 161)', + 'rgb(212, 166, 200)', + 'rgb(157, 118, 96)', + 'rgb(215, 181, 166)' + ], + "Tableau ColorBlind": [ + 'rgb(17, 112, 170)', + 'rgb(252, 125, 11)', + 'rgb(163, 172, 185)', + 'rgb(87, 96, 108)', + 'rgb(95, 162, 206)', + 'rgb(200, 82, 0)', + 'rgb(123, 132, 143)', + 'rgb(163, 204, 233)', + 'rgb(255, 188, 121)', + 'rgb(200, 208, 217)' + ], + "ColorBrewer": [ + 'rgb(31,120,180)', + 'rgb(51,160,44)', + 'rgb(255,127,0)', + 'rgb(106,61,154)', + 'rgb(177,89,40)', + 'rgb(227,26,28)', + 'rgb(166,206,227)', + 'rgb(253,191,111)', + 'rgb(178,223,138)', + 'rgb(251,154,153)', + 'rgb(202,178,214)', + 'rgb(255,255,153)' + ] + }; function findColor(i) { + let colourPalette = colourPalettes[colourPaletteName]; - // colorbrewer qualitative option for 12 sets, rearranged order - var colorbrewerArray = ['rgb(31,120,180)','rgb(51,160,44)','rgb(255,127,0)','rgb(106,61,154)', - 'rgb(177,89,40)','rgb(227,26,28)','rgb(166,206,227)','rgb(253,191,111)', - 'rgb(178,223,138)','rgb(251,154,153)','rgb(202,178,214)','rgb(255,255,153)'] - - if(i < colorbrewerArray.length) { - return colorbrewerArray[i]; - } - - var nextColor = i-colorbrewerArray.length; - predefinedNameArray = ["blue", "magenta", "cyan", "orange", "black", "green", "gray", "yellow", "pink", "purple", "red", "brown", "teal", "aqua"] - if(nextColor < predefinedNameArray.length) { - return predefinedNameArray[nextColor]; + if (i < colourPalette.length) { + return colourPalette[i]; } return get_random_color(); } - function findContours(abstractDescription) { // prevent repeated processing @@ -1202,19 +1255,20 @@ console.log("timed out after "+(currentTime-start)/1000+" seconds. Permutation c function findLabelSizes() { + document.getElementById('textLengthMeasure').innerHTML = ""; // clear the div let svg = document.createElementNS("http://www.w3.org/2000/svg", "svg"); let text = document.createElementNS("http://www.w3.org/2000/svg", "text"); - text.setAttribute("style", "dominant-baseline: central; font-family: Helvetica; font-size: 12pt;"); + text.setAttribute("style", "font-family: Helvetica; font-size: " + labelFontSize + ";"); svg.appendChild(text); document.getElementById('textLengthMeasure').appendChild(svg); - const spaceWidth = text.getComputedTextLength(); + const spaceWidth = text.getComputedTextLength(); var lengths = new Array(); var heights = new Array(); let maxHeight = 0; let maxWidth = 0; - for(var i=0; i < ellipseLabel.length; i++) { + for (var i=0; i < ellipseLabel.length; i++) { var label = ellipseLabel[i]; text.textContent = label; @@ -1237,24 +1291,26 @@ console.log("timed out after "+(currentTime-start)/1000+" seconds. Permutation c function findValueSizes() { + document.getElementById('textLengthMeasure').innerHTML = ""; // clear the div + let svg = document.createElementNS("http://www.w3.org/2000/svg", "svg"); + let text = document.createElementNS("http://www.w3.org/2000/svg", "text"); + text.setAttribute("style", "font-family: Helvetica; font-size: " + valueFontSize + ";"); + svg.appendChild(text); + document.getElementById('textLengthMeasure').appendChild(svg); + var lengths = new Array(); var heights = new Array(); - for(var i=0; i < globalOriginalProportions.length; i++) { + for (var i=0; i < globalOriginalProportions.length; i++) { var label = globalOriginalProportions[i]; - var textSVG = ' '+label+''+"\n"; + text.textContent = label; - var svgText = ''+textSVG+'' - document.getElementById('textLengthMeasure').innerHTML = svgText; - var bbox1 = document.getElementById(label).getBBox(); - var textWidth = Math.ceil(bbox1.width); - var textHeight = Math.ceil(bbox1.height); - lengths[i] = textWidth; - heights[i] = textHeight; + lengths[i] = text.getComputedTextLength(); + heights[i] = text.getBBox().height; } document.getElementById('textLengthMeasure').innerHTML = ""; // clear the div return { - lengths : lengths, - heights: heights + lengths, + heights }; }