Skip to content

Commit

Permalink
Merge pull request #59 from conveyal/add-storybook
Browse files Browse the repository at this point in the history
Add storybook for improved testing/debugging
  • Loading branch information
evansiroky committed Nov 24, 2020
2 parents 6c17b8d + 867f653 commit ada188e
Show file tree
Hide file tree
Showing 16 changed files with 11,231 additions and 1,983 deletions.
11 changes: 11 additions & 0 deletions .babelrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"presets": [
[
"@babel/preset-env", {
"useBuiltIns": "entry",
"corejs": 2
}
],
"@babel/preset-react"
]
}
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ lib-cov
*.csv
*.dat
*.out
out*
*.pid
*.gz

Expand Down
17 changes: 17 additions & 0 deletions .storybook/main.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
const path = require('path')
// your app's webpack.config.js
const custom = require('./webpack.config.js');

module.exports = {
stories: ['../stories/*.stories.js'],
addons: [
'@storybook/addon-links',
'@storybook/addon-essentials',
'@storybook/preset-create-react-app'
],
// Ensures that, when running storybook, webpack rules (loaders for css, file,
// etc.) from the custom config are used.
webpackFinal: (config) => {
return { ...config, module: { ...config.module, rules: custom.module.rules } };
}
}
72 changes: 72 additions & 0 deletions .storybook/webpack.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
const path = require('path');
const webpack = require('webpack');

/**
* This is a (mostly) auto-generated webpack config that storybook created when
* initializing the storybook.
*/

const TerserPlugin = require('terser-webpack-plugin');

module.exports = {
mode: 'development',
entry: '../lib/transitive.js',

output: {
path: path.resolve(__dirname, 'build'),
},

plugins: [new webpack.ProgressPlugin()],

module: {
rules: [
{
test: /\.(js|jsx)$/,
include: [path.resolve(__dirname, '../lib'), path.resolve(__dirname, '../stories')],
loader: 'babel-loader',
},
{
test: /\.(png|jpe?g|gif)$/i,
use: [
{
loader: 'file-loader',
},
],
},
{
test: /.css$/,

use: [
{
loader: 'style-loader',
},
{
loader: 'css-loader',

options: {
sourceMap: true,
},
},
],
},
],
},

optimization: {
minimizer: [new TerserPlugin()],

splitChunks: {
cacheGroups: {
vendors: {
priority: -10,
test: /[\\/]node_modules[\\/]/,
},
},

chunks: 'async',
minChunks: 1,
minSize: 30000,
name: false,
},
},
};
10 changes: 10 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,13 @@ notifications:
email: false
node_js:
- '10'
# Install AWS CLI for uploading storybook to S3.
before_install:
- pyenv global 3.7.1
- pip install -U pip
- pip install awscli
# add aws 'default' profile for uploading storybook
- mkdir ~/.aws && printf '%s\n' '[default]' "aws_access_key_id=${AWS_ACCESS_KEY_ID}" "aws_secret_access_key=${AWS_SECRET_ACCESS_KEY}" 'region=us-east-1' > ~/.aws/config
install:
- yarn
script:
Expand All @@ -14,6 +21,9 @@ script:
after_success:
- bash <(curl -s https://codecov.io/bash)
- semantic-release
# Deploy storybook demo to S3 if handling a non-PR build on the main branch
# https://s3.amazonaws.com/transitive.js/index.html
- if [ "$TRAVIS_BRANCH" = "master" -a "$TRAVIS_PULL_REQUEST" = "false" ]; then yarn deploy-storybook; else echo 'skipping deploy to s3'; fi
branches:
except:
- /^v\d+\.\d+\.\d+$/
34 changes: 34 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,40 @@ A Transitive map can be embedded as a freestanding web element or overlaid onto

Transitive is supported by the [Mobility Lab](http://mobilitylab.org/) [Transit Tech Initiative](http://mobilitylab.org/tech/transit-tech-initiative/). Read more in [this Mobility Lab article](http://mobilitylab.org/2014/04/16/the-technology-behind-a-new-kind-of-travel-planning/).

## Storybook

To view samples of Transitive in action, [check out the live Storybook](https://s3.amazonaws.com/transitive.js/index.html).

You can also run this locally with:

```bash
git clone https://github.com/conveyal/transitive.js
cd transitive.js
yarn start
# Go to http://localhost:5555 to view the storybook (the web page should open automatically)
```

### Usage of otp-ui

These stories rely on the [otp-ui](https://github.com/opentripplanner/otp-ui)
project to render transitive data on a Leaflet map. Specifically, it uses:
- @opentripplanner/base-map - renders a Leaflet base map
- @opentripplanner/core-utils - converts an OpenTripPlanner itinerary object into
data that Transitive can read.
- @opentripplanner/transitive-overlay - copied from the otp-ui project and
replaces the Transitive import with the local copy (useful for testing local
changes)

### BYOD - Bring your own data

To test out how your own data (e.g., an OpenTripPlanner itinerary) would appear in
Transitive, try replacing the `itinerary` prop in the [Itinerary](https://s3.amazonaws.com/transitive.js/index.html?path=/story/example-transitive--itinerary) (for OpenTripPlanner itineraries) story (or `transitiveData`
in the [Profile](https://s3.amazonaws.com/transitive.js/index.html?path=/story/example-transitive--profile)
story).

You can also override the default style by adding a `style` prop. See a style
example here: https://github.com/conveyal/transitive-demo/blob/master/styles.js

## Demo

* [Demo of a freestanding Transitive map](http://conveyal.github.io/transitive.js)
Expand Down
12 changes: 6 additions & 6 deletions lib/styler/styles.js
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ const stopsMerged = {

'marker-padding': 3,

visibility: function (display, data) {
visibility: (display, data) => {
if (!data.owner.containsSegmentEndPoint()) return 'hidden'
}
}
Expand All @@ -112,18 +112,18 @@ const stopsMerged = {
* Stops Along a Pattern
*/

const stopsPattern = exports.stops_pattern = {
const stopsPattern = {
cx: 0,
cy: 0,
r: [
4,
function (display, data, index, utils) {
(display, data, index, utils) => {
return utils.pixels(display.scale, 1, 2, 4)
},
function (display, data, index, utils) {
(display, data, index, utils) => {
var point = data.owner
var busOnly = true
point.getPatterns().forEach(function (pattern) {
point.getPatterns().forEach(pattern => {
if (pattern.route && pattern.route.route_type !== 3) busOnly = false
})
if (busOnly && !point.containsSegmentEndPoint()) {
Expand All @@ -132,7 +132,7 @@ const stopsPattern = exports.stops_pattern = {
}
],
stroke: 'none',
visibility: function (display, data) {
visibility: (display, data) => {
if (display.scale < 1.5) return 'hidden'
if (data.owner.containsSegmentEndPoint()) return 'hidden'
}
Expand Down
31 changes: 26 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,19 +26,40 @@
"sphericalmercator": "^1.0.5",
"svg.js": "^2.6.5"
},
"peerDependencies": {
"svg.js": "^2.6.4"
},
"scripts": {
"prepublish": "mastarm prepublish lib:build",
"cover": "npm test -- --coverage",
"lint": "mastarm lint lib",
"semantic-release": "semantic-release pre && npm publish && semantic-release post",
"test": "mastarm test"
"start": "start-storybook -p 5555",
"deploy-storybook": "storybook-to-aws-s3 --bucket-path=transitive.js --s3-sync-options=--acl=public-read"
},
"devDependencies": {
"@babel/core": "^7.12.3",
"@babel/preset-env": "^7.12.1",
"@opentripplanner/base-map": "^1.0.4",
"@opentripplanner/core-utils": "^3.0.2",
"@storybook/addon-essentials": "^6.1.0-beta.6",
"@storybook/addon-info": "5.3.21",
"@storybook/addon-links": "^6.1.0-beta.6",
"@storybook/preset-create-react-app": "^3.1.5",
"@storybook/react": "^6.1.0-beta.6",
"@storybook/storybook-deployer": "^2.8.7",
"@webpack-cli/init": "^1.0.3",
"babel-loader": "^8.1.0",
"core-js": "2",
"css-loader": "^5.0.1",
"file-loader": "^6.2.0",
"leaflet": "^1.7.1",
"lodash.isequal": "^4.5.0",
"mastarm": "^5.0.1",
"semantic-release": "^15.13.16"
"react-leaflet": "^2.6.1",
"semantic-release": "^15.13.16",
"style-loader": "^2.0.0",
"styled-components": "^5.2.1",
"terser-webpack-plugin": "^5.0.3",
"webpack": "^5.4.0",
"webpack-cli": "^4.2.0"
},
"standard": {
"parser": "babel-eslint"
Expand Down
35 changes: 35 additions & 0 deletions stories/Transitive.stories.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import {TransitiveMap} from './TransitiveMap'

const companies = [
{
id: 'RAZOR',
label: 'Razor',
modes: 'MICROMOBILITY_RENT'
},
{
id: 'SHARED',
label: 'Shared',
modes: 'MICROMOBILITY_RENT'
}
]

export default {
title: 'Example/Transitive'
}

const Template = (args) => TransitiveMap(args)

export const Itinerary = Template.bind({})
Itinerary.args = {
companies,
itinerary: require('./data/walk-interlined-transit-walk-itinerary.json'),
styles: undefined
}

export const Profile = Template.bind({})
Profile.args = {
center: [38.885, -77.0369],
styles: undefined,
transitiveData: require('./data/profile.json'),
zoom: 14
}
52 changes: 52 additions & 0 deletions stories/TransitiveMap.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import BaseMap from '@opentripplanner/base-map'
import {itineraryToTransitive} from '@opentripplanner/core-utils/lib/map'
import React from 'react'
import styled from 'styled-components'

import TransitiveOverlay from './transitive-overlay'

import '../node_modules/leaflet/dist/leaflet.css'

require('./leaflet-canvas-layer')

const MapContainer = styled.div`
height: 800px;
width: 100%;
.map {
height: 800px;
width: 100%;
}
* {
box-sizing: unset;
}
`

/**
* Primary UI component for user interaction
*/
export const TransitiveMap = ({
center = [45.506, -122.68302],
companies = [],
itinerary,
styles,
// If no transitiveData is provided, default to generating from itinerary.
transitiveData = itineraryToTransitive(itinerary, companies),
zoom = 15
}) => {
return (
<MapContainer>
<BaseMap
// TODO: Determine center/zoom based on input data?
center={center}
zoom={zoom}
>
<TransitiveOverlay
transitiveData={transitiveData}
visible
/>
</BaseMap>
</MapContainer>
)
}
1 change: 1 addition & 0 deletions stories/data/profile.json

Large diffs are not rendered by default.

Loading

0 comments on commit ada188e

Please sign in to comment.