Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enable collapse of graph pane on smaller screens #11

Merged
merged 3 commits into from
Jan 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
93 changes: 92 additions & 1 deletion public/css/hanzi-graph.css
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
--right-button-margin: 10px 0 0 20px;
--menu-button-margin: 18px 0 0 0;
--primary-container-height: calc(100% - 42px);
--legend-height: 14px;
--legend-height: 16px;
--graph-height: calc(100% - var(--legend-height) - 4px);
--section-container-margin: 0 20px;
--calendar-day-color: #eee;
Expand All @@ -54,6 +54,7 @@
--legend-switch-button-border: 1px solid #000;
--button-border-bottom: 3px solid var(--accent-color);
--legend-switch-box-shadow: 1px 1px #444;
--graph-expand-button-box-shadow: 2px 2px #444;
}

html {
Expand Down Expand Up @@ -661,6 +662,41 @@ svg+.explore-stat-header {
box-sizing: border-box;
}

#collapse-graph {
border: var(--legend-switch-button-border);
padding: 0 4px;
box-shadow: var(--legend-switch-box-shadow);
margin: 0 0 0 6px;
cursor: pointer;
display: none;
}

.graph-expander {
display: none;
}

.down-arrow {
display: inline-block;
width: 10px;
height: 10px;
border-top: 3px solid;
border-right: 3px solid;
transform: rotate(135deg);
box-sizing: border-box;
margin-bottom: 1px;
}

.big-up-arrow {
display: inline-block;
width: 26px;
height: 26px;
border-top: 6px solid;
border-right: 6px solid;
transform: rotate(315deg);
box-sizing: border-box;
margin: 10px 0 0 5px;
}

#tone-legend span {
font-size: 14px;
margin: 0 6px;
Expand Down Expand Up @@ -1041,6 +1077,7 @@ main.auth-form {
--accent-color: #ccc;
--legend-switch-button-border: 1px solid #ccc;
--legend-switch-box-shadow: 0;
--graph-expand-button-box-shadow: 0;
}
}

Expand Down Expand Up @@ -1090,4 +1127,58 @@ main.auth-form {
height: 55%;
border-top: var(--border);
}

/* should be unreachable other than when this media query is reached... */
@keyframes expand-panel {
0% {
height: 45%;
}

100% {
height: 100%;
}
}

.expand-panel {
animation: expand-panel 0.5s;
}

@keyframes collapse-panel {
0% {
height: 100%;
}

100% {
height: 45%;
}
}

.collapse-panel {
animation: collapse-panel 0.5s;
}

/* probably an anti-pattern, but it's the first thing that popped into my head */
#collapse-graph {
display: block;
}

.legend-container {
display: grid;
grid-template-columns: 26px 1fr;
height: var(--legend-height);
}

.graph-expander {
display: block;
position: fixed;
bottom: 20px;
right: 20px;
border: 3px solid;
padding: 2px;
box-shadow: var(--graph-expand-button-box-shadow);
background: var(--background-color);
cursor: pointer;
height: 36px;
width: 36px;
}
}
37 changes: 22 additions & 15 deletions public/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ <h3>Study Mode</h3>
<p id="hide-study-explanation"><a class="active-link">Hide this message</a></p>
</div>
<p id="cards-due" class="explanation">
Cards due: <span id="card-due-count"></span>
Cards due: <span id="card-due-count" class="emphasized"></span>
</p>
<p id="study-call-to-action" class="study-call-to-action">
<span id="task-description">What does the text below mean?</span>
Expand Down Expand Up @@ -118,22 +118,29 @@ <h3>Study Mode</h3>
</div>
</div>
</div>
<div id="graph-expander" class="graph-expander" style="display: none;">
<span class="big-up-arrow"></span>
</div>
</div>
<div id="graph-container" class="primary-panel">
<div id="freq-legend" style="display:none" class="legend">
Common
<div id="level-container"></div>
Uncommon
<a class="legend-switch-button" id="switch-to-tone-legend"><span class="right-arrow"></span></a>
</div>
<div id="tone-legend" class="legend">
<div>Tone:
<span class="tone1">1st</span>
<span class="tone2">2nd</span>
<span class="tone3">3rd</span>
<span class="tone4">4th</span>
<span class="tone5">Neutral</span>
<a class="legend-switch-button" id="switch-to-freq-legend"><span class="right-arrow"></span></a>
<div class="legend-container">
<div id="collapse-graph"><span class="down-arrow"></span></div>
<div id="freq-legend" style="display:none" class="legend">
Common
<div id="level-container"></div>
Uncommon
<a class="legend-switch-button" id="switch-to-tone-legend"><span class="right-arrow"></span></a>
</div>
<div id="tone-legend" class="legend">
<div>Tone:
<span class="tone1">1st</span>
<span class="tone2">2nd</span>
<span class="tone3">3rd</span>
<span class="tone4">4th</span>
<span class="tone5">Neutral</span>
<a class="legend-switch-button" id="switch-to-freq-legend"><span
class="right-arrow"></span></a>
</div>
</div>
</div>
<div id="graph" class="graph"></div>
Expand Down
3 changes: 3 additions & 0 deletions public/js/modules/flow-diagram.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { diagramKeys, switchDiagramView } from "./ui-orchestrator";
import { sankey, sankeyLinkHorizontal, sankeyCenter, sankeyJustify, sankeyRight, sankeyLeft } from "d3-sankey";
import { map, schemeTableau10, union, scaleOrdinal, format as d3format, create } from "d3";
import { getPartition, getActiveGraph } from "./options";
Expand Down Expand Up @@ -140,6 +141,7 @@ function renderCollocationData(term, collocations, nextSibling, container) {
wordHolder.classList.add('emphasized', 'navigable', `freq${getFrequencyLevel(wordSet[word], getActiveGraph().ranks)}`);
wordHolder.innerText = word;
wordHolder.addEventListener('click', function () {
switchDiagramView(diagramKeys.main);
document.dispatchEvent(new CustomEvent('graph-update', { detail: word }));
})
collocationsContainer.appendChild(wordHolder);
Expand Down Expand Up @@ -202,6 +204,7 @@ async function renderUsageDiagram(term, container) {
linkTitle: d => `${elements.labels[d.source.id]} ${elements.labels[d.target.id]}: ${d.value}`,
linkClickHandler: (d, i) => {
getCollocations(elements.labels[i.id]);
switchDiagramView(diagramKeys.main);
document.dispatchEvent(new CustomEvent('graph-update', { detail: elements.labels[i.id] }));
},
fontColor: 'currentColor',
Expand Down
34 changes: 34 additions & 0 deletions public/js/modules/graph.js
Original file line number Diff line number Diff line change
Expand Up @@ -382,6 +382,32 @@ function toggleColorCodeVisibility() {
switchToTones.style.display = 'none';
}
}
/*
graph substitute text:
position: fixed;
bottom: 20px;
right:20px;
*/
/*
go away:
document.getElementById('text-container').addEventListener('animationend', function(){
document.getElementById('graph-container').style.display = 'none';
document.getElementById('text-container').style.height = '100%';
document.getElementById('main-app-container').classList.remove('primary-container');
document.getElementById('text-container').classList.remove('expand-panel');
}, {once:true});
document.getElementById('text-container').classList.add('expand-panel');
*/
/*
come back:
document.getElementById('text-container').addEventListener('animationend', function(){
document.getElementById('text-container').classList.remove('collapse-panel');
}, {once:true});
document.getElementById('text-container').removeAttribute('style');
document.getElementById('main-app-container').classList.add('primary-container');
document.getElementById('graph-container').removeAttribute('style');
document.getElementById('text-container').classList.add('collapse-panel');
*/
function initialize() {
toggleColorCodeVisibility();
switchToTones.addEventListener('click', function () {
Expand All @@ -399,6 +425,9 @@ function initialize() {
document.addEventListener('graph-update', function (event) {
buildGraph(event.detail);
});
document.getElementById('collapse-graph').addEventListener('click', function () {
switchDiagramView(diagramKeys.none);
});
document.addEventListener('components-update', function (event) {
// Anytime the components are being rendered, ensure the main diagram is shown.
// TODO: could also call this when `components-update` is dispatched. Note that
Expand All @@ -420,6 +449,11 @@ function initialize() {
window.addEventListener('resize', function () {
clearTimeout(pendingResizeTimeout);
pendingResizeTimeout = setTimeout(() => {
// if the window resizes with the graph collapsed, re-expand it
// note that switchDiagramView no-ops if we're going main-->main
if(window.innerWidth > 664) {
switchDiagramView(diagramKeys.main);
}
// TODO: probably want a sizeDirty bit we can check for when the graph isn't shown and a resize happens
if (cy && showingGraph) {
cy.layout(mode === modes.graph ? layout(cy.nodes().length) : bfsLayout(root)).run();
Expand Down
5 changes: 1 addition & 4 deletions public/js/modules/main.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { initialize as firebaseInit } from './firebase-init.js';
import { initialize as authStateInit } from './auth-state.js';
import { diagramKeys, initialize as orchestratorInit, stateKeys, switchDiagramView, switchToState } from "./ui-orchestrator.js"
import { diagramKeys, initialize as orchestratorInit, stateKeys, switchToState } from "./ui-orchestrator.js"
import { initialize as exploreInit } from "./explore.js";
import { initialize as faqInit } from "./faq.js";
import { initialize as studyModeInit } from "./study-mode.js";
Expand Down Expand Up @@ -127,9 +127,6 @@ Promise.all(
if (needsTokenization) {
searchInit(urlState.word, urlState.mode);
}
if (urlState.mode === 'flow' && getActiveGraph().collocationsPath) {
switchDiagramView(diagramKeys.flow);
}
// These happen last due to being secondary functionality
statsInit();
faqInit();
Expand Down
59 changes: 37 additions & 22 deletions public/js/modules/ui-orchestrator.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ const statsContainer = document.getElementById('stats-container');
const faqContainer = document.getElementById('faq-container');
const menuContainer = document.getElementById('menu-container');

const textContainer = document.getElementById('text-container');
const graphContainer = document.getElementById('graph-container');
const graphExpander = document.getElementById('graph-expander');

const explorePane = document.getElementById('explore-container');
const studyPane = document.getElementById('study-container');

Expand Down Expand Up @@ -135,35 +139,46 @@ function switchToState(state) {
}
}

const diagrams = {
main: {
element: document.getElementById('graph-container'),
animation: 'slide-from-right'
},
flow: {
element: document.getElementById('flow-diagram-container'),
animation: 'slide-from-right'
}
};
const diagramKeys = { main: 'main', flow: 'flow' };
const diagramKeys = { main: 'main', none: 'none' };
let currentDiagramKey = diagramKeys.main;

function switchDiagramView(diagramKey) {
if (diagramKey === currentDiagramKey) {
return;
}
for (const [key, diagram] of Object.entries(diagrams)) {
if (key !== diagramKey) {
diagram.element.style.display = 'none';
diagram.element.dispatchEvent(new Event('hidden'));
} else {
diagram.element.removeAttribute('style');
diagram.element.classList.add(diagram.animation);
diagram.element.addEventListener('animationend', function () {
diagram.element.dispatchEvent(new Event('shown-animationend'));
diagram.element.classList.remove(diagram.animation);
if (diagramKey === diagramKeys.none) {
textContainer.addEventListener('animationend', function () {
graphContainer.dispatchEvent(new Event('hidden'));
graphContainer.style.display = 'none';
textContainer.style.height = '100%';
mainAppContainer.classList.remove('primary-container');
textContainer.classList.remove('expand-panel');
setTimeout(function () {
graphExpander.removeAttribute('style');
}, 250);
graphExpander.addEventListener('click', function () {
switchDiagramView(diagramKeys.main);
}, { once: true });
diagram.element.dispatchEvent(new Event('shown'));
}, { once: true });
textContainer.classList.add('expand-panel');
} else {
if (window.innerWidth <= 664) {
textContainer.addEventListener('animationend', function () {
graphContainer.dispatchEvent(new Event('shown-animationend'));
textContainer.classList.remove('collapse-panel');
}, { once: true });
}
graphExpander.style.display = 'none';
graphContainer.dispatchEvent(new Event('shown'));
textContainer.removeAttribute('style');
mainAppContainer.classList.add('primary-container');
graphContainer.removeAttribute('style');
// Else here reachable if the user re-sizes from small to a larger window
// in that case, the animation isn't run, so reset to the wide view.
if (window.innerWidth > 664) {
graphContainer.dispatchEvent(new Event('shown-animationend'));
} else {
textContainer.classList.add('collapse-panel');
}
}
currentDiagramKey = diagramKey;
Expand Down
Loading