Commit b9cb1e08 authored by Almouhannad Hafez's avatar Almouhannad Hafez

Add scatter plot

parent 0a8a1501
trail,region,difficulty,time,distance,season
Abby Grind,Fraser Valley East,Intermediate,1.5,4,year-round
Admiralty Point,Tri Cities,Easy,1.5,5,year-round
Al's Habrich Ridge Trail,Howe Sound,Intermediate,5,7,July - October
Aldergrove Regional Park,Surrey and Langley,Easy,2,5,year-round
Alexandra Bridge,Fraser Valley East,Easy,0.5,1.6,March - November
Alice Lake,Howe Sound,Easy,2,6,April - November
Ancient Cedars Trail,Whistler,Intermediate,2,5,June - October
Ascent Trail,Whistler,Difficult,3.5,6.1,July - September
Baden Powell Deep Cove to Lynn Canyon,The North Shore,Intermediate,5,12,year-round
Baden Powell Lynn Canyon to Grouse,The North Shore,Intermediate,5,10,year-round
BCMC Trail,The North Shore,Difficult,1.5,3,June - September
Bert Flinn Park,Tri Cities,Easy,1,2.6,year-round
Big Cedar and Kennedy Falls Trail,The North Shore,Intermediate,5,10,year-round
Black Tusk,Whistler,Difficult,11,29,July - October
Blackcomb Meadows,Whistler,Intermediate,3,8,July - October
Bosumarne Falls,Fraser Valley East,Easy,1,2.5,April - November
Boundary Bay Regional Park,Tsawwassen and Delta,Easy,2,5,year-round
Bowen Lookout,The North Shore,Easy,1.5,4,July - October
Brae Island Regional Park,Surrey and Langley,Easy,1,4.2,year-round
Brandywine Falls,Whistler,Easy,0.5,1,year-round
Brandywine Meadows,Whistler,Difficult,3.5,6,July - October
Bridal Veil Falls,Fraser Valley East,Easy,0.25,0.8,May - October
Brohm Lake,Howe Sound,Intermediate,5,7.5,April - October
Brothers Creek Loop,The North Shore,Intermediate,4,7,April - November
Brunswick Point,Tsawwassen and Delta,Easy,2,8,year-round
Buntzen Lake,Tri Cities,Easy,3.5,10,year-round
Burnaby Lake,Vancouver City,Easy,2,10,year-round
Burnaby Mountain,Vancouver City,Easy,3,7.5,year-round
Burnett Falls,Sunshine Coast,Easy,0.5,0.5,year-round
Burns Bog Delta Nature Reserve,Tsawwassen and Delta,Easy,1.5,3,year-round
Campbell Valley Regional Park,Surrey and Langley,Easy,1.5,4,year-round
Capilano Canyon,The North Shore,Easy,1,2.6,year-round
Capilano Pacific Trail,The North Shore,Easy,4,15,year-round
Cascade Falls,Fraser Valley East,Easy,0.5,0.75,April - November
Chapman Falls,Sunshine Coast,Easy,1.5,4,year-round
Cheakamus Canyon Trail,Howe Sound,Easy,3,9,April - October
Cheakamus Lake,Whistler,Easy,5,16,May - November
Cheam Lake Wetlands,Fraser Valley East,Easy,1,2.3,year-round
Chilliwack Community Forest,Fraser Valley East,Easy,1.5,3,February - November
Cliff Gilker Park,Sunshine Coast,Easy,1,2,year-round
Coliseum Mountain,The North Shore,Difficult,10,23.5,July - September
Colony Farm Regional Park,Vancouver City,Easy,1.5,8,year-round
Conflict Lake,Whistler,Intermediate,5,12,June - September
Cool Creek Canyon,Pemberton,Intermediate,2,2.5,April - October
Coquitlam Crunch,Tri Cities,Intermediate,1.5,4.5,year-round
Crater Rim Trail,Whistler,Intermediate,2,4.5,May - October
Crooked Falls,Howe Sound,Intermediate,3.5,6,April - November
Crown Mountain,The North Shore,Difficult,7,9.8,July - October
Crystal Falls,Tri Cities,Easy,2,7,year-round
Cypress Falls,The North Shore,Easy,1.5,3,year-round
Dam Mountain,The North Shore,Easy,2,5,July - September
Deas Island Regional Park,Tsawwassen and Delta,Easy,2,4.5,year-round
Deer Lake,Vancouver City,Easy,1,5,year-round
Demon Ridge,Howe Sound,Difficult,8,16,July - September
Derby Reach Regional Park,Surrey and Langley,Easy,2.5,8,year-round
Dilly Dally Loop,Tri Cities,Difficult,12,25,July - October
Dog Mountain,The North Shore,Easy,2,5,June - October
Dorman Point,Howe Sound,Easy,1,2.5,year-round
Downes Bowl Trail,Fraser Valley East,Easy,1,3,year-round
Eagle Bluffs,The North Shore,Intermediate,4,8,July - October
Eagle Bluffs via Horseshoe Bay,The North Shore,Difficult,7.5,11.5,June - October
Elfin Lakes,Howe Sound,Intermediate,6,22,July - October
Elk Mountain,Fraser Valley East,Intermediate,4,7,June - October
Falls Lake,Fraser Valley East,Easy,1,2,May - October
Fisherman's Trail,The North Shore,Easy,5,12,year-round
Flood Falls,Fraser Valley East,Easy,0.75,1,year-round
Foreshore Trail,Vancouver City,Easy,3,5,year-round
Fort To Fort Trail,Surrey and Langley,Easy,2.5,8,year-round
Francis Point Provincial Park,Sunshine Coast,Easy,1.5,3,year-round
Frosty Mountain,Manning Provincial Park,Difficult,8,22,July - September
Garibaldi Lake,Whistler,Intermediate,5,18,July - October
Goat Mountain,The North Shore,Intermediate,4,8,July - October
Gold Creek Falls,Ridge Meadows,Easy,2,5.5,year-round
Golden Ears,Ridge Meadows,Difficult,12,24,July - September
Golden Ears Canyon Loop,Ridge Meadows,Intermediate,4,12,April - October
Goldie Lake,The North Shore,Easy,2,3,June - October
Grouse Grind,The North Shore,Difficult,2,2.9,June - September
Hanes Valley Trail,The North Shore,Difficult,8.5,16,July - September
Harrison Grind,Fraser Valley East,Difficult,6,7,March - November
Hayward Lake,Fraser Valley East,Easy,5.5,17,year-round
Helm Lake,Whistler,Difficult,9,26,July - October
Hicks Lake,Fraser Valley East,Easy,2,6,year-round
Hidden Grove,Sunshine Coast,Easy,1.5,3.5,year-round
High Falls Creek,Howe Sound,Intermediate,5,12,May - October
High Note Trail,Whistler,Intermediate,4,9.5,July - October
Hollyburn Mountain,The North Shore,Intermediate,3.5,7,July - October
Homesite Caves Trail,Sunshine Coast,Easy,0.75,1.5,year-round
Homesite Creek Falls,Sunshine Coast,Easy,1.5,3,year-round
Hope Lookout Trail,Fraser Valley East,Intermediate,2.5,4.5,March - November
Hunter Road Trail,Fraser Valley East,Intermediate,3,8,March - November
Iceberg Lake,Whistler,Intermediate,7,15,July - September
Iona Beach Regional Park,Vancouver City,Easy,1.5,6,year-round
Joffre Lakes,Pemberton,Intermediate,4,10,June - September
Jug Island Beach,Tri Cities,Intermediate,2.5,5.5,year-round
Kanaka Creek Cliff Falls,Ridge Meadows,Easy,2,4,year-round
Kanaka Creek Riverfront,Ridge Meadows,Easy,1,2.5,year-round
Killarney Lake,Howe Sound,Easy,2,9,year-round
Ledgeview Trail,Fraser Valley East,Intermediate,3,5.5,year-round
Levette Lake Loop,Howe Sound,Intermediate,5,11,May - November
Lighthouse Park,The North Shore,Easy,2,6,year-round
Lightning Lake Loop,Manning Provincial Park,Easy,2.5,8.5,July - September
Lightning Lakes Chain Trail,Manning Provincial Park,Intermediate,7,19,June - October
Lindeman Lake,Fraser Valley East,Intermediate,2,3.4,May - October
Lions Bay Loop,Howe Sound,Easy,2,4.5,year-round
Little Goat Mountain,The North Shore,Easy,2.5,5.5,July - September
Lost Lake Nature Trail,Whistler,Easy,1.5,5,March -October
Lower Hollyburn,The North Shore,Intermediate,4.5,10,June - November
Lynn Loop,The North Shore,Easy,1.5,5.1,year-round
Lynn Peak,The North Shore,Intermediate,4,9,June - October
Maplewood Flats,The North Shore,Easy,0.75,2.5,year-round
Mike Lake,Ridge Meadows,Easy,0.75,2,year-round
Minnekhada Regional Park,Tri Cities,Easy,2.5,10,year-round
Mount Cheam,Fraser Valley East,Intermediate,4.5,9.5,July - October
Mount Crumpit,Howe Sound,Intermediate,3.5,6,April - October
Mount Daniel,Sunshine Coast,Intermediate,2.5,5,year-round
Mount Fromme,The North Shore,Intermediate,5,10,July - October
Mount Gardner,Howe Sound,Intermediate,7,17,year-round
Mount Seymour,The North Shore,Intermediate,5,9,July - October
Mount Strachan,The North Shore,Intermediate,5.5,10.5,July - October
Mount Thom,Fraser Valley East,Intermediate,2.5,10,year-round
Mundy Park,Tri Cities,Easy,2,6,year-round
Murrin Loop Trail,Howe Sound,Intermediate,1.5,2,February - October
Mystery Lake,The North Shore,Easy,1.25,3,July - October
Nairn Falls,Pemberton,Easy,1.5,3,year-round
Norvan Falls,The North Shore,Intermediate,5,14,year-round
One Mile Lake,Pemberton,Easy,0.75,1.6,March - November
Othello Tunnels,Fraser Valley East,Easy,1,3.5,May - October
Pacific Spirit Regional Park,Vancouver City,Easy,3,10,year-round
Panorama Ridge,Whistler,Difficult,11,30,July - October
Paton Peak,The North Shore,Difficult,4,4.5,July - October
Pender Hill,Sunshine Coast,Intermediate,1.25,2,year-round
Petgill Lake,Howe Sound,Intermediate,6,11.5,March - October
Pitt River Regional Greenway,Ridge Meadows,Easy,5,17.2,year-round
Pitt Wildlife Loop,Ridge Meadows,Easy,4,15,year-round
Porpoise Bay,Sunshine Coast,Easy,0.5,1,year-round
Quarry Rock,The North Shore,Easy,1.5,3.8,year-round
Rainbow Lake,Whistler,Intermediate,6,16,July - September
Reifel Bird Sanctuary,Tsawwassen and Delta,Easy,1,5,year-round
Rice Lake,The North Shore,Easy,1,3,year-round
Rohr Lake,Pemberton,Difficult,6,10,July - September
Rolley Lake,Fraser Valley East,Easy,2,5,year-round
Sargeant Bay,Sunshine Coast,Easy,0.25,0.8,year-round
Sasamat Lake,Tri Cities,Easy,3,8,year-round
Sea To Summit Trail,Howe Sound,Intermediate,3.5,7.5,March - November
Sendero Diez Vistas,Tri Cities,Intermediate,7,15,April - November
Serpentine Fen Nature Trail,Surrey and Langley,Easy,1.5,3.5,year-round
Seton Lake Lookout,Pemberton,Easy,0.5,1,May - November
Seven Sisters Trail,Fraser Valley East,Easy,1,3,year-round
Shadow Lake,Pemberton,Easy,2,5,June - October
Shoreline Trail,Tri Cities,Easy,2,6,year-round
Skookumchuck Narrows,Sunshine Coast,Easy,2,8,year-round
Skyline Trail,The North Shore,Intermediate,3,5,April - November
Skywalk North Loop,Whistler,Difficult,9,19.5,July - September
Skywalk South Loop,Whistler,Difficult,7,19,July - September
Slesse Memorial Trail,Fraser Valley East,Intermediate,6,12,July - October
Smoke Bluffs Park,Howe Sound,Easy,1.5,3.5,February - November
Smuggler Cove Marine Provincial Park,Sunshine Coast,Easy,1.5,4,year-round
Soames Hill,Sunshine Coast,Intermediate,1,2,year-round
Spirit Caves Trail,Fraser Valley East,Intermediate,3.5,4.5,April - October
St Mark's Summit,The North Shore,Intermediate,5,11,July - October
Stanley Park,Vancouver City,Easy,2,6.5,year-round
Stave Dam Forest Interpretation Forest,Fraser Valley East,Easy,1,1.6,year-round
Stawamus Chief,Howe Sound,Intermediate,6,11,March - November
Steelhead Falls,Fraser Valley East,Easy,0.75,2,year-round
Sumas Mountain,Fraser Valley East,Intermediate,6.5,13.5,May - November
Swan Falls Viewpoint,Tri Cities,Intermediate,3.5,10,year-round
Teapot Hill,Fraser Valley East,Easy,2,5,year-round
The Lions Binkert Trail,Howe Sound,Difficult,8,16,July - October
Three Brothers Mountain,Manning Provincial Park,Intermediate,7,21.5,July - September
Thunderbird Ridge,The North Shore,Easy,2.5,6,July - September
Triangle Lake,Sunshine Coast,Easy,3,8,year-round
Tunnel Bluffs,Howe Sound,Intermediate,4,11.5,May - November
Twin Falls,The North Shore,Easy,1,1.5,year-round
Two Canyon Loop,The North Shore,Easy,3,8,February - November
Tynehead Regional Park,Surrey and Langley,Easy,1.5,4.5,year-round
UBC Malcolm Knapp Research Forest,Ridge Meadows,Intermediate,3,8,February - November
Vedder Ridge Trail,Fraser Valley East,Intermediate,3.5,9,May - October
Vedder River Rotary Trail,Fraser Valley East,Easy,4,16,year-round
Velodrome Trail,Vancouver City,Intermediate,1,3,year-round
Watersprite Lake,Howe Sound,Intermediate,7,17,July - September
Wedgemount Lake,Whistler,Difficult,7,12,July - September
Whippoorwill Point Trail,Fraser Valley East,Easy,1.5,4,year-round
Whistler Train Wreck,Whistler,Easy,1,2,May - November
Whyte Lake,The North Shore,Easy,2,5,year-round
Whytecliff Park,The North Shore,Easy,1.5,2,year-round
Widgeon Falls,Ridge Meadows,Easy,5,6,year-round
Woodland Walk Trail,Tri Cities,Easy,3,8,year-round
Zoa Peak,Fraser Valley East,Intermediate,4.5,8,June - October
\ No newline at end of file
......@@ -8,6 +8,14 @@
</head>
<body>
<div id="scatterplot-container">
<svg id="scatterplot"></svg>
<ul class="legend" id="scatterplot-legend">
<li><span class="legend-e easy" id="scatterplot-legend-easy"></span> Easy</li>
<li><span class="legend-e intermediate" id="scatterplot-intermediate"></span> Intermediate</li>
<li><span class="legend-e difficult" id="scatterplot-difficult"></span> Difficult</li>
</ul>
</div>
<script type="module" src="/src/ts/main.ts"></script>
</body>
......
......@@ -5,8 +5,87 @@ body {
padding: 0;
box-sizing: border-box;
overflow-x: hidden;
background: #f7f7f7;
}
h1 {
color: red;
}
\ No newline at end of file
/* #region scatterplot*/
#scatterplot-container {
padding: 1em;
}
#scatterplot-container .source {
font-size: 10px;
color: #888;
}
#scatterplot-container .source a {
color: #888;
}
/* Axes */
#scatterplot-container .axis line {
fill: none;
stroke: #ddd;
shape-rendering: crispEdges;
}
#scatterplot-container .axis text {
font-size: 13px;
fill: #6b6b6b;
}
#scatterplot-container .axis-title {
font-size: 13px;
fill: #888;
}
.y-axis .tick:first-child line {
stroke: #b1b1b1;
}
#scatterplot-container .y-axis .tick:first-child text {
display: none;
}
#scatterplot-container .x-axis .tick:first-child line {
display: none;
}
#scatterplot-container .axis path {
display: none;
}
/* Legend */
#scatterplot-container .legend {
margin: 20px 0;
list-style: none;
padding: 0;
}
#scatterplot-container .legend li {
display: inline-block;
margin: 0 20px 0 0;
}
#scatterplot-container .legend-e {
width: 12px;
height: 12px;
margin-right: 3px;
display: inline-block;
}
#scatterplot-container .legend-e.easy {
background: #d3eecd;
}
#scatterplot-container .legend-e.intermediate {
background: #7bc77e;
}
#scatterplot-container .legend-e.difficult {
background: #2a8d46;
}
/* #endregion */
\ No newline at end of file
import '../css/style.css';
import { ChartConfiguration } from './chartConfiguration';
import { Scatterplot } from './scatter';
import '/src/css/style.css';
import * as d3 from 'd3';
d3.select("body")
.append("h1")
.text("Hello world");
/**
* Load data from CSV file asynchronously and render scatter plot
*/
const scatterplot = new Scatterplot(new ChartConfiguration("#scatterplot"));
d3.csv('/data/vancouver_trails.csv')
.then(data => {
// Convert strings to numbers
data.forEach((d: any) => {
d.time = +d.time;
d.distance = +d.distance;
});
// Initialize chart
scatterplot.data = data;
// Show chart
scatterplot.updateVis();
})
.catch(error => console.error(error));
setTimeout(() => {
scatterplot.data = [];
scatterplot.updateVis();
}, 1000);
import * as d3 from 'd3';
import { Chart } from "./chart";
import { ChartConfiguration } from './chartConfiguration';
export class Scatterplot extends Chart {
private colorScale: d3.ScaleOrdinal<string, unknown, never>;
private xScale: d3.ScaleLinear<number, number, never>;
private yScale: d3.ScaleLinear<number, number, never>;
private xAxis: d3.Axis<d3.NumberValue>;
private yAxis: d3.Axis<d3.NumberValue>;
private xAxisG: any;
private yAxisG: any;
private colorValue: (d: any) => any;
private xValue: (d: any) => any;
private yValue: (d: any) => any;
private idValue: (d: any) => any;
constructor(_config: ChartConfiguration, _data?: any[]) {
super(_config, _data);
this.initVis();
}
protected getDefaultMargins(): { top: number; right: number; bottom: number; left: number; } {
return { top: 25, right: 20, bottom: 20, left: 35 };
}
protected getDefaultContainerSize(): { width: number; height: number; } {
return { width: 600, height: 400 };
}
protected initVis(): void {
const vis = this;
vis.colorScale = d3.scaleOrdinal()
.range(['#d3eecd', '#7bc77e', '#2a8d46']) // light green to dark green
.domain(['Easy', 'Intermediate', 'Difficult']);
vis.xScale = d3.scaleLinear()
.range([0, vis.width]);
vis.yScale = d3.scaleLinear()
.range([vis.height, 0]);
// Initialize axes
vis.xAxis = d3.axisBottom(vis.xScale)
.ticks(6)
.tickSize(-vis.height - 10)
.tickPadding(10)
.tickFormat(d => d + ' km');
vis.yAxis = d3.axisLeft(vis.yScale)
.ticks(6)
.tickSize(-vis.width - 10)
.tickPadding(10);
// Append empty x-axis group and move it to the bottom of the chart
vis.xAxisG = vis.chart.append('g')
.attr('class', 'axis x-axis')
.attr('transform', `translate(0,${vis.height})`);
// Append y-axis group
vis.yAxisG = vis.chart.append('g')
.attr('class', 'axis y-axis');
// Append both axis titles
vis.chart.append('text')
.attr('class', 'axis-title')
.attr('y', vis.height - 15)
.attr('x', vis.width + 10)
.attr('dy', '.71em')
.style('text-anchor', 'end')
.text('Distance');
vis.svg.append('text')
.attr('class', 'axis-title')
.attr('x', 0)
.attr('y', 0)
.attr('dy', '.71em')
.text('Hours');
}
public updateVis(): void {
let vis = this;
// Specificy accessor functions
vis.colorValue = d => d.difficulty;
vis.xValue = d => d.time;
vis.yValue = d => d.distance;
// Set the scale input domains
vis.xScale.domain([0, d3.max(vis.data, vis.xValue)]);
vis.yScale.domain([0, d3.max(vis.data, vis.yValue)]);
vis.renderVis();
}
protected renderVis() {
let vis = this;
vis.idValue = (d: any) => d.trail;
// Bind data to circles
const circles = vis.chart.selectAll('.point')
.data(vis.data, (d: any) => vis.idValue(d));
// Enter phase
const circlesEnter = circles.enter()
.append('circle')
.attr('class', 'point')
.attr('r', 4)
.attr('fill', (d: any) => vis.colorScale(vis.colorValue(d)))
.attr('cy', vis.yScale(0)) // Start from y=0
.attr('cx', (d: any) => vis.xScale(vis.xValue(d)));
circlesEnter.transition()
.duration(1000)
.attr('cy', (d: any) => vis.yScale(vis.yValue(d))); // Animate to the final position
// Update phase
circlesEnter.merge(circles)
.transition()
.duration(1000)
.attr('cy', (d: any) => vis.yScale(vis.yValue(d)))
.attr('cx', (d: any) => vis.xScale(vis.xValue(d)))
.attr('fill', (d: any) => vis.colorScale(vis.colorValue(d)));
// Exit phase: remove circles that no longer have data
circles.exit()
.transition()
.duration(1000)
.attr('r', 0)
.remove();
// Update the axes/gridlines
vis.xAxisG
.call(vis.xAxis)
.call((g: any) => g.select('.domain').remove());
vis.yAxisG
.call(vis.yAxis)
.call((g: any) => g.select('.domain').remove());
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment