Giter Club home page Giter Club logo

itsb's Introduction

In The Same Boats

A React rewrite of the In The Same Boats (ITSB) project, which maps the movements of significant cultural actors from the Caribbean and wider Americas, Africa, and Europe within the 20th century Afro-Atlantic world.

This version of In The Same Boats is built on the Linked Places and Linked Traces standards for representing historical and geographical data, and makes use of the Peripleo and Deck.GL libraries for search and interactive visualization.

For more information and credits, visit the current deployment of In The Same Boats.

Usage

Requirements

  • Python v3.9+
  • Node.JS v16
  • NPM v8

Data generation

This project takes CSV files in the format created by contributors to the original ITSB project, and converts them to Linked Places and Linked Traces JSON-formatted records.

Each CSV file representing an author's movements should be placed in /script/in/movements, while any additional places should be appended to /script/in/places/ITSB Place Names - Places.csv.

Then, the following script can be run to convert the CSV formatted data into JSON:

cd script
python ./convertJSON.py

This will save updated data JSON files to /public/data, from where they are served statically and used in the React application. This script will also print warnings and errors about missing or malformed data.

Installation

To install NPM dependencies, run the following script from the project root:

npm install

Build for production

This project uses Vite to build a static bundle that can be deployed to a server. To generate a static build output to /dist:

npm run build

You can also preview the built bundle using:

npm run preview

In this mode, Vite will launch a development server which serves the built assets from the /dist folder.

Deploy

A build of In The Same Boats created using the above steps can be deployed with minimal configuration; for an example build, see the gh-pages branch of this repo and its resulting deployment here.

We have configured a GitHub Workflow, stored at /.github/workflows/gh-pages.yml, to automatically build and deploy ITSB to this repo's GitHub Pages instance upon any push to the main branch.

Development

Run in development

This project uses Vite to enable hot-module reloading during development. To start a development build served over localhost:5173, run the following from the project root:

npm start

This build will refresh automatically as you save local changes to code in the /src directory.

Unit tests

Unit tests are written using Vitest and stored alongside components in *.test.js files, and the entire test suite can be run with the following script from the root directory:

npm test

A GitHub Workflow is also configured to run unit tests on each push to any branch in this repo.

itsb's People

Contributors

blms avatar elotroalex avatar jamiefolsom avatar rsimon avatar

Stargazers

 avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

itsb's Issues

Migrate to sameboats.org domain

The line in the workflow was necessary because the current site is served from https://performant-software.github.io/itsb/ instead of the root https://performant-software.github.io/. This assumes the site is meant to be served from the root sameboats.org/.

When successfully deployed:

  • Update the readme to use the new URL:
    For more information and credits, visit the current deployment of [_In The Same Boats_](https://performant-software.github.io/itsb/).

Selecting places in different map views

I looked at what happens when selecting a place in the original app design. The original app has a popup displaying the list of waypoints. (It seems to be buggy and doesn't always work. Also, it tends to get unwieldy for more than one or two waypoints.) At the moment, we only have a hover tooltip with the placename. Question is if we want to add something in our app, too?

Another, only half-related issue: when clicking on a place in the Trajectories view, this place gets globally selected, which then also causes it to be the current selection when switching to Intersections view. This seems confusing, especially because there's no visual feedback when clicking a place in the Trajectories view. I vote for making selections "local", i.e. clicks in the Trajectories view don't affect selection in the Intersections view. (Disclaimer: I'm the one who introduced this behavior in the first place, i.e. take the blame ;-)

Detail information on intersections

Update: I found the original version now, so much of this is now clarified thx to issue #9 (I still leave it here for the record).

I've been wondering about what detail information to show for an intersection place. I think this will also influence the exact API / datastructure we should be aiming for. Some thoughts...

About place markers:

  • If there are more than two itineraries selected, should the map show only places where all selected authors are in the same place? Or all places where more than one author was at the same place at the same time?
  • Right now, lower likelihood results in larger dots with higher opacity. Should higher likelihood produce larger dots instead?

About a hover or popup component:
Currently, there's only a debug hover tooltip. As soon as more than two authors are involved, information can become a bit complex. Would some sort of calendar heatmap (like Github's activity chart) be an option? Or is this too much detail for this project?

AuthorSelect design

I'm just going over the differences between our implementation and the original app. One thing that IMO looked nice in the original design was the author list. It did not have checkboxes, but instead author names were greyed out, and colored if selected. Should we adopt the same design? (I'm a bit mixed about it TBH. On the one hand, I like the aesthetics of the original. On the other hand, having explicit checkboxes might be a good thing for UX?)

Design for mobile

  • Expand/collapse global nav
  • Adapt content pages
  • Decide what to do about aside on homepage
  • Stack viz controls vertically
  • Prevent scroll trap on maps
  • Revise mobile author selection (grid?)
  • Fix medium-sized nav issue (already stashed locally)
  • Make author selection collapsible

Trajectories view: GeoJSON layer

Another difference between the original design and our implementation: in the original design, dot-markers in the Trajectories view were scaled by the number of waypoints at this place. Should we replicate this behavior?

Zooming in bug

Once you zoom out all the way, you can't zoom back in. Tried in different browsers.

Legend for reading the intersections map

The original app had an absolutely-positioned legend with an explanation of the visualization on the intersections map. Would likely be worth porting over in some form.

Screen Shot 2022-11-15 at 12 05 51 PM

Convert existing JSDoc for react props to new format (and other docs cleanup)

  • convert my existing props by moving destructured props out of function signatures
  • add @typedef entries for each
  • scope all ReactElement to React.ReactElement
  • document arrow functions (or ignore them with eslint-disable comment)
/**
 * @typedef {Object} Props
 * @property {string} prop1 - The first property of the object.
 * @property {number} prop2 - The second property of the object.
 *
 *  MyFunction takes an object of type Props.
 *
 * @param {Props} props - the props
 */

Map not showing on the new server

Quick question. I hadn't noticed until now, that the tiles are not showing on the project in its new home. Before I start digging into the project files to figure out why, or write the server admins to see if they have some blocks that would do that, do you have any idea why this would be, Ben? I thought you might know.

http://sameboats.org/#/trajectories

Navigation and layout

Doesn't need to follow original exactly.

  • Top navigation instead of side
  • Slight differences for visualizations:

Trajectories:

Screen Shot 2022-09-26 at 4 27 57 PM

Floating for intersections:

Screen Shot 2022-09-26 at 4 30 56 PM

Maintain search state across page navigation

Currently, the search state (=selected authors and time filter) resets when the user changes between Trajectories and Intersections pages. I played with this a bit, and the reason is the following:

  • For each page change, the mapLoader function is triggered, causing the data files to get re-loaded
  • The ITSBGraphProvider creates a new graph whenever the data changes here.
  • Because the graph has changed, the ITSBSearchHandler will reset the search here.

A quick workaround would be to force the ITSBGraphProvider to only ever create the graph once, even if the data changes. E.g.:

useEffect(() => {
  const { authors, places, itineraries } = props;

  // was: if (authors && places && itineraries) { ...
  if (!graph) {
    const g = new ITSBGraph();
    g.init(authors, places, itineraries);
    setGraph(g);
  }
}, [props.authors, props.places, props.itineraries]);

I tested this, and it will retain state across page nav.

Caution: this would mean that the app won't function properly if a different dataset is loaded after the graph was created.This is never the case in our application, however. A cleaner solution, ultimately, would be to avoid re-triggering the mapLoader somehow.

Data warnings/errors

@elotroalex I'm creating this issue you let you know about a few warnings and errors that show up during the CSV conversion. The CSVs are in the /script/in directory.

Skipped entries with no key dates—these waypoints will not be mapped.
Maryse Condé (14): This entry has no key dates listed and has been skipped.
Maryse Condé (22): This entry has no key dates listed and has been skipped.
Maryse Condé (31): This entry has no key dates listed and has been skipped.
Maryse Condé (32): This entry has no key dates listed and has been skipped.
Maryse Condé (33): This entry has no key dates listed and has been skipped.
Maryse Condé (34): This entry has no key dates listed and has been skipped.
Maryse Condé (35): This entry has no key dates listed and has been skipped.
Maryse Condé (36): This entry has no key dates listed and has been skipped.
Maryse Condé (37): This entry has no key dates listed and has been skipped.
Maryse Condé (38): This entry has no key dates listed and has been skipped.
Maryse Condé (39): This entry has no key dates listed and has been skipped.
Maryse Condé (40): This entry has no key dates listed and has been skipped.
Katherine Dunham (147): This entry has no key dates listed and has been skipped.
Katherine Dunham (148): This entry has no key dates listed and has been skipped.
Katherine Dunham (149): This entry has no key dates listed and has been skipped.
Katherine Dunham (150): This entry has no key dates listed and has been skipped.
Katherine Dunham (151): This entry has no key dates listed and has been skipped.
Katherine Dunham (152): This entry has no key dates listed and has been skipped.
Katherine Dunham (153): This entry has no key dates listed and has been skipped.
Katherine Dunham (154): This entry has no key dates listed and has been skipped.
Katherine Dunham (155): This entry has no key dates listed and has been skipped.
Katherine Dunham (156): This entry has no key dates listed and has been skipped.
Katherine Dunham (157): This entry has no key dates listed and has been skipped.
Katherine Dunham (158): This entry has no key dates listed and has been skipped.
Katherine Dunham (159): This entry has no key dates listed and has been skipped.
Katherine Dunham (160): This entry has no key dates listed and has been skipped.
Katherine Dunham (161): This entry has no key dates listed and has been skipped.
Katherine Dunham (162): This entry has no key dates listed and has been skipped.
Katherine Dunham (163): This entry has no key dates listed and has been skipped.
Katherine Dunham (164): This entry has no key dates listed and has been skipped.
Katherine Dunham (165): This entry has no key dates listed and has been skipped.
Katherine Dunham (166): This entry has no key dates listed and has been skipped.
Katherine Dunham (167): This entry has no key dates listed and has been skipped.
Katherine Dunham (168): This entry has no key dates listed and has been skipped.
Katherine Dunham (170): This entry has no key dates listed and has been skipped.
Katherine Dunham (171): This entry has no key dates listed and has been skipped.
Katherine Dunham (172): This entry has no key dates listed and has been skipped.
Katherine Dunham (174): This entry has no key dates listed and has been skipped.
Katherine Dunham (176): This entry has no key dates listed and has been skipped.
Katherine Dunham (177): This entry has no key dates listed and has been skipped.
Katherine Dunham (178): This entry has no key dates listed and has been skipped.
Katherine Dunham (179): This entry has no key dates listed and has been skipped.
Katherine Dunham (180): This entry has no key dates listed and has been skipped.
Katherine Dunham (181): This entry has no key dates listed and has been skipped.
Wifredo Lam (10): This entry has no key dates listed and has been skipped.
Wifredo Lam (11): This entry has no key dates listed and has been skipped.
Wifredo Lam (14): This entry has no key dates listed and has been skipped.
Wifredo Lam (16): This entry has no key dates listed and has been skipped.
Wifredo Lam (23): This entry has no key dates listed and has been skipped.
Wifredo Lam (30): This entry has no key dates listed and has been skipped.
Wifredo Lam (39): This entry has no key dates listed and has been skipped.
Wifredo Lam (43): This entry has no key dates listed and has been skipped.
Wifredo Lam (44): This entry has no key dates listed and has been skipped.
Wifredo Lam (53): This entry has no key dates listed and has been skipped.
Wifredo Lam (54): This entry has no key dates listed and has been skipped.
Wifredo Lam (55): This entry has no key dates listed and has been skipped.
Wifredo Lam (59): This entry has no key dates listed and has been skipped.
Wifredo Lam (61): This entry has no key dates listed and has been skipped.
Wifredo Lam (62): This entry has no key dates listed and has been skipped.
Wifredo Lam (63): This entry has no key dates listed and has been skipped.
Wifredo Lam (76): This entry has no key dates listed and has been skipped.
Wifredo Lam (77): This entry has no key dates listed and has been skipped.
Wifredo Lam (78): This entry has no key dates listed and has been skipped.
Wifredo Lam (79): This entry has no key dates listed and has been skipped.
Wifredo Lam (81): This entry has no key dates listed and has been skipped.
Wifredo Lam (83): This entry has no key dates listed and has been skipped.
Wifredo Lam (97): This entry has no key dates listed and has been skipped.
René Depestre (73): This entry has no key dates listed and has been skipped.
George Lamming (55): This entry has no key dates listed and has been skipped.

There are also two warnings in the app frontend that read "skipping unconnected nodes." These are two waypoints with the following two missing place IDs:

Place ID not found—these places will not be mapped.
René Depestre (11): Place ID  not found in master Place Name list.
René Depestre (81): Place ID ougadogou_burkina_faso not found in master Place Name list.

Finally, this last set does not affect app function, but worth noting anyway:

Country code errors—not critical, only affects the completeness of the Linked Places dataset.

Country codes are matched using pycountry, and that package may have particular country names listed, such as "Cote D'Ivoire" instead of "Ivory Coast."

country code not found for Horta, Azores.
country code not found for Boma, Kongo Central, Democratic Republic of Congo.
country code not found for Matadi, Kongo Central, Democratic Republic of Congo.
country code not found for Mbeni, Democratic Republic of the Congo.
country code not found for Lubumbashi, Democratic Republic of the Congo.
country code not found for Kinshasa, Democratic Republic of the Congo.
country code not found for Bournemouth, England.
country code not found for Cambridge, England.
country code not found for Falmer, Sussex, England.
country code not found for London, England.
country code not found for English Provinces, England.
country code not found for England.
country code not found for Liverpool, England.
country code not found for Manchester, England.
country code not found for Hull, England.
country code not found for Margate, England.
country code not found for Ramsgate, England.
country code not found for Brighton, England.
country code not found for Lake District, England.
country code not found for Southampton, England.
country code not found for Newcastle upon Thyne, England.
country code not found for Knaresborough, England.
country code not found for Europe.
country code not found for Abidjan, Ivory Coast.
country code not found for Grand-Bassam, Ivory Coast.
country code not found for Malay Federation (Malaysia).
country code not found for Brazzaville, Republic of Congo.
country code not found for Saint Maarten.
country code not found for Saint-Thomas.
country code not found for Scotland.
country code not found for Glasgow, Scotland.
country code not found for St Maarten.
country code not found for Basseterre, St. Kitts and Nevis.
country code not found for Ho, Trans-Volta Togoland.
country code not found for Trinidad & Tobago.
country code not found for Yugoslavia.
country code not found for Bingerville, Ivory Coast.
country code not found for Portsmouth, England.

EDIT: Ouagadougou has been fixed.

GeoJSON layer of linked places

I don't think it would cause much overhead. It would essentially be a single group-by operation, which should be quite fast. (Itineraries are lists of waypoints. You'd just need to loop through the waypoints once to get a list of distinct place IDs. Probably hardly noticable on today's hardware, even with many waypoints.) Once you have the place ID, you can map the IDs to GeoJSON features by retrieving them from the in-memory graph. Should also be very fast.

Originally posted by @rsimon in #4 (comment)

Website

The website is a rebuild of https://sameboats.org/. It should be built following core principles of minicomp, consistent with using mature, widely deployed tech. It should have sections for:

Candidates for a framework could include, but are not limited to:

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.