-
Notifications
You must be signed in to change notification settings - Fork 1
Yearbook opus #283
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
Open
cornhundred
wants to merge
28
commits into
main
Choose a base branch
from
yearbook_opus
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Yearbook opus #283
Changes from all commits
Commits
Show all changes
28 commits
Select commit
Hold shift + click to select a range
c9f6a5f
testing opus dataset update
cornhundred e52dbd0
Enhance image layer management by disposing of old layers and forcing…
cornhundred 230743d
fixing statefulness
cornhundred 6a437f7
camel_case
cornhundred 0c94766
fixed first gene click obs_store state
cornhundred 63c2141
working on opus yearbook
cornhundred 66c8400
fixed initialization error
cornhundred cb8d3b9
added pagination
cornhundred 114bc20
fixed pagination update
cornhundred cac145a
fixing portrait image layers
cornhundred 842e612
improved pagination
cornhundred 963f170
test yearbook and dataset_dropdown
cornhundred 3a1c9c6
aws creds for yearbook
cornhundred 3492f3c
aws creds for yearbook
cornhundred e9a64cd
ruff format
cornhundred 0f9aedf
js lint
cornhundred c69f6ea
js format
cornhundred ce16781
linting and format js
cornhundred d511fc3
merged dataset_dropdown_opus_2
cornhundred cf07bb0
updating file
cornhundred 77294e3
remove console logs
cornhundred 23bd63b
merging in main
cornhundred c0f4212
fixing linting errors
cornhundred e536f42
fixing linting errors
cornhundred 666f3a3
add example notebook
cornhundred e3c799c
reusing scale bar code
cornhundred abc5892
cleared state
cornhundred c09d361
Merge branch 'main' into yearbook_opus
cornhundred File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,228 @@ | ||
| import { OrthographicView } from 'deck.gl'; | ||
|
|
||
| import { visibleTiles } from '../../vector_tile/visibleTiles'; | ||
|
|
||
| /** | ||
| * Create multiple OrthographicViews for the yearbook grid layout. | ||
| * Each portrait gets its own view with specific x, y, width, height. | ||
| * | ||
| * @param {number} num_rows - Number of rows in the grid | ||
| * @param {number} num_cols - Number of columns in the grid | ||
| * @param {number} portrait_size - Size of each portrait in pixels | ||
| * @param {number} gap - Gap between portraits in pixels | ||
| * @returns {Array<OrthographicView>} Array of deck.gl views | ||
| */ | ||
| export const create_yearbook_views = ( | ||
| num_rows, | ||
| num_cols, | ||
| portrait_size, | ||
| gap | ||
| ) => { | ||
| const views = []; | ||
|
|
||
| for (let row = 0; row < num_rows; row++) { | ||
| for (let col = 0; col < num_cols; col++) { | ||
| const index = row * num_cols + col; | ||
|
|
||
| // Calculate the position of this portrait | ||
| const x = col * (portrait_size + gap); | ||
| const y = row * (portrait_size + gap); | ||
|
|
||
| views.push( | ||
| new OrthographicView({ | ||
| id: `portrait-${index}`, | ||
| x, | ||
| y, | ||
| width: portrait_size, | ||
| height: portrait_size, | ||
| controller: { | ||
| doubleClickZoom: false, | ||
| dragPan: false, // Disable panning in yearbook | ||
| scrollZoom: true, // Enable zoom | ||
| touchZoom: true, | ||
| }, | ||
| }) | ||
| ); | ||
| } | ||
| } | ||
|
|
||
| return views; | ||
| }; | ||
|
|
||
| /** | ||
| * Calculate the viewport bounds for each portrait based on its center. | ||
| * When zoom=0, view_width and view_height should be in data/image coordinates. | ||
| * | ||
| * @param {Array<{cell_id: string, x: number, y: number}>} centers - Center coordinates for each portrait | ||
| * @param {number} zoom - Current zoom level (use 0 if view dimensions are already in data coords) | ||
| * @param {number} view_width - Width of each portrait view (in data coordinates when zoom=0) | ||
| * @param {number} view_height - Height of each portrait view (in data coordinates when zoom=0) | ||
| * @returns {Array<{min_x, max_x, min_y, max_y}>} Viewport bounds for each portrait | ||
| */ | ||
| export const calc_portrait_viewports = ( | ||
| centers, | ||
| zoom, | ||
| view_width, | ||
| view_height | ||
| ) => { | ||
| const zoomFactor = Math.pow(2, zoom); | ||
| const halfWidthZoomed = view_width / (2 * zoomFactor); | ||
| const halfHeightZoomed = view_height / (2 * zoomFactor); | ||
|
|
||
| return centers.map((center) => ({ | ||
| cell_id: center.cell_id, | ||
| min_x: center.x - halfWidthZoomed, | ||
| max_x: center.x + halfWidthZoomed, | ||
| min_y: center.y - halfHeightZoomed, | ||
| max_y: center.y + halfHeightZoomed, | ||
| center_x: center.x, | ||
| center_y: center.y, | ||
| })); | ||
| }; | ||
|
|
||
| /** | ||
| * Get tiles visible across all portraits (discontiguous tile loading). | ||
| * This returns a unique set of tiles that cover all portrait viewports. | ||
| * | ||
| * @param {Array<{cell_id: string, x: number, y: number}>} centers - Center coordinates for each portrait | ||
| * @param {number} zoom - Current zoom level | ||
| * @param {number} view_width - Width of each portrait view in pixels | ||
| * @param {number} view_height - Height of each portrait view in pixels | ||
| * @param {number} tile_size - Size of each tile | ||
| * @returns {Array<{tileX: number, tileY: number, name: string}>} Unique tiles across all viewports | ||
| */ | ||
| export const get_discontiguous_tiles = ( | ||
| centers, | ||
| zoom, | ||
| view_width, | ||
| view_height, | ||
| tile_size | ||
| ) => { | ||
| const viewports = calc_portrait_viewports( | ||
| centers, | ||
| zoom, | ||
| view_width, | ||
| view_height | ||
| ); | ||
|
|
||
| // Collect all tiles from all viewports | ||
| const tile_map = new Map(); | ||
|
|
||
| viewports.forEach((viewport) => { | ||
| const tiles = visibleTiles( | ||
| viewport.min_x, | ||
| viewport.max_x, | ||
| viewport.min_y, | ||
| viewport.max_y, | ||
| tile_size | ||
| ); | ||
|
|
||
| tiles.forEach((tile) => { | ||
| // Use tile name as key to deduplicate | ||
| if (!tile_map.has(tile.name)) { | ||
| tile_map.set(tile.name, tile); | ||
| } | ||
| }); | ||
| }); | ||
|
|
||
| return Array.from(tile_map.values()); | ||
| }; | ||
|
|
||
| /** | ||
| * Create initial view states for all portraits. | ||
| * | ||
| * @param {Array<{cell_id: string, x: number, y: number}>} centers - Center coordinates for each portrait | ||
| * @param {number} zoom - Initial zoom level | ||
| * @returns {Object} View states keyed by view id | ||
| */ | ||
| export const create_initial_view_states = (centers, zoom) => { | ||
| const view_states = {}; | ||
|
|
||
| centers.forEach((center, index) => { | ||
| const view_id = `portrait-${index}`; | ||
| view_states[view_id] = { | ||
| target: [center.x, center.y, 0], | ||
| zoom, | ||
| }; | ||
| }); | ||
|
|
||
| return view_states; | ||
| }; | ||
|
|
||
| /** | ||
| * Update all view states with a new zoom level (keeping centers the same). | ||
| * | ||
| * @param {Object} current_view_states - Current view states | ||
| * @param {number} new_zoom - New zoom level | ||
| * @returns {Object} Updated view states | ||
| */ | ||
| export const update_view_states_zoom = (current_view_states, new_zoom) => { | ||
| const updated_states = {}; | ||
|
|
||
| Object.entries(current_view_states).forEach(([view_id, state]) => { | ||
| updated_states[view_id] = { | ||
| ...state, | ||
| zoom: new_zoom, | ||
| }; | ||
| }); | ||
|
|
||
| return updated_states; | ||
| }; | ||
|
|
||
| /** | ||
| * Calculate the total portraits per page. | ||
| * | ||
| * @param {number} num_rows - Number of rows | ||
| * @param {number} num_cols - Number of columns | ||
| * @returns {number} Total portraits per page | ||
| */ | ||
| export const get_portraits_per_page = (num_rows, num_cols) => { | ||
| return num_rows * num_cols; | ||
| }; | ||
|
|
||
| /** | ||
| * Calculate total pages needed. | ||
| * | ||
| * @param {number} total_cells - Total number of cells | ||
| * @param {number} num_rows - Number of rows | ||
| * @param {number} num_cols - Number of columns | ||
| * @returns {number} Total pages | ||
| */ | ||
| export const get_total_pages = (total_cells, num_rows, num_cols) => { | ||
| const portraits_per_page = get_portraits_per_page(num_rows, num_cols); | ||
| return Math.max(1, Math.ceil(total_cells / portraits_per_page)); | ||
| }; | ||
|
|
||
| /** | ||
| * Get cells for a specific page. | ||
| * | ||
| * @param {Array<string>} cells - All cell ids | ||
| * @param {number} page - Page number (0-indexed) | ||
| * @param {number} num_rows - Number of rows | ||
| * @param {number} num_cols - Number of columns | ||
| * @returns {Array<string>} Cell ids for the page | ||
| */ | ||
| export const get_cells_for_page = (cells, page, num_rows, num_cols) => { | ||
| const portraits_per_page = get_portraits_per_page(num_rows, num_cols); | ||
| const start_index = page * portraits_per_page; | ||
| return cells.slice(start_index, start_index + portraits_per_page); | ||
| }; | ||
|
|
||
| /** | ||
| * Filter data points to those visible in any portrait. | ||
| * | ||
| * @param {Array<{x: number, y: number}>} data - Data points with x, y coordinates | ||
| * @param {Array<{min_x, max_x, min_y, max_y}>} viewports - Viewport bounds | ||
| * @returns {Array} Filtered data points | ||
| */ | ||
| export const filter_data_in_viewports = (data, viewports) => { | ||
| return data.filter((point) => { | ||
| return viewports.some( | ||
| (viewport) => | ||
| point.x >= viewport.min_x && | ||
| point.x <= viewport.max_x && | ||
| point.y >= viewport.min_y && | ||
| point.y <= viewport.max_y | ||
| ); | ||
| }); | ||
| }; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.