Skip to content

Commit

Permalink
Merge branch 'sit' into feature/soul_dashboard_tpe_env_saving
Browse files Browse the repository at this point in the history
Signed-off-by: power80203 <[email protected]>
  • Loading branch information
power80203 authored Dec 10, 2024
2 parents c5e76f2 + 487b1a5 commit 63e7924
Show file tree
Hide file tree
Showing 30 changed files with 417 additions and 215 deletions.
2 changes: 2 additions & 0 deletions Taipei-City-Dashboard-BE/cloudbuild.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -52,3 +52,5 @@ steps:
- "--region"
- us-central1
- "--allow-unauthenticated"
options:
logging: "CLOUD_LOGGING_ONLY"
16 changes: 13 additions & 3 deletions Taipei-City-Dashboard-DE/cicd/add-dags-to-composer.cloudbuild.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,17 @@

# [START composer_cicd_dagsync_yaml]
steps:
# install dependencies
# # install dependencies
# - name: python
# entrypoint: pip
# dir: "Taipei-City-Dashboard-DE/cicd"
# args: ["install", "--upgrade", "pip"]

# - name: python
# entrypoint: pip
# dir: "Taipei-City-Dashboard-DE/cicd"
# args: ["install", "--upgrade", "setuptools", "wheel"]

- name: python
entrypoint: pip
dir: "Taipei-City-Dashboard-DE/cicd"
Expand All @@ -30,6 +40,6 @@ steps:
"--dags_directory=${_DAGS_DIRECTORY}",
"--dags_bucket=${_DAGS_BUCKET}",
]
options:
logging: CLOUD_LOGGING_ONLY
# [END composer_cicd_dagsync_yaml]
options:
logging: CLOUD_LOGGING_ONLY
17 changes: 16 additions & 1 deletion Taipei-City-Dashboard-DE/cicd/utils/requirements.txt
Original file line number Diff line number Diff line change
@@ -1 +1,16 @@
google-cloud-storage==2.9.0
google-cloud-storage==2.9.0
# apache-airflow-providers-mongo==4.0.0
# apache-airflow-providers-microsoft-mssql==3.6.1
# pymongo==4.6.3
# pymssql==2.3.0
# geopandas==0.13.2
# GeoAlchemy2==0.14.7
# openpyxl==3.1.2
# wget==3.2
# Rtree==1.2.0
# psycopg2==2.9.9
# geopy==2.4.1
# XlsxWriter==3.2.0
# pyminizip==0.2.6
# minio==7.2.5
# odfpy==1.4.1
26 changes: 13 additions & 13 deletions Taipei-City-Dashboard-FE/src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ Testing: Jack Huang (Data Scientist), Ian Huang (Data Analysis Intern)

<script setup>
import { onBeforeMount, onMounted, onBeforeUnmount, ref, computed } from "vue";
import { useAuthStore } from "./store/authStore";
import { usePersonStore } from "./store/personStore";
import { useDialogStore } from "./store/dialogStore";
import { useContentStore } from "./store/contentStore";

Expand All @@ -23,7 +23,7 @@ import InitialWarning from "./components/dialogs/InitialWarning.vue";
import ComponentSideBar from "./components/utilities/bars/ComponentSideBar.vue";
import LogIn from "./components/dialogs/LogIn.vue";

const authStore = useAuthStore();
const personStore = usePersonStore();
const dialogStore = useDialogStore();
const contentStore = useContentStore();
const timeToUpdate = ref(600);
Expand All @@ -35,12 +35,12 @@ const formattedTimeToUpdate = computed(() => {
});

function reloadChartData() {
if (!["dashboard", "mapview"].includes(authStore.currentPath)) return;
if (!["dashboard", "mapview"].includes(personStore.currentPath)) return;
contentStore.setCurrentDashboardChartData();
timeToUpdate.value = 600;
}
function updateTimeToUpdate() {
if (!["dashboard", "mapview"].includes(authStore.currentPath)) return;
if (!["dashboard", "mapview"].includes(personStore.currentPath)) return;
if (timeToUpdate.value <= 0) {
timeToUpdate.value = 0;
return;
Expand All @@ -49,7 +49,7 @@ function updateTimeToUpdate() {
}

onBeforeMount(() => {
authStore.initialChecks();
personStore.initialChecks();

let vh = window.innerHeight * 0.01;
document.documentElement.style.setProperty("--vh", `${vh}px`);
Expand Down Expand Up @@ -80,12 +80,12 @@ onBeforeUnmount(() => {
<template>
<div class="app-container">
<NotificationBar />
<NavBar v-if="authStore.currentPath !== 'embed'" />
<NavBar v-if="personStore.currentPath !== 'embed'" />
<!-- /mapview, /dashboard layouts -->
<div
v-if="
authStore.currentPath === 'mapview' ||
authStore.currentPath === 'dashboard'
personStore.currentPath === 'mapview' ||
personStore.currentPath === 'dashboard'
"
class="app-content"
>
Expand All @@ -97,7 +97,7 @@ onBeforeUnmount(() => {
</div>
<!-- /admin layouts -->
<div
v-else-if="authStore.currentPath === 'admin'"
v-else-if="personStore.currentPath === 'admin'"
class="app-content"
>
<AdminSideBar />
Expand All @@ -107,7 +107,7 @@ onBeforeUnmount(() => {
</div>
<!-- /component, /component/:index layouts -->
<div
v-else-if="authStore.currentPath.includes('component')"
v-else-if="personStore.currentPath.includes('component')"
class="app-content"
>
<ComponentSideBar />
Expand All @@ -122,9 +122,9 @@ onBeforeUnmount(() => {
<LogIn />
<div
v-if="
['dashboard', 'mapview'].includes(authStore.currentPath) &&
!authStore.isMobile &&
!authStore.isNarrowDevice
['dashboard', 'mapview'].includes(personStore.currentPath) &&
!personStore.isMobile &&
!personStore.isNarrowDevice
"
class="app-update"
>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@

export class DataManager {
constructor(data) {
this.obj = data || {};
this.mapping = [
{ name: "token", key: "data" },
{ name: "isso_token", key: "taipei_code" },
{ name: "user", key: "person" },
{ name: "user_id", key: "identity" },
];
}

getData(key = "data") {
const mapItem = this.mapping.find(item => item.key === key);
if (!mapItem) {
return null;
}

return this.obj[mapItem.name] || null;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,29 @@
// An array that contains m values, representing the predicted value on each of the target coordinates.

export function interpolation(dataPoints, targetPoints) {
const pointCount = dataPoints.length;
let answers = [];
for (let k = 0; k < targetPoints.length; k++) {

// Early return for invalid inputs
if (!Array.isArray(dataPoints) || !Array.isArray(targetPoints)) {
return answers;
}

// Set maximum limits for data points to prevent excessive processing
const MAX_DATA_POINTS = 10000;
const MAX_TARGET_POINTS = 10000;

const pointCount = Math.min(dataPoints.length, MAX_DATA_POINTS);
const targetCount = Math.min(targetPoints.length, MAX_TARGET_POINTS);

for (let k = 0; k < targetCount; k++) {
if(k >= targetPoints.length) break;
if (dataPoints.includes(targetPoints[k])) {
answers.push(dataPoints[dataPoints.indexOf(targetPoints[k])].value);
} else {
let weight_sum = 0;
let weight_value = 0;
for (let i = 0; i < pointCount; i++) {
if(i >= dataPoints.length) break;
let weight =
1 /
((dataPoints[i].x - targetPoints[k].x) ** 2 +
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,20 @@
// ]

export function marchingSquare(discreteData, isoValue) {
let columnN = discreteData[0].length;
let rowN = discreteData.length;
// Input validation and size limits
if (!Array.isArray(discreteData) || !discreteData.length || !Array.isArray(discreteData[0])) {
console.error("Invalid discrete data format");
return [];
}

const MAX_GRID_SIZE = 10000;
let columnN = Math.min(discreteData[0].length, MAX_GRID_SIZE);
let rowN = Math.min(discreteData.length, MAX_GRID_SIZE);
let result = [];

const maxRow = rowN - 1;
const maxCol = columnN - 1;

// discreteData:
//
// ┌> latitude increases
Expand All @@ -32,8 +42,12 @@ export function marchingSquare(discreteData, isoValue) {
// │ [0][0]-> [0][1]-> [0][2]->
// └────────┴────────┴────────┴─ -> longitude increases

for (let row = 0; row < rowN - 1; row++) {
for (let col = 0; col < columnN - 1; col++) {
for (let row = 0; row < maxRow; row++) {
if (row >= discreteData.length) break;

for (let col = 0; col < maxCol; col++) {
if (col >= discreteData[0].length) break;

// Drawing isoline for the following square surrounded by four discreteData values:
//
// [row+1][col] ┌────┐ [row+1][col+1]
Expand Down
17 changes: 15 additions & 2 deletions Taipei-City-Dashboard-FE/src/assets/utilityFunctions/voronoi.js
Original file line number Diff line number Diff line change
Expand Up @@ -336,7 +336,13 @@ function findVoronoiCell(point) {
// \ / \ /
// \ / 4 \ /
// ---------


// Input validation
if (!point || !point.lastEdgeConnected || !point.lastEdgeConnected.edges) {
console.error("Invalid input point");
return null;
}

let currentEdge = point.lastEdgeConnected;
if (
currentEdge === null ||
Expand All @@ -355,8 +361,11 @@ function findVoronoiCell(point) {

// Go through (1) each edge connected to the point and (2) each triangle surrounding the point.
while (currentTriangle.center !== firstPoint) {
const edgeCount = 3;
let i = 0;
for (i = 0; i < 3; i++) {
for (i = 0; i < edgeCount; i++) {
if (i >= edgeCount) break;

if (
currentEdge !== currentTriangle.edges[i] &&
(currentTriangle.edges[i].p1 === point ||
Expand Down Expand Up @@ -403,6 +412,10 @@ function findVoronoiCell(point) {
// [[x1, y1], [x2, y2]...]...]

export function voronoi(data) {
if (!Array.isArray(data) || data.length === 0 || !data.every(coord => Array.isArray(coord) && coord.length === 2)) {
console.error("Invalid input data for voronoi function");
return [];
}
let points = data.map((coord) => new Point(coord[0], coord[1]));

BowyerWatson(points);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@
import { ref, computed } from "vue";
import { useMapStore } from "../../store/mapStore";
import { useDialogStore } from "../../store/dialogStore";
import { useAuthStore } from "../../store/authStore";
import { usePersonStore } from "../../store/personStore";

import DialogContainer from "./DialogContainer.vue";
import CustomCheckBox from "../utilities/forms/CustomCheckBox.vue";

const mapStore = useMapStore();
const dialogStore = useDialogStore();
const authStore = useAuthStore();
const personStore = usePersonStore();

const selectedLocation = ref("0");

Expand Down Expand Up @@ -60,7 +60,7 @@ function handleFind() {
<h2>尋找最近點</h2>
<div class="findclosestpoint-input">
<label>
請選擇搜尋基準點{{ authStore.token && " (用戶定位與地標)" }}
請選擇搜尋基準點{{ personStore.code && " (用戶定位與地標)" }}
</label>
<div
v-if="availableLocations.length > 0"
Expand All @@ -85,7 +85,7 @@ function handleFind() {
<div v-else>
<p>
查無基準點。請點擊地圖右上角按紐,開啟定位功能{{
authStore.token && "或加入地標"
personStore.code && "或加入地標"
}}。
</p>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@
<script setup>
import { ref } from "vue";
import { useDialogStore } from "../../store/dialogStore";
import { useAuthStore } from "../../store/authStore";
import { usePersonStore } from "../../store/personStore";

import DialogContainer from "./DialogContainer.vue";
import CustomCheckBox from "../utilities/forms/CustomCheckBox.vue";

const dialogStore = useDialogStore();
const authStore = useAuthStore();
const personStore = usePersonStore();

// Stores whether the user doesn't want to see this dialog again
const dontShowAgain = ref(false);
Expand All @@ -32,14 +32,14 @@ function handleClose() {
@on-close="handleClose"
>
<div class="initialwarning">
<h2 v-if="authStore.isMobileDevice">
<h2 v-if="personStore.isMbDevice">
臺北城市儀表板行動版注意事項
</h2>
<h2 v-else>
臺北城市儀表板使用說明
</h2>
<div
v-if="authStore.isMobileDevice"
v-if="personStore.isMbDevice"
class="initialwarning-message"
>
<p>
Expand Down
6 changes: 3 additions & 3 deletions Taipei-City-Dashboard-FE/src/components/dialogs/LogIn.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<script setup>
import { computed, ref } from "vue";
import { useDialogStore } from "../../store/dialogStore";
import { useAuthStore } from "../../store/authStore";
import { usePersonStore } from "../../store/personStore";

import DialogContainer from "./DialogContainer.vue";

Expand All @@ -16,7 +16,7 @@ const {
} = import.meta.env;

const dialogStore = useDialogStore();
const authStore = useAuthStore();
const personStore = usePersonStore();

const loginMode = ref("tp");
const email = ref("");
Expand All @@ -39,7 +39,7 @@ function handleTaipeiPassLogin() {
window.open(taipeiPassUrl.value, "_self");
}
async function handleEmailLogin() {
const loggedIn = await authStore.loginByEmail(email.value, password.value);
const loggedIn = await personStore.loginByEmail(email.value, password.value);
if (loggedIn) {
handleClose();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@
<script setup>
import { useDialogStore } from "../../store/dialogStore";
import { useContentStore } from "../../store/contentStore";
import { useAuthStore } from "../../store/authStore";
import { usePersonStore } from "../../store/personStore";

import SideBarTab from "../utilities/miscellaneous/SideBarTab.vue";

const dialogStore = useDialogStore();
const contentStore = useContentStore();
const authStore = useAuthStore();
const personStore = usePersonStore();
</script>

<template>
Expand All @@ -25,7 +25,7 @@ const authStore = useAuthStore();
/>
<div class="dialogcontainer-dialog">
<div class="mobilenavigation">
<div v-if="authStore.token">
<div v-if="personStore.code">
<h2>我的最愛</h2>
<SideBarTab
icon="favorite"
Expand Down
Loading

0 comments on commit 63e7924

Please sign in to comment.