Skip to content

Commit d3b9af7

Browse files
Merge pull request #8 from KunshuYang/Kunshu_Yang_path1
Add Demo1 folder
2 parents 0072413 + 81ac5c4 commit d3b9af7

6 files changed

+33084
-0
lines changed

Demo1/.vscode/launch.json

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
2+
{
3+
// 使用 IntelliSense 了解相关属性。
4+
// 悬停以查看现有属性的描述。
5+
// 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387
6+
"version": "0.2.0",
7+
"configurations": [
8+
{
9+
"type": "chrome",
10+
"request": "launch",
11+
"name": "Open Flask App",
12+
"url": "http://127.0.0.1:5000/", // 使用 Flask 应用的 URL
13+
"webRoot": "${workspaceFolder}" // 指定工作区根目录
14+
}
15+
]
16+
}

Demo1/app.py

+47
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
import pandas as pd
2+
import json
3+
4+
# Read the CSV file
5+
df = pd.read_csv(r'C:\Users\ykks\Desktop\zuoye\spark\final_dataset.csv')
6+
7+
# Group the data by CoC Name, Year, and Homelessness Type
8+
grouped = df.groupby(['CoC Name', 'Year', 'Homelessness.Type'])['Count'].sum().unstack(level='Homelessness.Type').reset_index()
9+
10+
# Rename columns to match the expected format
11+
grouped = grouped.rename(columns={
12+
'Overall.Homeless': 'Overall_Homeless',
13+
'Sheltered.Total.Homeless': 'Sheltered',
14+
'Unsheltered.Homeless': 'Unsheltered'
15+
})
16+
17+
# Fill NaN values with 0
18+
grouped = grouped.fillna(0)
19+
20+
# Convert data to the required format
21+
data = grouped.to_dict('records')
22+
23+
# Create JavaScript code string
24+
js_data = f"var data = {json.dumps(data)};"
25+
26+
# Read HTML template
27+
with open('templates/index.html', 'r', encoding='utf-8') as file:
28+
html_template = file.read()
29+
30+
# Insert data into HTML template
31+
html_with_data = html_template.replace('// INSERT_DATA_HERE', js_data)
32+
33+
# Write the result to a new HTML file
34+
output_path = r'C:\Users\ykks\Desktop\zuoye\spark\Demo1\homeless_data_visualization.html'
35+
with open(output_path, 'w', encoding='utf-8') as file:
36+
file.write(html_with_data)
37+
38+
print(f"HTML file has been generated: {output_path}")
39+
40+
# Verify the data was inserted into the HTML
41+
print("Data insertion verification:")
42+
print("Data variable definition found:" if "var data = [" in html_with_data else "Data variable definition NOT found")
43+
print("First data item found:" if str(data[0]) in html_with_data else "First data item NOT found")
44+
45+
# Print the first few items of the processed data
46+
print("\nProcessed data sample:")
47+
print(json.dumps(data[:5], indent=2))

Demo1/homeless_data_visualization.html

+220
Large diffs are not rendered by default.

Demo1/templates/index.html

+220
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,220 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8">
5+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
6+
<title>Optimized Homeless Data Visualization</title>
7+
<script src="https://cdnjs.cloudflare.com/ajax/libs/echarts/5.4.2/echarts.min.js"></script>
8+
<style>
9+
body {
10+
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
11+
margin: 0;
12+
padding: 20px;
13+
background-color: #f0f2f5;
14+
color: #333;
15+
}
16+
#main-container {
17+
position: relative;
18+
background-color: white;
19+
border-radius: 12px;
20+
box-shadow: 0 4px 15px rgba(0,0,0,0.1);
21+
padding: 20px;
22+
margin-bottom: 20px;
23+
}
24+
#chart {
25+
height: 600px;
26+
width: 100%;
27+
margin-top: 60px; /* Add space for controls */
28+
}
29+
#controls {
30+
display: flex;
31+
justify-content: flex-start;
32+
align-items: center;
33+
padding: 10px;
34+
background-color: #f8f9fa;
35+
border-bottom: 1px solid #e9ecef;
36+
position: absolute;
37+
top: 0;
38+
left: 0;
39+
right: 0;
40+
z-index: 10;
41+
}
42+
.control-group {
43+
margin-right: 20px;
44+
}
45+
select, button {
46+
padding: 6px 12px;
47+
font-size: 14px;
48+
border: 1px solid #ced4da;
49+
border-radius: 4px;
50+
background-color: white;
51+
color: #495057;
52+
cursor: pointer;
53+
transition: all 0.3s ease;
54+
}
55+
select:hover, button:hover {
56+
border-color: #80bdff;
57+
box-shadow: 0 0 0 0.2rem rgba(0,123,255,.25);
58+
}
59+
h1 {
60+
text-align: center;
61+
color: #1a3a5c;
62+
margin-bottom: 20px;
63+
font-size: 28px;
64+
font-weight: 700;
65+
}
66+
label {
67+
margin-right: 5px;
68+
font-weight: 500;
69+
}
70+
</style>
71+
</head>
72+
<body>
73+
<h1>Homeless Population Data by City</h1>
74+
<div id="main-container">
75+
<div id="controls">
76+
<div class="control-group">
77+
<label for="year">Year:</label>
78+
<select id="year"></select>
79+
</div>
80+
<div class="control-group">
81+
<label for="topN">Top N CoCs:</label>
82+
<select id="topN">
83+
<option value="10">10</option>
84+
<option value="15" selected>15</option>
85+
<option value="20">20</option>
86+
</select>
87+
</div>
88+
<button id="toggleView">Toggle View</button>
89+
</div>
90+
<div id="chart"></div>
91+
</div>
92+
<script>
93+
// INSERT_DATA_HERE
94+
95+
var myChart = echarts.init(document.getElementById('chart'));
96+
var years = [...new Set(data.map(item => item.Year))].sort((a, b) => a - b);
97+
var yearSelector = document.getElementById('year');
98+
var topNSelector = document.getElementById('topN');
99+
var toggleViewButton = document.getElementById('toggleView');
100+
var isHorizontal = false;
101+
102+
years.forEach(year => {
103+
var option = document.createElement('option');
104+
option.value = year;
105+
option.textContent = year;
106+
yearSelector.appendChild(option);
107+
});
108+
yearSelector.value = years[years.length - 1];
109+
110+
function formatNumber(num) {
111+
if (num >= 1000000) {
112+
return (num / 1000000).toFixed(1) + 'M';
113+
} else if (num >= 1000) {
114+
return (num / 1000).toFixed(1) + 'K';
115+
}
116+
return num.toString();
117+
}
118+
119+
function truncateLabel(str, maxLength) {
120+
if (str.length > maxLength) {
121+
return str.substr(0, maxLength - 3) + '...';
122+
}
123+
return str;
124+
}
125+
126+
function updateChart() {
127+
var year = yearSelector.value;
128+
var topN = parseInt(topNSelector.value);
129+
var yearData = data.filter(item => item.Year == year);
130+
yearData.sort((a, b) => b.Overall_Homeless - a.Overall_Homeless);
131+
var topCoCNames = yearData.slice(0, topN).map(item => item['CoC Name']);
132+
133+
var seriesData = ['Overall_Homeless', 'Sheltered', 'Unsheltered'].map(type => ({
134+
name: type.replace('_', ' '),
135+
type: 'bar',
136+
data: topCoCNames.map(name => yearData.find(item => item['CoC Name'] === name)[type] || 0)
137+
}));
138+
139+
var option = {
140+
title: {
141+
text: `Top ${topN} CoCs by Homeless Population Types in ${year}`,
142+
left: 'center',
143+
top: '20px',
144+
textStyle: {
145+
fontSize: 20,
146+
fontWeight: 'bold',
147+
color: '#1a3a5c'
148+
}
149+
},
150+
tooltip: {
151+
trigger: 'axis',
152+
axisPointer: { type: 'shadow' }
153+
},
154+
legend: {
155+
data: ['Overall Homeless', 'Sheltered', 'Unsheltered'],
156+
top: '50px',
157+
textStyle: { fontSize: 12 }
158+
},
159+
grid: {
160+
left: '3%',
161+
right: '4%',
162+
bottom: isHorizontal ? '3%' : '15%',
163+
top: '100px',
164+
containLabel: true
165+
},
166+
xAxis: {
167+
type: isHorizontal ? 'value' : 'category',
168+
data: isHorizontal ? null : topCoCNames,
169+
axisLabel: {
170+
interval: 0,
171+
rotate: isHorizontal ? 0 : 45,
172+
fontSize: 12,
173+
fontWeight: 'bold',
174+
color: '#555',
175+
formatter: function(value) {
176+
return isHorizontal ? formatNumber(value) : truncateLabel(value, 20);
177+
}
178+
},
179+
axisLine: {
180+
lineStyle: {
181+
color: '#999'
182+
}
183+
}
184+
},
185+
yAxis: {
186+
type: isHorizontal ? 'category' : 'value',
187+
data: isHorizontal ? topCoCNames : null,
188+
axisLabel: {
189+
fontSize: 12,
190+
formatter: function(value) {
191+
return isHorizontal ? truncateLabel(value, 20) : formatNumber(value);
192+
}
193+
},
194+
axisLine: {
195+
lineStyle: {
196+
color: '#999'
197+
}
198+
}
199+
},
200+
series: seriesData
201+
};
202+
203+
myChart.setOption(option);
204+
}
205+
206+
yearSelector.addEventListener('change', updateChart);
207+
topNSelector.addEventListener('change', updateChart);
208+
toggleViewButton.addEventListener('click', function() {
209+
isHorizontal = !isHorizontal;
210+
updateChart();
211+
});
212+
213+
updateChart();
214+
215+
window.addEventListener('resize', function() {
216+
myChart.resize();
217+
});
218+
</script>
219+
</body>
220+
</html>

0 commit comments

Comments
 (0)