Finally extracting questions from the survey. Additional table added to hold questions

This commit is contained in:
Peter Edmond 2025-05-31 00:16:39 +01:00
parent 437e1afede
commit dc68e98d92
7 changed files with 213 additions and 122 deletions

View File

@ -1,3 +1,7 @@
/* CREATE THE DATABASE FROM SCRATCH */
CREATE database demodb;
USE demodb; USE demodb;
CREATE TABLE `Surveys` ( CREATE TABLE `Surveys` (

View File

@ -0,0 +1,28 @@
Process required to get data into local database:
1.
2. getSurveys.php (identifies the surveys and calls:
getData.php to import the data)
3. getQuestions.php
getQuestionsData.php
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

View File

@ -28,7 +28,8 @@ 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;
@ -276,7 +277,46 @@ 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 ) {
// 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_qid_counts.php', {
method: 'POST',
body: formData
})
.then(response => response.text())
.then(data => {
// Output result
console.log(data);
const parsed = JSON.parse(data);
// 2. Clean the keys and build a usable object
const bardata = {};
parsed.forEach(entry => {
const rawKey = Object.keys(entry)[0];
const cleanKey = rawKey.replace(/"/g, ''); // Remove extra quotes
bardata[cleanKey] = entry[rawKey];
});
console.log(bardata);
drawBar(id,bardata);
// return data; // Should be an array like [{ value: -3, count: 2 }, ..., { value: 3, count: 5 }]
})
.catch(error => {
console.error('Error:', error);
});
}
function Backup() {
return fetch('get_qid_counts.php', { return fetch('get_qid_counts.php', {
method: 'POST', method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, headers: { 'Content-Type': 'application/x-www-form-urlencoded' },

View File

@ -2,66 +2,57 @@
<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>
body { font-family: Arial, sans-serif; margin: 2em; } textarea {
label, input, button { font-size: 1em; margin: 0.5em 0; } width: 100%;
ul { list-style-type: none; padding-left: 0; } height: 200px;
li { padding: 0.3em 0; } margin-top: 1em;
.error { color: red; } }
</style> </style>
</head> </head>
<body> <body>
<h1>Query Value Counts by QID</h1>
<form id="qidForm"> <form id="qidForm">
<label for="qidInput">Enter QID:</label><br /> <label for="qidInput">Enter QID:</label>
<input type="text" id="qidInput" name="qid" required /> <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> <button type="submit">Get Counts</button>
</form> </form>
<div id="results"></div> <textarea id="output" readonly placeholder="Results will appear here..."></textarea>
<script> <script>
document.getElementById('qidForm').addEventListener('submit', function(e) { document.getElementById('qidForm').addEventListener('submit', async function (e) {
e.preventDefault(); e.preventDefault();
const qid = document.getElementById('qidInput').value.trim();
const resultsDiv = document.getElementById('results');
resultsDiv.innerHTML = 'Loading...';
fetch('get_qid_counts.php', { const formData = new FormData(this);
try {
const response = await 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 => 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; const text = await response.text();
}) document.getElementById('output').value = text;
.catch(err => { } catch (error) {
resultsDiv.innerHTML = `<p class="error">Error: ${err.message}</p>`; document.getElementById('output').value = 'Error: ' + error.message;
}); }
}); });
</script> </script>
</body> </body>
</html> </html>

View File

@ -15,14 +15,29 @@ if (php_sapi_name() === 'cli') {
exit; exit;
} }
$qid = $_POST['qid']; $qid = $_POST['qid'];
$q1 = filter_input(INPUT_POST, 'q1', FILTER_VALIDATE_INT); $input = $_POST['survey'] ?? '';
$q2 = filter_input(INPUT_POST, 'q2', FILTER_VALIDATE_INT);
$q3 = filter_input(INPUT_POST, 'q3', FILTER_VALIDATE_INT);
if (preg_match('/^SV_[a-zA-Z0-9]+$/', $input)) {
// Input is valid
$survey = $input;
} else {
// Invalid format
die("Invalid survey ID format.");
} }
$qualifier = ""; $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) { if ($q1 > 0) {
$qualifier.=" AND r.Q1 = " . $q1; $qualifier.=" AND r.Q1 = " . $q1;
} }
if ($q2 > 0) { if ($q2 > 0) {
@ -52,7 +67,7 @@ $options = [
try { try {
$pdo = new PDO($dsn, $user, $pass, $options); $pdo = new PDO($dsn, $user, $pass, $options);
$sql = " $baseSql = "
SELECT SELECT
a.value, a.value,
COUNT(*) AS count, COUNT(*) AS count,
@ -61,12 +76,16 @@ try {
r.Q3 r.Q3
FROM Answers a FROM Answers a
INNER JOIN Responses r ON a.responseId = r.id INNER JOIN Responses r ON a.responseId = r.id
WHERE a.QID = :qid' . $quantifier . ' INNER JOIN Surveys s ON a.surveyId = s.id
WHERE a.QID = :qid
";
$sql = $baseSql . $qualifier . "
GROUP BY a.value, r.Q1, r.Q2, r.Q3 GROUP BY a.value, r.Q1, r.Q2, r.Q3
ORDER BY a.value; ORDER BY a.value;
"; ";
echo $sql; //echo $sql;
$stmt = $pdo->prepare($sql); $stmt = $pdo->prepare($sql);
$stmt->execute(['qid' => $qid]); $stmt->execute(['qid' => $qid]);

View File

@ -37,8 +37,17 @@ function getAverage(prefix) {
} }
function loaded(){ function getSurveyData(){
console.log("loaded"); 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 = '#ffbf00'; let amber = '#ffbf00';
//doBigWhiteTriangle('svg1'); //doBigWhiteTriangle('svg1');
@ -55,156 +64,156 @@ function loaded(){
//EO ROLES //EO ROLES
//Great Employee Owners //Great Employee Owners
let average = doBarData('#svg1_1','QID35_7'); let average = doBarData('#svg1_1','QID35_7',survey,Q1,Q2,Q3);
//makeSvgRightClickable('svg1_1'); //makeSvgRightClickable('svg1_1');
doBarData('#svg1_2','QID35_2'); doBarData('#svg1_2','QID35_2',survey,Q1,Q2,Q3);
//makeSvgRightClickable('svg1_2'); //makeSvgRightClickable('svg1_2');
doBarData('#svg1_3','QID35_8'); doBarData('#svg1_3','QID35_8',survey,Q1,Q2,Q3);
//makeSvgRightClickable('svg1_3'); //makeSvgRightClickable('svg1_3');
doBarData('#svg1_4','QID35_9'); doBarData('#svg1_4','QID35_9',survey,Q1,Q2,Q3);
//makeSvgRightClickable('svg1_4'); //makeSvgRightClickable('svg1_4');
doBarData('#svg1_5','QID35_10'); 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'); average = doBarData('#svg2_1','QID36_7',survey,Q1,Q2,Q3);
//makeSvgRightClickable('svg1_1'); //makeSvgRightClickable('svg1_1');
doBarData('#svg2_2','QID36_2'); doBarData('#svg2_2','QID36_2',survey,Q1,Q2,Q3);
//makeSvgRightClickable('svg1_2'); //makeSvgRightClickable('svg1_2');
doBarData('#svg2_3','QID36_8'); doBarData('#svg2_3','QID36_8',survey,Q1,Q2,Q3);
//makeSvgRightClickable('svg1_3'); //makeSvgRightClickable('svg1_3');
doBarData('#svg2_4','QID36_9'); 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'); average = doBarData('#svg3_1','QID37_7',survey,Q1,Q2,Q3);
//makeSvgRightClickable('svg1_1'); //makeSvgRightClickable('svg1_1');
doBarData('#svg3_2','QID37_2'); doBarData('#svg3_2','QID37_2',survey,Q1,Q2,Q3);
//makeSvgRightClickable('svg1_2'); //makeSvgRightClickable('svg1_2');
doBarData('#svg3_3','QID37_8'); doBarData('#svg3_3','QID37_8',survey,Q1,Q2,Q3);
//makeSvgRightClickable('svg1_3'); //makeSvgRightClickable('svg1_3');
doBarData('#svg3_4','QID37_20'); doBarData('#svg3_4','QID37_20',survey,Q1,Q2,Q3);
//makeSvgRightClickable('svg1_4'); //makeSvgRightClickable('svg1_4');
doBarData('#svg3_5','QID37_21'); doBarData('#svg3_5','QID37_21',survey,Q1,Q2,Q3);
//makeSvgRightClickable('svg1_5'); //makeSvgRightClickable('svg1_5');
doBarData('#svg3_6','QID37_22'); 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'); average = doBarData('#svg4_1','QID2_7',survey,Q1,Q2,Q3);
//makeSvgRightClickable('svg1_1'); //makeSvgRightClickable('svg1_1');
doBarData('#svg4_2','QID2_2'); doBarData('#svg4_2','QID2_2',survey,Q1,Q2,Q3);
//makeSvgRightClickable('svg1_2'); //makeSvgRightClickable('svg1_2');
doBarData('#svg4_3','QID2_8'); doBarData('#svg4_3','QID2_8',survey,Q1,Q2,Q3);
//makeSvgRightClickable('svg1_3'); //makeSvgRightClickable('svg1_3');
doBarData('#svg4_4','QID2_9'); 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'); average = doBarData('#svg5_1','QID33_7',survey,Q1,Q2,Q3);
//makeSvgRightClickable('svg1_1'); //makeSvgRightClickable('svg1_1');
doBarData('#svg5_2','QID33_2'); doBarData('#svg5_2','QID33_2',survey,Q1,Q2,Q3);
//makeSvgRightClickable('svg1_2'); //makeSvgRightClickable('svg1_2');
doBarData('#svg5_3','QID33_8'); doBarData('#svg5_3','QID33_8',survey,Q1,Q2,Q3);
//makeSvgRightClickable('svg1_3'); //makeSvgRightClickable('svg1_3');
doBarData('#svg5_4','QID33_9'); 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'); average = doBarData('#svg6_1','QID34_7',survey,Q1,Q2,Q3);
//makeSvgRightClickable('svg1_1'); //makeSvgRightClickable('svg1_1');
doBarData('#svg6_2','QID34_2'); doBarData('#svg6_2','QID34_2',survey,Q1,Q2,Q3);
//makeSvgRightClickable('svg1_2'); //makeSvgRightClickable('svg1_2');
doBarData('#svg6_3','QID34_8'); doBarData('#svg6_3','QID34_8',survey,Q1,Q2,Q3);
//makeSvgRightClickable('svg1_3'); //makeSvgRightClickable('svg1_3');
doBarData('#svg6_4','QID34_17'); 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'); average = doBarData('#svg7_1','QID40_7',survey,Q1,Q2,Q3);
//makeSvgRightClickable('svg1_1'); //makeSvgRightClickable('svg1_1');
doBarData('#svg7_2','QID40_2'); doBarData('#svg7_2','QID40_2',survey,Q1,Q2,Q3);
//makeSvgRightClickable('svg1_2'); //makeSvgRightClickable('svg1_2');
doBarData('#svg7_3','QID40_8'); doBarData('#svg7_3','QID40_8',survey,Q1,Q2,Q3);
//makeSvgRightClickable('svg1_3'); //makeSvgRightClickable('svg1_3');
doBarData('#svg7_4','QID40_9'); 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'); average = doBarData('#svg8_1','QID41_7');
//makeSvgRightClickable('svg1_1'); //makeSvgRightClickable('svg1_1');
doBarData('#svg8_2','QID41_2'); doBarData('#svg8_2','QID41_2',survey,Q1,Q2,Q3);
//makeSvgRightClickable('svg1_2'); //makeSvgRightClickable('svg1_2');
doBarData('#svg8_3','QID41_19'); doBarData('#svg8_3','QID41_19',survey,Q1,Q2,Q3);
//makeSvgRightClickable('svg1_3'); //makeSvgRightClickable('svg1_3');
doBarData('#svg8_4','QID41_20'); doBarData('#svg8_4','QID41_20',survey,Q1,Q2,Q3);
//makeSvgRightClickable('svg1_4'); //makeSvgRightClickable('svg1_4');
doBarData('#svg8_5','QID41_21'); 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'); average = doBarData('#svg9_1','QID42_7',survey,Q1,Q2,Q3);
//makeSvgRightClickable('svg1_1'); //makeSvgRightClickable('svg1_1');
doBarData('#svg9_2','QID42_2'); doBarData('#svg9_2','QID42_2',survey,Q1,Q2,Q3);
//makeSvgRightClickable('svg1_2'); //makeSvgRightClickable('svg1_2');
doBarData('#svg9_3','QID42_8'); 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'); average = doBarData('#svg10_1','QID44_21',survey,Q1,Q2,Q3);
//makeSvgRightClickable('svg1_1'); //makeSvgRightClickable('svg1_1');
doBarData('#svg10_2','QID44_7'); doBarData('#svg10_2','QID44_7',survey,Q1,Q2,Q3);
//makeSvgRightClickable('svg1_2'); //makeSvgRightClickable('svg1_2');
doBarData('#svg10_3','QID44_2'); doBarData('#svg10_3','QID44_2',survey,Q1,Q2,Q3);
//makeSvgRightClickable('svg1_3'); //makeSvgRightClickable('svg1_3');
doBarData('#svg10_4','QID44_8'); 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'); average = doBarData('#svg11_1','QID45_24',survey,Q1,Q2,Q3);
//makeSvgRightClickable('svg1_1'); //makeSvgRightClickable('svg1_1');
doBarData('#svg11_2','QID45_25'); doBarData('#svg11_2','QID45_25',survey,Q1,Q2,Q3);
//makeSvgRightClickable('svg1_2'); //makeSvgRightClickable('svg1_2');
doBarData('#svg11_3','QID45_26'); doBarData('#svg11_3','QID45_26',survey,Q1,Q2,Q3);
//makeSvgRightClickable('svg1_3'); //makeSvgRightClickable('svg1_3');
doBarData('#svg11_4','QID45_29'); 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'); average = doBarData('#svg12_1','QID46_27',survey,Q1,Q2,Q3);
//makeSvgRightClickable('svg1_1'); //makeSvgRightClickable('svg1_1');
doBarData('#svg12_2','QID46_28'); doBarData('#svg12_2','QID46_28',survey,Q1,Q2,Q3);
//makeSvgRightClickable('svg1_2'); //makeSvgRightClickable('svg1_2');
doBarData('#svg12_3','QID46_29'); doBarData('#svg12_3','QID46_29',survey,Q1,Q2,Q3);
//makeSvgRightClickable('svg1_3'); //makeSvgRightClickable('svg1_3');
doBarData('#svg12_4','QID46_30'); doBarData('#svg12_4','QID46_30',survey,Q1,Q2,Q3);
//makeSvgRightClickable('svg1_4'); //makeSvgRightClickable('svg1_4');
doBarData('#svg12_5','QID46_31'); doBarData('#svg12_5','QID46_31',survey,Q1,Q2,Q3);
//makeSvgRightClickable('svg1_5'); //makeSvgRightClickable('svg1_5');
doBarData('#svg12_6','QID46_32'); doBarData('#svg12_6','QID46_32',survey,Q1,Q2,Q3);
//makeSvgRightClickable('svg1_5'); //makeSvgRightClickable('svg1_5');
doBarData('#svg12_7','QID46_33'); doBarData('#svg12_7','QID46_33',survey,Q1,Q2,Q3);
//makeSvgRightClickable('svg1_3'); //makeSvgRightClickable('svg1_3');
doBarData('#svg12_8','QID46_34'); doBarData('#svg12_8','QID46_34',survey,Q1,Q2,Q3);
//makeSvgRightClickable('svg1_4'); //makeSvgRightClickable('svg1_4');
doBarData('#svg12_9','QID46_36'); doBarData('#svg12_9','QID46_36',survey,Q1,Q2,Q3);
//makeSvgRightClickable('svg1_5'); //makeSvgRightClickable('svg1_5');
doBarData('#svg12_10','QID46_37'); doBarData('#svg12_10','QID46_37',survey,Q1,Q2,Q3);
//makeSvgRightClickable('svg1_5'); //makeSvgRightClickable('svg1_5');

View File

@ -81,17 +81,17 @@
} }
</style> </style>
</head> </head>
<body onload="loaded()"> <body>
<h1>QUALTRICS SURVEY ANALYSIS TOOL</h1> <h1>QUALTRICS SURVEY ANALYSIS TOOL</h1>
<p>You first need to enter the Survey ID, and press submit in order to get the correct groupings available to select from</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>
<form id="surveyForm"> <form id="surveyForm">
<label for="surveyId">Survey iD</label> <label for="surveyId">Survey iD</label>
<input type="text" id="surveyId" name="surveyId" /> <input type="text" id="surveyId" name="surveyId" />
<br> <br>
<button type="button" onclick="getSurveyAll()">Submit</button> <button type="button" onclick="getSurveyData()">Submit</button>
</form> </form>
<br> <br>