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
3a6cef04
Commit
3a6cef04
authored
Jan 11, 2025
by
Almouhannad Hafez
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Use Chart factory
parent
88f5d2aa
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
153 additions
and
72 deletions
+153
-72
index.html
index.html
+11
-2
style.css
src/css/style.css
+58
-21
ChartFactory.ts
src/ts/ChartFactory.ts
+25
-0
chartsNames.ts
src/ts/chartsNames.ts
+6
-0
lineChart.ts
src/ts/lineChart.ts
+7
-0
main.ts
src/ts/main.ts
+42
-49
scatter.ts
src/ts/scatter.ts
+4
-0
No files found.
index.html
View file @
3a6cef04
...
@@ -9,7 +9,16 @@
...
@@ -9,7 +9,16 @@
<body>
<body>
<div
id=
"scatterplot-container"
>
<div
id=
"chart-select"
>
<label
for=
"chart"
>
Select chart:
</label>
<select
id=
"charts-select-list"
name=
"charts-select-list"
>
<option
value=
""
disabled
selected
></option>
<option
value=
"Scatterplot"
>
Scatterplot
</option>
<option
value=
"LineChart"
>
Line chart
</option>
</select>
</div>
<div
id=
"Scatterplot-container"
style=
"display: none;"
>
<div
id=
"scatterplot-tooltip"
></div>
<div
id=
"scatterplot-tooltip"
></div>
<svg
id=
"scatterplot"
></svg>
<svg
id=
"scatterplot"
></svg>
<ul
class=
"legend"
id=
"scatterplot-legend"
>
<ul
class=
"legend"
id=
"scatterplot-legend"
>
...
@@ -20,7 +29,7 @@
...
@@ -20,7 +29,7 @@
</ul>
</ul>
</div>
</div>
<div
id=
"
line-chart-container
"
>
<div
id=
"
LineChart-container"
style=
"display: none;
"
>
<div
id=
"line-chart-tooltip"
></div>
<div
id=
"line-chart-tooltip"
></div>
<div
class=
"heading"
>
<div
class=
"heading"
>
<p
class=
"title"
>
S
&
P 500 Index
</p>
<p
class=
"title"
>
S
&
P 500 Index
</p>
...
...
src/css/style.css
View file @
3a6cef04
...
@@ -8,35 +8,72 @@ body {
...
@@ -8,35 +8,72 @@ body {
background
:
#f7f7f7
;
background
:
#f7f7f7
;
}
}
#chart-select
{
margin-left
:
2em
;
background-color
:
#fff
;
border-radius
:
8px
;
box-shadow
:
0
4px
10px
rgba
(
0
,
0
,
0
,
0.1
);
padding
:
20px
;
width
:
300px
;
text-align
:
center
;
}
label
{
font-size
:
1.2em
;
margin-bottom
:
10px
;
display
:
block
;
color
:
#333
;
}
select
{
width
:
100%
;
padding
:
10px
;
border
:
1px
solid
#ccc
;
border-radius
:
5px
;
font-size
:
1em
;
color
:
#555
;
background-color
:
#f9f9f9
;
transition
:
border-color
0.3s
;
}
select
:focus
{
border-color
:
#007BFF
;
outline
:
none
;
background-color
:
#fff
;
}
option
{
padding
:
10px
;
}
/* #region scatterplot*/
/* #region scatterplot*/
#
s
catterplot-container
{
#
S
catterplot-container
{
padding
:
1em
;
padding
:
1em
;
}
}
#
s
catterplot-container
.source
{
#
S
catterplot-container
.source
{
font-size
:
10px
;
font-size
:
10px
;
color
:
#888
;
color
:
#888
;
}
}
#
s
catterplot-container
.source
a
{
#
S
catterplot-container
.source
a
{
color
:
#888
;
color
:
#888
;
}
}
/* Axes */
/* Axes */
#
s
catterplot-container
.axis
line
{
#
S
catterplot-container
.axis
line
{
fill
:
none
;
fill
:
none
;
stroke
:
#ddd
;
stroke
:
#ddd
;
shape-rendering
:
crispEdges
;
shape-rendering
:
crispEdges
;
}
}
#
s
catterplot-container
.axis
text
{
#
S
catterplot-container
.axis
text
{
font-size
:
13px
;
font-size
:
13px
;
fill
:
#6b6b6b
;
fill
:
#6b6b6b
;
}
}
#
s
catterplot-container
.axis-title
{
#
S
catterplot-container
.axis-title
{
font-size
:
13px
;
font-size
:
13px
;
fill
:
#888
;
fill
:
#888
;
}
}
...
@@ -45,50 +82,50 @@ body {
...
@@ -45,50 +82,50 @@ body {
stroke
:
#b1b1b1
;
stroke
:
#b1b1b1
;
}
}
#
s
catterplot-container
.y-axis
.tick
:first-child
text
{
#
S
catterplot-container
.y-axis
.tick
:first-child
text
{
display
:
none
;
display
:
none
;
}
}
#
s
catterplot-container
.x-axis
.tick
:first-child
line
{
#
S
catterplot-container
.x-axis
.tick
:first-child
line
{
display
:
none
;
display
:
none
;
}
}
#
s
catterplot-container
.axis
path
{
#
S
catterplot-container
.axis
path
{
display
:
none
;
display
:
none
;
}
}
/* Legend */
/* Legend */
#
s
catterplot-container
.legend
{
#
S
catterplot-container
.legend
{
margin
:
20px
0
;
margin
:
20px
0
;
list-style
:
none
;
list-style
:
none
;
padding
:
0
;
padding
:
0
;
}
}
#
s
catterplot-container
.legend
li
{
#
S
catterplot-container
.legend
li
{
display
:
inline-block
;
display
:
inline-block
;
margin
:
0
20px
0
0
;
margin
:
0
20px
0
0
;
}
}
#
s
catterplot-container
.legend-e
{
#
S
catterplot-container
.legend-e
{
width
:
12px
;
width
:
12px
;
height
:
12px
;
height
:
12px
;
margin-right
:
3px
;
margin-right
:
3px
;
display
:
inline-block
;
display
:
inline-block
;
}
}
#
s
catterplot-container
.legend-e.easy
{
#
S
catterplot-container
.legend-e.easy
{
background
:
#d3eecd
;
background
:
#d3eecd
;
}
}
#
s
catterplot-container
.legend-e.intermediate
{
#
S
catterplot-container
.legend-e.intermediate
{
background
:
#7bc77e
;
background
:
#7bc77e
;
}
}
#
s
catterplot-container
.legend-e.difficult
{
#
S
catterplot-container
.legend-e.difficult
{
background
:
#2a8d46
;
background
:
#2a8d46
;
}
}
#
s
catterplot-container
p
{
#
S
catterplot-container
p
{
font-weight
:
900
;
font-weight
:
900
;
color
:
#2a8d46
;
color
:
#2a8d46
;
}
}
...
@@ -117,28 +154,28 @@ body {
...
@@ -117,28 +154,28 @@ body {
/* #region Area chart */
/* #region Area chart */
#
line-c
hart-container
.area
{
#
LineC
hart-container
.area
{
fill
:
#e9eff5
;
fill
:
#e9eff5
;
position
:
relative
;
position
:
relative
;
}
}
#
line-c
hart-container
.line
{
#
LineC
hart-container
.line
{
fill
:
none
;
fill
:
none
;
stroke
:
#537591
;
stroke
:
#537591
;
stroke-width
:
2.5px
;
stroke-width
:
2.5px
;
}
}
#
line-c
hart-container
.title
{
#
LineC
hart-container
.title
{
font-weight
:
900
;
font-weight
:
900
;
font-size
:
40px
;
font-size
:
40px
;
}
}
#
line-c
hart-container
.select-text
{
#
LineC
hart-container
.select-text
{
font-weight
:
900
;
font-weight
:
900
;
margin-right
:
0.5em
;
margin-right
:
0.5em
;
}
}
#
line-c
hart-container
.heading
{
#
LineC
hart-container
.heading
{
margin-left
:
3em
;
margin-left
:
3em
;
}
}
...
...
src/ts/ChartFactory.ts
0 → 100644
View file @
3a6cef04
import
{
Chart
}
from
"./chart"
;
import
{
ChartConfiguration
}
from
"./chartConfiguration"
;
import
{
ChartNames
}
from
"./ChartsNames"
;
import
{
LineChart
}
from
"./lineChart"
;
import
{
Scatterplot
}
from
"./scatter"
;
export
class
ChartFactory
{
private
static
chartMap
:
Map
<
string
,
{
instance
:
Chart
;
datasetName
:
string
}
>
=
new
Map
();
private
static
scatterPlot
:
Chart
=
new
Scatterplot
(
new
ChartConfiguration
(
"#scatterplot"
));
private
static
lineChart
:
Chart
=
new
LineChart
(
new
ChartConfiguration
(
"#line-chart"
));
static
{
this
.
chartMap
.
set
(
ChartNames
.
SCATTER
,
{
instance
:
this
.
scatterPlot
,
datasetName
:
"/data/vancouver_trails.csv"
});
this
.
chartMap
.
set
(
ChartNames
.
LINE_CHART
,
{
instance
:
this
.
lineChart
,
datasetName
:
"/data/sp_500_index.csv"
});
}
static
createChart
(
chartName
:
string
):
{
instance
:
Chart
;
datasetName
:
string
}
{
const
chartInstance
=
this
.
chartMap
.
get
(
chartName
);
if
(
chartInstance
)
{
return
chartInstance
;
}
else
throw
new
Error
(
"No such chart"
);
}
}
src/ts/chartsNames.ts
0 → 100644
View file @
3a6cef04
export
class
ChartNames
{
static
readonly
SCATTER
=
'Scatterplot'
;
static
readonly
LINE_CHART
=
'LineChart'
;
static
readonly
CHARTS
=
[
this
.
SCATTER
,
this
.
LINE_CHART
];
}
\ No newline at end of file
src/ts/lineChart.ts
View file @
3a6cef04
...
@@ -156,6 +156,13 @@ export class LineChart extends Chart {
...
@@ -156,6 +156,13 @@ export class LineChart extends Chart {
public
updateVis
():
void
{
public
updateVis
():
void
{
const
vis
=
this
;
const
vis
=
this
;
const
dateParser
=
d3
.
timeParse
(
"%Y-%m-%d"
);
vis
.
data
.
forEach
((
d
:
any
)
=>
{
if
(
typeof
(
d
.
date
)
==
"string"
)
d
.
date
=
dateParser
(
d
.
date
);
d
.
close
=
+
d
.
close
;
});
// Specificy accessor functions
// Specificy accessor functions
vis
.
xValue
=
(
d
:
any
)
=>
d
.
date
;
vis
.
xValue
=
(
d
:
any
)
=>
d
.
date
;
vis
.
yValue
=
(
d
:
any
)
=>
d
.
close
;
vis
.
yValue
=
(
d
:
any
)
=>
d
.
close
;
...
...
src/ts/main.ts
View file @
3a6cef04
import
{
Chart
}
from
'./chart'
;
import
{
ChartConfiguration
}
from
'./chartConfiguration'
;
import
{
ChartFactory
}
from
'./ChartFactory'
;
import
{
LineChart
}
from
'./lineChart'
;
import
{
ChartNames
}
from
'./ChartsNames'
;
import
{
Scatterplot
}
from
'./scatter'
;
import
'/src/css/style.css'
;
import
'/src/css/style.css'
;
import
*
as
d3
from
'd3'
;
import
*
as
d3
from
'd3'
;
const
selectedDifficulties
:
string
[]
=
[];
let
data
:
any
[]
=
[];
let
data
:
any
[]
=
[];
const
scatterplot
=
new
Scatterplot
(
new
ChartConfiguration
(
"#scatterplot"
));
let
chart
:
Chart
;
d3
.
select
(
"#charts-select-list"
)
.
on
(
"change"
,
function
()
{
let
selectedChart
:
string
=
d3
.
select
(
this
).
property
(
'value'
);
let
chartInstance
=
ChartFactory
.
createChart
(
selectedChart
);
chart
=
chartInstance
.
instance
;
for
(
const
chartName
of
ChartNames
.
CHARTS
)
{
d3
.
select
(
`#
${
chartName
}
-container`
).
style
(
"display"
,
"none"
);
}
d3
.
select
(
`#
${
selectedChart
}
-container`
).
style
(
"display"
,
"block"
);
/**
* Load data from CSV file
*/
d3
.
csv
(
chartInstance
.
datasetName
)
.
then
(
inputData
=>
{
data
=
inputData
;
// Initialize chart
chart
.
data
=
inputData
;
// Show chart
chart
.
updateVis
();
})
.
catch
(
error
=>
console
.
error
(
error
));
});
////////////////////// Events handlers //////////////////////
// #region Scatterplot
const
selectedDifficulties
:
string
[]
=
[];
function
handleLevelSelectionEvent
(
element
:
any
,
difficulty
:
string
)
{
function
handleLevelSelectionEvent
(
element
:
any
,
difficulty
:
string
)
{
const
index
=
selectedDifficulties
.
indexOf
(
difficulty
);
const
index
=
selectedDifficulties
.
indexOf
(
difficulty
);
if
(
index
>
-
1
)
{
if
(
index
>
-
1
)
{
...
@@ -20,8 +48,8 @@ function handleLevelSelectionEvent(element: any, difficulty: string) {
...
@@ -20,8 +48,8 @@ function handleLevelSelectionEvent(element: any, difficulty: string) {
d3
.
select
(
element
).
style
(
"opacity"
,
0.5
);
d3
.
select
(
element
).
style
(
"opacity"
,
0.5
);
}
}
const
filteredData
=
data
.
filter
(
item
=>
!
selectedDifficulties
.
includes
(
item
.
difficulty
));
const
filteredData
=
data
.
filter
(
item
=>
!
selectedDifficulties
.
includes
(
item
.
difficulty
));
scatterplo
t
.
data
=
filteredData
;
char
t
.
data
=
filteredData
;
scatterplo
t
.
updateVis
();
char
t
.
updateVis
();
}
}
const
difficulties
=
[
"Easy"
,
"Intermediate"
,
"Difficult"
]
const
difficulties
=
[
"Easy"
,
"Intermediate"
,
"Difficult"
]
// Add click event listeners for each difficulty level
// Add click event listeners for each difficulty level
...
@@ -32,52 +60,17 @@ for (const level of difficulties) {
...
@@ -32,52 +60,17 @@ for (const level of difficulties) {
handleLevelSelectionEvent
(
this
,
level
);
handleLevelSelectionEvent
(
this
,
level
);
});
});
}
}
/**
// #endregion
* Load data from CSV file asynchronously and render scatter plot
*/
d3
.
csv
(
'/data/vancouver_trails.csv'
)
.
then
(
inputData
=>
{
// Convert strings to numbers
inputData
.
forEach
((
d
:
any
)
=>
{
d
.
time
=
+
d
.
time
;
d
.
distance
=
+
d
.
distance
;
});
data
=
inputData
;
// Initialize chart
scatterplot
.
data
=
inputData
;
// Show chart
scatterplot
.
updateVis
();
})
.
catch
(
error
=>
console
.
error
(
error
));
/**
* Load data from CSV file asynchronously and render scatter plot
*/
const
lineChart
=
new
LineChart
(
new
ChartConfiguration
(
"#line-chart"
));
// #region LineChart
let
lineChartData
:
any
[];
d3
.
select
(
'#line-chart-year-input'
)
d3
.
select
(
'#line-chart-year-input'
)
.
on
(
'input'
,
function
()
{
.
on
(
'input'
,
function
()
{
// Get the current value of the input
// Get the current value of the input
let
value
=
d3
.
select
(
this
).
property
(
'value'
);
let
value
=
d3
.
select
(
this
).
property
(
'value'
);
value
=
+
value
;
value
=
+
value
;
console
.
log
(
lineChartData
[
0
].
date
);
const
lineChartFilteredData
=
data
.
filter
(
item
=>
item
.
date
.
getFullYear
()
>=
value
);
const
lineChartFilteredData
=
lineChartData
.
filter
(
item
=>
item
.
date
.
getFullYear
()
>=
value
);
chart
.
data
=
lineChartFilteredData
;
lineChart
.
data
=
lineChartFilteredData
;
chart
.
updateVis
();
lineChart
.
updateVis
();
});
});
// #endregion
d3
.
csv
(
'/data/sp_500_index.csv'
)
.
then
(
inputData
=>
{
const
dateParser
=
d3
.
timeParse
(
"%Y-%m-%d"
);
inputData
.
forEach
((
d
:
any
)
=>
{
d
.
date
=
dateParser
(
d
.
date
);
d
.
close
=
+
d
.
close
;
});
lineChartData
=
inputData
;
lineChart
.
data
=
inputData
;
lineChart
.
updateVis
();
})
.
catch
(
error
=>
console
.
error
(
error
));
src/ts/scatter.ts
View file @
3a6cef04
...
@@ -83,6 +83,10 @@ export class Scatterplot extends Chart {
...
@@ -83,6 +83,10 @@ export class Scatterplot extends Chart {
public
updateVis
():
void
{
public
updateVis
():
void
{
let
vis
=
this
;
let
vis
=
this
;
vis
.
data
.
forEach
((
d
:
any
)
=>
{
d
.
time
=
+
d
.
time
;
d
.
distance
=
+
d
.
distance
;
});
// Specificy accessor functions
// Specificy accessor functions
vis
.
colorValue
=
d
=>
d
.
difficulty
;
vis
.
colorValue
=
d
=>
d
.
difficulty
;
vis
.
xValue
=
d
=>
d
.
time
;
vis
.
xValue
=
d
=>
d
.
time
;
...
...
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