Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Sign in
Toggle navigation
D
DV-HW4
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
almohanad.hafez
DV-HW4
Commits
b9cb1e08
You need to sign in or sign up before continuing.
Commit
b9cb1e08
authored
Jan 10, 2025
by
Almouhannad Hafez
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add scatter plot
parent
0a8a1501
Changes
5
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
443 additions
and
7 deletions
+443
-7
vancouver_trails.csv
data/vancouver_trails.csv
+189
-0
index.html
index.html
+8
-0
style.css
src/css/style.css
+82
-3
main.ts
src/ts/main.ts
+24
-4
scatter.ts
src/ts/scatter.ts
+140
-0
No files found.
data/vancouver_trails.csv
0 → 100644
View file @
b9cb1e08
This diff is collapsed.
Click to expand it.
index.html
View file @
b9cb1e08
...
@@ -8,6 +8,14 @@
...
@@ -8,6 +8,14 @@
</head>
</head>
<body>
<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>
<script
type=
"module"
src=
"/src/ts/main.ts"
></script>
</body>
</body>
...
...
src/css/style.css
View file @
b9cb1e08
...
@@ -5,8 +5,87 @@ body {
...
@@ -5,8 +5,87 @@ body {
padding
:
0
;
padding
:
0
;
box-sizing
:
border-box
;
box-sizing
:
border-box
;
overflow-x
:
hidden
;
overflow-x
:
hidden
;
background
:
#f7f7f7
;
}
}
h1
{
color
:
red
;
/* #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
src/ts/main.ts
View file @
b9cb1e08
import
'../css/style.css'
;
import
{
ChartConfiguration
}
from
'./chartConfiguration'
;
import
{
Scatterplot
}
from
'./scatter'
;
import
'/src/css/style.css'
;
import
*
as
d3
from
'd3'
;
import
*
as
d3
from
'd3'
;
d3
.
select
(
"body"
)
/**
.
append
(
"h1"
)
* Load data from CSV file asynchronously and render scatter plot
.
text
(
"Hello world"
);
*/
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
);
src/ts/scatter.ts
0 → 100644
View file @
b9cb1e08
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
());
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment