Sunday, June 16, 2024

Happy Father's Day!

Happy Father's Day to all the dads out there, from me, also a dad.  I'm spending today watching the Seattle Mariners on my TV (hoping they can capture their first division title since 2001), and working on my website a bit!

Welcome to all the new visitors from japanballtickets.com, and thanks again to that website's proprietor Michael Westbay for featuring sportsmap.world on his site, and also for providing me with more accurate Japanese baseball schedule data, which was a big goal of mine because I love the NPB experience.

I'm going to experiment with a Reddit ad campaign to see if I can get some more traffic coming in that way.  Should be fun to see if we get some new users from that.

Everything is out-of-pocket for this site; there's no ad revenue, no tracking data, no cookies, etc.  Just old-timey fun that's "free" as in beer, as we used to say.  (Personally, I've gotten weary of previously good quality Internet experiences getting further degraded by staid corporations and narcissistic billionaires, so I'm enjoying just bringing useful and fun data visualization to the masses.)  I'm paying for site hosting, domain registration, and now an ad campaign, but I'm treating it all as a hobby expense and just for fun, at least for now.

I always put a disclaimer up to remind people to double-check venue and event information before making travel plans, partially because of the way I collect venue information for some events.  My primary data source doesn't always provide venue data explicitly along with events' data, and in those cases, I do a query for the home team's usual home venue.  Of course, that might not be correct; some events might take place at neutral or alternate sites, and in some cases my data source has incorrect or out-of-date venue information for a competitor.  

This has been a problem with the NBA's development league, which has seen frequent relocation of teams; I've noticed that sometimes the venue info for the home team is way out of date.  Closer to where I live, there's a popular lower-level soccer team called FC Ballard, which previously played its home matches at a small stadium in the Interbay neighborhood of Seattle, but has this year switched to Memorial Stadium in the shadow of the Space Needle (where I refereed dozens of high school football games in the past).  I've made some spot fixes here and there for the venues I've noticed don't look right or that I know to be wrong, but of course, I can't do that for the whole world, so some venues may just be wrong.  Always verify the venue before you book travel or tickets!

Along those lines, a lot of the home-team venue entries I collected for these "unvenued" events are more than a year old, and I'm going to start doing some work to refresh them on a regular basis.  The number of queries I'm allowed to make from my primary data source are limited, so I have to be a little strategic about it; but, my goal is to try to make sure these are no more than about 15 months out of date.  Doing this allows me to present way more events than I previously was able to, including college sports, lower-level soccer leagues, etc.

By the way, if you enjoy the site, feel free to connect with me on LinkedIn to drop me a line, or Buy Me a Coffee!  I recently re-entered to workforce as a principal engineer working on Tableau Public, one my old employers; that's quite exciting indeed, but it also means that for now, that will get most of my engineering attention, so changes here will be less frequent.  I do at least plan to keep it running, and fortunately the site is in good shape and actually requires very little maintenance to keep the lights on and the event updates flowing.

Sunday, March 17, 2024

Adding alternate sites for the NPB; thanks, JapanBallTickets.com

Japan's professional baseball league, NPB (Nippon Professional Baseball), is near and dear to my heart.  I first visited in 2016 and was captivated by the crowd and atmosphere at a game in Hiroshima between the Carp and the Tigers.  My wife and I sat in the visitor's "performance" section with the Tigers' supporters at Mazda Stadium, and they could not have been friendlier (or rowdier!).  Since then I've been back to see games in 2018 at Meiji Jingu Stadium in Tokyo, in 2019 at the Fukuoka PayPay Dome and Koshien Field, and in 2023 at the Tokyo Dome.  It's always been a delight to catch one of these games and marvel at the atmosphere.

It was really important to me to get the NPB schedule data right; some games take place at alternate venues across the country (for example in Akita, Okinawa, and Kumamoto), and I wanted to represent those correctly on the map.  Enter Michael Westbay, the brains behind JapanBallTickets.com; he was kind enough to share his spreadsheet of ticketing data, which contains the correct locations for all games during the season.  After adapting his data, I'm happy to present correct alternate venue locations for NPB games in 2024:



This was something I really wanted to get right on the site, and it's nice to be able to do so.  As I write this, my primary data source has correct date/time info for games through May 29; after that, a few games have had their start times changed, but it isn't yet reflected in the data.  

As always, please verify start times and home venues with the home team before making travel plans and buying tickets.  

Have a great season and play ball!

Saturday, September 2, 2023

Improved filter performance; implementing custom hooks with react-query made it easier

I finally got some time to do a little work on sportsmap.world, and used it to work on improving filter performance in the frontend.

Working with getting start times for all these sporting events displaying correctly in their local time zone is actually a little tricky; it gets harder when you consider how to filter by date.  Midnight on September 2 in Seattle is different from the start time of September 2 in Italy, when you consider all the times I'm working with are normalized to UTC.  I had previously been doing a calculation at filter time to determine if the local start time for an event fell within the date filter range; by moving that calculation to the initial query function, I was able to improve query performance in the frontend.  

(Not a super-complicated perf improvement, but as with all software tasks, it's just a matter of finding the time and getting in the right mental space to work on it.)

One thing I have warmed up to is using custom hooks in React, especially in conjunction with Tanstack's react-query library.  One of my setup tasks for this perf improvement was to refactor two similar backend queries into a single custom hook with input parameters.  By tying into react-query's existing hooks for data, isLoading, isError, etc., I've been able to greatly reduce my own usage of useEffect, which makes for cleaner components.

A great combination I used on a recent work project: OpenAPI to define backend APIs, openapi-typescript and openapi-typescript-fetch to turn the API into usable Typescript objects, react-query to do the querying and maintain loading state and show errors, and wrap it all up into a custom hook which can be re-used by multiple components.  A really clean solution, especially for projects where the frontend is stateless; that is, object state is the responsibility of the backend, which is an especially useful paradigm for microservice environments.

Monday, February 6, 2023

Big changes: more events starting with version 2 of sportsmap.world!

One of my goals with sportsmap.world was to be able to show the full, wide world of sporting events taking place around the world.  Not just the big events like the "Big Game" coming up next Sunday in Glendale, Ariz., but the small events, like the Everett Silvertips junior hockey team about a half hour up the interstate from my house.

I've had to dance around some of the limitations of my data source; simply put, I'm limited in the number of API calls I can make per month.  I can query each calendar day for events and updates, but only up to 1,000 calls per sport per month.  Most of the major events have venue information with lat/long locations attached to their event objects, but many more smaller events do not; this includes some leagues I wanted to represent on the map, including Japanese baseball (NPB), junior hockey across Canada and the U.S., minor league baseball, smaller soccer leagues across Europe and the rest of the world, etc.

For many summers as a kid, I would visit my dad in Great Falls, Montana; I spent several summer days at the local ballpark, watching the Great Falls Dodgers (now Great Falls Voyagers) rookie-league team.  It was something fun to do at a time when I would have been otherwise bored; I loved having the distraction, following the teams' budding young stars, and getting an up close seat of the action.  It was at one of these games, on a chilly, windy night, when I discovered my love for coffee (the ballpark had cups available for $0.25 each!).

I'd like for people who are traveling in an unfamiliar place to be able to see on a map where events are going on, no matter how small they are.  Now on the map, you can find really minor soccer leagues, lower levels of college basketball, college and junior hockey, and more.  I see these as "neighborhood" events; fun to check out if you're in the area, are bored, and want to see what sports looks like where you are.

One world of caution: to get the venues for these events, I'm querying for the home stadium of the listed home team.  This won't always be accurate; for example, my beloved Hanshin Tigers don't play all of their games at Koshien Stadium, even though that is how their home games would otherwise be listed (because my data feed lacks more specific venue information).  I'm considering ways to put a disclaimer on these events' venue information to call that out.  In other cases, I'm finding that the lat/long information for venues is not always correct; there are some typos in the data source.

In the meantime, as always, please verify the home venue and location before making travel plans for buying tickets.  Check the website of the league or hosting team, or consider calling or e-mailing them directly.  

Do give these teams and smaller leagues your support; in many cases they depend on live fan support and ticket sales to keep them afloat!

Tuesday, December 27, 2022

Map marker clusters and more user-friendly UI changes!

A big big thank you to open source developer Leigh Halladay, who published this useSupercluster hook for React:

use-supercluster npm package

use-supercluster Github page

I had been wanting to do map marker clustering using Mapbox and React, but hadn't found a solution until I stumbled on Leigh's library, described here.

This finally allowed me to cluster markers together, allowing me to publish sportsmap.world with a much friendlier interface for mobile users.  I've made additional changes to make the site more smartphone and mobile friendly, as that's the primary experience for most people browsing the web these days!

More UI upgrades since November:

- A better mobile calendar experience, including a dropdown calendar widget to allow you to select a date range, rather than relying on the double-date slider (which is still present for wider screen).

- A filter-by-sport widget, to remove specific sport pins from the map.

- Fast load times & optimized queries, plus a loading spinner while the initial query is in progress

Tuesday, October 4, 2022

Navigating the (React x Google Maps) Wild West

I wanted to try Google Maps in my React front-end, and figured that probably someone has written a React wrapper for Google Maps, or perhaps Google itself had taken it on at some point.

Here are some open-source packages that show up in an npm search:

  • react-google-maps, last updated five years ago but still gets 150k downloads/day.
  • @react-google-maps/api, a "complete re-write of the (sadly unmaintained) react-google-maps"
  • google-map-react 
  • google-maps-react 😂
  • @google-maps/react-wrapper
  • simple-react-google-maps [Sure, Jan]
  • react-maps-google [Now I'm just annoyed]
  • react-hook-google-maps [For those of you addicted to custom hooks for everything]
  • react-google-maps-loader 
  • react-static-google-map 
  • google-maps-react-17 [I guess the 17 is for React v17? Great, that will never go out of date]
  • google-maps-js-api-react

There are more, of course.  I feel like I'm in NYC looking for real Original Ray's.  Or maybe touring a graveyard.

So!  This is frustrating for a number of reasons:

  • They all solve the problem slightly differently, so the resulting React code can look vastly different depending on which one you use.
  • Looking for help on Stack Overflow or Google is difficult, because I keep winding up on help for a different repository.
  • The varying degrees of unmaintainedness [new word copyright me] of these repositories by their owners makes it hard to pick one; and I don't have a whole lot of faith that the one I pick will be maintained long-term.
  • My ultimate solution doesn't feel very React-like.  A lot of these packages tackle the simple case of adding a map element and some markers, but I wanted to go a little further than that by clustering close-together markers and adding a search bar.  I would expect to be able to add child elements to a parent map element that do that, but could not find a package that gives me that option.  I think I have a solution that works, but it involves creating a React useRef hook to manipulate the map object directly; not very React-y, definitely feels like I'm breaking some rules.
  • I'm sure there's a React developer out there who will say, "Oh of course you should use react-maps-google, you fool!  It's obviously the best one!"
I like React for simple things, and it's been good for quickly building up my frontend, but often when I get into more complicated scenarios, finding the correct path forward is non-obvious to say the least.  And this is a framework that came out nearly 10 years ago!  There have been so many fundamental changes to React that it's hard to keep up with the latest best practices, and among the community there seems to be a lot of disagreement on that anyway.  This situation with the dozen-plus possible Google Maps packages feels like more of the same chaotic soup.

Wednesday, September 21, 2022

Version 1.2.0 is live

 A few minor improvements:

  • Added a Mapbox search widget (called a Geocoder in code), which allows you to search and zoom the map to a destination.  Useful to search for sporting events near a specific landmark, hotel, address, etc.
  • Changed some data query profiles around so that events coming up in the upcoming week and upcoming month get refreshed more frequently.  (As always, check with official league and/or team online resources to verify up-to-date event venues, dates and times.)
What I'm working on next:
  • There are a couple of things Mapbox doesn't lend itself well to, especially for the mobile experience; I'd like to be able to group map pins together, for example.  Also I'm finding some locations aren't up to date in the search box (Seattle's Lumen Field is still called CenturyLink Field, for example).  I'll be experimenting with Google Maps' API to see if I like the user experience better (and also if I like the React developer experience any more or less!).
  • Some other UI elements need to be improved for the smartphone user experience, which is the dominant one these days.
  • The filter widget could use some alternate method to easily pick dates, like a calendar widget.  Will be looking around for one of those.
  • Filtering by sport would be nice.
Another future backlog item:
  • My data source has info on a lot more events that don't have venue location information attached.  I'd like to come up with a way to show a pin for the assumed venue based on the home team; this is going to take a little work to make sure I get it right.  If I can get it work, I can greatly increase the number of leagues and teams I show (for example, Japanese professional baseball, minor league baseball in the US, WNBA, etc.).  Ultimately I'd like to even show lower-league soccer; sometimes there's a team playing in your neighborhood and you wouldn't otherwise know it!  That could be a fun way to spur local community interest in more minor leagues and teams.  (Or, help you figure out something fun to do outside of the house when you're visiting relatives over the holidays...?)
Enjoy and beinvenue au monde sportif, bon voyage!