Public
Edited
Sep 7, 2023
1 star
Insert cell
Insert cell
Insert cell
Plot.plot({
color: { domain: likert.order, scheme: "RdBu", legend: true },
x: {
tickFormat: Math.abs,
domain: [-maxValue, maxValue],
label: "# of answers →"
},
fy: { tickRotate: -90 },
marks: [
Plot.barX(
survey,
Plot.groupY(
{ x: "count" },
{ fy: "Group", y: "Question", fill: "Response", ...likert }
)
),
Plot.ruleX([0])
]
})
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
maxValue = {
const uniqueGroups = [...new Set(survey.map((r) => r.Group))];
// calculate max. values for each subset of the survey data
const maxValues = uniqueGroups.map((group) =>
calcMaxValueForDataset(
survey.filter((r) => r.Group === group),
"Question",
"Response",
weights
)
);

return Math.max(...maxValues);
}
Insert cell
function calcMaxValueForDataset(data, questionKey, responseKey, weights) {
const weightsLookup = Object.fromEntries(weights);
return d3
.groups(
data,
(d) => d[questionKey],
(d) => d[responseKey]
)
.reduce((max, question, i, qs) => {
let neutralsVal =
question[1]
.filter((r) => weightsLookup[r[0]] === 0)
.reduce((length, arr) => (length += arr[1].length), 0) / 2 || 0;
let largestNegVal =
question[1]
.filter((r) => weightsLookup[r[0]] < 0)
.reduce((length, arr) => (length += arr[1].length), 0) +
neutralsVal || 0;
let largestPosVal =
question[1]
.filter((r) => weightsLookup[r[0]] < 0)
.reduce((length, arr) => (length += arr[1].length), 0) +
neutralsVal || 0;

if (largestNegVal > max) max = largestNegVal;
if (largestPosVal > max) max = largestPosVal;

return max;
}, 0);
}
Insert cell
weights = [
["Strongly Disagree", -1],
["Disagree", -1],
["Neutral", 0],
["Agree", 1],
["Strongly Agree", 1]
]
Insert cell
likert = Likert(weights)
Insert cell
Insert cell
function Likert(responses) {
const map = new Map(responses);
return {
order: Array.from(map.keys()),
offset(I, X1, X2, Z) {
for (const stacks of I) {
for (const stack of stacks) {
const k = d3.sum(stack, (i) => (X2[i] - X1[i]) * (1 - map.get(Z[i]))) / 2;
for (const i of stack) {
X1[i] -= k;
X2[i] -= k;
}
}
}
}
};
}
Insert cell
Insert cell
survey = (await FileAttachment("survey.json").json()).map((row, i) => ({
...row,
Group: i % 2 === 0 ? "Treatment" : "Control"
}))
Insert cell
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more