00runners 2번째 러닝 세션이 열렸다. 어제는 광화문을 뛰었다. 페이서들이 신경써준 덕분에 사고는 발생하지 않았지만 보행자와 엉키거나 횡단보도에서 자칫 위험해질 뻔한 상황들이 있었다. 다름 러닝까지 안전에 대한 부분을 많이 보강해야겠다.
00runners의 포인트 시스템, Marathon
디스콰이엇에서 메이커 챌린지를 설계하고 운영하면서 포인트 시스템이 참가자 간의 교류를 유의미하게 증가시킨다는 인사이트를 얻었다. 그래서 크루도 Game-fi 하고 있다.
멤버는 정규런에 한 번 참여할 때마다, QR코드로 체크인하면 5K 씩 Marathon을 받을 수 있다.
우리 크루는 매주 금요일 정규런을, 정규런 중에서 한달에 한번에는 '용기런'이라는 이름으로 Member Only Run을 연다. 이때 용기런에는 더 많은 크루 멤버가 왔으면 좋겠다는 생각에서 Marathon을 10K 씩 준다.
그리고 멤버 리스트 대시보드를 만들어서 Marathon 점수 순서대로 보여지게 했다. QR 체크인 데이터에 기반해서 포인트를 합산하고 정렬하는 코드를 짰다. 이 웹은 백엔드가 없다.
"QR코드 -> Tally 폼 -> 구글 시트에서 수동으로 데이터 정리하기 -> JSON 파일로 업로드" 한다.
HTML의 컴포넌트화
Bootstrap이라는 프론트엔드 라이브러리를 커스텀해서 사용하면서, 쌩 HTML을 컴포넌트화하여 사용한다. 깐지는 떨어지지만 내가 쓰기 쉬우면 되는 거 아닌가 싶다.. 이런 코드를 html 파일 맨 아래에 넣는다.
import c from "/src/component.js";
document.getElementById("navBar").insertAdjacentHTML("beforeEnd", c['navBar']);
document.getElementById("nextRun").insertAdjacentHTML("beforeEnd", c['nextRun']);
document.getElementById("footer").insertAdjacentHTML("beforeEnd", c['footer']);
지금까지는 정적(static) 웹을 만들고 있기 때문에 상태관리가 필요하지 않아서 리액트 등의 라이브러리를 쓰지 않고도 충분히 재밌게 만들 수 있다. 참고로 component.js파일은 아래와 같이 생겼다.
export default {
"navBar" :
` <nav id="navbar-example2" class="navbar bg-transparent px-3 fixed-top" style="font-size: 1rem; font-family: 'Roboto Mono'; backdrop-filter: blur(1px); -webkit-backdrop-filter: blur(1px);">
<a class="navbar-brand" href="index.html" style="color: white; font-size: 1.2rem"><b> 00runners</b></a>
<ul class="nav nav-pills">
<li class="nav-item">
<a class="nav-link" style="border-radius: 50px; color: white" href="index.html#member">멤버</a>
</li>
</nav>`,
"nextRun" :
` <h2 style="margin-bottom: 16px;">Next Run:</h2>
<p style="text-align: center; line-height: 60%;">3/24 (금)</p>
<p style="text-align: center; line-height: 60%; font-size: 1.6rem;"><b>석촌호수 5K</b></p>`,
"footer" :
`<section id="footer" style="font-family: 'Roboto Mono'; text-align: center; color: grey;">
2023 (c)00runners<br><small>Design/Development: 박종한</small>
</section>
<br><br>`
}
SQL 없이 데이터 가져오고 정렬하기
예전에 들었던 웹개발 온라인 강의(이고잉 선생님과 Angela Yu 선생님 감사합니다)에서 NoSQL이 Javascript Object의 구조를 가진다고 했던 게 기억났다. 원래 나는 학교에서 IoT 프로젝트의 하드웨어랑 서버를 만들면서 웹개발에 입문해서 MySQL과 PHP를 쓰는 사람이었지만, 정적으로 이미 정리된 데이터를 가져와 복잡하지 않은 방식으로 정렬해서 보여주는 거라면 굳이 sql을 쓰지 않아도 될 것 같았다.
그래서 공통된 key로 uid라는 키를 사용하는 json 파일 2개를 만들었다. 하나는 user.js, 하나는 log.js 이다. 테이블을 두개로 나눈 건 업데이트의 편리함 때문이다. 러닝 회차가 거듭될 때마다 log.js 테이블만 tally form 데이터를 csv로 다운받아 이상한 데이터를 정리한 뒤 csv2json 웹을 활용해서 넣어주면 된다.
관계형 json을 사용해서, 쿼리 대신에 파일 전체를 import 하고 reduce와 map 함수들을 이용해서 view를 위한 형식으로 만든다. 이건 회원수가 120명 정도밖에 안돼서 가능하다. 회원수가 1만명이고 이랬다면 더 나은 방식을 찾았어야 할 것이다.
(신규 업데이트!) 처음으로 해보는 데이터 시각화
D3 is a JavaScript library for visualizing data with HTML, SVG, and CSS.
d3.js 라는 라이브러리를 처음으로 사용해 보았다. 데이터 시각화를 도와주는 자바스크립트 라이브러리인데 정말 다양한 함수와 기능을 제공한다. svg로 막대그래프를 그렸다. 나는 승부욕이 강한 편이라 포인트 시스템 속에 들어가면 쉽게 중독된다. 다른 경쟁자들은 어느 정도 있고, 1등을 하려면 얼마나 더 열심히 참여해야 하는지 한눈에 보고 싶어 한다ㅋㅋ. 00runners.xyz에도 그래프가 있으면 한눈에 보기 쉬울 것 같아서 만들었다. 아직 디자인 완성도는 떨어지지만, 러닝 세션이 반복되면서 그래프 모양이 달라지는 걸 보는 건 흥미로울 것 같다.
내가 만들고 있는 00runners.xyz는 아래 링크에서 볼 수 있다.
메이킹이 너무 재밌다
나는 내가 어떤 시스템을 만들고 그 안에서 보여지는, 움직이는 걸 뚝딱뚝딱 만드는게 너무 재밌다. 요즘 주말 새벽에 이런 걸 만들고 있는데 이 시간이 진짜 행복하다. 처음 웹으로 이것저것 만들어볼 때 '개발의 한계는 오직 나의 상상력에 있다'는 생각이 들었다. 내가 웹사이트에 넣고 싶어하는 모든 걸 이미 만들어서 예제로 제공하는 사람들이 있었다.
나는 커뮤니티 데이터를 활용하여 커뮤니티의 문화 유틸리티와 디지털 오브제 를 만드는 사람이 되고 싶다. 그걸 하기 제일 좋은 곳이 디스콰이엇이다. 그래서 기쁜 마음으로 커뮤니티 운영과 프로그램/상품 개발을 하고 있다.
d3.js 오랜만이네요 ㅎㅎ 종한님은 정말 메이커 같아요 멋져요!