Skip to content

Commit 72ef8c8

Browse files
committed
upd win '26
1 parent 8e578b8 commit 72ef8c8

16 files changed

Lines changed: 1206 additions & 655 deletions

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
/.quarto/
22
/_site/
3-
.DS_Store
3+
.DS_Store
4+
**/*.quarto_ipynb

_quarto.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,7 @@ format:
1111
css: styles.css
1212
toc: false
1313
header-includes: |
14+
<link rel="preconnect" href="https://fonts.googleapis.com">
15+
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
16+
<link href="https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@300;400;500;600;700&display=swap" rel="stylesheet">
1417
<link rel="stylesheet" href="https://use.typekit.net/ywh1hax.css">

docs/index.html

Lines changed: 361 additions & 369 deletions
Large diffs are not rendered by default.

docs/search.json

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,20 @@
44
"href": "index.html",
55
"title": "Hi, I’m Max!",
66
"section": "",
7-
"text": "My name is Maxim Lisnic and I am an Assistant Professor of Computer Science at WPI.\nI received my Ph.D. student from the University of Utah’s Kahlert School of Computing where I was advised by Marina Kogan and Alexander Lex. During my graduate studies, I was fortunate to intern at Tableau Research and work with Nicole Sultanum and Vidya Setlur.\nI am broadly interested in human-data interaction and data visualization. My research focuses on how people interpret and misinterpret, frame and reframe data and charts. My goal is to make charts and data portals more useful, understandable, and transparent.\nYou can access my CV here."
7+
"text": "My name is Maxim Lisnic and I am an Assistant Professor of Computer Science at WPI.\nI received my Ph.D. from the University of Utah’s Kahlert School of Computing where I was advised by Marina Kogan and Alexander Lex. During my graduate studies, I was fortunate to intern at Tableau Research and work with Nicole Sultanum and Vidya Setlur.\nI am broadly interested in human-data interaction and data visualization. My research focuses on how people interpret and misinterpret, frame and reframe data and charts. My goal is to make charts and data portals more useful, understandable, and transparent.\nYou can access my CV here."
8+
},
9+
{
10+
"objectID": "index.html#blog-posts",
11+
"href": "index.html#blog-posts",
12+
"title": "Hi, I’m Max!",
13+
"section": "Blog posts",
14+
"text": "Blog posts\nCo-Authoring Dashboard Text with AI\nMay 29, 2025 with Nicole Sultanum\nHow People Actually Lie with Charts\nApril 17, 2023"
815
},
916
{
1017
"objectID": "index.html#select-publications",
1118
"href": "index.html#select-publications",
1219
"title": "Hi, I’m Max!",
1320
"section": "Select publications",
14-
"text": "Select publications\n\nHere’s what you need to know about my data: Exploring Expert Knowledge’s Role in Data Analysis\nHaihan Lin, Maxim Lisnic, Derya Akbaba, Miriah Meyer, Alexander Lex\n2025 IEEE Visualization Conference (forthcoming)\nHonorable Mention Award\nPreprint doi: 10.31219/osf.io/dn32z\n\n\nPlume: Scaffolding Text Composition in Dashboards\nMaxim Lisnic, Vidya Setlur, Nicole Sultanum\n2025 CHI Conference on Human Factors in Computing Systems\nPaper doi: 10.1145/3706598.3713580\n\n\nVisualization Guardrails: Designing Interventions Against Cherry-Picking in Interactive Data Explorers\nMaxim Lisnic, Zach Cutler, Marina Kogan, Alexander Lex\n2025 CHI Conference on Human Factors in Computing Systems\nPaper doi: 10.1145/3706598.3713385\n\n\n“Yeah, this graph doesn’t show that”: Analysis of Online Engagement with Misleading Data Visualizations\nMaxim Lisnic, Alexander Lex, Marina Kogan\n2024 CHI Conference on Human Factors in Computing Systems\nPaper doi: 10.1145/3613904.3642448\n\n\nMisleading Beyond Visual Tricks: How People Actually Lie With Charts\nMaxim Lisnic, Cole Polychronis, Alexander Lex, Marina Kogan\n2023 CHI Conference on Human Factors in Computing Systems\nPaper doi: 10.1145/3544548.3580910"
21+
"text": "Select publications\n\nHere’s what you need to know about my data: Exploring Expert Knowledge’s Role in Data Analysis\nHaihan Lin, Maxim Lisnic, Derya Akbaba, Miriah Meyer, Alexander Lex\n2025 IEEE Visualization Conference\nHonorable Mention Award\nPreprint doi: 10.31219/osf.io/dn32z\n\n\nPlume: Scaffolding Text Composition in Dashboards\nMaxim Lisnic, Vidya Setlur, Nicole Sultanum\n2025 CHI Conference on Human Factors in Computing Systems\nPaper doi: 10.1145/3706598.3713580\n\n\nVisualization Guardrails: Designing Interventions Against Cherry-Picking in Interactive Data Explorers\nMaxim Lisnic, Zach Cutler, Marina Kogan, Alexander Lex\n2025 CHI Conference on Human Factors in Computing Systems\nPaper doi: 10.1145/3706598.3713385\n\n\n“Yeah, this graph doesn’t show that”: Analysis of Online Engagement with Misleading Data Visualizations\nMaxim Lisnic, Alexander Lex, Marina Kogan\n2024 CHI Conference on Human Factors in Computing Systems\nPaper doi: 10.1145/3613904.3642448\n\n\nMisleading Beyond Visual Tricks: How People Actually Lie With Charts\nMaxim Lisnic, Cole Polychronis, Alexander Lex, Marina Kogan\n2023 CHI Conference on Human Factors in Computing Systems\nPaper doi: 10.1145/3544548.3580910"
1522
}
1623
]

docs/site_libs/bootstrap/bootstrap-5b4ad623e5705c0698d39aec6f10cf02.min.css

Lines changed: 12 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

docs/site_libs/bootstrap/bootstrap-icons.css

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
/*!
2-
* Bootstrap Icons v1.11.1 (https://icons.getbootstrap.com/)
3-
* Copyright 2019-2023 The Bootstrap Authors
2+
* Bootstrap Icons v1.13.1 (https://icons.getbootstrap.com/)
3+
* Copyright 2019-2024 The Bootstrap Authors
44
* Licensed under MIT (https://github.com/twbs/icons/blob/main/LICENSE)
55
*/
66

77
@font-face {
88
font-display: block;
99
font-family: "bootstrap-icons";
1010
src:
11-
url("./bootstrap-icons.woff?2820a3852bdb9a5832199cc61cec4e65") format("woff");
11+
url("./bootstrap-icons.woff?e34853135f9e39acf64315236852cd5a") format("woff");
1212
}
1313

1414
.bi::before,
@@ -2076,3 +2076,31 @@ url("./bootstrap-icons.woff?2820a3852bdb9a5832199cc61cec4e65") format("woff");
20762076
.bi-suitcase2-fill::before { content: "\f901"; }
20772077
.bi-suitcase2::before { content: "\f902"; }
20782078
.bi-vignette::before { content: "\f903"; }
2079+
.bi-bluesky::before { content: "\f7f9"; }
2080+
.bi-tux::before { content: "\f904"; }
2081+
.bi-beaker-fill::before { content: "\f905"; }
2082+
.bi-beaker::before { content: "\f906"; }
2083+
.bi-flask-fill::before { content: "\f907"; }
2084+
.bi-flask-florence-fill::before { content: "\f908"; }
2085+
.bi-flask-florence::before { content: "\f909"; }
2086+
.bi-flask::before { content: "\f90a"; }
2087+
.bi-leaf-fill::before { content: "\f90b"; }
2088+
.bi-leaf::before { content: "\f90c"; }
2089+
.bi-measuring-cup-fill::before { content: "\f90d"; }
2090+
.bi-measuring-cup::before { content: "\f90e"; }
2091+
.bi-unlock2-fill::before { content: "\f90f"; }
2092+
.bi-unlock2::before { content: "\f910"; }
2093+
.bi-battery-low::before { content: "\f911"; }
2094+
.bi-anthropic::before { content: "\f912"; }
2095+
.bi-apple-music::before { content: "\f913"; }
2096+
.bi-claude::before { content: "\f914"; }
2097+
.bi-openai::before { content: "\f915"; }
2098+
.bi-perplexity::before { content: "\f916"; }
2099+
.bi-css::before { content: "\f917"; }
2100+
.bi-javascript::before { content: "\f918"; }
2101+
.bi-typescript::before { content: "\f919"; }
2102+
.bi-fork-knife::before { content: "\f91a"; }
2103+
.bi-globe-americas-fill::before { content: "\f91b"; }
2104+
.bi-globe-asia-australia-fill::before { content: "\f91c"; }
2105+
.bi-globe-central-south-asia-fill::before { content: "\f91d"; }
2106+
.bi-globe-europe-africa-fill::before { content: "\f91e"; }
3.99 KB
Binary file not shown.

docs/site_libs/bootstrap/bootstrap.min.css

Lines changed: 0 additions & 12 deletions
This file was deleted.
Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
class QuartoAxeReporter {
2+
constructor(axeResult, options) {
3+
this.axeResult = axeResult;
4+
this.options = options;
5+
}
6+
7+
report() {
8+
throw new Error("report() is an abstract method");
9+
}
10+
}
11+
12+
class QuartoAxeJsonReporter extends QuartoAxeReporter {
13+
constructor(axeResult, options) {
14+
super(axeResult, options);
15+
}
16+
17+
report() {
18+
console.log(JSON.stringify(this.axeResult, null, 2));
19+
}
20+
}
21+
22+
class QuartoAxeConsoleReporter extends QuartoAxeReporter {
23+
constructor(axeResult, options) {
24+
super(axeResult, options);
25+
}
26+
27+
report() {
28+
for (const violation of this.axeResult.violations) {
29+
console.log(violation.description);
30+
for (const node of violation.nodes) {
31+
for (const target of node.target) {
32+
console.log(target);
33+
console.log(document.querySelector(target));
34+
}
35+
}
36+
}
37+
}
38+
}
39+
40+
class QuartoAxeDocumentReporter extends QuartoAxeReporter {
41+
constructor(axeResult, options) {
42+
super(axeResult, options);
43+
}
44+
45+
createViolationElement(violation) {
46+
const violationElement = document.createElement("div");
47+
48+
const descriptionElement = document.createElement("div");
49+
descriptionElement.className = "quarto-axe-violation-description";
50+
descriptionElement.innerText = `${violation.impact.replace(/^[a-z]/, match => match.toLocaleUpperCase())}: ${violation.description}`;
51+
violationElement.appendChild(descriptionElement);
52+
53+
const helpElement = document.createElement("div");
54+
helpElement.className = "quarto-axe-violation-help";
55+
helpElement.innerText = violation.help;
56+
violationElement.appendChild(helpElement);
57+
58+
const nodesElement = document.createElement("div");
59+
nodesElement.className = "quarto-axe-violation-nodes";
60+
violationElement.appendChild(nodesElement);
61+
const nodeElement = document.createElement("div");
62+
nodeElement.className = "quarto-axe-violation-selector";
63+
for (const node of violation.nodes) {
64+
for (const target of node.target) {
65+
const targetElement = document.createElement("span");
66+
targetElement.className = "quarto-axe-violation-target";
67+
targetElement.innerText = target;
68+
nodeElement.appendChild(targetElement);
69+
nodeElement.addEventListener("mouseenter", () => {
70+
const element = document.querySelector(target);
71+
if (element) {
72+
element.scrollIntoView({ behavior: "smooth", block: "center" });
73+
element.classList.add("quarto-axe-hover-highlight");
74+
setTimeout(() => {
75+
element.style.border = "";
76+
}, 2000);
77+
}
78+
});
79+
nodeElement.addEventListener("mouseleave", () => {
80+
const element = document.querySelector(target);
81+
if (element) {
82+
element.classList.remove("quarto-axe-hover-highlight");
83+
}
84+
});
85+
nodeElement.addEventListener("click", () => {
86+
console.log(document.querySelector(target));
87+
});
88+
nodeElement.appendChild(targetElement);
89+
}
90+
nodesElement.appendChild(nodeElement);
91+
}
92+
return violationElement;
93+
}
94+
95+
report() {
96+
const violations = this.axeResult.violations;
97+
const reportElement = document.createElement("div");
98+
reportElement.className = "quarto-axe-report";
99+
if (violations.length === 0) {
100+
const noViolationsElement = document.createElement("div");
101+
noViolationsElement.className = "quarto-axe-no-violations";
102+
noViolationsElement.innerText = "No axe-core violations found.";
103+
reportElement.appendChild(noViolationsElement);
104+
}
105+
violations.forEach((violation) => {
106+
reportElement.appendChild(this.createViolationElement(violation));
107+
});
108+
document.querySelector("main").appendChild(reportElement);
109+
}
110+
}
111+
112+
const reporters = {
113+
json: QuartoAxeJsonReporter,
114+
console: QuartoAxeConsoleReporter,
115+
document: QuartoAxeDocumentReporter,
116+
};
117+
118+
class QuartoAxeChecker {
119+
constructor(opts) {
120+
this.options = opts;
121+
}
122+
async init() {
123+
const axe = (await import("https://cdn.skypack.dev/pin/axe-core@v4.10.3-aVOFXWsJaCpVrtv89pCa/mode=imports,min/optimized/axe-core.js")).default;
124+
const result = await axe.run({
125+
exclude: [
126+
// https://github.com/microsoft/tabster/issues/288
127+
// MS has claimed they won't fix this, so we need to add an exclusion to
128+
// all tabster elements
129+
"[data-tabster-dummy]"
130+
],
131+
preload: { assets: ['cssom'], timeout: 50000 }
132+
});
133+
const reporter = this.options === true ? new QuartoAxeConsoleReporter(result) : new reporters[this.options.output](result, this.options);
134+
reporter.report();
135+
}
136+
}
137+
138+
export async function init() {
139+
const opts = document.querySelector("#quarto-axe-checker-options");
140+
if (opts) {
141+
const jsonOptions = JSON.parse(atob(opts.textContent));
142+
const checker = new QuartoAxeChecker(jsonOptions);
143+
await checker.init();
144+
}
145+
}

0 commit comments

Comments
 (0)