Compare commits

...

56 Commits

Author SHA1 Message Date
ff33c0e063 Corrected some HTML errors 2025-08-31 15:38:13 +01:00
b4f05b0559 Changed answer range to be a max of 1024 2025-08-26 19:05:44 +01:00
37831d20b1 Changed text to account for removal of anonimity limit relating to user qualifiers 2025-07-23 19:46:18 +01:00
b4e1617e52 Added basic auth to directory - needs appropriate .htpasswd file 2025-07-23 19:16:30 +01:00
9321bf1881 Merge branch 'main' of https://git.telos.digital/PeterEdmond/EoQ_Supporting_Files 2025-07-12 09:37:48 +01:00
fc8bde55e8 Changed Q3 to match with QID71 2025-07-12 09:34:14 +01:00
56e9fd1d76 Updated template as of 5 July 2025 2025-07-05 19:35:17 +01:00
75d671218b Created cloned template for the v2.0 statements 2025-07-05 18:49:08 +01:00
09a75dae36 Removed remaining privacy code 2025-07-05 18:08:01 +01:00
dfb887f641 Tweaked pyramids a little more 2025-06-26 22:32:37 +01:00
b1d518d9cd Adjusted pyramids to make infinitely scaleable 2025-06-26 21:17:15 +01:00
e812cdfcd2 Corrected typo 2025-06-26 16:22:59 +01:00
ad62afc2b6 Repositioned axis in order to match requirements 2025-06-26 15:49:43 +01:00
e4e75c6cab Adjusted amber and RAG settings 2025-06-25 14:44:26 +01:00
2da945fb9b Section averages added 2025-06-21 22:01:46 +01:00
455876378e Changed tool name to LARRIE 2025-06-21 19:02:25 +01:00
19c67efa8e Changed name to LARIE 2025-06-21 18:59:12 +01:00
124de779ac Corrected Any to All on *ALL* of the qualifiers 2025-06-18 13:32:10 +01:00
aef4eaae92 Corrected Any to All 2025-06-18 13:30:22 +01:00
8ed3296e0d Removed anonymity for bar graphs - still exists for text comments 2025-06-18 12:36:32 +01:00
8b1e862c3c Added extra logging to the drawbar function 2025-06-16 19:14:32 +01:00
241d7b151a Added Survey Indexes and documentation 2025-06-14 17:06:19 +01:00
09172a24e6 Added ability to cope with up to 100 options in quantification selections 2025-06-13 21:31:35 +01:00
aaee1758c3 Added default values for IP addresses to avoid errors 2025-06-13 21:28:34 +01:00
e0d2684d29 Check for null values added 2025-06-13 18:48:03 +01:00
d85e82decc Clear comments before re-adding - probably ought to think of a better way to do this? 2025-06-13 17:57:26 +01:00
0b47c2b3e4 Corrected test situation 2025-06-13 17:27:36 +01:00
8ceb409dc3 Adjusted comments to fill if the calculated number of respondents in the cohort is greater than 7 rather than if the number of comments is more than 7. Note that this is done client side so is technically unsafe! 2025-06-03 15:51:53 +01:00
bc88d41831 Updated documentation to make simpler to import data 2025-06-03 11:38:42 +01:00
b4fc103f28 Added favico and corrected grammar 2025-06-03 11:29:29 +01:00
c9a646ac6d Clear all text boxes on new search to prevent confusion 2025-06-02 20:34:54 +01:00
95aa220199 Added ability to insert comments 2025-06-02 20:26:25 +01:00
5dc5d0c728 Added code to get comments from database 2025-06-02 17:24:32 +01:00
827924bd26 Sorted out refreshing of graphics for inverted triangles and also for bar graphs if no data was available 2025-06-01 21:58:00 +01:00
bf17427cc4 Updated report system to analyse subsets 2025-06-01 20:46:42 +01:00
7d571d240d Added code to dynamically update the qualifiers from the Qualtrics database 2025-05-31 21:59:15 +01:00
6cf83a1a5e Created code to extract qualifiers directly from the QUALTRIX system 2025-05-31 20:36:28 +01:00
9aeb6be1a9 Added a workflow in simplified web pages 2025-05-31 20:35:26 +01:00
83008da9bf Added index.html with user instructions 2025-05-31 18:01:54 +01:00
cd32d67b95 Now correctly importing the survey specific question data into the filters table 2025-05-31 17:25:23 +01:00
943ae44e2b Added total number of records to page 2025-05-31 03:38:30 +01:00
5b4f7b5119 Missed an update to one of the bar chart function calls) 2025-05-31 02:08:43 +01:00
99c59cf977 Ensuring that bar graphs are cleared before redrawing 2025-05-31 01:53:14 +01:00
4aeb8c37b6 Collecting the bespoke questions for selection against - Need to insert this into the filters database 2025-05-31 00:45:40 +01:00
2cffceb5f5 Added code to update database from survey 2025-05-31 00:29:56 +01:00
dc68e98d92 Finally extracting questions from the survey. Additional table added to hold questions 2025-05-31 00:16:39 +01:00
437e1afede Added Filters table 2025-05-30 21:27:29 +01:00
a6793ac03e Packaged bargraph for release under MIT license 2025-05-30 00:23:05 +01:00
3471227d55 Removed folder duplicate 2025-05-29 23:50:52 +01:00
02cdde08c2 Added MIT licence header to the draw triangle js code 2025-05-29 23:21:58 +01:00
6de4c2c282 Minor text changes 2025-05-28 20:54:37 +01:00
b3a6763cc6 Equi-spaced 3 triangles per row 2025-05-28 20:50:11 +01:00
1f7422448c Increased white border around the edges of triangles 2025-05-28 20:43:28 +01:00
0ffdc2b65b Removed numbers from section headers 2025-05-28 20:11:36 +01:00
0a94ae36dc Added update script for server 2025-05-28 20:05:57 +01:00
f265303b20 Template updates 2025-05-28 20:04:31 +01:00
47 changed files with 2136 additions and 6197 deletions

5
.htaccess Normal file
View File

@@ -0,0 +1,5 @@
AuthType Basic
AuthName "EoQ Data"
AuthUserFile /var/www/private/.htpasswd
require valid-user

File diff suppressed because it is too large Load Diff

0
MITLicense.txt Normal file
View File

76
MakeDatabase.sql Normal file
View File

@@ -0,0 +1,76 @@
/* CREATE THE DATABASE FROM SCRATCH */
CREATE database demodb;
USE demodb;
CREATE TABLE `Surveys` (
`id` int NOT NULL AUTO_INCREMENT,
`surveyId` varchar(20) COLLATE utf8mb4_unicode_ci NOT NULL,
`description` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '',
PRIMARY KEY (`id`),
UNIQUE KEY `unique_id` (`id`),
UNIQUE KEY `unique_surveyid` (`surveyId`)
);
CREATE TABLE `Responses` (
`id` int NOT NULL AUTO_INCREMENT,
`Q1` int DEFAULT NULL,
`Q2` int DEFAULT NULL,
`Q3` int DEFAULT NULL,
`surveyId` int NOT NULL,
`responseId` varchar(18) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`startDate` datetime DEFAULT NULL,
`endDate` datetime DEFAULT NULL,
`status` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`ipAddress` varchar(45) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`progress` int DEFAULT NULL,
`duration` int DEFAULT NULL,
`finished` tinyint(1) DEFAULT NULL,
`recordedDate` datetime DEFAULT NULL,
`locationLatitude` decimal(9,6) DEFAULT NULL,
`locationLongitude` decimal(9,6) DEFAULT NULL,
`distributionChannel` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`userLanguage` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `unique_id` (`id`),
UNIQUE KEY `unique_response_id` (`responseId`),
KEY `Responses_ibfk_1` (`surveyId`),
CONSTRAINT `Responses_ibfk_1` FOREIGN KEY (`surveyId`) REFERENCES `Surveys` (`id`)
);
CREATE TABLE `Answers` (
`id` int NOT NULL AUTO_INCREMENT,
`surveyId` int NOT NULL,
`responseId` int NOT NULL,
`QID` varchar(16) COLLATE utf8mb4_unicode_ci NOT NULL,
`text` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`value` tinyint DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `unique_survey_response_qid` (`surveyId`,`responseId`,`QID`),
KEY `surveyId` (`surveyId`),
KEY `responseId` (`responseId`),
CONSTRAINT `Answers_ibfk_1` FOREIGN KEY (`surveyId`) REFERENCES `Surveys` (`id`),
CONSTRAINT `Answers_ibfk_2` FOREIGN KEY (`responseId`) REFERENCES `Responses` (`id`),
CONSTRAINT `Answers_chk_1` CHECK ((`value` between -(3) and 3))
);
CREATE TABLE `Users` (
`id` int NOT NULL AUTO_INCREMENT,
`username` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
`password_hash` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
`totp_secret` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`role` enum('user','admin') COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT 'user',
`created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
UNIQUE KEY `username` (`username`)
);
CREATE TABLE Filters (
id INT NOT NULL AUTO_INCREMENT,
surveyId VARCHAR(20),
FilterQuestion INT NOT NULL,
FilterOption INT NOT NULL,
Text VARCHAR(128),
PRIMARY KEY (id)
);

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,51 @@
README
======
VERSIONS
========
v1.0 - This was the original version with anonymity filter
v1.01 - Anonymity filter removed
v2.0 - Updated statements (no anonymity filter), otherwise identical to v1.01
OTHER INFO
==========
Process required to get data into local database is now all self documented via the index.html file
Then the reportTemplate.html will work correctly
backup database:
mysqldump -u username -p > backup.sql
restore database:
mysql -u username -p < backup.sql
SURVEYS:
SV_cwKjMqAqGxImjMG - Is the correct template one!
SV_3pyZVUNpxXm1PZI - is a baaaad one!
TESTING:
get_qid_counts.html provides the ability to test the various splicing and dicing with specific questions against a specific survey.
This connects directly to get_qid_counts.php
get_text_data.html has the ability to connect directly to get_text_data.php to upload text against each QID.
Actual QID values needed can be seen in the reportTemplate.html onclick code for each button.

BIN
SurveyIndexes.pdf Normal file

Binary file not shown.

View File

@@ -117,10 +117,10 @@ $stmt = $pdo->prepare("
$value = null; $value = null;
// Handle numeric between -3 and +3 // Handle numeric between -3 and +3
if (is_numeric($val) && $val >= -3 && $val <= 3) { if (is_numeric($val) && $val >= -3 && $val <= 100) {
$value = (int) $val; $value = (int) $val;
} else { } else {
$text = substr($val, 0, 255); // enforce VARCHAR(255) limit $text = substr($val, 0, 1024); // enforce VARCHAR(1024) limit
} }
$stmt->execute([ $stmt->execute([
@@ -130,10 +130,59 @@ $stmt = $pdo->prepare("
'text' => $text, 'text' => $text,
'value' => $value 'value' => $value
]); ]);
if ($qid == "QID68"){
if ($value === 'null' || is_null($value)) {
$value = 0;
}
updateResponseQ1($pdo, $value, $responseId);
}
if ($qid == "QID69"){
if ($value === 'null' || is_null($value)) {
$value = 0;
}
updateResponseQ2($pdo, $value, $responseId);
}
if ($qid == "QID71"){
if ($value === 'null' || is_null($value)) {
$value = 0;
}
updateResponseQ3($pdo, $value, $responseId);
}
} }
} }
} }
function updateResponseQ1(PDO $pdo, int $q1Value, string $responseId): bool {
$sql = "UPDATE Responses SET Q1 = :q1 WHERE id = :responseId";
$stmt = $pdo->prepare($sql);
$stmt->bindParam(':q1', $q1Value, PDO::PARAM_INT);
$stmt->bindParam(':responseId', $responseId, PDO::PARAM_STR);
return $stmt->execute();
}
function updateResponseQ2(PDO $pdo, int $q2Value, string $responseId): bool {
$sql = "UPDATE Responses SET Q2 = :q2 WHERE id = :responseId";
$stmt = $pdo->prepare($sql);
$stmt->bindParam(':q2', $q2Value, PDO::PARAM_INT);
$stmt->bindParam(':responseId', $responseId, PDO::PARAM_STR);
return $stmt->execute();
}
function updateResponseQ3(PDO $pdo, int $q3Value, string $responseId): bool {
$sql = "UPDATE Responses SET Q3 = :q3 WHERE id = :responseId";
$stmt = $pdo->prepare($sql);
$stmt->bindParam(':q3', $q3Value, PDO::PARAM_INT);
$stmt->bindParam(':responseId', $responseId, PDO::PARAM_STR);
return $stmt->execute();
}
?> ?>

View File

@@ -1,8 +1,35 @@
/* This code is copywrite Telos Digital 2025 working for Telos Partners:
https://www.telospartners.com/
It is released under the MIT licence https://opensource.org/license/mit
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the “Software”), to
deal in the Software without restriction, including without limitation the
rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
sell copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
function drawBar(id,data) { function drawBar(id,data) {
//console.log(id); //console.log(id);
//console.log(data);
const svg = d3.select(`${id}`); const svg = d3.select(`${id}`);
const backgroundwidth = +svg.attr("width"); const backgroundwidth = +svg.attr("width");
const backgroundradius = 10; const backgroundradius = 10;
@@ -10,6 +37,9 @@ const width = 600; //+svg.attr("width");
const height = 200; //+svg.attr("height"); const height = 200; //+svg.attr("height");
const margin = { top: 40, right: 30, bottom: 60, left: 30 }; const margin = { top: 40, right: 30, bottom: 60, left: 30 };
//First clean the svg:
svg.selectAll("*").remove();
// Draw the white background // Draw the white background
// Draw the rounded rectangle // Draw the rounded rectangle
svg.append("rect") svg.append("rect")
@@ -250,37 +280,49 @@ return average; //Needed for the next layer up in the analysis
function doBarData(id,qid) { function doBarData(id,qid, survey, Q1=0, Q2=0, Q3=0 ) {
return fetch('get_qid_counts.php', { // Create the form data object
const formData = new FormData();
formData.append('qid', qid);
formData.append('survey', survey);
formData.append('Q1', Q1);
formData.append('Q2', Q2);
formData.append('Q3', Q3);
console.log("Selectors:",Q1,Q2,Q3);
// Send the form data using fetch
fetch('get_qid_counts.php', {
method: 'POST', method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, body: formData
body: new URLSearchParams({ qid })
})
.then(response => {
if (!response.ok) {
throw new Error('Network response was not OK');
}
return response.json();
}) })
.then(response => response.text())
.then(data => { .then(data => {
if (data.error) { // Output result
throw new Error(data.error); //console.log(data);
} const parsed = JSON.parse(data);
// console.log(data);
// console.log(data[0][Object.keys(data[0])[0]]); // 2. Clean the keys and build a usable object
/* */ const bardata = {};
bardata = { parsed.forEach(entry => {
"-3": data[0][Object.keys(data[0])[0]], const rawKey = Object.keys(entry)[0];
"-2": data[1][Object.keys(data[1])[0]], const cleanKey = rawKey.replace(/"/g, ''); // Remove extra quotes
"-1": data[2][Object.keys(data[2])[0]], bardata[cleanKey] = entry[rawKey];
"0": data[3][Object.keys(data[3])[0]], });
"1": data[4][Object.keys(data[4])[0]],
"2": data[5][Object.keys(data[5])[0]],
"3": data[6][Object.keys(data[6])[0]],
};
//console.log(bardata); //console.log(bardata);
const total = Object.values(bardata).reduce((sum, value) => sum + value, 0);
//console.log(total);
document.getElementById("record_no").textContent = total;
//Anonymity filter commented out for bar graphs only
//if (total < 8){
// return;
//}
drawBar(id,bardata); drawBar(id,bardata);
// return data; // Should be an array like [{ value: -3, count: 2 }, ..., { value: 3, count: 5 }] // return data; // Should be an array like [{ value: -3, count: 2 }, ..., { value: 3, count: 5 }]
})
.catch(error => {
console.error('Error:', error);
}); });
} }

View File

@@ -1,3 +1,30 @@
/* This code is copywrite Telos Digital 2025 working for Telos Partners:
https://www.telospartners.com/
It is released under the MIT licence https://opensource.org/license/mit
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the “Software”), to
deal in the Software without restriction, including without limitation the
rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
sell copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
function drawtriangle(id,text,colour,values,rag,offset,mean) function drawtriangle(id,text,colour,values,rag,offset,mean)
{ {
@@ -16,7 +43,7 @@ if (rag !== "")
{ {
polycolour = rag; polycolour = rag;
textcolour = "black"; textcolour = "black";
console.log("rag: "+rag); //console.log("rag: "+rag);
opacity = 0.6; opacity = 0.6;
} }

View File

@@ -1,3 +1,30 @@
/* This code is copywrite Telos Digital 2025 working for Telos Partners:
https://www.telospartners.com/
It is released under the MIT licence https://opensource.org/license/mit
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the “Software”), to
deal in the Software without restriction, including without limitation the
rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
sell copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
function drawtriangleinverted(id,text,colour,values,rag,offset,mean) function drawtriangleinverted(id,text,colour,values,rag,offset,mean)
{ {
@@ -16,7 +43,7 @@ if (rag !== "")
{ {
polycolour = rag; polycolour = rag;
textcolour = "black"; textcolour = "black";
console.log("rag: "+rag); //console.log("rag: "+rag);
opacity = 0.6; opacity = 0.6;
} }

File diff suppressed because it is too large Load Diff

Binary file not shown.

View File

@@ -1,82 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Spider Graph</title>
<script src="https://d3js.org/d3.v7.min.js"></script>
<style>
svg {
border: 1px solid #ccc;
}
.axis {
stroke: #ccc;
stroke-width: 1px;
}
.area {
fill: steelblue;
fill-opacity: 0.3;
stroke: steelblue;
stroke-width: 2px;
}
.debug {
fill: red;
}
</style>
</head>
<body>
<svg id="spider" width="300" height="300"></svg>
<script>
const svg = d3.select("#spider");
const width = +svg.attr("width");
const height = +svg.attr("height");
const center = { x: width / 2, y: height / 2 };
const radius = 100;
// Define 3 axes at 0, 120, 240 degrees in radians
const axes = [
{ angle: 0 },
{ angle: 2 * Math.PI / 3 },
{ angle: 4 * Math.PI / 3 }
];
// Example values for each axis (normalized from 0 to 1)
const values = [0.8, 0.6, 0.9];
// Draw axis lines
svg.selectAll(".axis")
.data(axes)
.join("line")
.attr("class", "axis")
.attr("x1", center.x)
.attr("y1", center.y)
.attr("x2", d => center.x + radius * Math.cos(d.angle))
.attr("y2", d => center.y + radius * Math.sin(d.angle));
// Convert values to coordinates
const valuePoints = axes.map((d, i) => {
const r = radius * values[i];
return [
center.x + r * Math.cos(d.angle),
center.y + r * Math.sin(d.angle)
];
});
// Draw filled polygon (data area)
svg.append("polygon")
.attr("class", "area")
.attr("points", valuePoints.map(p => p.join(",")).join(" "));
// OPTIONAL: Debug points at each value vertex
svg.selectAll(".debug")
.data(valuePoints)
.join("circle")
.attr("class", "debug")
.attr("cx", d => d[0])
.attr("cy", d => d[1])
.attr("r", 3);
</script>
</body>
</html>

View File

@@ -1,111 +0,0 @@
function drawGraph() {
let ValA = 0.8;
let ValB = 0.4;
let ValC = 0.6;
createSVGgraphic("#Q1","FeatureA", "FeatureB", "FeatureC", ValA, ValB, ValC);
createSVGgraphic("#Q2","ConceptA", "ConceptB", "ConceptC", 0.2, 0.8, 0.8);
}
function createSVGgraphic(divID,FA,FB,FC,VA,VB,VC) {
const svg = d3.select(divID);
const width = +svg.attr("width");
const height = +svg.attr("height");
const radius = 150;
const center = { x: width / 2, y: height / 2 };
// Define axes with A at the top (rotate -90 degrees)
const axes = [
{ name: FA, angle: 0 },
{ name: FB, angle: 120 },
{ name: FC, angle: 240 }
];
axes.forEach(d => d.angle = (d.angle - 90) * Math.PI / 180);
// Sample data: [0-1] scale
const values = [VA, VB, VC];
// Draw axis lines
svg.append("g")
.attr("class", "axis")
.selectAll("line")
.data(axes)
.join("line")
.attr("x1", center.x)
.attr("y1", center.y)
.attr("x2", d => center.x + radius * Math.cos(d.angle))
.attr("y2", d => center.y + radius * Math.sin(d.angle));
// Draw grid rings (polygons)
const levels = 5;
for (let i = 1; i <= levels; i++) {
const r = (radius / levels) * i;
const points = axes.map(d => {
return [
center.x + r * Math.cos(d.angle),
center.y + r * Math.sin(d.angle)
];
});
svg.append("polygon")
.attr("class", "grid")
.attr("points", points.map(p => p.join(",")).join(" "));
}
// Draw axis ticks
const tickLength = 5;
axes.forEach(axis => {
for (let i = 1; i <= levels; i++) {
const r = (radius / levels) * i;
const angle = axis.angle;
const x1 = center.x + r * Math.cos(angle);
const y1 = center.y + r * Math.sin(angle);
// Perpendicular tick
const perpAngle = angle + Math.PI / 2;
const x2 = x1 + tickLength * Math.cos(perpAngle);
const y2 = y1 + tickLength * Math.sin(perpAngle);
svg.append("line")
.attr("x1", x1)
.attr("y1", y1)
.attr("x2", x2)
.attr("y2", y2)
.attr("class", "tick");
}
});
// Convert values to coordinates
const valuePoints = axes.map((d, i) => {
const r = radius * values[i];
return [
center.x + r * Math.cos(d.angle),
center.y + r * Math.sin(d.angle)
];
});
// Draw data area
svg.append("polygon")
.attr("class", "area")
.attr("points", valuePoints.map(p => p.join(",")).join(" "))
// Add axis labels
svg.selectAll(".label")
.data(axes)
.join("text")
.attr("class", "label")
.attr("x", d => center.x + (radius + 20) * Math.cos(d.angle))
.attr("y", (d,i) => {
if (i === 0) { //adjust for 1st access, rather than using d.name
return center.y + (radius + 20) * Math.sin(d.angle)
} else
return center.y + (radius + 20 + 30) * Math.sin(d.angle)
})
.text(d => d.name);
}

View File

@@ -1,285 +0,0 @@
function drawBar(id,data) {
//console.log(id);
const svg = d3.select(`${id}`);
const backgroundwidth = +svg.attr("width");
const backgroundradius = 10;
const width = 600; //+svg.attr("width");
const height = 200; //+svg.attr("height");
const margin = { top: 40, right: 30, bottom: 60, left: 30 };
// Draw the white background
// Draw the rounded rectangle
svg.append("rect")
.attr("x", 0)
.attr("y", 0)
.attr("width", backgroundwidth)
.attr("height", height)
.attr("rx", backgroundradius)
.attr("ry", backgroundradius)
.attr("fill", "white");
// .attr("stroke", "white")
// .attr("stroke-width", 2);
//const data = {
/*
data = {
"-3": 0,
"-2": 1,
"-1": 3,
"0": 0,
"1": 2,
"2": 0,
"3": 10
};
*/
//console.log(data);
const dataArray = Object.entries(data).map(([key, count]) => ({
key: +key,
count: count
}));
const x = d3.scaleBand()
.domain([-3,-2,-1,0,1,2,3])
.range([margin.left, width - margin.right])
.padding(0);
const y = d3.scaleLinear()
.domain([0, d3.max(dataArray, d => d.count)])
.nice()
.range([height - margin.bottom, margin.top]);
// X Axis
svg.append("g")
.attr("transform", `translate(0,${height - margin.bottom})`)
.call(d3.axisBottom(x)
.tickSize(0))
.selectAll("text")
.attr("x", 0)
.attr("y", 10)
.style("text-anchor", "middle")
.style("font-size", "12px");
// Add the required ticks
const xTicks = d3.scaleLinear()
.domain([-3.5, 3.5])
.range([margin.left, width - margin.right]);
svg.append("g")
.attr("transform", `translate(0,${height - margin.bottom})`)
.call(d3.axisBottom(xTicks).tickValues(d3.range(-3.5, 4, 1)))
.selectAll("text")
.style("visibility", "hidden"); // This hides the labels
// Y Axis
//svg.append("g")
// .attr("transform", `translate(${margin.left},0)`)
// .call(d3.axisLeft(y).ticks(5));
// Bars
svg.selectAll(".bar")
.data(dataArray)
.enter()
.append("rect")
.attr("class", "bar")
.attr("x", d => x(d.key))
.attr("y", d => y(d.count))
.attr("width", x.bandwidth())
.attr("height", d => y(0) - y(d.count))
.attr("fill", "#003c4b"); // From brand guidelines
// Labels
svg.selectAll(".label")
.data(dataArray)
.enter()
.append("text")
.attr("x", d => x(d.key) + x.bandwidth() / 2)
.attr("y", d => d.count > 0 ? y(d.count) - 5 : y(0))
.attr("text-anchor", "middle")
.attr("font-size", "12px")
.attr("font-style", "italic")
.attr("fill", "black")
.text(d => d.count > 0 ? d.count : "");
// Average line
const format = d3.format(".2f");
const totalCount = d3.sum(dataArray, d => d.count);
const weightedSum = d3.sum(dataArray, d => d.key * d.count);
average = totalCount > 0 ? weightedSum / totalCount : 0;
const xLinear = d3.scaleLinear()
.domain([-3, 3])
.range([margin.left + x.bandwidth() / 2, width - margin.right - x.bandwidth() / 2]);
const avgX = xLinear(average);
//const avgX = xLinear(-0.50); // Temporary for testing
svg.append("line")
.attr("x1", avgX)
.attr("x2", avgX)
.attr("y1", y(0)+20)
.attr("y2", y(d3.max(dataArray, d => d.count)) - 20)
.attr("stroke", "#e40074") // From brand guidelines
.attr("stroke-width", 4)
.attr("stroke-dasharray", "6,2");
/*
svg.append("text")
.attr("x", avgX)
.attr("y", y(d3.max(dataArray, d => d.count)) - 30)
.attr("text-anchor", "middle")
.attr("fill", "#e40074")
.attr("font-size", "12px")
.text("Average ("+average+")");
*/
// Title beneath the graph
/*
svg.append("text")
.attr("x", width / 2)
.attr("y", height - 10) // Just below the x-axis
.attr("text-anchor", "middle")
.attr("font-size", "14px")
.attr("fill", "black")
.text("Demo bar graph");
*/
// Add info to right of bar chart
// Oblong settings
const boxx = 610;
const boxy = 60;
const boxwidth = 170;
const boxheight = 80;
const cornerRadius = 10;
// Draw the rounded rectangle
svg.append("rect")
.attr("x", boxx)
.attr("y", boxy)
.attr("width", boxwidth)
.attr("height", boxheight)
.attr("rx", cornerRadius)
.attr("ry", cornerRadius)
.attr("fill", "white")
.attr("stroke", "#333")
.attr("stroke-width", 2);
// Draw the horizontal divider
svg.append("line")
.attr("x1", boxx)
.attr("x2", boxx + boxwidth)
.attr("y1", boxy + boxheight / 2)
.attr("y2", boxy + boxheight / 2)
.attr("stroke", "#333")
.attr("stroke-width", 1);
// Add text to the top half
svg.append("text")
.attr("x", boxx + boxwidth / 2)
.attr("y", boxy + boxheight / 4)
.attr("text-anchor", "middle")
.attr("dominant-baseline", "middle")
.attr("font-size", "20px")
.attr("font-weight", "400") // 400 is normal, 700 is bold, 900 is extra-bold
.attr("font-family", "sans-serif")
.text("Average: ")
.append(function() {
return document.createElementNS("http://www.w3.org/2000/svg", "tspan");
})
.text(average.toFixed(1))
.attr("class", "average")
.attr("font-weight", "900");
// .text("Average : "+average.toFixed(2));
// Get the score gap:
let maxKey = null;
let minKey = null;
for (const [key, value] of Object.entries(data)) {
if (value > 0) {
const numKey = Number(key);
//console.log(numkey);
if (maxKey === null || numKey > maxKey) {
maxKey = numKey;
}
if (minKey === null || numKey < minKey) {
minKey = numKey;
}
}
}
scoregap = maxKey - minKey+1;
// Add text to the bottom half
svg.append("text")
.attr("x", boxx + boxwidth / 2)
.attr("y", boxy + 3 * boxheight / 4)
.attr("text-anchor", "middle")
.attr("dominant-baseline", "middle")
.attr("font-size", "20px")
.attr("font-weight", "400") // 400 is normal, 700 is bold, 900 is extra-bold
.attr("font-family", "sans-serif")
.text("Score gap: ")
.append(function() {
return document.createElementNS("http://www.w3.org/2000/svg", "tspan");
})
.text(scoregap)
.attr("font-weight", "900");
// .text("Score Gap : "+scoregap);
return average; //Needed for the next layer up in the analysis
}
function doBarData(id,qid) {
return fetch('get_qid_counts.php', {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: new URLSearchParams({ qid })
})
.then(response => {
if (!response.ok) {
throw new Error('Network response was not OK');
}
return response.json();
})
.then(data => {
if (data.error) {
throw new Error(data.error);
}
// console.log(data);
// console.log(data[0][Object.keys(data[0])[0]]);
/* */
bardata = {
"-3": data[0][Object.keys(data[0])[0]],
"-2": data[1][Object.keys(data[1])[0]],
"-1": data[2][Object.keys(data[2])[0]],
"0": data[3][Object.keys(data[3])[0]],
"1": data[4][Object.keys(data[4])[0]],
"2": data[5][Object.keys(data[5])[0]],
"3": data[6][Object.keys(data[6])[0]],
};
//console.log(bardata);
drawBar(id,bardata);
// return data; // Should be an array like [{ value: -3, count: 2 }, ..., { value: 3, count: 5 }]
});
}

View File

@@ -1,178 +0,0 @@
function drawtriangle(id,text,colour,values,rag,offset,mean)
{
const svg = d3.select(`${id}`);
const width = 500; // Fixed size. Was +svg.attr("width");
const height = 500; // Fixed size. Was +svg.attr("height");
const radius = 200;
const center = { x: (width / 2) + offset.x, y: (height / 2) + offset.y};
let textcolour = colour;
let polycolour = colour;
let opacity = 0.3;
if (rag !== "")
{
polycolour = rag;
textcolour = "black";
console.log("rag: "+rag);
opacity = 0.6;
}
// Define axes with A at the top (rotate -90 degrees)
const axes = [
{ name: "Feature A", angle: 0 },
{ name: "Feature B", angle: 120 },
{ name: "Feature C", angle: 240 }
];
axes.forEach(d => d.angle = (d.angle - 90) * Math.PI / 180);
// Sample data: [0-1] scale
// const values = [0.8, 0.1, 0.76]; Now passed in function args
// Don't draw if class "no-axis"
if (!svg.classed("no-axis")) {
// Draw axis lines
svg.append("g")
.attr("class", "axis")
.selectAll("line")
.data(axes)
.join("line")
.attr("x1", center.x)
.attr("y1", center.y)
.attr("x2", d => center.x + radius * Math.cos(d.angle))
.attr("y2", d => center.y + radius * Math.sin(d.angle));
}
// Draw grid rings (polygons)
const levels = 7;
for (let i = 1; i <= levels; i++) {
const r = (radius / levels) * i;
const points = axes.map(d => {
return [
center.x + r * Math.cos(d.angle),
center.y + r * Math.sin(d.angle)
];
});
svg.append("polygon")
.attr("class", "grid")
.attr("points", points.map(p => p.join(",")).join(" "));
}
// Draw axis ticks
let tickLength = 5;
if (svg.classed("no-axis")) {
tickLength = 0;
}
axes.forEach(axis => {
for (let i = 1; i <= levels -1 ; i++) { // -1 to remove tick outside outline
const r = (radius / levels) * i;
const angle = axis.angle;
const x1 = center.x + r * Math.cos(angle);
const y1 = center.y + r * Math.sin(angle);
// Perpendicular tick
const perpAngle = angle + Math.PI / 2;
const x2 = x1 + tickLength * Math.cos(perpAngle);
const y2 = y1 + tickLength * Math.sin(perpAngle);
svg.append("line")
.attr("x1", x1)
.attr("y1", y1)
.attr("x2", x2)
.attr("y2", y2)
.attr("class", "tick");
}
});
// Convert values to coordinates
const valuePoints = axes.map((d, i) => {
const r = radius * values[i];
return [
center.x + r * Math.cos(d.angle),
center.y + r * Math.sin(d.angle)
];
});
// Draw data area
svg.append("polygon")
.attr("class", "area")
.attr("points", valuePoints.map(p => p.join(",")).join(" "))
.attr("fill", polycolour) // #d76a23 with 30% opacity (translucent)
.attr("fill-opacity", opacity)
.attr("stroke", polycolour) // Outer line color
.attr("stroke-width", 1); // Thin outer line
// Draw outer triangle border (goes to edge of chart)
const outerPoints = axes.map(d => [
center.x + radius * Math.cos(d.angle),
center.y + radius * Math.sin(d.angle)
]);
// Draw border separately (on top)
svg.append("polygon")
.attr("points", outerPoints.map(p => p.join(",")).join(" "))
.attr("fill","none")
.attr("stroke", colour) // Outer line color
.attr("stroke-width", 5); // Thicker outer line
// Put label in bottom centre of triangle
const bottomLeft = outerPoints[1];
const bottomRight = outerPoints[2];
const midX = (bottomLeft[0] + bottomRight[0]) / 2;
const midY = (bottomLeft[1] + bottomRight[1]) / 2;
//Don't draw the label for 'no-text' class
if (!svg.classed("no-text")){
svg.append("text")
.attr("x", midX)
.attr("y", midY - 10) // Alter for correct height
.attr("text-anchor", "middle")
.attr("fill", textcolour) /// My Colour
.attr("font-size", "22px")
.attr("font-weight", "bold")
.text(`${text}`);
}
// And now a central number
let bigy = midY-45;
let bigfont = "36px";
if (svg.classed("big-number")){
bigy = midY-85;
bigfont = "70px";
}
svg.append("text")
.attr("x", midX)
.attr("y", bigy)
.attr("text-anchor", "middle")
.attr("fill", "black") // 🎨 customize color
.attr("font-size", bigfont)
.attr("font-weight", "bold")
.attr("font-family", "Courier New, monospace")
.text(`${mean}`);
// Add axis labels
/*
svg.selectAll(".label")
.data(axes)
.join("text")
.attr("class", "label")
.attr("x", d => center.x + (radius + 20) * Math.cos(d.angle))
.attr("y", (d,i) => {
if (i === 0) { //adjust for 1st access, rather than using d.name
return center.y + (radius + 20) * Math.sin(d.angle)
} else
return center.y + (radius + 20 + 30) * Math.sin(d.angle)
})
.text(d => d.name);
*/
}

View File

@@ -1,161 +0,0 @@
function drawtriangleinverted(id,text,colour,values,rag,offset,mean)
{
const svg = d3.select(`${id}`);
const width = 500; // Fixed size. Was +svg.attr("width");
const height = 500; // Fixed size. Was +svg.attr("height");
const radius = 200;
const center = { x: (width / 2) + offset.x, y: (height / 2) + offset.y};
let textcolour = colour;
let polycolour = colour;
let opacity = 0.3;
if (rag !== "")
{
polycolour = rag;
textcolour = "black";
console.log("rag: "+rag);
opacity = 0.6;
}
// Update angles for flat top triangle
const axes = [
{ name: "Feature A", angle: 60 }, // Left axis
{ name: "Feature B", angle: 180 }, // Top axis (flat)
{ name: "Feature C", angle: 300 } // Right axis
];
// Convert angles to radians (subtract 90 degrees to rotate the whole chart)
axes.forEach(d => d.angle = (d.angle - 90) * Math.PI / 180);
// Sample data: [0-1] scale
// const values = [0.8, 0.1, 0.76]; Now passed in function args
// Don't draw if class "no-axis"
if (!svg.classed("no-axis")) {
// Draw axis lines
svg.append("g")
.attr("class", "axis")
.selectAll("line")
.data(axes)
.join("line")
.attr("x1", center.x)
.attr("y1", center.y)
.attr("x2", d => center.x + radius * Math.cos(d.angle))
.attr("y2", d => center.y + radius * Math.sin(d.angle));
}
// Draw grid rings (polygons)
const levels = 7;
for (let i = 1; i <= levels; i++) {
const r = (radius / levels) * i;
const points = axes.map(d => {
return [
center.x + r * Math.cos(d.angle),
center.y + r * Math.sin(d.angle)
];
});
svg.append("polygon")
.attr("class", "grid")
.attr("points", points.map(p => p.join(",")).join(" "));
}
// Draw axis ticks
let tickLength = 5;
if (svg.classed("no-axis")) {
tickLength = 0;
}
axes.forEach(axis => {
for (let i = 1; i <= levels - 1; i++) { // -1 so that tick doesn't stick out
const r = (radius / levels) * i;
const angle = axis.angle;
const x1 = center.x + r * Math.cos(angle);
const y1 = center.y + r * Math.sin(angle);
// Perpendicular tick
const perpAngle = angle + Math.PI / 2;
const x2 = x1 + tickLength * Math.cos(perpAngle);
const y2 = y1 + tickLength * Math.sin(perpAngle);
svg.append("line")
.attr("x1", x1)
.attr("y1", y1)
.attr("x2", x2)
.attr("y2", y2)
.attr("class", "tick");
}
});
// Convert values to coordinates
const valuePoints = axes.map((d, i) => {
const r = radius * values[i];
return [
center.x + r * Math.cos(d.angle),
center.y + r * Math.sin(d.angle)
];
});
// Draw data area
svg.append("polygon")
.attr("class", "area")
.attr("points", valuePoints.map(p => p.join(",")).join(" "))
.attr("fill", polycolour) // #9f84b8
.attr("fill-opacity", opacity) // with 30% opacity (translucent)
.attr("stroke", polycolour) // Outer line color
.attr("stroke-width", 1); // Thin outer line
// Draw outer triangle border (goes to edge of chart)
const outerPoints = axes.map(d => [
center.x + radius * Math.cos(d.angle),
center.y + radius * Math.sin(d.angle)
]);
// Draw border separately (on top)
svg.append("polygon")
.attr("points", outerPoints.map(p => p.join(",")).join(" "))
.attr("fill","none")
.attr("stroke", colour) // Outer line color
.attr("stroke-width", 5); // Thicker outer line
// Put label in bottom centre of triangle (adjust for flat top)
const bottomLeft = outerPoints[0];
const bottomRight = outerPoints[2];
const midX = (bottomLeft[0] + bottomRight[0]) / 2;
const midY = (bottomLeft[1] + bottomRight[1]) / 2;
//Don't draw the label for 'no-text' class
if (!svg.classed("no-text")){
svg.append("text")
.attr("x", midX)
.attr("y", midY + 25) // Adjust for correct height (moved to bottom)
.attr("text-anchor", "middle")
.attr("fill", textcolour) // My Colour
.attr("font-size", "22px")
.attr("font-weight", "bold")
.text(`${text}`);
}
// And now a central number
let bigy = midY + 70;
let bigfont = "36px";
if (svg.classed("big-number")){
bigy = midY + 120;
bigfont = "70px";
}
svg.append("text")
.attr("x", midX)
.attr("y", bigy)
.attr("text-anchor", "middle")
.attr("fill", "black") // 🎨 customize color
.attr("font-size", bigfont)
.attr("font-weight", "bold")
.attr("font-family", "Courier New, monospace")
.text(`${mean}`);
}

View File

@@ -1,152 +0,0 @@
<?php
// Settings
$config = require 'config.php';
require_once 'db.php'; // include the connection
$apiToken = $config['api_token'];
$dataCentre = $config['data_centre'];
$surveyId = $_POST['survey_id'] ?? null;
if (!$surveyId) {
$surveyId="SV_bD838sNKZEmi6Tc"; // *****FIXME***** JUST FOR DEVELOPMENT
//die("No survey ID provided.");
}
$baseUrl = "https://$dataCentre.qualtrics.com/API/v3";
$headers = [
"X-API-TOKEN: $apiToken",
"Content-Type: application/json"
];
// Step 1: Start the export (with compress = false)
$exportUrl = "$baseUrl/surveys/$surveyId/export-responses/";
$postFields = json_encode([
"format" => "json",
"compress" => false
]);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $exportUrl);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $postFields);
$response = curl_exec($ch);
if (curl_errno($ch)) {
echo "cURL Error: " . curl_error($ch);
curl_close($ch);
exit;
}
curl_close($ch);
$result = json_decode($response, true);
echo "<pre>".$surveyId." ".$exportUrl."</pre>";
if (!isset($result['result']['progressId'])) {
echo "<pre>Export API Response:\n";
print_r($response);
echo "</pre>";
die("Failed to start export.\n$response");
}
$progressId = $result['result']['progressId'];
echo "Polling for completion";
// Step 2: Poll for completion
$progressUrl = "$exportUrl/$progressId";
do {
sleep(2); // avoid hammering the API
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $progressUrl);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
$response = curl_exec($ch);
curl_close($ch);
$result = json_decode($response, true);
$status = $result['result']['status'] ?? 'failed';
} while ($status !== 'complete' && $status !== 'failed');
if ($status !== 'complete') {
die("Export failed or timed out.\n$response");
}
$fileId = $result['result']['fileId'];
// Step 4: Download the file (uncompressed JSON)
$downloadUrl = "$exportUrl/$fileId/file";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $downloadUrl);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
$response = curl_exec($ch);
if (curl_errno($ch)) {
die("Error downloading the file: " . curl_error($ch));
}
curl_close($ch);
// Decode the response
$data = json_decode($response, true);
//Save surveyId
//insertSurveyIfNotExists($identifier, $description); // The identifier is actually the surveyId, and the description isn't included at this point.
$surveyIndex = getOrCreateSurvey($surveyId, "");
echo "-------".$surveyIndex."-----------";
// $data = $result['result'][''] ?? [];
echo "Total responses: " . count($data['responses']) . "\n\n<br>";
if (isset($data['responses']) && is_array($data['responses'])) {
foreach ($data['responses'] as $response) {
echo "Response ID: " . $response['responseId'] . "\n";
//Insert responseId into the database
//
$startDate = new DateTime($response['values']['startDate']);
$startDateFormatted = $startDate->format('Y-m-d H:i:s');
$endDate = new DateTime($response['values']['endDate']);
$endDateFormatted = $endDate->format('Y-m-d H:i:s');
$recordedDate = new DateTime($response['values']['recordedDate']);
$recordedDateFormatted = $recordedDate->format('Y-m-d H:i:s');
$responseData = [
'responseId' => $response['responseId'],
'surveyId' => $surveyIndex,
'startDate' => $startDateFormatted,
'endDate' => $endDateFormatted,
'status' => $response['values']['status'],
'ipAddress' => $response['values']['ipAddress'],
'progress' => $response['values']['progress'],
'duration' => $response['values']['duration'],
'finished' => $response['values']['finished'],
'recordedDate' => $recordedDateFormatted,
'locationLatitude' => $response['values']['locationLatitude'],
'locationLongitude' => $response['values']['locationLongitude'],
'distributionChannel' => $response['values']['distributionChannel'],
'userLanguage' => $response['values']['userLanguage']
];
$responseIndex = upsertResponse($responseData);
// Now read in the answers. These all start with QID????? etc
$answers = $response['values'];
insertAnswers($pdo, $surveyIndex, $responseIndex, $answers);
// Prepare and execute the INSERT statement
//
//
}
} else {
echo "No responses found.";
}
?>

View File

@@ -1,66 +0,0 @@
<?php
// Load config
$config = require 'config.php';
$apiToken = $config['api_token'];
$dataCenter = $config['data_centre'];
// Get the survey ID from POST
$surveyId = $_POST['survey_id'] ?? null;
if (!$surveyId) {
//$surveyId="SV_cAstEvm4ZrPaqGi";
$surveyId="SV_cwKjMqAqGxImjMG";
#die("No survey ID provided.");
}
// Build URL
$baseUrl = "https://$dataCenter.qualtrics.com/API/v3";
$questionsUrl = "$baseUrl/survey-definitions/$surveyId/questions";
// Set headers
$headers = [
"X-API-TOKEN: $apiToken",
"Content-Type: application/json"
];
// Make request
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $questionsUrl);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
$response = curl_exec($ch);
if (curl_errno($ch)) {
die("Request error: " . curl_error($ch));
}
curl_close($ch);
// Output the raw JSON
//header('Content-Type: application/json');
//echo $response;
//var_dump($response);
$data = json_decode($response, true);
$questions = $data['result']['elements'] ?? [];
echo '<pre>';
print_r(array_slice($questions, 0, 1)); // Show one question object
echo '</pre>';
?>
<!DOCTYPE html>
<html>
<head>
<title>Survey Questions</title>
</head>
<body>
<h1>Survey Questions</h1>
<ul>
<?php foreach ($questions as $qid => $question): ?>
<li>
<strong><?= htmlspecialchars($qid) ?>:</strong>
<?= htmlspecialchars($question['QuestionText'] ?? '[No question text]') ?>
</li>
<?php endforeach; ?>
</ul>
</body>
</html>

View File

@@ -1,68 +0,0 @@
<?php
// Set your API key and data center
$apiToken = 'GZjoFiLmb2j62s8AHmMWKN25BZjGBhsU5ez4cwjn';
$dataCenter = 'fra1'; // Your data center, e.g., 'fra1'
// Set the endpoint URL
$baseUrl = "https://$dataCenter.qualtrics.com/API/v3/surveys";
// Initialize cURL session
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $baseUrl);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
"X-API-TOKEN: $apiToken",
"Content-Type: application/json"
]);
// Execute the request
$response = curl_exec($ch);
// Check for cURL errors
if(curl_errno($ch)){
die('Request Error: ' . curl_error($ch));
}
curl_close($ch);
// Decode the response
$result = json_decode($response, true);
$surveys = $result['result']['elements'] ?? [];
?>
<!DOCTYPE html>
<html>
<head>
<title>Select a Qualtrics Survey</title>
</head>
<body>
<h1>Select a Survey</h1>
<?php if (empty($surveys)): ?>
<p>No surveys found or an error occurred.</p><br><br><hr><br>
<pre><?php echo print_r($result); ?></pre>
<pre><?php
?></pre>
<?php else: ?>
<form method="POST" action="getData.php">
<label for="survey_id">Choose a survey to download data and produce reports:</label>
<select name="survey_id" id="survey_id">
<?php foreach ($surveys as $survey): ?>
<option value="<?= htmlspecialchars($survey['id']) ?>">
<?= htmlspecialchars($survey['name']) ?>
</option>
<?php endforeach; ?>
</select>
<br><br>
<input type="submit" value="Submit">
</form>
<?php endif; ?>
</body>
</html>

View File

@@ -1,67 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>QID Value Counts</title>
<style>
body { font-family: Arial, sans-serif; margin: 2em; }
label, input, button { font-size: 1em; margin: 0.5em 0; }
ul { list-style-type: none; padding-left: 0; }
li { padding: 0.3em 0; }
.error { color: red; }
</style>
</head>
<body>
<h1>Query Value Counts by QID</h1>
<form id="qidForm">
<label for="qidInput">Enter QID:</label><br />
<input type="text" id="qidInput" name="qid" required />
<button type="submit">Get Counts</button>
</form>
<div id="results"></div>
<script>
document.getElementById('qidForm').addEventListener('submit', function(e) {
e.preventDefault();
const qid = document.getElementById('qidInput').value.trim();
const resultsDiv = document.getElementById('results');
resultsDiv.innerHTML = 'Loading...';
fetch('get_qid_counts.php', {
method: 'POST',
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
body: new URLSearchParams({qid})
})
.then(response => response.json())
.then(data => {
if (data.error) {
resultsDiv.innerHTML = `<p class="error">${data.error}</p>`;
return;
}
if (!Array.isArray(data) || data.length === 0) {
resultsDiv.innerHTML = '<p>No data found.</p>';
return;
}
let html = '<h2>Value Counts for ' + qid + '</h2><ul>';
data.forEach(item => {
html += `<li><strong>Value ${item.value}:</strong> ${item.count}</li>`;
});
html += '</ul>';
resultsDiv.innerHTML = html;
})
.catch(err => {
resultsDiv.innerHTML = `<p class="error">Error: ${err.message}</p>`;
});
});
</script>
</body>
</html>

View File

@@ -1,67 +0,0 @@
<?php
header('Content-Type: application/json');
// Basic input validation and sanitization
if (!isset($_POST['qid']) || empty($_POST['qid'])) {
echo json_encode(['error' => 'Missing QID parameter']);
exit;
}
$qid = $_POST['qid'];
// Database connection (adjust credentials accordingly)
//
$config = require 'config.php';
$host = $config['db_host'];
$db = $config['db_name'];
$user = $config['db_user'];
$pass = $config['db_pass'];
$charset = 'utf8mb4';
$dsn = "mysql:host=$host;dbname=$db;charset=$charset";
$options = [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
];
try {
$pdo = new PDO($dsn, $user, $pass, $options);
$sql = "
SELECT value, COUNT(*) AS count
FROM Answers
WHERE QID = :qid
AND value BETWEEN -3 AND 3
GROUP BY value
ORDER BY value
";
$stmt = $pdo->prepare($sql);
$stmt->execute(['qid' => $qid]);
$results = $stmt->fetchAll();
// Initialize array with all possible values from -3 to 3 with zero counts
$counts = [];
for ($i = -3; $i <= 3; $i++) {
$counts[$i] = 0;
}
// Fill in counts from query results
foreach ($results as $row) {
$counts[(int)$row['value']] = (int)$row['count'];
}
// Return as JSON array of objects [{value: -3, count: 5}, ...]
$response = [];
foreach ($counts as $value => $count) {
//$response[] = ['value' => $value, 'count' => $count];
$response[] = ['"'.strval($value).'"' => $count];
}
echo json_encode($response);
} catch (PDOException $e) {
echo json_encode(['error' => 'Database error: ' . $e->getMessage()]);
exit;
}

View File

@@ -1,337 +0,0 @@
function RAGGED(average){
// This returns the correct colour red, amber or gree depending on the value presented
if (average <= -1) {
return "red";
}
if (average >= 1) {
return "green";
}
return "#ffbf00";
}
function getAverage(prefix) {
console.log("Prefix:", prefix);
const elements = Array.from(document.querySelectorAll(`svg[id^="${prefix}"] tspan.average`));
const numbers = elements.map(el => {
const text = el.textContent;
//console.log("Raw text content:", text);
const value = parseFloat(text);
//console.log("Parsed value:", value);
return value;
}).filter(n => !isNaN(n));
//console.log("Parsed numeric values:", numbers);
if (numbers.length === 0) {
console.warn("No valid numbers found!");
return NaN;
}
const avg = numbers.reduce((sum, n) => sum + n, 0) / numbers.length;
//console.log("Average of averages:", avg);
return avg;
}
function loaded(){
console.log("loaded");
let amber = '#ffbf00';
//doBigWhiteTriangle('svg1');
//drawtriangle('#svg1','Roles','#008845',[0.5,0.6,0.5],'red', { x: 0, y: 350 },-0.7);
//drawtriangle('#svg1','Actions','#b2c8c4',[0.1,0.6,0.5],'green',{ x: 370, y: 350 },2.3);
//drawtriangle('#svg1','Approach','#ed4c0c',[0.3,0.6,0.5],amber,{ x: 185, y: 30 },1.4);
//drawtriangleinverted('#svg1','Impact','#74469c',[0.7,0.6,0.8],'green',{ x: 185, y: 243},2.4);
//makeSvgRightClickable('svg1');
//doLittleWhiteTriangle('svg2');
//drawtriangle('#svg2','Roles','#008845',[0.5,0.6,0.5],'', { x: 0, y: 100 },-0.7);
//EO ROLES
//Great Employee Owners
let average = doBarData('#svg1_1','QID35_7');
//makeSvgRightClickable('svg1_1');
doBarData('#svg1_2','QID35_2');
//makeSvgRightClickable('svg1_2');
doBarData('#svg1_3','QID35_8');
//makeSvgRightClickable('svg1_3');
doBarData('#svg1_4','QID35_9');
//makeSvgRightClickable('svg1_4');
doBarData('#svg1_5','QID35_10');
//makeSvgRightClickable('svg1_5');
//Great EO Leaders
average = doBarData('#svg2_1','QID36_7');
//makeSvgRightClickable('svg1_1');
doBarData('#svg2_2','QID36_2');
//makeSvgRightClickable('svg1_2');
doBarData('#svg2_3','QID36_8');
//makeSvgRightClickable('svg1_3');
doBarData('#svg2_4','QID36_9');
//makeSvgRightClickable('svg1_4');
//Great EO Governance
average = doBarData('#svg3_1','QID37_7');
//makeSvgRightClickable('svg1_1');
doBarData('#svg3_2','QID37_2');
//makeSvgRightClickable('svg1_2');
doBarData('#svg3_3','QID37_8');
//makeSvgRightClickable('svg1_3');
doBarData('#svg3_4','QID37_20');
//makeSvgRightClickable('svg1_4');
doBarData('#svg3_5','QID37_21');
//makeSvgRightClickable('svg1_5');
doBarData('#svg3_6','QID37_22');
//makeSvgRightClickable('svg1_5');
//EO APPROACH
//Great EO Culture
average = doBarData('#svg4_1','QID2_7');
//makeSvgRightClickable('svg1_1');
doBarData('#svg4_2','QID2_2');
//makeSvgRightClickable('svg1_2');
doBarData('#svg4_3','QID2_8');
//makeSvgRightClickable('svg1_3');
doBarData('#svg4_4','QID2_9');
//makeSvgRightClickable('svg1_4');
//Great EO Engagement
average = doBarData('#svg5_1','QID33_7');
//makeSvgRightClickable('svg1_1');
doBarData('#svg5_2','QID33_2');
//makeSvgRightClickable('svg1_2');
doBarData('#svg5_3','QID33_8');
//makeSvgRightClickable('svg1_3');
doBarData('#svg5_4','QID33_9');
//makeSvgRightClickable('svg1_4');
//Great EO Stewardship
average = doBarData('#svg6_1','QID34_7');
//makeSvgRightClickable('svg1_1');
doBarData('#svg6_2','QID34_2');
//makeSvgRightClickable('svg1_2');
doBarData('#svg6_3','QID34_8');
//makeSvgRightClickable('svg1_3');
doBarData('#svg6_4','QID34_17');
//makeSvgRightClickable('svg1_4');
//EO ACTIONS
//Great EO Strategy
average = doBarData('#svg7_1','QID40_7');
//makeSvgRightClickable('svg1_1');
doBarData('#svg7_2','QID40_2');
//makeSvgRightClickable('svg1_2');
doBarData('#svg7_3','QID40_8');
//makeSvgRightClickable('svg1_3');
doBarData('#svg7_4','QID40_9');
//makeSvgRightClickable('svg1_4');
//Great EO Innovation
average = doBarData('#svg8_1','QID41_7');
//makeSvgRightClickable('svg1_1');
doBarData('#svg8_2','QID41_2');
//makeSvgRightClickable('svg1_2');
doBarData('#svg8_3','QID41_19');
//makeSvgRightClickable('svg1_3');
doBarData('#svg8_4','QID41_20');
//makeSvgRightClickable('svg1_4');
doBarData('#svg8_5','QID41_21');
//makeSvgRightClickable('svg1_5');
//Great EO Advantage
average = doBarData('#svg9_1','QID42_7');
//makeSvgRightClickable('svg1_1');
doBarData('#svg9_2','QID42_2');
//makeSvgRightClickable('svg1_2');
doBarData('#svg9_3','QID42_8');
//makeSvgRightClickable('svg1_3');
//EO RESULTS
//Great EO Measurement
average = doBarData('#svg10_1','QID44_21');
//makeSvgRightClickable('svg1_1');
doBarData('#svg10_2','QID44_7');
//makeSvgRightClickable('svg1_2');
doBarData('#svg10_3','QID44_2');
//makeSvgRightClickable('svg1_3');
doBarData('#svg10_4','QID44_8');
//makeSvgRightClickable('svg1_4');
//Great EO Evaluation
average = doBarData('#svg11_1','QID45_24');
//makeSvgRightClickable('svg1_1');
doBarData('#svg11_2','QID45_25');
//makeSvgRightClickable('svg1_2');
doBarData('#svg11_3','QID45_26');
//makeSvgRightClickable('svg1_3');
doBarData('#svg11_4','QID45_29');
//makeSvgRightClickable('svg1_4');
//Great EO Impact
average = doBarData('#svg12_1','QID46_27');
//makeSvgRightClickable('svg1_1');
doBarData('#svg12_2','QID46_28');
//makeSvgRightClickable('svg1_2');
doBarData('#svg12_3','QID46_29');
//makeSvgRightClickable('svg1_3');
doBarData('#svg12_4','QID46_30');
//makeSvgRightClickable('svg1_4');
doBarData('#svg12_5','QID46_31');
//makeSvgRightClickable('svg1_5');
doBarData('#svg12_6','QID46_32');
//makeSvgRightClickable('svg1_5');
doBarData('#svg12_7','QID46_33');
//makeSvgRightClickable('svg1_3');
doBarData('#svg12_8','QID46_34');
//makeSvgRightClickable('svg1_4');
doBarData('#svg12_9','QID46_36');
//makeSvgRightClickable('svg1_5');
doBarData('#svg12_10','QID46_37');
//makeSvgRightClickable('svg1_5');
// Make sure that evreything is loaded!
setTimeout(() => {
console.log("Waited 2 seconds");
// We now have access to all of the averages, so can calculate the basic triangle.
//EO ROLES
let svg1_avg = (getAverage("svg1_")+3)/7;
let svg2_avg = (getAverage("svg2_")+3)/7;
let svg3_avg = (getAverage("svg3_")+3)/7;
let roles_avg = (7*(svg1_avg+svg2_avg+svg3_avg)/3)-3; // this converts the scales lengths to the correct value
console.log(svg1_avg,svg2_avg,svg3_avg, roles_avg);
doLittleWhiteTriangle('svg_roles');
//drawtriangle('#svg_roles','Roles','#008845',[0.25,0.5,0.75],'', { x: 0, y: 100 },roles_avg.toFixed(1));
drawtriangle('#svg_roles','Roles','#008845',[svg1_avg,svg2_avg,svg3_avg],'', { x: 0, y: 100 },roles_avg.toFixed(1));
//makeSvgRightClickable('svg_roles');
doLittleWhiteTriangle('svg_roles_RAG');
drawtriangle('#svg_roles_RAG','Roles','#008845',[svg1_avg,svg2_avg,svg3_avg],RAGGED(roles_avg), { x: 0, y: 100 },roles_avg.toFixed(1));
//makeSvgRightClickable('svg_roles_RAG');
doLittleWhiteTriangle('svg_roles_test');
drawtriangle('#svg_roles_test','Roles','#008845',[0.95,0.95,0.95],RAGGED(roles_avg), { x: 0, y: 100 },roles_avg.toFixed(1));
//makeSvgRightClickable('svg_roles_test');
//EO APPROACH
let svg4_avg = (getAverage("svg4_")+3)/7;
let svg5_avg = (getAverage("svg5_")+3)/7;
let svg6_avg = (getAverage("svg6_")+3)/7;
let approach_avg = (7*(svg4_avg+svg5_avg+svg6_avg)/3)-3; // this converts the scales lengths to the correct value
console.log(svg4_avg,svg5_avg,svg6_avg,approach_avg);
doLittleWhiteTriangle('svg_approach');
//drawtriangle('#svg_approach','Approach','#008845',[0.25,0.5,0.75],'', { x: 0, y: 100 },average_avg.toFixed(1));
drawtriangle('#svg_approach','Approach','#ed4c0c',[svg4_avg,svg5_avg,svg6_avg],'', { x: 0, y: 100 },approach_avg.toFixed(1));
//makeSvgRightClickable('svg_approach');
doLittleWhiteTriangle('svg_approach_RAG');
drawtriangle('#svg_approach_RAG','Approach','#ed4c0c',[svg4_avg,svg5_avg,svg6_avg],RAGGED(approach_avg), { x: 0, y: 100 },approach_avg.toFixed(1));
//makeSvgRightClickable('svg_approach_RAG');
//doLittleWhiteTriangle('svg_approach_test');
//drawtriangle('#svg_approach_test','Approach','#ed4c0c',[0.95,0.95,0.95],RAGGED(approach_avg), { x: 0, y: 100 },approach_avg.toFixed(1));
//makeSvgRightClickable('svg_approach_test');
//EO ACTIONS
let svg7_avg = (getAverage("svg7_")+3)/7;
let svg8_avg = (getAverage("svg8_")+3)/7;
let svg9_avg = (getAverage("svg9_")+3)/7;
let actions_avg = (7*(svg7_avg+svg8_avg+svg9_avg)/3)-3; // this converts the scales lengths to the correct value
console.log(svg7_avg,svg8_avg,svg9_avg,actions_avg);
doLittleWhiteTriangle('svg_actions');
//drawtriangle('#svg_actions','Actions','#b2c8c4',[0.25,0.5,0.75],'', { x: 0, y: 100 },actions_avg.toFixed(1));
drawtriangle('#svg_actions','Actions','#b2c8c4',[svg7_avg,svg8_avg,svg9_avg],'', { x: 0, y: 100 },actions_avg.toFixed(1));
//makeSvgRightClickable('svg_actions');
doLittleWhiteTriangle('svg_actions_RAG');
drawtriangle('#svg_actions_RAG','Actions','#b2c8c4',[svg7_avg,svg8_avg,svg9_avg],RAGGED(actions_avg), { x: 0, y: 100 },actions_avg.toFixed(1));
//makeSvgRightClickable('svg_actions_RAG');
//doLittleWhiteTriangle('svg_actions_test');
//drawtriangle('#svg_actions_test','Actions','#b2c8c4',[0.95,0.95,0.95],RAGGED(actions_avg), { x: 0, y: 100 },actions_avg.toFixed(1));
//makeSvgRightClickable('svg_actions_test');
//EO IMPACT
let svg10_avg = (getAverage("svg10_")+3)/7;
let svg11_avg = (getAverage("svg11_")+3)/7;
let svg12_avg = (getAverage("svg12_")+3)/7;
let results_avg = (7*(svg10_avg+svg11_avg+svg12_avg)/3)-3; // this converts the scales lengths to the correct value
console.log(svg10_avg,svg11_avg,svg12_avg,results_avg);
doLittleWhiteTriangle('svg_results');
//drawtriangle('#svg_results','Results','#74469',[0.25,0.5,0.75],'', { x: 0, y: 100 },impact_avg.toFixed(1));
drawtriangleinverted('#svg_results','Results','#74469c',[svg10_avg,svg11_avg,svg12_avg],'', { x: 0, y: 0 },results_avg.toFixed(1));
//makeSvgRightClickable('svg_results');
doLittleWhiteTriangle('svg_results_RAG');
drawtriangleinverted('#svg_results_RAG','Results','#74469c',[svg10_avg,svg11_avg,svg12_avg],RAGGED(results_avg), { x: 0, y: 0 },results_avg.toFixed(1));
//makeSvgRightClickable('svg_results_RAG');
doLittleWhiteTriangle('svg_results_test');
drawtriangleinverted('#svg_results_test','Results','#74469c',[0.95,0.95,0.95],RAGGED(results_avg), { x: 0, y: 0 },results_avg.toFixed(1));
//makeSvgRightClickable('svg_results_test');
doBigWhiteTriangle('svg_pyramid');
drawtriangle('#svg_pyramid','Roles','#008845',[svg1_avg,svg2_avg,svg3_avg],'', { x: 0, y: 350 },roles_avg.toFixed(1));
drawtriangle('#svg_pyramid','Actions','#b2c8c4',[svg4_avg,svg5_avg,svg6_avg],'',{ x: 370, y: 350 },actions_avg.toFixed(1));
drawtriangle('#svg_pyramid','Approach','#ed4c0c',[svg7_avg,svg8_avg,svg9_avg],'',{ x: 185, y: 30 },approach_avg.toFixed(1));
drawtriangleinverted('#svg_pyramid','Results','#74469c',[svg10_avg,svg11_avg,svg12_avg],'',{ x: 185, y: 243},results_avg.toFixed(1));
makeSvgRightClickable('svg_pyramid');
doBigWhiteTriangle('svg_pyramid_RAG');
drawtriangle('#svg_pyramid_RAG','Roles','#008845',[svg1_avg,svg2_avg,svg3_avg],RAGGED(roles_avg), { x: 0, y: 350 },roles_avg.toFixed(1));
drawtriangle('#svg_pyramid_RAG','Actions','#b2c8c4',[svg4_avg,svg5_avg,svg6_avg],RAGGED(actions_avg),{ x: 370, y: 350 },actions_avg.toFixed(1));
drawtriangle('#svg_pyramid_RAG','Approach','#ed4c0c',[svg7_avg,svg8_avg,svg9_avg],RAGGED(approach_avg),{ x: 185, y: 30 },approach_avg.toFixed(1));
drawtriangleinverted('#svg_pyramid_RAG','Results','#74469c',[svg10_avg,svg11_avg,svg12_avg],RAGGED(results_avg),{ x: 185, y: 243},results_avg.toFixed(1));
makeSvgRightClickable('svg_pyramid_RAG');
doBigWhiteTriangle('svg_pyramid_RAG_test');
drawtriangle('#svg_pyramid_RAG_test','Roles','#008845',[0.95,0.95,0.95],RAGGED(roles_avg), { x: 0, y: 350 },roles_avg.toFixed(1));
drawtriangle('#svg_pyramid_RAG_test','Actions','#b2c8c4',[0.95,0.95,0.95],RAGGED(actions_avg),{ x: 370, y: 350 },actions_avg.toFixed(1));
drawtriangle('#svg_pyramid_RAG_test','Approach','#ed4c0c',[0.95,0.95,0.95],RAGGED(approach_avg),{ x: 185, y: 30 },approach_avg.toFixed(1));
drawtriangleinverted('#svg_pyramid_RAG_test','Results','#74469c',[0.95,0.95,0.95],RAGGED(results_avg),{ x: 185, y: 243},results_avg.toFixed(1));
makeSvgRightClickable('svg_pyramid_RAG_test');
}, 500);
}

View File

@@ -1,347 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>EOQ Output</title>
<script src="https://d3js.org/d3.v7.min.js"></script>
<script src="./drawtriangle.js"></script>
<script src="./drawtriangleinverted.js"></script>
<script src="./drawbar.js"></script>
<script src="./savesvg.js"></script>
<script src="./populateGraphics.js"></script>
<style>
body {
font-family: sans-serif;
margin: 0;
padding: 0;
background-color: white;
}
svg {
background: none;
display: block;
margin: auto;
}
.axis line {
stroke: black;
stroke-width: 1.5px;
}
line.tick {
stroke: black;
stroke-width: 1;
}
polygon.grid {
fill: none;
stroke: rgba(200, 200, 200, 0.5); /* light grey with 50% opacity */
stroke-dasharray: 2,2;
}
.label {
font-size: 12px;
font-weight: bold;
text-anchor: middle;
}
</style>
</head>
<body onload="loaded()">
<h1>TITLE</h1>
<p>Dates: TO </p>
<p>Number of completed surveys: </p>
<hr>
<h2>A Health Check for your Employee Owned Business</h2>
<p>Employee ownership (EO) has the potential to deliver outstanding benefits to individual owners and drive exceptional company performance.</p>
<p>However, research shows, for that to happen, a business must have excellent EO management practices in place.</p>
<p>To help identify EO best practice, we developed the EO Framework. It is built on insights gathered directly from leaders, senior decision-makers and employee owners on how they have successfully implemented impactful EO.</p>
<p>Developed by Great EO's founding partners in collaboration with the Employee Ownership Association, the EO Framework sets out four simple areas of EO management best practice:</p>
<ul>
<li><strong>EO Roles:</strong> Clearly defined EO roles through which leaders, trustees and employee owners all understand the part they play in making EO successful.</li>
<li><strong>EO Approach:</strong> Strong EO core practices that empower employees to contribute to success.</li>
<li><strong>EO Actions:</strong> Specific areas of EO management practice that can harness the full potential of employee ownership to strengthen strategy, innovation, and brand difference.</li>
<li><strong>EO Results:</strong> Structured and consistent ways of measuring EO practice to track and enhance owner benefits and business outcomes.</li>
</ul>
<p>To bring the EO Framework to life, we have created a simple health check - the eoQ™ test - to help you assess the strength of your current EO practice and signpost areas for possible improvement. It should take up to 20-30 minutes to complete the questionnaire.</p>
<svg style="display: inline-block" xmlns="http://www.w3.org/2000/svg" id="svg_pyramid" width="1000" height="1000"></svg>
<svg style="display: inline-block" xmlns="http://www.w3.org/2000/svg" id="svg_pyramid_RAG" width="1000" height="1000"></svg>
<svg class="no-axis no-text big-number" style="display: inline-block" xmlns="http://www.w3.org/2000/svg" id="svg_pyramid_RAG_test" width="1000" height="1000"></svg>
<hr>
<h2>1. EO Roles</h2>
<p>It is vital that individual leaders, trustees, employee representatives and all employee owners understand their roles to ensure a successful EO business.</p>
<p><strong>To what extent does everyone fulfil their responsibilities in your business?</strong></p>
<svg style="display: inline-block" xmlns="http://www.w3.org/2000/svg" id="svg_roles" width="500" height="500"></svg>
<svg style="display: inline-block" xmlns="http://www.w3.org/2000/svg" id="svg_roles_RAG" width="500" height="500"></svg>
<svg class = "no-axis no-text big-number" style="display: inline-block" xmlns="http://www.w3.org/2000/svg" id="svg_roles_test" width="500" height="500"></svg>
<hr>
<h3>Q14 Great Employee Owners</h3>
<p>1. Our employee owners understand how to think and act like an owner.</p>
<svg xmlns="http://www.w3.org/2000/svg" id="svg1_1" width="800" height="200"></svg>
<p>2. Our employee owners are committed to making the business stronger.</p>
<svg xmlns="http://www.w3.org/2000/svg" id="svg1_2" width="800" height="200"></svg>
<p>3. Our employee owners understand how their actions impact the current years business results.</p>
<svg xmlns="http://www.w3.org/2000/svg" id="svg1_3" width="800" height="200"></svg>
<p>4. Our employee owners understand how their actions help to execute our longer-term strategy.</p>
<svg xmlns="http://www.w3.org/2000/svg" id="svg1_4" width="800" height="200"></svg>
<p>5. Our employee owners understand how their actions strengthen our organisational culture.</p>
<svg xmlns="http://www.w3.org/2000/svg" id="svg1_5" width="800" height="200"></svg>
<p>Q15 Please add any additional comments:</p>
<hr>
<h3>Q16 Great EO Leaders</h3>
<p>1. Our executive leaders (those responsible for leading the business) are committed to realising the full business potential of our employee ownership.</p>
<svg xmlns="http://www.w3.org/2000/svg" id="svg2_1" width="800" height="200"></svg>
<p>2. Our executive leaders regularly engage our people to contribute as owners to our vision and strategy.</p>
<svg xmlns="http://www.w3.org/2000/svg" id="svg2_2" width="800" height="200"></svg>
<p>3. Our executive leaders ensure our people feel connected to our purpose, values, owner mindset and behaviours.</p>
<svg xmlns="http://www.w3.org/2000/svg" id="svg2_3" width="800" height="200"></svg>
<p>4. Our executive leaders are role models for our desired owner behaviours and culture.</p>
<svg xmlns="http://www.w3.org/2000/svg" id="svg2_4" width="800" height="200"></svg>
<p>Q17 Please add any additional comments:</p>
<hr>
<h3>Q18 Great EO Governance</h3>
<p>1. All our governance bodies (boards, councils and voice groups) are clear on their role in ensuring long-term success for the business and its employee owners.</p>
<svg xmlns="http://www.w3.org/2000/svg" id="svg3_1" width="800" height="200"></svg>
<p>2. All our governance bodies work collaboratively and effectively to promote an ownership culture.</p>
<svg xmlns="http://www.w3.org/2000/svg" id="svg3_2" width="800" height="200"></svg>
<p>3. All our governance bodies involve independent members who bring relevant experience, perspectives, and insights.</p>
<svg xmlns="http://www.w3.org/2000/svg" id="svg3_3" width="800" height="200"></svg>
<p>4. All our governance bodies effectively use the diverse skills, experiences and opinions of their members.</p>
<svg xmlns="http://www.w3.org/2000/svg" id="svg3_4" width="800" height="200"></svg>
<p>5. All our governance bodies fairly distribute ownership benefits in a manner that supports an ownership culture.</p>
<svg xmlns="http://www.w3.org/2000/svg" id="svg3_5" width="800" height="200"></svg>
<p>6. All our governance bodies make decisions in the long-term best interests of the organisation and its stakeholders.</p>
<svg xmlns="http://www.w3.org/2000/svg" id="svg3_6" width="800" height="200"></svg>
<p>Q19 Please add any additional comments:</p>
<hr>
<h2>2. EO Approach</h2>
<p>EO core practices build a strong ownership culture which drives engagement levels and encourages owner behaviours, including how to promote and protect the business over the long-term.</p>
<p><strong>To what extent are you effectively engaging your people as owners and building an ownership mindset?</strong></p>
<svg style="display: inline-block" xmlns="http://www.w3.org/2000/svg" id="svg_approach" width="500" height="500"></svg>
<svg style="display: inline-block" xmlns="http://www.w3.org/2000/svg" id="svg_approach_RAG" width="500" height="500"></svg>
<hr>
<h3>Great EO Culture</h3>
<p>1. Our behaviours as owners are improving the performance of the business.</p>
<svg xmlns="http://www.w3.org/2000/svg" id="svg4_1" width="800" height="200"></svg>
<p>2. Our people processes (recruitment, development, appraisal and reward) encourage and reward our desired owner behaviours.</p>
<svg xmlns="http://www.w3.org/2000/svg" id="svg4_2" width="800" height="200"></svg>
<p>3. Our culture creates a safe environment for feedback, learning, growth, health, well-being, inclusion and diversity.</p>
<svg xmlns="http://www.w3.org/2000/svg" id="svg4_3" width="800" height="200"></svg>
<p>4. Our culture and support for people develops and retains the right talent.</p>
<svg xmlns="http://www.w3.org/2000/svg" id="svg4_4" width="800" height="200"></svg>
<p>Q22 Please add any additional comments:</p>
<hr>
<h3>Q23 Great EO Engagement</h3>
<p>1. All of our managers (those responsible for managing people and processes) help ensure our people understand how and where decisions are made in the business.</p>
<svg xmlns="http://www.w3.org/2000/svg" id="svg5_1" width="800" height="200"></svg>
<p>2. All of our managers help ensure our planning process, goal setting, and feedback channels enable people to influence decision-making as owners.</p>
<svg xmlns="http://www.w3.org/2000/svg" id="svg5_2" width="800" height="200"></svg>
<p>3. All of our managers help ensure our people clearly understand the connection between their owner behaviours and strategy, business performance and reward.</p>
<svg xmlns="http://www.w3.org/2000/svg" id="svg5_3" width="800" height="200"></svg>
<p>4. All of our managers help ensure our people are encouraged and empowered as owners to take responsibility for their own performance and contribution.</p>
<svg xmlns="http://www.w3.org/2000/svg" id="svg5_4" width="800" height="200"></svg>
<p>Q24 Please add any additional comments:</p>
<hr>
<h3>Q25 Great EO Stewardship</h3>
<p>1. During tough times, we balance the current and future needs of our employee owners with those of the organisation.</p>
<svg xmlns="http://www.w3.org/2000/svg" id="svg6_1" width="800" height="200"></svg>
<p>2. Our employee owners identify and manage risks to protect our organisation and reputation.</p>
<svg xmlns="http://www.w3.org/2000/svg" id="svg6_2" width="800" height="200"></svg>
<p>3. We learn from tough times to become stronger in the future.</p>
<svg xmlns="http://www.w3.org/2000/svg" id="svg6_3" width="800" height="200"></svg>
<p>4. Our culture encourages leaders, managers and specialists to develop candidates for their own succession.</p>
<svg xmlns="http://www.w3.org/2000/svg" id="svg6_4" width="800" height="200"></svg>
<p>Q26 Please add any additional comments:</p>
<hr>
<h2>3. EO Actions</h2>
<p>An EO business can use its ownership model to provide commercial advantages as it faces into the world.</p>
<p><strong>To what extent are you harnessing the contributions of employees as owners to strengthen the quality and effectiveness of your strategy, innovation and commercial sustainability?</strong></p>
<svg style="display: inline-block" xmlns="http://www.w3.org/2000/svg" id="svg_actions" width="500" height="500"></svg>
<svg style="display: inline-block" xmlns="http://www.w3.org/2000/svg" id="svg_actions_RAG" width="500" height="500"></svg>
<hr>
<h3>Q28 Great EO Strategy</h3>
<p>1. Our vision sets out the compelling benefits of our ownership model.</p>
<svg xmlns="http://www.w3.org/2000/svg" id="svg7_1" width="800" height="200"></svg>
<p>2. Our strategy builds on our unique strengths including our ownership model.</p>
<svg xmlns="http://www.w3.org/2000/svg" id="svg7_2" width="800" height="200"></svg>
<p>3. Our strategy outlines key activities and milestones that ensure our employee owners know how to contribute to a successful business.</p>
<svg xmlns="http://www.w3.org/2000/svg" id="svg7_3" width="800" height="200"></svg>
<p>4. Our strategic approach to key markets ensures success by drawing on the experience and insights of our employee owners.</p>
<svg xmlns="http://www.w3.org/2000/svg" id="svg7_4" width="800" height="200"></svg>
<p>Q29 Please add any additional comments:</p>
<hr>
<h3>Q30 Great EO Innovation</h3>
<p>1. Our employee owners understand how our business works and delivers results.</p>
<svg xmlns="http://www.w3.org/2000/svg" id="svg8_1" width="800" height="200"></svg>
<p>2. Our employee owners are committed to driving continuous improvement and growth.</p>
<svg xmlns="http://www.w3.org/2000/svg" id="svg8_2" width="800" height="200"></svg>
<p>3. Our employee owners consistently contribute ideas that improve our business.</p>
<svg xmlns="http://www.w3.org/2000/svg" id="svg8_3" width="800" height="200"></svg>
<p>4. We provide clear channels and processes to capture, consider and provide feedback on new ideas and suggestions.</p>
<svg xmlns="http://www.w3.org/2000/svg" id="svg8_4" width="800" height="200"></svg>
<p>5. We successfully prioritise and manage these ideas to deliver improvements to our business.</p>
<svg xmlns="http://www.w3.org/2000/svg" id="svg8_5" width="800" height="200"></svg>
<p>Q31 Please add any additional comments:</p>
<hr>
<h3>Great EO Advantage</h3>
<p>1. We leverage our EO status to differentiate our customer brand to win against our competitors in the market.</p>
<svg xmlns="http://www.w3.org/2000/svg" id="svg9_1" width="800" height="200"></svg>
<p>2. We leverage our EO status to differentiate our employer brand to strengthen our people proposition and attract talent.</p>
<svg xmlns="http://www.w3.org/2000/svg" id="svg9_2" width="800" height="200"></svg>
<p>3. We leverage our EO status to differentiate our company brand to develop and retain high-quality relationships with suppliers and delivery partners.</p>
<svg xmlns="http://www.w3.org/2000/svg" id="svg9_3" width="800" height="200"></svg>
<p>Q33 Please add any additional comments:</p>
<hr>
<h2>4. EO Results</h2>
<p>Well-run EO businesses ensure decision-making is informed by relevant data and insights from inside the business and by benchmarking themselves against others. This helps set strategic focus, direct operational effort, ensure continuous improvement and drive better business performance.</p>
<p><strong>Do you have the right EO data and insights to make this happen?</strong></p>
<svg style="display: inline-block" xmlns="http://www.w3.org/2000/svg" id="svg_results" width="500" height="500"></svg>
<svg style="display: inline-block" xmlns="http://www.w3.org/2000/svg" id="svg_results_RAG" width="500" height="500"></svg>
<svg class = "no-axis no-text big-number" style="display: inline-block" xmlns="http://www.w3.org/2000/svg" id="svg_results_test" width="500" height="500"></svg>
<hr>
<h3>Q35 Great EO Measurement</h3>
<p>1. We are collecting data within the business that helps us understand how we benefit from our EO model.</p>
<svg xmlns="http://www.w3.org/2000/svg" id="svg10_1" width="800" height="200"></svg>
<p>2. We measure and compare our EO performance with other similar EO businesses.</p>
<svg xmlns="http://www.w3.org/2000/svg" id="svg10_2" width="800" height="200"></svg>
<p>3. We measure and compare our performance with other businesses in our sector (regardless of their ownership model).</p>
<svg xmlns="http://www.w3.org/2000/svg" id="svg10_3" width="800" height="200"></svg>
<p>4. We pay attention to our impacts on more than just our employee owners (e.g. our customers, community or planet).</p>
<svg xmlns="http://www.w3.org/2000/svg" id="svg10_4" width="800" height="200"></svg>
<p>Q36 Please add any additional comments:</p>
<hr>
<h3>Q37 Great EO Evaluation</h3>
<p>1. Our leaders and governance bodies use relevant EO data and insights to increase engagement levels among our people.</p>
<svg xmlns="http://www.w3.org/2000/svg" id="svg11_1" width="800" height="200"></svg>
<p>2. Our leaders and governance bodies use relevant EO data and insights to strengthen our ownership culture.</p>
<svg xmlns="http://www.w3.org/2000/svg" id="svg11_2" width="800" height="200"></svg>
<p>3. Our leaders and governance bodies use relevant EO data and insights to grow our business.</p>
<svg xmlns="http://www.w3.org/2000/svg" id="svg11_3" width="800" height="200"></svg>
<p>4. Our leaders and governance bodies use relevant EO data and insights to meet the aspirations of our current employee owners.</p>
<svg xmlns="http://www.w3.org/2000/svg" id="svg11_4" width="800" height="200"></svg>
<p>Q38 Please add any additional comments:</p>
<hr>
<h3>Q39 Great EO Impact</h3>
<p>1. EO data and insights helps us demonstrate that our EO model encourages collaboration and team-working.</p>
<svg xmlns="http://www.w3.org/2000/svg" id="svg12_1" width="800" height="200"></svg>
<p>2. EO data and insights help us demonstrate that our EO model promotes engagement and job satisfaction.</p>
<svg xmlns="http://www.w3.org/2000/svg" id="svg12_2" width="800" height="200"></svg>
<p>3. EO data and insights help us demonstrate that our EO model improves health and well-being for employee owners.</p>
<svg xmlns="http://www.w3.org/2000/svg" id="svg12_3" width="800" height="200"></svg>
<p>4. EO data and insights help us demonstrate that our EO model supports colleagues skills and capability.</p>
<svg xmlns="http://www.w3.org/2000/svg" id="svg12_4" width="800" height="200"></svg>
<p>5. EO data and insights help us demonstrate that our EO model encourages strong ideas from colleagues.</p>
<svg xmlns="http://www.w3.org/2000/svg" id="svg12_5" width="800" height="200"></svg>
<p>6. EO data and insights help us demonstrate that our EO model helps us recruit and retain talent.</p>
<svg xmlns="http://www.w3.org/2000/svg" id="svg12_6" width="800" height="200"></svg>
<p>7. EO data and insights help us demonstrate that our EO model boosts personal commitment and productivity.</p>
<svg xmlns="http://www.w3.org/2000/svg" id="svg12_7" width="800" height="200"></svg>
<p>8. EO data and insights help us demonstrate that our EO model increases profitability.</p>
<svg xmlns="http://www.w3.org/2000/svg" id="svg12_8" width="800" height="200"></svg>
<p>9. EO data and insights help us demonstrate that our EO model encourages more contribution to the local community.</p>
<svg xmlns="http://www.w3.org/2000/svg" id="svg12_9" width="800" height="200"></svg>
<p>10. EO data and insights help us demonstrate that our EO model encourages a focus on protecting the planet.</p>
<svg xmlns="http://www.w3.org/2000/svg" id="svg12_10" width="800" height="200"></svg>
<p>Q40 Please add any additional comments:</p>
<hr>
</body>
</html>

View File

@@ -1,177 +0,0 @@
function doBigWhiteTriangle(id){
const svg = document.getElementById(id);
// Triangle settings
const sideLength = 740;
const centerX = 435;
const centerY = 493;
const angleOffset = -90 * (Math.PI / 180); // Start at top
// Generate 3 equilateral triangle points
const points = [];
for (let i = 0; i < 3; i++) {
const angle = angleOffset + i * (2 * Math.PI / 3); // 120° steps
const x = centerX + (sideLength / Math.sqrt(3)) * Math.cos(angle);
const y = centerY + (sideLength / Math.sqrt(3)) * Math.sin(angle);
points.push(`${x},${y}`);
}
// Create the triangle
const triangle = document.createElementNS("http://www.w3.org/2000/svg", "polygon");
triangle.setAttribute("points", points.join(" "));
triangle.setAttribute("fill", "white");
//triangle.setAttribute("stroke", "black"); // Optional
//triangle.setAttribute("stroke-width", "2"); // Optional
svg.appendChild(triangle);
}
function doLittleWhiteTriangle(id){
const svg = document.getElementById(id);
// Triangle settings
const sideLength = 369;
const centerX = 250;
const centerY = 350;
const angleOffset = -90 * (Math.PI / 180); // Start at top
// Generate 3 equilateral triangle points
const points = [];
for (let i = 0; i < 3; i++) {
const angle = angleOffset + i * (2 * Math.PI / 3); // 120° steps
const x = centerX + (sideLength / Math.sqrt(3)) * Math.cos(angle);
const y = centerY + (sideLength / Math.sqrt(3)) * Math.sin(angle);
points.push(`${x},${y}`);
}
// Create the triangle
const triangle = document.createElementNS("http://www.w3.org/2000/svg", "polygon");
triangle.setAttribute("points", points.join(" "));
triangle.setAttribute("fill", "white");
//triangle.setAttribute("stroke", "black"); // Optional
//triangle.setAttribute("stroke-width", "2"); // Optional
svg.appendChild(triangle);
}
/*
function inlineStyles(svgElement) {
const allElements = svgElement.querySelectorAll('*');
const computedStyles = window.getComputedStyle(svgElement);
// Apply style to root SVG element
svgElement.setAttribute("style", computedStyles.cssText || "");
// Recursively apply computed styles to each element
allElements.forEach(el => {
const computed = window.getComputedStyle(el);
let inline = '';
for (let i = 0; i < computed.length; i++) {
const key = computed[i];
const value = computed.getPropertyValue(key);
inline += `${key}:${value};`;
}
el.setAttribute('style', inline);
});
}
*/
function inlineStyles(svgElement) {
const allElements = svgElement.querySelectorAll('*');
allElements.forEach(el => {
const computed = window.getComputedStyle(el);
const style = [];
for (let i = 0; i < computed.length; i++) {
const key = computed[i];
let value = computed.getPropertyValue(key);
// Replace currentColor with resolved color
if (value === 'currentcolor') {
value = computed.color;
}
style.push(`${key}:${value};`);
}
el.setAttribute('style', style.join(' '));
});
// Also inline root <svg>
const svgComputed = window.getComputedStyle(svgElement);
let rootStyle = '';
for (let i = 0; i < svgComputed.length; i++) {
const key = svgComputed[i];
let value = svgComputed.getPropertyValue(key);
if (value === 'currentcolor') {
value = svgComputed.color;
}
rootStyle += `${key}:${value};`;
}
svgElement.setAttribute('style', rootStyle);
}
/*
function makeSvgRightClickable(id) {
const svg = document.getElementById(id);
inlineStyles(svg);
// Ensure SVG has proper namespace
svg.setAttribute("xmlns", "http://www.w3.org/2000/svg");
// Serialize SVG
const svgData = new XMLSerializer().serializeToString(svg);
const svgBlob = new Blob([svgData], { type: "image/svg+xml;charset=utf-8" });
const url = URL.createObjectURL(svgBlob);
// Create image element
const img = document.createElement("img");
img.src = url;
img.width = svg.width.baseVal.value;
img.height = svg.height.baseVal.value;
img.alt = "Right-click to save SVG image";
// Replace or insert after SVG
//svg.style.display = "none"; // hide original
svg.parentNode.insertBefore(img, svg.nextSibling);
}
// Call the function after D3 has drawn the SVG
//makeSvgRightClickable("id");
*/
function makeSvgRightClickable(id) {
const svg = document.getElementById(id);
inlineStyles(svg);
// Set namespace
svg.setAttribute("xmlns", "http://www.w3.org/2000/svg");
// Ensure width and height are set
if (!svg.hasAttribute("width")) svg.setAttribute("width", svg.getBoundingClientRect().width);
if (!svg.hasAttribute("height")) svg.setAttribute("height", svg.getBoundingClientRect().height);
// Serialize
const svgData = new XMLSerializer().serializeToString(svg);
const svgBlob = new Blob([svgData], { type: "image/svg+xml;charset=utf-8" });
const url = URL.createObjectURL(svgBlob);
// Create image element
const img = document.createElement("img");
img.src = url;
img.width = svg.getAttribute("width");
img.height = svg.getAttribute("height");
img.alt = "Right-click to save SVG image";
svg.style.display = "none";
svg.parentNode.insertBefore(img, svg.nextSibling);
}

BIN
favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

BIN
favicon_io.zip Normal file

Binary file not shown.

66
fillcomments.js Normal file
View File

@@ -0,0 +1,66 @@
function doComments(id,qid) {
let survey=document.getElementById("surveyId").value;
console.log("Survey is:"+survey);
let Q1=document.getElementById("location").value;
let Q2=document.getElementById("level").value;
let Q3=document.getElementById("gov").value;
// Create the form data object
const formData = new FormData();
formData.append('qid', qid);
formData.append('survey', survey);
formData.append('Q1', Q1);
formData.append('Q2', Q2);
formData.append('Q3', Q3);
// Send the form data using fetch
fetch('get_text_data.php', {
method: 'POST',
body: formData
})
.then(response => response.text())
.then(data => {
// Output result
//console.log(data);
const recordNo = parseInt(document.getElementById('record_no').textContent, 10);
//if (recordNo <8){
// return;
//}
const parsed = JSON.parse(data);
const div = document.getElementById(id);
console.log(div);
div.innerHTML = "";
// Create a new <ul> element
const ul = document.createElement("ul");
parsed.forEach(item => {
const li = document.createElement("li");
li.textContent = item.text;
ul.appendChild(li);
console.log(item.text);
});
// Optionally, add some list items
// Append the <ul> to the div
div.appendChild(ul);
// Re-enable body, and revert cursor
return;
})
.catch(error => {
console.error('Error:', error);
});
}

View File

@@ -124,15 +124,15 @@ if (isset($data['responses']) && is_array($data['responses'])) {
'startDate' => $startDateFormatted, 'startDate' => $startDateFormatted,
'endDate' => $endDateFormatted, 'endDate' => $endDateFormatted,
'status' => $response['values']['status'], 'status' => $response['values']['status'],
'ipAddress' => $response['values']['ipAddress'], 'ipAddress' => $response['values']['ipAddress'] ?? '0.0.0.0',
'progress' => $response['values']['progress'], 'progress' => $response['values']['progress'],
'duration' => $response['values']['duration'], 'duration' => $response['values']['duration'],
'finished' => $response['values']['finished'], 'finished' => $response['values']['finished'],
'recordedDate' => $recordedDateFormatted, 'recordedDate' => $recordedDateFormatted,
'locationLatitude' => $response['values']['locationLatitude'], 'locationLatitude' => $response['values']['locationLatitude'] ?? '0.0',
'locationLongitude' => $response['values']['locationLongitude'], 'locationLongitude' => $response['values']['locationLongitude'] ?? '0.0',
'distributionChannel' => $response['values']['distributionChannel'], 'distributionChannel' => $response['values']['distributionChannel'],
'userLanguage' => $response['values']['userLanguage'] 'userLanguage' => $response['values']['userLanguage'] ?? 'en'
]; ];

31
getQuestionsData.html Normal file
View File

@@ -0,0 +1,31 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Customised Qualifiers</title>
</head>
<body>
<h1>Importing of customised qualifiers</h1>
<p>This form allows you to export the customised qualifying information relating to the survey</p>
<p>You will need to enter the appropriate surveyId, and then click submit, and the data will be imported
into the <a href='./reportTemplate.html'>analysis tool</a></p>
</p>
<p>If you enter no surveyId or invalid one, then the script will check for that value and create a template anyway. At
some point in the future these invalid templates may have to be cleaned up?
</p>
<form action="getQuestionsData.php" method="POST">
<label for="surveyId">Survey ID:</label>
<input type="text" id="surveyId" name="surveyId" required>
<button type="submit">Submit</button>
</form>
</body>
</html>

123
getQuestionsData.php Normal file
View File

@@ -0,0 +1,123 @@
<?php
function insertOption($surveyId, $question, $option, $text, $pdo) {
// Prepare the SQL insert statement
$stmt = $pdo->prepare("INSERT INTO Filters (surveyId, FilterQuestion, FilterOption, Text) VALUES (:survey, :question, :option, :text)");
$stmt->execute([
':survey' => $surveyId,
':question' => $question,
':option' => $option,
':text' => $text
]);
}
// Load config
$config = require 'config.php';
$apiToken = $config['api_token'];
$dataCenter = $config['data_centre'];
// Get the survey ID from POST
$surveyId = $_POST['surveyId'] ?? null;
if (!$surveyId) {
//$surveyId="SV_cAstEvm4ZrPaqGi";
//$surveyId="SV_cwKjMqAqGxImjMG";
die("No survey ID provided.");
}
// Build URL
$baseUrl = "https://$dataCenter.qualtrics.com/API/v3";
$questionsUrl = "$baseUrl/survey-definitions/$surveyId/questions";
// Set headers
$headers = [
"X-API-TOKEN: $apiToken",
"Content-Type: application/json"
];
// Make request
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $questionsUrl);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
$response = curl_exec($ch);
if (curl_errno($ch)) {
die("Request error: " . curl_error($ch));
}
curl_close($ch);
// Output the raw JSON
//header('Content-Type: application/json');
//echo $response;
//var_dump($response);
$data = json_decode($response, true);
// Database connection (PDO)
$pdo = new PDO("mysql:host=localhost;dbname={$config['db_name']};charset=utf8mb4", $config['db_user'], $config['db_pass']);
//Check if the survey data has previously been inserted:
$checkSql = "SELECT 1 FROM Filters WHERE surveyId = :surveyId LIMIT 1";
$stmt = $pdo->prepare($checkSql);
$stmt->execute([
':surveyId' => $surveyId
]);
if ($stmt->fetch()) {
echo "Custom user qualifiers already exported for this particular survey ({$surveyId}) .<br>".PHP_EOL;
echo "This process only ever needs to be carried out once for each survey.<br>".PHP_EOL;
echo "Skipping data export.<br>".PHP_EOL;
echo "<br><br>";
echo "You now need to <a href='./getSurveys.php'>go and export the answer data</a> before you can <a href='./reportTemplate.html'>get the survey reports</a>";
return;
}
if (isset($data['result']['elements']) && is_array($data['result']['elements'])) {
foreach ($data['result']['elements'] as $element) {
if (isset($element['QuestionID'])) {
/* if (isset($element['QuestionID']) && $element['QuestionID'] === "QID71") {
//echo json_encode($element, JSON_PRETTY_PRINT) . PHP_EOL;
}*/
if (isset($element['QuestionID']) && $element['QuestionID'] === "QID68") {
echo "Survey: {$surveyId}, QuestionID: {$element['QuestionID']} : Description: {$element['QuestionDescription']} : 0 ". PHP_EOL;
insertOption($surveyId, 1, 0, $element['QuestionDescription'], $pdo);
foreach ($element['Choices'] as $index => $choice) {
insertOption($surveyId, 1, $index, $choice['Display'], $pdo);
echo "ID: $index, Display: " . $choice['Display'] . "<br>";
}
}
if (isset($element['QuestionID']) && $element['QuestionID'] === "QID69") {
echo "Survey: {$surveyId}, QuestionID: {$element['QuestionID']} : ";
echo "Description: {$element['QuestionDescription']} : 0 ". PHP_EOL;
insertOption($surveyId, 2, 0, $element['QuestionDescription'], $pdo);
foreach ($element['Choices'] as $index => $choice) {
insertOption($surveyId, 2, $index, $choice['Display'], $pdo);
echo "ID: $index, Display: " . $choice['Display'] . "<br>";
}
}
if (isset($element['QuestionID']) && $element['QuestionID'] === "QID71") {
echo "Survey: {$surveyId}, QuestionID: {$element['QuestionID']} : ";
echo "Description: {$element['QuestionDescription']} : 0 ". PHP_EOL;
insertOption($surveyId, 3, 0, $element['QuestionDescription'], $pdo);
foreach ($element['Choices'] as $index => $choice) {
insertOption($surveyId, 3, $index, $choice['Display'], $pdo);
echo "ID: $index, Display: " . $choice['Display'] . "<br>";
}
}
}
}
} else {
echo "No elements found.";
}
?>

View File

@@ -1,67 +1,58 @@
<!DOCTYPE html> <!DOCTYPE html>
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="UTF-8" /> <meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" /> <title>Form Submit Example</title>
<title>QID Value Counts</title> <style>
<style> textarea {
body { font-family: Arial, sans-serif; margin: 2em; } width: 100%;
label, input, button { font-size: 1em; margin: 0.5em 0; } height: 200px;
ul { list-style-type: none; padding-left: 0; } margin-top: 1em;
li { padding: 0.3em 0; } }
.error { color: red; } </style>
</style>
</head> </head>
<body> <body>
<h1>Query Value Counts by QID</h1> <form id="qidForm">
<label for="qidInput">Enter QID:</label>
<input type="text" id="qidInput" name="qid" required /><br />
<form id="qidForm"> <label for="survey">Survey: (SV_cwKjMqAqGxImjMG)</label>
<label for="qidInput">Enter QID:</label><br /> <input type="text" id="survey" name="survey" required /><br />
<input type="text" id="qidInput" name="qid" required />
<button type="submit">Get Counts</button>
</form>
<div id="results"></div> <label for="Q1">Enter Q1:</label>
<input type="text" id="Q1" name="Q1" /><br />
<script> <label for="Q2">Enter Q2:</label>
document.getElementById('qidForm').addEventListener('submit', function(e) { <input type="text" id="Q2" name="Q2" /><br />
e.preventDefault();
const qid = document.getElementById('qidInput').value.trim();
const resultsDiv = document.getElementById('results');
resultsDiv.innerHTML = 'Loading...';
fetch('get_qid_counts.php', { <label for="Q3">Enter Q3:</label>
method: 'POST', <input type="text" id="Q3" name="Q3" /><br />
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
body: new URLSearchParams({qid})
})
.then(response => response.json())
.then(data => {
if (data.error) {
resultsDiv.innerHTML = `<p class="error">${data.error}</p>`;
return;
}
if (!Array.isArray(data) || data.length === 0) { <button type="submit">Get Counts</button>
resultsDiv.innerHTML = '<p>No data found.</p>'; </form>
return;
}
let html = '<h2>Value Counts for ' + qid + '</h2><ul>'; <textarea id="output" readonly placeholder="Results will appear here..."></textarea>
data.forEach(item => {
html += `<li><strong>Value ${item.value}:</strong> ${item.count}</li>`; <script>
document.getElementById('qidForm').addEventListener('submit', async function (e) {
e.preventDefault();
const formData = new FormData(this);
try {
const response = await fetch('get_qid_counts.php', {
method: 'POST',
body: formData
});
const text = await response.text();
document.getElementById('output').value = text;
} catch (error) {
document.getElementById('output').value = 'Error: ' + error.message;
}
}); });
html += '</ul>'; </script>
resultsDiv.innerHTML = html;
})
.catch(err => {
resultsDiv.innerHTML = `<p class="error">Error: ${err.message}</p>`;
});
});
</script>
</body> </body>
</html> </html>

View File

@@ -4,6 +4,10 @@ header('Content-Type: application/json');
if (php_sapi_name() === 'cli') { if (php_sapi_name() === 'cli') {
echo "Running from command line.\n"; echo "Running from command line.\n";
$qid="QID2_7"; $qid="QID2_7";
$survey="SV_cwKjMqAqGxImjMG";
$q1 = 1;
$q2 = 2;
$q3 = 0;
} else { } else {
//echo "Running from browser.\n"; //echo "Running from browser.\n";
// Basic input validation and sanitization // Basic input validation and sanitization
@@ -12,6 +16,37 @@ if (php_sapi_name() === 'cli') {
exit; exit;
} }
$qid = $_POST['qid']; $qid = $_POST['qid'];
$input = $_POST['survey'] ?? '';
if (preg_match('/^SV_[a-zA-Z0-9]+$/', $input)) {
// Input is valid
$survey = $input;
} else {
// Invalid format
die("Invalid survey ID format.");
}
$q1 = filter_input(INPUT_POST, 'Q1', FILTER_VALIDATE_INT);
$q2 = filter_input(INPUT_POST, 'Q2', FILTER_VALIDATE_INT);
$q3 = filter_input(INPUT_POST, 'Q3', FILTER_VALIDATE_INT);
}
$qualifier = " AND s.surveyId = '${survey}'";
if ($q1 > 0) {
$qualifier.=" AND r.Q1 = " . $q1;
}
if ($q2 > 0) {
$qualifier.=" AND r.Q2 = " . $q2;
}
if ($q3 > 0) {
$qualifier.=" AND r.Q3 = " . $q3;
} }
@@ -33,15 +68,24 @@ $options = [
try { try {
$pdo = new PDO($dsn, $user, $pass, $options); $pdo = new PDO($dsn, $user, $pass, $options);
$sql = " $baseSql = "
SELECT value, COUNT(*) AS count SELECT
FROM Answers a.value,
WHERE QID = :qid COUNT(*) AS count
AND value BETWEEN -3 AND 3 FROM Answers a
GROUP BY value INNER JOIN Responses r ON a.responseId = r.id
ORDER BY value INNER JOIN Surveys s ON a.surveyId = s.id
WHERE a.QID = :qid
"; ";
//GROUP BY a.value, r.Q1, r.Q2, r.Q3
$sql = $baseSql . $qualifier . "
GROUP BY a.value
ORDER BY a.value;
";
//echo $sql;
$stmt = $pdo->prepare($sql); $stmt = $pdo->prepare($sql);
$stmt->execute(['qid' => $qid]); $stmt->execute(['qid' => $qid]);
$results = $stmt->fetchAll(); $results = $stmt->fetchAll();

88
get_qualifiers.php Normal file
View File

@@ -0,0 +1,88 @@
<?php
header('Content-Type: application/json');
if (php_sapi_name() === 'cli') {
echo "Running from command line.\n";
$surveyId="SV_cwKjMqAqGxImjMG";
} else {
//echo "Running from browser.\n";
// Basic input validation and sanitization
if (!isset($_POST['surveyId']) || empty($_POST['surveyId'])) {
echo json_encode(['error' => 'Missing surveyId parameter']);
exit;
}
$input = $_POST['surveyId'] ?? '';
if (preg_match('/^SV_[a-zA-Z0-9]+$/', $input)) {
// Input is valid
$surveyId = $input;
} else {
// Invalid format
die("Invalid survey ID format.");
}
}
// Database connection (adjust credentials accordingly)
//
$config = require 'config.php';
$host = $config['db_host'];
$db = $config['db_name'];
$user = $config['db_user'];
$pass = $config['db_pass'];
$charset = 'utf8mb4';
$dsn = "mysql:host=$host;dbname=$db;charset=$charset";
$options = [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
];
try {
$pdo = new PDO($dsn, $user, $pass, $options);
$sql = "
SELECT FilterQuestion, FilterOption, Text
FROM Filters
WHERE surveyId = :surveyid
ORDER BY FilterQuestion, FilterOption
";
//echo $sql;
$stmt = $pdo->prepare($sql);
$stmt->execute(['surveyid' => $surveyId]);
$results = $stmt->fetchAll();
//print_r($results);
$grouped = [];
foreach ($results as $result) {
$question = $result['FilterQuestion'];
$option = $result['FilterOption'];
$text = $result['Text'];
$grouped[$question][$option] = $text;
}
echo json_encode($grouped);
} catch (PDOException $e) {
echo json_encode(['error' => 'Database error: ' . $e->getMessage()]);
exit;
}

58
get_text_data.html Normal file
View File

@@ -0,0 +1,58 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Form Submit Example</title>
<style>
textarea {
width: 100%;
height: 200px;
margin-top: 1em;
}
</style>
</head>
<body>
<form id="qidForm">
<label for="qidInput">Enter QID:</label>
<input type="text" id="qidInput" name="qid" required /><br />
<label for="survey">Survey: (SV_cwKjMqAqGxImjMG)</label>
<input type="text" id="survey" name="survey" required /><br />
<label for="Q1">Enter Q1:</label>
<input type="text" id="Q1" name="Q1" /><br />
<label for="Q2">Enter Q2:</label>
<input type="text" id="Q2" name="Q2" /><br />
<label for="Q3">Enter Q3:</label>
<input type="text" id="Q3" name="Q3" /><br />
<button type="submit">Get Counts</button>
</form>
<textarea id="output" readonly placeholder="Results will appear here..."></textarea>
<script>
document.getElementById('qidForm').addEventListener('submit', async function (e) {
e.preventDefault();
const formData = new FormData(this);
try {
const response = await fetch('get_text_data.php', {
method: 'POST',
body: formData
});
const text = await response.text();
document.getElementById('output').value = text;
} catch (error) {
document.getElementById('output').value = 'Error: ' + error.message;
}
});
</script>
</body>
</html>

107
get_text_data.php Normal file
View File

@@ -0,0 +1,107 @@
<?php
header('Content-Type: application/json');
if (php_sapi_name() === 'cli') {
echo "Running from command line.\n";
$qid="QID64_TEXT";
$survey="SV_cwKjMqAqGxImjMG";
$q1 = 1;
$q2 = 2;
$q3 = 0;
} else {
//echo "Running from browser.\n";
// Basic input validation and sanitization
if (!isset($_POST['qid']) || empty($_POST['qid'])) {
echo json_encode(['error' => 'Missing QID parameter']);
exit;
}
$qid = $_POST['qid'];
$input = $_POST['survey'] ?? '';
if (preg_match('/^SV_[a-zA-Z0-9]+$/', $input)) {
// Input is valid
$survey = $input;
} else {
// Invalid format
die("Invalid survey ID format.");
}
$q1 = filter_input(INPUT_POST, 'Q1', FILTER_VALIDATE_INT);
$q2 = filter_input(INPUT_POST, 'Q2', FILTER_VALIDATE_INT);
$q3 = filter_input(INPUT_POST, 'Q3', FILTER_VALIDATE_INT);
}
$qualifier = " AND s.surveyId = '${survey}'";
if ($q1 > 0) {
$qualifier.=" AND r.Q1 = " . $q1;
}
if ($q2 > 0) {
$qualifier.=" AND r.Q2 = " . $q2;
}
if ($q3 > 0) {
$qualifier.=" AND r.Q3 = " . $q3;
}
// Database connection (adjust credentials accordingly)
//
$config = require 'config.php';
$host = $config['db_host'];
$db = $config['db_name'];
$user = $config['db_user'];
$pass = $config['db_pass'];
$charset = 'utf8mb4';
$dsn = "mysql:host=$host;dbname=$db;charset=$charset";
$options = [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
];
try {
$pdo = new PDO($dsn, $user, $pass, $options);
$sql = "
SELECT
a.text
FROM Answers a
INNER JOIN Responses r ON a.responseId = r.id
INNER JOIN Surveys s ON a.surveyId = s.id
WHERE a.QID = :qid
".$qualifier;
// echo $sql;
$stmt = $pdo->prepare($sql);
$stmt->execute(['qid' => $qid]);
$results = $stmt->fetchAll();
$json = json_encode($results);
echo $json;
if ($json === false) {
echo json_last_error_msg();
}
} catch (PDOException $e) {
echo json_encode(['error' => 'Database error: ' . $e->getMessage()]);
exit;
}

View File

@@ -1,62 +1,37 @@
<!DOCTYPE html> <!DOCTYPE html>
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="UTF-8" /> <meta charset="UTF-8">
<title>3-Axis Radar Chart with Ticks</title> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="https://d3js.org/d3.v7.min.js"></script> <title>QUALTRICS DATA ANALYSIS CONTROL PANEL</title>
<script src="./draw3axis.js"></script>
<style>
body {
font-family: sans-serif;
margin: 0;
padding: 0;
background-color: white;
}
svg {
background: white;
display: block;
margin: auto;
}
.axis line {
stroke: black;
stroke-width: 1.5px;
}
line.tick {
stroke: black;
stroke-width: 1;
}
polygon.grid {
fill: none;
stroke: rgba(200, 200, 200, 0.5); /* light grey with 50% opacity */
stroke-dasharray: 2,2;
}
.area {
fill: rgba(70, 130, 180, 0.3); /* steelblue with transparency */
stroke: rgba(70, 130, 180, 0.6);
stroke-width: 2;
}
.label {
font-size: 12px;
font-weight: bold;
text-anchor: middle;
}
</style>
</head> </head>
<body onload="drawGraph()"> <body>
<h1>Features</h1> <h1>PROCESS</h1>
<svg id="Q1" width="400" height="400"></svg> <ul>
<h1>Concepts</h1> <li>Get the survey identification number (SurveyID). This is a unique value associated with each survey and is of the
<svg id="Q2" width="400" height="400"></svg> form SV_cwKjMqAqGxImjMG. All of them start with 'SV_' and there is then a random selection of characters.
</li>
<li><a href='./getQuestionsData.html'>Import the 'customised' qualifier questions into the database.</a> This only has to be done once.</li>
<li><a href='./getSurveys.php'>Import the survey answers into the database.</a> This only has to be done once for each
survey, unless additional people complete the survey. If that happens, then repeating this process will import the additional completed surveys.
</li>
<li>Go to the either <a href='./reportTemplate.html'>Report Template v1.01</a> or <a href='./reportTemplate2.html'>Report Template v2.0</a> (as appropriate) and create the required analysis visuals for your report.
</li>
</ul>
<h1>TECHIE STUFF</h1>
<p>This web application exports data from the QUALTRICS survey:
"eoQ Framework - How to achieve great EO Template - 15 May 2025 Quality Assurance v2"
surveyId (SV_cwKjMqAqGxImjMG) or a clone of this survey.</p>
<p>This data is then imported into a local database in order to speed up display and avoid
costs associated with repeatedly accessing the QUALTRICS API. This requires 2 steps
before the data can be used as outlined in the process above.
</p>
<p>Data in the database is then manipulated to produce the graphics using a custom graphics
library using d3.js to produce the visualisations that you see in the <a href='./reportTemplate.html'>reportTemplate</a> file.
</p>
</body> </body>
</html> </html>

View File

@@ -4,6 +4,7 @@
<meta charset="UTF-8" /> <meta charset="UTF-8" />
<title>Bar Chart - Fixed Height Bars</title> <title>Bar Chart - Fixed Height Bars</title>
<script src="https://d3js.org/d3.v7.min.js"></script> <script src="https://d3js.org/d3.v7.min.js"></script>
<script src="./drawbar.js"></script>
<style> <style>
body { body {
font-family: sans-serif; font-family: sans-serif;
@@ -35,113 +36,29 @@
</style> </style>
</head> </head>
<body> <body onload="startdrawing();">
<p>This is a minimal example of the barchart created as part of a Telos Partners contract
copyright 2025, and released under the <a href="https://opensource.org/license/mit">MIT license.</a>
</p>
<svg id="bargraph" width="800" height="200"></svg>
<svg width="600" height="200"></svg>
<script> <script>
const svg = d3.select("svg");
const width = +svg.attr("width");
const height = +svg.attr("height");
const margin = { top: 40, right: 30, bottom: 40, left: 30 };
const data = { function startdrawing() {
"-3": 0, const data = {
"-2": 1, "-3": 0,
"-1": 3, "-2": 1,
"0": 0, "-1": 3,
"1": 2, "0": 0,
"2": 0, "1": 2,
"3": 6 "2": 0,
}; "3": 6
};
// Convert object to array of {key, value} drawBar('#bargraph',data);
const dataArray = Object.entries(data).map(([key, count]) => ({ }
key: +key,
count: count,
show: count > 0
}));
// Scales
const x = d3.scaleBand()
.domain(d3.range(-3, 4)) // [-3, -2, ..., 3]
.range([margin.left, width - margin.right])
.padding(0); //space between bars
const y = d3.scaleLinear()
.domain([0, 1]) // fixed height of 1
.range([height - margin.bottom, margin.top]);
// X-axis
svg.append("g")
.attr("transform", `translate(0,${height - margin.bottom})`)
.call(d3.axisBottom(x).tickFormat(d => d))
.attr("class", "axis");
// Draw bars
svg.selectAll(".bar")
.data(dataArray)
.enter()
.append("rect")
.attr("class", "bar")
.attr("x", d => x(d.key))
.attr("y", d => d.show ? y(1) : y(0))
.attr("width", x.bandwidth())
.attr("height", d => d.show ? y(0) - y(1) : 0);
//Add values above bars:
svg.selectAll(".bar-label")
.data(dataArray)
.enter()
.append("text")
.attr("class", "bar-label")
.attr("x", d => x(d.key) + x.bandwidth() / 2)
.attr("y", d => d.count > 0 ? y(1) - 5 : y(0)) // 5px above the bar
.attr("text-anchor", "middle")
.attr("font-size", "12px")
.attr("fill", "black")
.text(d => d.count > 0 ? d.count : "");
// Display average line
const totalCount = d3.sum(dataArray, d => d.count);
const weightedSum = d3.sum(dataArray, d => d.key * d.count);
const average = totalCount > 0 ? weightedSum / totalCount : 0;
const xLinear = d3.scaleLinear()
.domain([-3, 3])
.range([margin.left + x.bandwidth() / 2, width - margin.right - x.bandwidth() / 2]);
const averageX = xLinear(average);
// Draw the vertical red line
svg.append("line")
.attr("x1", averageX)
.attr("x2", averageX)
.attr("y1", y(0))
.attr("y2", y(1) - 20) //raise by 20px
.attr("stroke", "red")
.attr("stroke-width", 2)
.attr("stroke-dasharray", "4,2"); // Optional dashed line
// Add "Average" label above the line
const formatAvg = d3.format(".2f");
svg.append("text")
.attr("x", averageX)
.attr("y", y(1) - 30) //was -10
.attr("text-anchor", "middle")
.attr("fill", "red")
.attr("font-size", "12px")
.text(`Average(mean): ${formatAvg(average)}`);
// Title beneath the graph
svg.append("text")
.attr("x", width / 2)
.attr("y", height - 5) // Just below the x-axis
.attr("text-anchor", "middle")
.attr("font-size", "14px")
.attr("fill", "black")
.text("Demo bar graph");
</script> </script>

95
insertQualifiers.js Normal file
View File

@@ -0,0 +1,95 @@
function insertQualifiers(){
//alert("qualifying....");
surveyId = document.getElementById("surveyId").value;
if (/^SV_[a-zA-Z0-9]+$/.test(surveyId)) {
console.log("Valid: starts with SV_ and followed by letters/numbers only");
console.log(surveyId);
} else {
console.log("Invalid: must start with SV_ and be followed by only letters or numbers");
alert("Invalid survey ID");
return;
}
// Create the form data object
const formData = new FormData();
formData.append('surveyId', surveyId);
// Send the form data using fetch
fetch('get_qualifiers.php', {
method: 'POST',
body: formData
})
.then(response => response.text())
.then(data => {
// Output result
console.log(data);
const parsed = JSON.parse(data);
document.querySelector('label[for="location"]').textContent = parsed["1"][0];
// .shift(); //
parsed["1"][0] = "All";
select = document.getElementById('location');
optionCount = select.options.length;
if (optionCount > 1) {return;}
select.innerHTML = ''; // removes all option elements inside
parsed["1"].forEach((loc, index) => {
const option = document.createElement("option");
option.value = index;
option.textContent = loc;
select.appendChild(option);
});
document.querySelector('label[for="level"]').textContent = parsed["2"][0];
// .shift(); //
parsed["2"][0] = "All";
select = document.getElementById('level');
optionCount = select.options.length;
if (optionCount > 1) {return;}
select.innerHTML = ''; // removes all option elements inside
parsed["2"].forEach((loc, index) => {
const option = document.createElement("option");
option.value = index;
option.textContent = loc;
select.appendChild(option);
});
document.querySelector('label[for="gov"]').textContent = parsed["3"][0];
parsed["3"][0] = "All";
select = document.getElementById('gov');
optionCount = select.options.length;
if (optionCount > 1) {return;}
select.innerHTML = ''; // removes all option elements inside
parsed["3"].forEach((loc, index) => {
const option = document.createElement("option");
option.value = index;
option.textContent = loc;
select.appendChild(option);
});
//Disable the surveyId input
document.getElementById("surveyId").disabled = true;
/*document.getElementById("record_no").textContent = total;
if (total < 9){
return;
}*/
// return data; // Should be an array like [{ value: -3, count: 2 }, ..., { value: 3, count: 5 }]
})
.catch(error => {
console.error('Error:', error);
});
}

View File

@@ -1,18 +1,18 @@
function RAGGED(average){ function RAGGED(average){
// This returns the correct colour red, amber or gree depending on the value presented // This returns the correct colour red, amber or green depending on the value presented
if (average <= -1) { if (average <= -1) {
return "red"; return "red";
} }
if (average >= 1) { if (average >= 2) {
return "green"; return "green";
} }
return "#ffbf00"; return "#ff9b21";
} }
function getAverage(prefix) { function getAverage(prefix) {
console.log("Prefix:", prefix); //console.log("Prefix:", prefix);
const elements = Array.from(document.querySelectorAll(`svg[id^="${prefix}"] tspan.average`)); const elements = Array.from(document.querySelectorAll(`svg[id^="${prefix}"] tspan.average`));
@@ -32,15 +32,54 @@ function getAverage(prefix) {
} }
const avg = numbers.reduce((sum, n) => sum + n, 0) / numbers.length; const avg = numbers.reduce((sum, n) => sum + n, 0) / numbers.length;
//console.log("Average of averages:", avg); console.log("Average of averages:", avg);
return avg; return avg;
} }
function loaded(){ function getSurveyData(){
console.log("loaded");
let amber = '#ffbf00'; // Reset all comments
document.getElementById("greatOwners").innerHTML = "";
document.getElementById("greatLeaders").innerHTML = "";
document.getElementById("greatGovernance").innerHTML = "";
document.getElementById("greatCulture").innerHTML = "";
document.getElementById("greatEngagement").innerHTML = "";
document.getElementById("greatStewardship").innerHTML = "";
document.getElementById("greatStrategy").innerHTML = "";
document.getElementById("greatInnovation").innerHTML = "";
document.getElementById("greatAdvantage").innerHTML = "";
document.getElementById("greatMeasurement").innerHTML = "";
document.getElementById("greatEvaluation").innerHTML = "";
document.getElementById("greatImpact").innerHTML = "";
// Reset all averages
document.getElementById("Owners_avg").innerHTML = "";
document.getElementById("Leaders_avg").innerHTML = "";
document.getElementById("Governance_avg").innerHTML = "";
document.getElementById("Culture_avg").innerHTML = "";
document.getElementById("Engagement_avg").innerHTML = "";
document.getElementById("Stewardship_avg").innerHTML = "";
document.getElementById("Strategy_avg").innerHTML = "";
document.getElementById("Innovation_avg").innerHTML = "";
document.getElementById("Advantage_avg").innerHTML = "";
document.getElementById("Measurement_avg").innerHTML = "";
document.getElementById("Evaluation_avg").innerHTML = "";
document.getElementById("Impact_avg").innerHTML = "";
console.log("gettingSurveyData");
let survey=document.getElementById("surveyId").value;
console.log("Survey is:"+survey);
let Q1=document.getElementById("location").value;
let Q2=document.getElementById("level").value;
let Q3=document.getElementById("gov").value;
let amber = '#ff9b21';
//doBigWhiteTriangle('svg1'); //doBigWhiteTriangle('svg1');
//drawtriangle('#svg1','Roles','#008845',[0.5,0.6,0.5],'red', { x: 0, y: 350 },-0.7); //drawtriangle('#svg1','Roles','#008845',[0.5,0.6,0.5],'red', { x: 0, y: 350 },-0.7);
//drawtriangle('#svg1','Actions','#b2c8c4',[0.1,0.6,0.5],'green',{ x: 370, y: 350 },2.3); //drawtriangle('#svg1','Actions','#b2c8c4',[0.1,0.6,0.5],'green',{ x: 370, y: 350 },2.3);
@@ -55,156 +94,213 @@ function loaded(){
//EO ROLES //EO ROLES
//Great Employee Owners //Great Employee Owners
let average = doBarData('#svg1_1','QID35_7'); resetSvg('svg1_1');
let average = doBarData('#svg1_1','QID35_7',survey,Q1,Q2,Q3);
//makeSvgRightClickable('svg1_1'); //makeSvgRightClickable('svg1_1');
doBarData('#svg1_2','QID35_2'); resetSvg('svg1_2');
doBarData('#svg1_2','QID35_2',survey,Q1,Q2,Q3);
//makeSvgRightClickable('svg1_2'); //makeSvgRightClickable('svg1_2');
doBarData('#svg1_3','QID35_8'); resetSvg('svg1_3');
doBarData('#svg1_3','QID35_8',survey,Q1,Q2,Q3);
//makeSvgRightClickable('svg1_3'); //makeSvgRightClickable('svg1_3');
doBarData('#svg1_4','QID35_9'); resetSvg('svg1_4');
doBarData('#svg1_4','QID35_9',survey,Q1,Q2,Q3);
//makeSvgRightClickable('svg1_4'); //makeSvgRightClickable('svg1_4');
doBarData('#svg1_5','QID35_10'); resetSvg('svg1_5');
doBarData('#svg1_5','QID35_10',survey,Q1,Q2,Q3);
//makeSvgRightClickable('svg1_5'); //makeSvgRightClickable('svg1_5');
//Great EO Leaders //Great EO Leaders
average = doBarData('#svg2_1','QID36_7'); resetSvg('svg2_1');
average = doBarData('#svg2_1','QID36_7',survey,Q1,Q2,Q3);
//makeSvgRightClickable('svg1_1'); //makeSvgRightClickable('svg1_1');
doBarData('#svg2_2','QID36_2'); resetSvg('svg2_2');
doBarData('#svg2_2','QID36_2',survey,Q1,Q2,Q3);
//makeSvgRightClickable('svg1_2'); //makeSvgRightClickable('svg1_2');
doBarData('#svg2_3','QID36_8'); resetSvg('svg2_3');
doBarData('#svg2_3','QID36_8',survey,Q1,Q2,Q3);
//makeSvgRightClickable('svg1_3'); //makeSvgRightClickable('svg1_3');
doBarData('#svg2_4','QID36_9'); resetSvg('svg2_4');
doBarData('#svg2_4','QID36_9',survey,Q1,Q2,Q3);
//makeSvgRightClickable('svg1_4'); //makeSvgRightClickable('svg1_4');
//Great EO Governance //Great EO Governance
average = doBarData('#svg3_1','QID37_7'); resetSvg('svg3_1');
average = doBarData('#svg3_1','QID37_7',survey,Q1,Q2,Q3);
//makeSvgRightClickable('svg1_1'); //makeSvgRightClickable('svg1_1');
doBarData('#svg3_2','QID37_2'); resetSvg('svg3_2');
doBarData('#svg3_2','QID37_2',survey,Q1,Q2,Q3);
//makeSvgRightClickable('svg1_2'); //makeSvgRightClickable('svg1_2');
doBarData('#svg3_3','QID37_8'); resetSvg('svg3_3');
doBarData('#svg3_3','QID37_8',survey,Q1,Q2,Q3);
//makeSvgRightClickable('svg1_3'); //makeSvgRightClickable('svg1_3');
doBarData('#svg3_4','QID37_20'); resetSvg('svg3_4');
doBarData('#svg3_4','QID37_20',survey,Q1,Q2,Q3);
//makeSvgRightClickable('svg1_4'); //makeSvgRightClickable('svg1_4');
doBarData('#svg3_5','QID37_21'); resetSvg('svg3_5');
doBarData('#svg3_5','QID37_21',survey,Q1,Q2,Q3);
//makeSvgRightClickable('svg1_5'); //makeSvgRightClickable('svg1_5');
doBarData('#svg3_6','QID37_22'); resetSvg('svg3_6');
doBarData('#svg3_6','QID37_22',survey,Q1,Q2,Q3);
//makeSvgRightClickable('svg1_5'); //makeSvgRightClickable('svg1_5');
//EO APPROACH //EO APPROACH
//Great EO Culture //Great EO Culture
average = doBarData('#svg4_1','QID2_7'); resetSvg('svg4_1');
average = doBarData('#svg4_1','QID2_7',survey,Q1,Q2,Q3);
//makeSvgRightClickable('svg1_1'); //makeSvgRightClickable('svg1_1');
doBarData('#svg4_2','QID2_2'); resetSvg('svg4_2');
doBarData('#svg4_2','QID2_2',survey,Q1,Q2,Q3);
//makeSvgRightClickable('svg1_2'); //makeSvgRightClickable('svg1_2');
doBarData('#svg4_3','QID2_8'); resetSvg('svg4_3');
doBarData('#svg4_3','QID2_8',survey,Q1,Q2,Q3);
//makeSvgRightClickable('svg1_3'); //makeSvgRightClickable('svg1_3');
doBarData('#svg4_4','QID2_9'); resetSvg('svg4_4');
doBarData('#svg4_4','QID2_9',survey,Q1,Q2,Q3);
//makeSvgRightClickable('svg1_4'); //makeSvgRightClickable('svg1_4');
//Great EO Engagement //Great EO Engagement
average = doBarData('#svg5_1','QID33_7'); resetSvg('svg5_1');
average = doBarData('#svg5_1','QID33_7',survey,Q1,Q2,Q3);
//makeSvgRightClickable('svg1_1'); //makeSvgRightClickable('svg1_1');
doBarData('#svg5_2','QID33_2'); resetSvg('svg5_2');
doBarData('#svg5_2','QID33_2',survey,Q1,Q2,Q3);
//makeSvgRightClickable('svg1_2'); //makeSvgRightClickable('svg1_2');
doBarData('#svg5_3','QID33_8'); resetSvg('svg5_3');
doBarData('#svg5_3','QID33_8',survey,Q1,Q2,Q3);
//makeSvgRightClickable('svg1_3'); //makeSvgRightClickable('svg1_3');
doBarData('#svg5_4','QID33_9'); resetSvg('svg5_4');
doBarData('#svg5_4','QID33_9',survey,Q1,Q2,Q3);
//makeSvgRightClickable('svg1_4'); //makeSvgRightClickable('svg1_4');
//Great EO Stewardship //Great EO Stewardship
average = doBarData('#svg6_1','QID34_7'); resetSvg('svg6_1');
average = doBarData('#svg6_1','QID34_7',survey,Q1,Q2,Q3);
//makeSvgRightClickable('svg1_1'); //makeSvgRightClickable('svg1_1');
doBarData('#svg6_2','QID34_2'); resetSvg('svg6_2');
doBarData('#svg6_2','QID34_2',survey,Q1,Q2,Q3);
//makeSvgRightClickable('svg1_2'); //makeSvgRightClickable('svg1_2');
doBarData('#svg6_3','QID34_8'); resetSvg('svg6_3');
doBarData('#svg6_3','QID34_8',survey,Q1,Q2,Q3);
//makeSvgRightClickable('svg1_3'); //makeSvgRightClickable('svg1_3');
doBarData('#svg6_4','QID34_17'); resetSvg('svg6_4');
doBarData('#svg6_4','QID34_17',survey,Q1,Q2,Q3);
//makeSvgRightClickable('svg1_4'); //makeSvgRightClickable('svg1_4');
//EO ACTIONS //EO ACTIONS
//Great EO Strategy //Great EO Strategy
average = doBarData('#svg7_1','QID40_7'); resetSvg('svg7_1');
average = doBarData('#svg7_1','QID40_7',survey,Q1,Q2,Q3);
//makeSvgRightClickable('svg1_1'); //makeSvgRightClickable('svg1_1');
doBarData('#svg7_2','QID40_2'); resetSvg('svg7_2');
doBarData('#svg7_2','QID40_2',survey,Q1,Q2,Q3);
//makeSvgRightClickable('svg1_2'); //makeSvgRightClickable('svg1_2');
doBarData('#svg7_3','QID40_8'); resetSvg('svg7_3');
doBarData('#svg7_3','QID40_8',survey,Q1,Q2,Q3);
//makeSvgRightClickable('svg1_3'); //makeSvgRightClickable('svg1_3');
doBarData('#svg7_4','QID40_9'); resetSvg('svg7_4');
doBarData('#svg7_4','QID40_9',survey,Q1,Q2,Q3);
//makeSvgRightClickable('svg1_4'); //makeSvgRightClickable('svg1_4');
//Great EO Innovation //Great EO Innovation
average = doBarData('#svg8_1','QID41_7'); resetSvg('svg8_1');
average = doBarData('#svg8_1','QID41_7',survey,Q1,Q2,Q3);
//makeSvgRightClickable('svg1_1'); //makeSvgRightClickable('svg1_1');
doBarData('#svg8_2','QID41_2'); resetSvg('svg8_2');
doBarData('#svg8_2','QID41_2',survey,Q1,Q2,Q3);
//makeSvgRightClickable('svg1_2'); //makeSvgRightClickable('svg1_2');
doBarData('#svg8_3','QID41_19'); resetSvg('svg8_3');
doBarData('#svg8_3','QID41_19',survey,Q1,Q2,Q3);
//makeSvgRightClickable('svg1_3'); //makeSvgRightClickable('svg1_3');
doBarData('#svg8_4','QID41_20'); resetSvg('svg8_4');
doBarData('#svg8_4','QID41_20',survey,Q1,Q2,Q3);
//makeSvgRightClickable('svg1_4'); //makeSvgRightClickable('svg1_4');
doBarData('#svg8_5','QID41_21'); resetSvg('svg8_5');
doBarData('#svg8_5','QID41_21',survey,Q1,Q2,Q3);
//makeSvgRightClickable('svg1_5'); //makeSvgRightClickable('svg1_5');
//Great EO Advantage //Great EO Advantage
average = doBarData('#svg9_1','QID42_7'); resetSvg('svg9_1');
average = doBarData('#svg9_1','QID42_7',survey,Q1,Q2,Q3);
//makeSvgRightClickable('svg1_1'); //makeSvgRightClickable('svg1_1');
doBarData('#svg9_2','QID42_2'); resetSvg('svg9_2');
doBarData('#svg9_2','QID42_2',survey,Q1,Q2,Q3);
//makeSvgRightClickable('svg1_2'); //makeSvgRightClickable('svg1_2');
doBarData('#svg9_3','QID42_8'); resetSvg('svg9_3');
doBarData('#svg9_3','QID42_8',survey,Q1,Q2,Q3);
//makeSvgRightClickable('svg1_3'); //makeSvgRightClickable('svg1_3');
//EO RESULTS //EO RESULTS
//Great EO Measurement //Great EO Measurement
average = doBarData('#svg10_1','QID44_21'); resetSvg('svg10_1');
average = doBarData('#svg10_1','QID44_21',survey,Q1,Q2,Q3);
//makeSvgRightClickable('svg1_1'); //makeSvgRightClickable('svg1_1');
doBarData('#svg10_2','QID44_7'); resetSvg('svg10_2');
doBarData('#svg10_2','QID44_7',survey,Q1,Q2,Q3);
//makeSvgRightClickable('svg1_2'); //makeSvgRightClickable('svg1_2');
doBarData('#svg10_3','QID44_2'); resetSvg('svg10_3');
doBarData('#svg10_3','QID44_2',survey,Q1,Q2,Q3);
//makeSvgRightClickable('svg1_3'); //makeSvgRightClickable('svg1_3');
doBarData('#svg10_4','QID44_8'); resetSvg('svg10_4');
doBarData('#svg10_4','QID44_8',survey,Q1,Q2,Q3);
//makeSvgRightClickable('svg1_4'); //makeSvgRightClickable('svg1_4');
//Great EO Evaluation //Great EO Evaluation
average = doBarData('#svg11_1','QID45_24'); resetSvg('svg11_1');
average = doBarData('#svg11_1','QID45_24',survey,Q1,Q2,Q3);
//makeSvgRightClickable('svg1_1'); //makeSvgRightClickable('svg1_1');
doBarData('#svg11_2','QID45_25'); resetSvg('svg11_2');
doBarData('#svg11_2','QID45_25',survey,Q1,Q2,Q3);
//makeSvgRightClickable('svg1_2'); //makeSvgRightClickable('svg1_2');
doBarData('#svg11_3','QID45_26'); resetSvg('svg11_3');
doBarData('#svg11_3','QID45_26',survey,Q1,Q2,Q3);
//makeSvgRightClickable('svg1_3'); //makeSvgRightClickable('svg1_3');
doBarData('#svg11_4','QID45_29'); resetSvg('svg11_4');
doBarData('#svg11_4','QID45_29',survey,Q1,Q2,Q3);
//makeSvgRightClickable('svg1_4'); //makeSvgRightClickable('svg1_4');
//Great EO Impact //Great EO Impact
average = doBarData('#svg12_1','QID46_27'); resetSvg('svg12_1');
average = doBarData('#svg12_1','QID46_27',survey,Q1,Q2,Q3);
//makeSvgRightClickable('svg1_1'); //makeSvgRightClickable('svg1_1');
doBarData('#svg12_2','QID46_28'); resetSvg('svg12_2');
doBarData('#svg12_2','QID46_28',survey,Q1,Q2,Q3);
//makeSvgRightClickable('svg1_2'); //makeSvgRightClickable('svg1_2');
doBarData('#svg12_3','QID46_29'); resetSvg('svg12_3');
doBarData('#svg12_3','QID46_29',survey,Q1,Q2,Q3);
//makeSvgRightClickable('svg1_3'); //makeSvgRightClickable('svg1_3');
doBarData('#svg12_4','QID46_30'); resetSvg('svg12_4');
doBarData('#svg12_4','QID46_30',survey,Q1,Q2,Q3);
//makeSvgRightClickable('svg1_4'); //makeSvgRightClickable('svg1_4');
doBarData('#svg12_5','QID46_31'); resetSvg('svg12_5');
doBarData('#svg12_5','QID46_31',survey,Q1,Q2,Q3);
//makeSvgRightClickable('svg1_5'); //makeSvgRightClickable('svg1_5');
doBarData('#svg12_6','QID46_32'); resetSvg('svg12_6');
doBarData('#svg12_6','QID46_32',survey,Q1,Q2,Q3);
//makeSvgRightClickable('svg1_5'); //makeSvgRightClickable('svg1_5');
doBarData('#svg12_7','QID46_33'); resetSvg('svg12_7');
doBarData('#svg12_7','QID46_33',survey,Q1,Q2,Q3);
//makeSvgRightClickable('svg1_3'); //makeSvgRightClickable('svg1_3');
doBarData('#svg12_8','QID46_34'); resetSvg('svg12_8');
doBarData('#svg12_8','QID46_34',survey,Q1,Q2,Q3);
//makeSvgRightClickable('svg1_4'); //makeSvgRightClickable('svg1_4');
doBarData('#svg12_9','QID46_36'); resetSvg('svg12_9');
doBarData('#svg12_9','QID46_36',survey,Q1,Q2,Q3);
//makeSvgRightClickable('svg1_5'); //makeSvgRightClickable('svg1_5');
doBarData('#svg12_10','QID46_37'); resetSvg('svg12_10');
doBarData('#svg12_10','QID46_37',survey,Q1,Q2,Q3);
//makeSvgRightClickable('svg1_5'); //makeSvgRightClickable('svg1_5');
@@ -217,31 +313,37 @@ function loaded(){
// We now have access to all of the averages, so can calculate the basic triangle. // We now have access to all of the averages, so can calculate the basic triangle.
//EO ROLES //EO ROLES
let svg1_avg = (getAverage("svg1_")+3)/7; document.getElementById("Owners_avg").innerHTML = getAverage("svg1_").toFixed(2);
let svg2_avg = (getAverage("svg2_")+3)/7; document.getElementById("Leaders_avg").innerHTML = getAverage("svg2_").toFixed(2);
let svg3_avg = (getAverage("svg3_")+3)/7; document.getElementById("Governance_avg").innerHTML = getAverage("svg3_").toFixed(2);
let svg1_avg = (getAverage("svg1_")+3)/7; //Owners
let svg2_avg = (getAverage("svg2_")+3)/7; //Leaders
let svg3_avg = (getAverage("svg3_")+3)/7; //Governance
let roles_avg = (7*(svg1_avg+svg2_avg+svg3_avg)/3)-3; // this converts the scales lengths to the correct value let roles_avg = (7*(svg1_avg+svg2_avg+svg3_avg)/3)-3; // this converts the scales lengths to the correct value
console.log(svg1_avg,svg2_avg,svg3_avg, roles_avg); //console.log(svg1_avg,svg2_avg,svg3_avg, roles_avg);
doLittleWhiteTriangle('svg_roles'); doLittleWhiteTriangle('svg_roles');
//drawtriangle('#svg_roles','Roles','#008845',[0.25,0.5,0.75],'', { x: 0, y: 100 },roles_avg.toFixed(1)); //drawtriangle('#svg_roles','Roles','#008845',[0.25,0.5,0.75],'', { x: 0, y: 100 },roles_avg.toFixed(1));
drawtriangle('#svg_roles','Roles','#008845',[svg1_avg,svg2_avg,svg3_avg],'', { x: 0, y: 100 },roles_avg.toFixed(1)); drawtriangle('#svg_roles','Roles','#008845',[svg2_avg,svg3_avg,svg1_avg],'', { x: 0, y: 100 },roles_avg.toFixed(1));
//makeSvgRightClickable('svg_roles'); //makeSvgRightClickable('svg_roles');
doLittleWhiteTriangle('svg_roles_RAG'); doLittleWhiteTriangle('svg_roles_RAG');
drawtriangle('#svg_roles_RAG','Roles','#008845',[svg1_avg,svg2_avg,svg3_avg],RAGGED(roles_avg), { x: 0, y: 100 },roles_avg.toFixed(1)); drawtriangle('#svg_roles_RAG','Roles','#008845',[svg2_avg,svg3_avg,svg1_avg],RAGGED(roles_avg), { x: 0, y: 100 },roles_avg.toFixed(1));
//makeSvgRightClickable('svg_roles_RAG'); //makeSvgRightClickable('svg_roles_RAG');
doLittleWhiteTriangle('svg_roles_test'); doLittleWhiteTriangle('svg_roles_test');
drawtriangle('#svg_roles_test','Roles','#008845',[0.95,0.95,0.95],RAGGED(roles_avg), { x: 0, y: 100 },roles_avg.toFixed(1)); drawtriangle('#svg_roles_test','Roles','#008845',[0.9,0.9,0.9],RAGGED(roles_avg), { x: 0, y: 100 },roles_avg.toFixed(1));
//makeSvgRightClickable('svg_roles_test'); //makeSvgRightClickable('svg_roles_test');
//EO APPROACH //EO APPROACH
let svg4_avg = (getAverage("svg4_")+3)/7; document.getElementById("Culture_avg").innerHTML = getAverage("svg4_").toFixed(2);
let svg5_avg = (getAverage("svg5_")+3)/7; document.getElementById("Engagement_avg").innerHTML = getAverage("svg5_").toFixed(2);
let svg6_avg = (getAverage("svg6_")+3)/7; document.getElementById("Stewardship_avg").innerHTML = getAverage("svg6_").toFixed(2);
let svg4_avg = (getAverage("svg4_")+3)/7; //Culture
let svg5_avg = (getAverage("svg5_")+3)/7; //Engagement
let svg6_avg = (getAverage("svg6_")+3)/7; //Stewardship
let approach_avg = (7*(svg4_avg+svg5_avg+svg6_avg)/3)-3; // this converts the scales lengths to the correct value let approach_avg = (7*(svg4_avg+svg5_avg+svg6_avg)/3)-3; // this converts the scales lengths to the correct value
console.log(svg4_avg,svg5_avg,svg6_avg,approach_avg); console.log(svg4_avg,svg5_avg,svg6_avg,approach_avg);
@@ -255,34 +357,40 @@ function loaded(){
drawtriangle('#svg_approach_RAG','Approach','#ed4c0c',[svg4_avg,svg5_avg,svg6_avg],RAGGED(approach_avg), { x: 0, y: 100 },approach_avg.toFixed(1)); drawtriangle('#svg_approach_RAG','Approach','#ed4c0c',[svg4_avg,svg5_avg,svg6_avg],RAGGED(approach_avg), { x: 0, y: 100 },approach_avg.toFixed(1));
//makeSvgRightClickable('svg_approach_RAG'); //makeSvgRightClickable('svg_approach_RAG');
//doLittleWhiteTriangle('svg_approach_test'); doLittleWhiteTriangle('svg_approach_test');
//drawtriangle('#svg_approach_test','Approach','#ed4c0c',[0.95,0.95,0.95],RAGGED(approach_avg), { x: 0, y: 100 },approach_avg.toFixed(1)); drawtriangle('#svg_approach_test','Approach','#ed4c0c',[0.9,0.9,0.9],RAGGED(approach_avg), { x: 0, y: 100 },approach_avg.toFixed(1));
//makeSvgRightClickable('svg_approach_test'); //makeSvgRightClickable('svg_approach_test');
//EO ACTIONS //EO ACTIONS
let svg7_avg = (getAverage("svg7_")+3)/7; document.getElementById("Strategy_avg").innerHTML = getAverage("svg7_").toFixed(2);
let svg8_avg = (getAverage("svg8_")+3)/7; document.getElementById("Innovation_avg").innerHTML = getAverage("svg8_").toFixed(2);
let svg9_avg = (getAverage("svg9_")+3)/7; document.getElementById("Advantage_avg").innerHTML = getAverage("svg9_").toFixed(2);
let svg7_avg = (getAverage("svg7_")+3)/7; //Strategy
let svg8_avg = (getAverage("svg8_")+3)/7; //Innovation
let svg9_avg = (getAverage("svg9_")+3)/7; //Advantage
let actions_avg = (7*(svg7_avg+svg8_avg+svg9_avg)/3)-3; // this converts the scales lengths to the correct value let actions_avg = (7*(svg7_avg+svg8_avg+svg9_avg)/3)-3; // this converts the scales lengths to the correct value
console.log(svg7_avg,svg8_avg,svg9_avg,actions_avg); console.log(svg7_avg,svg8_avg,svg9_avg,actions_avg);
doLittleWhiteTriangle('svg_actions'); resetSvg('svg_actions');
//drawtriangle('#svg_actions','Actions','#b2c8c4',[0.25,0.5,0.75],'', { x: 0, y: 100 },actions_avg.toFixed(1)); //drawtriangle('#svg_actions','Actions','#b2c8c4',[0.25,0.5,0.75],'', { x: 0, y: 100 },actions_avg.toFixed(1));
drawtriangle('#svg_actions','Actions','#b2c8c4',[svg7_avg,svg8_avg,svg9_avg],'', { x: 0, y: 100 },actions_avg.toFixed(1)); drawtriangle('#svg_actions','Actions','#b2c8c4',[svg8_avg,svg9_avg,svg7_avg],'', { x: 0, y: 100 },actions_avg.toFixed(1));
//makeSvgRightClickable('svg_actions'); //makeSvgRightClickable('svg_actions');
doLittleWhiteTriangle('svg_actions_RAG'); resetSvg('svg_actions_RAG');
drawtriangle('#svg_actions_RAG','Actions','#b2c8c4',[svg7_avg,svg8_avg,svg9_avg],RAGGED(actions_avg), { x: 0, y: 100 },actions_avg.toFixed(1)); drawtriangle('#svg_actions_RAG','Actions','#b2c8c4',[svg8_avg,svg9_avg,svg7_avg],RAGGED(actions_avg), { x: 0, y: 100 },actions_avg.toFixed(1));
//makeSvgRightClickable('svg_actions_RAG'); //makeSvgRightClickable('svg_actions_RAG');
//doLittleWhiteTriangle('svg_actions_test'); resetSvg('svg_actions_test');
//drawtriangle('#svg_actions_test','Actions','#b2c8c4',[0.95,0.95,0.95],RAGGED(actions_avg), { x: 0, y: 100 },actions_avg.toFixed(1)); drawtriangle('#svg_actions_test','Actions','#b2c8c4',[0.9,0.9,0.9],RAGGED(actions_avg), { x: 0, y: 100 },actions_avg.toFixed(1));
//makeSvgRightClickable('svg_actions_test'); //makeSvgRightClickable('svg_actions_test');
//EO IMPACT //EO IMPACT
document.getElementById("Measurement_avg").innerHTML = getAverage("svg10_").toFixed(2);
document.getElementById("Evaluation_avg").innerHTML = getAverage("svg11_").toFixed(2);
document.getElementById("Impact_avg").innerHTML = getAverage("svg12_").toFixed(2);
let svg10_avg = (getAverage("svg10_")+3)/7; let svg10_avg = (getAverage("svg10_")+3)/7;
let svg11_avg = (getAverage("svg11_")+3)/7; let svg11_avg = (getAverage("svg11_")+3)/7;
let svg12_avg = (getAverage("svg12_")+3)/7; let svg12_avg = (getAverage("svg12_")+3)/7;
@@ -290,27 +398,35 @@ function loaded(){
console.log(svg10_avg,svg11_avg,svg12_avg,results_avg); console.log(svg10_avg,svg11_avg,svg12_avg,results_avg);
doLittleWhiteTriangle('svg_results'); resetSvg('svg_results');
//drawtriangle('#svg_results','Results','#74469',[0.25,0.5,0.75],'', { x: 0, y: 100 },impact_avg.toFixed(1)); //drawtriangle('#svg_results','Results','#74469',[0.25,0.5,0.75],'', { x: 0, y: 100 },impact_avg.toFixed(1));
drawtriangleinverted('#svg_results','Results','#74469c',[svg10_avg,svg11_avg,svg12_avg],'', { x: 0, y: 0 },results_avg.toFixed(1)); drawtriangleinverted('#svg_results','Results','#74469c',[svg11_avg,svg12_avg,svg10_avg],'', { x: 0, y: 0 },results_avg.toFixed(1));
//makeSvgRightClickable('svg_results'); //makeSvgRightClickable('svg_results');
doLittleWhiteTriangle('svg_results_RAG'); resetSvg('svg_results_RAG');
drawtriangleinverted('#svg_results_RAG','Results','#74469c',[svg10_avg,svg11_avg,svg12_avg],RAGGED(results_avg), { x: 0, y: 0 },results_avg.toFixed(1)); drawtriangleinverted('#svg_results_RAG','Results','#74469c',[svg11_avg,svg12_avg,svg10_avg],RAGGED(results_avg), { x: 0, y: 0 },results_avg.toFixed(1));
//makeSvgRightClickable('svg_results_RAG'); //makeSvgRightClickable('svg_results_RAG');
doLittleWhiteTriangle('svg_results_test'); resetSvg('svg_results_test');
drawtriangleinverted('#svg_results_test','Results','#74469c',[0.95,0.95,0.95],RAGGED(results_avg), { x: 0, y: 0 },results_avg.toFixed(1)); drawtriangleinverted('#svg_results_test','Results','#74469c',[0.9,0.9,0.9],RAGGED(results_avg), { x: 0, y: 0 },results_avg.toFixed(1));
//makeSvgRightClickable('svg_results_test'); //makeSvgRightClickable('svg_results_test');
//Clear up the pyramids by resetting the html
document.getElementById("pyramids").innerHTML = `
<svg class="pyramid" style="display: inline-block" xmlns="http://www.w3.org/2000/svg" id="svg_pyramid" width="1000" height="1000"></svg>
<svg class="pyramid" style="display: inline-block" xmlns="http://www.w3.org/2000/svg" id="svg_pyramid_RAG" width="1000" height="1000"></svg>
<svg class="pyramid no-axis no-text big-number" style="display: inline-block" xmlns="http://www.w3.org/2000/svg" id="svg_pyramid_RAG_test" width="1000" height="1000"></svg>
<svg class="pyramid no-axis big-number" style="display: inline-block" xmlns="http://www.w3.org/2000/svg" id="svg_pyramid_RAG_test2" width="1000" height="1000"></svg>
`;
doBigWhiteTriangle('svg_pyramid'); doBigWhiteTriangle('svg_pyramid');
drawtriangle('#svg_pyramid','Roles','#008845',[svg1_avg,svg2_avg,svg3_avg],'', { x: 0, y: 350 },roles_avg.toFixed(1)); drawtriangle('#svg_pyramid','Roles','#008845',[svg1_avg,svg2_avg,svg3_avg],'', { x: 0, y: 350 },roles_avg.toFixed(1));
drawtriangle('#svg_pyramid','Actions','#b2c8c4',[svg4_avg,svg5_avg,svg6_avg],'',{ x: 370, y: 350 },actions_avg.toFixed(1)); drawtriangle('#svg_pyramid','Actions','#b2c8c4',[svg4_avg,svg5_avg,svg6_avg],'',{ x: 370, y: 350 },actions_avg.toFixed(1));
drawtriangle('#svg_pyramid','Approach','#ed4c0c',[svg7_avg,svg8_avg,svg9_avg],'',{ x: 185, y: 30 },approach_avg.toFixed(1)); drawtriangle('#svg_pyramid','Approach','#ed4c0c',[svg7_avg,svg8_avg,svg9_avg],'',{ x: 185, y: 30 },approach_avg.toFixed(1));
drawtriangleinverted('#svg_pyramid','Results','#74469c',[svg10_avg,svg11_avg,svg12_avg],'',{ x: 185, y: 243},results_avg.toFixed(1)); drawtriangleinverted('#svg_pyramid','Results','#74469c',[svg10_avg,svg11_avg,svg12_avg],'',{ x: 185, y: 243},results_avg.toFixed(1));
makeSvgRightClickable('svg_pyramid'); //makeSvgRightClickable('svg_pyramid');
@@ -319,7 +435,7 @@ function loaded(){
drawtriangle('#svg_pyramid_RAG','Actions','#b2c8c4',[svg4_avg,svg5_avg,svg6_avg],RAGGED(actions_avg),{ x: 370, y: 350 },actions_avg.toFixed(1)); drawtriangle('#svg_pyramid_RAG','Actions','#b2c8c4',[svg4_avg,svg5_avg,svg6_avg],RAGGED(actions_avg),{ x: 370, y: 350 },actions_avg.toFixed(1));
drawtriangle('#svg_pyramid_RAG','Approach','#ed4c0c',[svg7_avg,svg8_avg,svg9_avg],RAGGED(approach_avg),{ x: 185, y: 30 },approach_avg.toFixed(1)); drawtriangle('#svg_pyramid_RAG','Approach','#ed4c0c',[svg7_avg,svg8_avg,svg9_avg],RAGGED(approach_avg),{ x: 185, y: 30 },approach_avg.toFixed(1));
drawtriangleinverted('#svg_pyramid_RAG','Results','#74469c',[svg10_avg,svg11_avg,svg12_avg],RAGGED(results_avg),{ x: 185, y: 243},results_avg.toFixed(1)); drawtriangleinverted('#svg_pyramid_RAG','Results','#74469c',[svg10_avg,svg11_avg,svg12_avg],RAGGED(results_avg),{ x: 185, y: 243},results_avg.toFixed(1));
makeSvgRightClickable('svg_pyramid_RAG'); //makeSvgRightClickable('svg_pyramid_RAG');
doBigWhiteTriangle('svg_pyramid_RAG_test'); doBigWhiteTriangle('svg_pyramid_RAG_test');
@@ -327,15 +443,15 @@ function loaded(){
drawtriangle('#svg_pyramid_RAG_test','Actions','#b2c8c4',[0.9,0.9,0.9],RAGGED(actions_avg),{ x: 370, y: 350 },actions_avg.toFixed(1)); drawtriangle('#svg_pyramid_RAG_test','Actions','#b2c8c4',[0.9,0.9,0.9],RAGGED(actions_avg),{ x: 370, y: 350 },actions_avg.toFixed(1));
drawtriangle('#svg_pyramid_RAG_test','Approach','#ed4c0c',[0.9,0.9,0.9],RAGGED(approach_avg),{ x: 185, y: 30 },approach_avg.toFixed(1)); drawtriangle('#svg_pyramid_RAG_test','Approach','#ed4c0c',[0.9,0.9,0.9],RAGGED(approach_avg),{ x: 185, y: 30 },approach_avg.toFixed(1));
drawtriangleinverted('#svg_pyramid_RAG_test','Results','#74469c',[0.9,0.9,0.9],RAGGED(results_avg),{ x: 185, y: 243},results_avg.toFixed(1)); drawtriangleinverted('#svg_pyramid_RAG_test','Results','#74469c',[0.9,0.9,0.9],RAGGED(results_avg),{ x: 185, y: 243},results_avg.toFixed(1));
makeSvgRightClickable('svg_pyramid_RAG_test'); //makeSvgRightClickable('svg_pyramid_RAG_test');
doBigWhiteTriangle('svg_pyramid_RAG_test2'); //doBigWhiteTriangle('svg_pyramid_RAG_test2');
drawtriangle('#svg_pyramid_RAG_test2','Roles','#008845',[0.95,0.95,0.95],RAGGED(roles_avg), { x: 0, y: 350 },roles_avg.toFixed(1)); //drawtriangle('#svg_pyramid_RAG_test2','Roles','#008845',[0.95,0.95,0.95],RAGGED(roles_avg), { x: 0, y: 350 },roles_avg.toFixed(1));
drawtriangle('#svg_pyramid_RAG_test2','Actions','#b2c8c4',[0.95,0.95,0.95],RAGGED(actions_avg),{ x: 370, y: 350 },actions_avg.toFixed(1)); //drawtriangle('#svg_pyramid_RAG_test2','Actions','#b2c8c4',[0.95,0.95,0.95],RAGGED(actions_avg),{ x: 370, y: 350 },actions_avg.toFixed(1));
drawtriangle('#svg_pyramid_RAG_test2','Approach','#ed4c0c',[0.95,0.95,0.95],RAGGED(approach_avg),{ x: 185, y: 30 },approach_avg.toFixed(1)); //drawtriangle('#svg_pyramid_RAG_test2','Approach','#ed4c0c',[0.95,0.95,0.95],RAGGED(approach_avg),{ x: 185, y: 30 },approach_avg.toFixed(1));
drawtriangleinverted('#svg_pyramid_RAG_test2','Results','#74469c',[0.95,0.95,0.95],RAGGED(results_avg),{ x: 185, y: 243},results_avg.toFixed(1)); //drawtriangleinverted('#svg_pyramid_RAG_test2','Results','#74469c',[0.95,0.95,0.95],RAGGED(results_avg),{ x: 185, y: 243},results_avg.toFixed(1));
makeSvgRightClickable('svg_pyramid_RAG_test2'); //makeSvgRightClickable('svg_pyramid_RAG_test2');
}, 800); }, 800);

View File

@@ -2,22 +2,77 @@
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="UTF-8" /> <meta charset="UTF-8" />
<title>EOQ Output</title> <title>LARRIE</title>
<script src="https://d3js.org/d3.v7.min.js"></script> <script src="https://d3js.org/d3.v7.min.js"></script>
<script src="./drawtriangle.js"></script> <script src="./drawtriangle.js"></script>
<script src="./drawtriangleinverted.js"></script> <script src="./drawtriangleinverted.js"></script>
<script src="./drawbar.js"></script> <script src="./drawbar.js"></script>
<script src="./fillcomments.js"></script>
<script src="./savesvg.js"></script> <script src="./savesvg.js"></script>
<script src="./populateGraphics.js"></script> <script src="./populateGraphics.js"></script>
<script src="./insertQualifiers.js"></script>
<style> <style>
body { body {
font-family: sans-serif; font-family: sans-serif;
margin: 0; margin: 5px;
padding: 0; padding: 0;
background-color: white; background-color: white;
} }
#surveyForm {
border: 20px solid white;
margin: 20px;
}
#surveyForm input#surveyId {
width: 315px;
}
#surveyForm input, #surveyForm label {
display: inline-block;
margin: 10px 0;
}
#surveyForm select {
width: 400px;
}
.pyramid {
width: auto;
height: auto;
}
.triangle {
width: auto;
height: 500;
}
.section {
margin: 30px;
}
.section p {
width: 30%;
text-align: left;
font-size: 20px;
font-weight: 600;
margin: 0;
float: left;
height: 200px; /* height should be the same as SVG */
display: flex;
align-items: center;
}
.section svg {
width: 70%;
margin: 0;
}
svg { svg {
background: none; background: none;
display: block; display: block;
@@ -45,16 +100,54 @@
font-weight: bold; font-weight: bold;
text-anchor: middle; text-anchor: middle;
} }
.comments {
height: 200px;
margin: 10px;
overflow-y: scroll;
background-color: #EEE;
}
.avgs {
color: #e40074;
}
</style> </style>
</head> </head>
<body onload="loaded()"> <body>
<h1>TITLE</h1> <h1>LARRIE - Logical Analysis and Reporting of Real Insights from Employees. (v1.0)</h1>
<p>Dates: TO </p> <p>You first need to enter the Survey ID, and press submit in order to get the correct groupings available to select from. The master template survey is SV_cwKjMqAqGxImjMG if you want a survey to just try out.</p>
<p>You will need to refresh this page in order to enter a new survey Id.</p>
<form id="surveyForm">
<label for="surveyId">Survey Id:</label>
<input type="text" id="surveyId" name="surveyId" />
<br>
<p>Number of completed surveys: </p> <label for="location">Where do you work in the organisation?:</label><br>
<select id="location" name="location">
<option value="0">All</option>
</select>
<br>
<label for="level">Where operational level do you work at in the organisation?:</label><br>
<select id="level" name="level">
<option value="0">All</option>
</select>
<br>
<label for="gov">Have you ever held one of the following roles in our business?:</label><br>
<select id="gov" name="gov">
<option value="0">All</option>
</select>
<br>
<br>
<button type="button" onclick="insertQualifiers(); getSurveyData();">Submit</button>
</form>
</div>
<p>Number of completed surveys. (No data will be shown if this is less than 8) : <span id="record_no">0</span></p>
<hr> <hr>
@@ -78,272 +171,334 @@
<p>To bring the EO Framework to life, we have created a simple health check - the eoQ™ test - to help you assess the strength of your current EO practice and signpost areas for possible improvement. It should take up to 20-30 minutes to complete the questionnaire.</p> <p>To bring the EO Framework to life, we have created a simple health check - the eoQ™ test - to help you assess the strength of your current EO practice and signpost areas for possible improvement. It should take up to 20-30 minutes to complete the questionnaire.</p>
<svg xmlns="http://www.w3.org/2000/svg" id="svg_pyramid" width="800" height="200"></svg> <div id="pyramids">
<svg class="pyramid" style="display: inline-block" xmlns="http://www.w3.org/2000/svg" id="svg_pyramid" width="1000" height="1000"></svg>
<svg class="pyramid" style="display: inline-block" xmlns="http://www.w3.org/2000/svg" id="svg_pyramid_RAG" width="1000" height="1000"></svg>
<svg class="pyramid no-axis no-text big-number" style="display: inline-block" xmlns="http://www.w3.org/2000/svg" id="svg_pyramid_RAG_test" width="1000" height="1000"></svg>
<svg class="pyramid no-axis big-number" style="display: inline-block" xmlns="http://www.w3.org/2000/svg" id="svg_pyramid_RAG_test2" width="1000" height="1000"></svg>
</div>
<hr> <hr>
<h2>1. EO Roles</h2> <h2>EO Roles</h2>
<p>It is vital that individual leaders, trustees, employee representatives and all employee owners understand their roles to ensure a successful EO business.</p> <p>It is vital that individual leaders, trustees, employee representatives and all employee owners understand their roles to ensure a successful EO business.</p>
<p><strong>To what extent does everyone fulfil their responsibilities in your business?</strong></p> <p><strong>To what extent does everyone fulfil their responsibilities in your business?</strong></p>
<svg style="display: inline-block" xmlns="http://www.w3.org/2000/svg" id="svg_roles" width="500" height="500"></svg> <svg class="triangle" style="display: inline-block" xmlns="http://www.w3.org/2000/svg" id="svg_roles" width="500" height="500"></svg>
<svg style="display: inline-block" xmlns="http://www.w3.org/2000/svg" id="svg_roles_RAG" width="500" height="500"></svg> <svg class="triangle" style="display: inline-block" xmlns="http://www.w3.org/2000/svg" id="svg_roles_RAG" width="500" height="500"></svg>
<svg class = "no-axis no-text big-number" style="display: inline-block" xmlns="http://www.w3.org/2000/svg" id="svg_roles_test" width="500" height="500"></svg> <svg class="triangle no-axis no-text big-number" style="display: inline-block" xmlns="http://www.w3.org/2000/svg" id="svg_roles_test" width="500" height="500"></svg>
<hr> <hr>
<h3>Q14 Great Employee Owners</h3> <h3>Great Employee Owners: <span id="Owners_avg" class="avgs"></span></h3>
<p>1. Our employee owners understand how to think and act like an owner.</p> <div class="section">
<svg xmlns="http://www.w3.org/2000/svg" id="svg1_1" width="800" height="200"></svg> <p>1. Our employee owners understand how to think and act like an owner.</p>
<p>2. Our employee owners are committed to making the business stronger.</p> <svg xmlns="http://www.w3.org/2000/svg" id="svg1_1" width="800" height="200"></svg>
<svg xmlns="http://www.w3.org/2000/svg" id="svg1_2" width="800" height="200"></svg> <p>2. Our employee owners are committed to making the business stronger.</p>
<p>3. Our employee owners understand how their actions impact the current years business results.</p> <svg xmlns="http://www.w3.org/2000/svg" id="svg1_2" width="800" height="200"></svg>
<svg xmlns="http://www.w3.org/2000/svg" id="svg1_3" width="800" height="200"></svg> <p>3. Our employee owners understand how their actions impact the current years business results.</p>
<p>4. Our employee owners understand how their actions help to execute our longer-term strategy.</p> <svg xmlns="http://www.w3.org/2000/svg" id="svg1_3" width="800" height="200"></svg>
<svg xmlns="http://www.w3.org/2000/svg" id="svg1_4" width="800" height="200"></svg> <p>4. Our employee owners understand how their actions help to execute our longer-term strategy.</p>
<p>5. Our employee owners understand how their actions strengthen our organisational culture.</p> <svg xmlns="http://www.w3.org/2000/svg" id="svg1_4" width="800" height="200"></svg>
<svg xmlns="http://www.w3.org/2000/svg" id="svg1_5" width="800" height="200"></svg> <p>5. Our employee owners understand how their actions strengthen our organisational culture.</p>
<p>Q15 Please add any additional comments:</p> <svg xmlns="http://www.w3.org/2000/svg" id="svg1_5" width="800" height="200"></svg>
</div>
<p>Please add any additional comments: <button onclick="doComments('greatOwners','QID48_TEXT')">Load comments</button></p>
<div class="comments" id="greatOwners">
</div>
<hr>
<h3>Great EO Leaders: <span id="Leaders_avg" class="avgs"></span></h3>
<div class="section">
<p>1. Our executive leaders (those responsible for leading the business) are committed to realising the full business potential of our employee ownership.</p>
<svg xmlns="http://www.w3.org/2000/svg" id="svg2_1" width="800" height="200"></svg>
<p>2. Our executive leaders regularly engage our people to contribute as owners to our vision and strategy.</p>
<svg xmlns="http://www.w3.org/2000/svg" id="svg2_2" width="800" height="200"></svg>
<p>3. Our executive leaders ensure our people feel connected to our purpose, values, owner mindset and behaviours.</p>
<svg xmlns="http://www.w3.org/2000/svg" id="svg2_3" width="800" height="200"></svg>
<p>4. Our executive leaders are role models for our desired owner behaviours and culture.</p>
<svg xmlns="http://www.w3.org/2000/svg" id="svg2_4" width="800" height="200"></svg>
</div>
<p>Please add any additional comments: <button onclick="doComments('greatLeaders','QID60_TEXT')">Load comments</button></p>
<div class="comments" id="greatLeaders">
</div>
<hr>
<h3>Great EO Governance: <span id="Governance_avg" class="avgs"></span></h3>
<div class="section">
<p>1. All our governance bodies (boards, councils and voice groups) are clear on their role in ensuring long-term success for the business and its employee owners.</p>
<svg xmlns="http://www.w3.org/2000/svg" id="svg3_1" width="800" height="200"></svg>
<p>2. All our governance bodies work collaboratively and effectively to promote an ownership culture.</p>
<svg xmlns="http://www.w3.org/2000/svg" id="svg3_2" width="800" height="200"></svg>
<p>3. All our governance bodies involve independent members who bring relevant experience, perspectives, and insights.</p>
<svg xmlns="http://www.w3.org/2000/svg" id="svg3_3" width="800" height="200"></svg>
<p>4. All our governance bodies effectively use the diverse skills, experiences and opinions of their members.</p>
<svg xmlns="http://www.w3.org/2000/svg" id="svg3_4" width="800" height="200"></svg>
<p>5. All our governance bodies fairly distribute ownership benefits in a manner that supports an ownership culture.</p>
<svg xmlns="http://www.w3.org/2000/svg" id="svg3_5" width="800" height="200"></svg>
<p>6. All our governance bodies make decisions in the long-term best interests of the organisation and its stakeholders.</p>
<svg xmlns="http://www.w3.org/2000/svg" id="svg3_6" width="800" height="200"></svg>
</div>
<p>Please add any additional comments: <button onclick="doComments('greatGovernance','QID59_TEXT')">Load comments</button></p>
<div class="comments" id="greatGovernance">
</div>
<hr> <hr>
<h3>Q16 Great EO Leaders</h3> <h2>EO Approach</h2>
<p>1. Our executive leaders (those responsible for leading the business) are committed to realising the full business potential of our employee ownership.</p>
<svg xmlns="http://www.w3.org/2000/svg" id="svg2_1" width="800" height="200"></svg>
<p>2. Our executive leaders regularly engage our people to contribute as owners to our vision and strategy.</p>
<svg xmlns="http://www.w3.org/2000/svg" id="svg2_2" width="800" height="200"></svg>
<p>3. Our executive leaders ensure our people feel connected to our purpose, values, owner mindset and behaviours.</p>
<svg xmlns="http://www.w3.org/2000/svg" id="svg2_3" width="800" height="200"></svg>
<p>4. Our executive leaders are role models for our desired owner behaviours and culture.</p>
<svg xmlns="http://www.w3.org/2000/svg" id="svg2_4" width="800" height="200"></svg>
<p>Q17 Please add any additional comments:</p>
<hr>
<h3>Q18 Great EO Governance</h3>
<p>1. All our governance bodies (boards, councils and voice groups) are clear on their role in ensuring long-term success for the business and its employee owners.</p>
<svg xmlns="http://www.w3.org/2000/svg" id="svg3_1" width="800" height="200"></svg>
<p>2. All our governance bodies work collaboratively and effectively to promote an ownership culture.</p>
<svg xmlns="http://www.w3.org/2000/svg" id="svg3_2" width="800" height="200"></svg>
<p>3. All our governance bodies involve independent members who bring relevant experience, perspectives, and insights.</p>
<svg xmlns="http://www.w3.org/2000/svg" id="svg3_3" width="800" height="200"></svg>
<p>4. All our governance bodies effectively use the diverse skills, experiences and opinions of their members.</p>
<svg xmlns="http://www.w3.org/2000/svg" id="svg3_4" width="800" height="200"></svg>
<p>5. All our governance bodies fairly distribute ownership benefits in a manner that supports an ownership culture.</p>
<svg xmlns="http://www.w3.org/2000/svg" id="svg3_5" width="800" height="200"></svg>
<p>6. All our governance bodies make decisions in the long-term best interests of the organisation and its stakeholders.</p>
<svg xmlns="http://www.w3.org/2000/svg" id="svg3_6" width="800" height="200"></svg>
<p>Q19 Please add any additional comments:</p>
<hr>
<h2>2. EO Approach</h2>
<p>EO core practices build a strong ownership culture which drives engagement levels and encourages owner behaviours, including how to promote and protect the business over the long-term.</p> <p>EO core practices build a strong ownership culture which drives engagement levels and encourages owner behaviours, including how to promote and protect the business over the long-term.</p>
<p><strong>To what extent are you effectively engaging your people as owners and building an ownership mindset?</strong></p> <p><strong>To what extent are you effectively engaging your people as owners and building an ownership mindset?</strong></p>
<svg class="triangle" style="display: inline-block" xmlns="http://www.w3.org/2000/svg" id="svg_approach" width="500" height="500"></svg>
<svg class="triangle" style="display: inline-block" xmlns="http://www.w3.org/2000/svg" id="svg_approach_RAG" width="500" height="500"></svg>
<svg class="triangle no-axis no-text big-number" style="display: inline-block" xmlns="http://www.w3.org/2000/svg" id="svg_approach_test" width="500" height="500"></svg>
<hr> <hr>
<h3>Great EO Culture</h3> <h3>Great EO Culture: <span id="Culture_avg" class="avgs"></span></h3>
<div class="section">
<p>1. Our behaviours as owners are improving the performance of the business.</p> <p>1. Our behaviours as owners are improving the performance of the business.</p>
<p>Insert bar chart</p> <svg xmlns="http://www.w3.org/2000/svg" id="svg4_1" width="800" height="200"></svg>
<p>2. Our people processes (recruitment, development, appraisal and reward) encourage and reward our desired owner behaviours.</p> <p>2. Our people processes (recruitment, development, appraisal and reward) encourage and reward our desired owner behaviours.</p>
<p>Insert bar chart</p> <svg xmlns="http://www.w3.org/2000/svg" id="svg4_2" width="800" height="200"></svg>
<p>3. Our culture creates a safe environment for feedback, learning, growth, health, well-being, inclusion and diversity.</p> <p>3. Our culture creates a safe environment for feedback, learning, growth, health, well-being, inclusion and diversity.</p>
<p>Insert bar chart</p> <svg xmlns="http://www.w3.org/2000/svg" id="svg4_3" width="800" height="200"></svg>
<p>4. Our culture and support for people develops and retains the right talent.</p> <p>4. Our culture and support for people develops and retains the right talent.</p>
<p>Insert bar chart</p> <svg xmlns="http://www.w3.org/2000/svg" id="svg4_4" width="800" height="200"></svg>
</div>
<p>Q22 Please add any additional comments:</p>
<p>INSERT 3 axis spider graph</p> <p>Please add any additional comments: <button onclick="doComments('greatCulture','QID47_TEXT')">Load comments</button></p>
<div class="comments" id="greatCulture">
</div>
<hr> <hr>
<h3>Q23 Great EO Engagement</h3> <h3>Great EO Engagement: <span id="Engagement_avg" class="avgs"></span></h3>
<div class="section">
<p>1. All of our managers (those responsible for managing people and processes) help ensure our people understand how and where decisions are made in the business.</p> <p>1. All of our managers (those responsible for managing people and processes) help ensure our people understand how and where decisions are made in the business.</p>
<p>Insert bar chart</p> <svg xmlns="http://www.w3.org/2000/svg" id="svg5_1" width="800" height="200"></svg>
<p>2. All of our managers help ensure our planning process, goal setting, and feedback channels enable people to influence decision-making as owners.</p> <p>2. All of our managers help ensure our planning process, goal setting, and feedback channels enable people to influence decision-making as owners.</p>
<p>Insert bar chart</p> <svg xmlns="http://www.w3.org/2000/svg" id="svg5_2" width="800" height="200"></svg>
<p>3. All of our managers help ensure our people clearly understand the connection between their owner behaviours and strategy, business performance and reward.</p> <p>3. All of our managers help ensure our people clearly understand the connection between their owner behaviours and strategy, business performance and reward.</p>
<p>Insert bar chart</p> <svg xmlns="http://www.w3.org/2000/svg" id="svg5_3" width="800" height="200"></svg>
<p>4. All of our managers help ensure our people are encouraged and empowered as owners to take responsibility for their own performance and contribution.</p> <p>4. All of our managers help ensure our people are encouraged and empowered as owners to take responsibility for their own performance and contribution.</p>
<p>Insert bar chart</p> <svg xmlns="http://www.w3.org/2000/svg" id="svg5_4" width="800" height="200"></svg>
</div>
<p>Q24 Please add any additional comments:</p> <p>Please add any additional comments: <button onclick="doComments('greatEngagement','QID62_TEXT')">Load comments</button></p>
<div class="comments" id="greatEngagement">
<p>INSERT 3 axis spider graph</p> </div>
<hr> <hr>
<h3>Q25 Great EO Stewardship</h3> <h3>Great EO Stewardship: <span id="Stewardship_avg" class="avgs"></span></h3>
<div class="section">
<p>1. During tough times, we balance the current and future needs of our employee owners with those of the organisation.</p> <p>1. During tough times, we balance the current and future needs of our employee owners with those of the organisation.</p>
<p>Insert bar chart</p> <svg xmlns="http://www.w3.org/2000/svg" id="svg6_1" width="800" height="200"></svg>
<p>2. Our employee owners identify and manage risks to protect our organisation and reputation.</p> <p>2. Our employee owners identify and manage risks to protect our organisation and reputation.</p>
<p>Insert bar chart</p> <svg xmlns="http://www.w3.org/2000/svg" id="svg6_2" width="800" height="200"></svg>
<p>3. We learn from tough times to become stronger in the future.</p> <p>3. We learn from tough times to become stronger in the future.</p>
<p>Insert bar chart</p> <svg xmlns="http://www.w3.org/2000/svg" id="svg6_3" width="800" height="200"></svg>
<p>4. Our culture encourages leaders, managers and specialists to develop candidates for their own succession.</p> <p>4. Our culture encourages leaders, managers and specialists to develop candidates for their own succession.</p>
<p>Insert bar chart</p> <svg xmlns="http://www.w3.org/2000/svg" id="svg6_4" width="800" height="200"></svg>
</div>
<p>Q26 Please add any additional comments:</p> <p>Please add any additional comments: <button onclick="doComments('greatStewardship','QID61_TEXT')">Load comments</button></p>
<div class="comments" id="greatStewardship">
<p>INSERT 3 axis spider graph</p> </div>
<hr> <hr>
<h2>3. EO Actions</h2> <h2>EO Actions</h2>
<p>An EO business can use its ownership model to provide commercial advantages as it faces into the world.</p> <p>An EO business can use its ownership model to provide commercial advantages as it faces into the world.</p>
<p><strong>To what extent are you harnessing the contributions of employees as owners to strengthen the quality and effectiveness of your strategy, innovation and commercial sustainability?</strong></p> <p><strong>To what extent are you harnessing the contributions of employees as owners to strengthen the quality and effectiveness of your strategy, innovation and commercial sustainability?</strong></p>
<svg class="triangle" style="display: inline-block" xmlns="http://www.w3.org/2000/svg" id="svg_actions" width="500" height="500"></svg>
<svg class="triangle" style="display: inline-block" xmlns="http://www.w3.org/2000/svg" id="svg_actions_RAG" width="500" height="500"></svg>
<svg class="triangle no-axis no-text big-number" style="display: inline-block" xmlns="http://www.w3.org/2000/svg" id="svg_actions_test" width="500" height="500"></svg>
<hr> <hr>
<h3>Q28 Great EO Strategy</h3> <h3>Great EO Strategy: <span id="Strategy_avg" class="avgs"></span></h3>
<div class="section">
<p>1. Our vision sets out the compelling benefits of our ownership model.</p> <p>1. Our vision sets out the compelling benefits of our ownership model.</p>
<p>Insert bar chart</p> <svg xmlns="http://www.w3.org/2000/svg" id="svg7_1" width="800" height="200"></svg>
<p>2. Our strategy builds on our unique strengths including our ownership model.</p> <p>2. Our strategy builds on our unique strengths including our ownership model.</p>
<p>Insert bar chart</p> <svg xmlns="http://www.w3.org/2000/svg" id="svg7_2" width="800" height="200"></svg>
<p>3. Our strategy outlines key activities and milestones that ensure our employee owners know how to contribute to a successful business.</p> <p>3. Our strategy outlines key activities and milestones that ensure our employee owners know how to contribute to a successful business.</p>
<p>Insert bar chart</p> <svg xmlns="http://www.w3.org/2000/svg" id="svg7_3" width="800" height="200"></svg>
<p>4. Our strategic approach to key markets ensures success by drawing on the experience and insights of our employee owners.</p> <p>4. Our strategic approach to key markets ensures success by drawing on the experience and insights of our employee owners.</p>
<p>Insert bar chart</p> <svg xmlns="http://www.w3.org/2000/svg" id="svg7_4" width="800" height="200"></svg>
</div>
<p>Q29 Please add any additional comments:</p> <p>Please add any additional comments: <button onclick="doComments('greatStrategy','QID49_TEXT')">Load comments</button></p>
<div class="comments" id="greatStrategy">
<p>INSERT 3 axis spider graph</p> </div>
<hr> <hr>
<h3>Q30 Great EO Innovation</h3> <h3>Great EO Innovation: <span id="Innovation_avg" class="avgs"></span></h3>
<div class="section">
<p>1. Our employee owners understand how our business works and delivers results.</p> <p>1. Our employee owners understand how our business works and delivers results.</p>
<p>Insert bar chart</p> <svg xmlns="http://www.w3.org/2000/svg" id="svg8_1" width="800" height="200"></svg>
<p>2. Our employee owners are committed to driving continuous improvement and growth.</p> <p>2. Our employee owners are committed to driving continuous improvement and growth.</p>
<p>Insert bar chart</p> <svg xmlns="http://www.w3.org/2000/svg" id="svg8_2" width="800" height="200"></svg>
<p>3. Our employee owners consistently contribute ideas that improve our business.</p> <p>3. Our employee owners consistently contribute ideas that improve our business.</p>
<p>Insert bar chart</p> <svg xmlns="http://www.w3.org/2000/svg" id="svg8_3" width="800" height="200"></svg>
<p>4. We provide clear channels and processes to capture, consider and provide feedback on new ideas and suggestions.</p> <p>4. We provide clear channels and processes to capture, consider and provide feedback on new ideas and suggestions.</p>
<p>Insert bar chart</p> <svg xmlns="http://www.w3.org/2000/svg" id="svg8_4" width="800" height="200"></svg>
<p>5. We successfully prioritise and manage these ideas to deliver improvements to our business.</p> <p>5. We successfully prioritise and manage these ideas to deliver improvements to our business.</p>
<p>Insert bar chart</p> <svg xmlns="http://www.w3.org/2000/svg" id="svg8_5" width="800" height="200"></svg>
</div>
<p>Q31 Please add any additional comments:</p> <p>Please add any additional comments: <button onclick="doComments('greatInnovation','QID64_TEXT')">Load comments</button></p>
<div class="comments" id="greatInnovation">
<p>INSERT 3 axis spider graph</p> </div>
<hr> <hr>
<h3>Great EO Advantage</h3> <h3>Great EO Advantage: <span id="Advantage_avg" class="avgs"></span></h3>
<div class="section">
<p>1. We leverage our EO status to differentiate our customer brand to win against our competitors in the market.</p> <p>1. We leverage our EO status to differentiate our customer brand to win against our competitors in the market.</p>
<p>Insert bar chart</p> <svg xmlns="http://www.w3.org/2000/svg" id="svg9_1" width="800" height="200"></svg>
<p>2. We leverage our EO status to differentiate our employer brand to strengthen our people proposition and attract talent.</p> <p>2. We leverage our EO status to differentiate our employer brand to strengthen our people proposition and attract talent.</p>
<p>Insert bar chart</p> <svg xmlns="http://www.w3.org/2000/svg" id="svg9_2" width="800" height="200"></svg>
<p>3. We leverage our EO status to differentiate our company brand to develop and retain high-quality relationships with suppliers and delivery partners.</p> <p>3. We leverage our EO status to differentiate our company brand to develop and retain high-quality relationships with suppliers and delivery partners.</p>
<p>Insert bar chart</p> <svg xmlns="http://www.w3.org/2000/svg" id="svg9_3" width="800" height="200"></svg>
</div>
<p>Q33 Please add any additional comments:</p> <p>Please add any additional comments: <button onclick="doComments('greatAdvantage','QID63_TEXT')">Load comments</button></p>
<div class="comments" id="greatAdvantage">
<p>INSERT 3 axis spider graph</p> </div>
<hr> <hr>
<h2>4. EO Results</h2>
<h2>EO Results</h2>
<p>Well-run EO businesses ensure decision-making is informed by relevant data and insights from inside the business and by benchmarking themselves against others. This helps set strategic focus, direct operational effort, ensure continuous improvement and drive better business performance.</p> <p>Well-run EO businesses ensure decision-making is informed by relevant data and insights from inside the business and by benchmarking themselves against others. This helps set strategic focus, direct operational effort, ensure continuous improvement and drive better business performance.</p>
<p><strong>Do you have the right EO data and insights to make this happen?</strong></p> <p><strong>Do you have the right EO data and insights to make this happen?</strong></p>
<svg class="triangle" style="display: inline-block" xmlns="http://www.w3.org/2000/svg" id="svg_results" width="500" height="500"></svg>
<svg class="triangle" style="display: inline-block" xmlns="http://www.w3.org/2000/svg" id="svg_results_RAG" width="500" height="500"></svg>
<svg class="triangle no-axis no-text big-number" style="display: inline-block" xmlns="http://www.w3.org/2000/svg" id="svg_results_test" width="500" height="500"></svg>
<hr> <hr>
<h3>Great EO Measurement: <span id="Measurement_avg" class="avgs"></span></h3>
<h3>Q35 Great EO Measurement</h3>
<div class="section">
<p>1. We are collecting data within the business that helps us understand how we benefit from our EO model.</p> <p>1. We are collecting data within the business that helps us understand how we benefit from our EO model.</p>
<p>Insert bar chart</p> <svg xmlns="http://www.w3.org/2000/svg" id="svg10_1" width="800" height="200"></svg>
<p>2. We measure and compare our EO performance with other similar EO businesses.</p> <p>2. We measure and compare our EO performance with other similar EO businesses.</p>
<p>Insert bar chart</p> <svg xmlns="http://www.w3.org/2000/svg" id="svg10_2" width="800" height="200"></svg>
<p>3. We measure and compare our performance with other businesses in our sector (regardless of their ownership model).</p> <p>3. We measure and compare our performance with other businesses in our sector (regardless of their ownership model).</p>
<p>Insert bar chart</p> <svg xmlns="http://www.w3.org/2000/svg" id="svg10_3" width="800" height="200"></svg>
<p>4. We pay attention to our impacts on more than just our employee owners (e.g. our customers, community or planet).</p> <p>4. We pay attention to our impacts on more than just our employee owners (e.g. our customers, community or planet).</p>
<p>Insert bar chart</p> <svg xmlns="http://www.w3.org/2000/svg" id="svg10_4" width="800" height="200"></svg>
</div>
<p>Q36 Please add any additional comments:</p>
<p>INSERT 3 axis spider graph</p> <p>Please add any additional comments: <button onclick="doComments('greatMeasurement','QID50_TEXT')">Load comments</button></p>
<div class="comments" id="greatMeasurement">
</div>
<hr> <hr>
<h3>Q37 Great EO Evaluation</h3> <h3>Great EO Evaluation: <span id="Evaluation_avg" class="avgs"></span></h3>
<div class="section">
<p>1. Our leaders and governance bodies use relevant EO data and insights to increase engagement levels among our people.</p> <p>1. Our leaders and governance bodies use relevant EO data and insights to increase engagement levels among our people.</p>
<p>Insert bar chart</p> <svg xmlns="http://www.w3.org/2000/svg" id="svg11_1" width="800" height="200"></svg>
<p>2. Our leaders and governance bodies use relevant EO data and insights to strengthen our ownership culture.</p> <p>2. Our leaders and governance bodies use relevant EO data and insights to strengthen our ownership culture.</p>
<p>Insert bar chart</p> <svg xmlns="http://www.w3.org/2000/svg" id="svg11_2" width="800" height="200"></svg>
<p>3. Our leaders and governance bodies use relevant EO data and insights to grow our business.</p> <p>3. Our leaders and governance bodies use relevant EO data and insights to grow our business.</p>
<p>Insert bar chart</p> <svg xmlns="http://www.w3.org/2000/svg" id="svg11_3" width="800" height="200"></svg>
<p>4. Our leaders and governance bodies use relevant EO data and insights to meet the aspirations of our current employee owners.</p> <p>4. Our leaders and governance bodies use relevant EO data and insights to meet the aspirations of our current employee owners.</p>
<p>Insert bar chart</p> <svg xmlns="http://www.w3.org/2000/svg" id="svg11_4" width="800" height="200"></svg>
</div>
<p>Q38 Please add any additional comments:</p> <p>Please add any additional comments: <button onclick="doComments('greatEvaluation','QID66_TEXT')">Load comments</button></p>
<div class="comments" id="greatEvaluation">
<p>INSERT 3 axis spider graph</p> </div>
<hr> <hr>
<h3>Great EO Impact: <span id="Impact_avg" class="avgs"></span></h3>
<h3>Q39 Great EO Impact</h3>
<div class="section">
<p>1. EO data and insights helps us demonstrate that our EO model encourages collaboration and team-working.</p> <p>1. EO data and insights helps us demonstrate that our EO model encourages collaboration and team-working.</p>
<p>Insert bar chart</p> <svg xmlns="http://www.w3.org/2000/svg" id="svg12_1" width="800" height="200"></svg>
<p>2. EO data and insights help us demonstrate that our EO model promotes engagement and job satisfaction.</p> <p>2. EO data and insights help us demonstrate that our EO model promotes engagement and job satisfaction.</p>
<p>Insert bar chart</p> <svg xmlns="http://www.w3.org/2000/svg" id="svg12_2" width="800" height="200"></svg>
<p>3. EO data and insights help us demonstrate that our EO model improves health and well-being for employee owners.</p> <p>3. EO data and insights help us demonstrate that our EO model improves health and well-being for employee owners.</p>
<p>Insert bar chart</p> <svg xmlns="http://www.w3.org/2000/svg" id="svg12_3" width="800" height="200"></svg>
<p>4. EO data and insights help us demonstrate that our EO model supports colleagues skills and capability.</p> <p>4. EO data and insights help us demonstrate that our EO model supports colleagues skills and capability.</p>
<p>Insert bar chart</p> <svg xmlns="http://www.w3.org/2000/svg" id="svg12_4" width="800" height="200"></svg>
<p>5. EO data and insights help us demonstrate that our EO model encourages strong ideas from colleagues.</p> <p>5. EO data and insights help us demonstrate that our EO model encourages strong ideas from colleagues.</p>
<p>Insert bar chart</p> <svg xmlns="http://www.w3.org/2000/svg" id="svg12_5" width="800" height="200"></svg>
<p>6. EO data and insights help us demonstrate that our EO model helps us recruit and retain talent.</p> <p>6. EO data and insights help us demonstrate that our EO model helps us recruit and retain talent.</p>
<p>Insert bar chart</p> <svg xmlns="http://www.w3.org/2000/svg" id="svg12_6" width="800" height="200"></svg>
<p>7. EO data and insights help us demonstrate that our EO model boosts personal commitment and productivity.</p> <p>7. EO data and insights help us demonstrate that our EO model boosts personal commitment and productivity.</p>
<p>Insert bar chart</p> <svg xmlns="http://www.w3.org/2000/svg" id="svg12_7" width="800" height="200"></svg>
<p>8. EO data and insights help us demonstrate that our EO model increases profitability.</p> <p>8. EO data and insights help us demonstrate that our EO model increases profitability.</p>
<p>Insert bar chart</p> <svg xmlns="http://www.w3.org/2000/svg" id="svg12_8" width="800" height="200"></svg>
<p>9. EO data and insights help us demonstrate that our EO model encourages more contribution to the local community.</p> <p>9. EO data and insights help us demonstrate that our EO model encourages more contribution to the local community.</p>
<p>Insert bar chart</p> <svg xmlns="http://www.w3.org/2000/svg" id="svg12_9" width="800" height="200"></svg>
<p>10. EO data and insights help us demonstrate that our EO model encourages a focus on protecting the planet.</p> <p>10. EO data and insights help us demonstrate that our EO model encourages a focus on protecting the planet.</p>
<p>Insert bar chart</p> <svg xmlns="http://www.w3.org/2000/svg" id="svg12_10" width="800" height="200"></svg>
</div>
<p>Q40 Please add any additional comments:</p> <p>Please add any additional comments: <button onclick="doComments('greatImpact','QID65_TEXT')">Load comments</button></p>
<div class="comments" id="greatImpact">
<p>INSERT 3 axis spider graph</p> </div>
<hr> <hr>

508
reportTemplate2.html Normal file
View File

@@ -0,0 +1,508 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>LARRIE</title>
<script src="https://d3js.org/d3.v7.min.js"></script>
<script src="./drawtriangle.js"></script>
<script src="./drawtriangleinverted.js"></script>
<script src="./drawbar.js"></script>
<script src="./fillcomments.js"></script>
<script src="./savesvg.js"></script>
<script src="./populateGraphics.js"></script>
<script src="./insertQualifiers.js"></script>
<style>
body {
font-family: sans-serif;
margin: 5px;
padding: 0;
background-color: white;
}
#surveyForm {
border: 20px solid white;
margin: 20px;
}
#surveyForm input#surveyId {
width: 315px;
}
#surveyForm input, #surveyForm label {
display: inline-block;
margin: 10px 0;
}
#surveyForm select {
width: 400px;
}
.pyramid {
width: auto;
height: auto;
}
.triangle {
width: auto;
height: 500;
}
.section {
margin: 30px;
}
.section p {
width: 30%;
text-align: left;
font-size: 20px;
font-weight: 600;
margin: 0;
float: left;
height: 200px; /* height should be the same as SVG */
display: flex;
align-items: center;
}
.section svg {
width: 70%;
margin: 0;
}
svg {
background: none;
display: block;
margin: auto;
}
.axis line {
stroke: black;
stroke-width: 1.5px;
}
line.tick {
stroke: black;
stroke-width: 1;
}
polygon.grid {
fill: none;
stroke: rgba(200, 200, 200, 0.5); /* light grey with 50% opacity */
stroke-dasharray: 2,2;
}
.label {
font-size: 12px;
font-weight: bold;
text-anchor: middle;
}
.comments {
height: 200px;
margin: 10px;
overflow-y: scroll;
background-color: #EEE;
}
.avgs {
color: #e40074;
}
</style>
</head>
<body>
<h1>LARRIE - Logical Analysis and Reporting of Real Insights from Employees. (v2.0)</h1>
<p>You first need to enter the Survey ID, and press submit in order to get the correct groupings available to select from. The master template survey is SV_cwKjMqAqGxImjMG if you want a survey to just try out.</p>
<p>You will need to refresh this page in order to enter a new survey Id.</p>
<form id="surveyForm">
<label for="surveyId">Survey Id:</label>
<input type="text" id="surveyId" name="surveyId" />
<br>
<label for="location">Where do you work in the organisation?:</label><br>
<select id="location" name="location">
<option value="0">All</option>
</select>
<br>
<label for="level">Where operational level do you work at in the organisation?:</label><br>
<select id="level" name="level">
<option value="0">All</option>
</select>
<br>
<label for="gov">Have you ever held one of the following roles in our business?:</label><br>
<select id="gov" name="gov">
<option value="0">All</option>
</select>
<br>
<br>
<button type="button" onclick="insertQualifiers(); getSurveyData();">Submit</button>
</form>
</div>
<p>Number of completed surveys. (No data will be shown if this is number is 0) : <span id="record_no">0</span></p>
<hr>
<h2>A Healthcheck for your Employee Owned Business</h2>
<p>Employee ownership (EO) has the potential to deliver outstanding benefits to individual owners and drive exceptional company performance.</p>
<p>However, research shows for that to happen a business must have excellent EO management practices in place.</p>
<p>To help identify EO best practice, we developed the EO Framework. It is built on insights gathered directly from leaders, senior decision-makers and employee owners on how they have successfully implemented impactful EO.</p>
<p>Developed by Great EOs founding partners in collaboration with the Employee Ownership Association, the Framework sets out four simple areas of EO management best practice:</p>
<ul>
<li><strong>EO Roles:</strong> Clearly defined EO roles through which leaders, trustees and employee owners all understand the part they play in making EO successful.</li>
<li><strong>EO Approach:</strong> Strong EO core practices that empower employees to contribute to success.</li>
<li><strong>EO Actions:</strong> Specific areas of EO management practice that can harness the full potential of employee ownership to strengthen strategy, innovation, and brand difference.</li>
<li><strong>EO Results:</strong> Structured and consistent ways of measuring EO practice to track and enhance owner benefits and business outcomes.</li>
</ul>
<p>To bring the Framework to life, we have created a simple healthcheck &hyphen; an eoQ&trade; test &hyphen; to help you assess the strength of your current EO practice and signpost you at areas for possible improvement. It should take upto 20-30 minutes to complete the questionnaire.</p>
<p>You are not expected to know absolutely everything about your business. Even if you are unsure when responding to any statement, please just give your best answer based on what you know right now.</p>
<div id="pyramids">
<svg class="pyramid" style="display: inline-block" xmlns="http://www.w3.org/2000/svg" id="svg_pyramid" width="1000" height="1000"></svg>
<svg class="pyramid" style="display: inline-block" xmlns="http://www.w3.org/2000/svg" id="svg_pyramid_RAG" width="1000" height="1000"></svg>
<svg class="pyramid no-axis no-text big-number" style="display: inline-block" xmlns="http://www.w3.org/2000/svg" id="svg_pyramid_RAG_test" width="1000" height="1000"></svg>
<svg class="pyramid no-axis big-number" style="display: inline-block" xmlns="http://www.w3.org/2000/svg" id="svg_pyramid_RAG_test2" width="1000" height="1000"></svg>
</div>
<hr>
<h2>EO Roles</h2>
<p>It is vital that individual leaders, trustees, employee representatives and all employee owners understand their roles to ensure a successful an EO business.</p>
<p><strong>To what extent does everyone fulfil their responsibilities in your business?</strong></p>
<svg class="triangle" style="display: inline-block" xmlns="http://www.w3.org/2000/svg" id="svg_roles" width="500" height="500"></svg>
<svg class="triangle" style="display: inline-block" xmlns="http://www.w3.org/2000/svg" id="svg_roles_RAG" width="500" height="500"></svg>
<svg class="triangle no-axis no-text big-number" style="display: inline-block" xmlns="http://www.w3.org/2000/svg" id="svg_roles_test" width="500" height="500"></svg>
<hr>
<h3>Great Employee Owners: <span id="Owners_avg" class="avgs"></span></h3>
<div class="section">
<p>1. Our employee owners understand how to think and act like an owner.</p>
<svg xmlns="http://www.w3.org/2000/svg" id="svg1_1" width="800" height="200"></svg>
<p>2. Our employee owners are committed to making the business stronger.</p>
<svg xmlns="http://www.w3.org/2000/svg" id="svg1_2" width="800" height="200"></svg>
<p>3. Our employee owners understand how their actions impact the current years business results.</p>
<svg xmlns="http://www.w3.org/2000/svg" id="svg1_3" width="800" height="200"></svg>
<p>4. Our employee owners understand how their actions help to execute our longer-term strategy.</p>
<svg xmlns="http://www.w3.org/2000/svg" id="svg1_4" width="800" height="200"></svg>
<p>5. Our employee owners understand how their actions strengthen our organisational culture.</p>
<svg xmlns="http://www.w3.org/2000/svg" id="svg1_5" width="800" height="200"></svg>
</div>
<p>Please add any additional comments: <button onclick="doComments('greatOwners','QID48_TEXT')">Load comments</button></p>
<div class="comments" id="greatOwners">
</div>
<hr>
<h3>Great EO Leaders: <span id="Leaders_avg" class="avgs"></span></h3>
<div class="section">
<p>1. Our executive leaders (those responsible for leading the business) are committed to realising the full business potential of our employee ownership.</p>
<svg xmlns="http://www.w3.org/2000/svg" id="svg2_1" width="800" height="200"></svg>
<p>2. Our executive leaders regularly engage our people to contribute as owners to our vision and strategy.</p>
<svg xmlns="http://www.w3.org/2000/svg" id="svg2_2" width="800" height="200"></svg>
<p>3. Our executive leaders ensure our people feel connected to our purpose, values, owner mindset and behaviours.</p>
<svg xmlns="http://www.w3.org/2000/svg" id="svg2_3" width="800" height="200"></svg>
<p>4. Our executive leaders are role models for our desired owner behaviours and culture.</p>
<svg xmlns="http://www.w3.org/2000/svg" id="svg2_4" width="800" height="200"></svg>
</div>
<p>Please add any additional comments: <button onclick="doComments('greatLeaders','QID60_TEXT')">Load comments</button></p>
<div class="comments" id="greatLeaders">
</div>
<hr>
<h3>Great EO Governance: <span id="Governance_avg" class="avgs"></span></h3>
<div class="section">
<p>1. Our governance bodies (operating board and trustees) effectively carry out their roles in ensuring success for the business and its employee owners.</p>
<svg xmlns="http://www.w3.org/2000/svg" id="svg3_1" width="800" height="200"></svg>
<p>2. Our governance bodies work collaboratively and effectively to promote an ownership culture.</p>
<svg xmlns="http://www.w3.org/2000/svg" id="svg3_2" width="800" height="200"></svg>
<p>3. Our governance bodies involve independent members who bring relevant experience, perspectives and insights.</p>
<svg xmlns="http://www.w3.org/2000/svg" id="svg3_3" width="800" height="200"></svg>
<p>4. Our governance bodies effectively use the diverse skills, experiences and opinions of their members.</p>
<svg xmlns="http://www.w3.org/2000/svg" id="svg3_4" width="800" height="200"></svg>
<p>5. Our governance bodies fairly distribute ownership benefits in a way that supports a strong ownership culture.</p>
<svg xmlns="http://www.w3.org/2000/svg" id="svg3_5" width="800" height="200"></svg>
<p>6. Our governance bodies make decisions in the long-term best interests of the organisation and its stakeholders.</p>
<svg xmlns="http://www.w3.org/2000/svg" id="svg3_6" width="800" height="200"></svg>
</div>
<p>Please add any additional comments: <button onclick="doComments('greatGovernance','QID59_TEXT')">Load comments</button></p>
<div class="comments" id="greatGovernance">
</div>
<hr>
<h2>EO Approach</h2>
<p>EO core practices build a strong ownership culture which drives engagement levels and encourages owner behaviours, including how to promote and protect the business over the long-term.</p>
<p><strong>To what extent are you effectively engaging your people as owners and building an ownership mindset?</strong></p>
<svg class="triangle" style="display: inline-block" xmlns="http://www.w3.org/2000/svg" id="svg_approach" width="500" height="500"></svg>
<svg class="triangle" style="display: inline-block" xmlns="http://www.w3.org/2000/svg" id="svg_approach_RAG" width="500" height="500"></svg>
<svg class="triangle no-axis no-text big-number" style="display: inline-block" xmlns="http://www.w3.org/2000/svg" id="svg_approach_test" width="500" height="500"></svg>
<hr>
<h3>Great EO Culture: <span id="Culture_avg" class="avgs"></span></h3>
<div class="section">
<p>1. Our behaviours as owners are improving the performance of the business.</p>
<svg xmlns="http://www.w3.org/2000/svg" id="svg4_1" width="800" height="200"></svg>
<p>2. Our people processes (recruitment, development, appraisal and reward) encourage and reward our desired owner behaviours.</p>
<svg xmlns="http://www.w3.org/2000/svg" id="svg4_2" width="800" height="200"></svg>
<p>3. Our culture creates a safe environment for honest feedback and meaningful contribution to business decisions.</p>
<svg xmlns="http://www.w3.org/2000/svg" id="svg4_3" width="800" height="200"></svg>
<p>4. Our culture celebrates our ownership model and uses it to build collaboration and connection.</p>
<svg xmlns="http://www.w3.org/2000/svg" id="svg4_4" width="800" height="200"></svg>
</div>
<p>Please add any additional comments: <button onclick="doComments('greatCulture','QID47_TEXT')">Load comments</button></p>
<div class="comments" id="greatCulture">
</div>
<hr>
<h3>Great EO Engagement: <span id="Engagement_avg" class="avgs"></span></h3>
<div class="section">
<p>1. Our managers (those responsible for managing people and processes) help ensure our people understand how and where decisions are made in the business.</p>
<svg xmlns="http://www.w3.org/2000/svg" id="svg5_1" width="800" height="200"></svg>
<p>2. Our managers help ensure our planning process, goal setting and feedback channels enable people to influence decision-making as owners.</p>
<svg xmlns="http://www.w3.org/2000/svg" id="svg5_2" width="800" height="200"></svg>
<p>3. Our managers help ensure our people clearly understand the connection between their owner behaviours and strategy, business performance and reward.</p>
<svg xmlns="http://www.w3.org/2000/svg" id="svg5_3" width="800" height="200"></svg>
<p>4. Our managers help ensure our people are encouraged and empowered as owners to take responsibility for their own performance and contribution.</p>
<svg xmlns="http://www.w3.org/2000/svg" id="svg5_4" width="800" height="200"></svg>
</div>
<p>Please add any additional comments: <button onclick="doComments('greatEngagement','QID62_TEXT')">Load comments</button></p>
<div class="comments" id="greatEngagement">
</div>
<hr>
<h3>Great EO Stewardship: <span id="Stewardship_avg" class="avgs"></span></h3>
<div class="section">
<p>1. During tough times, we balance the current and future needs of our employee owners to ensure we are stronger in the future.</p>
<svg xmlns="http://www.w3.org/2000/svg" id="svg6_1" width="800" height="200"></svg>
<p>2. Our employee owners identify and manage risks to protect our organisation and reputation.</p>
<svg xmlns="http://www.w3.org/2000/svg" id="svg6_2" width="800" height="200"></svg>
<p>3. We ensure our ownership model helps promote long-term retention of talented colleagues.</p>
<svg xmlns="http://www.w3.org/2000/svg" id="svg6_3" width="800" height="200"></svg>
<p>4. Our culture encourages leaders, managers and specialists to develop candidates for their own succession.</p>
<svg xmlns="http://www.w3.org/2000/svg" id="svg6_4" width="800" height="200"></svg>
</div>
<p>Please add any additional comments: <button onclick="doComments('greatStewardship','QID61_TEXT')">Load comments</button></p>
<div class="comments" id="greatStewardship">
</div>
<hr>
<h2>EO Actions</h2>
<p>An EO business can use its ownership model to provide commercial advantages as it faces into the world.</p>
<p><strong>To what extent are you harnessing the contributions of employees as owners can strengthen the quality and effectiveness of your strategy, innovation and commercial sustainability?</strong></p>
<svg class="triangle" style="display: inline-block" xmlns="http://www.w3.org/2000/svg" id="svg_actions" width="500" height="500"></svg>
<svg class="triangle" style="display: inline-block" xmlns="http://www.w3.org/2000/svg" id="svg_actions_RAG" width="500" height="500"></svg>
<svg class="triangle no-axis no-text big-number" style="display: inline-block" xmlns="http://www.w3.org/2000/svg" id="svg_actions_test" width="500" height="500"></svg>
<hr>
<h3>Great EO Strategy: <span id="Strategy_avg" class="avgs"></span></h3>
<div class="section">
<p>1. Our vision sets out the compelling benefits of our ownership model.</p>
<svg xmlns="http://www.w3.org/2000/svg" id="svg7_1" width="800" height="200"></svg>
<p>2. Our strategy builds on our unique strengths including our ownership model.</p>
<svg xmlns="http://www.w3.org/2000/svg" id="svg7_2" width="800" height="200"></svg>
<p>3. Our strategy outlines key activities and milestones that ensure our employee owners know how to contribute to a successful business.</p>
<svg xmlns="http://www.w3.org/2000/svg" id="svg7_3" width="800" height="200"></svg>
<p>4. Our strategic approach to key markets ensures success by drawing on the experience and insights of our employee owners.</p>
<svg xmlns="http://www.w3.org/2000/svg" id="svg7_4" width="800" height="200"></svg>
</div>
<p>Please add any additional comments: <button onclick="doComments('greatStrategy','QID49_TEXT')">Load comments</button></p>
<div class="comments" id="greatStrategy">
</div>
<hr>
<h3>Great EO Innovation: <span id="Innovation_avg" class="avgs"></span></h3>
<div class="section">
<p>1. Our employee owners understand how our business works and delivers results.</p>
<svg xmlns="http://www.w3.org/2000/svg" id="svg8_1" width="800" height="200"></svg>
<p>2. Our employee owners are committed to driving continuous improvement and growth.</p>
<svg xmlns="http://www.w3.org/2000/svg" id="svg8_2" width="800" height="200"></svg>
<p>3. Our employee owners consistently contribute ideas that improve our business.</p>
<svg xmlns="http://www.w3.org/2000/svg" id="svg8_3" width="800" height="200"></svg>
<p>4. We provide clear channels and processes to capture, consider and provide feedback on new ideas and suggestions.</p>
<svg xmlns="http://www.w3.org/2000/svg" id="svg8_4" width="800" height="200"></svg>
<p>5. We successfully prioritise and manage these ideas to deliver improvements to our business.</p>
<svg xmlns="http://www.w3.org/2000/svg" id="svg8_5" width="800" height="200"></svg>
</div>
<p>Please add any additional comments: <button onclick="doComments('greatInnovation','QID64_TEXT')">Load comments</button></p>
<div class="comments" id="greatInnovation">
</div>
<hr>
<h3>Great EO Advantage: <span id="Advantage_avg" class="avgs"></span></h3>
<div class="section">
<p>1. We leverage our EO status to differentiate our customer brand to win against our competitors in the market.</p>
<svg xmlns="http://www.w3.org/2000/svg" id="svg9_1" width="800" height="200"></svg>
<p>2. We leverage our EO status to differentiate our employer brand to strengthen our people proposition and attract talent.</p>
<svg xmlns="http://www.w3.org/2000/svg" id="svg9_2" width="800" height="200"></svg>
<p>3. We leverage our EO status to differentiate our company brand to attract and retain high-quality relationships with suppliers and delivery partners.</p>
<svg xmlns="http://www.w3.org/2000/svg" id="svg9_3" width="800" height="200"></svg>
</div>
<p>Please add any additional comments: <button onclick="doComments('greatAdvantage','QID63_TEXT')">Load comments</button></p>
<div class="comments" id="greatAdvantage">
</div>
<hr>
<h2>EO Results</h2>
<p>Well-run EO organisations ensure decision-making is informed by relevant data and insights from inside the business and by benchmarking themselves against other firms. This helps set strategic focus, direct operational effort, ensure continuous improvement and drive better business performance.</p>
<p><strong>Do you have the right EO data and insights to make this happen?</strong></p>
<svg class="triangle" style="display: inline-block" xmlns="http://www.w3.org/2000/svg" id="svg_results" width="500" height="500"></svg>
<svg class="triangle" style="display: inline-block" xmlns="http://www.w3.org/2000/svg" id="svg_results_RAG" width="500" height="500"></svg>
<svg class="triangle no-axis no-text big-number" style="display: inline-block" xmlns="http://www.w3.org/2000/svg" id="svg_results_test" width="500" height="500"></svg>
<hr>
<h3>Great EO Measurement: <span id="Measurement_avg" class="avgs"></span></h3>
<div class="section">
<p>1. The business collects data from our employee owners that help us understand the benefits of our EO model.</p>
<svg xmlns="http://www.w3.org/2000/svg" id="svg10_1" width="800" height="200"></svg>
<p>2. We compare our EO performance with other EO businesses and learn from them.</p>
<svg xmlns="http://www.w3.org/2000/svg" id="svg10_2" width="800" height="200"></svg>
<p>3. We measure and compare our performance with other businesses in our sector (regardless of their ownership model) and learn from them.</p>
<svg xmlns="http://www.w3.org/2000/svg" id="svg10_3" width="800" height="200"></svg>
<p>4. We pay attention to our impacts on more than just our employee owners (e.g. our customers, community or planet).</p>
<svg xmlns="http://www.w3.org/2000/svg" id="svg10_4" width="800" height="200"></svg>
</div>
<p>Please add any additional comments: <button onclick="doComments('greatMeasurement','QID50_TEXT')">Load comments</button></p>
<div class="comments" id="greatMeasurement">
</div>
<hr>
<h3>Great EO Evaluation: <span id="Evaluation_avg" class="avgs"></span></h3>
<div class="section">
<p>1. We use relevant EO data and insights to increase engagement levels among our people.</p>
<svg xmlns="http://www.w3.org/2000/svg" id="svg11_1" width="800" height="200"></svg>
<p>2. We use relevant EO data and insights to strengthen our ownership culture.</p>
<svg xmlns="http://www.w3.org/2000/svg" id="svg11_2" width="800" height="200"></svg>
<p>3. We use relevant EO data and insights to grow our business.</p>
<svg xmlns="http://www.w3.org/2000/svg" id="svg11_3" width="800" height="200"></svg>
<p>4. We use relevant EO data and insights to meet the aspirations of our current employee owners.</p>
<svg xmlns="http://www.w3.org/2000/svg" id="svg11_4" width="800" height="200"></svg>
</div>
<p>Please add any additional comments: <button onclick="doComments('greatEvaluation','QID66_TEXT')">Load comments</button></p>
<div class="comments" id="greatEvaluation">
</div>
<hr>
<h3>Great EO Impact: <span id="Impact_avg" class="avgs"></span></h3>
<div class="section">
<p>1. We are confident that our EO model encourages collaboration and team-working.</p>
<svg xmlns="http://www.w3.org/2000/svg" id="svg12_1" width="800" height="200"></svg>
<p>2. We are confident that our EO model promotes engagement and job satisfaction.</p>
<svg xmlns="http://www.w3.org/2000/svg" id="svg12_2" width="800" height="200"></svg>
<p>3. We are confident that our EO model improves health and well-being for employee owners.</p>
<svg xmlns="http://www.w3.org/2000/svg" id="svg12_3" width="800" height="200"></svg>
<p>4. We are confident that our EO model supports colleagues skills and capability</p>
<svg xmlns="http://www.w3.org/2000/svg" id="svg12_4" width="800" height="200"></svg>
<p>5. We are confident that our EO model encourages strong ideas from colleagues.</p>
<svg xmlns="http://www.w3.org/2000/svg" id="svg12_5" width="800" height="200"></svg>
<p>6. We are confident that our EO model helps us recruit and retain talent.</p>
<svg xmlns="http://www.w3.org/2000/svg" id="svg12_6" width="800" height="200"></svg>
<p>7. We are confident that our EO model boosts personal commitment and productivity.</p>
<svg xmlns="http://www.w3.org/2000/svg" id="svg12_7" width="800" height="200"></svg>
<p>8. We are confident that our EO model increases profitability.</p>
<svg xmlns="http://www.w3.org/2000/svg" id="svg12_8" width="800" height="200"></svg>
<p>9. We are confident that our EO model encourages more contribution to the local community.</p>
<svg xmlns="http://www.w3.org/2000/svg" id="svg12_9" width="800" height="200"></svg>
<p>10. We are confident that our EO model encourages a focus on protecting the planet.</p>
<svg xmlns="http://www.w3.org/2000/svg" id="svg12_10" width="800" height="200"></svg>
</div>
<p>Please add any additional comments: <button onclick="doComments('greatImpact','QID65_TEXT')">Load comments</button></p>
<div class="comments" id="greatImpact">
</div>
<hr>
</body>
</html>

View File

@@ -50,35 +50,13 @@ function doLittleWhiteTriangle(id){
//triangle.setAttribute("stroke", "black"); // Optional //triangle.setAttribute("stroke", "black"); // Optional
//triangle.setAttribute("stroke-width", "2"); // Optional //triangle.setAttribute("stroke-width", "2"); // Optional
svg.appendChild(triangle); svg.appendChild(triangle);
} }
function resetSvg(id){
const svg = document.getElementById(id);
svg.innerHTML="";
}
/*
function inlineStyles(svgElement) {
const allElements = svgElement.querySelectorAll('*');
const computedStyles = window.getComputedStyle(svgElement);
// Apply style to root SVG element
svgElement.setAttribute("style", computedStyles.cssText || "");
// Recursively apply computed styles to each element
allElements.forEach(el => {
const computed = window.getComputedStyle(el);
let inline = '';
for (let i = 0; i < computed.length; i++) {
const key = computed[i];
const value = computed.getPropertyValue(key);
inline += `${key}:${value};`;
}
el.setAttribute('style', inline);
});
}
*/
function inlineStyles(svgElement) { function inlineStyles(svgElement) {
const allElements = svgElement.querySelectorAll('*'); const allElements = svgElement.querySelectorAll('*');

80
setupGroups.php Normal file
View File

@@ -0,0 +1,80 @@
<?php
header('Content-Type: application/json');
if (php_sapi_name() === 'cli') {
echo "Running from command line.\n";
} else {
//echo "Running from browser.\n";
// Basic input validation and sanitization
if (!isset($_POST['action']) || empty($_POST['qid'])) {
echo json_encode(['error' => 'Needs an action to carry out']);
exit;
}
}
// Database connection (adjust credentials accordingly)
//
$config = require 'config.php';
$host = $config['db_host'];
$db = $config['db_name'];
$user = $config['db_user'];
$pass = $config['db_pass'];
$charset = 'utf8mb4';
$dsn = "mysql:host=$host;dbname=$db;charset=$charset";
$options = [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
];
try {
$pdo = new PDO($dsn, $user, $pass, $options);
// Map of QIDs to Response columns
$qidToColumn = [
'QID68' => 'Q1',
'QID69' => 'Q2',
'QID71' => 'Q3'
];
$totalUpdated = 0;
foreach ($qidToColumn as $qid => $column) {
$sql = "
UPDATE Responses r
JOIN Answers a ON r.id = a.responseId
SET r.{$column} = a.value
WHERE a.QID = :qid
AND r.{$column} IS NULL
";
$stmt = $pdo->prepare($sql);
$stmt->execute(['qid' => $qid]);
$rows = $stmt->rowCount();
echo "Updated {$rows} rows for {$qid}{$column}\n";
$totalUpdated += $rows;
}
echo "Total rows updated: {$totalUpdated}\n";
} catch (PDOException $e) {
echo "Database error: " . $e->getMessage();
}

File diff suppressed because one or more lines are too long

10
update_code.sh Normal file
View File

@@ -0,0 +1,10 @@
#!/bin/bash
#Not that this should be run in order to update the code during updates
rm -Rf ./EoQ_Supporting_Files
git clone https://git.telos.digital/PeterEdmond/EoQ_Supporting_Files.git
rm -Rf /var/www/html/surveys
mv ./EoQ_Supporting_Files /var/www/html/surveys