diff --git a/.history/package_20240725151341.json b/.history/package_20240725151341.json
new file mode 100644
index 0000000..ee4e31c
--- /dev/null
+++ b/.history/package_20240725151341.json
@@ -0,0 +1,52 @@
+{
+ "name": "open-insight-front",
+ "version": "0.1.0",
+ "private": true,
+ "engines": {
+ "node": "^16"
+ },
+ "dependencies": {
+ "@ant-design/icons": "^5.0.1",
+ "@testing-library/jest-dom": "^5.16.1",
+ "@testing-library/react": "^12.1.2",
+ "@testing-library/user-event": "^13.5.0",
+ "antd": "^4.18.0",
+ "i18next": "^21.6.4",
+ "i18next-browser-languagedetector": "^6.1.2",
+ "i18next-http-backend": "^1.3.1",
+ "moment": "^2.29.4",
+ "prettier": "^2.8.4",
+ "react": "^17.0.2",
+ "react-dom": "^17.0.2",
+ "react-i18next": "^11.15.2",
+ "react-router-dom": "^6.2.1",
+ "react-scripts": "5.0.0",
+ "web-vitals": "^2.1.2"
+ },
+ "scripts": {
+ "start": "react-scripts start",
+ "build": "react-scripts build",
+ "test": "react-scripts test",
+ "eject": "react-scripts eject",
+ "prettier": "prettier --write \"**/*.{js,jsx,ts,tsx,json,css,scss}\"",
+ "prettier:check": "prettier --check \"**/*.{js,jsx,ts,tsx,json,css,scss}\""
+ },
+ "eslintConfig": {
+ "extends": [
+ "react-app",
+ "react-app/jest"
+ ]
+ },
+ "browserslist": {
+ "production": [
+ ">0.2%",
+ "not dead",
+ "not op_mini all"
+ ],
+ "development": [
+ "last 1 chrome version",
+ "last 1 firefox version",
+ "last 1 safari version"
+ ]
+ }
+}
diff --git a/.history/package_20240728145142.json b/.history/package_20240728145142.json
new file mode 100644
index 0000000..6e07233
--- /dev/null
+++ b/.history/package_20240728145142.json
@@ -0,0 +1,55 @@
+{
+ "name": "open-insight-front",
+ "version": "0.1.0",
+ "private": true,
+ "engines": {
+ "node": "^16"
+ },
+ "dependencies": {
+ "@ant-design/icons": "^5.0.1",
+ "@testing-library/jest-dom": "^5.16.1",
+ "@testing-library/react": "^12.1.2",
+ "@testing-library/user-event": "^13.5.0",
+ "antd": "^4.18.0",
+ "i18next": "^21.6.4",
+ "i18next-browser-languagedetector": "^6.1.2",
+ "i18next-http-backend": "^1.3.1",
+ "moment": "^2.29.4",
+ "prettier": "^2.8.4",
+ "react": "^17.0.2",
+ "react-dom": "^17.0.2",
+ "react-i18next": "^11.15.2",
+ "react-router-dom": "^6.2.1",
+ "react-scripts": "5.0.0",
+ "web-vitals": "^2.1.2"
+ },
+ "scripts": {
+ "start": "react-scripts start",
+ "build": "react-scripts build",
+ "test": "react-scripts test",
+ "eject": "react-scripts eject",
+ "prettier": "prettier --write \"**/*.{js,jsx,ts,tsx,json,css,scss}\"",
+ "prettier:check": "prettier --check \"**/*.{js,jsx,ts,tsx,json,css,scss}\""
+ },
+ "eslintConfig": {
+ "extends": [
+ "react-app",
+ "react-app/jest"
+ ]
+ },
+ "browserslist": {
+ "production": [
+ ">0.2%",
+ "not dead",
+ "not op_mini all"
+ ],
+ "development": [
+ "last 1 chrome version",
+ "last 1 firefox version",
+ "last 1 safari version"
+ ],
+ "rules":{
+ "no-undef": "off"
+ }
+ }
+}
diff --git a/.history/package_20240728195511.json b/.history/package_20240728195511.json
new file mode 100644
index 0000000..ee4e31c
--- /dev/null
+++ b/.history/package_20240728195511.json
@@ -0,0 +1,52 @@
+{
+ "name": "open-insight-front",
+ "version": "0.1.0",
+ "private": true,
+ "engines": {
+ "node": "^16"
+ },
+ "dependencies": {
+ "@ant-design/icons": "^5.0.1",
+ "@testing-library/jest-dom": "^5.16.1",
+ "@testing-library/react": "^12.1.2",
+ "@testing-library/user-event": "^13.5.0",
+ "antd": "^4.18.0",
+ "i18next": "^21.6.4",
+ "i18next-browser-languagedetector": "^6.1.2",
+ "i18next-http-backend": "^1.3.1",
+ "moment": "^2.29.4",
+ "prettier": "^2.8.4",
+ "react": "^17.0.2",
+ "react-dom": "^17.0.2",
+ "react-i18next": "^11.15.2",
+ "react-router-dom": "^6.2.1",
+ "react-scripts": "5.0.0",
+ "web-vitals": "^2.1.2"
+ },
+ "scripts": {
+ "start": "react-scripts start",
+ "build": "react-scripts build",
+ "test": "react-scripts test",
+ "eject": "react-scripts eject",
+ "prettier": "prettier --write \"**/*.{js,jsx,ts,tsx,json,css,scss}\"",
+ "prettier:check": "prettier --check \"**/*.{js,jsx,ts,tsx,json,css,scss}\""
+ },
+ "eslintConfig": {
+ "extends": [
+ "react-app",
+ "react-app/jest"
+ ]
+ },
+ "browserslist": {
+ "production": [
+ ">0.2%",
+ "not dead",
+ "not op_mini all"
+ ],
+ "development": [
+ "last 1 chrome version",
+ "last 1 firefox version",
+ "last 1 safari version"
+ ]
+ }
+}
diff --git a/.history/public/tech-foundation/foundationchinese_20240728172909.json b/.history/public/tech-foundation/foundationchinese_20240728172909.json
new file mode 100644
index 0000000..e69de29
diff --git a/.history/public/tech-foundation/foundationchinese_20240728172930.json b/.history/public/tech-foundation/foundationchinese_20240728172930.json
new file mode 100644
index 0000000..ce7dab2
--- /dev/null
+++ b/.history/public/tech-foundation/foundationchinese_20240728172930.json
@@ -0,0 +1,76 @@
+{
+ "type": "Foundation_China",
+ "time": "2024",
+ "data": [
+ {
+ "rank": "1",
+ "name": "apache/doris",
+ "value": "4307.26",
+ "rankDelta": 1,
+ "valueDelta": 100
+ },
+ {
+ "rank": "2",
+ "name": "openharmony/docs",
+ "value": "3277.69",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "3",
+ "name": "openharmony/arkui_ace_engine",
+ "value": "2818.09",
+ "rankDelta": -1,
+ "valueDelta": -3
+ },
+ {
+ "rank": "4",
+ "name": "milvus-io/milvus",
+ "value": "2001.11",
+ "rankDelta": 3,
+ "valueDelta": -100
+ },
+ {
+ "rank": "5",
+ "name": "apache/flink",
+ "value": "1816.72",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "6",
+ "name": "apache/shardingsphere",
+ "value": "1662.8",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "7",
+ "name": "apache/ozone",
+ "value": "1281.57",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "8",
+ "name": "apache/iotdb",
+ "value": "1265.72",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "9",
+ "name": "openharmony/graphic_graphic_2d",
+ "value": "1239.6",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "10",
+ "name": "apache/pulsar",
+ "value": "1227.93",
+ "rankDelta": 0,
+ "valueDelta": 0
+ }
+ ]
+ }
\ No newline at end of file
diff --git a/.history/public/tech-foundation/foundationglobal_20240728172918.json b/.history/public/tech-foundation/foundationglobal_20240728172918.json
new file mode 100644
index 0000000..e69de29
diff --git a/.history/public/tech-foundation/foundationglobal_20240728173949.json b/.history/public/tech-foundation/foundationglobal_20240728173949.json
new file mode 100644
index 0000000..6355a41
--- /dev/null
+++ b/.history/public/tech-foundation/foundationglobal_20240728173949.json
@@ -0,0 +1,5 @@
+{
+ "type": "Foundation_Global",
+ "time": "2024",
+ "data":
+}
\ No newline at end of file
diff --git a/.history/public/tech-foundation/foundationglobal_20240728182812.json b/.history/public/tech-foundation/foundationglobal_20240728182812.json
new file mode 100644
index 0000000..833d3ab
--- /dev/null
+++ b/.history/public/tech-foundation/foundationglobal_20240728182812.json
@@ -0,0 +1,76 @@
+{
+ "type": "Foundation_Global",
+ "time": "2024",
+ "data": [
+ {
+ "rank": "1",
+ "name": "kubernetes/kubernetes",
+ "value": "5374.14",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "2",
+ "name": "apache/doris",
+ "value": "4307.26",
+ "rankDelta": 2,
+ "valueDelta": 3
+ },
+ {
+ "rank": "3",
+ "name": "apache/airflow",
+ "value": "3642.9",
+ "rankDelta": -1,
+ "valueDelta": -3
+ },
+ {
+ "rank": "4",
+ "name": "openharmony/docs",
+ "value": "3277.69",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "5",
+ "name": "openharmony/arkui_ace_engine",
+ "value": "2818.09",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "6",
+ "name": "nodejs/node",
+ "value": "2736.37",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "7",
+ "name": "apache/spark",
+ "value": "2654.02",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "8",
+ "name": "apache/arrow",
+ "value": "2219.95",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "9",
+ "name": "apache/beam",
+ "value": "2188.52",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "10",
+ "name": "apache/hudi",
+ "value": "2124.67",
+ "rankDelta": 0,
+ "valueDelta": 0
+ }
+ ]
+}
\ No newline at end of file
diff --git a/.history/public/tech-foundation/foundationglobal_20240728182818.json b/.history/public/tech-foundation/foundationglobal_20240728182818.json
new file mode 100644
index 0000000..1b2502b
--- /dev/null
+++ b/.history/public/tech-foundation/foundationglobal_20240728182818.json
@@ -0,0 +1,76 @@
+{
+ "type": "Foundation_Global",
+ "time": "2024",
+ "data": [
+ {
+ "rank": "1",
+ "name": "kubernetes/kubernetes",
+ "value": "5374.14",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "2",
+ "name": "apache/doris",
+ "value": "4307.26",
+ "rankDelta": 2,
+ "valueDelta": 3
+ },
+ {
+ "rank": "3",
+ "name": "apache/airflow",
+ "value": "3642.9",
+ "rankDelta": -1,
+ "valueDelta": -3
+ },
+ {
+ "rank": "4",
+ "name": "openharmony/docs",
+ "value": "3277.69",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "5",
+ "name": "openharmony/arkui_ace_engine",
+ "value": "2818.09",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "6",
+ "name": "nodejs/node",
+ "value": "2736.37",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "7",
+ "name": "apache/spark",
+ "value": "2654.02",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "8",
+ "name": "apache/arrow",
+ "value": "2219.95",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "9",
+ "name": "apache/beam",
+ "value": "2188.52",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "10",
+ "name": "apache/hudi",
+ "value": "2124.67",
+ "rankDelta": 0,
+ "valueDelta": 0
+ }
+ ]
+}
\ No newline at end of file
diff --git a/.history/public/tech-foundation/foundationglobal_20240728195837.json b/.history/public/tech-foundation/foundationglobal_20240728195837.json
new file mode 100644
index 0000000..1b2502b
--- /dev/null
+++ b/.history/public/tech-foundation/foundationglobal_20240728195837.json
@@ -0,0 +1,76 @@
+{
+ "type": "Foundation_Global",
+ "time": "2024",
+ "data": [
+ {
+ "rank": "1",
+ "name": "kubernetes/kubernetes",
+ "value": "5374.14",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "2",
+ "name": "apache/doris",
+ "value": "4307.26",
+ "rankDelta": 2,
+ "valueDelta": 3
+ },
+ {
+ "rank": "3",
+ "name": "apache/airflow",
+ "value": "3642.9",
+ "rankDelta": -1,
+ "valueDelta": -3
+ },
+ {
+ "rank": "4",
+ "name": "openharmony/docs",
+ "value": "3277.69",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "5",
+ "name": "openharmony/arkui_ace_engine",
+ "value": "2818.09",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "6",
+ "name": "nodejs/node",
+ "value": "2736.37",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "7",
+ "name": "apache/spark",
+ "value": "2654.02",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "8",
+ "name": "apache/arrow",
+ "value": "2219.95",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "9",
+ "name": "apache/beam",
+ "value": "2188.52",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "10",
+ "name": "apache/hudi",
+ "value": "2124.67",
+ "rankDelta": 0,
+ "valueDelta": 0
+ }
+ ]
+}
\ No newline at end of file
diff --git a/.history/public/tech-foundation/technologyai_20240728172713.json b/.history/public/tech-foundation/technologyai_20240728172713.json
new file mode 100644
index 0000000..e69de29
diff --git a/.history/public/tech-foundation/technologyai_20240728173532.json b/.history/public/tech-foundation/technologyai_20240728173532.json
new file mode 100644
index 0000000..497d76f
--- /dev/null
+++ b/.history/public/tech-foundation/technologyai_20240728173532.json
@@ -0,0 +1,77 @@
+{
+ "type": "Foundation_China",
+ "time": "2024",
+ "data":[
+ {
+ "rank": "1",
+ "name": "pytorch/pytorch",
+ "value": "10182.45",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "2",
+ "name": "langchain-ai/langchain",
+ "value": "6080.25",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "3",
+ "name": "PaddlePaddle/Paddle",
+ "value": "5408.62",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "4",
+ "name": "huggingface/transformers",
+ "value": "4422.84",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "5",
+ "name": "AUTOMATIC1111/stable-diffusion-webui",
+ "value": "3881.6",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "6",
+ "name": "openvinotoolkit/openvino",
+ "value": "3857.31",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "7",
+ "name": "microsoft/onnxruntime",
+ "value": "3006.75",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "8",
+ "name": "tensorflow/tensorflow",
+ "value": "2723.26",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "9",
+ "name": "Significant-Gravitas/AutoGPT",
+ "value": "2664.85",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "10",
+ "name": "ggerganov/llama.cpp",
+ "value": "2339.8",
+ "rankDelta": 0,
+ "valueDelta": 0
+ }
+ ]
+
+}
\ No newline at end of file
diff --git a/.history/public/tech-foundation/technologyai_20240728173534.json b/.history/public/tech-foundation/technologyai_20240728173534.json
new file mode 100644
index 0000000..72f1387
--- /dev/null
+++ b/.history/public/tech-foundation/technologyai_20240728173534.json
@@ -0,0 +1,76 @@
+{
+ "type": "Foundation_China",
+ "time": "2024",
+ "data":[
+ {
+ "rank": "1",
+ "name": "pytorch/pytorch",
+ "value": "10182.45",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "2",
+ "name": "langchain-ai/langchain",
+ "value": "6080.25",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "3",
+ "name": "PaddlePaddle/Paddle",
+ "value": "5408.62",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "4",
+ "name": "huggingface/transformers",
+ "value": "4422.84",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "5",
+ "name": "AUTOMATIC1111/stable-diffusion-webui",
+ "value": "3881.6",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "6",
+ "name": "openvinotoolkit/openvino",
+ "value": "3857.31",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "7",
+ "name": "microsoft/onnxruntime",
+ "value": "3006.75",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "8",
+ "name": "tensorflow/tensorflow",
+ "value": "2723.26",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "9",
+ "name": "Significant-Gravitas/AutoGPT",
+ "value": "2664.85",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "10",
+ "name": "ggerganov/llama.cpp",
+ "value": "2339.8",
+ "rankDelta": 0,
+ "valueDelta": 0
+ }
+ ]
+}
\ No newline at end of file
diff --git a/.history/public/tech-foundation/technologyai_20240728173542.json b/.history/public/tech-foundation/technologyai_20240728173542.json
new file mode 100644
index 0000000..d1d2a6d
--- /dev/null
+++ b/.history/public/tech-foundation/technologyai_20240728173542.json
@@ -0,0 +1,76 @@
+{
+ "type": "Foundation_China",
+ "time": "2024",
+ "data": [
+ {
+ "rank": "1",
+ "name": "pytorch/pytorch",
+ "value": "10182.45",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "2",
+ "name": "langchain-ai/langchain",
+ "value": "6080.25",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "3",
+ "name": "PaddlePaddle/Paddle",
+ "value": "5408.62",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "4",
+ "name": "huggingface/transformers",
+ "value": "4422.84",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "5",
+ "name": "AUTOMATIC1111/stable-diffusion-webui",
+ "value": "3881.6",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "6",
+ "name": "openvinotoolkit/openvino",
+ "value": "3857.31",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "7",
+ "name": "microsoft/onnxruntime",
+ "value": "3006.75",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "8",
+ "name": "tensorflow/tensorflow",
+ "value": "2723.26",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "9",
+ "name": "Significant-Gravitas/AutoGPT",
+ "value": "2664.85",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "10",
+ "name": "ggerganov/llama.cpp",
+ "value": "2339.8",
+ "rankDelta": 0,
+ "valueDelta": 0
+ }
+ ]
+}
\ No newline at end of file
diff --git a/.history/public/tech-foundation/technologyai_20240728173926.json b/.history/public/tech-foundation/technologyai_20240728173926.json
new file mode 100644
index 0000000..5b5d101
--- /dev/null
+++ b/.history/public/tech-foundation/technologyai_20240728173926.json
@@ -0,0 +1,76 @@
+{
+ "type": "Technology_ai",
+ "time": "2024",
+ "data": [
+ {
+ "rank": "1",
+ "name": "pytorch/pytorch",
+ "value": "10182.45",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "2",
+ "name": "langchain-ai/langchain",
+ "value": "6080.25",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "3",
+ "name": "PaddlePaddle/Paddle",
+ "value": "5408.62",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "4",
+ "name": "huggingface/transformers",
+ "value": "4422.84",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "5",
+ "name": "AUTOMATIC1111/stable-diffusion-webui",
+ "value": "3881.6",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "6",
+ "name": "openvinotoolkit/openvino",
+ "value": "3857.31",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "7",
+ "name": "microsoft/onnxruntime",
+ "value": "3006.75",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "8",
+ "name": "tensorflow/tensorflow",
+ "value": "2723.26",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "9",
+ "name": "Significant-Gravitas/AutoGPT",
+ "value": "2664.85",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "10",
+ "name": "ggerganov/llama.cpp",
+ "value": "2339.8",
+ "rankDelta": 0,
+ "valueDelta": 0
+ }
+ ]
+}
\ No newline at end of file
diff --git a/.history/public/tech-foundation/technologybig-data_20240728172727.json b/.history/public/tech-foundation/technologybig-data_20240728172727.json
new file mode 100644
index 0000000..e69de29
diff --git a/.history/public/tech-foundation/technologybig-data_20240728173618.json b/.history/public/tech-foundation/technologybig-data_20240728173618.json
new file mode 100644
index 0000000..4da1df0
--- /dev/null
+++ b/.history/public/tech-foundation/technologybig-data_20240728173618.json
@@ -0,0 +1,77 @@
+{
+ "type": "Foundation_China",
+ "time": "2024",
+ "data":[
+ {
+ "rank": "1",
+ "name": "elastic/kibana",
+ "value": "7601.04",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "2",
+ "name": "grafana/grafana",
+ "value": "7134.37",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "3",
+ "name": "ClickHouse/ClickHouse",
+ "value": "4941.99",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "4",
+ "name": "airbytehq/airbyte",
+ "value": "4658.86",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "5",
+ "name": "apache/doris",
+ "value": "4307.26",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "6",
+ "name": "elastic/elasticsearch",
+ "value": "3729.39",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "7",
+ "name": "apache/airflow",
+ "value": "3642.9",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "8",
+ "name": "StarRocks/starrocks",
+ "value": "3194.56",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "9",
+ "name": "trinodb/trino",
+ "value": "2703.4",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "10",
+ "name": "apache/spark",
+ "value": "2654.02",
+ "rankDelta": 0,
+ "valueDelta": 0
+ }
+ ]
+
+}
\ No newline at end of file
diff --git a/.history/public/tech-foundation/technologybig-data_20240728173633.json b/.history/public/tech-foundation/technologybig-data_20240728173633.json
new file mode 100644
index 0000000..a694155
--- /dev/null
+++ b/.history/public/tech-foundation/technologybig-data_20240728173633.json
@@ -0,0 +1,76 @@
+{
+ "type": "Foundation_China",
+ "time": "2024",
+ "data": [
+ {
+ "rank": "1",
+ "name": "elastic/kibana",
+ "value": "7601.04",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "2",
+ "name": "grafana/grafana",
+ "value": "7134.37",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "3",
+ "name": "ClickHouse/ClickHouse",
+ "value": "4941.99",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "4",
+ "name": "airbytehq/airbyte",
+ "value": "4658.86",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "5",
+ "name": "apache/doris",
+ "value": "4307.26",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "6",
+ "name": "elastic/elasticsearch",
+ "value": "3729.39",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "7",
+ "name": "apache/airflow",
+ "value": "3642.9",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "8",
+ "name": "StarRocks/starrocks",
+ "value": "3194.56",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "9",
+ "name": "trinodb/trino",
+ "value": "2703.4",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "10",
+ "name": "apache/spark",
+ "value": "2654.02",
+ "rankDelta": 0,
+ "valueDelta": 0
+ }
+ ]
+}
\ No newline at end of file
diff --git a/.history/public/tech-foundation/technologybig-data_20240728195750.json b/.history/public/tech-foundation/technologybig-data_20240728195750.json
new file mode 100644
index 0000000..08dd4a7
--- /dev/null
+++ b/.history/public/tech-foundation/technologybig-data_20240728195750.json
@@ -0,0 +1,76 @@
+{
+ "type": "Technology_big-data",
+ "time": "2024",
+ "data": [
+ {
+ "rank": "1",
+ "name": "elastic/kibana",
+ "value": "7601.04",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "2",
+ "name": "grafana/grafana",
+ "value": "7134.37",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "3",
+ "name": "ClickHouse/ClickHouse",
+ "value": "4941.99",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "4",
+ "name": "airbytehq/airbyte",
+ "value": "4658.86",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "5",
+ "name": "apache/doris",
+ "value": "4307.26",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "6",
+ "name": "elastic/elasticsearch",
+ "value": "3729.39",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "7",
+ "name": "apache/airflow",
+ "value": "3642.9",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "8",
+ "name": "StarRocks/starrocks",
+ "value": "3194.56",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "9",
+ "name": "trinodb/trino",
+ "value": "2703.4",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "10",
+ "name": "apache/spark",
+ "value": "2654.02",
+ "rankDelta": 0,
+ "valueDelta": 0
+ }
+ ]
+}
\ No newline at end of file
diff --git a/.history/public/tech-foundation/technologycloud-native_20240728172857.json b/.history/public/tech-foundation/technologycloud-native_20240728172857.json
new file mode 100644
index 0000000..e69de29
diff --git a/.history/public/tech-foundation/technologycloud-native_20240728173058.json b/.history/public/tech-foundation/technologycloud-native_20240728173058.json
new file mode 100644
index 0000000..fccc6d9
--- /dev/null
+++ b/.history/public/tech-foundation/technologycloud-native_20240728173058.json
@@ -0,0 +1,76 @@
+{
+ "type": "Foundation_China",
+ "time": "2024",
+ "data": [
+ {
+ "rank": "1",
+ "name": "grafana/grafana",
+ "value": "7134.37",
+ "rankDelta": 1,
+ "valueDelta": 100
+ },
+ {
+ "rank": "2",
+ "name": "llvm/llvm-project",
+ "value": "7049.62",
+ "rankDelta": -2,
+ "valueDelta": -220
+ },
+ {
+ "rank": "3",
+ "name": "kubernetes/kubernetes",
+ "value": "5374.14",
+ "rankDelta": 3,
+ "valueDelta": 300
+ },
+ {
+ "rank": "4",
+ "name": "ClickHouse/ClickHouse",
+ "value": "4941.99",
+ "rankDelta": -4,
+ "valueDelta": 400
+ },
+ {
+ "rank": "5",
+ "name": "cilium/cilium",
+ "value": "3215.42",
+ "rankDelta": 5,
+ "valueDelta": -500
+ },
+ {
+ "rank": "6",
+ "name": "ceph/ceph",
+ "value": "3172.49",
+ "rankDelta": -6,
+ "valueDelta": 600
+ },
+ {
+ "rank": "7",
+ "name": "keycloak/keycloak",
+ "value": "3095.56",
+ "rankDelta": 7,
+ "valueDelta": 700
+ },
+ {
+ "rank": "8",
+ "name": "gravitational/teleport",
+ "value": "3082.18",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "9",
+ "name": "envoyproxy/envoy",
+ "value": "2929.08",
+ "rankDelta": 9,
+ "valueDelta": -900
+ },
+ {
+ "rank": "10",
+ "name": "backstage/backstage",
+ "value": "2903.39",
+ "rankDelta": 10,
+ "valueDelta": 100
+ }
+ ]
+ }
\ No newline at end of file
diff --git a/.history/public/tech-foundation/technologycloud-native_20240728173847.json b/.history/public/tech-foundation/technologycloud-native_20240728173847.json
new file mode 100644
index 0000000..c6d4351
--- /dev/null
+++ b/.history/public/tech-foundation/technologycloud-native_20240728173847.json
@@ -0,0 +1,76 @@
+{
+ "type": "Technology_cloud-native",
+ "time": "2024",
+ "data": [
+ {
+ "rank": "1",
+ "name": "grafana/grafana",
+ "value": "7134.37",
+ "rankDelta": 1,
+ "valueDelta": 100
+ },
+ {
+ "rank": "2",
+ "name": "llvm/llvm-project",
+ "value": "7049.62",
+ "rankDelta": -2,
+ "valueDelta": -220
+ },
+ {
+ "rank": "3",
+ "name": "kubernetes/kubernetes",
+ "value": "5374.14",
+ "rankDelta": 3,
+ "valueDelta": 300
+ },
+ {
+ "rank": "4",
+ "name": "ClickHouse/ClickHouse",
+ "value": "4941.99",
+ "rankDelta": -4,
+ "valueDelta": 400
+ },
+ {
+ "rank": "5",
+ "name": "cilium/cilium",
+ "value": "3215.42",
+ "rankDelta": 5,
+ "valueDelta": -500
+ },
+ {
+ "rank": "6",
+ "name": "ceph/ceph",
+ "value": "3172.49",
+ "rankDelta": -6,
+ "valueDelta": 600
+ },
+ {
+ "rank": "7",
+ "name": "keycloak/keycloak",
+ "value": "3095.56",
+ "rankDelta": 7,
+ "valueDelta": 700
+ },
+ {
+ "rank": "8",
+ "name": "gravitational/teleport",
+ "value": "3082.18",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "9",
+ "name": "envoyproxy/envoy",
+ "value": "2929.08",
+ "rankDelta": 9,
+ "valueDelta": -900
+ },
+ {
+ "rank": "10",
+ "name": "backstage/backstage",
+ "value": "2903.39",
+ "rankDelta": 10,
+ "valueDelta": 100
+ }
+ ]
+ }
\ No newline at end of file
diff --git a/.history/public/tech-foundation/technologydatabase_20240728172821.json b/.history/public/tech-foundation/technologydatabase_20240728172821.json
new file mode 100644
index 0000000..e69de29
diff --git a/.history/public/tech-foundation/technologydatabase_20240728173704.json b/.history/public/tech-foundation/technologydatabase_20240728173704.json
new file mode 100644
index 0000000..01acd8b
--- /dev/null
+++ b/.history/public/tech-foundation/technologydatabase_20240728173704.json
@@ -0,0 +1,77 @@
+{
+ "type": "Foundation_China",
+ "time": "2024",
+ "data":[
+ {
+ "rank": "1",
+ "name": "ClickHouse/ClickHouse",
+ "value": "4941.99",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "2",
+ "name": "apache/doris",
+ "value": "4307.26",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "3",
+ "name": "elastic/elasticsearch",
+ "value": "3729.39",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "4",
+ "name": "cockroachdb/cockroach",
+ "value": "3443.7",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "5",
+ "name": "StarRocks/starrocks",
+ "value": "3194.56",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "6",
+ "name": "trinodb/trino",
+ "value": "2703.4",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "7",
+ "name": "apache/spark",
+ "value": "2654.02",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "8",
+ "name": "pingcap/tidb",
+ "value": "2200.38",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "9",
+ "name": "milvus-io/milvus",
+ "value": "2001.11",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "10",
+ "name": "yugabyte/yugabyte-db",
+ "value": "1940.75",
+ "rankDelta": 0,
+ "valueDelta": 0
+ }
+ ]
+
+}
\ No newline at end of file
diff --git a/.history/public/tech-foundation/technologydatabase_20240728173710.json b/.history/public/tech-foundation/technologydatabase_20240728173710.json
new file mode 100644
index 0000000..0674215
--- /dev/null
+++ b/.history/public/tech-foundation/technologydatabase_20240728173710.json
@@ -0,0 +1,76 @@
+{
+ "type": "Foundation_China",
+ "time": "2024",
+ "data": [
+ {
+ "rank": "1",
+ "name": "ClickHouse/ClickHouse",
+ "value": "4941.99",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "2",
+ "name": "apache/doris",
+ "value": "4307.26",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "3",
+ "name": "elastic/elasticsearch",
+ "value": "3729.39",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "4",
+ "name": "cockroachdb/cockroach",
+ "value": "3443.7",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "5",
+ "name": "StarRocks/starrocks",
+ "value": "3194.56",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "6",
+ "name": "trinodb/trino",
+ "value": "2703.4",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "7",
+ "name": "apache/spark",
+ "value": "2654.02",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "8",
+ "name": "pingcap/tidb",
+ "value": "2200.38",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "9",
+ "name": "milvus-io/milvus",
+ "value": "2001.11",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "10",
+ "name": "yugabyte/yugabyte-db",
+ "value": "1940.75",
+ "rankDelta": 0,
+ "valueDelta": 0
+ }
+ ]
+}
\ No newline at end of file
diff --git a/.history/public/tech-foundation/technologydatabase_20240728195805.json b/.history/public/tech-foundation/technologydatabase_20240728195805.json
new file mode 100644
index 0000000..2d6a2a7
--- /dev/null
+++ b/.history/public/tech-foundation/technologydatabase_20240728195805.json
@@ -0,0 +1,76 @@
+{
+ "type": "Technology_database",
+ "time": "2024",
+ "data": [
+ {
+ "rank": "1",
+ "name": "ClickHouse/ClickHouse",
+ "value": "4941.99",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "2",
+ "name": "apache/doris",
+ "value": "4307.26",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "3",
+ "name": "elastic/elasticsearch",
+ "value": "3729.39",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "4",
+ "name": "cockroachdb/cockroach",
+ "value": "3443.7",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "5",
+ "name": "StarRocks/starrocks",
+ "value": "3194.56",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "6",
+ "name": "trinodb/trino",
+ "value": "2703.4",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "7",
+ "name": "apache/spark",
+ "value": "2654.02",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "8",
+ "name": "pingcap/tidb",
+ "value": "2200.38",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "9",
+ "name": "milvus-io/milvus",
+ "value": "2001.11",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "10",
+ "name": "yugabyte/yugabyte-db",
+ "value": "1940.75",
+ "rankDelta": 0,
+ "valueDelta": 0
+ }
+ ]
+}
\ No newline at end of file
diff --git a/.history/public/tech-foundation/technologyfront-end_20240728172808.json b/.history/public/tech-foundation/technologyfront-end_20240728172808.json
new file mode 100644
index 0000000..e69de29
diff --git a/.history/public/tech-foundation/technologyfront-end_20240728173446.json b/.history/public/tech-foundation/technologyfront-end_20240728173446.json
new file mode 100644
index 0000000..46296d7
--- /dev/null
+++ b/.history/public/tech-foundation/technologyfront-end_20240728173446.json
@@ -0,0 +1,7 @@
+{
+ "type": "Foundation_China",
+ "time": "2024",
+ "data":[
+
+ ]
+}
\ No newline at end of file
diff --git a/.history/public/tech-foundation/technologyfront-end_20240728173736.json b/.history/public/tech-foundation/technologyfront-end_20240728173736.json
new file mode 100644
index 0000000..d182bfb
--- /dev/null
+++ b/.history/public/tech-foundation/technologyfront-end_20240728173736.json
@@ -0,0 +1,77 @@
+{
+ "type": "Foundation_China",
+ "time": "2024",
+ "data":[
+ {
+ "rank": "1",
+ "name": "flutter/flutter",
+ "value": "9361.81",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "2",
+ "name": "vercel/next.js",
+ "value": "6638.65",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "3",
+ "name": "appsmithorg/appsmith",
+ "value": "3474.07",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "4",
+ "name": "nuxt/nuxt",
+ "value": "3387.23",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "5",
+ "name": "facebook/react-native",
+ "value": "3260.55",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "6",
+ "name": "ant-design/ant-design",
+ "value": "3053.25",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "7",
+ "name": "nodejs/node",
+ "value": "2736.37",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "8",
+ "name": "angular/angular",
+ "value": "2273.82",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "9",
+ "name": "electron/electron",
+ "value": "1773.31",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "10",
+ "name": "denoland/deno",
+ "value": "1654.01",
+ "rankDelta": 0,
+ "valueDelta": 0
+ }
+ ]
+
+}
\ No newline at end of file
diff --git a/.history/public/tech-foundation/technologyfront-end_20240728173741.json b/.history/public/tech-foundation/technologyfront-end_20240728173741.json
new file mode 100644
index 0000000..b3eee58
--- /dev/null
+++ b/.history/public/tech-foundation/technologyfront-end_20240728173741.json
@@ -0,0 +1,76 @@
+{
+ "type": "Foundation_China",
+ "time": "2024",
+ "data": [
+ {
+ "rank": "1",
+ "name": "flutter/flutter",
+ "value": "9361.81",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "2",
+ "name": "vercel/next.js",
+ "value": "6638.65",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "3",
+ "name": "appsmithorg/appsmith",
+ "value": "3474.07",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "4",
+ "name": "nuxt/nuxt",
+ "value": "3387.23",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "5",
+ "name": "facebook/react-native",
+ "value": "3260.55",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "6",
+ "name": "ant-design/ant-design",
+ "value": "3053.25",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "7",
+ "name": "nodejs/node",
+ "value": "2736.37",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "8",
+ "name": "angular/angular",
+ "value": "2273.82",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "9",
+ "name": "electron/electron",
+ "value": "1773.31",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "10",
+ "name": "denoland/deno",
+ "value": "1654.01",
+ "rankDelta": 0,
+ "valueDelta": 0
+ }
+ ]
+}
\ No newline at end of file
diff --git a/.history/public/tech-foundation/technologyfront-end_20240728195817.json b/.history/public/tech-foundation/technologyfront-end_20240728195817.json
new file mode 100644
index 0000000..88e549f
--- /dev/null
+++ b/.history/public/tech-foundation/technologyfront-end_20240728195817.json
@@ -0,0 +1,76 @@
+{
+ "type": "Technology_front-end",
+ "time": "2024",
+ "data": [
+ {
+ "rank": "1",
+ "name": "flutter/flutter",
+ "value": "9361.81",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "2",
+ "name": "vercel/next.js",
+ "value": "6638.65",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "3",
+ "name": "appsmithorg/appsmith",
+ "value": "3474.07",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "4",
+ "name": "nuxt/nuxt",
+ "value": "3387.23",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "5",
+ "name": "facebook/react-native",
+ "value": "3260.55",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "6",
+ "name": "ant-design/ant-design",
+ "value": "3053.25",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "7",
+ "name": "nodejs/node",
+ "value": "2736.37",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "8",
+ "name": "angular/angular",
+ "value": "2273.82",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "9",
+ "name": "electron/electron",
+ "value": "1773.31",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "10",
+ "name": "denoland/deno",
+ "value": "1654.01",
+ "rankDelta": 0,
+ "valueDelta": 0
+ }
+ ]
+}
\ No newline at end of file
diff --git a/.history/public/tech-foundation/technologyos_20240728172838.json b/.history/public/tech-foundation/technologyos_20240728172838.json
new file mode 100644
index 0000000..e69de29
diff --git a/.history/public/tech-foundation/technologyos_20240728173806.json b/.history/public/tech-foundation/technologyos_20240728173806.json
new file mode 100644
index 0000000..3b5d996
--- /dev/null
+++ b/.history/public/tech-foundation/technologyos_20240728173806.json
@@ -0,0 +1,77 @@
+{
+ "type": "Foundation_China",
+ "time": "2024",
+ "data":[
+ {
+ "rank": "1",
+ "name": "openharmony/docs",
+ "value": "3277.69",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "2",
+ "name": "openharmony/arkui_ace_engine",
+ "value": "2818.09",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "3",
+ "name": "SerenityOS/serenity",
+ "value": "2257.68",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "4",
+ "name": "openharmony/graphic_graphic_2d",
+ "value": "1239.6",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "5",
+ "name": "openeuler/docs",
+ "value": "1206.9",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "6",
+ "name": "openharmony/xts_acts",
+ "value": "1186.06",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "7",
+ "name": "openharmony/arkcompiler_ets_runtime",
+ "value": "961.99",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "8",
+ "name": "openharmony/interface_sdk-js",
+ "value": "910.91",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "9",
+ "name": "reactos/reactos",
+ "value": "745.23",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "10",
+ "name": "armbian/build",
+ "value": "679.1",
+ "rankDelta": 0,
+ "valueDelta": 0
+ }
+ ]
+
+}
\ No newline at end of file
diff --git a/.history/public/tech-foundation/technologyos_20240728173810.json b/.history/public/tech-foundation/technologyos_20240728173810.json
new file mode 100644
index 0000000..9659408
--- /dev/null
+++ b/.history/public/tech-foundation/technologyos_20240728173810.json
@@ -0,0 +1,76 @@
+{
+ "type": "Foundation_China",
+ "time": "2024",
+ "data": [
+ {
+ "rank": "1",
+ "name": "openharmony/docs",
+ "value": "3277.69",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "2",
+ "name": "openharmony/arkui_ace_engine",
+ "value": "2818.09",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "3",
+ "name": "SerenityOS/serenity",
+ "value": "2257.68",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "4",
+ "name": "openharmony/graphic_graphic_2d",
+ "value": "1239.6",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "5",
+ "name": "openeuler/docs",
+ "value": "1206.9",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "6",
+ "name": "openharmony/xts_acts",
+ "value": "1186.06",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "7",
+ "name": "openharmony/arkcompiler_ets_runtime",
+ "value": "961.99",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "8",
+ "name": "openharmony/interface_sdk-js",
+ "value": "910.91",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "9",
+ "name": "reactos/reactos",
+ "value": "745.23",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "10",
+ "name": "armbian/build",
+ "value": "679.1",
+ "rankDelta": 0,
+ "valueDelta": 0
+ }
+ ]
+}
\ No newline at end of file
diff --git a/.history/public/tech-foundation/technologyos_20240728195829.json b/.history/public/tech-foundation/technologyos_20240728195829.json
new file mode 100644
index 0000000..93a8e86
--- /dev/null
+++ b/.history/public/tech-foundation/technologyos_20240728195829.json
@@ -0,0 +1,76 @@
+{
+ "type": "Technology_os",
+ "time": "2024",
+ "data": [
+ {
+ "rank": "1",
+ "name": "openharmony/docs",
+ "value": "3277.69",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "2",
+ "name": "openharmony/arkui_ace_engine",
+ "value": "2818.09",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "3",
+ "name": "SerenityOS/serenity",
+ "value": "2257.68",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "4",
+ "name": "openharmony/graphic_graphic_2d",
+ "value": "1239.6",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "5",
+ "name": "openeuler/docs",
+ "value": "1206.9",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "6",
+ "name": "openharmony/xts_acts",
+ "value": "1186.06",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "7",
+ "name": "openharmony/arkcompiler_ets_runtime",
+ "value": "961.99",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "8",
+ "name": "openharmony/interface_sdk-js",
+ "value": "910.91",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "9",
+ "name": "reactos/reactos",
+ "value": "745.23",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "10",
+ "name": "armbian/build",
+ "value": "679.1",
+ "rankDelta": 0,
+ "valueDelta": 0
+ }
+ ]
+}
\ No newline at end of file
diff --git a/.history/public/technologycloud-native_20240728153801.json b/.history/public/technologycloud-native_20240728153801.json
new file mode 100644
index 0000000..e69de29
diff --git a/.history/public/technologycloud-native_20240728154040.json b/.history/public/technologycloud-native_20240728154040.json
new file mode 100644
index 0000000..fccc6d9
--- /dev/null
+++ b/.history/public/technologycloud-native_20240728154040.json
@@ -0,0 +1,76 @@
+{
+ "type": "Foundation_China",
+ "time": "2024",
+ "data": [
+ {
+ "rank": "1",
+ "name": "grafana/grafana",
+ "value": "7134.37",
+ "rankDelta": 1,
+ "valueDelta": 100
+ },
+ {
+ "rank": "2",
+ "name": "llvm/llvm-project",
+ "value": "7049.62",
+ "rankDelta": -2,
+ "valueDelta": -220
+ },
+ {
+ "rank": "3",
+ "name": "kubernetes/kubernetes",
+ "value": "5374.14",
+ "rankDelta": 3,
+ "valueDelta": 300
+ },
+ {
+ "rank": "4",
+ "name": "ClickHouse/ClickHouse",
+ "value": "4941.99",
+ "rankDelta": -4,
+ "valueDelta": 400
+ },
+ {
+ "rank": "5",
+ "name": "cilium/cilium",
+ "value": "3215.42",
+ "rankDelta": 5,
+ "valueDelta": -500
+ },
+ {
+ "rank": "6",
+ "name": "ceph/ceph",
+ "value": "3172.49",
+ "rankDelta": -6,
+ "valueDelta": 600
+ },
+ {
+ "rank": "7",
+ "name": "keycloak/keycloak",
+ "value": "3095.56",
+ "rankDelta": 7,
+ "valueDelta": 700
+ },
+ {
+ "rank": "8",
+ "name": "gravitational/teleport",
+ "value": "3082.18",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "9",
+ "name": "envoyproxy/envoy",
+ "value": "2929.08",
+ "rankDelta": 9,
+ "valueDelta": -900
+ },
+ {
+ "rank": "10",
+ "name": "backstage/backstage",
+ "value": "2903.39",
+ "rankDelta": 10,
+ "valueDelta": 100
+ }
+ ]
+ }
\ No newline at end of file
diff --git a/.history/public/technologycloud-native_20240728154042.json b/.history/public/technologycloud-native_20240728154042.json
new file mode 100644
index 0000000..fccc6d9
--- /dev/null
+++ b/.history/public/technologycloud-native_20240728154042.json
@@ -0,0 +1,76 @@
+{
+ "type": "Foundation_China",
+ "time": "2024",
+ "data": [
+ {
+ "rank": "1",
+ "name": "grafana/grafana",
+ "value": "7134.37",
+ "rankDelta": 1,
+ "valueDelta": 100
+ },
+ {
+ "rank": "2",
+ "name": "llvm/llvm-project",
+ "value": "7049.62",
+ "rankDelta": -2,
+ "valueDelta": -220
+ },
+ {
+ "rank": "3",
+ "name": "kubernetes/kubernetes",
+ "value": "5374.14",
+ "rankDelta": 3,
+ "valueDelta": 300
+ },
+ {
+ "rank": "4",
+ "name": "ClickHouse/ClickHouse",
+ "value": "4941.99",
+ "rankDelta": -4,
+ "valueDelta": 400
+ },
+ {
+ "rank": "5",
+ "name": "cilium/cilium",
+ "value": "3215.42",
+ "rankDelta": 5,
+ "valueDelta": -500
+ },
+ {
+ "rank": "6",
+ "name": "ceph/ceph",
+ "value": "3172.49",
+ "rankDelta": -6,
+ "valueDelta": 600
+ },
+ {
+ "rank": "7",
+ "name": "keycloak/keycloak",
+ "value": "3095.56",
+ "rankDelta": 7,
+ "valueDelta": 700
+ },
+ {
+ "rank": "8",
+ "name": "gravitational/teleport",
+ "value": "3082.18",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "9",
+ "name": "envoyproxy/envoy",
+ "value": "2929.08",
+ "rankDelta": 9,
+ "valueDelta": -900
+ },
+ {
+ "rank": "10",
+ "name": "backstage/backstage",
+ "value": "2903.39",
+ "rankDelta": 10,
+ "valueDelta": 100
+ }
+ ]
+ }
\ No newline at end of file
diff --git a/.history/src/components/data_20240728143018.js b/.history/src/components/data_20240728143018.js
new file mode 100644
index 0000000..e69de29
diff --git a/.history/src/components/data_20240728171418.js b/.history/src/components/data_20240728171418.js
new file mode 100644
index 0000000..99d263b
--- /dev/null
+++ b/.history/src/components/data_20240728171418.js
@@ -0,0 +1,218 @@
+export const foundationChineseData = [
+ {
+ rank: '1',
+ name: 'apache/doris',
+ value: '4307.26',
+ rankDelta: 1,
+ valueDelta: +100,
+ },
+ {
+ rank: '2',
+ name: 'openharmony/docs',
+ value: '3277.69',
+ rankDelta: 0,
+ valueDelta: 0,
+ },
+ {
+ rank: '3',
+ name: 'openharmony/arkui_ace_engine',
+ value: '2818.09',
+ rankDelta: -1,
+ valueDelta: -3,
+ },
+ {
+ rank: '4',
+ name: 'milvus-io/milvus',
+ value: '2001.11',
+ rankDelta: 3,
+ valueDelta: -100,
+ },
+ {
+ rank: '5',
+ name: 'apache/flink',
+ value: '1816.72',
+ rankDelta: 0,
+ valueDelta: 0,
+ },
+ {
+ rank: '6',
+ name: 'apache/shardingsphere',
+ value: '1662.8',
+ rankDelta: 0,
+ valueDelta: 0,
+ },
+ {
+ rank: '7',
+ name: 'apache/ozone',
+ value: '1281.57',
+ rankDelta: 0,
+ valueDelta: 0,
+ },
+ {
+ rank: '8',
+ name: 'apache/iotdb',
+ value: '1265.72',
+ rankDelta: 0,
+ valueDelta: 0,
+ },
+ {
+ rank: '9',
+ name: 'openharmony/graphic_graphic_2d',
+ value: '1239.6',
+ rankDelta: 0,
+ valueDelta: 0,
+ },
+ {
+ rank: '10',
+ name: 'apache/pulsar',
+ value: '1227.93',
+ rankDelta: 0,
+ valueDelta: 0,
+ },
+ ]
+
+ export const foundationGlobalData = [
+ {
+ rank: '1',
+ name: 'kubernetes/kubernetes',
+ value: '5374.14',
+ rankDelta: 0,
+ valueDelta: 0,
+ },
+ {
+ rank: '2',
+ name: 'apache/doris',
+ value: '4307.26',
+ rankDelta: 2,
+ valueDelta: 3,
+ },
+ {
+ rank: '3',
+ name: 'apache/airflow',
+ value: '3642.9',
+ rankDelta: -1,
+ valueDelta: -3,
+ },
+ {
+ rank: '4',
+ name: 'openharmony/docs',
+ value: '3277.69',
+ rankDelta: 0,
+ valueDelta: 0,
+ },
+ {
+ rank: '5',
+ name: 'openharmony/arkui_ace_engine',
+ value: '2818.09',
+ rankDelta: 0,
+ valueDelta: 0,
+ },
+ {
+ rank: '6',
+ name: 'nodejs/node',
+ value: '2736.37',
+ rankDelta: 0,
+ valueDelta: 0,
+ },
+ {
+ rank: '7',
+ name: 'apache/spark',
+ value: '2654.02',
+ rankDelta: 0,
+ valueDelta: 0,
+ },
+ {
+ rank: '8',
+ name: 'apache/arrow',
+ value: '2219.95',
+ rankDelta: 0,
+ valueDelta: 0,
+ },
+ {
+ rank: '9',
+ name: 'apache/beam',
+ value: '2188.52',
+ rankDelta: 0,
+ valueDelta: 0,
+ },
+ {
+ rank: '10',
+ name: 'apache/hudi',
+ value: '2124.67',
+ rankDelta: 0,
+ valueDelta: 0,
+ },
+ ]
+
+ export const cloudNative = [
+ {
+ rank: '1',
+ name: 'grafana/grafana',
+ value: '7134.37',
+ rankDelta: 1,
+ valueDelta: 100,
+ },
+ {
+ rank: '2',
+ name: 'llvm/llvm-project',
+ value: '7049.62',
+ rankDelta: -2,
+ valueDelta: -220,
+ },
+ {
+ rank: '3',
+ name: 'kubernetes/kubernetes',
+ value: '5374.14',
+ rankDelta: 3,
+ valueDelta: 300,
+ },
+ {
+ rank: '4',
+ name: 'ClickHouse/ClickHouse',
+ value: '4941.99',
+ rankDelta: -4,
+ valueDelta: 400,
+ },
+ {
+ rank: '5',
+ name: 'cilium/cilium',
+ value: '3215.42',
+ rankDelta: 5,
+ valueDelta: -500,
+ },
+ {
+ rank: '6',
+ name: 'ceph/ceph',
+ value: '3172.49',
+ rankDelta: -6,
+ valueDelta: 600,
+ },
+ {
+ rank: '7',
+ name: 'keycloak/keycloak',
+ value: '3095.56',
+ rankDelta: 7,
+ valueDelta: 700,
+ },
+ {
+ rank: '8',
+ name: 'gravitational/teleport',
+ value: '3082.18',
+ rankDelta: 0,
+ valueDelta: 0,
+ },
+ {
+ rank: '9',
+ name: 'envoyproxy/envoy',
+ value: '2929.08',
+ rankDelta: 9,
+ valueDelta: -900,
+ },
+ {
+ rank: '10',
+ name: 'backstage/backstage',
+ value: '2903.39',
+ rankDelta: 10,
+ valueDelta: 100,
+ },
+ ]
\ No newline at end of file
diff --git a/.history/src/components/table_20240727221129.js b/.history/src/components/table_20240727221129.js
new file mode 100644
index 0000000..2c4f26f
--- /dev/null
+++ b/.history/src/components/table_20240727221129.js
@@ -0,0 +1,1319 @@
+import React, { useState, useEffect } from 'react';
+import { Col, message, Row, Table, Card } from 'antd';
+import MyAvatar from './avatar';
+import 'antd/dist/antd.css';
+import QAmiss from './QA2';
+import TablePanel from './TablePanel';
+import ArrowRender from './arrow';
+import PointRender from './changeNumber';
+import RoundFloat from './resolveFloat';
+import Trophy from './rankTrophy';
+import expandObject from '../util/expandObject';
+import { t } from 'i18next';
+import './table.css';
+
+const activityColumns = (object, t_month) => [
+ {
+ title: t('rank'),
+ dataIndex: 'rank',
+ width: '5%',
+ align: 'center',
+ render: Trophy,
+ fixed: 'left',
+ },
+ ...(object == 'actor'
+ ? [
+ {
+ title: t('avatar'),
+ dataIndex: 'id',
+ width: '5%',
+ align: 'center',
+ render: MyAvatar,
+ fixed: 'left',
+ },
+ ]
+ : []),
+ {
+ title: '',
+ dataIndex: 'rankDelta',
+ render: ArrowRender,
+ align: 'left',
+ width: '5%',
+ fixed: 'left',
+ },
+ {
+ title: t(object),
+ dataIndex: 'name',
+ align: 'center',
+ width: '20%',
+ render: function (text, row, index) {
+ if (object !== 'company') {
+ return (
+
+ {text}
+
+ );
+ } else {
+ return text;
+ }
+ },
+ },
+ ...(object == 'repo'
+ ? [
+ {
+ title: t('insight_board'),
+ dataIndex: 'name',
+ align: 'center',
+ width: '10%',
+ render: function (text, row, index) {
+ return dashboard(text, index, t_month);
+ },
+ },
+ ]
+ : []),
+ {
+ title: t('activity'),
+ dataIndex: 'value',
+ align: 'right',
+ width: '20%',
+ },
+ {
+ title: '',
+ dataIndex: 'valueDelta',
+ width: '10%',
+ align: 'left',
+ render: PointRender,
+ },
+];
+const activityDetailColumns = (object, t_month) => [
+ {
+ title: t('rank'),
+ dataIndex: 'rank',
+ width: '5%',
+ align: 'center',
+ render: Trophy,
+ fixed: 'left',
+ },
+ ...(object == 'actor'
+ ? [
+ {
+ title: t('avatar'),
+ dataIndex: 'id',
+ width: '5%',
+ align: 'center',
+ render: MyAvatar,
+ fixed: 'left',
+ },
+ ]
+ : []),
+ {
+ title: '',
+ dataIndex: 'rankDelta',
+ render: ArrowRender,
+ align: 'left',
+ width: '5%',
+ fixed: 'left',
+ },
+ {
+ title: t(object),
+ dataIndex: 'name',
+ align: 'center',
+ width: '5%',
+ render: function (text, row, index) {
+ if (object !== 'company') {
+ return (
+
+ {text}
+
+ );
+ } else {
+ return text;
+ }
+ },
+ },
+ ...(object == 'repo'
+ ? [
+ {
+ title: t('insight_board'),
+ dataIndex: 'name',
+ align: 'center',
+ width: '10%',
+ render: function (text, row, index) {
+ return dashboard(text, index, t_month);
+ },
+ },
+ ]
+ : []),
+ {
+ title: t('activity'),
+ dataIndex: 'value',
+ align: 'center',
+ width: '10%',
+ },
+ {
+ title: '',
+ dataIndex: 'valueDelta',
+ width: '10%',
+ align: 'left',
+ render: PointRender,
+ },
+ {
+ title: t('issue_comments'),
+ dataIndex: 'issue_comment',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('open_issues'),
+ dataIndex: 'open_issue',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('open_pulls'),
+ dataIndex: 'open_pull',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('merge_pulls'),
+ dataIndex: 'merged_pull',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('pr_reviews'),
+ dataIndex: 'review_comment',
+ width: '10%',
+ align: 'center',
+ },
+];
+const open_rankColumns = (object, t_month) => [
+ {
+ // 第一列:排名
+ title: t('rank'),
+ dataIndex: 'rank',
+ width: '5%',
+ render: Trophy,
+ align: 'center',
+ fixed: 'left',
+ },
+ // 如果 object 是 'actor',则添加头像列
+ ...(object == 'actor'
+ ? [
+ {
+ title: t('avatar'),
+ dataIndex: 'id',
+ width: '5%',
+ align: 'center',
+ render: MyAvatar,
+ fixed: 'left',
+ },
+ ]
+ : []),
+ // 第二列:排名变化
+ {
+ title: '',
+ dataIndex: 'rankDelta',
+ render: ArrowRender,
+ align: 'left',
+ width: '5%',
+ fixed: 'left',
+ },
+ // 第三列:对象名称(可能是 actor, repo 或 company)
+ {
+ title: t(object),
+ dataIndex: 'name',
+ width: '20%',
+ align: 'center',
+ render: function (text) {
+ if (object !== 'company') {
+ return (
+
+ {text}
+
+ );
+ } else {
+ return text;
+ }
+ },
+ },
+ // 如果 object 是 'repo',则添加 insight_board 列
+ ...(object == 'repo'
+ ? [
+ {
+ title: t('insight_board'),
+ dataIndex: 'name',
+ align: 'center',
+ width: '10%',
+ render: function (text, row, index) {
+ return dashboard(text, index, t_month);
+ },
+ },
+ ]
+ : []),
+ // 第四列:影响力
+ {
+ title: t('influence'),
+ dataIndex: 'value',
+ width: '20%',
+ align: 'right',
+ render: (text, row, index) => {
+ return RoundFloat(text);
+ },
+ },
+ // 第五列:影响力变化
+ {
+ title: '',
+ dataIndex: 'valueDelta',
+ width: '10%',
+ align: 'left',
+ render: (text, row, index) => {
+ text = RoundFloat(text);
+ return PointRender(text, row, index);
+ },
+ },
+];
+
+const solveDate = (year, month) => {
+ if (year === null && month === null) {
+ return 'not found';
+ }
+ if (month === null) {
+ return year + '年';
+ }
+ return year + '年' + (month + 1) + '月';
+};
+
+function dashboard(text, index, t_month) {
+ if (index < 300) {
+ let [org_name, repo_name] = text.split('/');
+ const t_month_copy = t_month + ' ' + '00:00:00';
+ let params = {
+ org_name,
+ repo_name,
+ t_month_copy,
+ t_month,
+ };
+ return (
+
+
+
+ );
+ }
+}
+
+function DateTitle(props) {
+ return
{solveDate(props.year, props.month)}
;
+}
+
+function MyTable(props) {
+ const [state, setState] = useState({
+ object: 'technology',
+ index: 'open_rank',
+ region: 'global',
+ showDetail: false,
+ hasDetail: true,
+ data: [],
+ showSize: 25,
+ loading: true,
+ url: '', // base + index + object + region + yearmonth + .json
+ base: 'https://oss.x-lab.info/open_leaderboard/',
+ year: null, // 字符串格式
+ month: null, // 整数格式,0表示1月,1表示2月..., null for year type time
+ type: 'month',
+ search: null,
+ category: 'cloud-native',
+ });
+
+ // 请求一次数据更新表格。如果还没读取好配置文件则不请求数据。
+ useEffect(() => {
+ if (props.year == null && props.month == null) {
+ console.log('the first loading');
+ return;
+ }
+ updateDate({
+ year: String(props.year),
+ month: props.month,
+ });
+ }, [props]);
+
+ const expandData = () => {
+ setState({
+ ...state,
+ showSize: state.showSize + 25,
+ });
+ };
+ const updateDate = (newstate) => {
+ console.log('table update', newstate);
+ // 先获取原先的表格属性
+ let {
+ base,
+ object,
+ index,
+ region,
+ month,
+ year,
+ columns,
+ showDetail,
+ hasDetail,
+ type,
+ search,
+ category,
+ } = state;
+ // 然后把表格改为加载中的状态
+ setState({ ...state, ...newstate, loading: true });
+ // 如果 newstate 有对应的属性,则进行更新
+ if (newstate.hasOwnProperty('object')) object = newstate.object;
+ if (newstate.hasOwnProperty('index')) index = newstate.index;
+ if (newstate.hasOwnProperty('region')) region = newstate.region;
+ if (newstate.hasOwnProperty('month')) month = newstate.month;
+ if (newstate.hasOwnProperty('year')) year = newstate.year;
+ if (newstate.hasOwnProperty('showDetail')) showDetail = newstate.showDetail;
+ if (newstate.hasOwnProperty('type')) type = newstate.type;
+ if (newstate.hasOwnProperty('search')) search = newstate.search;
+ if (newstate.hasOwnProperty('category')) category = newstate.category;
+
+ //获取数据大屏的‘t_month’参数
+ let myyear = newstate.year == null ? state.year : newstate.year;
+ let mymonth = newstate.month == null ? state.month : newstate.month;
+
+ mymonth = ('' + (1 + mymonth)).padStart(2, '0');
+ let t_month = `${myyear}-${mymonth}-01`;
+
+ // 根据 index 和 showDetail 改变表格的 columns 格式
+ if (index == 'activity') {
+ columns = activityColumns(object, t_month);
+ hasDetail = true;
+ }
+ if (index == 'activity' && showDetail == true) {
+ columns = activityDetailColumns(object, t_month);
+ hasDetail = true;
+ }
+ if (index == 'open_rank') {
+ columns = open_rankColumns(object, t_month);
+ hasDetail = false;
+ showDetail = false;
+ }
+ // 如果是年份数据,则把 month 置为 null。
+ // TODO:待验证,如果从年份数据切换到月份数据,似乎会自动回到原来 month 值?
+ if (type == 'year') {
+ month = null;
+ }
+ // 以当前的属性构造请求 url
+ let url = base + index + '/' + object + '/' + region + '/';
+ if (month === null) {
+ url += year + '.json';
+ } else {
+ url += year + (1 + month) + '.json';
+ }
+ console.log(url);
+ console.log(region);
+ if (object == 'foundation' && region == 'chinese') {
+ let data = new Array();
+ url = 'https://github.com/xiaoAugenstern/open-leadboard-data/blob/main/foundation.json'
+ // 预处理数据,对新上榜单数据进行特殊标记处理
+
+ data = data.data;
+ let dataSource = [];
+ data.map((obj) => {
+ obj = expandObject(obj);
+ if (obj.rankDelta == 0 && obj.value == obj.valueDelta) {
+ obj.rankDelta = -10000000;
+ obj.valueDelta = 0;
+ }
+ dataSource.push(obj);
+ });
+ console.log(dataSource);
+
+ // 更新属性和表格数据
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ showDetail: showDetail,
+ hasDetail: hasDetail,
+ data: dataSource,
+ });
+ } else if (object == 'foundation' && region == 'global') {
+ let data = new Array();
+ // 预处理数据,对新上榜单数据进行特殊标记处理
+ data = {
+ type: 'Foundation_China',
+ time: '2024',
+ data: [
+ {
+ rank: '1',
+ name: 'kubernetes/kubernetes',
+ value: '5374.14',
+ rankDelta: 0,
+ valueDelta: 0,
+ },
+ {
+ rank: '2',
+ name: 'apache/doris',
+ value: '4307.26',
+ rankDelta: 2,
+ valueDelta: 3,
+ },
+ {
+ rank: '3',
+ name: 'apache/airflow',
+ value: '3642.9',
+ rankDelta: -1,
+ valueDelta: -3,
+ },
+ {
+ rank: '4',
+ name: 'openharmony/docs',
+ value: '3277.69',
+ rankDelta: 0,
+ valueDelta: 0,
+ },
+ {
+ rank: '5',
+ name: 'openharmony/arkui_ace_engine',
+ value: '2818.09',
+ rankDelta: 0,
+ valueDelta: 0,
+ },
+ {
+ rank: '6',
+ name: 'nodejs/node',
+ value: '2736.37',
+ rankDelta: 0,
+ valueDelta: 0,
+ },
+ {
+ rank: '7',
+ name: 'apache/spark',
+ value: '2654.02',
+ rankDelta: 0,
+ valueDelta: 0,
+ },
+ {
+ rank: '8',
+ name: 'apache/arrow',
+ value: '2219.95',
+ rankDelta: 0,
+ valueDelta: 0,
+ },
+ {
+ rank: '9',
+ name: 'apache/beam',
+ value: '2188.52',
+ rankDelta: 0,
+ valueDelta: 0,
+ },
+ {
+ rank: '10',
+ name: 'apache/hudi',
+ value: '2124.67',
+ rankDelta: 0,
+ valueDelta: 0,
+ },
+ ],
+ };
+ data = data.data;
+ let dataSource = [];
+ data.map((obj) => {
+ obj = expandObject(obj);
+ if (obj.rankDelta == 0 && obj.value == obj.valueDelta) {
+ obj.rankDelta = -10000000;
+ obj.valueDelta = 0;
+ }
+ dataSource.push(obj);
+ });
+ console.log(dataSource);
+
+ // 更新属性和表格数据
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ showDetail: showDetail,
+ hasDetail: hasDetail,
+ data: dataSource,
+ });
+ } else if (object == 'technology' && category == 'cloud-native') {
+ let data = new Array();
+ // 预处理数据,对新上榜单数据进行特殊标记处理
+ data = {
+ type: 'Foundation_China',
+ time: '2024',
+ data: [
+ {
+ rank: '1',
+ name: 'grafana/grafana',
+ value: '7134.37',
+ rankDelta: 1,
+ valueDelta: 100,
+ },
+ {
+ rank: '2',
+ name: 'llvm/llvm-project',
+ value: '7049.62',
+ rankDelta: -2,
+ valueDelta: -220,
+ },
+ {
+ rank: '3',
+ name: 'kubernetes/kubernetes',
+ value: '5374.14',
+ rankDelta: 3,
+ valueDelta: 300,
+ },
+ {
+ rank: '4',
+ name: 'ClickHouse/ClickHouse',
+ value: '4941.99',
+ rankDelta: -4,
+ valueDelta: 400,
+ },
+ {
+ rank: '5',
+ name: 'cilium/cilium',
+ value: '3215.42',
+ rankDelta: 5,
+ valueDelta: -500,
+ },
+ {
+ rank: '6',
+ name: 'ceph/ceph',
+ value: '3172.49',
+ rankDelta: -6,
+ valueDelta: 600,
+ },
+ {
+ rank: '7',
+ name: 'keycloak/keycloak',
+ value: '3095.56',
+ rankDelta: 7,
+ valueDelta: 700,
+ },
+ {
+ rank: '8',
+ name: 'gravitational/teleport',
+ value: '3082.18',
+ rankDelta: 0,
+ valueDelta: 0,
+ },
+ {
+ rank: '9',
+ name: 'envoyproxy/envoy',
+ value: '2929.08',
+ rankDelta: 9,
+ valueDelta: -900,
+ },
+ {
+ rank: '10',
+ name: 'backstage/backstage',
+ value: '2903.39',
+ rankDelta: 10,
+ valueDelta: 100,
+ },
+ ],
+ };
+ data = data.data;
+ let dataSource = [];
+ data.map((obj) => {
+ obj = expandObject(obj);
+ if (obj.rankDelta == 0 && obj.value == obj.valueDelta) {
+ obj.rankDelta = -10000000;
+ obj.valueDelta = 0;
+ }
+ dataSource.push(obj);
+ });
+ console.log(dataSource);
+
+ // 更新属性和表格数据
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ showDetail: showDetail,
+ hasDetail: hasDetail,
+ data: dataSource,
+ });
+ } else if (object == 'technology' && category == 'ai') {
+ let data = new Array();
+ // 预处理数据,对新上榜单数据进行特殊标记处理
+ data = {
+ type: 'Foundation_China',
+ time: '2024',
+ data: [
+ {
+ rank: '1',
+ name: 'pytorch/pytorch',
+ value: '10182.45',
+ rankDelta: 0,
+ valueDelta: 0,
+ },
+ {
+ rank: '2',
+ name: 'langchain-ai/langchain',
+ value: '6080.25',
+ rankDelta: 0,
+ valueDelta: 0,
+ },
+ {
+ rank: '3',
+ name: 'PaddlePaddle/Paddle',
+ value: '5408.62',
+ rankDelta: 0,
+ valueDelta: 0,
+ },
+ {
+ rank: '4',
+ name: 'huggingface/transformers',
+ value: '4422.84',
+ rankDelta: 0,
+ valueDelta: 0,
+ },
+ {
+ rank: '5',
+ name: 'AUTOMATIC1111/stable-diffusion-webui',
+ value: '3881.6',
+ rankDelta: 0,
+ valueDelta: 0,
+ },
+ {
+ rank: '6',
+ name: 'openvinotoolkit/openvino',
+ value: '3857.31',
+ rankDelta: 0,
+ valueDelta: 0,
+ },
+ {
+ rank: '7',
+ name: 'microsoft/onnxruntime',
+ value: '3006.75',
+ rankDelta: 0,
+ valueDelta: 0,
+ },
+ {
+ rank: '8',
+ name: 'tensorflow/tensorflow',
+ value: '2723.26',
+ rankDelta: 0,
+ valueDelta: 0,
+ },
+ {
+ rank: '9',
+ name: 'Significant-Gravitas/AutoGPT',
+ value: '2664.85',
+ rankDelta: 0,
+ valueDelta: 0,
+ },
+ {
+ rank: '10',
+ name: 'ggerganov/llama.cpp',
+ value: '2339.8',
+ rankDelta: 0,
+ valueDelta: 0,
+ },
+ ],
+ };
+ data = data.data;
+ let dataSource = [];
+ data.map((obj) => {
+ obj = expandObject(obj);
+ if (obj.rankDelta == 0 && obj.value == obj.valueDelta) {
+ obj.rankDelta = -10000000;
+ obj.valueDelta = 0;
+ }
+ dataSource.push(obj);
+ });
+ console.log(dataSource);
+
+ // 更新属性和表格数据
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ showDetail: showDetail,
+ hasDetail: hasDetail,
+ data: dataSource,
+ });
+ } else if (object == 'technology' && category == 'big-data') {
+ let data = new Array();
+ // 预处理数据,对新上榜单数据进行特殊标记处理
+ data = {
+ type: 'Foundation_China',
+ time: '2024',
+ data: [
+ {
+ rank: '1',
+ name: 'elastic/kibana',
+ value: '7601.04',
+ rankDelta: 0,
+ valueDelta: 0,
+ },
+ {
+ rank: '2',
+ name: 'grafana/grafana',
+ value: '7134.37',
+ rankDelta: 0,
+ valueDelta: 0,
+ },
+ {
+ rank: '3',
+ name: 'ClickHouse/ClickHouse',
+ value: '4941.99',
+ rankDelta: 0,
+ valueDelta: 0,
+ },
+ {
+ rank: '4',
+ name: 'airbytehq/airbyte',
+ value: '4658.86',
+ rankDelta: 0,
+ valueDelta: 0,
+ },
+ {
+ rank: '5',
+ name: 'apache/doris',
+ value: '4307.26',
+ rankDelta: 0,
+ valueDelta: 0,
+ },
+ {
+ rank: '6',
+ name: 'elastic/elasticsearch',
+ value: '3729.39',
+ rankDelta: 0,
+ valueDelta: 0,
+ },
+ {
+ rank: '7',
+ name: 'apache/airflow',
+ value: '3642.9',
+ rankDelta: 0,
+ valueDelta: 0,
+ },
+ {
+ rank: '8',
+ name: 'StarRocks/starrocks',
+ value: '3194.56',
+ rankDelta: 0,
+ valueDelta: 0,
+ },
+ {
+ rank: '9',
+ name: 'trinodb/trino',
+ value: '2703.4',
+ rankDelta: 0,
+ valueDelta: 0,
+ },
+ {
+ rank: '10',
+ name: 'apache/spark',
+ value: '2654.02',
+ rankDelta: 0,
+ valueDelta: 0,
+ },
+ ],
+ };
+ data = data.data;
+ let dataSource = [];
+ data.map((obj) => {
+ obj = expandObject(obj);
+ if (obj.rankDelta == 0 && obj.value == obj.valueDelta) {
+ obj.rankDelta = -10000000;
+ obj.valueDelta = 0;
+ }
+ dataSource.push(obj);
+ });
+ console.log(dataSource);
+
+ // 更新属性和表格数据
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ showDetail: showDetail,
+ hasDetail: hasDetail,
+ data: dataSource,
+ });
+ } else if (object == 'technology' && category == 'database') {
+ let data = new Array();
+ // 预处理数据,对新上榜单数据进行特殊标记处理
+ data = {
+ type: 'Foundation_China',
+ time: '2024',
+ data: [
+ {
+ rank: '1',
+ name: 'ClickHouse/ClickHouse',
+ value: '4941.99',
+ rankDelta: 0,
+ valueDelta: 0,
+ },
+ {
+ rank: '2',
+ name: 'apache/doris',
+ value: '4307.26',
+ rankDelta: 0,
+ valueDelta: 0,
+ },
+ {
+ rank: '3',
+ name: 'elastic/elasticsearch',
+ value: '3729.39',
+ rankDelta: 0,
+ valueDelta: 0,
+ },
+ {
+ rank: '4',
+ name: 'cockroachdb/cockroach',
+ value: '3443.7',
+ rankDelta: 0,
+ valueDelta: 0,
+ },
+ {
+ rank: '5',
+ name: 'StarRocks/starrocks',
+ value: '3194.56',
+ rankDelta: 0,
+ valueDelta: 0,
+ },
+ {
+ rank: '6',
+ name: 'trinodb/trino',
+ value: '2703.4',
+ rankDelta: 0,
+ valueDelta: 0,
+ },
+ {
+ rank: '7',
+ name: 'apache/spark',
+ value: '2654.02',
+ rankDelta: 0,
+ valueDelta: 0,
+ },
+ {
+ rank: '8',
+ name: 'pingcap/tidb',
+ value: '2200.38',
+ rankDelta: 0,
+ valueDelta: 0,
+ },
+ {
+ rank: '9',
+ name: 'milvus-io/milvus',
+ value: '2001.11',
+ rankDelta: 0,
+ valueDelta: 0,
+ },
+ {
+ rank: '10',
+ name: 'yugabyte/yugabyte-db',
+ value: '1940.75',
+ rankDelta: 0,
+ valueDelta: 0,
+ },
+ ],
+ };
+ data = data.data;
+ let dataSource = [];
+ data.map((obj) => {
+ obj = expandObject(obj);
+ if (obj.rankDelta == 0 && obj.value == obj.valueDelta) {
+ obj.rankDelta = -10000000;
+ obj.valueDelta = 0;
+ }
+ dataSource.push(obj);
+ });
+ console.log(dataSource);
+ // 更新属性和表格数据
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ showDetail: showDetail,
+ hasDetail: hasDetail,
+ data: dataSource,
+ });
+ } else if (object == 'technology' && category == 'front-end') {
+ let data = new Array();
+ // 预处理数据,对新上榜单数据进行特殊标记处理
+ data = {
+ type: 'Foundation_China',
+ time: '2024',
+ data: [
+ {
+ rank: '1',
+ name: 'flutter/flutter',
+ value: '9361.81',
+ rankDelta: 0,
+ valueDelta: 0,
+ },
+ {
+ rank: '2',
+ name: 'vercel/next.js',
+ value: '6638.65',
+ rankDelta: 0,
+ valueDelta: 0,
+ },
+ {
+ rank: '3',
+ name: 'appsmithorg/appsmith',
+ value: '3474.07',
+ rankDelta: 0,
+ valueDelta: 0,
+ },
+ {
+ rank: '4',
+ name: 'nuxt/nuxt',
+ value: '3387.23',
+ rankDelta: 0,
+ valueDelta: 0,
+ },
+ {
+ rank: '5',
+ name: 'facebook/react-native',
+ value: '3260.55',
+ rankDelta: 0,
+ valueDelta: 0,
+ },
+ {
+ rank: '6',
+ name: 'ant-design/ant-design',
+ value: '3053.25',
+ rankDelta: 0,
+ valueDelta: 0,
+ },
+ {
+ rank: '7',
+ name: 'nodejs/node',
+ value: '2736.37',
+ rankDelta: 0,
+ valueDelta: 0,
+ },
+ {
+ rank: '8',
+ name: 'angular/angular',
+ value: '2273.82',
+ rankDelta: 0,
+ valueDelta: 0,
+ },
+ {
+ rank: '9',
+ name: 'electron/electron',
+ value: '1773.31',
+ rankDelta: 0,
+ valueDelta: 0,
+ },
+ {
+ rank: '10',
+ name: 'denoland/deno',
+ value: '1654.01',
+ rankDelta: 0,
+ valueDelta: 0,
+ },
+ ],
+ };
+ data = data.data;
+ let dataSource = [];
+ data.map((obj) => {
+ obj = expandObject(obj);
+ if (obj.rankDelta == 0 && obj.value == obj.valueDelta) {
+ obj.rankDelta = -10000000;
+ obj.valueDelta = 0;
+ }
+ dataSource.push(obj);
+ });
+ console.log(dataSource);
+
+ // 更新属性和表格数据
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ showDetail: showDetail,
+ hasDetail: hasDetail,
+ data: dataSource,
+ });
+ } else if (object == 'technology' && category == 'os') {
+ let data = new Array();
+ // 预处理数据,对新上榜单数据进行特殊标记处理
+ data = {
+ type: 'Foundation_China',
+ time: '2024',
+ data: [
+ {
+ rank: '1',
+ name: 'openharmony/docs',
+ value: '3277.69',
+ rankDelta: 0,
+ valueDelta: 0,
+ },
+ {
+ rank: '2',
+ name: 'openharmony/arkui_ace_engine',
+ value: '2818.09',
+ rankDelta: 0,
+ valueDelta: 0,
+ },
+ {
+ rank: '3',
+ name: 'SerenityOS/serenity',
+ value: '2257.68',
+ rankDelta: 0,
+ valueDelta: 0,
+ },
+ {
+ rank: '4',
+ name: 'openharmony/graphic_graphic_2d',
+ value: '1239.6',
+ rankDelta: 0,
+ valueDelta: 0,
+ },
+ {
+ rank: '5',
+ name: 'openeuler/docs',
+ value: '1206.9',
+ rankDelta: 0,
+ valueDelta: 0,
+ },
+ {
+ rank: '6',
+ name: 'openharmony/xts_acts',
+ value: '1186.06',
+ rankDelta: 0,
+ valueDelta: 0,
+ },
+ {
+ rank: '7',
+ name: 'openharmony/arkcompiler_ets_runtime',
+ value: '961.99',
+ rankDelta: 0,
+ valueDelta: 0,
+ },
+ {
+ rank: '8',
+ name: 'openharmony/interface_sdk-js',
+ value: '910.91',
+ rankDelta: 0,
+ valueDelta: 0,
+ },
+ {
+ rank: '9',
+ name: 'reactos/reactos',
+ value: '745.23',
+ rankDelta: 0,
+ valueDelta: 0,
+ },
+ {
+ rank: '10',
+ name: 'armbian/build',
+ value: '679.1',
+ rankDelta: 0,
+ valueDelta: 0,
+ },
+ ],
+ };
+ data = data.data;
+ let dataSource = [];
+ data.map((obj) => {
+ obj = expandObject(obj);
+ if (obj.rankDelta == 0 && obj.value == obj.valueDelta) {
+ obj.rankDelta = -10000000;
+ obj.valueDelta = 0;
+ }
+ dataSource.push(obj);
+ });
+ console.log(dataSource);
+
+ // 更新属性和表格数据
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ showDetail: showDetail,
+ hasDetail: hasDetail,
+ data: dataSource,
+ });
+ } else {
+ // fetch 异步请求
+ fetch(url)
+ .then((res) => {
+ // Todo:最好的情况是在日期选择器中,只显示可以查询的日期,
+ if (res.status == 404) {
+ message.warning(t('no_result'));
+ return '';
+ }
+ return res.json();
+ })
+ .then((data) => {
+ data = data.data;
+ let dataSource = [];
+ // 预处理数据,对新上榜单数据进行特殊标记处理
+ data.map((obj) => {
+ obj = expandObject(obj);
+ if (obj.rankDelta == 0 && obj.value == obj.valueDelta) {
+ obj.rankDelta = -10000000;
+ obj.valueDelta = 0;
+ }
+ dataSource.push(obj);
+ });
+ console.log(dataSource);
+
+ //搜索特定数据
+ let queryData;
+ if (search) {
+ queryData = dataSource.filter((dataSource) => {
+ let reg = new RegExp(search.trim(), 'i');
+ return reg.test(dataSource.name);
+ });
+ if (queryData.length == 0) {
+ message.warning(t('no_result'));
+ } else {
+ dataSource = queryData;
+ }
+ }
+
+ // 更新属性和表格数据
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ showDetail: showDetail,
+ hasDetail: hasDetail,
+ data: dataSource,
+ });
+ })
+ .catch((err) => {
+ console.log('hi!' + err);
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ data: [],
+ });
+ });
+ }
+ };
+
+ const {
+ object,
+ index,
+ region,
+ data,
+ columns,
+ loading,
+ showSize,
+ showDetail,
+ hasDetail,
+ month,
+ year,
+ type,
+ category,
+ } = state;
+ return (
+
+
+
+
+ record.rank}
+ dataSource={data.slice(0, Math.min(showSize, data.length))}
+ pagination={false}
+ loading={loading}
+ scroll={{ x: 'max-content' }}
+ />
+
+
+
+
+ {showSize < data.length ? (
+
+ {t('showMore') + '>>'}
+
+ ) : (
+
+ {t('noMore')}
+
+ )}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+}
+
+export default MyTable;
diff --git a/.history/src/components/table_20240727221246.js b/.history/src/components/table_20240727221246.js
new file mode 100644
index 0000000..6728cfe
--- /dev/null
+++ b/.history/src/components/table_20240727221246.js
@@ -0,0 +1,1297 @@
+import React, { useState, useEffect } from 'react';
+import { Col, message, Row, Table, Card } from 'antd';
+import MyAvatar from './avatar';
+import 'antd/dist/antd.css';
+import QAmiss from './QA2';
+import TablePanel from './TablePanel';
+import ArrowRender from './arrow';
+import PointRender from './changeNumber';
+import RoundFloat from './resolveFloat';
+import Trophy from './rankTrophy';
+import expandObject from '../util/expandObject';
+import { t } from 'i18next';
+import './table.css';
+
+const activityColumns = (object, t_month) => [
+ {
+ title: t('rank'),
+ dataIndex: 'rank',
+ width: '5%',
+ align: 'center',
+ render: Trophy,
+ fixed: 'left',
+ },
+ ...(object == 'actor'
+ ? [
+ {
+ title: t('avatar'),
+ dataIndex: 'id',
+ width: '5%',
+ align: 'center',
+ render: MyAvatar,
+ fixed: 'left',
+ },
+ ]
+ : []),
+ {
+ title: '',
+ dataIndex: 'rankDelta',
+ render: ArrowRender,
+ align: 'left',
+ width: '5%',
+ fixed: 'left',
+ },
+ {
+ title: t(object),
+ dataIndex: 'name',
+ align: 'center',
+ width: '20%',
+ render: function (text, row, index) {
+ if (object !== 'company') {
+ return (
+
+ {text}
+
+ );
+ } else {
+ return text;
+ }
+ },
+ },
+ ...(object == 'repo'
+ ? [
+ {
+ title: t('insight_board'),
+ dataIndex: 'name',
+ align: 'center',
+ width: '10%',
+ render: function (text, row, index) {
+ return dashboard(text, index, t_month);
+ },
+ },
+ ]
+ : []),
+ {
+ title: t('activity'),
+ dataIndex: 'value',
+ align: 'right',
+ width: '20%',
+ },
+ {
+ title: '',
+ dataIndex: 'valueDelta',
+ width: '10%',
+ align: 'left',
+ render: PointRender,
+ },
+];
+const activityDetailColumns = (object, t_month) => [
+ {
+ title: t('rank'),
+ dataIndex: 'rank',
+ width: '5%',
+ align: 'center',
+ render: Trophy,
+ fixed: 'left',
+ },
+ ...(object == 'actor'
+ ? [
+ {
+ title: t('avatar'),
+ dataIndex: 'id',
+ width: '5%',
+ align: 'center',
+ render: MyAvatar,
+ fixed: 'left',
+ },
+ ]
+ : []),
+ {
+ title: '',
+ dataIndex: 'rankDelta',
+ render: ArrowRender,
+ align: 'left',
+ width: '5%',
+ fixed: 'left',
+ },
+ {
+ title: t(object),
+ dataIndex: 'name',
+ align: 'center',
+ width: '5%',
+ render: function (text, row, index) {
+ if (object !== 'company') {
+ return (
+
+ {text}
+
+ );
+ } else {
+ return text;
+ }
+ },
+ },
+ ...(object == 'repo'
+ ? [
+ {
+ title: t('insight_board'),
+ dataIndex: 'name',
+ align: 'center',
+ width: '10%',
+ render: function (text, row, index) {
+ return dashboard(text, index, t_month);
+ },
+ },
+ ]
+ : []),
+ {
+ title: t('activity'),
+ dataIndex: 'value',
+ align: 'center',
+ width: '10%',
+ },
+ {
+ title: '',
+ dataIndex: 'valueDelta',
+ width: '10%',
+ align: 'left',
+ render: PointRender,
+ },
+ {
+ title: t('issue_comments'),
+ dataIndex: 'issue_comment',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('open_issues'),
+ dataIndex: 'open_issue',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('open_pulls'),
+ dataIndex: 'open_pull',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('merge_pulls'),
+ dataIndex: 'merged_pull',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('pr_reviews'),
+ dataIndex: 'review_comment',
+ width: '10%',
+ align: 'center',
+ },
+];
+const open_rankColumns = (object, t_month) => [
+ {
+ // 第一列:排名
+ title: t('rank'),
+ dataIndex: 'rank',
+ width: '5%',
+ render: Trophy,
+ align: 'center',
+ fixed: 'left',
+ },
+ // 如果 object 是 'actor',则添加头像列
+ ...(object == 'actor'
+ ? [
+ {
+ title: t('avatar'),
+ dataIndex: 'id',
+ width: '5%',
+ align: 'center',
+ render: MyAvatar,
+ fixed: 'left',
+ },
+ ]
+ : []),
+ // 第二列:排名变化
+ {
+ title: '',
+ dataIndex: 'rankDelta',
+ render: ArrowRender,
+ align: 'left',
+ width: '5%',
+ fixed: 'left',
+ },
+ // 第三列:对象名称(可能是 actor, repo 或 company)
+ {
+ title: t(object),
+ dataIndex: 'name',
+ width: '20%',
+ align: 'center',
+ render: function (text) {
+ if (object !== 'company') {
+ return (
+
+ {text}
+
+ );
+ } else {
+ return text;
+ }
+ },
+ },
+ // 如果 object 是 'repo',则添加 insight_board 列
+ ...(object == 'repo'
+ ? [
+ {
+ title: t('insight_board'),
+ dataIndex: 'name',
+ align: 'center',
+ width: '10%',
+ render: function (text, row, index) {
+ return dashboard(text, index, t_month);
+ },
+ },
+ ]
+ : []),
+ // 第四列:影响力
+ {
+ title: t('influence'),
+ dataIndex: 'value',
+ width: '20%',
+ align: 'right',
+ render: (text, row, index) => {
+ return RoundFloat(text);
+ },
+ },
+ // 第五列:影响力变化
+ {
+ title: '',
+ dataIndex: 'valueDelta',
+ width: '10%',
+ align: 'left',
+ render: (text, row, index) => {
+ text = RoundFloat(text);
+ return PointRender(text, row, index);
+ },
+ },
+];
+
+const solveDate = (year, month) => {
+ if (year === null && month === null) {
+ return 'not found';
+ }
+ if (month === null) {
+ return year + '年';
+ }
+ return year + '年' + (month + 1) + '月';
+};
+
+function dashboard(text, index, t_month) {
+ if (index < 300) {
+ let [org_name, repo_name] = text.split('/');
+ const t_month_copy = t_month + ' ' + '00:00:00';
+ let params = {
+ org_name,
+ repo_name,
+ t_month_copy,
+ t_month,
+ };
+ return (
+
+
+
+ );
+ }
+}
+
+function DateTitle(props) {
+ return {solveDate(props.year, props.month)}
;
+}
+
+function MyTable(props) {
+ const [state, setState] = useState({
+ object: 'technology',
+ index: 'open_rank',
+ region: 'global',
+ showDetail: false,
+ hasDetail: true,
+ data: [],
+ showSize: 25,
+ loading: true,
+ url: '', // base + index + object + region + yearmonth + .json
+ base: 'https://oss.x-lab.info/open_leaderboard/',
+ year: null, // 字符串格式
+ month: null, // 整数格式,0表示1月,1表示2月..., null for year type time
+ type: 'month',
+ search: null,
+ category: 'cloud-native',
+ });
+
+ // 请求一次数据更新表格。如果还没读取好配置文件则不请求数据。
+ useEffect(() => {
+ if (props.year == null && props.month == null) {
+ console.log('the first loading');
+ return;
+ }
+ updateDate({
+ year: String(props.year),
+ month: props.month,
+ });
+ }, [props]);
+
+ const expandData = () => {
+ setState({
+ ...state,
+ showSize: state.showSize + 25,
+ });
+ };
+ const updateDate = (newstate) => {
+ console.log('table update', newstate);
+ // 先获取原先的表格属性
+ let {
+ base,
+ object,
+ index,
+ region,
+ month,
+ year,
+ columns,
+ showDetail,
+ hasDetail,
+ type,
+ search,
+ category,
+ } = state;
+ // 然后把表格改为加载中的状态
+ setState({ ...state, ...newstate, loading: true });
+ // 如果 newstate 有对应的属性,则进行更新
+ if (newstate.hasOwnProperty('object')) object = newstate.object;
+ if (newstate.hasOwnProperty('index')) index = newstate.index;
+ if (newstate.hasOwnProperty('region')) region = newstate.region;
+ if (newstate.hasOwnProperty('month')) month = newstate.month;
+ if (newstate.hasOwnProperty('year')) year = newstate.year;
+ if (newstate.hasOwnProperty('showDetail')) showDetail = newstate.showDetail;
+ if (newstate.hasOwnProperty('type')) type = newstate.type;
+ if (newstate.hasOwnProperty('search')) search = newstate.search;
+ if (newstate.hasOwnProperty('category')) category = newstate.category;
+
+ //获取数据大屏的‘t_month’参数
+ let myyear = newstate.year == null ? state.year : newstate.year;
+ let mymonth = newstate.month == null ? state.month : newstate.month;
+
+ mymonth = ('' + (1 + mymonth)).padStart(2, '0');
+ let t_month = `${myyear}-${mymonth}-01`;
+
+ // 根据 index 和 showDetail 改变表格的 columns 格式
+ if (index == 'activity') {
+ columns = activityColumns(object, t_month);
+ hasDetail = true;
+ }
+ if (index == 'activity' && showDetail == true) {
+ columns = activityDetailColumns(object, t_month);
+ hasDetail = true;
+ }
+ if (index == 'open_rank') {
+ columns = open_rankColumns(object, t_month);
+ hasDetail = false;
+ showDetail = false;
+ }
+ // 如果是年份数据,则把 month 置为 null。
+ // TODO:待验证,如果从年份数据切换到月份数据,似乎会自动回到原来 month 值?
+ if (type == 'year') {
+ month = null;
+ }
+ // 以当前的属性构造请求 url
+ let url = base + index + '/' + object + '/' + region + '/';
+ if (month === null) {
+ url += year + '.json';
+ } else {
+ url += year + (1 + month) + '.json';
+ }
+ console.log(url);
+ console.log(region);
+ if (object == 'foundation' && region == 'chinese') {
+ let data = new Array();
+ url = 'https://github.com/xiaoAugenstern/open-leadboard-data/blob/main/foundation.json'
+ // 预处理数据,对新上榜单数据进行特殊标记处理
+
+ } else if (object == 'foundation' && region == 'global') {
+ let data = new Array();
+ // 预处理数据,对新上榜单数据进行特殊标记处理
+ data = {
+ type: 'Foundation_China',
+ time: '2024',
+ data: [
+ {
+ rank: '1',
+ name: 'kubernetes/kubernetes',
+ value: '5374.14',
+ rankDelta: 0,
+ valueDelta: 0,
+ },
+ {
+ rank: '2',
+ name: 'apache/doris',
+ value: '4307.26',
+ rankDelta: 2,
+ valueDelta: 3,
+ },
+ {
+ rank: '3',
+ name: 'apache/airflow',
+ value: '3642.9',
+ rankDelta: -1,
+ valueDelta: -3,
+ },
+ {
+ rank: '4',
+ name: 'openharmony/docs',
+ value: '3277.69',
+ rankDelta: 0,
+ valueDelta: 0,
+ },
+ {
+ rank: '5',
+ name: 'openharmony/arkui_ace_engine',
+ value: '2818.09',
+ rankDelta: 0,
+ valueDelta: 0,
+ },
+ {
+ rank: '6',
+ name: 'nodejs/node',
+ value: '2736.37',
+ rankDelta: 0,
+ valueDelta: 0,
+ },
+ {
+ rank: '7',
+ name: 'apache/spark',
+ value: '2654.02',
+ rankDelta: 0,
+ valueDelta: 0,
+ },
+ {
+ rank: '8',
+ name: 'apache/arrow',
+ value: '2219.95',
+ rankDelta: 0,
+ valueDelta: 0,
+ },
+ {
+ rank: '9',
+ name: 'apache/beam',
+ value: '2188.52',
+ rankDelta: 0,
+ valueDelta: 0,
+ },
+ {
+ rank: '10',
+ name: 'apache/hudi',
+ value: '2124.67',
+ rankDelta: 0,
+ valueDelta: 0,
+ },
+ ],
+ };
+ data = data.data;
+ let dataSource = [];
+ data.map((obj) => {
+ obj = expandObject(obj);
+ if (obj.rankDelta == 0 && obj.value == obj.valueDelta) {
+ obj.rankDelta = -10000000;
+ obj.valueDelta = 0;
+ }
+ dataSource.push(obj);
+ });
+ console.log(dataSource);
+
+ // 更新属性和表格数据
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ showDetail: showDetail,
+ hasDetail: hasDetail,
+ data: dataSource,
+ });
+ } else if (object == 'technology' && category == 'cloud-native') {
+ let data = new Array();
+ // 预处理数据,对新上榜单数据进行特殊标记处理
+ data = {
+ type: 'Foundation_China',
+ time: '2024',
+ data: [
+ {
+ rank: '1',
+ name: 'grafana/grafana',
+ value: '7134.37',
+ rankDelta: 1,
+ valueDelta: 100,
+ },
+ {
+ rank: '2',
+ name: 'llvm/llvm-project',
+ value: '7049.62',
+ rankDelta: -2,
+ valueDelta: -220,
+ },
+ {
+ rank: '3',
+ name: 'kubernetes/kubernetes',
+ value: '5374.14',
+ rankDelta: 3,
+ valueDelta: 300,
+ },
+ {
+ rank: '4',
+ name: 'ClickHouse/ClickHouse',
+ value: '4941.99',
+ rankDelta: -4,
+ valueDelta: 400,
+ },
+ {
+ rank: '5',
+ name: 'cilium/cilium',
+ value: '3215.42',
+ rankDelta: 5,
+ valueDelta: -500,
+ },
+ {
+ rank: '6',
+ name: 'ceph/ceph',
+ value: '3172.49',
+ rankDelta: -6,
+ valueDelta: 600,
+ },
+ {
+ rank: '7',
+ name: 'keycloak/keycloak',
+ value: '3095.56',
+ rankDelta: 7,
+ valueDelta: 700,
+ },
+ {
+ rank: '8',
+ name: 'gravitational/teleport',
+ value: '3082.18',
+ rankDelta: 0,
+ valueDelta: 0,
+ },
+ {
+ rank: '9',
+ name: 'envoyproxy/envoy',
+ value: '2929.08',
+ rankDelta: 9,
+ valueDelta: -900,
+ },
+ {
+ rank: '10',
+ name: 'backstage/backstage',
+ value: '2903.39',
+ rankDelta: 10,
+ valueDelta: 100,
+ },
+ ],
+ };
+ data = data.data;
+ let dataSource = [];
+ data.map((obj) => {
+ obj = expandObject(obj);
+ if (obj.rankDelta == 0 && obj.value == obj.valueDelta) {
+ obj.rankDelta = -10000000;
+ obj.valueDelta = 0;
+ }
+ dataSource.push(obj);
+ });
+ console.log(dataSource);
+
+ // 更新属性和表格数据
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ showDetail: showDetail,
+ hasDetail: hasDetail,
+ data: dataSource,
+ });
+ } else if (object == 'technology' && category == 'ai') {
+ let data = new Array();
+ // 预处理数据,对新上榜单数据进行特殊标记处理
+ data = {
+ type: 'Foundation_China',
+ time: '2024',
+ data: [
+ {
+ rank: '1',
+ name: 'pytorch/pytorch',
+ value: '10182.45',
+ rankDelta: 0,
+ valueDelta: 0,
+ },
+ {
+ rank: '2',
+ name: 'langchain-ai/langchain',
+ value: '6080.25',
+ rankDelta: 0,
+ valueDelta: 0,
+ },
+ {
+ rank: '3',
+ name: 'PaddlePaddle/Paddle',
+ value: '5408.62',
+ rankDelta: 0,
+ valueDelta: 0,
+ },
+ {
+ rank: '4',
+ name: 'huggingface/transformers',
+ value: '4422.84',
+ rankDelta: 0,
+ valueDelta: 0,
+ },
+ {
+ rank: '5',
+ name: 'AUTOMATIC1111/stable-diffusion-webui',
+ value: '3881.6',
+ rankDelta: 0,
+ valueDelta: 0,
+ },
+ {
+ rank: '6',
+ name: 'openvinotoolkit/openvino',
+ value: '3857.31',
+ rankDelta: 0,
+ valueDelta: 0,
+ },
+ {
+ rank: '7',
+ name: 'microsoft/onnxruntime',
+ value: '3006.75',
+ rankDelta: 0,
+ valueDelta: 0,
+ },
+ {
+ rank: '8',
+ name: 'tensorflow/tensorflow',
+ value: '2723.26',
+ rankDelta: 0,
+ valueDelta: 0,
+ },
+ {
+ rank: '9',
+ name: 'Significant-Gravitas/AutoGPT',
+ value: '2664.85',
+ rankDelta: 0,
+ valueDelta: 0,
+ },
+ {
+ rank: '10',
+ name: 'ggerganov/llama.cpp',
+ value: '2339.8',
+ rankDelta: 0,
+ valueDelta: 0,
+ },
+ ],
+ };
+ data = data.data;
+ let dataSource = [];
+ data.map((obj) => {
+ obj = expandObject(obj);
+ if (obj.rankDelta == 0 && obj.value == obj.valueDelta) {
+ obj.rankDelta = -10000000;
+ obj.valueDelta = 0;
+ }
+ dataSource.push(obj);
+ });
+ console.log(dataSource);
+
+ // 更新属性和表格数据
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ showDetail: showDetail,
+ hasDetail: hasDetail,
+ data: dataSource,
+ });
+ } else if (object == 'technology' && category == 'big-data') {
+ let data = new Array();
+ // 预处理数据,对新上榜单数据进行特殊标记处理
+ data = {
+ type: 'Foundation_China',
+ time: '2024',
+ data: [
+ {
+ rank: '1',
+ name: 'elastic/kibana',
+ value: '7601.04',
+ rankDelta: 0,
+ valueDelta: 0,
+ },
+ {
+ rank: '2',
+ name: 'grafana/grafana',
+ value: '7134.37',
+ rankDelta: 0,
+ valueDelta: 0,
+ },
+ {
+ rank: '3',
+ name: 'ClickHouse/ClickHouse',
+ value: '4941.99',
+ rankDelta: 0,
+ valueDelta: 0,
+ },
+ {
+ rank: '4',
+ name: 'airbytehq/airbyte',
+ value: '4658.86',
+ rankDelta: 0,
+ valueDelta: 0,
+ },
+ {
+ rank: '5',
+ name: 'apache/doris',
+ value: '4307.26',
+ rankDelta: 0,
+ valueDelta: 0,
+ },
+ {
+ rank: '6',
+ name: 'elastic/elasticsearch',
+ value: '3729.39',
+ rankDelta: 0,
+ valueDelta: 0,
+ },
+ {
+ rank: '7',
+ name: 'apache/airflow',
+ value: '3642.9',
+ rankDelta: 0,
+ valueDelta: 0,
+ },
+ {
+ rank: '8',
+ name: 'StarRocks/starrocks',
+ value: '3194.56',
+ rankDelta: 0,
+ valueDelta: 0,
+ },
+ {
+ rank: '9',
+ name: 'trinodb/trino',
+ value: '2703.4',
+ rankDelta: 0,
+ valueDelta: 0,
+ },
+ {
+ rank: '10',
+ name: 'apache/spark',
+ value: '2654.02',
+ rankDelta: 0,
+ valueDelta: 0,
+ },
+ ],
+ };
+ data = data.data;
+ let dataSource = [];
+ data.map((obj) => {
+ obj = expandObject(obj);
+ if (obj.rankDelta == 0 && obj.value == obj.valueDelta) {
+ obj.rankDelta = -10000000;
+ obj.valueDelta = 0;
+ }
+ dataSource.push(obj);
+ });
+ console.log(dataSource);
+
+ // 更新属性和表格数据
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ showDetail: showDetail,
+ hasDetail: hasDetail,
+ data: dataSource,
+ });
+ } else if (object == 'technology' && category == 'database') {
+ let data = new Array();
+ // 预处理数据,对新上榜单数据进行特殊标记处理
+ data = {
+ type: 'Foundation_China',
+ time: '2024',
+ data: [
+ {
+ rank: '1',
+ name: 'ClickHouse/ClickHouse',
+ value: '4941.99',
+ rankDelta: 0,
+ valueDelta: 0,
+ },
+ {
+ rank: '2',
+ name: 'apache/doris',
+ value: '4307.26',
+ rankDelta: 0,
+ valueDelta: 0,
+ },
+ {
+ rank: '3',
+ name: 'elastic/elasticsearch',
+ value: '3729.39',
+ rankDelta: 0,
+ valueDelta: 0,
+ },
+ {
+ rank: '4',
+ name: 'cockroachdb/cockroach',
+ value: '3443.7',
+ rankDelta: 0,
+ valueDelta: 0,
+ },
+ {
+ rank: '5',
+ name: 'StarRocks/starrocks',
+ value: '3194.56',
+ rankDelta: 0,
+ valueDelta: 0,
+ },
+ {
+ rank: '6',
+ name: 'trinodb/trino',
+ value: '2703.4',
+ rankDelta: 0,
+ valueDelta: 0,
+ },
+ {
+ rank: '7',
+ name: 'apache/spark',
+ value: '2654.02',
+ rankDelta: 0,
+ valueDelta: 0,
+ },
+ {
+ rank: '8',
+ name: 'pingcap/tidb',
+ value: '2200.38',
+ rankDelta: 0,
+ valueDelta: 0,
+ },
+ {
+ rank: '9',
+ name: 'milvus-io/milvus',
+ value: '2001.11',
+ rankDelta: 0,
+ valueDelta: 0,
+ },
+ {
+ rank: '10',
+ name: 'yugabyte/yugabyte-db',
+ value: '1940.75',
+ rankDelta: 0,
+ valueDelta: 0,
+ },
+ ],
+ };
+ data = data.data;
+ let dataSource = [];
+ data.map((obj) => {
+ obj = expandObject(obj);
+ if (obj.rankDelta == 0 && obj.value == obj.valueDelta) {
+ obj.rankDelta = -10000000;
+ obj.valueDelta = 0;
+ }
+ dataSource.push(obj);
+ });
+ console.log(dataSource);
+ // 更新属性和表格数据
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ showDetail: showDetail,
+ hasDetail: hasDetail,
+ data: dataSource,
+ });
+ } else if (object == 'technology' && category == 'front-end') {
+ let data = new Array();
+ // 预处理数据,对新上榜单数据进行特殊标记处理
+ data = {
+ type: 'Foundation_China',
+ time: '2024',
+ data: [
+ {
+ rank: '1',
+ name: 'flutter/flutter',
+ value: '9361.81',
+ rankDelta: 0,
+ valueDelta: 0,
+ },
+ {
+ rank: '2',
+ name: 'vercel/next.js',
+ value: '6638.65',
+ rankDelta: 0,
+ valueDelta: 0,
+ },
+ {
+ rank: '3',
+ name: 'appsmithorg/appsmith',
+ value: '3474.07',
+ rankDelta: 0,
+ valueDelta: 0,
+ },
+ {
+ rank: '4',
+ name: 'nuxt/nuxt',
+ value: '3387.23',
+ rankDelta: 0,
+ valueDelta: 0,
+ },
+ {
+ rank: '5',
+ name: 'facebook/react-native',
+ value: '3260.55',
+ rankDelta: 0,
+ valueDelta: 0,
+ },
+ {
+ rank: '6',
+ name: 'ant-design/ant-design',
+ value: '3053.25',
+ rankDelta: 0,
+ valueDelta: 0,
+ },
+ {
+ rank: '7',
+ name: 'nodejs/node',
+ value: '2736.37',
+ rankDelta: 0,
+ valueDelta: 0,
+ },
+ {
+ rank: '8',
+ name: 'angular/angular',
+ value: '2273.82',
+ rankDelta: 0,
+ valueDelta: 0,
+ },
+ {
+ rank: '9',
+ name: 'electron/electron',
+ value: '1773.31',
+ rankDelta: 0,
+ valueDelta: 0,
+ },
+ {
+ rank: '10',
+ name: 'denoland/deno',
+ value: '1654.01',
+ rankDelta: 0,
+ valueDelta: 0,
+ },
+ ],
+ };
+ data = data.data;
+ let dataSource = [];
+ data.map((obj) => {
+ obj = expandObject(obj);
+ if (obj.rankDelta == 0 && obj.value == obj.valueDelta) {
+ obj.rankDelta = -10000000;
+ obj.valueDelta = 0;
+ }
+ dataSource.push(obj);
+ });
+ console.log(dataSource);
+
+ // 更新属性和表格数据
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ showDetail: showDetail,
+ hasDetail: hasDetail,
+ data: dataSource,
+ });
+ } else if (object == 'technology' && category == 'os') {
+ let data = new Array();
+ // 预处理数据,对新上榜单数据进行特殊标记处理
+ data = {
+ type: 'Foundation_China',
+ time: '2024',
+ data: [
+ {
+ rank: '1',
+ name: 'openharmony/docs',
+ value: '3277.69',
+ rankDelta: 0,
+ valueDelta: 0,
+ },
+ {
+ rank: '2',
+ name: 'openharmony/arkui_ace_engine',
+ value: '2818.09',
+ rankDelta: 0,
+ valueDelta: 0,
+ },
+ {
+ rank: '3',
+ name: 'SerenityOS/serenity',
+ value: '2257.68',
+ rankDelta: 0,
+ valueDelta: 0,
+ },
+ {
+ rank: '4',
+ name: 'openharmony/graphic_graphic_2d',
+ value: '1239.6',
+ rankDelta: 0,
+ valueDelta: 0,
+ },
+ {
+ rank: '5',
+ name: 'openeuler/docs',
+ value: '1206.9',
+ rankDelta: 0,
+ valueDelta: 0,
+ },
+ {
+ rank: '6',
+ name: 'openharmony/xts_acts',
+ value: '1186.06',
+ rankDelta: 0,
+ valueDelta: 0,
+ },
+ {
+ rank: '7',
+ name: 'openharmony/arkcompiler_ets_runtime',
+ value: '961.99',
+ rankDelta: 0,
+ valueDelta: 0,
+ },
+ {
+ rank: '8',
+ name: 'openharmony/interface_sdk-js',
+ value: '910.91',
+ rankDelta: 0,
+ valueDelta: 0,
+ },
+ {
+ rank: '9',
+ name: 'reactos/reactos',
+ value: '745.23',
+ rankDelta: 0,
+ valueDelta: 0,
+ },
+ {
+ rank: '10',
+ name: 'armbian/build',
+ value: '679.1',
+ rankDelta: 0,
+ valueDelta: 0,
+ },
+ ],
+ };
+ data = data.data;
+ let dataSource = [];
+ data.map((obj) => {
+ obj = expandObject(obj);
+ if (obj.rankDelta == 0 && obj.value == obj.valueDelta) {
+ obj.rankDelta = -10000000;
+ obj.valueDelta = 0;
+ }
+ dataSource.push(obj);
+ });
+ console.log(dataSource);
+
+ // 更新属性和表格数据
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ showDetail: showDetail,
+ hasDetail: hasDetail,
+ data: dataSource,
+ });
+ }
+ // fetch 异步请求
+ fetch(url)
+ .then((res) => {
+ // Todo:最好的情况是在日期选择器中,只显示可以查询的日期,
+ if (res.status == 404) {
+ message.warning(t('no_result'));
+ return '';
+ }
+ return res.json();
+ })
+ .then((data) => {
+ data = data.data;
+ let dataSource = [];
+ // 预处理数据,对新上榜单数据进行特殊标记处理
+ data.map((obj) => {
+ obj = expandObject(obj);
+ if (obj.rankDelta == 0 && obj.value == obj.valueDelta) {
+ obj.rankDelta = -10000000;
+ obj.valueDelta = 0;
+ }
+ dataSource.push(obj);
+ });
+ console.log(dataSource);
+
+ //搜索特定数据
+ let queryData;
+ if (search) {
+ queryData = dataSource.filter((dataSource) => {
+ let reg = new RegExp(search.trim(), 'i');
+ return reg.test(dataSource.name);
+ });
+ if (queryData.length == 0) {
+ message.warning(t('no_result'));
+ } else {
+ dataSource = queryData;
+ }
+ }
+
+ // 更新属性和表格数据
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ showDetail: showDetail,
+ hasDetail: hasDetail,
+ data: dataSource,
+ });
+ })
+ .catch((err) => {
+ console.log('hi!' + err);
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ data: [],
+ });
+ });
+
+ };
+
+ const {
+ object,
+ index,
+ region,
+ data,
+ columns,
+ loading,
+ showSize,
+ showDetail,
+ hasDetail,
+ month,
+ year,
+ type,
+ category,
+ } = state;
+ return (
+
+
+
+
+ record.rank}
+ dataSource={data.slice(0, Math.min(showSize, data.length))}
+ pagination={false}
+ loading={loading}
+ scroll={{ x: 'max-content' }}
+ />
+
+
+
+
+ {showSize < data.length ? (
+
+ {t('showMore') + '>>'}
+
+ ) : (
+
+ {t('noMore')}
+
+ )}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+}
+
+export default MyTable;
diff --git a/.history/src/components/table_20240727224142.js b/.history/src/components/table_20240727224142.js
new file mode 100644
index 0000000..df163be
--- /dev/null
+++ b/.history/src/components/table_20240727224142.js
@@ -0,0 +1,653 @@
+import React, { useState, useEffect } from 'react';
+import { Col, message, Row, Table, Card } from 'antd';
+import MyAvatar from './avatar';
+import 'antd/dist/antd.css';
+import QAmiss from './QA2';
+import TablePanel from './TablePanel';
+import ArrowRender from './arrow';
+import PointRender from './changeNumber';
+import RoundFloat from './resolveFloat';
+import Trophy from './rankTrophy';
+import expandObject from '../util/expandObject';
+import { t } from 'i18next';
+import './table.css';
+
+const activityColumns = (object, t_month) => [
+ {
+ title: t('rank'),
+ dataIndex: 'rank',
+ width: '5%',
+ align: 'center',
+ render: Trophy,
+ fixed: 'left',
+ },
+ ...(object == 'actor'
+ ? [
+ {
+ title: t('avatar'),
+ dataIndex: 'id',
+ width: '5%',
+ align: 'center',
+ render: MyAvatar,
+ fixed: 'left',
+ },
+ ]
+ : []),
+ {
+ title: '',
+ dataIndex: 'rankDelta',
+ render: ArrowRender,
+ align: 'left',
+ width: '5%',
+ fixed: 'left',
+ },
+ {
+ title: t(object),
+ dataIndex: 'name',
+ align: 'center',
+ width: '20%',
+ render: function (text, row, index) {
+ if (object !== 'company') {
+ return (
+
+ {text}
+
+ );
+ } else {
+ return text;
+ }
+ },
+ },
+ ...(object == 'repo'
+ ? [
+ {
+ title: t('insight_board'),
+ dataIndex: 'name',
+ align: 'center',
+ width: '10%',
+ render: function (text, row, index) {
+ return dashboard(text, index, t_month);
+ },
+ },
+ ]
+ : []),
+ {
+ title: t('activity'),
+ dataIndex: 'value',
+ align: 'right',
+ width: '20%',
+ },
+ {
+ title: '',
+ dataIndex: 'valueDelta',
+ width: '10%',
+ align: 'left',
+ render: PointRender,
+ },
+];
+const activityDetailColumns = (object, t_month) => [
+ {
+ title: t('rank'),
+ dataIndex: 'rank',
+ width: '5%',
+ align: 'center',
+ render: Trophy,
+ fixed: 'left',
+ },
+ ...(object == 'actor'
+ ? [
+ {
+ title: t('avatar'),
+ dataIndex: 'id',
+ width: '5%',
+ align: 'center',
+ render: MyAvatar,
+ fixed: 'left',
+ },
+ ]
+ : []),
+ {
+ title: '',
+ dataIndex: 'rankDelta',
+ render: ArrowRender,
+ align: 'left',
+ width: '5%',
+ fixed: 'left',
+ },
+ {
+ title: t(object),
+ dataIndex: 'name',
+ align: 'center',
+ width: '5%',
+ render: function (text, row, index) {
+ if (object !== 'company') {
+ return (
+
+ {text}
+
+ );
+ } else {
+ return text;
+ }
+ },
+ },
+ ...(object == 'repo'
+ ? [
+ {
+ title: t('insight_board'),
+ dataIndex: 'name',
+ align: 'center',
+ width: '10%',
+ render: function (text, row, index) {
+ return dashboard(text, index, t_month);
+ },
+ },
+ ]
+ : []),
+ {
+ title: t('activity'),
+ dataIndex: 'value',
+ align: 'center',
+ width: '10%',
+ },
+ {
+ title: '',
+ dataIndex: 'valueDelta',
+ width: '10%',
+ align: 'left',
+ render: PointRender,
+ },
+ {
+ title: t('issue_comments'),
+ dataIndex: 'issue_comment',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('open_issues'),
+ dataIndex: 'open_issue',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('open_pulls'),
+ dataIndex: 'open_pull',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('merge_pulls'),
+ dataIndex: 'merged_pull',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('pr_reviews'),
+ dataIndex: 'review_comment',
+ width: '10%',
+ align: 'center',
+ },
+];
+const open_rankColumns = (object, t_month) => [
+ {
+ // 第一列:排名
+ title: t('rank'),
+ dataIndex: 'rank',
+ width: '5%',
+ render: Trophy,
+ align: 'center',
+ fixed: 'left',
+ },
+ // 如果 object 是 'actor',则添加头像列
+ ...(object == 'actor'
+ ? [
+ {
+ title: t('avatar'),
+ dataIndex: 'id',
+ width: '5%',
+ align: 'center',
+ render: MyAvatar,
+ fixed: 'left',
+ },
+ ]
+ : []),
+ // 第二列:排名变化
+ {
+ title: '',
+ dataIndex: 'rankDelta',
+ render: ArrowRender,
+ align: 'left',
+ width: '5%',
+ fixed: 'left',
+ },
+ // 第三列:对象名称(可能是 actor, repo 或 company)
+ {
+ title: t(object),
+ dataIndex: 'name',
+ width: '20%',
+ align: 'center',
+ render: function (text) {
+ if (object !== 'company') {
+ return (
+
+ {text}
+
+ );
+ } else {
+ return text;
+ }
+ },
+ },
+ // 如果 object 是 'repo',则添加 insight_board 列
+ ...(object == 'repo'
+ ? [
+ {
+ title: t('insight_board'),
+ dataIndex: 'name',
+ align: 'center',
+ width: '10%',
+ render: function (text, row, index) {
+ return dashboard(text, index, t_month);
+ },
+ },
+ ]
+ : []),
+ // 第四列:影响力
+ {
+ title: t('influence'),
+ dataIndex: 'value',
+ width: '20%',
+ align: 'right',
+ render: (text, row, index) => {
+ return RoundFloat(text);
+ },
+ },
+ // 第五列:影响力变化
+ {
+ title: '',
+ dataIndex: 'valueDelta',
+ width: '10%',
+ align: 'left',
+ render: (text, row, index) => {
+ text = RoundFloat(text);
+ return PointRender(text, row, index);
+ },
+ },
+];
+
+const solveDate = (year, month) => {
+ if (year === null && month === null) {
+ return 'not found';
+ }
+ if (month === null) {
+ return year + '年';
+ }
+ return year + '年' + (month + 1) + '月';
+};
+
+function dashboard(text, index, t_month) {
+ if (index < 300) {
+ let [org_name, repo_name] = text.split('/');
+ const t_month_copy = t_month + ' ' + '00:00:00';
+ let params = {
+ org_name,
+ repo_name,
+ t_month_copy,
+ t_month,
+ };
+ return (
+
+
+
+ );
+ }
+}
+
+function DateTitle(props) {
+ return {solveDate(props.year, props.month)}
;
+}
+
+function MyTable(props) {
+ const [state, setState] = useState({
+ object: 'technology',
+ index: 'open_rank',
+ region: 'global',
+ showDetail: false,
+ hasDetail: true,
+ data: [],
+ showSize: 25,
+ loading: true,
+ url: '', // base + index + object + region + yearmonth + .json
+ base: 'https://oss.x-lab.info/open_leaderboard/',
+ year: null, // 字符串格式
+ month: null, // 整数格式,0表示1月,1表示2月..., null for year type time
+ type: 'month',
+ search: null,
+ category: 'cloud-native',
+ });
+
+ // 请求一次数据更新表格。如果还没读取好配置文件则不请求数据。
+ useEffect(() => {
+ if (props.year == null && props.month == null) {
+ console.log('the first loading');
+ return;
+ }
+ updateDate({
+ year: String(props.year),
+ month: props.month,
+ });
+ }, [props]);
+
+ const expandData = () => {
+ setState({
+ ...state,
+ showSize: state.showSize + 25,
+ });
+ };
+ const updateDate = (newstate) => {
+ console.log('table update', newstate);
+ // 先获取原先的表格属性
+ let {
+ base,
+ object,
+ index,
+ region,
+ month,
+ year,
+ columns,
+ showDetail,
+ hasDetail,
+ type,
+ search,
+ category,
+ } = state;
+ // 然后把表格改为加载中的状态
+ setState({ ...state, ...newstate, loading: true });
+ // 如果 newstate 有对应的属性,则进行更新
+ if (newstate.hasOwnProperty('object')) object = newstate.object;
+ if (newstate.hasOwnProperty('index')) index = newstate.index;
+ if (newstate.hasOwnProperty('region')) region = newstate.region;
+ if (newstate.hasOwnProperty('month')) month = newstate.month;
+ if (newstate.hasOwnProperty('year')) year = newstate.year;
+ if (newstate.hasOwnProperty('showDetail')) showDetail = newstate.showDetail;
+ if (newstate.hasOwnProperty('type')) type = newstate.type;
+ if (newstate.hasOwnProperty('search')) search = newstate.search;
+ if (newstate.hasOwnProperty('category')) category = newstate.category;
+
+ //获取数据大屏的‘t_month’参数
+ let myyear = newstate.year == null ? state.year : newstate.year;
+ let mymonth = newstate.month == null ? state.month : newstate.month;
+
+ mymonth = ('' + (1 + mymonth)).padStart(2, '0');
+ let t_month = `${myyear}-${mymonth}-01`;
+
+ // 根据 index 和 showDetail 改变表格的 columns 格式
+ if (index == 'activity') {
+ columns = activityColumns(object, t_month);
+ hasDetail = true;
+ }
+ if (index == 'activity' && showDetail == true) {
+ columns = activityDetailColumns(object, t_month);
+ hasDetail = true;
+ }
+ if (index == 'open_rank') {
+ columns = open_rankColumns(object, t_month);
+ hasDetail = false;
+ showDetail = false;
+ }
+ // 如果是年份数据,则把 month 置为 null。
+ // TODO:待验证,如果从年份数据切换到月份数据,似乎会自动回到原来 month 值?
+ if (type == 'year') {
+ month = null;
+ }
+ // 以当前的属性构造请求 url
+ let url = base + index + '/' + object + '/' + region + '/';
+ if (month === null) {
+ url += year + '.json';
+ } else {
+ url += year + (1 + month) + '.json';
+ }
+ console.log(url);
+ console.log(region);
+ if (object == 'foundation' && region == 'chinese') {
+ url = 'https://github.com/xiaoAugenstern/open-leadboard-data/blob/main/foundation.json'
+ fetch(url, {
+ method: 'post', // 如果是get方式的话,只能把参数拼接在url里传过去,get方式不能有body
+ "Access-Control-Allow-Origin" : "*",
+ "Access-Control-Allow-Credentials" : true,
+ headers: {
+ 'Content-Type': 'application/json'
+ },})
+ .then((res) => {
+ // Todo:最好的情况是在日期选择器中,只显示可以查询的日期,
+ if (res.status == 404) {
+ message.warning(t('no_result'));
+ return '';
+ }
+ return res.json();
+ })
+ .then((data) => {
+ data = data.data;
+ let dataSource = [];
+ // 预处理数据,对新上榜单数据进行特殊标记处理
+ data.map((obj) => {
+ obj = expandObject(obj);
+ if (obj.rankDelta == 0 && obj.value == obj.valueDelta) {
+ obj.rankDelta = -10000000;
+ obj.valueDelta = 0;
+ }
+ dataSource.push(obj);
+ });
+ console.log(dataSource);
+
+ //搜索特定数据
+ let queryData;
+ if (search) {
+ queryData = dataSource.filter((dataSource) => {
+ let reg = new RegExp(search.trim(), 'i');
+ return reg.test(dataSource.name);
+ });
+ if (queryData.length == 0) {
+ message.warning(t('no_result'));
+ } else {
+ dataSource = queryData;
+ }
+ }
+
+ // 更新属性和表格数据
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ showDetail: showDetail,
+ hasDetail: hasDetail,
+ data: dataSource,
+ });
+ })
+ .catch((err) => {
+ console.log('hi!' + err);
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ data: [],
+ });
+ });
+ }
+ // fetch 异步请求
+ else{fetch(url)
+ .then((res) => {
+ // Todo:最好的情况是在日期选择器中,只显示可以查询的日期,
+ if (res.status == 404) {
+ message.warning(t('no_result'));
+ return '';
+ }
+ return res.json();
+ })
+ .then((data) => {
+ data = data.data;
+ let dataSource = [];
+ // 预处理数据,对新上榜单数据进行特殊标记处理
+ data.map((obj) => {
+ obj = expandObject(obj);
+ if (obj.rankDelta == 0 && obj.value == obj.valueDelta) {
+ obj.rankDelta = -10000000;
+ obj.valueDelta = 0;
+ }
+ dataSource.push(obj);
+ });
+ console.log(dataSource);
+
+ //搜索特定数据
+ let queryData;
+ if (search) {
+ queryData = dataSource.filter((dataSource) => {
+ let reg = new RegExp(search.trim(), 'i');
+ return reg.test(dataSource.name);
+ });
+ if (queryData.length == 0) {
+ message.warning(t('no_result'));
+ } else {
+ dataSource = queryData;
+ }
+ }
+
+ // 更新属性和表格数据
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ showDetail: showDetail,
+ hasDetail: hasDetail,
+ data: dataSource,
+ });
+ })
+ .catch((err) => {
+ console.log('hi!' + err);
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ data: [],
+ });
+ });
+ }
+
+ };
+
+ const {
+ object,
+ index,
+ region,
+ data,
+ columns,
+ loading,
+ showSize,
+ showDetail,
+ hasDetail,
+ month,
+ year,
+ type,
+ category,
+ } = state;
+ return (
+
+
+
+
+ record.rank}
+ dataSource={data.slice(0, Math.min(showSize, data.length))}
+ pagination={false}
+ loading={loading}
+ scroll={{ x: 'max-content' }}
+ />
+
+
+
+
+ {showSize < data.length ? (
+
+ {t('showMore') + '>>'}
+
+ ) : (
+
+ {t('noMore')}
+
+ )}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+}
+
+export default MyTable;
diff --git a/.history/src/components/table_20240727224145.js b/.history/src/components/table_20240727224145.js
new file mode 100644
index 0000000..df163be
--- /dev/null
+++ b/.history/src/components/table_20240727224145.js
@@ -0,0 +1,653 @@
+import React, { useState, useEffect } from 'react';
+import { Col, message, Row, Table, Card } from 'antd';
+import MyAvatar from './avatar';
+import 'antd/dist/antd.css';
+import QAmiss from './QA2';
+import TablePanel from './TablePanel';
+import ArrowRender from './arrow';
+import PointRender from './changeNumber';
+import RoundFloat from './resolveFloat';
+import Trophy from './rankTrophy';
+import expandObject from '../util/expandObject';
+import { t } from 'i18next';
+import './table.css';
+
+const activityColumns = (object, t_month) => [
+ {
+ title: t('rank'),
+ dataIndex: 'rank',
+ width: '5%',
+ align: 'center',
+ render: Trophy,
+ fixed: 'left',
+ },
+ ...(object == 'actor'
+ ? [
+ {
+ title: t('avatar'),
+ dataIndex: 'id',
+ width: '5%',
+ align: 'center',
+ render: MyAvatar,
+ fixed: 'left',
+ },
+ ]
+ : []),
+ {
+ title: '',
+ dataIndex: 'rankDelta',
+ render: ArrowRender,
+ align: 'left',
+ width: '5%',
+ fixed: 'left',
+ },
+ {
+ title: t(object),
+ dataIndex: 'name',
+ align: 'center',
+ width: '20%',
+ render: function (text, row, index) {
+ if (object !== 'company') {
+ return (
+
+ {text}
+
+ );
+ } else {
+ return text;
+ }
+ },
+ },
+ ...(object == 'repo'
+ ? [
+ {
+ title: t('insight_board'),
+ dataIndex: 'name',
+ align: 'center',
+ width: '10%',
+ render: function (text, row, index) {
+ return dashboard(text, index, t_month);
+ },
+ },
+ ]
+ : []),
+ {
+ title: t('activity'),
+ dataIndex: 'value',
+ align: 'right',
+ width: '20%',
+ },
+ {
+ title: '',
+ dataIndex: 'valueDelta',
+ width: '10%',
+ align: 'left',
+ render: PointRender,
+ },
+];
+const activityDetailColumns = (object, t_month) => [
+ {
+ title: t('rank'),
+ dataIndex: 'rank',
+ width: '5%',
+ align: 'center',
+ render: Trophy,
+ fixed: 'left',
+ },
+ ...(object == 'actor'
+ ? [
+ {
+ title: t('avatar'),
+ dataIndex: 'id',
+ width: '5%',
+ align: 'center',
+ render: MyAvatar,
+ fixed: 'left',
+ },
+ ]
+ : []),
+ {
+ title: '',
+ dataIndex: 'rankDelta',
+ render: ArrowRender,
+ align: 'left',
+ width: '5%',
+ fixed: 'left',
+ },
+ {
+ title: t(object),
+ dataIndex: 'name',
+ align: 'center',
+ width: '5%',
+ render: function (text, row, index) {
+ if (object !== 'company') {
+ return (
+
+ {text}
+
+ );
+ } else {
+ return text;
+ }
+ },
+ },
+ ...(object == 'repo'
+ ? [
+ {
+ title: t('insight_board'),
+ dataIndex: 'name',
+ align: 'center',
+ width: '10%',
+ render: function (text, row, index) {
+ return dashboard(text, index, t_month);
+ },
+ },
+ ]
+ : []),
+ {
+ title: t('activity'),
+ dataIndex: 'value',
+ align: 'center',
+ width: '10%',
+ },
+ {
+ title: '',
+ dataIndex: 'valueDelta',
+ width: '10%',
+ align: 'left',
+ render: PointRender,
+ },
+ {
+ title: t('issue_comments'),
+ dataIndex: 'issue_comment',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('open_issues'),
+ dataIndex: 'open_issue',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('open_pulls'),
+ dataIndex: 'open_pull',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('merge_pulls'),
+ dataIndex: 'merged_pull',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('pr_reviews'),
+ dataIndex: 'review_comment',
+ width: '10%',
+ align: 'center',
+ },
+];
+const open_rankColumns = (object, t_month) => [
+ {
+ // 第一列:排名
+ title: t('rank'),
+ dataIndex: 'rank',
+ width: '5%',
+ render: Trophy,
+ align: 'center',
+ fixed: 'left',
+ },
+ // 如果 object 是 'actor',则添加头像列
+ ...(object == 'actor'
+ ? [
+ {
+ title: t('avatar'),
+ dataIndex: 'id',
+ width: '5%',
+ align: 'center',
+ render: MyAvatar,
+ fixed: 'left',
+ },
+ ]
+ : []),
+ // 第二列:排名变化
+ {
+ title: '',
+ dataIndex: 'rankDelta',
+ render: ArrowRender,
+ align: 'left',
+ width: '5%',
+ fixed: 'left',
+ },
+ // 第三列:对象名称(可能是 actor, repo 或 company)
+ {
+ title: t(object),
+ dataIndex: 'name',
+ width: '20%',
+ align: 'center',
+ render: function (text) {
+ if (object !== 'company') {
+ return (
+
+ {text}
+
+ );
+ } else {
+ return text;
+ }
+ },
+ },
+ // 如果 object 是 'repo',则添加 insight_board 列
+ ...(object == 'repo'
+ ? [
+ {
+ title: t('insight_board'),
+ dataIndex: 'name',
+ align: 'center',
+ width: '10%',
+ render: function (text, row, index) {
+ return dashboard(text, index, t_month);
+ },
+ },
+ ]
+ : []),
+ // 第四列:影响力
+ {
+ title: t('influence'),
+ dataIndex: 'value',
+ width: '20%',
+ align: 'right',
+ render: (text, row, index) => {
+ return RoundFloat(text);
+ },
+ },
+ // 第五列:影响力变化
+ {
+ title: '',
+ dataIndex: 'valueDelta',
+ width: '10%',
+ align: 'left',
+ render: (text, row, index) => {
+ text = RoundFloat(text);
+ return PointRender(text, row, index);
+ },
+ },
+];
+
+const solveDate = (year, month) => {
+ if (year === null && month === null) {
+ return 'not found';
+ }
+ if (month === null) {
+ return year + '年';
+ }
+ return year + '年' + (month + 1) + '月';
+};
+
+function dashboard(text, index, t_month) {
+ if (index < 300) {
+ let [org_name, repo_name] = text.split('/');
+ const t_month_copy = t_month + ' ' + '00:00:00';
+ let params = {
+ org_name,
+ repo_name,
+ t_month_copy,
+ t_month,
+ };
+ return (
+
+
+
+ );
+ }
+}
+
+function DateTitle(props) {
+ return {solveDate(props.year, props.month)}
;
+}
+
+function MyTable(props) {
+ const [state, setState] = useState({
+ object: 'technology',
+ index: 'open_rank',
+ region: 'global',
+ showDetail: false,
+ hasDetail: true,
+ data: [],
+ showSize: 25,
+ loading: true,
+ url: '', // base + index + object + region + yearmonth + .json
+ base: 'https://oss.x-lab.info/open_leaderboard/',
+ year: null, // 字符串格式
+ month: null, // 整数格式,0表示1月,1表示2月..., null for year type time
+ type: 'month',
+ search: null,
+ category: 'cloud-native',
+ });
+
+ // 请求一次数据更新表格。如果还没读取好配置文件则不请求数据。
+ useEffect(() => {
+ if (props.year == null && props.month == null) {
+ console.log('the first loading');
+ return;
+ }
+ updateDate({
+ year: String(props.year),
+ month: props.month,
+ });
+ }, [props]);
+
+ const expandData = () => {
+ setState({
+ ...state,
+ showSize: state.showSize + 25,
+ });
+ };
+ const updateDate = (newstate) => {
+ console.log('table update', newstate);
+ // 先获取原先的表格属性
+ let {
+ base,
+ object,
+ index,
+ region,
+ month,
+ year,
+ columns,
+ showDetail,
+ hasDetail,
+ type,
+ search,
+ category,
+ } = state;
+ // 然后把表格改为加载中的状态
+ setState({ ...state, ...newstate, loading: true });
+ // 如果 newstate 有对应的属性,则进行更新
+ if (newstate.hasOwnProperty('object')) object = newstate.object;
+ if (newstate.hasOwnProperty('index')) index = newstate.index;
+ if (newstate.hasOwnProperty('region')) region = newstate.region;
+ if (newstate.hasOwnProperty('month')) month = newstate.month;
+ if (newstate.hasOwnProperty('year')) year = newstate.year;
+ if (newstate.hasOwnProperty('showDetail')) showDetail = newstate.showDetail;
+ if (newstate.hasOwnProperty('type')) type = newstate.type;
+ if (newstate.hasOwnProperty('search')) search = newstate.search;
+ if (newstate.hasOwnProperty('category')) category = newstate.category;
+
+ //获取数据大屏的‘t_month’参数
+ let myyear = newstate.year == null ? state.year : newstate.year;
+ let mymonth = newstate.month == null ? state.month : newstate.month;
+
+ mymonth = ('' + (1 + mymonth)).padStart(2, '0');
+ let t_month = `${myyear}-${mymonth}-01`;
+
+ // 根据 index 和 showDetail 改变表格的 columns 格式
+ if (index == 'activity') {
+ columns = activityColumns(object, t_month);
+ hasDetail = true;
+ }
+ if (index == 'activity' && showDetail == true) {
+ columns = activityDetailColumns(object, t_month);
+ hasDetail = true;
+ }
+ if (index == 'open_rank') {
+ columns = open_rankColumns(object, t_month);
+ hasDetail = false;
+ showDetail = false;
+ }
+ // 如果是年份数据,则把 month 置为 null。
+ // TODO:待验证,如果从年份数据切换到月份数据,似乎会自动回到原来 month 值?
+ if (type == 'year') {
+ month = null;
+ }
+ // 以当前的属性构造请求 url
+ let url = base + index + '/' + object + '/' + region + '/';
+ if (month === null) {
+ url += year + '.json';
+ } else {
+ url += year + (1 + month) + '.json';
+ }
+ console.log(url);
+ console.log(region);
+ if (object == 'foundation' && region == 'chinese') {
+ url = 'https://github.com/xiaoAugenstern/open-leadboard-data/blob/main/foundation.json'
+ fetch(url, {
+ method: 'post', // 如果是get方式的话,只能把参数拼接在url里传过去,get方式不能有body
+ "Access-Control-Allow-Origin" : "*",
+ "Access-Control-Allow-Credentials" : true,
+ headers: {
+ 'Content-Type': 'application/json'
+ },})
+ .then((res) => {
+ // Todo:最好的情况是在日期选择器中,只显示可以查询的日期,
+ if (res.status == 404) {
+ message.warning(t('no_result'));
+ return '';
+ }
+ return res.json();
+ })
+ .then((data) => {
+ data = data.data;
+ let dataSource = [];
+ // 预处理数据,对新上榜单数据进行特殊标记处理
+ data.map((obj) => {
+ obj = expandObject(obj);
+ if (obj.rankDelta == 0 && obj.value == obj.valueDelta) {
+ obj.rankDelta = -10000000;
+ obj.valueDelta = 0;
+ }
+ dataSource.push(obj);
+ });
+ console.log(dataSource);
+
+ //搜索特定数据
+ let queryData;
+ if (search) {
+ queryData = dataSource.filter((dataSource) => {
+ let reg = new RegExp(search.trim(), 'i');
+ return reg.test(dataSource.name);
+ });
+ if (queryData.length == 0) {
+ message.warning(t('no_result'));
+ } else {
+ dataSource = queryData;
+ }
+ }
+
+ // 更新属性和表格数据
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ showDetail: showDetail,
+ hasDetail: hasDetail,
+ data: dataSource,
+ });
+ })
+ .catch((err) => {
+ console.log('hi!' + err);
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ data: [],
+ });
+ });
+ }
+ // fetch 异步请求
+ else{fetch(url)
+ .then((res) => {
+ // Todo:最好的情况是在日期选择器中,只显示可以查询的日期,
+ if (res.status == 404) {
+ message.warning(t('no_result'));
+ return '';
+ }
+ return res.json();
+ })
+ .then((data) => {
+ data = data.data;
+ let dataSource = [];
+ // 预处理数据,对新上榜单数据进行特殊标记处理
+ data.map((obj) => {
+ obj = expandObject(obj);
+ if (obj.rankDelta == 0 && obj.value == obj.valueDelta) {
+ obj.rankDelta = -10000000;
+ obj.valueDelta = 0;
+ }
+ dataSource.push(obj);
+ });
+ console.log(dataSource);
+
+ //搜索特定数据
+ let queryData;
+ if (search) {
+ queryData = dataSource.filter((dataSource) => {
+ let reg = new RegExp(search.trim(), 'i');
+ return reg.test(dataSource.name);
+ });
+ if (queryData.length == 0) {
+ message.warning(t('no_result'));
+ } else {
+ dataSource = queryData;
+ }
+ }
+
+ // 更新属性和表格数据
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ showDetail: showDetail,
+ hasDetail: hasDetail,
+ data: dataSource,
+ });
+ })
+ .catch((err) => {
+ console.log('hi!' + err);
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ data: [],
+ });
+ });
+ }
+
+ };
+
+ const {
+ object,
+ index,
+ region,
+ data,
+ columns,
+ loading,
+ showSize,
+ showDetail,
+ hasDetail,
+ month,
+ year,
+ type,
+ category,
+ } = state;
+ return (
+
+
+
+
+ record.rank}
+ dataSource={data.slice(0, Math.min(showSize, data.length))}
+ pagination={false}
+ loading={loading}
+ scroll={{ x: 'max-content' }}
+ />
+
+
+
+
+ {showSize < data.length ? (
+
+ {t('showMore') + '>>'}
+
+ ) : (
+
+ {t('noMore')}
+
+ )}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+}
+
+export default MyTable;
diff --git a/.history/src/components/table_20240727224820.js b/.history/src/components/table_20240727224820.js
new file mode 100644
index 0000000..57eb0fa
--- /dev/null
+++ b/.history/src/components/table_20240727224820.js
@@ -0,0 +1,651 @@
+import React, { useState, useEffect } from 'react';
+import { Col, message, Row, Table, Card } from 'antd';
+import MyAvatar from './avatar';
+import 'antd/dist/antd.css';
+import QAmiss from './QA2';
+import TablePanel from './TablePanel';
+import ArrowRender from './arrow';
+import PointRender from './changeNumber';
+import RoundFloat from './resolveFloat';
+import Trophy from './rankTrophy';
+import expandObject from '../util/expandObject';
+import { t } from 'i18next';
+import './table.css';
+
+const activityColumns = (object, t_month) => [
+ {
+ title: t('rank'),
+ dataIndex: 'rank',
+ width: '5%',
+ align: 'center',
+ render: Trophy,
+ fixed: 'left',
+ },
+ ...(object == 'actor'
+ ? [
+ {
+ title: t('avatar'),
+ dataIndex: 'id',
+ width: '5%',
+ align: 'center',
+ render: MyAvatar,
+ fixed: 'left',
+ },
+ ]
+ : []),
+ {
+ title: '',
+ dataIndex: 'rankDelta',
+ render: ArrowRender,
+ align: 'left',
+ width: '5%',
+ fixed: 'left',
+ },
+ {
+ title: t(object),
+ dataIndex: 'name',
+ align: 'center',
+ width: '20%',
+ render: function (text, row, index) {
+ if (object !== 'company') {
+ return (
+
+ {text}
+
+ );
+ } else {
+ return text;
+ }
+ },
+ },
+ ...(object == 'repo'
+ ? [
+ {
+ title: t('insight_board'),
+ dataIndex: 'name',
+ align: 'center',
+ width: '10%',
+ render: function (text, row, index) {
+ return dashboard(text, index, t_month);
+ },
+ },
+ ]
+ : []),
+ {
+ title: t('activity'),
+ dataIndex: 'value',
+ align: 'right',
+ width: '20%',
+ },
+ {
+ title: '',
+ dataIndex: 'valueDelta',
+ width: '10%',
+ align: 'left',
+ render: PointRender,
+ },
+];
+const activityDetailColumns = (object, t_month) => [
+ {
+ title: t('rank'),
+ dataIndex: 'rank',
+ width: '5%',
+ align: 'center',
+ render: Trophy,
+ fixed: 'left',
+ },
+ ...(object == 'actor'
+ ? [
+ {
+ title: t('avatar'),
+ dataIndex: 'id',
+ width: '5%',
+ align: 'center',
+ render: MyAvatar,
+ fixed: 'left',
+ },
+ ]
+ : []),
+ {
+ title: '',
+ dataIndex: 'rankDelta',
+ render: ArrowRender,
+ align: 'left',
+ width: '5%',
+ fixed: 'left',
+ },
+ {
+ title: t(object),
+ dataIndex: 'name',
+ align: 'center',
+ width: '5%',
+ render: function (text, row, index) {
+ if (object !== 'company') {
+ return (
+
+ {text}
+
+ );
+ } else {
+ return text;
+ }
+ },
+ },
+ ...(object == 'repo'
+ ? [
+ {
+ title: t('insight_board'),
+ dataIndex: 'name',
+ align: 'center',
+ width: '10%',
+ render: function (text, row, index) {
+ return dashboard(text, index, t_month);
+ },
+ },
+ ]
+ : []),
+ {
+ title: t('activity'),
+ dataIndex: 'value',
+ align: 'center',
+ width: '10%',
+ },
+ {
+ title: '',
+ dataIndex: 'valueDelta',
+ width: '10%',
+ align: 'left',
+ render: PointRender,
+ },
+ {
+ title: t('issue_comments'),
+ dataIndex: 'issue_comment',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('open_issues'),
+ dataIndex: 'open_issue',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('open_pulls'),
+ dataIndex: 'open_pull',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('merge_pulls'),
+ dataIndex: 'merged_pull',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('pr_reviews'),
+ dataIndex: 'review_comment',
+ width: '10%',
+ align: 'center',
+ },
+];
+const open_rankColumns = (object, t_month) => [
+ {
+ // 第一列:排名
+ title: t('rank'),
+ dataIndex: 'rank',
+ width: '5%',
+ render: Trophy,
+ align: 'center',
+ fixed: 'left',
+ },
+ // 如果 object 是 'actor',则添加头像列
+ ...(object == 'actor'
+ ? [
+ {
+ title: t('avatar'),
+ dataIndex: 'id',
+ width: '5%',
+ align: 'center',
+ render: MyAvatar,
+ fixed: 'left',
+ },
+ ]
+ : []),
+ // 第二列:排名变化
+ {
+ title: '',
+ dataIndex: 'rankDelta',
+ render: ArrowRender,
+ align: 'left',
+ width: '5%',
+ fixed: 'left',
+ },
+ // 第三列:对象名称(可能是 actor, repo 或 company)
+ {
+ title: t(object),
+ dataIndex: 'name',
+ width: '20%',
+ align: 'center',
+ render: function (text) {
+ if (object !== 'company') {
+ return (
+
+ {text}
+
+ );
+ } else {
+ return text;
+ }
+ },
+ },
+ // 如果 object 是 'repo',则添加 insight_board 列
+ ...(object == 'repo'
+ ? [
+ {
+ title: t('insight_board'),
+ dataIndex: 'name',
+ align: 'center',
+ width: '10%',
+ render: function (text, row, index) {
+ return dashboard(text, index, t_month);
+ },
+ },
+ ]
+ : []),
+ // 第四列:影响力
+ {
+ title: t('influence'),
+ dataIndex: 'value',
+ width: '20%',
+ align: 'right',
+ render: (text, row, index) => {
+ return RoundFloat(text);
+ },
+ },
+ // 第五列:影响力变化
+ {
+ title: '',
+ dataIndex: 'valueDelta',
+ width: '10%',
+ align: 'left',
+ render: (text, row, index) => {
+ text = RoundFloat(text);
+ return PointRender(text, row, index);
+ },
+ },
+];
+
+const solveDate = (year, month) => {
+ if (year === null && month === null) {
+ return 'not found';
+ }
+ if (month === null) {
+ return year + '年';
+ }
+ return year + '年' + (month + 1) + '月';
+};
+
+function dashboard(text, index, t_month) {
+ if (index < 300) {
+ let [org_name, repo_name] = text.split('/');
+ const t_month_copy = t_month + ' ' + '00:00:00';
+ let params = {
+ org_name,
+ repo_name,
+ t_month_copy,
+ t_month,
+ };
+ return (
+
+
+
+ );
+ }
+}
+
+function DateTitle(props) {
+ return {solveDate(props.year, props.month)}
;
+}
+
+function MyTable(props) {
+ const [state, setState] = useState({
+ object: 'technology',
+ index: 'open_rank',
+ region: 'global',
+ showDetail: false,
+ hasDetail: true,
+ data: [],
+ showSize: 25,
+ loading: true,
+ url: '', // base + index + object + region + yearmonth + .json
+ base: 'https://oss.x-lab.info/open_leaderboard/',
+ year: null, // 字符串格式
+ month: null, // 整数格式,0表示1月,1表示2月..., null for year type time
+ type: 'month',
+ search: null,
+ category: 'cloud-native',
+ });
+
+ // 请求一次数据更新表格。如果还没读取好配置文件则不请求数据。
+ useEffect(() => {
+ if (props.year == null && props.month == null) {
+ console.log('the first loading');
+ return;
+ }
+ updateDate({
+ year: String(props.year),
+ month: props.month,
+ });
+ }, [props]);
+
+ const expandData = () => {
+ setState({
+ ...state,
+ showSize: state.showSize + 25,
+ });
+ };
+ const updateDate = (newstate) => {
+ console.log('table update', newstate);
+ // 先获取原先的表格属性
+ let {
+ base,
+ object,
+ index,
+ region,
+ month,
+ year,
+ columns,
+ showDetail,
+ hasDetail,
+ type,
+ search,
+ category,
+ } = state;
+ // 然后把表格改为加载中的状态
+ setState({ ...state, ...newstate, loading: true });
+ // 如果 newstate 有对应的属性,则进行更新
+ if (newstate.hasOwnProperty('object')) object = newstate.object;
+ if (newstate.hasOwnProperty('index')) index = newstate.index;
+ if (newstate.hasOwnProperty('region')) region = newstate.region;
+ if (newstate.hasOwnProperty('month')) month = newstate.month;
+ if (newstate.hasOwnProperty('year')) year = newstate.year;
+ if (newstate.hasOwnProperty('showDetail')) showDetail = newstate.showDetail;
+ if (newstate.hasOwnProperty('type')) type = newstate.type;
+ if (newstate.hasOwnProperty('search')) search = newstate.search;
+ if (newstate.hasOwnProperty('category')) category = newstate.category;
+
+ //获取数据大屏的‘t_month’参数
+ let myyear = newstate.year == null ? state.year : newstate.year;
+ let mymonth = newstate.month == null ? state.month : newstate.month;
+
+ mymonth = ('' + (1 + mymonth)).padStart(2, '0');
+ let t_month = `${myyear}-${mymonth}-01`;
+
+ // 根据 index 和 showDetail 改变表格的 columns 格式
+ if (index == 'activity') {
+ columns = activityColumns(object, t_month);
+ hasDetail = true;
+ }
+ if (index == 'activity' && showDetail == true) {
+ columns = activityDetailColumns(object, t_month);
+ hasDetail = true;
+ }
+ if (index == 'open_rank') {
+ columns = open_rankColumns(object, t_month);
+ hasDetail = false;
+ showDetail = false;
+ }
+ // 如果是年份数据,则把 month 置为 null。
+ // TODO:待验证,如果从年份数据切换到月份数据,似乎会自动回到原来 month 值?
+ if (type == 'year') {
+ month = null;
+ }
+ // 以当前的属性构造请求 url
+ let url = base + index + '/' + object + '/' + region + '/';
+ if (month === null) {
+ url += year + '.json';
+ } else {
+ url += year + (1 + month) + '.json';
+ }
+ console.log(url);
+ console.log(region);
+ if (object == 'foundation' && region == 'chinese') {
+ url = 'https://github.com/xiaoAugenstern/open-leadboard-data/blob/main/foundation.json'
+ fetch(url, {
+ "Access-Control-Allow-Origin" : "*",
+ "Access-Control-Allow-Credentials" : true,
+ mode: 'cors',
+ })
+ .then((res) => {
+ // Todo:最好的情况是在日期选择器中,只显示可以查询的日期,
+ if (res.status == 404) {
+ message.warning(t('no_result'));
+ return '';
+ }
+ return res.json();
+ })
+ .then((data) => {
+ data = data.data;
+ let dataSource = [];
+ // 预处理数据,对新上榜单数据进行特殊标记处理
+ data.map((obj) => {
+ obj = expandObject(obj);
+ if (obj.rankDelta == 0 && obj.value == obj.valueDelta) {
+ obj.rankDelta = -10000000;
+ obj.valueDelta = 0;
+ }
+ dataSource.push(obj);
+ });
+ console.log(dataSource);
+
+ //搜索特定数据
+ let queryData;
+ if (search) {
+ queryData = dataSource.filter((dataSource) => {
+ let reg = new RegExp(search.trim(), 'i');
+ return reg.test(dataSource.name);
+ });
+ if (queryData.length == 0) {
+ message.warning(t('no_result'));
+ } else {
+ dataSource = queryData;
+ }
+ }
+
+ // 更新属性和表格数据
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ showDetail: showDetail,
+ hasDetail: hasDetail,
+ data: dataSource,
+ });
+ })
+ .catch((err) => {
+ console.log('hi!' + err);
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ data: [],
+ });
+ });
+ }
+ // fetch 异步请求
+ else{fetch(url)
+ .then((res) => {
+ // Todo:最好的情况是在日期选择器中,只显示可以查询的日期,
+ if (res.status == 404) {
+ message.warning(t('no_result'));
+ return '';
+ }
+ return res.json();
+ })
+ .then((data) => {
+ data = data.data;
+ let dataSource = [];
+ // 预处理数据,对新上榜单数据进行特殊标记处理
+ data.map((obj) => {
+ obj = expandObject(obj);
+ if (obj.rankDelta == 0 && obj.value == obj.valueDelta) {
+ obj.rankDelta = -10000000;
+ obj.valueDelta = 0;
+ }
+ dataSource.push(obj);
+ });
+ console.log(dataSource);
+
+ //搜索特定数据
+ let queryData;
+ if (search) {
+ queryData = dataSource.filter((dataSource) => {
+ let reg = new RegExp(search.trim(), 'i');
+ return reg.test(dataSource.name);
+ });
+ if (queryData.length == 0) {
+ message.warning(t('no_result'));
+ } else {
+ dataSource = queryData;
+ }
+ }
+
+ // 更新属性和表格数据
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ showDetail: showDetail,
+ hasDetail: hasDetail,
+ data: dataSource,
+ });
+ })
+ .catch((err) => {
+ console.log('hi!' + err);
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ data: [],
+ });
+ });
+ }
+
+ };
+
+ const {
+ object,
+ index,
+ region,
+ data,
+ columns,
+ loading,
+ showSize,
+ showDetail,
+ hasDetail,
+ month,
+ year,
+ type,
+ category,
+ } = state;
+ return (
+
+
+
+
+ record.rank}
+ dataSource={data.slice(0, Math.min(showSize, data.length))}
+ pagination={false}
+ loading={loading}
+ scroll={{ x: 'max-content' }}
+ />
+
+
+
+
+ {showSize < data.length ? (
+
+ {t('showMore') + '>>'}
+
+ ) : (
+
+ {t('noMore')}
+
+ )}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+}
+
+export default MyTable;
diff --git a/.history/src/components/table_20240727225058.js b/.history/src/components/table_20240727225058.js
new file mode 100644
index 0000000..bbc6406
--- /dev/null
+++ b/.history/src/components/table_20240727225058.js
@@ -0,0 +1,651 @@
+import React, { useState, useEffect } from 'react';
+import { Col, message, Row, Table, Card } from 'antd';
+import MyAvatar from './avatar';
+import 'antd/dist/antd.css';
+import QAmiss from './QA2';
+import TablePanel from './TablePanel';
+import ArrowRender from './arrow';
+import PointRender from './changeNumber';
+import RoundFloat from './resolveFloat';
+import Trophy from './rankTrophy';
+import expandObject from '../util/expandObject';
+import { t } from 'i18next';
+import './table.css';
+
+const activityColumns = (object, t_month) => [
+ {
+ title: t('rank'),
+ dataIndex: 'rank',
+ width: '5%',
+ align: 'center',
+ render: Trophy,
+ fixed: 'left',
+ },
+ ...(object == 'actor'
+ ? [
+ {
+ title: t('avatar'),
+ dataIndex: 'id',
+ width: '5%',
+ align: 'center',
+ render: MyAvatar,
+ fixed: 'left',
+ },
+ ]
+ : []),
+ {
+ title: '',
+ dataIndex: 'rankDelta',
+ render: ArrowRender,
+ align: 'left',
+ width: '5%',
+ fixed: 'left',
+ },
+ {
+ title: t(object),
+ dataIndex: 'name',
+ align: 'center',
+ width: '20%',
+ render: function (text, row, index) {
+ if (object !== 'company') {
+ return (
+
+ {text}
+
+ );
+ } else {
+ return text;
+ }
+ },
+ },
+ ...(object == 'repo'
+ ? [
+ {
+ title: t('insight_board'),
+ dataIndex: 'name',
+ align: 'center',
+ width: '10%',
+ render: function (text, row, index) {
+ return dashboard(text, index, t_month);
+ },
+ },
+ ]
+ : []),
+ {
+ title: t('activity'),
+ dataIndex: 'value',
+ align: 'right',
+ width: '20%',
+ },
+ {
+ title: '',
+ dataIndex: 'valueDelta',
+ width: '10%',
+ align: 'left',
+ render: PointRender,
+ },
+];
+const activityDetailColumns = (object, t_month) => [
+ {
+ title: t('rank'),
+ dataIndex: 'rank',
+ width: '5%',
+ align: 'center',
+ render: Trophy,
+ fixed: 'left',
+ },
+ ...(object == 'actor'
+ ? [
+ {
+ title: t('avatar'),
+ dataIndex: 'id',
+ width: '5%',
+ align: 'center',
+ render: MyAvatar,
+ fixed: 'left',
+ },
+ ]
+ : []),
+ {
+ title: '',
+ dataIndex: 'rankDelta',
+ render: ArrowRender,
+ align: 'left',
+ width: '5%',
+ fixed: 'left',
+ },
+ {
+ title: t(object),
+ dataIndex: 'name',
+ align: 'center',
+ width: '5%',
+ render: function (text, row, index) {
+ if (object !== 'company') {
+ return (
+
+ {text}
+
+ );
+ } else {
+ return text;
+ }
+ },
+ },
+ ...(object == 'repo'
+ ? [
+ {
+ title: t('insight_board'),
+ dataIndex: 'name',
+ align: 'center',
+ width: '10%',
+ render: function (text, row, index) {
+ return dashboard(text, index, t_month);
+ },
+ },
+ ]
+ : []),
+ {
+ title: t('activity'),
+ dataIndex: 'value',
+ align: 'center',
+ width: '10%',
+ },
+ {
+ title: '',
+ dataIndex: 'valueDelta',
+ width: '10%',
+ align: 'left',
+ render: PointRender,
+ },
+ {
+ title: t('issue_comments'),
+ dataIndex: 'issue_comment',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('open_issues'),
+ dataIndex: 'open_issue',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('open_pulls'),
+ dataIndex: 'open_pull',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('merge_pulls'),
+ dataIndex: 'merged_pull',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('pr_reviews'),
+ dataIndex: 'review_comment',
+ width: '10%',
+ align: 'center',
+ },
+];
+const open_rankColumns = (object, t_month) => [
+ {
+ // 第一列:排名
+ title: t('rank'),
+ dataIndex: 'rank',
+ width: '5%',
+ render: Trophy,
+ align: 'center',
+ fixed: 'left',
+ },
+ // 如果 object 是 'actor',则添加头像列
+ ...(object == 'actor'
+ ? [
+ {
+ title: t('avatar'),
+ dataIndex: 'id',
+ width: '5%',
+ align: 'center',
+ render: MyAvatar,
+ fixed: 'left',
+ },
+ ]
+ : []),
+ // 第二列:排名变化
+ {
+ title: '',
+ dataIndex: 'rankDelta',
+ render: ArrowRender,
+ align: 'left',
+ width: '5%',
+ fixed: 'left',
+ },
+ // 第三列:对象名称(可能是 actor, repo 或 company)
+ {
+ title: t(object),
+ dataIndex: 'name',
+ width: '20%',
+ align: 'center',
+ render: function (text) {
+ if (object !== 'company') {
+ return (
+
+ {text}
+
+ );
+ } else {
+ return text;
+ }
+ },
+ },
+ // 如果 object 是 'repo',则添加 insight_board 列
+ ...(object == 'repo'
+ ? [
+ {
+ title: t('insight_board'),
+ dataIndex: 'name',
+ align: 'center',
+ width: '10%',
+ render: function (text, row, index) {
+ return dashboard(text, index, t_month);
+ },
+ },
+ ]
+ : []),
+ // 第四列:影响力
+ {
+ title: t('influence'),
+ dataIndex: 'value',
+ width: '20%',
+ align: 'right',
+ render: (text, row, index) => {
+ return RoundFloat(text);
+ },
+ },
+ // 第五列:影响力变化
+ {
+ title: '',
+ dataIndex: 'valueDelta',
+ width: '10%',
+ align: 'left',
+ render: (text, row, index) => {
+ text = RoundFloat(text);
+ return PointRender(text, row, index);
+ },
+ },
+];
+
+const solveDate = (year, month) => {
+ if (year === null && month === null) {
+ return 'not found';
+ }
+ if (month === null) {
+ return year + '年';
+ }
+ return year + '年' + (month + 1) + '月';
+};
+
+function dashboard(text, index, t_month) {
+ if (index < 300) {
+ let [org_name, repo_name] = text.split('/');
+ const t_month_copy = t_month + ' ' + '00:00:00';
+ let params = {
+ org_name,
+ repo_name,
+ t_month_copy,
+ t_month,
+ };
+ return (
+
+
+
+ );
+ }
+}
+
+function DateTitle(props) {
+ return {solveDate(props.year, props.month)}
;
+}
+
+function MyTable(props) {
+ const [state, setState] = useState({
+ object: 'technology',
+ index: 'open_rank',
+ region: 'global',
+ showDetail: false,
+ hasDetail: true,
+ data: [],
+ showSize: 25,
+ loading: true,
+ url: '', // base + index + object + region + yearmonth + .json
+ base: 'https://oss.x-lab.info/open_leaderboard/',
+ year: null, // 字符串格式
+ month: null, // 整数格式,0表示1月,1表示2月..., null for year type time
+ type: 'month',
+ search: null,
+ category: 'cloud-native',
+ });
+
+ // 请求一次数据更新表格。如果还没读取好配置文件则不请求数据。
+ useEffect(() => {
+ if (props.year == null && props.month == null) {
+ console.log('the first loading');
+ return;
+ }
+ updateDate({
+ year: String(props.year),
+ month: props.month,
+ });
+ }, [props]);
+
+ const expandData = () => {
+ setState({
+ ...state,
+ showSize: state.showSize + 25,
+ });
+ };
+ const updateDate = (newstate) => {
+ console.log('table update', newstate);
+ // 先获取原先的表格属性
+ let {
+ base,
+ object,
+ index,
+ region,
+ month,
+ year,
+ columns,
+ showDetail,
+ hasDetail,
+ type,
+ search,
+ category,
+ } = state;
+ // 然后把表格改为加载中的状态
+ setState({ ...state, ...newstate, loading: true });
+ // 如果 newstate 有对应的属性,则进行更新
+ if (newstate.hasOwnProperty('object')) object = newstate.object;
+ if (newstate.hasOwnProperty('index')) index = newstate.index;
+ if (newstate.hasOwnProperty('region')) region = newstate.region;
+ if (newstate.hasOwnProperty('month')) month = newstate.month;
+ if (newstate.hasOwnProperty('year')) year = newstate.year;
+ if (newstate.hasOwnProperty('showDetail')) showDetail = newstate.showDetail;
+ if (newstate.hasOwnProperty('type')) type = newstate.type;
+ if (newstate.hasOwnProperty('search')) search = newstate.search;
+ if (newstate.hasOwnProperty('category')) category = newstate.category;
+
+ //获取数据大屏的‘t_month’参数
+ let myyear = newstate.year == null ? state.year : newstate.year;
+ let mymonth = newstate.month == null ? state.month : newstate.month;
+
+ mymonth = ('' + (1 + mymonth)).padStart(2, '0');
+ let t_month = `${myyear}-${mymonth}-01`;
+
+ // 根据 index 和 showDetail 改变表格的 columns 格式
+ if (index == 'activity') {
+ columns = activityColumns(object, t_month);
+ hasDetail = true;
+ }
+ if (index == 'activity' && showDetail == true) {
+ columns = activityDetailColumns(object, t_month);
+ hasDetail = true;
+ }
+ if (index == 'open_rank') {
+ columns = open_rankColumns(object, t_month);
+ hasDetail = false;
+ showDetail = false;
+ }
+ // 如果是年份数据,则把 month 置为 null。
+ // TODO:待验证,如果从年份数据切换到月份数据,似乎会自动回到原来 month 值?
+ if (type == 'year') {
+ month = null;
+ }
+ // 以当前的属性构造请求 url
+ let url = base + index + '/' + object + '/' + region + '/';
+ if (month === null) {
+ url += year + '.json';
+ } else {
+ url += year + (1 + month) + '.json';
+ }
+ console.log(url);
+ console.log(region);
+ if (object == 'foundation' && region == 'chinese') {
+ url = 'https://github.com/xiaoAugenstern/open-leadboard-data/blob/main/foundation.json'
+ fetch(url, {
+ "Access-Control-Allow-Origin" : "*",
+ "Access-Control-Allow-Credentials" : true,
+ mode: "no-cors",
+ })
+ .then((res) => {
+ // Todo:最好的情况是在日期选择器中,只显示可以查询的日期,
+ if (res.status == 404) {
+ message.warning(t('no_result'));
+ return '';
+ }
+ return res.json();
+ })
+ .then((data) => {
+ data = data.data;
+ let dataSource = [];
+ // 预处理数据,对新上榜单数据进行特殊标记处理
+ data.map((obj) => {
+ obj = expandObject(obj);
+ if (obj.rankDelta == 0 && obj.value == obj.valueDelta) {
+ obj.rankDelta = -10000000;
+ obj.valueDelta = 0;
+ }
+ dataSource.push(obj);
+ });
+ console.log(dataSource);
+
+ //搜索特定数据
+ let queryData;
+ if (search) {
+ queryData = dataSource.filter((dataSource) => {
+ let reg = new RegExp(search.trim(), 'i');
+ return reg.test(dataSource.name);
+ });
+ if (queryData.length == 0) {
+ message.warning(t('no_result'));
+ } else {
+ dataSource = queryData;
+ }
+ }
+
+ // 更新属性和表格数据
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ showDetail: showDetail,
+ hasDetail: hasDetail,
+ data: dataSource,
+ });
+ })
+ .catch((err) => {
+ console.log('hi!' + err);
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ data: [],
+ });
+ });
+ }
+ // fetch 异步请求
+ else{fetch(url)
+ .then((res) => {
+ // Todo:最好的情况是在日期选择器中,只显示可以查询的日期,
+ if (res.status == 404) {
+ message.warning(t('no_result'));
+ return '';
+ }
+ return res.json();
+ })
+ .then((data) => {
+ data = data.data;
+ let dataSource = [];
+ // 预处理数据,对新上榜单数据进行特殊标记处理
+ data.map((obj) => {
+ obj = expandObject(obj);
+ if (obj.rankDelta == 0 && obj.value == obj.valueDelta) {
+ obj.rankDelta = -10000000;
+ obj.valueDelta = 0;
+ }
+ dataSource.push(obj);
+ });
+ console.log(dataSource);
+
+ //搜索特定数据
+ let queryData;
+ if (search) {
+ queryData = dataSource.filter((dataSource) => {
+ let reg = new RegExp(search.trim(), 'i');
+ return reg.test(dataSource.name);
+ });
+ if (queryData.length == 0) {
+ message.warning(t('no_result'));
+ } else {
+ dataSource = queryData;
+ }
+ }
+
+ // 更新属性和表格数据
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ showDetail: showDetail,
+ hasDetail: hasDetail,
+ data: dataSource,
+ });
+ })
+ .catch((err) => {
+ console.log('hi!' + err);
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ data: [],
+ });
+ });
+ }
+
+ };
+
+ const {
+ object,
+ index,
+ region,
+ data,
+ columns,
+ loading,
+ showSize,
+ showDetail,
+ hasDetail,
+ month,
+ year,
+ type,
+ category,
+ } = state;
+ return (
+
+
+
+
+ record.rank}
+ dataSource={data.slice(0, Math.min(showSize, data.length))}
+ pagination={false}
+ loading={loading}
+ scroll={{ x: 'max-content' }}
+ />
+
+
+
+
+ {showSize < data.length ? (
+
+ {t('showMore') + '>>'}
+
+ ) : (
+
+ {t('noMore')}
+
+ )}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+}
+
+export default MyTable;
diff --git a/.history/src/components/table_20240727225519.js b/.history/src/components/table_20240727225519.js
new file mode 100644
index 0000000..ec95856
--- /dev/null
+++ b/.history/src/components/table_20240727225519.js
@@ -0,0 +1,651 @@
+import React, { useState, useEffect } from 'react';
+import { Col, message, Row, Table, Card } from 'antd';
+import MyAvatar from './avatar';
+import 'antd/dist/antd.css';
+import QAmiss from './QA2';
+import TablePanel from './TablePanel';
+import ArrowRender from './arrow';
+import PointRender from './changeNumber';
+import RoundFloat from './resolveFloat';
+import Trophy from './rankTrophy';
+import expandObject from '../util/expandObject';
+import { t } from 'i18next';
+import './table.css';
+
+const activityColumns = (object, t_month) => [
+ {
+ title: t('rank'),
+ dataIndex: 'rank',
+ width: '5%',
+ align: 'center',
+ render: Trophy,
+ fixed: 'left',
+ },
+ ...(object == 'actor'
+ ? [
+ {
+ title: t('avatar'),
+ dataIndex: 'id',
+ width: '5%',
+ align: 'center',
+ render: MyAvatar,
+ fixed: 'left',
+ },
+ ]
+ : []),
+ {
+ title: '',
+ dataIndex: 'rankDelta',
+ render: ArrowRender,
+ align: 'left',
+ width: '5%',
+ fixed: 'left',
+ },
+ {
+ title: t(object),
+ dataIndex: 'name',
+ align: 'center',
+ width: '20%',
+ render: function (text, row, index) {
+ if (object !== 'company') {
+ return (
+
+ {text}
+
+ );
+ } else {
+ return text;
+ }
+ },
+ },
+ ...(object == 'repo'
+ ? [
+ {
+ title: t('insight_board'),
+ dataIndex: 'name',
+ align: 'center',
+ width: '10%',
+ render: function (text, row, index) {
+ return dashboard(text, index, t_month);
+ },
+ },
+ ]
+ : []),
+ {
+ title: t('activity'),
+ dataIndex: 'value',
+ align: 'right',
+ width: '20%',
+ },
+ {
+ title: '',
+ dataIndex: 'valueDelta',
+ width: '10%',
+ align: 'left',
+ render: PointRender,
+ },
+];
+const activityDetailColumns = (object, t_month) => [
+ {
+ title: t('rank'),
+ dataIndex: 'rank',
+ width: '5%',
+ align: 'center',
+ render: Trophy,
+ fixed: 'left',
+ },
+ ...(object == 'actor'
+ ? [
+ {
+ title: t('avatar'),
+ dataIndex: 'id',
+ width: '5%',
+ align: 'center',
+ render: MyAvatar,
+ fixed: 'left',
+ },
+ ]
+ : []),
+ {
+ title: '',
+ dataIndex: 'rankDelta',
+ render: ArrowRender,
+ align: 'left',
+ width: '5%',
+ fixed: 'left',
+ },
+ {
+ title: t(object),
+ dataIndex: 'name',
+ align: 'center',
+ width: '5%',
+ render: function (text, row, index) {
+ if (object !== 'company') {
+ return (
+
+ {text}
+
+ );
+ } else {
+ return text;
+ }
+ },
+ },
+ ...(object == 'repo'
+ ? [
+ {
+ title: t('insight_board'),
+ dataIndex: 'name',
+ align: 'center',
+ width: '10%',
+ render: function (text, row, index) {
+ return dashboard(text, index, t_month);
+ },
+ },
+ ]
+ : []),
+ {
+ title: t('activity'),
+ dataIndex: 'value',
+ align: 'center',
+ width: '10%',
+ },
+ {
+ title: '',
+ dataIndex: 'valueDelta',
+ width: '10%',
+ align: 'left',
+ render: PointRender,
+ },
+ {
+ title: t('issue_comments'),
+ dataIndex: 'issue_comment',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('open_issues'),
+ dataIndex: 'open_issue',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('open_pulls'),
+ dataIndex: 'open_pull',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('merge_pulls'),
+ dataIndex: 'merged_pull',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('pr_reviews'),
+ dataIndex: 'review_comment',
+ width: '10%',
+ align: 'center',
+ },
+];
+const open_rankColumns = (object, t_month) => [
+ {
+ // 第一列:排名
+ title: t('rank'),
+ dataIndex: 'rank',
+ width: '5%',
+ render: Trophy,
+ align: 'center',
+ fixed: 'left',
+ },
+ // 如果 object 是 'actor',则添加头像列
+ ...(object == 'actor'
+ ? [
+ {
+ title: t('avatar'),
+ dataIndex: 'id',
+ width: '5%',
+ align: 'center',
+ render: MyAvatar,
+ fixed: 'left',
+ },
+ ]
+ : []),
+ // 第二列:排名变化
+ {
+ title: '',
+ dataIndex: 'rankDelta',
+ render: ArrowRender,
+ align: 'left',
+ width: '5%',
+ fixed: 'left',
+ },
+ // 第三列:对象名称(可能是 actor, repo 或 company)
+ {
+ title: t(object),
+ dataIndex: 'name',
+ width: '20%',
+ align: 'center',
+ render: function (text) {
+ if (object !== 'company') {
+ return (
+
+ {text}
+
+ );
+ } else {
+ return text;
+ }
+ },
+ },
+ // 如果 object 是 'repo',则添加 insight_board 列
+ ...(object == 'repo'
+ ? [
+ {
+ title: t('insight_board'),
+ dataIndex: 'name',
+ align: 'center',
+ width: '10%',
+ render: function (text, row, index) {
+ return dashboard(text, index, t_month);
+ },
+ },
+ ]
+ : []),
+ // 第四列:影响力
+ {
+ title: t('influence'),
+ dataIndex: 'value',
+ width: '20%',
+ align: 'right',
+ render: (text, row, index) => {
+ return RoundFloat(text);
+ },
+ },
+ // 第五列:影响力变化
+ {
+ title: '',
+ dataIndex: 'valueDelta',
+ width: '10%',
+ align: 'left',
+ render: (text, row, index) => {
+ text = RoundFloat(text);
+ return PointRender(text, row, index);
+ },
+ },
+];
+
+const solveDate = (year, month) => {
+ if (year === null && month === null) {
+ return 'not found';
+ }
+ if (month === null) {
+ return year + '年';
+ }
+ return year + '年' + (month + 1) + '月';
+};
+
+function dashboard(text, index, t_month) {
+ if (index < 300) {
+ let [org_name, repo_name] = text.split('/');
+ const t_month_copy = t_month + ' ' + '00:00:00';
+ let params = {
+ org_name,
+ repo_name,
+ t_month_copy,
+ t_month,
+ };
+ return (
+
+
+
+ );
+ }
+}
+
+function DateTitle(props) {
+ return {solveDate(props.year, props.month)}
;
+}
+
+function MyTable(props) {
+ const [state, setState] = useState({
+ object: 'technology',
+ index: 'open_rank',
+ region: 'global',
+ showDetail: false,
+ hasDetail: true,
+ data: [],
+ showSize: 25,
+ loading: true,
+ url: '', // base + index + object + region + yearmonth + .json
+ base: 'https://oss.x-lab.info/open_leaderboard/',
+ year: null, // 字符串格式
+ month: null, // 整数格式,0表示1月,1表示2月..., null for year type time
+ type: 'month',
+ search: null,
+ category: 'cloud-native',
+ });
+
+ // 请求一次数据更新表格。如果还没读取好配置文件则不请求数据。
+ useEffect(() => {
+ if (props.year == null && props.month == null) {
+ console.log('the first loading');
+ return;
+ }
+ updateDate({
+ year: String(props.year),
+ month: props.month,
+ });
+ }, [props]);
+
+ const expandData = () => {
+ setState({
+ ...state,
+ showSize: state.showSize + 25,
+ });
+ };
+ const updateDate = (newstate) => {
+ console.log('table update', newstate);
+ // 先获取原先的表格属性
+ let {
+ base,
+ object,
+ index,
+ region,
+ month,
+ year,
+ columns,
+ showDetail,
+ hasDetail,
+ type,
+ search,
+ category,
+ } = state;
+ // 然后把表格改为加载中的状态
+ setState({ ...state, ...newstate, loading: true });
+ // 如果 newstate 有对应的属性,则进行更新
+ if (newstate.hasOwnProperty('object')) object = newstate.object;
+ if (newstate.hasOwnProperty('index')) index = newstate.index;
+ if (newstate.hasOwnProperty('region')) region = newstate.region;
+ if (newstate.hasOwnProperty('month')) month = newstate.month;
+ if (newstate.hasOwnProperty('year')) year = newstate.year;
+ if (newstate.hasOwnProperty('showDetail')) showDetail = newstate.showDetail;
+ if (newstate.hasOwnProperty('type')) type = newstate.type;
+ if (newstate.hasOwnProperty('search')) search = newstate.search;
+ if (newstate.hasOwnProperty('category')) category = newstate.category;
+
+ //获取数据大屏的‘t_month’参数
+ let myyear = newstate.year == null ? state.year : newstate.year;
+ let mymonth = newstate.month == null ? state.month : newstate.month;
+
+ mymonth = ('' + (1 + mymonth)).padStart(2, '0');
+ let t_month = `${myyear}-${mymonth}-01`;
+
+ // 根据 index 和 showDetail 改变表格的 columns 格式
+ if (index == 'activity') {
+ columns = activityColumns(object, t_month);
+ hasDetail = true;
+ }
+ if (index == 'activity' && showDetail == true) {
+ columns = activityDetailColumns(object, t_month);
+ hasDetail = true;
+ }
+ if (index == 'open_rank') {
+ columns = open_rankColumns(object, t_month);
+ hasDetail = false;
+ showDetail = false;
+ }
+ // 如果是年份数据,则把 month 置为 null。
+ // TODO:待验证,如果从年份数据切换到月份数据,似乎会自动回到原来 month 值?
+ if (type == 'year') {
+ month = null;
+ }
+ // 以当前的属性构造请求 url
+ let url = base + index + '/' + object + '/' + region + '/';
+ if (month === null) {
+ url += year + '.json';
+ } else {
+ url += year + (1 + month) + '.json';
+ }
+ console.log(url);
+ console.log(region);
+ if (object == 'foundation' && region == 'chinese') {
+ url = 'https://github.com/xiaoAugenstern/open-leadboard-data/blob/main/foundation.json'
+ fetch(url, {
+ "Access-Control-Allow-Origin" : "*",
+ "Access-Control-Allow-Credentials" : true,
+ mode: "cors",
+ })
+ .then((res) => {
+ // Todo:最好的情况是在日期选择器中,只显示可以查询的日期,
+ if (res.status == 404) {
+ message.warning(t('no_result'));
+ return '';
+ }
+ return res.json();
+ })
+ .then((data) => {
+ data = data.data;
+ let dataSource = [];
+ // 预处理数据,对新上榜单数据进行特殊标记处理
+ data.map((obj) => {
+ obj = expandObject(obj);
+ if (obj.rankDelta == 0 && obj.value == obj.valueDelta) {
+ obj.rankDelta = -10000000;
+ obj.valueDelta = 0;
+ }
+ dataSource.push(obj);
+ });
+ console.log(dataSource);
+
+ //搜索特定数据
+ let queryData;
+ if (search) {
+ queryData = dataSource.filter((dataSource) => {
+ let reg = new RegExp(search.trim(), 'i');
+ return reg.test(dataSource.name);
+ });
+ if (queryData.length == 0) {
+ message.warning(t('no_result'));
+ } else {
+ dataSource = queryData;
+ }
+ }
+
+ // 更新属性和表格数据
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ showDetail: showDetail,
+ hasDetail: hasDetail,
+ data: dataSource,
+ });
+ })
+ .catch((err) => {
+ console.log('hi!' + err);
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ data: [],
+ });
+ });
+ }
+ // fetch 异步请求
+ else{fetch(url)
+ .then((res) => {
+ // Todo:最好的情况是在日期选择器中,只显示可以查询的日期,
+ if (res.status == 404) {
+ message.warning(t('no_result'));
+ return '';
+ }
+ return res.json();
+ })
+ .then((data) => {
+ data = data.data;
+ let dataSource = [];
+ // 预处理数据,对新上榜单数据进行特殊标记处理
+ data.map((obj) => {
+ obj = expandObject(obj);
+ if (obj.rankDelta == 0 && obj.value == obj.valueDelta) {
+ obj.rankDelta = -10000000;
+ obj.valueDelta = 0;
+ }
+ dataSource.push(obj);
+ });
+ console.log(dataSource);
+
+ //搜索特定数据
+ let queryData;
+ if (search) {
+ queryData = dataSource.filter((dataSource) => {
+ let reg = new RegExp(search.trim(), 'i');
+ return reg.test(dataSource.name);
+ });
+ if (queryData.length == 0) {
+ message.warning(t('no_result'));
+ } else {
+ dataSource = queryData;
+ }
+ }
+
+ // 更新属性和表格数据
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ showDetail: showDetail,
+ hasDetail: hasDetail,
+ data: dataSource,
+ });
+ })
+ .catch((err) => {
+ console.log('hi!' + err);
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ data: [],
+ });
+ });
+ }
+
+ };
+
+ const {
+ object,
+ index,
+ region,
+ data,
+ columns,
+ loading,
+ showSize,
+ showDetail,
+ hasDetail,
+ month,
+ year,
+ type,
+ category,
+ } = state;
+ return (
+
+
+
+
+ record.rank}
+ dataSource={data.slice(0, Math.min(showSize, data.length))}
+ pagination={false}
+ loading={loading}
+ scroll={{ x: 'max-content' }}
+ />
+
+
+
+
+ {showSize < data.length ? (
+
+ {t('showMore') + '>>'}
+
+ ) : (
+
+ {t('noMore')}
+
+ )}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+}
+
+export default MyTable;
diff --git a/.history/src/components/table_20240727230659.js b/.history/src/components/table_20240727230659.js
new file mode 100644
index 0000000..74e7f63
--- /dev/null
+++ b/.history/src/components/table_20240727230659.js
@@ -0,0 +1,652 @@
+import React, { useState, useEffect } from 'react';
+import { Col, message, Row, Table, Card } from 'antd';
+import MyAvatar from './avatar';
+import 'antd/dist/antd.css';
+import QAmiss from './QA2';
+import TablePanel from './TablePanel';
+import ArrowRender from './arrow';
+import PointRender from './changeNumber';
+import RoundFloat from './resolveFloat';
+import Trophy from './rankTrophy';
+import expandObject from '../util/expandObject';
+import { t } from 'i18next';
+import './table.css';
+
+const activityColumns = (object, t_month) => [
+ {
+ title: t('rank'),
+ dataIndex: 'rank',
+ width: '5%',
+ align: 'center',
+ render: Trophy,
+ fixed: 'left',
+ },
+ ...(object == 'actor'
+ ? [
+ {
+ title: t('avatar'),
+ dataIndex: 'id',
+ width: '5%',
+ align: 'center',
+ render: MyAvatar,
+ fixed: 'left',
+ },
+ ]
+ : []),
+ {
+ title: '',
+ dataIndex: 'rankDelta',
+ render: ArrowRender,
+ align: 'left',
+ width: '5%',
+ fixed: 'left',
+ },
+ {
+ title: t(object),
+ dataIndex: 'name',
+ align: 'center',
+ width: '20%',
+ render: function (text, row, index) {
+ if (object !== 'company') {
+ return (
+
+ {text}
+
+ );
+ } else {
+ return text;
+ }
+ },
+ },
+ ...(object == 'repo'
+ ? [
+ {
+ title: t('insight_board'),
+ dataIndex: 'name',
+ align: 'center',
+ width: '10%',
+ render: function (text, row, index) {
+ return dashboard(text, index, t_month);
+ },
+ },
+ ]
+ : []),
+ {
+ title: t('activity'),
+ dataIndex: 'value',
+ align: 'right',
+ width: '20%',
+ },
+ {
+ title: '',
+ dataIndex: 'valueDelta',
+ width: '10%',
+ align: 'left',
+ render: PointRender,
+ },
+];
+const activityDetailColumns = (object, t_month) => [
+ {
+ title: t('rank'),
+ dataIndex: 'rank',
+ width: '5%',
+ align: 'center',
+ render: Trophy,
+ fixed: 'left',
+ },
+ ...(object == 'actor'
+ ? [
+ {
+ title: t('avatar'),
+ dataIndex: 'id',
+ width: '5%',
+ align: 'center',
+ render: MyAvatar,
+ fixed: 'left',
+ },
+ ]
+ : []),
+ {
+ title: '',
+ dataIndex: 'rankDelta',
+ render: ArrowRender,
+ align: 'left',
+ width: '5%',
+ fixed: 'left',
+ },
+ {
+ title: t(object),
+ dataIndex: 'name',
+ align: 'center',
+ width: '5%',
+ render: function (text, row, index) {
+ if (object !== 'company') {
+ return (
+
+ {text}
+
+ );
+ } else {
+ return text;
+ }
+ },
+ },
+ ...(object == 'repo'
+ ? [
+ {
+ title: t('insight_board'),
+ dataIndex: 'name',
+ align: 'center',
+ width: '10%',
+ render: function (text, row, index) {
+ return dashboard(text, index, t_month);
+ },
+ },
+ ]
+ : []),
+ {
+ title: t('activity'),
+ dataIndex: 'value',
+ align: 'center',
+ width: '10%',
+ },
+ {
+ title: '',
+ dataIndex: 'valueDelta',
+ width: '10%',
+ align: 'left',
+ render: PointRender,
+ },
+ {
+ title: t('issue_comments'),
+ dataIndex: 'issue_comment',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('open_issues'),
+ dataIndex: 'open_issue',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('open_pulls'),
+ dataIndex: 'open_pull',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('merge_pulls'),
+ dataIndex: 'merged_pull',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('pr_reviews'),
+ dataIndex: 'review_comment',
+ width: '10%',
+ align: 'center',
+ },
+];
+const open_rankColumns = (object, t_month) => [
+ {
+ // 第一列:排名
+ title: t('rank'),
+ dataIndex: 'rank',
+ width: '5%',
+ render: Trophy,
+ align: 'center',
+ fixed: 'left',
+ },
+ // 如果 object 是 'actor',则添加头像列
+ ...(object == 'actor'
+ ? [
+ {
+ title: t('avatar'),
+ dataIndex: 'id',
+ width: '5%',
+ align: 'center',
+ render: MyAvatar,
+ fixed: 'left',
+ },
+ ]
+ : []),
+ // 第二列:排名变化
+ {
+ title: '',
+ dataIndex: 'rankDelta',
+ render: ArrowRender,
+ align: 'left',
+ width: '5%',
+ fixed: 'left',
+ },
+ // 第三列:对象名称(可能是 actor, repo 或 company)
+ {
+ title: t(object),
+ dataIndex: 'name',
+ width: '20%',
+ align: 'center',
+ render: function (text) {
+ if (object !== 'company') {
+ return (
+
+ {text}
+
+ );
+ } else {
+ return text;
+ }
+ },
+ },
+ // 如果 object 是 'repo',则添加 insight_board 列
+ ...(object == 'repo'
+ ? [
+ {
+ title: t('insight_board'),
+ dataIndex: 'name',
+ align: 'center',
+ width: '10%',
+ render: function (text, row, index) {
+ return dashboard(text, index, t_month);
+ },
+ },
+ ]
+ : []),
+ // 第四列:影响力
+ {
+ title: t('influence'),
+ dataIndex: 'value',
+ width: '20%',
+ align: 'right',
+ render: (text, row, index) => {
+ return RoundFloat(text);
+ },
+ },
+ // 第五列:影响力变化
+ {
+ title: '',
+ dataIndex: 'valueDelta',
+ width: '10%',
+ align: 'left',
+ render: (text, row, index) => {
+ text = RoundFloat(text);
+ return PointRender(text, row, index);
+ },
+ },
+];
+
+const solveDate = (year, month) => {
+ if (year === null && month === null) {
+ return 'not found';
+ }
+ if (month === null) {
+ return year + '年';
+ }
+ return year + '年' + (month + 1) + '月';
+};
+
+function dashboard(text, index, t_month) {
+ if (index < 300) {
+ let [org_name, repo_name] = text.split('/');
+ const t_month_copy = t_month + ' ' + '00:00:00';
+ let params = {
+ org_name,
+ repo_name,
+ t_month_copy,
+ t_month,
+ };
+ return (
+
+
+
+ );
+ }
+}
+
+function DateTitle(props) {
+ return {solveDate(props.year, props.month)}
;
+}
+
+function MyTable(props) {
+ const [state, setState] = useState({
+ object: 'technology',
+ index: 'open_rank',
+ region: 'global',
+ showDetail: false,
+ hasDetail: true,
+ data: [],
+ showSize: 25,
+ loading: true,
+ url: '', // base + index + object + region + yearmonth + .json
+ base: 'https://oss.x-lab.info/open_leaderboard/',
+ year: null, // 字符串格式
+ month: null, // 整数格式,0表示1月,1表示2月..., null for year type time
+ type: 'month',
+ search: null,
+ category: 'cloud-native',
+ });
+
+ // 请求一次数据更新表格。如果还没读取好配置文件则不请求数据。
+ useEffect(() => {
+ if (props.year == null && props.month == null) {
+ console.log('the first loading');
+ return;
+ }
+ updateDate({
+ year: String(props.year),
+ month: props.month,
+ });
+ }, [props]);
+
+ const expandData = () => {
+ setState({
+ ...state,
+ showSize: state.showSize + 25,
+ });
+ };
+ const updateDate = (newstate) => {
+ console.log('table update', newstate);
+ // 先获取原先的表格属性
+ let {
+ base,
+ object,
+ index,
+ region,
+ month,
+ year,
+ columns,
+ showDetail,
+ hasDetail,
+ type,
+ search,
+ category,
+ } = state;
+ // 然后把表格改为加载中的状态
+ setState({ ...state, ...newstate, loading: true });
+ // 如果 newstate 有对应的属性,则进行更新
+ if (newstate.hasOwnProperty('object')) object = newstate.object;
+ if (newstate.hasOwnProperty('index')) index = newstate.index;
+ if (newstate.hasOwnProperty('region')) region = newstate.region;
+ if (newstate.hasOwnProperty('month')) month = newstate.month;
+ if (newstate.hasOwnProperty('year')) year = newstate.year;
+ if (newstate.hasOwnProperty('showDetail')) showDetail = newstate.showDetail;
+ if (newstate.hasOwnProperty('type')) type = newstate.type;
+ if (newstate.hasOwnProperty('search')) search = newstate.search;
+ if (newstate.hasOwnProperty('category')) category = newstate.category;
+
+ //获取数据大屏的‘t_month’参数
+ let myyear = newstate.year == null ? state.year : newstate.year;
+ let mymonth = newstate.month == null ? state.month : newstate.month;
+
+ mymonth = ('' + (1 + mymonth)).padStart(2, '0');
+ let t_month = `${myyear}-${mymonth}-01`;
+
+ // 根据 index 和 showDetail 改变表格的 columns 格式
+ if (index == 'activity') {
+ columns = activityColumns(object, t_month);
+ hasDetail = true;
+ }
+ if (index == 'activity' && showDetail == true) {
+ columns = activityDetailColumns(object, t_month);
+ hasDetail = true;
+ }
+ if (index == 'open_rank') {
+ columns = open_rankColumns(object, t_month);
+ hasDetail = false;
+ showDetail = false;
+ }
+ // 如果是年份数据,则把 month 置为 null。
+ // TODO:待验证,如果从年份数据切换到月份数据,似乎会自动回到原来 month 值?
+ if (type == 'year') {
+ month = null;
+ }
+ // 以当前的属性构造请求 url
+ let url = base + index + '/' + object + '/' + region + '/';
+ if (month === null) {
+ url += year + '.json';
+ } else {
+ url += year + (1 + month) + '.json';
+ }
+ console.log(url);
+ console.log(region);
+ if (object == 'foundation' && region == 'chinese') {
+ url = 'https://github.com/xiaoAugenstern/open-leadboard-data/blob/main/foundation.json'
+ fetch(url, {
+ method: 'GET',
+ "Access-Control-Allow-Origin" : "*",
+ "Access-Control-Allow-Credentials" : true,
+ mode: "cors",
+ })
+ .then((res) => {
+ // Todo:最好的情况是在日期选择器中,只显示可以查询的日期,
+ if (res.status == 404) {
+ message.warning(t('no_result'));
+ return '';
+ }
+ return res.json();
+ })
+ .then((data) => {
+ data = data.data;
+ let dataSource = [];
+ // 预处理数据,对新上榜单数据进行特殊标记处理
+ data.map((obj) => {
+ obj = expandObject(obj);
+ if (obj.rankDelta == 0 && obj.value == obj.valueDelta) {
+ obj.rankDelta = -10000000;
+ obj.valueDelta = 0;
+ }
+ dataSource.push(obj);
+ });
+ console.log(dataSource);
+
+ //搜索特定数据
+ let queryData;
+ if (search) {
+ queryData = dataSource.filter((dataSource) => {
+ let reg = new RegExp(search.trim(), 'i');
+ return reg.test(dataSource.name);
+ });
+ if (queryData.length == 0) {
+ message.warning(t('no_result'));
+ } else {
+ dataSource = queryData;
+ }
+ }
+
+ // 更新属性和表格数据
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ showDetail: showDetail,
+ hasDetail: hasDetail,
+ data: dataSource,
+ });
+ })
+ .catch((err) => {
+ console.log('hi!' + err);
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ data: [],
+ });
+ });
+ }
+ // fetch 异步请求
+ else{fetch(url)
+ .then((res) => {
+ // Todo:最好的情况是在日期选择器中,只显示可以查询的日期,
+ if (res.status == 404) {
+ message.warning(t('no_result'));
+ return '';
+ }
+ return res.json();
+ })
+ .then((data) => {
+ data = data.data;
+ let dataSource = [];
+ // 预处理数据,对新上榜单数据进行特殊标记处理
+ data.map((obj) => {
+ obj = expandObject(obj);
+ if (obj.rankDelta == 0 && obj.value == obj.valueDelta) {
+ obj.rankDelta = -10000000;
+ obj.valueDelta = 0;
+ }
+ dataSource.push(obj);
+ });
+ console.log(dataSource);
+
+ //搜索特定数据
+ let queryData;
+ if (search) {
+ queryData = dataSource.filter((dataSource) => {
+ let reg = new RegExp(search.trim(), 'i');
+ return reg.test(dataSource.name);
+ });
+ if (queryData.length == 0) {
+ message.warning(t('no_result'));
+ } else {
+ dataSource = queryData;
+ }
+ }
+
+ // 更新属性和表格数据
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ showDetail: showDetail,
+ hasDetail: hasDetail,
+ data: dataSource,
+ });
+ })
+ .catch((err) => {
+ console.log('hi!' + err);
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ data: [],
+ });
+ });
+ }
+
+ };
+
+ const {
+ object,
+ index,
+ region,
+ data,
+ columns,
+ loading,
+ showSize,
+ showDetail,
+ hasDetail,
+ month,
+ year,
+ type,
+ category,
+ } = state;
+ return (
+
+
+
+
+ record.rank}
+ dataSource={data.slice(0, Math.min(showSize, data.length))}
+ pagination={false}
+ loading={loading}
+ scroll={{ x: 'max-content' }}
+ />
+
+
+
+
+ {showSize < data.length ? (
+
+ {t('showMore') + '>>'}
+
+ ) : (
+
+ {t('noMore')}
+
+ )}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+}
+
+export default MyTable;
diff --git a/.history/src/components/table_20240727230905.js b/.history/src/components/table_20240727230905.js
new file mode 100644
index 0000000..aac4c4d
--- /dev/null
+++ b/.history/src/components/table_20240727230905.js
@@ -0,0 +1,653 @@
+import React, { useState, useEffect } from 'react';
+import { Col, message, Row, Table, Card } from 'antd';
+import MyAvatar from './avatar';
+import 'antd/dist/antd.css';
+import QAmiss from './QA2';
+import TablePanel from './TablePanel';
+import ArrowRender from './arrow';
+import PointRender from './changeNumber';
+import RoundFloat from './resolveFloat';
+import Trophy from './rankTrophy';
+import expandObject from '../util/expandObject';
+import { t } from 'i18next';
+import './table.css';
+
+const activityColumns = (object, t_month) => [
+ {
+ title: t('rank'),
+ dataIndex: 'rank',
+ width: '5%',
+ align: 'center',
+ render: Trophy,
+ fixed: 'left',
+ },
+ ...(object == 'actor'
+ ? [
+ {
+ title: t('avatar'),
+ dataIndex: 'id',
+ width: '5%',
+ align: 'center',
+ render: MyAvatar,
+ fixed: 'left',
+ },
+ ]
+ : []),
+ {
+ title: '',
+ dataIndex: 'rankDelta',
+ render: ArrowRender,
+ align: 'left',
+ width: '5%',
+ fixed: 'left',
+ },
+ {
+ title: t(object),
+ dataIndex: 'name',
+ align: 'center',
+ width: '20%',
+ render: function (text, row, index) {
+ if (object !== 'company') {
+ return (
+
+ {text}
+
+ );
+ } else {
+ return text;
+ }
+ },
+ },
+ ...(object == 'repo'
+ ? [
+ {
+ title: t('insight_board'),
+ dataIndex: 'name',
+ align: 'center',
+ width: '10%',
+ render: function (text, row, index) {
+ return dashboard(text, index, t_month);
+ },
+ },
+ ]
+ : []),
+ {
+ title: t('activity'),
+ dataIndex: 'value',
+ align: 'right',
+ width: '20%',
+ },
+ {
+ title: '',
+ dataIndex: 'valueDelta',
+ width: '10%',
+ align: 'left',
+ render: PointRender,
+ },
+];
+const activityDetailColumns = (object, t_month) => [
+ {
+ title: t('rank'),
+ dataIndex: 'rank',
+ width: '5%',
+ align: 'center',
+ render: Trophy,
+ fixed: 'left',
+ },
+ ...(object == 'actor'
+ ? [
+ {
+ title: t('avatar'),
+ dataIndex: 'id',
+ width: '5%',
+ align: 'center',
+ render: MyAvatar,
+ fixed: 'left',
+ },
+ ]
+ : []),
+ {
+ title: '',
+ dataIndex: 'rankDelta',
+ render: ArrowRender,
+ align: 'left',
+ width: '5%',
+ fixed: 'left',
+ },
+ {
+ title: t(object),
+ dataIndex: 'name',
+ align: 'center',
+ width: '5%',
+ render: function (text, row, index) {
+ if (object !== 'company') {
+ return (
+
+ {text}
+
+ );
+ } else {
+ return text;
+ }
+ },
+ },
+ ...(object == 'repo'
+ ? [
+ {
+ title: t('insight_board'),
+ dataIndex: 'name',
+ align: 'center',
+ width: '10%',
+ render: function (text, row, index) {
+ return dashboard(text, index, t_month);
+ },
+ },
+ ]
+ : []),
+ {
+ title: t('activity'),
+ dataIndex: 'value',
+ align: 'center',
+ width: '10%',
+ },
+ {
+ title: '',
+ dataIndex: 'valueDelta',
+ width: '10%',
+ align: 'left',
+ render: PointRender,
+ },
+ {
+ title: t('issue_comments'),
+ dataIndex: 'issue_comment',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('open_issues'),
+ dataIndex: 'open_issue',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('open_pulls'),
+ dataIndex: 'open_pull',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('merge_pulls'),
+ dataIndex: 'merged_pull',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('pr_reviews'),
+ dataIndex: 'review_comment',
+ width: '10%',
+ align: 'center',
+ },
+];
+const open_rankColumns = (object, t_month) => [
+ {
+ // 第一列:排名
+ title: t('rank'),
+ dataIndex: 'rank',
+ width: '5%',
+ render: Trophy,
+ align: 'center',
+ fixed: 'left',
+ },
+ // 如果 object 是 'actor',则添加头像列
+ ...(object == 'actor'
+ ? [
+ {
+ title: t('avatar'),
+ dataIndex: 'id',
+ width: '5%',
+ align: 'center',
+ render: MyAvatar,
+ fixed: 'left',
+ },
+ ]
+ : []),
+ // 第二列:排名变化
+ {
+ title: '',
+ dataIndex: 'rankDelta',
+ render: ArrowRender,
+ align: 'left',
+ width: '5%',
+ fixed: 'left',
+ },
+ // 第三列:对象名称(可能是 actor, repo 或 company)
+ {
+ title: t(object),
+ dataIndex: 'name',
+ width: '20%',
+ align: 'center',
+ render: function (text) {
+ if (object !== 'company') {
+ return (
+
+ {text}
+
+ );
+ } else {
+ return text;
+ }
+ },
+ },
+ // 如果 object 是 'repo',则添加 insight_board 列
+ ...(object == 'repo'
+ ? [
+ {
+ title: t('insight_board'),
+ dataIndex: 'name',
+ align: 'center',
+ width: '10%',
+ render: function (text, row, index) {
+ return dashboard(text, index, t_month);
+ },
+ },
+ ]
+ : []),
+ // 第四列:影响力
+ {
+ title: t('influence'),
+ dataIndex: 'value',
+ width: '20%',
+ align: 'right',
+ render: (text, row, index) => {
+ return RoundFloat(text);
+ },
+ },
+ // 第五列:影响力变化
+ {
+ title: '',
+ dataIndex: 'valueDelta',
+ width: '10%',
+ align: 'left',
+ render: (text, row, index) => {
+ text = RoundFloat(text);
+ return PointRender(text, row, index);
+ },
+ },
+];
+
+const solveDate = (year, month) => {
+ if (year === null && month === null) {
+ return 'not found';
+ }
+ if (month === null) {
+ return year + '年';
+ }
+ return year + '年' + (month + 1) + '月';
+};
+
+function dashboard(text, index, t_month) {
+ if (index < 300) {
+ let [org_name, repo_name] = text.split('/');
+ const t_month_copy = t_month + ' ' + '00:00:00';
+ let params = {
+ org_name,
+ repo_name,
+ t_month_copy,
+ t_month,
+ };
+ return (
+
+
+
+ );
+ }
+}
+
+function DateTitle(props) {
+ return {solveDate(props.year, props.month)}
;
+}
+
+function MyTable(props) {
+ const [state, setState] = useState({
+ object: 'technology',
+ index: 'open_rank',
+ region: 'global',
+ showDetail: false,
+ hasDetail: true,
+ data: [],
+ showSize: 25,
+ loading: true,
+ url: '', // base + index + object + region + yearmonth + .json
+ base: 'https://oss.x-lab.info/open_leaderboard/',
+ year: null, // 字符串格式
+ month: null, // 整数格式,0表示1月,1表示2月..., null for year type time
+ type: 'month',
+ search: null,
+ category: 'cloud-native',
+ });
+
+ // 请求一次数据更新表格。如果还没读取好配置文件则不请求数据。
+ useEffect(() => {
+ if (props.year == null && props.month == null) {
+ console.log('the first loading');
+ return;
+ }
+ updateDate({
+ year: String(props.year),
+ month: props.month,
+ });
+ }, [props]);
+
+ const expandData = () => {
+ setState({
+ ...state,
+ showSize: state.showSize + 25,
+ });
+ };
+ const updateDate = (newstate) => {
+ console.log('table update', newstate);
+ // 先获取原先的表格属性
+ let {
+ base,
+ object,
+ index,
+ region,
+ month,
+ year,
+ columns,
+ showDetail,
+ hasDetail,
+ type,
+ search,
+ category,
+ } = state;
+ // 然后把表格改为加载中的状态
+ setState({ ...state, ...newstate, loading: true });
+ // 如果 newstate 有对应的属性,则进行更新
+ if (newstate.hasOwnProperty('object')) object = newstate.object;
+ if (newstate.hasOwnProperty('index')) index = newstate.index;
+ if (newstate.hasOwnProperty('region')) region = newstate.region;
+ if (newstate.hasOwnProperty('month')) month = newstate.month;
+ if (newstate.hasOwnProperty('year')) year = newstate.year;
+ if (newstate.hasOwnProperty('showDetail')) showDetail = newstate.showDetail;
+ if (newstate.hasOwnProperty('type')) type = newstate.type;
+ if (newstate.hasOwnProperty('search')) search = newstate.search;
+ if (newstate.hasOwnProperty('category')) category = newstate.category;
+
+ //获取数据大屏的‘t_month’参数
+ let myyear = newstate.year == null ? state.year : newstate.year;
+ let mymonth = newstate.month == null ? state.month : newstate.month;
+
+ mymonth = ('' + (1 + mymonth)).padStart(2, '0');
+ let t_month = `${myyear}-${mymonth}-01`;
+
+ // 根据 index 和 showDetail 改变表格的 columns 格式
+ if (index == 'activity') {
+ columns = activityColumns(object, t_month);
+ hasDetail = true;
+ }
+ if (index == 'activity' && showDetail == true) {
+ columns = activityDetailColumns(object, t_month);
+ hasDetail = true;
+ }
+ if (index == 'open_rank') {
+ columns = open_rankColumns(object, t_month);
+ hasDetail = false;
+ showDetail = false;
+ }
+ // 如果是年份数据,则把 month 置为 null。
+ // TODO:待验证,如果从年份数据切换到月份数据,似乎会自动回到原来 month 值?
+ if (type == 'year') {
+ month = null;
+ }
+ // 以当前的属性构造请求 url
+ let url = base + index + '/' + object + '/' + region + '/';
+ if (month === null) {
+ url += year + '.json';
+ } else {
+ url += year + (1 + month) + '.json';
+ }
+ console.log(url);
+ console.log(region);
+ if (object == 'foundation' && region == 'chinese') {
+ url = 'https://github.com/xiaoAugenstern/open-leadboard-data/blob/main/foundation.json'
+ fetch(url, {
+ method: 'GET',
+ "Access-Control-Allow-Origin" : "*",
+ "Access-Control-Allow-Credentials" : true,
+ "Access-Control-Allow-Methods":"POST, GET, OPTIONS, DELETE, HEAD",
+ mode: "cors",
+ })
+ .then((res) => {
+ // Todo:最好的情况是在日期选择器中,只显示可以查询的日期,
+ if (res.status == 404) {
+ message.warning(t('no_result'));
+ return '';
+ }
+ return res.json();
+ })
+ .then((data) => {
+ data = data.data;
+ let dataSource = [];
+ // 预处理数据,对新上榜单数据进行特殊标记处理
+ data.map((obj) => {
+ obj = expandObject(obj);
+ if (obj.rankDelta == 0 && obj.value == obj.valueDelta) {
+ obj.rankDelta = -10000000;
+ obj.valueDelta = 0;
+ }
+ dataSource.push(obj);
+ });
+ console.log(dataSource);
+
+ //搜索特定数据
+ let queryData;
+ if (search) {
+ queryData = dataSource.filter((dataSource) => {
+ let reg = new RegExp(search.trim(), 'i');
+ return reg.test(dataSource.name);
+ });
+ if (queryData.length == 0) {
+ message.warning(t('no_result'));
+ } else {
+ dataSource = queryData;
+ }
+ }
+
+ // 更新属性和表格数据
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ showDetail: showDetail,
+ hasDetail: hasDetail,
+ data: dataSource,
+ });
+ })
+ .catch((err) => {
+ console.log('hi!' + err);
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ data: [],
+ });
+ });
+ }
+ // fetch 异步请求
+ else{fetch(url)
+ .then((res) => {
+ // Todo:最好的情况是在日期选择器中,只显示可以查询的日期,
+ if (res.status == 404) {
+ message.warning(t('no_result'));
+ return '';
+ }
+ return res.json();
+ })
+ .then((data) => {
+ data = data.data;
+ let dataSource = [];
+ // 预处理数据,对新上榜单数据进行特殊标记处理
+ data.map((obj) => {
+ obj = expandObject(obj);
+ if (obj.rankDelta == 0 && obj.value == obj.valueDelta) {
+ obj.rankDelta = -10000000;
+ obj.valueDelta = 0;
+ }
+ dataSource.push(obj);
+ });
+ console.log(dataSource);
+
+ //搜索特定数据
+ let queryData;
+ if (search) {
+ queryData = dataSource.filter((dataSource) => {
+ let reg = new RegExp(search.trim(), 'i');
+ return reg.test(dataSource.name);
+ });
+ if (queryData.length == 0) {
+ message.warning(t('no_result'));
+ } else {
+ dataSource = queryData;
+ }
+ }
+
+ // 更新属性和表格数据
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ showDetail: showDetail,
+ hasDetail: hasDetail,
+ data: dataSource,
+ });
+ })
+ .catch((err) => {
+ console.log('hi!' + err);
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ data: [],
+ });
+ });
+ }
+
+ };
+
+ const {
+ object,
+ index,
+ region,
+ data,
+ columns,
+ loading,
+ showSize,
+ showDetail,
+ hasDetail,
+ month,
+ year,
+ type,
+ category,
+ } = state;
+ return (
+
+
+
+
+ record.rank}
+ dataSource={data.slice(0, Math.min(showSize, data.length))}
+ pagination={false}
+ loading={loading}
+ scroll={{ x: 'max-content' }}
+ />
+
+
+
+
+ {showSize < data.length ? (
+
+ {t('showMore') + '>>'}
+
+ ) : (
+
+ {t('noMore')}
+
+ )}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+}
+
+export default MyTable;
diff --git a/.history/src/components/table_20240727230907.js b/.history/src/components/table_20240727230907.js
new file mode 100644
index 0000000..aac4c4d
--- /dev/null
+++ b/.history/src/components/table_20240727230907.js
@@ -0,0 +1,653 @@
+import React, { useState, useEffect } from 'react';
+import { Col, message, Row, Table, Card } from 'antd';
+import MyAvatar from './avatar';
+import 'antd/dist/antd.css';
+import QAmiss from './QA2';
+import TablePanel from './TablePanel';
+import ArrowRender from './arrow';
+import PointRender from './changeNumber';
+import RoundFloat from './resolveFloat';
+import Trophy from './rankTrophy';
+import expandObject from '../util/expandObject';
+import { t } from 'i18next';
+import './table.css';
+
+const activityColumns = (object, t_month) => [
+ {
+ title: t('rank'),
+ dataIndex: 'rank',
+ width: '5%',
+ align: 'center',
+ render: Trophy,
+ fixed: 'left',
+ },
+ ...(object == 'actor'
+ ? [
+ {
+ title: t('avatar'),
+ dataIndex: 'id',
+ width: '5%',
+ align: 'center',
+ render: MyAvatar,
+ fixed: 'left',
+ },
+ ]
+ : []),
+ {
+ title: '',
+ dataIndex: 'rankDelta',
+ render: ArrowRender,
+ align: 'left',
+ width: '5%',
+ fixed: 'left',
+ },
+ {
+ title: t(object),
+ dataIndex: 'name',
+ align: 'center',
+ width: '20%',
+ render: function (text, row, index) {
+ if (object !== 'company') {
+ return (
+
+ {text}
+
+ );
+ } else {
+ return text;
+ }
+ },
+ },
+ ...(object == 'repo'
+ ? [
+ {
+ title: t('insight_board'),
+ dataIndex: 'name',
+ align: 'center',
+ width: '10%',
+ render: function (text, row, index) {
+ return dashboard(text, index, t_month);
+ },
+ },
+ ]
+ : []),
+ {
+ title: t('activity'),
+ dataIndex: 'value',
+ align: 'right',
+ width: '20%',
+ },
+ {
+ title: '',
+ dataIndex: 'valueDelta',
+ width: '10%',
+ align: 'left',
+ render: PointRender,
+ },
+];
+const activityDetailColumns = (object, t_month) => [
+ {
+ title: t('rank'),
+ dataIndex: 'rank',
+ width: '5%',
+ align: 'center',
+ render: Trophy,
+ fixed: 'left',
+ },
+ ...(object == 'actor'
+ ? [
+ {
+ title: t('avatar'),
+ dataIndex: 'id',
+ width: '5%',
+ align: 'center',
+ render: MyAvatar,
+ fixed: 'left',
+ },
+ ]
+ : []),
+ {
+ title: '',
+ dataIndex: 'rankDelta',
+ render: ArrowRender,
+ align: 'left',
+ width: '5%',
+ fixed: 'left',
+ },
+ {
+ title: t(object),
+ dataIndex: 'name',
+ align: 'center',
+ width: '5%',
+ render: function (text, row, index) {
+ if (object !== 'company') {
+ return (
+
+ {text}
+
+ );
+ } else {
+ return text;
+ }
+ },
+ },
+ ...(object == 'repo'
+ ? [
+ {
+ title: t('insight_board'),
+ dataIndex: 'name',
+ align: 'center',
+ width: '10%',
+ render: function (text, row, index) {
+ return dashboard(text, index, t_month);
+ },
+ },
+ ]
+ : []),
+ {
+ title: t('activity'),
+ dataIndex: 'value',
+ align: 'center',
+ width: '10%',
+ },
+ {
+ title: '',
+ dataIndex: 'valueDelta',
+ width: '10%',
+ align: 'left',
+ render: PointRender,
+ },
+ {
+ title: t('issue_comments'),
+ dataIndex: 'issue_comment',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('open_issues'),
+ dataIndex: 'open_issue',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('open_pulls'),
+ dataIndex: 'open_pull',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('merge_pulls'),
+ dataIndex: 'merged_pull',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('pr_reviews'),
+ dataIndex: 'review_comment',
+ width: '10%',
+ align: 'center',
+ },
+];
+const open_rankColumns = (object, t_month) => [
+ {
+ // 第一列:排名
+ title: t('rank'),
+ dataIndex: 'rank',
+ width: '5%',
+ render: Trophy,
+ align: 'center',
+ fixed: 'left',
+ },
+ // 如果 object 是 'actor',则添加头像列
+ ...(object == 'actor'
+ ? [
+ {
+ title: t('avatar'),
+ dataIndex: 'id',
+ width: '5%',
+ align: 'center',
+ render: MyAvatar,
+ fixed: 'left',
+ },
+ ]
+ : []),
+ // 第二列:排名变化
+ {
+ title: '',
+ dataIndex: 'rankDelta',
+ render: ArrowRender,
+ align: 'left',
+ width: '5%',
+ fixed: 'left',
+ },
+ // 第三列:对象名称(可能是 actor, repo 或 company)
+ {
+ title: t(object),
+ dataIndex: 'name',
+ width: '20%',
+ align: 'center',
+ render: function (text) {
+ if (object !== 'company') {
+ return (
+
+ {text}
+
+ );
+ } else {
+ return text;
+ }
+ },
+ },
+ // 如果 object 是 'repo',则添加 insight_board 列
+ ...(object == 'repo'
+ ? [
+ {
+ title: t('insight_board'),
+ dataIndex: 'name',
+ align: 'center',
+ width: '10%',
+ render: function (text, row, index) {
+ return dashboard(text, index, t_month);
+ },
+ },
+ ]
+ : []),
+ // 第四列:影响力
+ {
+ title: t('influence'),
+ dataIndex: 'value',
+ width: '20%',
+ align: 'right',
+ render: (text, row, index) => {
+ return RoundFloat(text);
+ },
+ },
+ // 第五列:影响力变化
+ {
+ title: '',
+ dataIndex: 'valueDelta',
+ width: '10%',
+ align: 'left',
+ render: (text, row, index) => {
+ text = RoundFloat(text);
+ return PointRender(text, row, index);
+ },
+ },
+];
+
+const solveDate = (year, month) => {
+ if (year === null && month === null) {
+ return 'not found';
+ }
+ if (month === null) {
+ return year + '年';
+ }
+ return year + '年' + (month + 1) + '月';
+};
+
+function dashboard(text, index, t_month) {
+ if (index < 300) {
+ let [org_name, repo_name] = text.split('/');
+ const t_month_copy = t_month + ' ' + '00:00:00';
+ let params = {
+ org_name,
+ repo_name,
+ t_month_copy,
+ t_month,
+ };
+ return (
+
+
+
+ );
+ }
+}
+
+function DateTitle(props) {
+ return {solveDate(props.year, props.month)}
;
+}
+
+function MyTable(props) {
+ const [state, setState] = useState({
+ object: 'technology',
+ index: 'open_rank',
+ region: 'global',
+ showDetail: false,
+ hasDetail: true,
+ data: [],
+ showSize: 25,
+ loading: true,
+ url: '', // base + index + object + region + yearmonth + .json
+ base: 'https://oss.x-lab.info/open_leaderboard/',
+ year: null, // 字符串格式
+ month: null, // 整数格式,0表示1月,1表示2月..., null for year type time
+ type: 'month',
+ search: null,
+ category: 'cloud-native',
+ });
+
+ // 请求一次数据更新表格。如果还没读取好配置文件则不请求数据。
+ useEffect(() => {
+ if (props.year == null && props.month == null) {
+ console.log('the first loading');
+ return;
+ }
+ updateDate({
+ year: String(props.year),
+ month: props.month,
+ });
+ }, [props]);
+
+ const expandData = () => {
+ setState({
+ ...state,
+ showSize: state.showSize + 25,
+ });
+ };
+ const updateDate = (newstate) => {
+ console.log('table update', newstate);
+ // 先获取原先的表格属性
+ let {
+ base,
+ object,
+ index,
+ region,
+ month,
+ year,
+ columns,
+ showDetail,
+ hasDetail,
+ type,
+ search,
+ category,
+ } = state;
+ // 然后把表格改为加载中的状态
+ setState({ ...state, ...newstate, loading: true });
+ // 如果 newstate 有对应的属性,则进行更新
+ if (newstate.hasOwnProperty('object')) object = newstate.object;
+ if (newstate.hasOwnProperty('index')) index = newstate.index;
+ if (newstate.hasOwnProperty('region')) region = newstate.region;
+ if (newstate.hasOwnProperty('month')) month = newstate.month;
+ if (newstate.hasOwnProperty('year')) year = newstate.year;
+ if (newstate.hasOwnProperty('showDetail')) showDetail = newstate.showDetail;
+ if (newstate.hasOwnProperty('type')) type = newstate.type;
+ if (newstate.hasOwnProperty('search')) search = newstate.search;
+ if (newstate.hasOwnProperty('category')) category = newstate.category;
+
+ //获取数据大屏的‘t_month’参数
+ let myyear = newstate.year == null ? state.year : newstate.year;
+ let mymonth = newstate.month == null ? state.month : newstate.month;
+
+ mymonth = ('' + (1 + mymonth)).padStart(2, '0');
+ let t_month = `${myyear}-${mymonth}-01`;
+
+ // 根据 index 和 showDetail 改变表格的 columns 格式
+ if (index == 'activity') {
+ columns = activityColumns(object, t_month);
+ hasDetail = true;
+ }
+ if (index == 'activity' && showDetail == true) {
+ columns = activityDetailColumns(object, t_month);
+ hasDetail = true;
+ }
+ if (index == 'open_rank') {
+ columns = open_rankColumns(object, t_month);
+ hasDetail = false;
+ showDetail = false;
+ }
+ // 如果是年份数据,则把 month 置为 null。
+ // TODO:待验证,如果从年份数据切换到月份数据,似乎会自动回到原来 month 值?
+ if (type == 'year') {
+ month = null;
+ }
+ // 以当前的属性构造请求 url
+ let url = base + index + '/' + object + '/' + region + '/';
+ if (month === null) {
+ url += year + '.json';
+ } else {
+ url += year + (1 + month) + '.json';
+ }
+ console.log(url);
+ console.log(region);
+ if (object == 'foundation' && region == 'chinese') {
+ url = 'https://github.com/xiaoAugenstern/open-leadboard-data/blob/main/foundation.json'
+ fetch(url, {
+ method: 'GET',
+ "Access-Control-Allow-Origin" : "*",
+ "Access-Control-Allow-Credentials" : true,
+ "Access-Control-Allow-Methods":"POST, GET, OPTIONS, DELETE, HEAD",
+ mode: "cors",
+ })
+ .then((res) => {
+ // Todo:最好的情况是在日期选择器中,只显示可以查询的日期,
+ if (res.status == 404) {
+ message.warning(t('no_result'));
+ return '';
+ }
+ return res.json();
+ })
+ .then((data) => {
+ data = data.data;
+ let dataSource = [];
+ // 预处理数据,对新上榜单数据进行特殊标记处理
+ data.map((obj) => {
+ obj = expandObject(obj);
+ if (obj.rankDelta == 0 && obj.value == obj.valueDelta) {
+ obj.rankDelta = -10000000;
+ obj.valueDelta = 0;
+ }
+ dataSource.push(obj);
+ });
+ console.log(dataSource);
+
+ //搜索特定数据
+ let queryData;
+ if (search) {
+ queryData = dataSource.filter((dataSource) => {
+ let reg = new RegExp(search.trim(), 'i');
+ return reg.test(dataSource.name);
+ });
+ if (queryData.length == 0) {
+ message.warning(t('no_result'));
+ } else {
+ dataSource = queryData;
+ }
+ }
+
+ // 更新属性和表格数据
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ showDetail: showDetail,
+ hasDetail: hasDetail,
+ data: dataSource,
+ });
+ })
+ .catch((err) => {
+ console.log('hi!' + err);
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ data: [],
+ });
+ });
+ }
+ // fetch 异步请求
+ else{fetch(url)
+ .then((res) => {
+ // Todo:最好的情况是在日期选择器中,只显示可以查询的日期,
+ if (res.status == 404) {
+ message.warning(t('no_result'));
+ return '';
+ }
+ return res.json();
+ })
+ .then((data) => {
+ data = data.data;
+ let dataSource = [];
+ // 预处理数据,对新上榜单数据进行特殊标记处理
+ data.map((obj) => {
+ obj = expandObject(obj);
+ if (obj.rankDelta == 0 && obj.value == obj.valueDelta) {
+ obj.rankDelta = -10000000;
+ obj.valueDelta = 0;
+ }
+ dataSource.push(obj);
+ });
+ console.log(dataSource);
+
+ //搜索特定数据
+ let queryData;
+ if (search) {
+ queryData = dataSource.filter((dataSource) => {
+ let reg = new RegExp(search.trim(), 'i');
+ return reg.test(dataSource.name);
+ });
+ if (queryData.length == 0) {
+ message.warning(t('no_result'));
+ } else {
+ dataSource = queryData;
+ }
+ }
+
+ // 更新属性和表格数据
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ showDetail: showDetail,
+ hasDetail: hasDetail,
+ data: dataSource,
+ });
+ })
+ .catch((err) => {
+ console.log('hi!' + err);
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ data: [],
+ });
+ });
+ }
+
+ };
+
+ const {
+ object,
+ index,
+ region,
+ data,
+ columns,
+ loading,
+ showSize,
+ showDetail,
+ hasDetail,
+ month,
+ year,
+ type,
+ category,
+ } = state;
+ return (
+
+
+
+
+ record.rank}
+ dataSource={data.slice(0, Math.min(showSize, data.length))}
+ pagination={false}
+ loading={loading}
+ scroll={{ x: 'max-content' }}
+ />
+
+
+
+
+ {showSize < data.length ? (
+
+ {t('showMore') + '>>'}
+
+ ) : (
+
+ {t('noMore')}
+
+ )}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+}
+
+export default MyTable;
diff --git a/.history/src/components/table_20240727230943.js b/.history/src/components/table_20240727230943.js
new file mode 100644
index 0000000..2914bd4
--- /dev/null
+++ b/.history/src/components/table_20240727230943.js
@@ -0,0 +1,653 @@
+import React, { useState, useEffect } from 'react';
+import { Col, message, Row, Table, Card } from 'antd';
+import MyAvatar from './avatar';
+import 'antd/dist/antd.css';
+import QAmiss from './QA2';
+import TablePanel from './TablePanel';
+import ArrowRender from './arrow';
+import PointRender from './changeNumber';
+import RoundFloat from './resolveFloat';
+import Trophy from './rankTrophy';
+import expandObject from '../util/expandObject';
+import { t } from 'i18next';
+import './table.css';
+
+const activityColumns = (object, t_month) => [
+ {
+ title: t('rank'),
+ dataIndex: 'rank',
+ width: '5%',
+ align: 'center',
+ render: Trophy,
+ fixed: 'left',
+ },
+ ...(object == 'actor'
+ ? [
+ {
+ title: t('avatar'),
+ dataIndex: 'id',
+ width: '5%',
+ align: 'center',
+ render: MyAvatar,
+ fixed: 'left',
+ },
+ ]
+ : []),
+ {
+ title: '',
+ dataIndex: 'rankDelta',
+ render: ArrowRender,
+ align: 'left',
+ width: '5%',
+ fixed: 'left',
+ },
+ {
+ title: t(object),
+ dataIndex: 'name',
+ align: 'center',
+ width: '20%',
+ render: function (text, row, index) {
+ if (object !== 'company') {
+ return (
+
+ {text}
+
+ );
+ } else {
+ return text;
+ }
+ },
+ },
+ ...(object == 'repo'
+ ? [
+ {
+ title: t('insight_board'),
+ dataIndex: 'name',
+ align: 'center',
+ width: '10%',
+ render: function (text, row, index) {
+ return dashboard(text, index, t_month);
+ },
+ },
+ ]
+ : []),
+ {
+ title: t('activity'),
+ dataIndex: 'value',
+ align: 'right',
+ width: '20%',
+ },
+ {
+ title: '',
+ dataIndex: 'valueDelta',
+ width: '10%',
+ align: 'left',
+ render: PointRender,
+ },
+];
+const activityDetailColumns = (object, t_month) => [
+ {
+ title: t('rank'),
+ dataIndex: 'rank',
+ width: '5%',
+ align: 'center',
+ render: Trophy,
+ fixed: 'left',
+ },
+ ...(object == 'actor'
+ ? [
+ {
+ title: t('avatar'),
+ dataIndex: 'id',
+ width: '5%',
+ align: 'center',
+ render: MyAvatar,
+ fixed: 'left',
+ },
+ ]
+ : []),
+ {
+ title: '',
+ dataIndex: 'rankDelta',
+ render: ArrowRender,
+ align: 'left',
+ width: '5%',
+ fixed: 'left',
+ },
+ {
+ title: t(object),
+ dataIndex: 'name',
+ align: 'center',
+ width: '5%',
+ render: function (text, row, index) {
+ if (object !== 'company') {
+ return (
+
+ {text}
+
+ );
+ } else {
+ return text;
+ }
+ },
+ },
+ ...(object == 'repo'
+ ? [
+ {
+ title: t('insight_board'),
+ dataIndex: 'name',
+ align: 'center',
+ width: '10%',
+ render: function (text, row, index) {
+ return dashboard(text, index, t_month);
+ },
+ },
+ ]
+ : []),
+ {
+ title: t('activity'),
+ dataIndex: 'value',
+ align: 'center',
+ width: '10%',
+ },
+ {
+ title: '',
+ dataIndex: 'valueDelta',
+ width: '10%',
+ align: 'left',
+ render: PointRender,
+ },
+ {
+ title: t('issue_comments'),
+ dataIndex: 'issue_comment',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('open_issues'),
+ dataIndex: 'open_issue',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('open_pulls'),
+ dataIndex: 'open_pull',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('merge_pulls'),
+ dataIndex: 'merged_pull',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('pr_reviews'),
+ dataIndex: 'review_comment',
+ width: '10%',
+ align: 'center',
+ },
+];
+const open_rankColumns = (object, t_month) => [
+ {
+ // 第一列:排名
+ title: t('rank'),
+ dataIndex: 'rank',
+ width: '5%',
+ render: Trophy,
+ align: 'center',
+ fixed: 'left',
+ },
+ // 如果 object 是 'actor',则添加头像列
+ ...(object == 'actor'
+ ? [
+ {
+ title: t('avatar'),
+ dataIndex: 'id',
+ width: '5%',
+ align: 'center',
+ render: MyAvatar,
+ fixed: 'left',
+ },
+ ]
+ : []),
+ // 第二列:排名变化
+ {
+ title: '',
+ dataIndex: 'rankDelta',
+ render: ArrowRender,
+ align: 'left',
+ width: '5%',
+ fixed: 'left',
+ },
+ // 第三列:对象名称(可能是 actor, repo 或 company)
+ {
+ title: t(object),
+ dataIndex: 'name',
+ width: '20%',
+ align: 'center',
+ render: function (text) {
+ if (object !== 'company') {
+ return (
+
+ {text}
+
+ );
+ } else {
+ return text;
+ }
+ },
+ },
+ // 如果 object 是 'repo',则添加 insight_board 列
+ ...(object == 'repo'
+ ? [
+ {
+ title: t('insight_board'),
+ dataIndex: 'name',
+ align: 'center',
+ width: '10%',
+ render: function (text, row, index) {
+ return dashboard(text, index, t_month);
+ },
+ },
+ ]
+ : []),
+ // 第四列:影响力
+ {
+ title: t('influence'),
+ dataIndex: 'value',
+ width: '20%',
+ align: 'right',
+ render: (text, row, index) => {
+ return RoundFloat(text);
+ },
+ },
+ // 第五列:影响力变化
+ {
+ title: '',
+ dataIndex: 'valueDelta',
+ width: '10%',
+ align: 'left',
+ render: (text, row, index) => {
+ text = RoundFloat(text);
+ return PointRender(text, row, index);
+ },
+ },
+];
+
+const solveDate = (year, month) => {
+ if (year === null && month === null) {
+ return 'not found';
+ }
+ if (month === null) {
+ return year + '年';
+ }
+ return year + '年' + (month + 1) + '月';
+};
+
+function dashboard(text, index, t_month) {
+ if (index < 300) {
+ let [org_name, repo_name] = text.split('/');
+ const t_month_copy = t_month + ' ' + '00:00:00';
+ let params = {
+ org_name,
+ repo_name,
+ t_month_copy,
+ t_month,
+ };
+ return (
+
+
+
+ );
+ }
+}
+
+function DateTitle(props) {
+ return {solveDate(props.year, props.month)}
;
+}
+
+function MyTable(props) {
+ const [state, setState] = useState({
+ object: 'technology',
+ index: 'open_rank',
+ region: 'global',
+ showDetail: false,
+ hasDetail: true,
+ data: [],
+ showSize: 25,
+ loading: true,
+ url: '', // base + index + object + region + yearmonth + .json
+ base: 'https://oss.x-lab.info/open_leaderboard/',
+ year: null, // 字符串格式
+ month: null, // 整数格式,0表示1月,1表示2月..., null for year type time
+ type: 'month',
+ search: null,
+ category: 'cloud-native',
+ });
+
+ // 请求一次数据更新表格。如果还没读取好配置文件则不请求数据。
+ useEffect(() => {
+ if (props.year == null && props.month == null) {
+ console.log('the first loading');
+ return;
+ }
+ updateDate({
+ year: String(props.year),
+ month: props.month,
+ });
+ }, [props]);
+
+ const expandData = () => {
+ setState({
+ ...state,
+ showSize: state.showSize + 25,
+ });
+ };
+ const updateDate = (newstate) => {
+ console.log('table update', newstate);
+ // 先获取原先的表格属性
+ let {
+ base,
+ object,
+ index,
+ region,
+ month,
+ year,
+ columns,
+ showDetail,
+ hasDetail,
+ type,
+ search,
+ category,
+ } = state;
+ // 然后把表格改为加载中的状态
+ setState({ ...state, ...newstate, loading: true });
+ // 如果 newstate 有对应的属性,则进行更新
+ if (newstate.hasOwnProperty('object')) object = newstate.object;
+ if (newstate.hasOwnProperty('index')) index = newstate.index;
+ if (newstate.hasOwnProperty('region')) region = newstate.region;
+ if (newstate.hasOwnProperty('month')) month = newstate.month;
+ if (newstate.hasOwnProperty('year')) year = newstate.year;
+ if (newstate.hasOwnProperty('showDetail')) showDetail = newstate.showDetail;
+ if (newstate.hasOwnProperty('type')) type = newstate.type;
+ if (newstate.hasOwnProperty('search')) search = newstate.search;
+ if (newstate.hasOwnProperty('category')) category = newstate.category;
+
+ //获取数据大屏的‘t_month’参数
+ let myyear = newstate.year == null ? state.year : newstate.year;
+ let mymonth = newstate.month == null ? state.month : newstate.month;
+
+ mymonth = ('' + (1 + mymonth)).padStart(2, '0');
+ let t_month = `${myyear}-${mymonth}-01`;
+
+ // 根据 index 和 showDetail 改变表格的 columns 格式
+ if (index == 'activity') {
+ columns = activityColumns(object, t_month);
+ hasDetail = true;
+ }
+ if (index == 'activity' && showDetail == true) {
+ columns = activityDetailColumns(object, t_month);
+ hasDetail = true;
+ }
+ if (index == 'open_rank') {
+ columns = open_rankColumns(object, t_month);
+ hasDetail = false;
+ showDetail = false;
+ }
+ // 如果是年份数据,则把 month 置为 null。
+ // TODO:待验证,如果从年份数据切换到月份数据,似乎会自动回到原来 month 值?
+ if (type == 'year') {
+ month = null;
+ }
+ // 以当前的属性构造请求 url
+ let url = base + index + '/' + object + '/' + region + '/';
+ if (month === null) {
+ url += year + '.json';
+ } else {
+ url += year + (1 + month) + '.json';
+ }
+ console.log(url);
+ console.log(region);
+ if (object == 'foundation' && region == 'chinese') {
+ url = 'https://github.com/xiaoAugenstern/open-leadboard-data/blob/main/foundation.json'
+ fetch(url, {
+ method: 'GET',
+ "Access-Control-Allow-Origin" : "*",
+ "Access-Control-Allow-Credentials" : true,
+ "Access-Control-Allow-Methods":"POST, GET, OPTIONS, DELETE, HEAD",
+ mode: "no-cors",
+ })
+ .then((res) => {
+ // Todo:最好的情况是在日期选择器中,只显示可以查询的日期,
+ if (res.status == 404) {
+ message.warning(t('no_result'));
+ return '';
+ }
+ return res.json();
+ })
+ .then((data) => {
+ data = data.data;
+ let dataSource = [];
+ // 预处理数据,对新上榜单数据进行特殊标记处理
+ data.map((obj) => {
+ obj = expandObject(obj);
+ if (obj.rankDelta == 0 && obj.value == obj.valueDelta) {
+ obj.rankDelta = -10000000;
+ obj.valueDelta = 0;
+ }
+ dataSource.push(obj);
+ });
+ console.log(dataSource);
+
+ //搜索特定数据
+ let queryData;
+ if (search) {
+ queryData = dataSource.filter((dataSource) => {
+ let reg = new RegExp(search.trim(), 'i');
+ return reg.test(dataSource.name);
+ });
+ if (queryData.length == 0) {
+ message.warning(t('no_result'));
+ } else {
+ dataSource = queryData;
+ }
+ }
+
+ // 更新属性和表格数据
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ showDetail: showDetail,
+ hasDetail: hasDetail,
+ data: dataSource,
+ });
+ })
+ .catch((err) => {
+ console.log('hi!' + err);
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ data: [],
+ });
+ });
+ }
+ // fetch 异步请求
+ else{fetch(url)
+ .then((res) => {
+ // Todo:最好的情况是在日期选择器中,只显示可以查询的日期,
+ if (res.status == 404) {
+ message.warning(t('no_result'));
+ return '';
+ }
+ return res.json();
+ })
+ .then((data) => {
+ data = data.data;
+ let dataSource = [];
+ // 预处理数据,对新上榜单数据进行特殊标记处理
+ data.map((obj) => {
+ obj = expandObject(obj);
+ if (obj.rankDelta == 0 && obj.value == obj.valueDelta) {
+ obj.rankDelta = -10000000;
+ obj.valueDelta = 0;
+ }
+ dataSource.push(obj);
+ });
+ console.log(dataSource);
+
+ //搜索特定数据
+ let queryData;
+ if (search) {
+ queryData = dataSource.filter((dataSource) => {
+ let reg = new RegExp(search.trim(), 'i');
+ return reg.test(dataSource.name);
+ });
+ if (queryData.length == 0) {
+ message.warning(t('no_result'));
+ } else {
+ dataSource = queryData;
+ }
+ }
+
+ // 更新属性和表格数据
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ showDetail: showDetail,
+ hasDetail: hasDetail,
+ data: dataSource,
+ });
+ })
+ .catch((err) => {
+ console.log('hi!' + err);
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ data: [],
+ });
+ });
+ }
+
+ };
+
+ const {
+ object,
+ index,
+ region,
+ data,
+ columns,
+ loading,
+ showSize,
+ showDetail,
+ hasDetail,
+ month,
+ year,
+ type,
+ category,
+ } = state;
+ return (
+
+
+
+
+ record.rank}
+ dataSource={data.slice(0, Math.min(showSize, data.length))}
+ pagination={false}
+ loading={loading}
+ scroll={{ x: 'max-content' }}
+ />
+
+
+
+
+ {showSize < data.length ? (
+
+ {t('showMore') + '>>'}
+
+ ) : (
+
+ {t('noMore')}
+
+ )}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+}
+
+export default MyTable;
diff --git a/.history/src/components/table_20240727231007.js b/.history/src/components/table_20240727231007.js
new file mode 100644
index 0000000..aac4c4d
--- /dev/null
+++ b/.history/src/components/table_20240727231007.js
@@ -0,0 +1,653 @@
+import React, { useState, useEffect } from 'react';
+import { Col, message, Row, Table, Card } from 'antd';
+import MyAvatar from './avatar';
+import 'antd/dist/antd.css';
+import QAmiss from './QA2';
+import TablePanel from './TablePanel';
+import ArrowRender from './arrow';
+import PointRender from './changeNumber';
+import RoundFloat from './resolveFloat';
+import Trophy from './rankTrophy';
+import expandObject from '../util/expandObject';
+import { t } from 'i18next';
+import './table.css';
+
+const activityColumns = (object, t_month) => [
+ {
+ title: t('rank'),
+ dataIndex: 'rank',
+ width: '5%',
+ align: 'center',
+ render: Trophy,
+ fixed: 'left',
+ },
+ ...(object == 'actor'
+ ? [
+ {
+ title: t('avatar'),
+ dataIndex: 'id',
+ width: '5%',
+ align: 'center',
+ render: MyAvatar,
+ fixed: 'left',
+ },
+ ]
+ : []),
+ {
+ title: '',
+ dataIndex: 'rankDelta',
+ render: ArrowRender,
+ align: 'left',
+ width: '5%',
+ fixed: 'left',
+ },
+ {
+ title: t(object),
+ dataIndex: 'name',
+ align: 'center',
+ width: '20%',
+ render: function (text, row, index) {
+ if (object !== 'company') {
+ return (
+
+ {text}
+
+ );
+ } else {
+ return text;
+ }
+ },
+ },
+ ...(object == 'repo'
+ ? [
+ {
+ title: t('insight_board'),
+ dataIndex: 'name',
+ align: 'center',
+ width: '10%',
+ render: function (text, row, index) {
+ return dashboard(text, index, t_month);
+ },
+ },
+ ]
+ : []),
+ {
+ title: t('activity'),
+ dataIndex: 'value',
+ align: 'right',
+ width: '20%',
+ },
+ {
+ title: '',
+ dataIndex: 'valueDelta',
+ width: '10%',
+ align: 'left',
+ render: PointRender,
+ },
+];
+const activityDetailColumns = (object, t_month) => [
+ {
+ title: t('rank'),
+ dataIndex: 'rank',
+ width: '5%',
+ align: 'center',
+ render: Trophy,
+ fixed: 'left',
+ },
+ ...(object == 'actor'
+ ? [
+ {
+ title: t('avatar'),
+ dataIndex: 'id',
+ width: '5%',
+ align: 'center',
+ render: MyAvatar,
+ fixed: 'left',
+ },
+ ]
+ : []),
+ {
+ title: '',
+ dataIndex: 'rankDelta',
+ render: ArrowRender,
+ align: 'left',
+ width: '5%',
+ fixed: 'left',
+ },
+ {
+ title: t(object),
+ dataIndex: 'name',
+ align: 'center',
+ width: '5%',
+ render: function (text, row, index) {
+ if (object !== 'company') {
+ return (
+
+ {text}
+
+ );
+ } else {
+ return text;
+ }
+ },
+ },
+ ...(object == 'repo'
+ ? [
+ {
+ title: t('insight_board'),
+ dataIndex: 'name',
+ align: 'center',
+ width: '10%',
+ render: function (text, row, index) {
+ return dashboard(text, index, t_month);
+ },
+ },
+ ]
+ : []),
+ {
+ title: t('activity'),
+ dataIndex: 'value',
+ align: 'center',
+ width: '10%',
+ },
+ {
+ title: '',
+ dataIndex: 'valueDelta',
+ width: '10%',
+ align: 'left',
+ render: PointRender,
+ },
+ {
+ title: t('issue_comments'),
+ dataIndex: 'issue_comment',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('open_issues'),
+ dataIndex: 'open_issue',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('open_pulls'),
+ dataIndex: 'open_pull',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('merge_pulls'),
+ dataIndex: 'merged_pull',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('pr_reviews'),
+ dataIndex: 'review_comment',
+ width: '10%',
+ align: 'center',
+ },
+];
+const open_rankColumns = (object, t_month) => [
+ {
+ // 第一列:排名
+ title: t('rank'),
+ dataIndex: 'rank',
+ width: '5%',
+ render: Trophy,
+ align: 'center',
+ fixed: 'left',
+ },
+ // 如果 object 是 'actor',则添加头像列
+ ...(object == 'actor'
+ ? [
+ {
+ title: t('avatar'),
+ dataIndex: 'id',
+ width: '5%',
+ align: 'center',
+ render: MyAvatar,
+ fixed: 'left',
+ },
+ ]
+ : []),
+ // 第二列:排名变化
+ {
+ title: '',
+ dataIndex: 'rankDelta',
+ render: ArrowRender,
+ align: 'left',
+ width: '5%',
+ fixed: 'left',
+ },
+ // 第三列:对象名称(可能是 actor, repo 或 company)
+ {
+ title: t(object),
+ dataIndex: 'name',
+ width: '20%',
+ align: 'center',
+ render: function (text) {
+ if (object !== 'company') {
+ return (
+
+ {text}
+
+ );
+ } else {
+ return text;
+ }
+ },
+ },
+ // 如果 object 是 'repo',则添加 insight_board 列
+ ...(object == 'repo'
+ ? [
+ {
+ title: t('insight_board'),
+ dataIndex: 'name',
+ align: 'center',
+ width: '10%',
+ render: function (text, row, index) {
+ return dashboard(text, index, t_month);
+ },
+ },
+ ]
+ : []),
+ // 第四列:影响力
+ {
+ title: t('influence'),
+ dataIndex: 'value',
+ width: '20%',
+ align: 'right',
+ render: (text, row, index) => {
+ return RoundFloat(text);
+ },
+ },
+ // 第五列:影响力变化
+ {
+ title: '',
+ dataIndex: 'valueDelta',
+ width: '10%',
+ align: 'left',
+ render: (text, row, index) => {
+ text = RoundFloat(text);
+ return PointRender(text, row, index);
+ },
+ },
+];
+
+const solveDate = (year, month) => {
+ if (year === null && month === null) {
+ return 'not found';
+ }
+ if (month === null) {
+ return year + '年';
+ }
+ return year + '年' + (month + 1) + '月';
+};
+
+function dashboard(text, index, t_month) {
+ if (index < 300) {
+ let [org_name, repo_name] = text.split('/');
+ const t_month_copy = t_month + ' ' + '00:00:00';
+ let params = {
+ org_name,
+ repo_name,
+ t_month_copy,
+ t_month,
+ };
+ return (
+
+
+
+ );
+ }
+}
+
+function DateTitle(props) {
+ return {solveDate(props.year, props.month)}
;
+}
+
+function MyTable(props) {
+ const [state, setState] = useState({
+ object: 'technology',
+ index: 'open_rank',
+ region: 'global',
+ showDetail: false,
+ hasDetail: true,
+ data: [],
+ showSize: 25,
+ loading: true,
+ url: '', // base + index + object + region + yearmonth + .json
+ base: 'https://oss.x-lab.info/open_leaderboard/',
+ year: null, // 字符串格式
+ month: null, // 整数格式,0表示1月,1表示2月..., null for year type time
+ type: 'month',
+ search: null,
+ category: 'cloud-native',
+ });
+
+ // 请求一次数据更新表格。如果还没读取好配置文件则不请求数据。
+ useEffect(() => {
+ if (props.year == null && props.month == null) {
+ console.log('the first loading');
+ return;
+ }
+ updateDate({
+ year: String(props.year),
+ month: props.month,
+ });
+ }, [props]);
+
+ const expandData = () => {
+ setState({
+ ...state,
+ showSize: state.showSize + 25,
+ });
+ };
+ const updateDate = (newstate) => {
+ console.log('table update', newstate);
+ // 先获取原先的表格属性
+ let {
+ base,
+ object,
+ index,
+ region,
+ month,
+ year,
+ columns,
+ showDetail,
+ hasDetail,
+ type,
+ search,
+ category,
+ } = state;
+ // 然后把表格改为加载中的状态
+ setState({ ...state, ...newstate, loading: true });
+ // 如果 newstate 有对应的属性,则进行更新
+ if (newstate.hasOwnProperty('object')) object = newstate.object;
+ if (newstate.hasOwnProperty('index')) index = newstate.index;
+ if (newstate.hasOwnProperty('region')) region = newstate.region;
+ if (newstate.hasOwnProperty('month')) month = newstate.month;
+ if (newstate.hasOwnProperty('year')) year = newstate.year;
+ if (newstate.hasOwnProperty('showDetail')) showDetail = newstate.showDetail;
+ if (newstate.hasOwnProperty('type')) type = newstate.type;
+ if (newstate.hasOwnProperty('search')) search = newstate.search;
+ if (newstate.hasOwnProperty('category')) category = newstate.category;
+
+ //获取数据大屏的‘t_month’参数
+ let myyear = newstate.year == null ? state.year : newstate.year;
+ let mymonth = newstate.month == null ? state.month : newstate.month;
+
+ mymonth = ('' + (1 + mymonth)).padStart(2, '0');
+ let t_month = `${myyear}-${mymonth}-01`;
+
+ // 根据 index 和 showDetail 改变表格的 columns 格式
+ if (index == 'activity') {
+ columns = activityColumns(object, t_month);
+ hasDetail = true;
+ }
+ if (index == 'activity' && showDetail == true) {
+ columns = activityDetailColumns(object, t_month);
+ hasDetail = true;
+ }
+ if (index == 'open_rank') {
+ columns = open_rankColumns(object, t_month);
+ hasDetail = false;
+ showDetail = false;
+ }
+ // 如果是年份数据,则把 month 置为 null。
+ // TODO:待验证,如果从年份数据切换到月份数据,似乎会自动回到原来 month 值?
+ if (type == 'year') {
+ month = null;
+ }
+ // 以当前的属性构造请求 url
+ let url = base + index + '/' + object + '/' + region + '/';
+ if (month === null) {
+ url += year + '.json';
+ } else {
+ url += year + (1 + month) + '.json';
+ }
+ console.log(url);
+ console.log(region);
+ if (object == 'foundation' && region == 'chinese') {
+ url = 'https://github.com/xiaoAugenstern/open-leadboard-data/blob/main/foundation.json'
+ fetch(url, {
+ method: 'GET',
+ "Access-Control-Allow-Origin" : "*",
+ "Access-Control-Allow-Credentials" : true,
+ "Access-Control-Allow-Methods":"POST, GET, OPTIONS, DELETE, HEAD",
+ mode: "cors",
+ })
+ .then((res) => {
+ // Todo:最好的情况是在日期选择器中,只显示可以查询的日期,
+ if (res.status == 404) {
+ message.warning(t('no_result'));
+ return '';
+ }
+ return res.json();
+ })
+ .then((data) => {
+ data = data.data;
+ let dataSource = [];
+ // 预处理数据,对新上榜单数据进行特殊标记处理
+ data.map((obj) => {
+ obj = expandObject(obj);
+ if (obj.rankDelta == 0 && obj.value == obj.valueDelta) {
+ obj.rankDelta = -10000000;
+ obj.valueDelta = 0;
+ }
+ dataSource.push(obj);
+ });
+ console.log(dataSource);
+
+ //搜索特定数据
+ let queryData;
+ if (search) {
+ queryData = dataSource.filter((dataSource) => {
+ let reg = new RegExp(search.trim(), 'i');
+ return reg.test(dataSource.name);
+ });
+ if (queryData.length == 0) {
+ message.warning(t('no_result'));
+ } else {
+ dataSource = queryData;
+ }
+ }
+
+ // 更新属性和表格数据
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ showDetail: showDetail,
+ hasDetail: hasDetail,
+ data: dataSource,
+ });
+ })
+ .catch((err) => {
+ console.log('hi!' + err);
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ data: [],
+ });
+ });
+ }
+ // fetch 异步请求
+ else{fetch(url)
+ .then((res) => {
+ // Todo:最好的情况是在日期选择器中,只显示可以查询的日期,
+ if (res.status == 404) {
+ message.warning(t('no_result'));
+ return '';
+ }
+ return res.json();
+ })
+ .then((data) => {
+ data = data.data;
+ let dataSource = [];
+ // 预处理数据,对新上榜单数据进行特殊标记处理
+ data.map((obj) => {
+ obj = expandObject(obj);
+ if (obj.rankDelta == 0 && obj.value == obj.valueDelta) {
+ obj.rankDelta = -10000000;
+ obj.valueDelta = 0;
+ }
+ dataSource.push(obj);
+ });
+ console.log(dataSource);
+
+ //搜索特定数据
+ let queryData;
+ if (search) {
+ queryData = dataSource.filter((dataSource) => {
+ let reg = new RegExp(search.trim(), 'i');
+ return reg.test(dataSource.name);
+ });
+ if (queryData.length == 0) {
+ message.warning(t('no_result'));
+ } else {
+ dataSource = queryData;
+ }
+ }
+
+ // 更新属性和表格数据
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ showDetail: showDetail,
+ hasDetail: hasDetail,
+ data: dataSource,
+ });
+ })
+ .catch((err) => {
+ console.log('hi!' + err);
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ data: [],
+ });
+ });
+ }
+
+ };
+
+ const {
+ object,
+ index,
+ region,
+ data,
+ columns,
+ loading,
+ showSize,
+ showDetail,
+ hasDetail,
+ month,
+ year,
+ type,
+ category,
+ } = state;
+ return (
+
+
+
+
+ record.rank}
+ dataSource={data.slice(0, Math.min(showSize, data.length))}
+ pagination={false}
+ loading={loading}
+ scroll={{ x: 'max-content' }}
+ />
+
+
+
+
+ {showSize < data.length ? (
+
+ {t('showMore') + '>>'}
+
+ ) : (
+
+ {t('noMore')}
+
+ )}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+}
+
+export default MyTable;
diff --git a/.history/src/components/table_20240727231113.js b/.history/src/components/table_20240727231113.js
new file mode 100644
index 0000000..17eb9f8
--- /dev/null
+++ b/.history/src/components/table_20240727231113.js
@@ -0,0 +1,653 @@
+import React, { useState, useEffect } from 'react';
+import { Col, message, Row, Table, Card } from 'antd';
+import MyAvatar from './avatar';
+import 'antd/dist/antd.css';
+import QAmiss from './QA2';
+import TablePanel from './TablePanel';
+import ArrowRender from './arrow';
+import PointRender from './changeNumber';
+import RoundFloat from './resolveFloat';
+import Trophy from './rankTrophy';
+import expandObject from '../util/expandObject';
+import { t } from 'i18next';
+import './table.css';
+
+const activityColumns = (object, t_month) => [
+ {
+ title: t('rank'),
+ dataIndex: 'rank',
+ width: '5%',
+ align: 'center',
+ render: Trophy,
+ fixed: 'left',
+ },
+ ...(object == 'actor'
+ ? [
+ {
+ title: t('avatar'),
+ dataIndex: 'id',
+ width: '5%',
+ align: 'center',
+ render: MyAvatar,
+ fixed: 'left',
+ },
+ ]
+ : []),
+ {
+ title: '',
+ dataIndex: 'rankDelta',
+ render: ArrowRender,
+ align: 'left',
+ width: '5%',
+ fixed: 'left',
+ },
+ {
+ title: t(object),
+ dataIndex: 'name',
+ align: 'center',
+ width: '20%',
+ render: function (text, row, index) {
+ if (object !== 'company') {
+ return (
+
+ {text}
+
+ );
+ } else {
+ return text;
+ }
+ },
+ },
+ ...(object == 'repo'
+ ? [
+ {
+ title: t('insight_board'),
+ dataIndex: 'name',
+ align: 'center',
+ width: '10%',
+ render: function (text, row, index) {
+ return dashboard(text, index, t_month);
+ },
+ },
+ ]
+ : []),
+ {
+ title: t('activity'),
+ dataIndex: 'value',
+ align: 'right',
+ width: '20%',
+ },
+ {
+ title: '',
+ dataIndex: 'valueDelta',
+ width: '10%',
+ align: 'left',
+ render: PointRender,
+ },
+];
+const activityDetailColumns = (object, t_month) => [
+ {
+ title: t('rank'),
+ dataIndex: 'rank',
+ width: '5%',
+ align: 'center',
+ render: Trophy,
+ fixed: 'left',
+ },
+ ...(object == 'actor'
+ ? [
+ {
+ title: t('avatar'),
+ dataIndex: 'id',
+ width: '5%',
+ align: 'center',
+ render: MyAvatar,
+ fixed: 'left',
+ },
+ ]
+ : []),
+ {
+ title: '',
+ dataIndex: 'rankDelta',
+ render: ArrowRender,
+ align: 'left',
+ width: '5%',
+ fixed: 'left',
+ },
+ {
+ title: t(object),
+ dataIndex: 'name',
+ align: 'center',
+ width: '5%',
+ render: function (text, row, index) {
+ if (object !== 'company') {
+ return (
+
+ {text}
+
+ );
+ } else {
+ return text;
+ }
+ },
+ },
+ ...(object == 'repo'
+ ? [
+ {
+ title: t('insight_board'),
+ dataIndex: 'name',
+ align: 'center',
+ width: '10%',
+ render: function (text, row, index) {
+ return dashboard(text, index, t_month);
+ },
+ },
+ ]
+ : []),
+ {
+ title: t('activity'),
+ dataIndex: 'value',
+ align: 'center',
+ width: '10%',
+ },
+ {
+ title: '',
+ dataIndex: 'valueDelta',
+ width: '10%',
+ align: 'left',
+ render: PointRender,
+ },
+ {
+ title: t('issue_comments'),
+ dataIndex: 'issue_comment',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('open_issues'),
+ dataIndex: 'open_issue',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('open_pulls'),
+ dataIndex: 'open_pull',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('merge_pulls'),
+ dataIndex: 'merged_pull',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('pr_reviews'),
+ dataIndex: 'review_comment',
+ width: '10%',
+ align: 'center',
+ },
+];
+const open_rankColumns = (object, t_month) => [
+ {
+ // 第一列:排名
+ title: t('rank'),
+ dataIndex: 'rank',
+ width: '5%',
+ render: Trophy,
+ align: 'center',
+ fixed: 'left',
+ },
+ // 如果 object 是 'actor',则添加头像列
+ ...(object == 'actor'
+ ? [
+ {
+ title: t('avatar'),
+ dataIndex: 'id',
+ width: '5%',
+ align: 'center',
+ render: MyAvatar,
+ fixed: 'left',
+ },
+ ]
+ : []),
+ // 第二列:排名变化
+ {
+ title: '',
+ dataIndex: 'rankDelta',
+ render: ArrowRender,
+ align: 'left',
+ width: '5%',
+ fixed: 'left',
+ },
+ // 第三列:对象名称(可能是 actor, repo 或 company)
+ {
+ title: t(object),
+ dataIndex: 'name',
+ width: '20%',
+ align: 'center',
+ render: function (text) {
+ if (object !== 'company') {
+ return (
+
+ {text}
+
+ );
+ } else {
+ return text;
+ }
+ },
+ },
+ // 如果 object 是 'repo',则添加 insight_board 列
+ ...(object == 'repo'
+ ? [
+ {
+ title: t('insight_board'),
+ dataIndex: 'name',
+ align: 'center',
+ width: '10%',
+ render: function (text, row, index) {
+ return dashboard(text, index, t_month);
+ },
+ },
+ ]
+ : []),
+ // 第四列:影响力
+ {
+ title: t('influence'),
+ dataIndex: 'value',
+ width: '20%',
+ align: 'right',
+ render: (text, row, index) => {
+ return RoundFloat(text);
+ },
+ },
+ // 第五列:影响力变化
+ {
+ title: '',
+ dataIndex: 'valueDelta',
+ width: '10%',
+ align: 'left',
+ render: (text, row, index) => {
+ text = RoundFloat(text);
+ return PointRender(text, row, index);
+ },
+ },
+];
+
+const solveDate = (year, month) => {
+ if (year === null && month === null) {
+ return 'not found';
+ }
+ if (month === null) {
+ return year + '年';
+ }
+ return year + '年' + (month + 1) + '月';
+};
+
+function dashboard(text, index, t_month) {
+ if (index < 300) {
+ let [org_name, repo_name] = text.split('/');
+ const t_month_copy = t_month + ' ' + '00:00:00';
+ let params = {
+ org_name,
+ repo_name,
+ t_month_copy,
+ t_month,
+ };
+ return (
+
+
+
+ );
+ }
+}
+
+function DateTitle(props) {
+ return {solveDate(props.year, props.month)}
;
+}
+
+function MyTable(props) {
+ const [state, setState] = useState({
+ object: 'technology',
+ index: 'open_rank',
+ region: 'global',
+ showDetail: false,
+ hasDetail: true,
+ data: [],
+ showSize: 25,
+ loading: true,
+ url: '', // base + index + object + region + yearmonth + .json
+ base: 'https://oss.x-lab.info/open_leaderboard/',
+ year: null, // 字符串格式
+ month: null, // 整数格式,0表示1月,1表示2月..., null for year type time
+ type: 'month',
+ search: null,
+ category: 'cloud-native',
+ });
+
+ // 请求一次数据更新表格。如果还没读取好配置文件则不请求数据。
+ useEffect(() => {
+ if (props.year == null && props.month == null) {
+ console.log('the first loading');
+ return;
+ }
+ updateDate({
+ year: String(props.year),
+ month: props.month,
+ });
+ }, [props]);
+
+ const expandData = () => {
+ setState({
+ ...state,
+ showSize: state.showSize + 25,
+ });
+ };
+ const updateDate = (newstate) => {
+ console.log('table update', newstate);
+ // 先获取原先的表格属性
+ let {
+ base,
+ object,
+ index,
+ region,
+ month,
+ year,
+ columns,
+ showDetail,
+ hasDetail,
+ type,
+ search,
+ category,
+ } = state;
+ // 然后把表格改为加载中的状态
+ setState({ ...state, ...newstate, loading: true });
+ // 如果 newstate 有对应的属性,则进行更新
+ if (newstate.hasOwnProperty('object')) object = newstate.object;
+ if (newstate.hasOwnProperty('index')) index = newstate.index;
+ if (newstate.hasOwnProperty('region')) region = newstate.region;
+ if (newstate.hasOwnProperty('month')) month = newstate.month;
+ if (newstate.hasOwnProperty('year')) year = newstate.year;
+ if (newstate.hasOwnProperty('showDetail')) showDetail = newstate.showDetail;
+ if (newstate.hasOwnProperty('type')) type = newstate.type;
+ if (newstate.hasOwnProperty('search')) search = newstate.search;
+ if (newstate.hasOwnProperty('category')) category = newstate.category;
+
+ //获取数据大屏的‘t_month’参数
+ let myyear = newstate.year == null ? state.year : newstate.year;
+ let mymonth = newstate.month == null ? state.month : newstate.month;
+
+ mymonth = ('' + (1 + mymonth)).padStart(2, '0');
+ let t_month = `${myyear}-${mymonth}-01`;
+
+ // 根据 index 和 showDetail 改变表格的 columns 格式
+ if (index == 'activity') {
+ columns = activityColumns(object, t_month);
+ hasDetail = true;
+ }
+ if (index == 'activity' && showDetail == true) {
+ columns = activityDetailColumns(object, t_month);
+ hasDetail = true;
+ }
+ if (index == 'open_rank') {
+ columns = open_rankColumns(object, t_month);
+ hasDetail = false;
+ showDetail = false;
+ }
+ // 如果是年份数据,则把 month 置为 null。
+ // TODO:待验证,如果从年份数据切换到月份数据,似乎会自动回到原来 month 值?
+ if (type == 'year') {
+ month = null;
+ }
+ // 以当前的属性构造请求 url
+ let url = base + index + '/' + object + '/' + region + '/';
+ if (month === null) {
+ url += year + '.json';
+ } else {
+ url += year + (1 + month) + '.json';
+ }
+ console.log(url);
+ console.log(region);
+ if (object == 'foundation' && region == 'chinese') {
+ url = 'https://oss.x-lab.info/open_leaderboard/open_rank/repo/chinese/20246.json'
+ fetch(url, {
+ method: 'GET',
+ "Access-Control-Allow-Origin" : "*",
+ "Access-Control-Allow-Credentials" : true,
+ "Access-Control-Allow-Methods":"POST, GET, OPTIONS, DELETE, HEAD",
+ mode: "cors",
+ })
+ .then((res) => {
+ // Todo:最好的情况是在日期选择器中,只显示可以查询的日期,
+ if (res.status == 404) {
+ message.warning(t('no_result'));
+ return '';
+ }
+ return res.json();
+ })
+ .then((data) => {
+ data = data.data;
+ let dataSource = [];
+ // 预处理数据,对新上榜单数据进行特殊标记处理
+ data.map((obj) => {
+ obj = expandObject(obj);
+ if (obj.rankDelta == 0 && obj.value == obj.valueDelta) {
+ obj.rankDelta = -10000000;
+ obj.valueDelta = 0;
+ }
+ dataSource.push(obj);
+ });
+ console.log(dataSource);
+
+ //搜索特定数据
+ let queryData;
+ if (search) {
+ queryData = dataSource.filter((dataSource) => {
+ let reg = new RegExp(search.trim(), 'i');
+ return reg.test(dataSource.name);
+ });
+ if (queryData.length == 0) {
+ message.warning(t('no_result'));
+ } else {
+ dataSource = queryData;
+ }
+ }
+
+ // 更新属性和表格数据
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ showDetail: showDetail,
+ hasDetail: hasDetail,
+ data: dataSource,
+ });
+ })
+ .catch((err) => {
+ console.log('hi!' + err);
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ data: [],
+ });
+ });
+ }
+ // fetch 异步请求
+ else{fetch(url)
+ .then((res) => {
+ // Todo:最好的情况是在日期选择器中,只显示可以查询的日期,
+ if (res.status == 404) {
+ message.warning(t('no_result'));
+ return '';
+ }
+ return res.json();
+ })
+ .then((data) => {
+ data = data.data;
+ let dataSource = [];
+ // 预处理数据,对新上榜单数据进行特殊标记处理
+ data.map((obj) => {
+ obj = expandObject(obj);
+ if (obj.rankDelta == 0 && obj.value == obj.valueDelta) {
+ obj.rankDelta = -10000000;
+ obj.valueDelta = 0;
+ }
+ dataSource.push(obj);
+ });
+ console.log(dataSource);
+
+ //搜索特定数据
+ let queryData;
+ if (search) {
+ queryData = dataSource.filter((dataSource) => {
+ let reg = new RegExp(search.trim(), 'i');
+ return reg.test(dataSource.name);
+ });
+ if (queryData.length == 0) {
+ message.warning(t('no_result'));
+ } else {
+ dataSource = queryData;
+ }
+ }
+
+ // 更新属性和表格数据
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ showDetail: showDetail,
+ hasDetail: hasDetail,
+ data: dataSource,
+ });
+ })
+ .catch((err) => {
+ console.log('hi!' + err);
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ data: [],
+ });
+ });
+ }
+
+ };
+
+ const {
+ object,
+ index,
+ region,
+ data,
+ columns,
+ loading,
+ showSize,
+ showDetail,
+ hasDetail,
+ month,
+ year,
+ type,
+ category,
+ } = state;
+ return (
+
+
+
+
+ record.rank}
+ dataSource={data.slice(0, Math.min(showSize, data.length))}
+ pagination={false}
+ loading={loading}
+ scroll={{ x: 'max-content' }}
+ />
+
+
+
+
+ {showSize < data.length ? (
+
+ {t('showMore') + '>>'}
+
+ ) : (
+
+ {t('noMore')}
+
+ )}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+}
+
+export default MyTable;
diff --git a/.history/src/components/table_20240727231156.js b/.history/src/components/table_20240727231156.js
new file mode 100644
index 0000000..ee8e5c0
--- /dev/null
+++ b/.history/src/components/table_20240727231156.js
@@ -0,0 +1,589 @@
+import React, { useState, useEffect } from 'react';
+import { Col, message, Row, Table, Card } from 'antd';
+import MyAvatar from './avatar';
+import 'antd/dist/antd.css';
+import QAmiss from './QA2';
+import TablePanel from './TablePanel';
+import ArrowRender from './arrow';
+import PointRender from './changeNumber';
+import RoundFloat from './resolveFloat';
+import Trophy from './rankTrophy';
+import expandObject from '../util/expandObject';
+import { t } from 'i18next';
+import './table.css';
+
+const activityColumns = (object, t_month) => [
+ {
+ title: t('rank'),
+ dataIndex: 'rank',
+ width: '5%',
+ align: 'center',
+ render: Trophy,
+ fixed: 'left',
+ },
+ ...(object == 'actor'
+ ? [
+ {
+ title: t('avatar'),
+ dataIndex: 'id',
+ width: '5%',
+ align: 'center',
+ render: MyAvatar,
+ fixed: 'left',
+ },
+ ]
+ : []),
+ {
+ title: '',
+ dataIndex: 'rankDelta',
+ render: ArrowRender,
+ align: 'left',
+ width: '5%',
+ fixed: 'left',
+ },
+ {
+ title: t(object),
+ dataIndex: 'name',
+ align: 'center',
+ width: '20%',
+ render: function (text, row, index) {
+ if (object !== 'company') {
+ return (
+
+ {text}
+
+ );
+ } else {
+ return text;
+ }
+ },
+ },
+ ...(object == 'repo'
+ ? [
+ {
+ title: t('insight_board'),
+ dataIndex: 'name',
+ align: 'center',
+ width: '10%',
+ render: function (text, row, index) {
+ return dashboard(text, index, t_month);
+ },
+ },
+ ]
+ : []),
+ {
+ title: t('activity'),
+ dataIndex: 'value',
+ align: 'right',
+ width: '20%',
+ },
+ {
+ title: '',
+ dataIndex: 'valueDelta',
+ width: '10%',
+ align: 'left',
+ render: PointRender,
+ },
+];
+const activityDetailColumns = (object, t_month) => [
+ {
+ title: t('rank'),
+ dataIndex: 'rank',
+ width: '5%',
+ align: 'center',
+ render: Trophy,
+ fixed: 'left',
+ },
+ ...(object == 'actor'
+ ? [
+ {
+ title: t('avatar'),
+ dataIndex: 'id',
+ width: '5%',
+ align: 'center',
+ render: MyAvatar,
+ fixed: 'left',
+ },
+ ]
+ : []),
+ {
+ title: '',
+ dataIndex: 'rankDelta',
+ render: ArrowRender,
+ align: 'left',
+ width: '5%',
+ fixed: 'left',
+ },
+ {
+ title: t(object),
+ dataIndex: 'name',
+ align: 'center',
+ width: '5%',
+ render: function (text, row, index) {
+ if (object !== 'company') {
+ return (
+
+ {text}
+
+ );
+ } else {
+ return text;
+ }
+ },
+ },
+ ...(object == 'repo'
+ ? [
+ {
+ title: t('insight_board'),
+ dataIndex: 'name',
+ align: 'center',
+ width: '10%',
+ render: function (text, row, index) {
+ return dashboard(text, index, t_month);
+ },
+ },
+ ]
+ : []),
+ {
+ title: t('activity'),
+ dataIndex: 'value',
+ align: 'center',
+ width: '10%',
+ },
+ {
+ title: '',
+ dataIndex: 'valueDelta',
+ width: '10%',
+ align: 'left',
+ render: PointRender,
+ },
+ {
+ title: t('issue_comments'),
+ dataIndex: 'issue_comment',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('open_issues'),
+ dataIndex: 'open_issue',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('open_pulls'),
+ dataIndex: 'open_pull',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('merge_pulls'),
+ dataIndex: 'merged_pull',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('pr_reviews'),
+ dataIndex: 'review_comment',
+ width: '10%',
+ align: 'center',
+ },
+];
+const open_rankColumns = (object, t_month) => [
+ {
+ // 第一列:排名
+ title: t('rank'),
+ dataIndex: 'rank',
+ width: '5%',
+ render: Trophy,
+ align: 'center',
+ fixed: 'left',
+ },
+ // 如果 object 是 'actor',则添加头像列
+ ...(object == 'actor'
+ ? [
+ {
+ title: t('avatar'),
+ dataIndex: 'id',
+ width: '5%',
+ align: 'center',
+ render: MyAvatar,
+ fixed: 'left',
+ },
+ ]
+ : []),
+ // 第二列:排名变化
+ {
+ title: '',
+ dataIndex: 'rankDelta',
+ render: ArrowRender,
+ align: 'left',
+ width: '5%',
+ fixed: 'left',
+ },
+ // 第三列:对象名称(可能是 actor, repo 或 company)
+ {
+ title: t(object),
+ dataIndex: 'name',
+ width: '20%',
+ align: 'center',
+ render: function (text) {
+ if (object !== 'company') {
+ return (
+
+ {text}
+
+ );
+ } else {
+ return text;
+ }
+ },
+ },
+ // 如果 object 是 'repo',则添加 insight_board 列
+ ...(object == 'repo'
+ ? [
+ {
+ title: t('insight_board'),
+ dataIndex: 'name',
+ align: 'center',
+ width: '10%',
+ render: function (text, row, index) {
+ return dashboard(text, index, t_month);
+ },
+ },
+ ]
+ : []),
+ // 第四列:影响力
+ {
+ title: t('influence'),
+ dataIndex: 'value',
+ width: '20%',
+ align: 'right',
+ render: (text, row, index) => {
+ return RoundFloat(text);
+ },
+ },
+ // 第五列:影响力变化
+ {
+ title: '',
+ dataIndex: 'valueDelta',
+ width: '10%',
+ align: 'left',
+ render: (text, row, index) => {
+ text = RoundFloat(text);
+ return PointRender(text, row, index);
+ },
+ },
+];
+
+const solveDate = (year, month) => {
+ if (year === null && month === null) {
+ return 'not found';
+ }
+ if (month === null) {
+ return year + '年';
+ }
+ return year + '年' + (month + 1) + '月';
+};
+
+function dashboard(text, index, t_month) {
+ if (index < 300) {
+ let [org_name, repo_name] = text.split('/');
+ const t_month_copy = t_month + ' ' + '00:00:00';
+ let params = {
+ org_name,
+ repo_name,
+ t_month_copy,
+ t_month,
+ };
+ return (
+
+
+
+ );
+ }
+}
+
+function DateTitle(props) {
+ return {solveDate(props.year, props.month)}
;
+}
+
+function MyTable(props) {
+ const [state, setState] = useState({
+ object: 'technology',
+ index: 'open_rank',
+ region: 'global',
+ showDetail: false,
+ hasDetail: true,
+ data: [],
+ showSize: 25,
+ loading: true,
+ url: '', // base + index + object + region + yearmonth + .json
+ base: 'https://oss.x-lab.info/open_leaderboard/',
+ year: null, // 字符串格式
+ month: null, // 整数格式,0表示1月,1表示2月..., null for year type time
+ type: 'month',
+ search: null,
+ category: 'cloud-native',
+ });
+
+ // 请求一次数据更新表格。如果还没读取好配置文件则不请求数据。
+ useEffect(() => {
+ if (props.year == null && props.month == null) {
+ console.log('the first loading');
+ return;
+ }
+ updateDate({
+ year: String(props.year),
+ month: props.month,
+ });
+ }, [props]);
+
+ const expandData = () => {
+ setState({
+ ...state,
+ showSize: state.showSize + 25,
+ });
+ };
+ const updateDate = (newstate) => {
+ console.log('table update', newstate);
+ // 先获取原先的表格属性
+ let {
+ base,
+ object,
+ index,
+ region,
+ month,
+ year,
+ columns,
+ showDetail,
+ hasDetail,
+ type,
+ search,
+ category,
+ } = state;
+ // 然后把表格改为加载中的状态
+ setState({ ...state, ...newstate, loading: true });
+ // 如果 newstate 有对应的属性,则进行更新
+ if (newstate.hasOwnProperty('object')) object = newstate.object;
+ if (newstate.hasOwnProperty('index')) index = newstate.index;
+ if (newstate.hasOwnProperty('region')) region = newstate.region;
+ if (newstate.hasOwnProperty('month')) month = newstate.month;
+ if (newstate.hasOwnProperty('year')) year = newstate.year;
+ if (newstate.hasOwnProperty('showDetail')) showDetail = newstate.showDetail;
+ if (newstate.hasOwnProperty('type')) type = newstate.type;
+ if (newstate.hasOwnProperty('search')) search = newstate.search;
+ if (newstate.hasOwnProperty('category')) category = newstate.category;
+
+ //获取数据大屏的‘t_month’参数
+ let myyear = newstate.year == null ? state.year : newstate.year;
+ let mymonth = newstate.month == null ? state.month : newstate.month;
+
+ mymonth = ('' + (1 + mymonth)).padStart(2, '0');
+ let t_month = `${myyear}-${mymonth}-01`;
+
+ // 根据 index 和 showDetail 改变表格的 columns 格式
+ if (index == 'activity') {
+ columns = activityColumns(object, t_month);
+ hasDetail = true;
+ }
+ if (index == 'activity' && showDetail == true) {
+ columns = activityDetailColumns(object, t_month);
+ hasDetail = true;
+ }
+ if (index == 'open_rank') {
+ columns = open_rankColumns(object, t_month);
+ hasDetail = false;
+ showDetail = false;
+ }
+ // 如果是年份数据,则把 month 置为 null。
+ // TODO:待验证,如果从年份数据切换到月份数据,似乎会自动回到原来 month 值?
+ if (type == 'year') {
+ month = null;
+ }
+ // 以当前的属性构造请求 url
+ let url = base + index + '/' + object + '/' + region + '/';
+ if (month === null) {
+ url += year + '.json';
+ } else {
+ url += year + (1 + month) + '.json';
+ }
+ console.log(url);
+ console.log(region);
+ if (object == 'foundation' && region == 'chinese') {
+ url = 'https://oss.x-lab.info/open_leaderboard/open_rank/repo/chinese/20246.json'
+ }
+ // fetch 异步请求
+ else{fetch(url)
+ .then((res) => {
+ // Todo:最好的情况是在日期选择器中,只显示可以查询的日期,
+ if (res.status == 404) {
+ message.warning(t('no_result'));
+ return '';
+ }
+ return res.json();
+ })
+ .then((data) => {
+ data = data.data;
+ let dataSource = [];
+ // 预处理数据,对新上榜单数据进行特殊标记处理
+ data.map((obj) => {
+ obj = expandObject(obj);
+ if (obj.rankDelta == 0 && obj.value == obj.valueDelta) {
+ obj.rankDelta = -10000000;
+ obj.valueDelta = 0;
+ }
+ dataSource.push(obj);
+ });
+ console.log(dataSource);
+
+ //搜索特定数据
+ let queryData;
+ if (search) {
+ queryData = dataSource.filter((dataSource) => {
+ let reg = new RegExp(search.trim(), 'i');
+ return reg.test(dataSource.name);
+ });
+ if (queryData.length == 0) {
+ message.warning(t('no_result'));
+ } else {
+ dataSource = queryData;
+ }
+ }
+
+ // 更新属性和表格数据
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ showDetail: showDetail,
+ hasDetail: hasDetail,
+ data: dataSource,
+ });
+ })
+ .catch((err) => {
+ console.log('hi!' + err);
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ data: [],
+ });
+ });
+ }
+
+ };
+
+ const {
+ object,
+ index,
+ region,
+ data,
+ columns,
+ loading,
+ showSize,
+ showDetail,
+ hasDetail,
+ month,
+ year,
+ type,
+ category,
+ } = state;
+ return (
+
+
+
+
+ record.rank}
+ dataSource={data.slice(0, Math.min(showSize, data.length))}
+ pagination={false}
+ loading={loading}
+ scroll={{ x: 'max-content' }}
+ />
+
+
+
+
+ {showSize < data.length ? (
+
+ {t('showMore') + '>>'}
+
+ ) : (
+
+ {t('noMore')}
+
+ )}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+}
+
+export default MyTable;
diff --git a/.history/src/components/table_20240727231303.js b/.history/src/components/table_20240727231303.js
new file mode 100644
index 0000000..1762022
--- /dev/null
+++ b/.history/src/components/table_20240727231303.js
@@ -0,0 +1,589 @@
+import React, { useState, useEffect } from 'react';
+import { Col, message, Row, Table, Card } from 'antd';
+import MyAvatar from './avatar';
+import 'antd/dist/antd.css';
+import QAmiss from './QA2';
+import TablePanel from './TablePanel';
+import ArrowRender from './arrow';
+import PointRender from './changeNumber';
+import RoundFloat from './resolveFloat';
+import Trophy from './rankTrophy';
+import expandObject from '../util/expandObject';
+import { t } from 'i18next';
+import './table.css';
+
+const activityColumns = (object, t_month) => [
+ {
+ title: t('rank'),
+ dataIndex: 'rank',
+ width: '5%',
+ align: 'center',
+ render: Trophy,
+ fixed: 'left',
+ },
+ ...(object == 'actor'
+ ? [
+ {
+ title: t('avatar'),
+ dataIndex: 'id',
+ width: '5%',
+ align: 'center',
+ render: MyAvatar,
+ fixed: 'left',
+ },
+ ]
+ : []),
+ {
+ title: '',
+ dataIndex: 'rankDelta',
+ render: ArrowRender,
+ align: 'left',
+ width: '5%',
+ fixed: 'left',
+ },
+ {
+ title: t(object),
+ dataIndex: 'name',
+ align: 'center',
+ width: '20%',
+ render: function (text, row, index) {
+ if (object !== 'company') {
+ return (
+
+ {text}
+
+ );
+ } else {
+ return text;
+ }
+ },
+ },
+ ...(object == 'repo'
+ ? [
+ {
+ title: t('insight_board'),
+ dataIndex: 'name',
+ align: 'center',
+ width: '10%',
+ render: function (text, row, index) {
+ return dashboard(text, index, t_month);
+ },
+ },
+ ]
+ : []),
+ {
+ title: t('activity'),
+ dataIndex: 'value',
+ align: 'right',
+ width: '20%',
+ },
+ {
+ title: '',
+ dataIndex: 'valueDelta',
+ width: '10%',
+ align: 'left',
+ render: PointRender,
+ },
+];
+const activityDetailColumns = (object, t_month) => [
+ {
+ title: t('rank'),
+ dataIndex: 'rank',
+ width: '5%',
+ align: 'center',
+ render: Trophy,
+ fixed: 'left',
+ },
+ ...(object == 'actor'
+ ? [
+ {
+ title: t('avatar'),
+ dataIndex: 'id',
+ width: '5%',
+ align: 'center',
+ render: MyAvatar,
+ fixed: 'left',
+ },
+ ]
+ : []),
+ {
+ title: '',
+ dataIndex: 'rankDelta',
+ render: ArrowRender,
+ align: 'left',
+ width: '5%',
+ fixed: 'left',
+ },
+ {
+ title: t(object),
+ dataIndex: 'name',
+ align: 'center',
+ width: '5%',
+ render: function (text, row, index) {
+ if (object !== 'company') {
+ return (
+
+ {text}
+
+ );
+ } else {
+ return text;
+ }
+ },
+ },
+ ...(object == 'repo'
+ ? [
+ {
+ title: t('insight_board'),
+ dataIndex: 'name',
+ align: 'center',
+ width: '10%',
+ render: function (text, row, index) {
+ return dashboard(text, index, t_month);
+ },
+ },
+ ]
+ : []),
+ {
+ title: t('activity'),
+ dataIndex: 'value',
+ align: 'center',
+ width: '10%',
+ },
+ {
+ title: '',
+ dataIndex: 'valueDelta',
+ width: '10%',
+ align: 'left',
+ render: PointRender,
+ },
+ {
+ title: t('issue_comments'),
+ dataIndex: 'issue_comment',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('open_issues'),
+ dataIndex: 'open_issue',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('open_pulls'),
+ dataIndex: 'open_pull',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('merge_pulls'),
+ dataIndex: 'merged_pull',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('pr_reviews'),
+ dataIndex: 'review_comment',
+ width: '10%',
+ align: 'center',
+ },
+];
+const open_rankColumns = (object, t_month) => [
+ {
+ // 第一列:排名
+ title: t('rank'),
+ dataIndex: 'rank',
+ width: '5%',
+ render: Trophy,
+ align: 'center',
+ fixed: 'left',
+ },
+ // 如果 object 是 'actor',则添加头像列
+ ...(object == 'actor'
+ ? [
+ {
+ title: t('avatar'),
+ dataIndex: 'id',
+ width: '5%',
+ align: 'center',
+ render: MyAvatar,
+ fixed: 'left',
+ },
+ ]
+ : []),
+ // 第二列:排名变化
+ {
+ title: '',
+ dataIndex: 'rankDelta',
+ render: ArrowRender,
+ align: 'left',
+ width: '5%',
+ fixed: 'left',
+ },
+ // 第三列:对象名称(可能是 actor, repo 或 company)
+ {
+ title: t(object),
+ dataIndex: 'name',
+ width: '20%',
+ align: 'center',
+ render: function (text) {
+ if (object !== 'company') {
+ return (
+
+ {text}
+
+ );
+ } else {
+ return text;
+ }
+ },
+ },
+ // 如果 object 是 'repo',则添加 insight_board 列
+ ...(object == 'repo'
+ ? [
+ {
+ title: t('insight_board'),
+ dataIndex: 'name',
+ align: 'center',
+ width: '10%',
+ render: function (text, row, index) {
+ return dashboard(text, index, t_month);
+ },
+ },
+ ]
+ : []),
+ // 第四列:影响力
+ {
+ title: t('influence'),
+ dataIndex: 'value',
+ width: '20%',
+ align: 'right',
+ render: (text, row, index) => {
+ return RoundFloat(text);
+ },
+ },
+ // 第五列:影响力变化
+ {
+ title: '',
+ dataIndex: 'valueDelta',
+ width: '10%',
+ align: 'left',
+ render: (text, row, index) => {
+ text = RoundFloat(text);
+ return PointRender(text, row, index);
+ },
+ },
+];
+
+const solveDate = (year, month) => {
+ if (year === null && month === null) {
+ return 'not found';
+ }
+ if (month === null) {
+ return year + '年';
+ }
+ return year + '年' + (month + 1) + '月';
+};
+
+function dashboard(text, index, t_month) {
+ if (index < 300) {
+ let [org_name, repo_name] = text.split('/');
+ const t_month_copy = t_month + ' ' + '00:00:00';
+ let params = {
+ org_name,
+ repo_name,
+ t_month_copy,
+ t_month,
+ };
+ return (
+
+
+
+ );
+ }
+}
+
+function DateTitle(props) {
+ return {solveDate(props.year, props.month)}
;
+}
+
+function MyTable(props) {
+ const [state, setState] = useState({
+ object: 'technology',
+ index: 'open_rank',
+ region: 'global',
+ showDetail: false,
+ hasDetail: true,
+ data: [],
+ showSize: 25,
+ loading: true,
+ url: '', // base + index + object + region + yearmonth + .json
+ base: 'https://oss.x-lab.info/open_leaderboard/',
+ year: null, // 字符串格式
+ month: null, // 整数格式,0表示1月,1表示2月..., null for year type time
+ type: 'month',
+ search: null,
+ category: 'cloud-native',
+ });
+
+ // 请求一次数据更新表格。如果还没读取好配置文件则不请求数据。
+ useEffect(() => {
+ if (props.year == null && props.month == null) {
+ console.log('the first loading');
+ return;
+ }
+ updateDate({
+ year: String(props.year),
+ month: props.month,
+ });
+ }, [props]);
+
+ const expandData = () => {
+ setState({
+ ...state,
+ showSize: state.showSize + 25,
+ });
+ };
+ const updateDate = (newstate) => {
+ console.log('table update', newstate);
+ // 先获取原先的表格属性
+ let {
+ base,
+ object,
+ index,
+ region,
+ month,
+ year,
+ columns,
+ showDetail,
+ hasDetail,
+ type,
+ search,
+ category,
+ } = state;
+ // 然后把表格改为加载中的状态
+ setState({ ...state, ...newstate, loading: true });
+ // 如果 newstate 有对应的属性,则进行更新
+ if (newstate.hasOwnProperty('object')) object = newstate.object;
+ if (newstate.hasOwnProperty('index')) index = newstate.index;
+ if (newstate.hasOwnProperty('region')) region = newstate.region;
+ if (newstate.hasOwnProperty('month')) month = newstate.month;
+ if (newstate.hasOwnProperty('year')) year = newstate.year;
+ if (newstate.hasOwnProperty('showDetail')) showDetail = newstate.showDetail;
+ if (newstate.hasOwnProperty('type')) type = newstate.type;
+ if (newstate.hasOwnProperty('search')) search = newstate.search;
+ if (newstate.hasOwnProperty('category')) category = newstate.category;
+
+ //获取数据大屏的‘t_month’参数
+ let myyear = newstate.year == null ? state.year : newstate.year;
+ let mymonth = newstate.month == null ? state.month : newstate.month;
+
+ mymonth = ('' + (1 + mymonth)).padStart(2, '0');
+ let t_month = `${myyear}-${mymonth}-01`;
+
+ // 根据 index 和 showDetail 改变表格的 columns 格式
+ if (index == 'activity') {
+ columns = activityColumns(object, t_month);
+ hasDetail = true;
+ }
+ if (index == 'activity' && showDetail == true) {
+ columns = activityDetailColumns(object, t_month);
+ hasDetail = true;
+ }
+ if (index == 'open_rank') {
+ columns = open_rankColumns(object, t_month);
+ hasDetail = false;
+ showDetail = false;
+ }
+ // 如果是年份数据,则把 month 置为 null。
+ // TODO:待验证,如果从年份数据切换到月份数据,似乎会自动回到原来 month 值?
+ if (type == 'year') {
+ month = null;
+ }
+ // 以当前的属性构造请求 url
+ let url = base + index + '/' + object + '/' + region + '/';
+ if (month === null) {
+ url += year + '.json';
+ } else {
+ url += year + (1 + month) + '.json';
+ }
+ console.log(url);
+ console.log(region);
+ if (object == 'foundation' && region == 'chinese') {
+ url = 'https://oss.x-lab.info/open_leaderboard/open_rank/repo/chinese/20246.json'
+ }
+ // fetch 异步请求
+ fetch(url)
+ .then((res) => {
+ // Todo:最好的情况是在日期选择器中,只显示可以查询的日期,
+ if (res.status == 404) {
+ message.warning(t('no_result'));
+ return '';
+ }
+ return res.json();
+ })
+ .then((data) => {
+ data = data.data;
+ let dataSource = [];
+ // 预处理数据,对新上榜单数据进行特殊标记处理
+ data.map((obj) => {
+ obj = expandObject(obj);
+ if (obj.rankDelta == 0 && obj.value == obj.valueDelta) {
+ obj.rankDelta = -10000000;
+ obj.valueDelta = 0;
+ }
+ dataSource.push(obj);
+ });
+ console.log(dataSource);
+
+ //搜索特定数据
+ let queryData;
+ if (search) {
+ queryData = dataSource.filter((dataSource) => {
+ let reg = new RegExp(search.trim(), 'i');
+ return reg.test(dataSource.name);
+ });
+ if (queryData.length == 0) {
+ message.warning(t('no_result'));
+ } else {
+ dataSource = queryData;
+ }
+ }
+
+ // 更新属性和表格数据
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ showDetail: showDetail,
+ hasDetail: hasDetail,
+ data: dataSource,
+ });
+ })
+ .catch((err) => {
+ console.log('hi!' + err);
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ data: [],
+ });
+ });
+
+
+ };
+
+ const {
+ object,
+ index,
+ region,
+ data,
+ columns,
+ loading,
+ showSize,
+ showDetail,
+ hasDetail,
+ month,
+ year,
+ type,
+ category,
+ } = state;
+ return (
+
+
+
+
+ record.rank}
+ dataSource={data.slice(0, Math.min(showSize, data.length))}
+ pagination={false}
+ loading={loading}
+ scroll={{ x: 'max-content' }}
+ />
+
+
+
+
+ {showSize < data.length ? (
+
+ {t('showMore') + '>>'}
+
+ ) : (
+
+ {t('noMore')}
+
+ )}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+}
+
+export default MyTable;
diff --git a/.history/src/components/table_20240727231305.js b/.history/src/components/table_20240727231305.js
new file mode 100644
index 0000000..1762022
--- /dev/null
+++ b/.history/src/components/table_20240727231305.js
@@ -0,0 +1,589 @@
+import React, { useState, useEffect } from 'react';
+import { Col, message, Row, Table, Card } from 'antd';
+import MyAvatar from './avatar';
+import 'antd/dist/antd.css';
+import QAmiss from './QA2';
+import TablePanel from './TablePanel';
+import ArrowRender from './arrow';
+import PointRender from './changeNumber';
+import RoundFloat from './resolveFloat';
+import Trophy from './rankTrophy';
+import expandObject from '../util/expandObject';
+import { t } from 'i18next';
+import './table.css';
+
+const activityColumns = (object, t_month) => [
+ {
+ title: t('rank'),
+ dataIndex: 'rank',
+ width: '5%',
+ align: 'center',
+ render: Trophy,
+ fixed: 'left',
+ },
+ ...(object == 'actor'
+ ? [
+ {
+ title: t('avatar'),
+ dataIndex: 'id',
+ width: '5%',
+ align: 'center',
+ render: MyAvatar,
+ fixed: 'left',
+ },
+ ]
+ : []),
+ {
+ title: '',
+ dataIndex: 'rankDelta',
+ render: ArrowRender,
+ align: 'left',
+ width: '5%',
+ fixed: 'left',
+ },
+ {
+ title: t(object),
+ dataIndex: 'name',
+ align: 'center',
+ width: '20%',
+ render: function (text, row, index) {
+ if (object !== 'company') {
+ return (
+
+ {text}
+
+ );
+ } else {
+ return text;
+ }
+ },
+ },
+ ...(object == 'repo'
+ ? [
+ {
+ title: t('insight_board'),
+ dataIndex: 'name',
+ align: 'center',
+ width: '10%',
+ render: function (text, row, index) {
+ return dashboard(text, index, t_month);
+ },
+ },
+ ]
+ : []),
+ {
+ title: t('activity'),
+ dataIndex: 'value',
+ align: 'right',
+ width: '20%',
+ },
+ {
+ title: '',
+ dataIndex: 'valueDelta',
+ width: '10%',
+ align: 'left',
+ render: PointRender,
+ },
+];
+const activityDetailColumns = (object, t_month) => [
+ {
+ title: t('rank'),
+ dataIndex: 'rank',
+ width: '5%',
+ align: 'center',
+ render: Trophy,
+ fixed: 'left',
+ },
+ ...(object == 'actor'
+ ? [
+ {
+ title: t('avatar'),
+ dataIndex: 'id',
+ width: '5%',
+ align: 'center',
+ render: MyAvatar,
+ fixed: 'left',
+ },
+ ]
+ : []),
+ {
+ title: '',
+ dataIndex: 'rankDelta',
+ render: ArrowRender,
+ align: 'left',
+ width: '5%',
+ fixed: 'left',
+ },
+ {
+ title: t(object),
+ dataIndex: 'name',
+ align: 'center',
+ width: '5%',
+ render: function (text, row, index) {
+ if (object !== 'company') {
+ return (
+
+ {text}
+
+ );
+ } else {
+ return text;
+ }
+ },
+ },
+ ...(object == 'repo'
+ ? [
+ {
+ title: t('insight_board'),
+ dataIndex: 'name',
+ align: 'center',
+ width: '10%',
+ render: function (text, row, index) {
+ return dashboard(text, index, t_month);
+ },
+ },
+ ]
+ : []),
+ {
+ title: t('activity'),
+ dataIndex: 'value',
+ align: 'center',
+ width: '10%',
+ },
+ {
+ title: '',
+ dataIndex: 'valueDelta',
+ width: '10%',
+ align: 'left',
+ render: PointRender,
+ },
+ {
+ title: t('issue_comments'),
+ dataIndex: 'issue_comment',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('open_issues'),
+ dataIndex: 'open_issue',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('open_pulls'),
+ dataIndex: 'open_pull',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('merge_pulls'),
+ dataIndex: 'merged_pull',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('pr_reviews'),
+ dataIndex: 'review_comment',
+ width: '10%',
+ align: 'center',
+ },
+];
+const open_rankColumns = (object, t_month) => [
+ {
+ // 第一列:排名
+ title: t('rank'),
+ dataIndex: 'rank',
+ width: '5%',
+ render: Trophy,
+ align: 'center',
+ fixed: 'left',
+ },
+ // 如果 object 是 'actor',则添加头像列
+ ...(object == 'actor'
+ ? [
+ {
+ title: t('avatar'),
+ dataIndex: 'id',
+ width: '5%',
+ align: 'center',
+ render: MyAvatar,
+ fixed: 'left',
+ },
+ ]
+ : []),
+ // 第二列:排名变化
+ {
+ title: '',
+ dataIndex: 'rankDelta',
+ render: ArrowRender,
+ align: 'left',
+ width: '5%',
+ fixed: 'left',
+ },
+ // 第三列:对象名称(可能是 actor, repo 或 company)
+ {
+ title: t(object),
+ dataIndex: 'name',
+ width: '20%',
+ align: 'center',
+ render: function (text) {
+ if (object !== 'company') {
+ return (
+
+ {text}
+
+ );
+ } else {
+ return text;
+ }
+ },
+ },
+ // 如果 object 是 'repo',则添加 insight_board 列
+ ...(object == 'repo'
+ ? [
+ {
+ title: t('insight_board'),
+ dataIndex: 'name',
+ align: 'center',
+ width: '10%',
+ render: function (text, row, index) {
+ return dashboard(text, index, t_month);
+ },
+ },
+ ]
+ : []),
+ // 第四列:影响力
+ {
+ title: t('influence'),
+ dataIndex: 'value',
+ width: '20%',
+ align: 'right',
+ render: (text, row, index) => {
+ return RoundFloat(text);
+ },
+ },
+ // 第五列:影响力变化
+ {
+ title: '',
+ dataIndex: 'valueDelta',
+ width: '10%',
+ align: 'left',
+ render: (text, row, index) => {
+ text = RoundFloat(text);
+ return PointRender(text, row, index);
+ },
+ },
+];
+
+const solveDate = (year, month) => {
+ if (year === null && month === null) {
+ return 'not found';
+ }
+ if (month === null) {
+ return year + '年';
+ }
+ return year + '年' + (month + 1) + '月';
+};
+
+function dashboard(text, index, t_month) {
+ if (index < 300) {
+ let [org_name, repo_name] = text.split('/');
+ const t_month_copy = t_month + ' ' + '00:00:00';
+ let params = {
+ org_name,
+ repo_name,
+ t_month_copy,
+ t_month,
+ };
+ return (
+
+
+
+ );
+ }
+}
+
+function DateTitle(props) {
+ return {solveDate(props.year, props.month)}
;
+}
+
+function MyTable(props) {
+ const [state, setState] = useState({
+ object: 'technology',
+ index: 'open_rank',
+ region: 'global',
+ showDetail: false,
+ hasDetail: true,
+ data: [],
+ showSize: 25,
+ loading: true,
+ url: '', // base + index + object + region + yearmonth + .json
+ base: 'https://oss.x-lab.info/open_leaderboard/',
+ year: null, // 字符串格式
+ month: null, // 整数格式,0表示1月,1表示2月..., null for year type time
+ type: 'month',
+ search: null,
+ category: 'cloud-native',
+ });
+
+ // 请求一次数据更新表格。如果还没读取好配置文件则不请求数据。
+ useEffect(() => {
+ if (props.year == null && props.month == null) {
+ console.log('the first loading');
+ return;
+ }
+ updateDate({
+ year: String(props.year),
+ month: props.month,
+ });
+ }, [props]);
+
+ const expandData = () => {
+ setState({
+ ...state,
+ showSize: state.showSize + 25,
+ });
+ };
+ const updateDate = (newstate) => {
+ console.log('table update', newstate);
+ // 先获取原先的表格属性
+ let {
+ base,
+ object,
+ index,
+ region,
+ month,
+ year,
+ columns,
+ showDetail,
+ hasDetail,
+ type,
+ search,
+ category,
+ } = state;
+ // 然后把表格改为加载中的状态
+ setState({ ...state, ...newstate, loading: true });
+ // 如果 newstate 有对应的属性,则进行更新
+ if (newstate.hasOwnProperty('object')) object = newstate.object;
+ if (newstate.hasOwnProperty('index')) index = newstate.index;
+ if (newstate.hasOwnProperty('region')) region = newstate.region;
+ if (newstate.hasOwnProperty('month')) month = newstate.month;
+ if (newstate.hasOwnProperty('year')) year = newstate.year;
+ if (newstate.hasOwnProperty('showDetail')) showDetail = newstate.showDetail;
+ if (newstate.hasOwnProperty('type')) type = newstate.type;
+ if (newstate.hasOwnProperty('search')) search = newstate.search;
+ if (newstate.hasOwnProperty('category')) category = newstate.category;
+
+ //获取数据大屏的‘t_month’参数
+ let myyear = newstate.year == null ? state.year : newstate.year;
+ let mymonth = newstate.month == null ? state.month : newstate.month;
+
+ mymonth = ('' + (1 + mymonth)).padStart(2, '0');
+ let t_month = `${myyear}-${mymonth}-01`;
+
+ // 根据 index 和 showDetail 改变表格的 columns 格式
+ if (index == 'activity') {
+ columns = activityColumns(object, t_month);
+ hasDetail = true;
+ }
+ if (index == 'activity' && showDetail == true) {
+ columns = activityDetailColumns(object, t_month);
+ hasDetail = true;
+ }
+ if (index == 'open_rank') {
+ columns = open_rankColumns(object, t_month);
+ hasDetail = false;
+ showDetail = false;
+ }
+ // 如果是年份数据,则把 month 置为 null。
+ // TODO:待验证,如果从年份数据切换到月份数据,似乎会自动回到原来 month 值?
+ if (type == 'year') {
+ month = null;
+ }
+ // 以当前的属性构造请求 url
+ let url = base + index + '/' + object + '/' + region + '/';
+ if (month === null) {
+ url += year + '.json';
+ } else {
+ url += year + (1 + month) + '.json';
+ }
+ console.log(url);
+ console.log(region);
+ if (object == 'foundation' && region == 'chinese') {
+ url = 'https://oss.x-lab.info/open_leaderboard/open_rank/repo/chinese/20246.json'
+ }
+ // fetch 异步请求
+ fetch(url)
+ .then((res) => {
+ // Todo:最好的情况是在日期选择器中,只显示可以查询的日期,
+ if (res.status == 404) {
+ message.warning(t('no_result'));
+ return '';
+ }
+ return res.json();
+ })
+ .then((data) => {
+ data = data.data;
+ let dataSource = [];
+ // 预处理数据,对新上榜单数据进行特殊标记处理
+ data.map((obj) => {
+ obj = expandObject(obj);
+ if (obj.rankDelta == 0 && obj.value == obj.valueDelta) {
+ obj.rankDelta = -10000000;
+ obj.valueDelta = 0;
+ }
+ dataSource.push(obj);
+ });
+ console.log(dataSource);
+
+ //搜索特定数据
+ let queryData;
+ if (search) {
+ queryData = dataSource.filter((dataSource) => {
+ let reg = new RegExp(search.trim(), 'i');
+ return reg.test(dataSource.name);
+ });
+ if (queryData.length == 0) {
+ message.warning(t('no_result'));
+ } else {
+ dataSource = queryData;
+ }
+ }
+
+ // 更新属性和表格数据
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ showDetail: showDetail,
+ hasDetail: hasDetail,
+ data: dataSource,
+ });
+ })
+ .catch((err) => {
+ console.log('hi!' + err);
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ data: [],
+ });
+ });
+
+
+ };
+
+ const {
+ object,
+ index,
+ region,
+ data,
+ columns,
+ loading,
+ showSize,
+ showDetail,
+ hasDetail,
+ month,
+ year,
+ type,
+ category,
+ } = state;
+ return (
+
+
+
+
+ record.rank}
+ dataSource={data.slice(0, Math.min(showSize, data.length))}
+ pagination={false}
+ loading={loading}
+ scroll={{ x: 'max-content' }}
+ />
+
+
+
+
+ {showSize < data.length ? (
+
+ {t('showMore') + '>>'}
+
+ ) : (
+
+ {t('noMore')}
+
+ )}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+}
+
+export default MyTable;
diff --git a/.history/src/components/table_20240727231408.js b/.history/src/components/table_20240727231408.js
new file mode 100644
index 0000000..29bc824
--- /dev/null
+++ b/.history/src/components/table_20240727231408.js
@@ -0,0 +1,589 @@
+import React, { useState, useEffect } from 'react';
+import { Col, message, Row, Table, Card } from 'antd';
+import MyAvatar from './avatar';
+import 'antd/dist/antd.css';
+import QAmiss from './QA2';
+import TablePanel from './TablePanel';
+import ArrowRender from './arrow';
+import PointRender from './changeNumber';
+import RoundFloat from './resolveFloat';
+import Trophy from './rankTrophy';
+import expandObject from '../util/expandObject';
+import { t } from 'i18next';
+import './table.css';
+
+const activityColumns = (object, t_month) => [
+ {
+ title: t('rank'),
+ dataIndex: 'rank',
+ width: '5%',
+ align: 'center',
+ render: Trophy,
+ fixed: 'left',
+ },
+ ...(object == 'actor'
+ ? [
+ {
+ title: t('avatar'),
+ dataIndex: 'id',
+ width: '5%',
+ align: 'center',
+ render: MyAvatar,
+ fixed: 'left',
+ },
+ ]
+ : []),
+ {
+ title: '',
+ dataIndex: 'rankDelta',
+ render: ArrowRender,
+ align: 'left',
+ width: '5%',
+ fixed: 'left',
+ },
+ {
+ title: t(object),
+ dataIndex: 'name',
+ align: 'center',
+ width: '20%',
+ render: function (text, row, index) {
+ if (object !== 'company') {
+ return (
+
+ {text}
+
+ );
+ } else {
+ return text;
+ }
+ },
+ },
+ ...(object == 'repo'
+ ? [
+ {
+ title: t('insight_board'),
+ dataIndex: 'name',
+ align: 'center',
+ width: '10%',
+ render: function (text, row, index) {
+ return dashboard(text, index, t_month);
+ },
+ },
+ ]
+ : []),
+ {
+ title: t('activity'),
+ dataIndex: 'value',
+ align: 'right',
+ width: '20%',
+ },
+ {
+ title: '',
+ dataIndex: 'valueDelta',
+ width: '10%',
+ align: 'left',
+ render: PointRender,
+ },
+];
+const activityDetailColumns = (object, t_month) => [
+ {
+ title: t('rank'),
+ dataIndex: 'rank',
+ width: '5%',
+ align: 'center',
+ render: Trophy,
+ fixed: 'left',
+ },
+ ...(object == 'actor'
+ ? [
+ {
+ title: t('avatar'),
+ dataIndex: 'id',
+ width: '5%',
+ align: 'center',
+ render: MyAvatar,
+ fixed: 'left',
+ },
+ ]
+ : []),
+ {
+ title: '',
+ dataIndex: 'rankDelta',
+ render: ArrowRender,
+ align: 'left',
+ width: '5%',
+ fixed: 'left',
+ },
+ {
+ title: t(object),
+ dataIndex: 'name',
+ align: 'center',
+ width: '5%',
+ render: function (text, row, index) {
+ if (object !== 'company') {
+ return (
+
+ {text}
+
+ );
+ } else {
+ return text;
+ }
+ },
+ },
+ ...(object == 'repo'
+ ? [
+ {
+ title: t('insight_board'),
+ dataIndex: 'name',
+ align: 'center',
+ width: '10%',
+ render: function (text, row, index) {
+ return dashboard(text, index, t_month);
+ },
+ },
+ ]
+ : []),
+ {
+ title: t('activity'),
+ dataIndex: 'value',
+ align: 'center',
+ width: '10%',
+ },
+ {
+ title: '',
+ dataIndex: 'valueDelta',
+ width: '10%',
+ align: 'left',
+ render: PointRender,
+ },
+ {
+ title: t('issue_comments'),
+ dataIndex: 'issue_comment',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('open_issues'),
+ dataIndex: 'open_issue',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('open_pulls'),
+ dataIndex: 'open_pull',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('merge_pulls'),
+ dataIndex: 'merged_pull',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('pr_reviews'),
+ dataIndex: 'review_comment',
+ width: '10%',
+ align: 'center',
+ },
+];
+const open_rankColumns = (object, t_month) => [
+ {
+ // 第一列:排名
+ title: t('rank'),
+ dataIndex: 'rank',
+ width: '5%',
+ render: Trophy,
+ align: 'center',
+ fixed: 'left',
+ },
+ // 如果 object 是 'actor',则添加头像列
+ ...(object == 'actor'
+ ? [
+ {
+ title: t('avatar'),
+ dataIndex: 'id',
+ width: '5%',
+ align: 'center',
+ render: MyAvatar,
+ fixed: 'left',
+ },
+ ]
+ : []),
+ // 第二列:排名变化
+ {
+ title: '',
+ dataIndex: 'rankDelta',
+ render: ArrowRender,
+ align: 'left',
+ width: '5%',
+ fixed: 'left',
+ },
+ // 第三列:对象名称(可能是 actor, repo 或 company)
+ {
+ title: t(object),
+ dataIndex: 'name',
+ width: '20%',
+ align: 'center',
+ render: function (text) {
+ if (object !== 'company') {
+ return (
+
+ {text}
+
+ );
+ } else {
+ return text;
+ }
+ },
+ },
+ // 如果 object 是 'repo',则添加 insight_board 列
+ ...(object == 'repo'
+ ? [
+ {
+ title: t('insight_board'),
+ dataIndex: 'name',
+ align: 'center',
+ width: '10%',
+ render: function (text, row, index) {
+ return dashboard(text, index, t_month);
+ },
+ },
+ ]
+ : []),
+ // 第四列:影响力
+ {
+ title: t('influence'),
+ dataIndex: 'value',
+ width: '20%',
+ align: 'right',
+ render: (text, row, index) => {
+ return RoundFloat(text);
+ },
+ },
+ // 第五列:影响力变化
+ {
+ title: '',
+ dataIndex: 'valueDelta',
+ width: '10%',
+ align: 'left',
+ render: (text, row, index) => {
+ text = RoundFloat(text);
+ return PointRender(text, row, index);
+ },
+ },
+];
+
+const solveDate = (year, month) => {
+ if (year === null && month === null) {
+ return 'not found';
+ }
+ if (month === null) {
+ return year + '年';
+ }
+ return year + '年' + (month + 1) + '月';
+};
+
+function dashboard(text, index, t_month) {
+ if (index < 300) {
+ let [org_name, repo_name] = text.split('/');
+ const t_month_copy = t_month + ' ' + '00:00:00';
+ let params = {
+ org_name,
+ repo_name,
+ t_month_copy,
+ t_month,
+ };
+ return (
+
+
+
+ );
+ }
+}
+
+function DateTitle(props) {
+ return {solveDate(props.year, props.month)}
;
+}
+
+function MyTable(props) {
+ const [state, setState] = useState({
+ object: 'technology',
+ index: 'open_rank',
+ region: 'global',
+ showDetail: false,
+ hasDetail: true,
+ data: [],
+ showSize: 25,
+ loading: true,
+ url: '', // base + index + object + region + yearmonth + .json
+ base: 'https://oss.x-lab.info/open_leaderboard/',
+ year: null, // 字符串格式
+ month: null, // 整数格式,0表示1月,1表示2月..., null for year type time
+ type: 'month',
+ search: null,
+ category: 'cloud-native',
+ });
+
+ // 请求一次数据更新表格。如果还没读取好配置文件则不请求数据。
+ useEffect(() => {
+ if (props.year == null && props.month == null) {
+ console.log('the first loading');
+ return;
+ }
+ updateDate({
+ year: String(props.year),
+ month: props.month,
+ });
+ }, [props]);
+
+ const expandData = () => {
+ setState({
+ ...state,
+ showSize: state.showSize + 25,
+ });
+ };
+ const updateDate = (newstate) => {
+ console.log('table update', newstate);
+ // 先获取原先的表格属性
+ let {
+ base,
+ object,
+ index,
+ region,
+ month,
+ year,
+ columns,
+ showDetail,
+ hasDetail,
+ type,
+ search,
+ category,
+ } = state;
+ // 然后把表格改为加载中的状态
+ setState({ ...state, ...newstate, loading: true });
+ // 如果 newstate 有对应的属性,则进行更新
+ if (newstate.hasOwnProperty('object')) object = newstate.object;
+ if (newstate.hasOwnProperty('index')) index = newstate.index;
+ if (newstate.hasOwnProperty('region')) region = newstate.region;
+ if (newstate.hasOwnProperty('month')) month = newstate.month;
+ if (newstate.hasOwnProperty('year')) year = newstate.year;
+ if (newstate.hasOwnProperty('showDetail')) showDetail = newstate.showDetail;
+ if (newstate.hasOwnProperty('type')) type = newstate.type;
+ if (newstate.hasOwnProperty('search')) search = newstate.search;
+ if (newstate.hasOwnProperty('category')) category = newstate.category;
+
+ //获取数据大屏的‘t_month’参数
+ let myyear = newstate.year == null ? state.year : newstate.year;
+ let mymonth = newstate.month == null ? state.month : newstate.month;
+
+ mymonth = ('' + (1 + mymonth)).padStart(2, '0');
+ let t_month = `${myyear}-${mymonth}-01`;
+
+ // 根据 index 和 showDetail 改变表格的 columns 格式
+ if (index == 'activity') {
+ columns = activityColumns(object, t_month);
+ hasDetail = true;
+ }
+ if (index == 'activity' && showDetail == true) {
+ columns = activityDetailColumns(object, t_month);
+ hasDetail = true;
+ }
+ if (index == 'open_rank') {
+ columns = open_rankColumns(object, t_month);
+ hasDetail = false;
+ showDetail = false;
+ }
+ // 如果是年份数据,则把 month 置为 null。
+ // TODO:待验证,如果从年份数据切换到月份数据,似乎会自动回到原来 month 值?
+ if (type == 'year') {
+ month = null;
+ }
+ // 以当前的属性构造请求 url
+ let url = base + index + '/' + object + '/' + region + '/';
+ if (month === null) {
+ url += year + '.json';
+ } else {
+ url += year + (1 + month) + '.json';
+ }
+ console.log(url);
+ console.log(region);
+ if (object == 'foundation' || category != null) {
+ url = 'https://oss.x-lab.info/open_leaderboard/open_rank/repo/chinese/20246.json'
+ }
+ // fetch 异步请求
+ fetch(url)
+ .then((res) => {
+ // Todo:最好的情况是在日期选择器中,只显示可以查询的日期,
+ if (res.status == 404) {
+ message.warning(t('no_result'));
+ return '';
+ }
+ return res.json();
+ })
+ .then((data) => {
+ data = data.data;
+ let dataSource = [];
+ // 预处理数据,对新上榜单数据进行特殊标记处理
+ data.map((obj) => {
+ obj = expandObject(obj);
+ if (obj.rankDelta == 0 && obj.value == obj.valueDelta) {
+ obj.rankDelta = -10000000;
+ obj.valueDelta = 0;
+ }
+ dataSource.push(obj);
+ });
+ console.log(dataSource);
+
+ //搜索特定数据
+ let queryData;
+ if (search) {
+ queryData = dataSource.filter((dataSource) => {
+ let reg = new RegExp(search.trim(), 'i');
+ return reg.test(dataSource.name);
+ });
+ if (queryData.length == 0) {
+ message.warning(t('no_result'));
+ } else {
+ dataSource = queryData;
+ }
+ }
+
+ // 更新属性和表格数据
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ showDetail: showDetail,
+ hasDetail: hasDetail,
+ data: dataSource,
+ });
+ })
+ .catch((err) => {
+ console.log('hi!' + err);
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ data: [],
+ });
+ });
+
+
+ };
+
+ const {
+ object,
+ index,
+ region,
+ data,
+ columns,
+ loading,
+ showSize,
+ showDetail,
+ hasDetail,
+ month,
+ year,
+ type,
+ category,
+ } = state;
+ return (
+
+
+
+
+ record.rank}
+ dataSource={data.slice(0, Math.min(showSize, data.length))}
+ pagination={false}
+ loading={loading}
+ scroll={{ x: 'max-content' }}
+ />
+
+
+
+
+ {showSize < data.length ? (
+
+ {t('showMore') + '>>'}
+
+ ) : (
+
+ {t('noMore')}
+
+ )}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+}
+
+export default MyTable;
diff --git a/.history/src/components/table_20240727231449.js b/.history/src/components/table_20240727231449.js
new file mode 100644
index 0000000..3e535ee
--- /dev/null
+++ b/.history/src/components/table_20240727231449.js
@@ -0,0 +1,589 @@
+import React, { useState, useEffect } from 'react';
+import { Col, message, Row, Table, Card } from 'antd';
+import MyAvatar from './avatar';
+import 'antd/dist/antd.css';
+import QAmiss from './QA2';
+import TablePanel from './TablePanel';
+import ArrowRender from './arrow';
+import PointRender from './changeNumber';
+import RoundFloat from './resolveFloat';
+import Trophy from './rankTrophy';
+import expandObject from '../util/expandObject';
+import { t } from 'i18next';
+import './table.css';
+
+const activityColumns = (object, t_month) => [
+ {
+ title: t('rank'),
+ dataIndex: 'rank',
+ width: '5%',
+ align: 'center',
+ render: Trophy,
+ fixed: 'left',
+ },
+ ...(object == 'actor'
+ ? [
+ {
+ title: t('avatar'),
+ dataIndex: 'id',
+ width: '5%',
+ align: 'center',
+ render: MyAvatar,
+ fixed: 'left',
+ },
+ ]
+ : []),
+ {
+ title: '',
+ dataIndex: 'rankDelta',
+ render: ArrowRender,
+ align: 'left',
+ width: '5%',
+ fixed: 'left',
+ },
+ {
+ title: t(object),
+ dataIndex: 'name',
+ align: 'center',
+ width: '20%',
+ render: function (text, row, index) {
+ if (object !== 'company') {
+ return (
+
+ {text}
+
+ );
+ } else {
+ return text;
+ }
+ },
+ },
+ ...(object == 'repo'
+ ? [
+ {
+ title: t('insight_board'),
+ dataIndex: 'name',
+ align: 'center',
+ width: '10%',
+ render: function (text, row, index) {
+ return dashboard(text, index, t_month);
+ },
+ },
+ ]
+ : []),
+ {
+ title: t('activity'),
+ dataIndex: 'value',
+ align: 'right',
+ width: '20%',
+ },
+ {
+ title: '',
+ dataIndex: 'valueDelta',
+ width: '10%',
+ align: 'left',
+ render: PointRender,
+ },
+];
+const activityDetailColumns = (object, t_month) => [
+ {
+ title: t('rank'),
+ dataIndex: 'rank',
+ width: '5%',
+ align: 'center',
+ render: Trophy,
+ fixed: 'left',
+ },
+ ...(object == 'actor'
+ ? [
+ {
+ title: t('avatar'),
+ dataIndex: 'id',
+ width: '5%',
+ align: 'center',
+ render: MyAvatar,
+ fixed: 'left',
+ },
+ ]
+ : []),
+ {
+ title: '',
+ dataIndex: 'rankDelta',
+ render: ArrowRender,
+ align: 'left',
+ width: '5%',
+ fixed: 'left',
+ },
+ {
+ title: t(object),
+ dataIndex: 'name',
+ align: 'center',
+ width: '5%',
+ render: function (text, row, index) {
+ if (object !== 'company') {
+ return (
+
+ {text}
+
+ );
+ } else {
+ return text;
+ }
+ },
+ },
+ ...(object == 'repo'
+ ? [
+ {
+ title: t('insight_board'),
+ dataIndex: 'name',
+ align: 'center',
+ width: '10%',
+ render: function (text, row, index) {
+ return dashboard(text, index, t_month);
+ },
+ },
+ ]
+ : []),
+ {
+ title: t('activity'),
+ dataIndex: 'value',
+ align: 'center',
+ width: '10%',
+ },
+ {
+ title: '',
+ dataIndex: 'valueDelta',
+ width: '10%',
+ align: 'left',
+ render: PointRender,
+ },
+ {
+ title: t('issue_comments'),
+ dataIndex: 'issue_comment',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('open_issues'),
+ dataIndex: 'open_issue',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('open_pulls'),
+ dataIndex: 'open_pull',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('merge_pulls'),
+ dataIndex: 'merged_pull',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('pr_reviews'),
+ dataIndex: 'review_comment',
+ width: '10%',
+ align: 'center',
+ },
+];
+const open_rankColumns = (object, t_month) => [
+ {
+ // 第一列:排名
+ title: t('rank'),
+ dataIndex: 'rank',
+ width: '5%',
+ render: Trophy,
+ align: 'center',
+ fixed: 'left',
+ },
+ // 如果 object 是 'actor',则添加头像列
+ ...(object == 'actor'
+ ? [
+ {
+ title: t('avatar'),
+ dataIndex: 'id',
+ width: '5%',
+ align: 'center',
+ render: MyAvatar,
+ fixed: 'left',
+ },
+ ]
+ : []),
+ // 第二列:排名变化
+ {
+ title: '',
+ dataIndex: 'rankDelta',
+ render: ArrowRender,
+ align: 'left',
+ width: '5%',
+ fixed: 'left',
+ },
+ // 第三列:对象名称(可能是 actor, repo 或 company)
+ {
+ title: t(object),
+ dataIndex: 'name',
+ width: '20%',
+ align: 'center',
+ render: function (text) {
+ if (object !== 'company') {
+ return (
+
+ {text}
+
+ );
+ } else {
+ return text;
+ }
+ },
+ },
+ // 如果 object 是 'repo',则添加 insight_board 列
+ ...(object == 'repo'
+ ? [
+ {
+ title: t('insight_board'),
+ dataIndex: 'name',
+ align: 'center',
+ width: '10%',
+ render: function (text, row, index) {
+ return dashboard(text, index, t_month);
+ },
+ },
+ ]
+ : []),
+ // 第四列:影响力
+ {
+ title: t('influence'),
+ dataIndex: 'value',
+ width: '20%',
+ align: 'right',
+ render: (text, row, index) => {
+ return RoundFloat(text);
+ },
+ },
+ // 第五列:影响力变化
+ {
+ title: '',
+ dataIndex: 'valueDelta',
+ width: '10%',
+ align: 'left',
+ render: (text, row, index) => {
+ text = RoundFloat(text);
+ return PointRender(text, row, index);
+ },
+ },
+];
+
+const solveDate = (year, month) => {
+ if (year === null && month === null) {
+ return 'not found';
+ }
+ if (month === null) {
+ return year + '年';
+ }
+ return year + '年' + (month + 1) + '月';
+};
+
+function dashboard(text, index, t_month) {
+ if (index < 300) {
+ let [org_name, repo_name] = text.split('/');
+ const t_month_copy = t_month + ' ' + '00:00:00';
+ let params = {
+ org_name,
+ repo_name,
+ t_month_copy,
+ t_month,
+ };
+ return (
+
+
+
+ );
+ }
+}
+
+function DateTitle(props) {
+ return {solveDate(props.year, props.month)}
;
+}
+
+function MyTable(props) {
+ const [state, setState] = useState({
+ object: 'technology',
+ index: 'open_rank',
+ region: 'global',
+ showDetail: false,
+ hasDetail: true,
+ data: [],
+ showSize: 25,
+ loading: true,
+ url: '', // base + index + object + region + yearmonth + .json
+ base: 'https://oss.x-lab.info/open_leaderboard/',
+ year: null, // 字符串格式
+ month: null, // 整数格式,0表示1月,1表示2月..., null for year type time
+ type: 'month',
+ search: null,
+ category: 'cloud-native',
+ });
+
+ // 请求一次数据更新表格。如果还没读取好配置文件则不请求数据。
+ useEffect(() => {
+ if (props.year == null && props.month == null) {
+ console.log('the first loading');
+ return;
+ }
+ updateDate({
+ year: String(props.year),
+ month: props.month,
+ });
+ }, [props]);
+
+ const expandData = () => {
+ setState({
+ ...state,
+ showSize: state.showSize + 25,
+ });
+ };
+ const updateDate = (newstate) => {
+ console.log('table update', newstate);
+ // 先获取原先的表格属性
+ let {
+ base,
+ object,
+ index,
+ region,
+ month,
+ year,
+ columns,
+ showDetail,
+ hasDetail,
+ type,
+ search,
+ category,
+ } = state;
+ // 然后把表格改为加载中的状态
+ setState({ ...state, ...newstate, loading: true });
+ // 如果 newstate 有对应的属性,则进行更新
+ if (newstate.hasOwnProperty('object')) object = newstate.object;
+ if (newstate.hasOwnProperty('index')) index = newstate.index;
+ if (newstate.hasOwnProperty('region')) region = newstate.region;
+ if (newstate.hasOwnProperty('month')) month = newstate.month;
+ if (newstate.hasOwnProperty('year')) year = newstate.year;
+ if (newstate.hasOwnProperty('showDetail')) showDetail = newstate.showDetail;
+ if (newstate.hasOwnProperty('type')) type = newstate.type;
+ if (newstate.hasOwnProperty('search')) search = newstate.search;
+ if (newstate.hasOwnProperty('category')) category = newstate.category;
+
+ //获取数据大屏的‘t_month’参数
+ let myyear = newstate.year == null ? state.year : newstate.year;
+ let mymonth = newstate.month == null ? state.month : newstate.month;
+
+ mymonth = ('' + (1 + mymonth)).padStart(2, '0');
+ let t_month = `${myyear}-${mymonth}-01`;
+
+ // 根据 index 和 showDetail 改变表格的 columns 格式
+ if (index == 'activity') {
+ columns = activityColumns(object, t_month);
+ hasDetail = true;
+ }
+ if (index == 'activity' && showDetail == true) {
+ columns = activityDetailColumns(object, t_month);
+ hasDetail = true;
+ }
+ if (index == 'open_rank') {
+ columns = open_rankColumns(object, t_month);
+ hasDetail = false;
+ showDetail = false;
+ }
+ // 如果是年份数据,则把 month 置为 null。
+ // TODO:待验证,如果从年份数据切换到月份数据,似乎会自动回到原来 month 值?
+ if (type == 'year') {
+ month = null;
+ }
+ // 以当前的属性构造请求 url
+ let url = base + index + '/' + object + '/' + region + '/';
+ if (month === null) {
+ url += year + '.json';
+ } else {
+ url += year + (1 + month) + '.json';
+ }
+ console.log(url);
+ console.log(region);
+ if (object == 'foundation' || category != '') {
+ url = 'https://oss.x-lab.info/open_leaderboard/open_rank/repo/chinese/20246.json'
+ }
+ // fetch 异步请求
+ fetch(url)
+ .then((res) => {
+ // Todo:最好的情况是在日期选择器中,只显示可以查询的日期,
+ if (res.status == 404) {
+ message.warning(t('no_result'));
+ return '';
+ }
+ return res.json();
+ })
+ .then((data) => {
+ data = data.data;
+ let dataSource = [];
+ // 预处理数据,对新上榜单数据进行特殊标记处理
+ data.map((obj) => {
+ obj = expandObject(obj);
+ if (obj.rankDelta == 0 && obj.value == obj.valueDelta) {
+ obj.rankDelta = -10000000;
+ obj.valueDelta = 0;
+ }
+ dataSource.push(obj);
+ });
+ console.log(dataSource);
+
+ //搜索特定数据
+ let queryData;
+ if (search) {
+ queryData = dataSource.filter((dataSource) => {
+ let reg = new RegExp(search.trim(), 'i');
+ return reg.test(dataSource.name);
+ });
+ if (queryData.length == 0) {
+ message.warning(t('no_result'));
+ } else {
+ dataSource = queryData;
+ }
+ }
+
+ // 更新属性和表格数据
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ showDetail: showDetail,
+ hasDetail: hasDetail,
+ data: dataSource,
+ });
+ })
+ .catch((err) => {
+ console.log('hi!' + err);
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ data: [],
+ });
+ });
+
+
+ };
+
+ const {
+ object,
+ index,
+ region,
+ data,
+ columns,
+ loading,
+ showSize,
+ showDetail,
+ hasDetail,
+ month,
+ year,
+ type,
+ category,
+ } = state;
+ return (
+
+
+
+
+ record.rank}
+ dataSource={data.slice(0, Math.min(showSize, data.length))}
+ pagination={false}
+ loading={loading}
+ scroll={{ x: 'max-content' }}
+ />
+
+
+
+
+ {showSize < data.length ? (
+
+ {t('showMore') + '>>'}
+
+ ) : (
+
+ {t('noMore')}
+
+ )}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+}
+
+export default MyTable;
diff --git a/.history/src/components/table_20240727231623.js b/.history/src/components/table_20240727231623.js
new file mode 100644
index 0000000..ed7a8b5
--- /dev/null
+++ b/.history/src/components/table_20240727231623.js
@@ -0,0 +1,589 @@
+import React, { useState, useEffect } from 'react';
+import { Col, message, Row, Table, Card } from 'antd';
+import MyAvatar from './avatar';
+import 'antd/dist/antd.css';
+import QAmiss from './QA2';
+import TablePanel from './TablePanel';
+import ArrowRender from './arrow';
+import PointRender from './changeNumber';
+import RoundFloat from './resolveFloat';
+import Trophy from './rankTrophy';
+import expandObject from '../util/expandObject';
+import { t } from 'i18next';
+import './table.css';
+
+const activityColumns = (object, t_month) => [
+ {
+ title: t('rank'),
+ dataIndex: 'rank',
+ width: '5%',
+ align: 'center',
+ render: Trophy,
+ fixed: 'left',
+ },
+ ...(object == 'actor'
+ ? [
+ {
+ title: t('avatar'),
+ dataIndex: 'id',
+ width: '5%',
+ align: 'center',
+ render: MyAvatar,
+ fixed: 'left',
+ },
+ ]
+ : []),
+ {
+ title: '',
+ dataIndex: 'rankDelta',
+ render: ArrowRender,
+ align: 'left',
+ width: '5%',
+ fixed: 'left',
+ },
+ {
+ title: t(object),
+ dataIndex: 'name',
+ align: 'center',
+ width: '20%',
+ render: function (text, row, index) {
+ if (object !== 'company') {
+ return (
+
+ {text}
+
+ );
+ } else {
+ return text;
+ }
+ },
+ },
+ ...(object == 'repo'
+ ? [
+ {
+ title: t('insight_board'),
+ dataIndex: 'name',
+ align: 'center',
+ width: '10%',
+ render: function (text, row, index) {
+ return dashboard(text, index, t_month);
+ },
+ },
+ ]
+ : []),
+ {
+ title: t('activity'),
+ dataIndex: 'value',
+ align: 'right',
+ width: '20%',
+ },
+ {
+ title: '',
+ dataIndex: 'valueDelta',
+ width: '10%',
+ align: 'left',
+ render: PointRender,
+ },
+];
+const activityDetailColumns = (object, t_month) => [
+ {
+ title: t('rank'),
+ dataIndex: 'rank',
+ width: '5%',
+ align: 'center',
+ render: Trophy,
+ fixed: 'left',
+ },
+ ...(object == 'actor'
+ ? [
+ {
+ title: t('avatar'),
+ dataIndex: 'id',
+ width: '5%',
+ align: 'center',
+ render: MyAvatar,
+ fixed: 'left',
+ },
+ ]
+ : []),
+ {
+ title: '',
+ dataIndex: 'rankDelta',
+ render: ArrowRender,
+ align: 'left',
+ width: '5%',
+ fixed: 'left',
+ },
+ {
+ title: t(object),
+ dataIndex: 'name',
+ align: 'center',
+ width: '5%',
+ render: function (text, row, index) {
+ if (object !== 'company') {
+ return (
+
+ {text}
+
+ );
+ } else {
+ return text;
+ }
+ },
+ },
+ ...(object == 'repo'
+ ? [
+ {
+ title: t('insight_board'),
+ dataIndex: 'name',
+ align: 'center',
+ width: '10%',
+ render: function (text, row, index) {
+ return dashboard(text, index, t_month);
+ },
+ },
+ ]
+ : []),
+ {
+ title: t('activity'),
+ dataIndex: 'value',
+ align: 'center',
+ width: '10%',
+ },
+ {
+ title: '',
+ dataIndex: 'valueDelta',
+ width: '10%',
+ align: 'left',
+ render: PointRender,
+ },
+ {
+ title: t('issue_comments'),
+ dataIndex: 'issue_comment',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('open_issues'),
+ dataIndex: 'open_issue',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('open_pulls'),
+ dataIndex: 'open_pull',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('merge_pulls'),
+ dataIndex: 'merged_pull',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('pr_reviews'),
+ dataIndex: 'review_comment',
+ width: '10%',
+ align: 'center',
+ },
+];
+const open_rankColumns = (object, t_month) => [
+ {
+ // 第一列:排名
+ title: t('rank'),
+ dataIndex: 'rank',
+ width: '5%',
+ render: Trophy,
+ align: 'center',
+ fixed: 'left',
+ },
+ // 如果 object 是 'actor',则添加头像列
+ ...(object == 'actor'
+ ? [
+ {
+ title: t('avatar'),
+ dataIndex: 'id',
+ width: '5%',
+ align: 'center',
+ render: MyAvatar,
+ fixed: 'left',
+ },
+ ]
+ : []),
+ // 第二列:排名变化
+ {
+ title: '',
+ dataIndex: 'rankDelta',
+ render: ArrowRender,
+ align: 'left',
+ width: '5%',
+ fixed: 'left',
+ },
+ // 第三列:对象名称(可能是 actor, repo 或 company)
+ {
+ title: t(object),
+ dataIndex: 'name',
+ width: '20%',
+ align: 'center',
+ render: function (text) {
+ if (object !== 'company') {
+ return (
+
+ {text}
+
+ );
+ } else {
+ return text;
+ }
+ },
+ },
+ // 如果 object 是 'repo',则添加 insight_board 列
+ ...(object == 'repo'
+ ? [
+ {
+ title: t('insight_board'),
+ dataIndex: 'name',
+ align: 'center',
+ width: '10%',
+ render: function (text, row, index) {
+ return dashboard(text, index, t_month);
+ },
+ },
+ ]
+ : []),
+ // 第四列:影响力
+ {
+ title: t('influence'),
+ dataIndex: 'value',
+ width: '20%',
+ align: 'right',
+ render: (text, row, index) => {
+ return RoundFloat(text);
+ },
+ },
+ // 第五列:影响力变化
+ {
+ title: '',
+ dataIndex: 'valueDelta',
+ width: '10%',
+ align: 'left',
+ render: (text, row, index) => {
+ text = RoundFloat(text);
+ return PointRender(text, row, index);
+ },
+ },
+];
+
+const solveDate = (year, month) => {
+ if (year === null && month === null) {
+ return 'not found';
+ }
+ if (month === null) {
+ return year + '年';
+ }
+ return year + '年' + (month + 1) + '月';
+};
+
+function dashboard(text, index, t_month) {
+ if (index < 300) {
+ let [org_name, repo_name] = text.split('/');
+ const t_month_copy = t_month + ' ' + '00:00:00';
+ let params = {
+ org_name,
+ repo_name,
+ t_month_copy,
+ t_month,
+ };
+ return (
+
+
+
+ );
+ }
+}
+
+function DateTitle(props) {
+ return {solveDate(props.year, props.month)}
;
+}
+
+function MyTable(props) {
+ const [state, setState] = useState({
+ object: 'technology',
+ index: 'open_rank',
+ region: 'global',
+ showDetail: false,
+ hasDetail: true,
+ data: [],
+ showSize: 25,
+ loading: true,
+ url: '', // base + index + object + region + yearmonth + .json
+ base: 'https://oss.x-lab.info/open_leaderboard/',
+ year: null, // 字符串格式
+ month: null, // 整数格式,0表示1月,1表示2月..., null for year type time
+ type: 'month',
+ search: null,
+ category: 'cloud-native',
+ });
+
+ // 请求一次数据更新表格。如果还没读取好配置文件则不请求数据。
+ useEffect(() => {
+ if (props.year == null && props.month == null) {
+ console.log('the first loading');
+ return;
+ }
+ updateDate({
+ year: String(props.year),
+ month: props.month,
+ });
+ }, [props]);
+
+ const expandData = () => {
+ setState({
+ ...state,
+ showSize: state.showSize + 25,
+ });
+ };
+ const updateDate = (newstate) => {
+ console.log('table update', newstate);
+ // 先获取原先的表格属性
+ let {
+ base,
+ object,
+ index,
+ region,
+ month,
+ year,
+ columns,
+ showDetail,
+ hasDetail,
+ type,
+ search,
+ category,
+ } = state;
+ // 然后把表格改为加载中的状态
+ setState({ ...state, ...newstate, loading: true });
+ // 如果 newstate 有对应的属性,则进行更新
+ if (newstate.hasOwnProperty('object')) object = newstate.object;
+ if (newstate.hasOwnProperty('index')) index = newstate.index;
+ if (newstate.hasOwnProperty('region')) region = newstate.region;
+ if (newstate.hasOwnProperty('month')) month = newstate.month;
+ if (newstate.hasOwnProperty('year')) year = newstate.year;
+ if (newstate.hasOwnProperty('showDetail')) showDetail = newstate.showDetail;
+ if (newstate.hasOwnProperty('type')) type = newstate.type;
+ if (newstate.hasOwnProperty('search')) search = newstate.search;
+ if (newstate.hasOwnProperty('category')) category = newstate.category;
+
+ //获取数据大屏的‘t_month’参数
+ let myyear = newstate.year == null ? state.year : newstate.year;
+ let mymonth = newstate.month == null ? state.month : newstate.month;
+
+ mymonth = ('' + (1 + mymonth)).padStart(2, '0');
+ let t_month = `${myyear}-${mymonth}-01`;
+
+ // 根据 index 和 showDetail 改变表格的 columns 格式
+ if (index == 'activity') {
+ columns = activityColumns(object, t_month);
+ hasDetail = true;
+ }
+ if (index == 'activity' && showDetail == true) {
+ columns = activityDetailColumns(object, t_month);
+ hasDetail = true;
+ }
+ if (index == 'open_rank') {
+ columns = open_rankColumns(object, t_month);
+ hasDetail = false;
+ showDetail = false;
+ }
+ // 如果是年份数据,则把 month 置为 null。
+ // TODO:待验证,如果从年份数据切换到月份数据,似乎会自动回到原来 month 值?
+ if (type == 'year') {
+ month = null;
+ }
+ // 以当前的属性构造请求 url
+ let url = base + index + '/' + object + '/' + region + '/';
+ if (month === null) {
+ url += year + '.json';
+ } else {
+ url += year + (1 + month) + '.json';
+ }
+ console.log(url);
+ console.log(region);
+ if (object == 'foundation' || object == 'technology') {
+ url = 'https://oss.x-lab.info/open_leaderboard/open_rank/repo/chinese/20246.json'
+ }
+ // fetch 异步请求
+ fetch(url)
+ .then((res) => {
+ // Todo:最好的情况是在日期选择器中,只显示可以查询的日期,
+ if (res.status == 404) {
+ message.warning(t('no_result'));
+ return '';
+ }
+ return res.json();
+ })
+ .then((data) => {
+ data = data.data;
+ let dataSource = [];
+ // 预处理数据,对新上榜单数据进行特殊标记处理
+ data.map((obj) => {
+ obj = expandObject(obj);
+ if (obj.rankDelta == 0 && obj.value == obj.valueDelta) {
+ obj.rankDelta = -10000000;
+ obj.valueDelta = 0;
+ }
+ dataSource.push(obj);
+ });
+ console.log(dataSource);
+
+ //搜索特定数据
+ let queryData;
+ if (search) {
+ queryData = dataSource.filter((dataSource) => {
+ let reg = new RegExp(search.trim(), 'i');
+ return reg.test(dataSource.name);
+ });
+ if (queryData.length == 0) {
+ message.warning(t('no_result'));
+ } else {
+ dataSource = queryData;
+ }
+ }
+
+ // 更新属性和表格数据
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ showDetail: showDetail,
+ hasDetail: hasDetail,
+ data: dataSource,
+ });
+ })
+ .catch((err) => {
+ console.log('hi!' + err);
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ data: [],
+ });
+ });
+
+
+ };
+
+ const {
+ object,
+ index,
+ region,
+ data,
+ columns,
+ loading,
+ showSize,
+ showDetail,
+ hasDetail,
+ month,
+ year,
+ type,
+ category,
+ } = state;
+ return (
+
+
+
+
+ record.rank}
+ dataSource={data.slice(0, Math.min(showSize, data.length))}
+ pagination={false}
+ loading={loading}
+ scroll={{ x: 'max-content' }}
+ />
+
+
+
+
+ {showSize < data.length ? (
+
+ {t('showMore') + '>>'}
+
+ ) : (
+
+ {t('noMore')}
+
+ )}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+}
+
+export default MyTable;
diff --git a/.history/src/components/table_20240728144201.js b/.history/src/components/table_20240728144201.js
new file mode 100644
index 0000000..f38476e
--- /dev/null
+++ b/.history/src/components/table_20240728144201.js
@@ -0,0 +1,601 @@
+import React, { useState, useEffect } from 'react';
+import { Col, message, Row, Table, Card } from 'antd';
+import MyAvatar from './avatar';
+import 'antd/dist/antd.css';
+import QAmiss from './QA2';
+import TablePanel from './TablePanel';
+import ArrowRender from './arrow';
+import PointRender from './changeNumber';
+import RoundFloat from './resolveFloat';
+import Trophy from './rankTrophy';
+import expandObject from '../util/expandObject';
+import { t } from 'i18next';
+import './table.css';
+import { foundationChineseData } from './data';
+
+const activityColumns = (object, t_month) => [
+ {
+ title: t('rank'),
+ dataIndex: 'rank',
+ width: '5%',
+ align: 'center',
+ render: Trophy,
+ fixed: 'left',
+ },
+ ...(object == 'actor'
+ ? [
+ {
+ title: t('avatar'),
+ dataIndex: 'id',
+ width: '5%',
+ align: 'center',
+ render: MyAvatar,
+ fixed: 'left',
+ },
+ ]
+ : []),
+ {
+ title: '',
+ dataIndex: 'rankDelta',
+ render: ArrowRender,
+ align: 'left',
+ width: '5%',
+ fixed: 'left',
+ },
+ {
+ title: t(object),
+ dataIndex: 'name',
+ align: 'center',
+ width: '20%',
+ render: function (text, row, index) {
+ if (object !== 'company') {
+ return (
+
+ {text}
+
+ );
+ } else {
+ return text;
+ }
+ },
+ },
+ ...(object == 'repo'
+ ? [
+ {
+ title: t('insight_board'),
+ dataIndex: 'name',
+ align: 'center',
+ width: '10%',
+ render: function (text, row, index) {
+ return dashboard(text, index, t_month);
+ },
+ },
+ ]
+ : []),
+ {
+ title: t('activity'),
+ dataIndex: 'value',
+ align: 'right',
+ width: '20%',
+ },
+ {
+ title: '',
+ dataIndex: 'valueDelta',
+ width: '10%',
+ align: 'left',
+ render: PointRender,
+ },
+];
+const activityDetailColumns = (object, t_month) => [
+ {
+ title: t('rank'),
+ dataIndex: 'rank',
+ width: '5%',
+ align: 'center',
+ render: Trophy,
+ fixed: 'left',
+ },
+ ...(object == 'actor'
+ ? [
+ {
+ title: t('avatar'),
+ dataIndex: 'id',
+ width: '5%',
+ align: 'center',
+ render: MyAvatar,
+ fixed: 'left',
+ },
+ ]
+ : []),
+ {
+ title: '',
+ dataIndex: 'rankDelta',
+ render: ArrowRender,
+ align: 'left',
+ width: '5%',
+ fixed: 'left',
+ },
+ {
+ title: t(object),
+ dataIndex: 'name',
+ align: 'center',
+ width: '5%',
+ render: function (text, row, index) {
+ if (object !== 'company') {
+ return (
+
+ {text}
+
+ );
+ } else {
+ return text;
+ }
+ },
+ },
+ ...(object == 'repo'
+ ? [
+ {
+ title: t('insight_board'),
+ dataIndex: 'name',
+ align: 'center',
+ width: '10%',
+ render: function (text, row, index) {
+ return dashboard(text, index, t_month);
+ },
+ },
+ ]
+ : []),
+ {
+ title: t('activity'),
+ dataIndex: 'value',
+ align: 'center',
+ width: '10%',
+ },
+ {
+ title: '',
+ dataIndex: 'valueDelta',
+ width: '10%',
+ align: 'left',
+ render: PointRender,
+ },
+ {
+ title: t('issue_comments'),
+ dataIndex: 'issue_comment',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('open_issues'),
+ dataIndex: 'open_issue',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('open_pulls'),
+ dataIndex: 'open_pull',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('merge_pulls'),
+ dataIndex: 'merged_pull',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('pr_reviews'),
+ dataIndex: 'review_comment',
+ width: '10%',
+ align: 'center',
+ },
+];
+const open_rankColumns = (object, t_month) => [
+ {
+ // 第一列:排名
+ title: t('rank'),
+ dataIndex: 'rank',
+ width: '5%',
+ render: Trophy,
+ align: 'center',
+ fixed: 'left',
+ },
+ // 如果 object 是 'actor',则添加头像列
+ ...(object == 'actor'
+ ? [
+ {
+ title: t('avatar'),
+ dataIndex: 'id',
+ width: '5%',
+ align: 'center',
+ render: MyAvatar,
+ fixed: 'left',
+ },
+ ]
+ : []),
+ // 第二列:排名变化
+ {
+ title: '',
+ dataIndex: 'rankDelta',
+ render: ArrowRender,
+ align: 'left',
+ width: '5%',
+ fixed: 'left',
+ },
+ // 第三列:对象名称(可能是 actor, repo 或 company)
+ {
+ title: t(object),
+ dataIndex: 'name',
+ width: '20%',
+ align: 'center',
+ render: function (text) {
+ if (object !== 'company') {
+ return (
+
+ {text}
+
+ );
+ } else {
+ return text;
+ }
+ },
+ },
+ // 如果 object 是 'repo',则添加 insight_board 列
+ ...(object == 'repo'
+ ? [
+ {
+ title: t('insight_board'),
+ dataIndex: 'name',
+ align: 'center',
+ width: '10%',
+ render: function (text, row, index) {
+ return dashboard(text, index, t_month);
+ },
+ },
+ ]
+ : []),
+ // 第四列:影响力
+ {
+ title: t('influence'),
+ dataIndex: 'value',
+ width: '20%',
+ align: 'right',
+ render: (text, row, index) => {
+ return RoundFloat(text);
+ },
+ },
+ // 第五列:影响力变化
+ {
+ title: '',
+ dataIndex: 'valueDelta',
+ width: '10%',
+ align: 'left',
+ render: (text, row, index) => {
+ text = RoundFloat(text);
+ return PointRender(text, row, index);
+ },
+ },
+];
+
+const solveDate = (year, month) => {
+ if (year === null && month === null) {
+ return 'not found';
+ }
+ if (month === null) {
+ return year + '年';
+ }
+ return year + '年' + (month + 1) + '月';
+};
+
+function dashboard(text, index, t_month) {
+ if (index < 300) {
+ let [org_name, repo_name] = text.split('/');
+ const t_month_copy = t_month + ' ' + '00:00:00';
+ let params = {
+ org_name,
+ repo_name,
+ t_month_copy,
+ t_month,
+ };
+ return (
+
+
+
+ );
+ }
+}
+
+function DateTitle(props) {
+ return {solveDate(props.year, props.month)}
;
+}
+
+function MyTable(props) {
+ const [state, setState] = useState({
+ object: 'technology',
+ index: 'open_rank',
+ region: 'global',
+ showDetail: false,
+ hasDetail: true,
+ data: [],
+ showSize: 25,
+ loading: true,
+ url: '', // base + index + object + region + yearmonth + .json
+ base: 'https://oss.x-lab.info/open_leaderboard/',
+ year: null, // 字符串格式
+ month: null, // 整数格式,0表示1月,1表示2月..., null for year type time
+ type: 'month',
+ search: null,
+ category: 'cloud-native',
+ });
+
+ // 请求一次数据更新表格。如果还没读取好配置文件则不请求数据。
+ useEffect(() => {
+ if (props.year == null && props.month == null) {
+ console.log('the first loading');
+ return;
+ }
+ updateDate({
+ year: String(props.year),
+ month: props.month,
+ });
+ }, [props]);
+
+ const expandData = () => {
+ setState({
+ ...state,
+ showSize: state.showSize + 25,
+ });
+ };
+ const updateDate = (newstate) => {
+ console.log('table update', newstate);
+ // 先获取原先的表格属性
+ let {
+ base,
+ object,
+ index,
+ region,
+ month,
+ year,
+ columns,
+ showDetail,
+ hasDetail,
+ type,
+ search,
+ category,
+ } = state;
+ // 然后把表格改为加载中的状态
+ setState({ ...state, ...newstate, loading: true });
+ // 如果 newstate 有对应的属性,则进行更新
+ if (newstate.hasOwnProperty('object')) object = newstate.object;
+ if (newstate.hasOwnProperty('index')) index = newstate.index;
+ if (newstate.hasOwnProperty('region')) region = newstate.region;
+ if (newstate.hasOwnProperty('month')) month = newstate.month;
+ if (newstate.hasOwnProperty('year')) year = newstate.year;
+ if (newstate.hasOwnProperty('showDetail')) showDetail = newstate.showDetail;
+ if (newstate.hasOwnProperty('type')) type = newstate.type;
+ if (newstate.hasOwnProperty('search')) search = newstate.search;
+ if (newstate.hasOwnProperty('category')) category = newstate.category;
+
+ //获取数据大屏的‘t_month’参数
+ let myyear = newstate.year == null ? state.year : newstate.year;
+ let mymonth = newstate.month == null ? state.month : newstate.month;
+
+ mymonth = ('' + (1 + mymonth)).padStart(2, '0');
+ let t_month = `${myyear}-${mymonth}-01`;
+
+ // 根据 index 和 showDetail 改变表格的 columns 格式
+ if (index == 'activity') {
+ columns = activityColumns(object, t_month);
+ hasDetail = true;
+ }
+ if (index == 'activity' && showDetail == true) {
+ columns = activityDetailColumns(object, t_month);
+ hasDetail = true;
+ }
+ if (index == 'open_rank') {
+ columns = open_rankColumns(object, t_month);
+ hasDetail = false;
+ showDetail = false;
+ }
+ // 如果是年份数据,则把 month 置为 null。
+ // TODO:待验证,如果从年份数据切换到月份数据,似乎会自动回到原来 month 值?
+ if (type == 'year') {
+ month = null;
+ }
+ // 以当前的属性构造请求 url
+ let url = base + index + '/' + object + '/' + region + '/';
+ if (month === null) {
+ url += year + '.json';
+ } else {
+ url += year + (1 + month) + '.json';
+ }
+ console.log(url);
+ console.log(region);
+ if (object == 'foundation' || region == 'chinese') {
+ dataSource = foundationChineseData;
+
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ showDetail: showDetail,
+ hasDetail: hasDetail,
+ data: dataSource,
+ });
+
+ }
+ // fetch 异步请求
+ else{fetch(url)
+ .then((res) => {
+ // Todo:最好的情况是在日期选择器中,只显示可以查询的日期,
+ if (res.status == 404) {
+ message.warning(t('no_result'));
+ return '';
+ }
+ return res.json();
+ })
+ .then((data) => {
+ data = data.data;
+ let dataSource = [];
+ // 预处理数据,对新上榜单数据进行特殊标记处理
+ data.map((obj) => {
+ obj = expandObject(obj);
+ if (obj.rankDelta == 0 && obj.value == obj.valueDelta) {
+ obj.rankDelta = -10000000;
+ obj.valueDelta = 0;
+ }
+ dataSource.push(obj);
+ });
+ console.log(dataSource);
+
+ //搜索特定数据
+ let queryData;
+ if (search) {
+ queryData = dataSource.filter((dataSource) => {
+ let reg = new RegExp(search.trim(), 'i');
+ return reg.test(dataSource.name);
+ });
+ if (queryData.length == 0) {
+ message.warning(t('no_result'));
+ } else {
+ dataSource = queryData;
+ }
+ }
+
+ // 更新属性和表格数据
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ showDetail: showDetail,
+ hasDetail: hasDetail,
+ data: dataSource,
+ });
+ })
+ .catch((err) => {
+ console.log('hi!' + err);
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ data: [],
+ });
+ });
+
+
+ };
+ }
+ const {
+ object,
+ index,
+ region,
+ data,
+ columns,
+ loading,
+ showSize,
+ showDetail,
+ hasDetail,
+ month,
+ year,
+ type,
+ category,
+ } = state;
+ return (
+
+
+
+
+ record.rank}
+ dataSource={data.slice(0, Math.min(showSize, data.length))}
+ pagination={false}
+ loading={loading}
+ scroll={{ x: 'max-content' }}
+ />
+
+
+
+
+ {showSize < data.length ? (
+
+ {t('showMore') + '>>'}
+
+ ) : (
+
+ {t('noMore')}
+
+ )}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+}
+
+export default MyTable;
diff --git a/.history/src/components/table_20240728144210.js b/.history/src/components/table_20240728144210.js
new file mode 100644
index 0000000..f69ea81
--- /dev/null
+++ b/.history/src/components/table_20240728144210.js
@@ -0,0 +1,601 @@
+import React, { useState, useEffect } from 'react';
+import { Col, message, Row, Table, Card } from 'antd';
+import MyAvatar from './avatar';
+import 'antd/dist/antd.css';
+import QAmiss from './QA2';
+import TablePanel from './TablePanel';
+import ArrowRender from './arrow';
+import PointRender from './changeNumber';
+import RoundFloat from './resolveFloat';
+import Trophy from './rankTrophy';
+import expandObject from '../util/expandObject';
+import { t } from 'i18next';
+import './table.css';
+import { foundationChineseData } from './data';
+
+const activityColumns = (object, t_month) => [
+ {
+ title: t('rank'),
+ dataIndex: 'rank',
+ width: '5%',
+ align: 'center',
+ render: Trophy,
+ fixed: 'left',
+ },
+ ...(object == 'actor'
+ ? [
+ {
+ title: t('avatar'),
+ dataIndex: 'id',
+ width: '5%',
+ align: 'center',
+ render: MyAvatar,
+ fixed: 'left',
+ },
+ ]
+ : []),
+ {
+ title: '',
+ dataIndex: 'rankDelta',
+ render: ArrowRender,
+ align: 'left',
+ width: '5%',
+ fixed: 'left',
+ },
+ {
+ title: t(object),
+ dataIndex: 'name',
+ align: 'center',
+ width: '20%',
+ render: function (text, row, index) {
+ if (object !== 'company') {
+ return (
+
+ {text}
+
+ );
+ } else {
+ return text;
+ }
+ },
+ },
+ ...(object == 'repo'
+ ? [
+ {
+ title: t('insight_board'),
+ dataIndex: 'name',
+ align: 'center',
+ width: '10%',
+ render: function (text, row, index) {
+ return dashboard(text, index, t_month);
+ },
+ },
+ ]
+ : []),
+ {
+ title: t('activity'),
+ dataIndex: 'value',
+ align: 'right',
+ width: '20%',
+ },
+ {
+ title: '',
+ dataIndex: 'valueDelta',
+ width: '10%',
+ align: 'left',
+ render: PointRender,
+ },
+];
+const activityDetailColumns = (object, t_month) => [
+ {
+ title: t('rank'),
+ dataIndex: 'rank',
+ width: '5%',
+ align: 'center',
+ render: Trophy,
+ fixed: 'left',
+ },
+ ...(object == 'actor'
+ ? [
+ {
+ title: t('avatar'),
+ dataIndex: 'id',
+ width: '5%',
+ align: 'center',
+ render: MyAvatar,
+ fixed: 'left',
+ },
+ ]
+ : []),
+ {
+ title: '',
+ dataIndex: 'rankDelta',
+ render: ArrowRender,
+ align: 'left',
+ width: '5%',
+ fixed: 'left',
+ },
+ {
+ title: t(object),
+ dataIndex: 'name',
+ align: 'center',
+ width: '5%',
+ render: function (text, row, index) {
+ if (object !== 'company') {
+ return (
+
+ {text}
+
+ );
+ } else {
+ return text;
+ }
+ },
+ },
+ ...(object == 'repo'
+ ? [
+ {
+ title: t('insight_board'),
+ dataIndex: 'name',
+ align: 'center',
+ width: '10%',
+ render: function (text, row, index) {
+ return dashboard(text, index, t_month);
+ },
+ },
+ ]
+ : []),
+ {
+ title: t('activity'),
+ dataIndex: 'value',
+ align: 'center',
+ width: '10%',
+ },
+ {
+ title: '',
+ dataIndex: 'valueDelta',
+ width: '10%',
+ align: 'left',
+ render: PointRender,
+ },
+ {
+ title: t('issue_comments'),
+ dataIndex: 'issue_comment',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('open_issues'),
+ dataIndex: 'open_issue',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('open_pulls'),
+ dataIndex: 'open_pull',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('merge_pulls'),
+ dataIndex: 'merged_pull',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('pr_reviews'),
+ dataIndex: 'review_comment',
+ width: '10%',
+ align: 'center',
+ },
+];
+const open_rankColumns = (object, t_month) => [
+ {
+ // 第一列:排名
+ title: t('rank'),
+ dataIndex: 'rank',
+ width: '5%',
+ render: Trophy,
+ align: 'center',
+ fixed: 'left',
+ },
+ // 如果 object 是 'actor',则添加头像列
+ ...(object == 'actor'
+ ? [
+ {
+ title: t('avatar'),
+ dataIndex: 'id',
+ width: '5%',
+ align: 'center',
+ render: MyAvatar,
+ fixed: 'left',
+ },
+ ]
+ : []),
+ // 第二列:排名变化
+ {
+ title: '',
+ dataIndex: 'rankDelta',
+ render: ArrowRender,
+ align: 'left',
+ width: '5%',
+ fixed: 'left',
+ },
+ // 第三列:对象名称(可能是 actor, repo 或 company)
+ {
+ title: t(object),
+ dataIndex: 'name',
+ width: '20%',
+ align: 'center',
+ render: function (text) {
+ if (object !== 'company') {
+ return (
+
+ {text}
+
+ );
+ } else {
+ return text;
+ }
+ },
+ },
+ // 如果 object 是 'repo',则添加 insight_board 列
+ ...(object == 'repo'
+ ? [
+ {
+ title: t('insight_board'),
+ dataIndex: 'name',
+ align: 'center',
+ width: '10%',
+ render: function (text, row, index) {
+ return dashboard(text, index, t_month);
+ },
+ },
+ ]
+ : []),
+ // 第四列:影响力
+ {
+ title: t('influence'),
+ dataIndex: 'value',
+ width: '20%',
+ align: 'right',
+ render: (text, row, index) => {
+ return RoundFloat(text);
+ },
+ },
+ // 第五列:影响力变化
+ {
+ title: '',
+ dataIndex: 'valueDelta',
+ width: '10%',
+ align: 'left',
+ render: (text, row, index) => {
+ text = RoundFloat(text);
+ return PointRender(text, row, index);
+ },
+ },
+];
+
+const solveDate = (year, month) => {
+ if (year === null && month === null) {
+ return 'not found';
+ }
+ if (month === null) {
+ return year + '年';
+ }
+ return year + '年' + (month + 1) + '月';
+};
+
+function dashboard(text, index, t_month) {
+ if (index < 300) {
+ let [org_name, repo_name] = text.split('/');
+ const t_month_copy = t_month + ' ' + '00:00:00';
+ let params = {
+ org_name,
+ repo_name,
+ t_month_copy,
+ t_month,
+ };
+ return (
+
+
+
+ );
+ }
+}
+
+function DateTitle(props) {
+ return {solveDate(props.year, props.month)}
;
+}
+
+function MyTable(props) {
+ const [state, setState] = useState({
+ object: 'technology',
+ index: 'open_rank',
+ region: 'global',
+ showDetail: false,
+ hasDetail: true,
+ data: [],
+ showSize: 25,
+ loading: true,
+ url: '', // base + index + object + region + yearmonth + .json
+ base: 'https://oss.x-lab.info/open_leaderboard/',
+ year: null, // 字符串格式
+ month: null, // 整数格式,0表示1月,1表示2月..., null for year type time
+ type: 'month',
+ search: null,
+ category: 'cloud-native',
+ });
+
+ // 请求一次数据更新表格。如果还没读取好配置文件则不请求数据。
+ useEffect(() => {
+ if (props.year == null && props.month == null) {
+ console.log('the first loading');
+ return;
+ }
+ updateDate({
+ year: String(props.year),
+ month: props.month,
+ });
+ }, [props]);
+
+ const expandData = () => {
+ setState({
+ ...state,
+ showSize: state.showSize + 25,
+ });
+ };
+ const updateDate = (newstate) => {
+ console.log('table update', newstate);
+ // 先获取原先的表格属性
+ let {
+ base,
+ object,
+ index,
+ region,
+ month,
+ year,
+ columns,
+ showDetail,
+ hasDetail,
+ type,
+ search,
+ category,
+ } = state;
+ // 然后把表格改为加载中的状态
+ setState({ ...state, ...newstate, loading: true });
+ // 如果 newstate 有对应的属性,则进行更新
+ if (newstate.hasOwnProperty('object')) object = newstate.object;
+ if (newstate.hasOwnProperty('index')) index = newstate.index;
+ if (newstate.hasOwnProperty('region')) region = newstate.region;
+ if (newstate.hasOwnProperty('month')) month = newstate.month;
+ if (newstate.hasOwnProperty('year')) year = newstate.year;
+ if (newstate.hasOwnProperty('showDetail')) showDetail = newstate.showDetail;
+ if (newstate.hasOwnProperty('type')) type = newstate.type;
+ if (newstate.hasOwnProperty('search')) search = newstate.search;
+ if (newstate.hasOwnProperty('category')) category = newstate.category;
+
+ //获取数据大屏的‘t_month’参数
+ let myyear = newstate.year == null ? state.year : newstate.year;
+ let mymonth = newstate.month == null ? state.month : newstate.month;
+
+ mymonth = ('' + (1 + mymonth)).padStart(2, '0');
+ let t_month = `${myyear}-${mymonth}-01`;
+
+ // 根据 index 和 showDetail 改变表格的 columns 格式
+ if (index == 'activity') {
+ columns = activityColumns(object, t_month);
+ hasDetail = true;
+ }
+ if (index == 'activity' && showDetail == true) {
+ columns = activityDetailColumns(object, t_month);
+ hasDetail = true;
+ }
+ if (index == 'open_rank') {
+ columns = open_rankColumns(object, t_month);
+ hasDetail = false;
+ showDetail = false;
+ }
+ // 如果是年份数据,则把 month 置为 null。
+ // TODO:待验证,如果从年份数据切换到月份数据,似乎会自动回到原来 month 值?
+ if (type == 'year') {
+ month = null;
+ }
+ // 以当前的属性构造请求 url
+ let url = base + index + '/' + object + '/' + region + '/';
+ if (month === null) {
+ url += year + '.json';
+ } else {
+ url += year + (1 + month) + '.json';
+ }
+ console.log(url);
+ console.log(region);
+ if (object == 'foundation' && region == 'chinese') {
+ dataSource = foundationChineseData;
+
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ showDetail: showDetail,
+ hasDetail: hasDetail,
+ data: dataSource,
+ });
+
+ }
+ // fetch 异步请求
+ else{fetch(url)
+ .then((res) => {
+ // Todo:最好的情况是在日期选择器中,只显示可以查询的日期,
+ if (res.status == 404) {
+ message.warning(t('no_result'));
+ return '';
+ }
+ return res.json();
+ })
+ .then((data) => {
+ data = data.data;
+ let dataSource = [];
+ // 预处理数据,对新上榜单数据进行特殊标记处理
+ data.map((obj) => {
+ obj = expandObject(obj);
+ if (obj.rankDelta == 0 && obj.value == obj.valueDelta) {
+ obj.rankDelta = -10000000;
+ obj.valueDelta = 0;
+ }
+ dataSource.push(obj);
+ });
+ console.log(dataSource);
+
+ //搜索特定数据
+ let queryData;
+ if (search) {
+ queryData = dataSource.filter((dataSource) => {
+ let reg = new RegExp(search.trim(), 'i');
+ return reg.test(dataSource.name);
+ });
+ if (queryData.length == 0) {
+ message.warning(t('no_result'));
+ } else {
+ dataSource = queryData;
+ }
+ }
+
+ // 更新属性和表格数据
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ showDetail: showDetail,
+ hasDetail: hasDetail,
+ data: dataSource,
+ });
+ })
+ .catch((err) => {
+ console.log('hi!' + err);
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ data: [],
+ });
+ });
+
+
+ };
+ }
+ const {
+ object,
+ index,
+ region,
+ data,
+ columns,
+ loading,
+ showSize,
+ showDetail,
+ hasDetail,
+ month,
+ year,
+ type,
+ category,
+ } = state;
+ return (
+
+
+
+
+ record.rank}
+ dataSource={data.slice(0, Math.min(showSize, data.length))}
+ pagination={false}
+ loading={loading}
+ scroll={{ x: 'max-content' }}
+ />
+
+
+
+
+ {showSize < data.length ? (
+
+ {t('showMore') + '>>'}
+
+ ) : (
+
+ {t('noMore')}
+
+ )}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+}
+
+export default MyTable;
diff --git a/.history/src/components/table_20240728144254.js b/.history/src/components/table_20240728144254.js
new file mode 100644
index 0000000..f69ea81
--- /dev/null
+++ b/.history/src/components/table_20240728144254.js
@@ -0,0 +1,601 @@
+import React, { useState, useEffect } from 'react';
+import { Col, message, Row, Table, Card } from 'antd';
+import MyAvatar from './avatar';
+import 'antd/dist/antd.css';
+import QAmiss from './QA2';
+import TablePanel from './TablePanel';
+import ArrowRender from './arrow';
+import PointRender from './changeNumber';
+import RoundFloat from './resolveFloat';
+import Trophy from './rankTrophy';
+import expandObject from '../util/expandObject';
+import { t } from 'i18next';
+import './table.css';
+import { foundationChineseData } from './data';
+
+const activityColumns = (object, t_month) => [
+ {
+ title: t('rank'),
+ dataIndex: 'rank',
+ width: '5%',
+ align: 'center',
+ render: Trophy,
+ fixed: 'left',
+ },
+ ...(object == 'actor'
+ ? [
+ {
+ title: t('avatar'),
+ dataIndex: 'id',
+ width: '5%',
+ align: 'center',
+ render: MyAvatar,
+ fixed: 'left',
+ },
+ ]
+ : []),
+ {
+ title: '',
+ dataIndex: 'rankDelta',
+ render: ArrowRender,
+ align: 'left',
+ width: '5%',
+ fixed: 'left',
+ },
+ {
+ title: t(object),
+ dataIndex: 'name',
+ align: 'center',
+ width: '20%',
+ render: function (text, row, index) {
+ if (object !== 'company') {
+ return (
+
+ {text}
+
+ );
+ } else {
+ return text;
+ }
+ },
+ },
+ ...(object == 'repo'
+ ? [
+ {
+ title: t('insight_board'),
+ dataIndex: 'name',
+ align: 'center',
+ width: '10%',
+ render: function (text, row, index) {
+ return dashboard(text, index, t_month);
+ },
+ },
+ ]
+ : []),
+ {
+ title: t('activity'),
+ dataIndex: 'value',
+ align: 'right',
+ width: '20%',
+ },
+ {
+ title: '',
+ dataIndex: 'valueDelta',
+ width: '10%',
+ align: 'left',
+ render: PointRender,
+ },
+];
+const activityDetailColumns = (object, t_month) => [
+ {
+ title: t('rank'),
+ dataIndex: 'rank',
+ width: '5%',
+ align: 'center',
+ render: Trophy,
+ fixed: 'left',
+ },
+ ...(object == 'actor'
+ ? [
+ {
+ title: t('avatar'),
+ dataIndex: 'id',
+ width: '5%',
+ align: 'center',
+ render: MyAvatar,
+ fixed: 'left',
+ },
+ ]
+ : []),
+ {
+ title: '',
+ dataIndex: 'rankDelta',
+ render: ArrowRender,
+ align: 'left',
+ width: '5%',
+ fixed: 'left',
+ },
+ {
+ title: t(object),
+ dataIndex: 'name',
+ align: 'center',
+ width: '5%',
+ render: function (text, row, index) {
+ if (object !== 'company') {
+ return (
+
+ {text}
+
+ );
+ } else {
+ return text;
+ }
+ },
+ },
+ ...(object == 'repo'
+ ? [
+ {
+ title: t('insight_board'),
+ dataIndex: 'name',
+ align: 'center',
+ width: '10%',
+ render: function (text, row, index) {
+ return dashboard(text, index, t_month);
+ },
+ },
+ ]
+ : []),
+ {
+ title: t('activity'),
+ dataIndex: 'value',
+ align: 'center',
+ width: '10%',
+ },
+ {
+ title: '',
+ dataIndex: 'valueDelta',
+ width: '10%',
+ align: 'left',
+ render: PointRender,
+ },
+ {
+ title: t('issue_comments'),
+ dataIndex: 'issue_comment',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('open_issues'),
+ dataIndex: 'open_issue',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('open_pulls'),
+ dataIndex: 'open_pull',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('merge_pulls'),
+ dataIndex: 'merged_pull',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('pr_reviews'),
+ dataIndex: 'review_comment',
+ width: '10%',
+ align: 'center',
+ },
+];
+const open_rankColumns = (object, t_month) => [
+ {
+ // 第一列:排名
+ title: t('rank'),
+ dataIndex: 'rank',
+ width: '5%',
+ render: Trophy,
+ align: 'center',
+ fixed: 'left',
+ },
+ // 如果 object 是 'actor',则添加头像列
+ ...(object == 'actor'
+ ? [
+ {
+ title: t('avatar'),
+ dataIndex: 'id',
+ width: '5%',
+ align: 'center',
+ render: MyAvatar,
+ fixed: 'left',
+ },
+ ]
+ : []),
+ // 第二列:排名变化
+ {
+ title: '',
+ dataIndex: 'rankDelta',
+ render: ArrowRender,
+ align: 'left',
+ width: '5%',
+ fixed: 'left',
+ },
+ // 第三列:对象名称(可能是 actor, repo 或 company)
+ {
+ title: t(object),
+ dataIndex: 'name',
+ width: '20%',
+ align: 'center',
+ render: function (text) {
+ if (object !== 'company') {
+ return (
+
+ {text}
+
+ );
+ } else {
+ return text;
+ }
+ },
+ },
+ // 如果 object 是 'repo',则添加 insight_board 列
+ ...(object == 'repo'
+ ? [
+ {
+ title: t('insight_board'),
+ dataIndex: 'name',
+ align: 'center',
+ width: '10%',
+ render: function (text, row, index) {
+ return dashboard(text, index, t_month);
+ },
+ },
+ ]
+ : []),
+ // 第四列:影响力
+ {
+ title: t('influence'),
+ dataIndex: 'value',
+ width: '20%',
+ align: 'right',
+ render: (text, row, index) => {
+ return RoundFloat(text);
+ },
+ },
+ // 第五列:影响力变化
+ {
+ title: '',
+ dataIndex: 'valueDelta',
+ width: '10%',
+ align: 'left',
+ render: (text, row, index) => {
+ text = RoundFloat(text);
+ return PointRender(text, row, index);
+ },
+ },
+];
+
+const solveDate = (year, month) => {
+ if (year === null && month === null) {
+ return 'not found';
+ }
+ if (month === null) {
+ return year + '年';
+ }
+ return year + '年' + (month + 1) + '月';
+};
+
+function dashboard(text, index, t_month) {
+ if (index < 300) {
+ let [org_name, repo_name] = text.split('/');
+ const t_month_copy = t_month + ' ' + '00:00:00';
+ let params = {
+ org_name,
+ repo_name,
+ t_month_copy,
+ t_month,
+ };
+ return (
+
+
+
+ );
+ }
+}
+
+function DateTitle(props) {
+ return {solveDate(props.year, props.month)}
;
+}
+
+function MyTable(props) {
+ const [state, setState] = useState({
+ object: 'technology',
+ index: 'open_rank',
+ region: 'global',
+ showDetail: false,
+ hasDetail: true,
+ data: [],
+ showSize: 25,
+ loading: true,
+ url: '', // base + index + object + region + yearmonth + .json
+ base: 'https://oss.x-lab.info/open_leaderboard/',
+ year: null, // 字符串格式
+ month: null, // 整数格式,0表示1月,1表示2月..., null for year type time
+ type: 'month',
+ search: null,
+ category: 'cloud-native',
+ });
+
+ // 请求一次数据更新表格。如果还没读取好配置文件则不请求数据。
+ useEffect(() => {
+ if (props.year == null && props.month == null) {
+ console.log('the first loading');
+ return;
+ }
+ updateDate({
+ year: String(props.year),
+ month: props.month,
+ });
+ }, [props]);
+
+ const expandData = () => {
+ setState({
+ ...state,
+ showSize: state.showSize + 25,
+ });
+ };
+ const updateDate = (newstate) => {
+ console.log('table update', newstate);
+ // 先获取原先的表格属性
+ let {
+ base,
+ object,
+ index,
+ region,
+ month,
+ year,
+ columns,
+ showDetail,
+ hasDetail,
+ type,
+ search,
+ category,
+ } = state;
+ // 然后把表格改为加载中的状态
+ setState({ ...state, ...newstate, loading: true });
+ // 如果 newstate 有对应的属性,则进行更新
+ if (newstate.hasOwnProperty('object')) object = newstate.object;
+ if (newstate.hasOwnProperty('index')) index = newstate.index;
+ if (newstate.hasOwnProperty('region')) region = newstate.region;
+ if (newstate.hasOwnProperty('month')) month = newstate.month;
+ if (newstate.hasOwnProperty('year')) year = newstate.year;
+ if (newstate.hasOwnProperty('showDetail')) showDetail = newstate.showDetail;
+ if (newstate.hasOwnProperty('type')) type = newstate.type;
+ if (newstate.hasOwnProperty('search')) search = newstate.search;
+ if (newstate.hasOwnProperty('category')) category = newstate.category;
+
+ //获取数据大屏的‘t_month’参数
+ let myyear = newstate.year == null ? state.year : newstate.year;
+ let mymonth = newstate.month == null ? state.month : newstate.month;
+
+ mymonth = ('' + (1 + mymonth)).padStart(2, '0');
+ let t_month = `${myyear}-${mymonth}-01`;
+
+ // 根据 index 和 showDetail 改变表格的 columns 格式
+ if (index == 'activity') {
+ columns = activityColumns(object, t_month);
+ hasDetail = true;
+ }
+ if (index == 'activity' && showDetail == true) {
+ columns = activityDetailColumns(object, t_month);
+ hasDetail = true;
+ }
+ if (index == 'open_rank') {
+ columns = open_rankColumns(object, t_month);
+ hasDetail = false;
+ showDetail = false;
+ }
+ // 如果是年份数据,则把 month 置为 null。
+ // TODO:待验证,如果从年份数据切换到月份数据,似乎会自动回到原来 month 值?
+ if (type == 'year') {
+ month = null;
+ }
+ // 以当前的属性构造请求 url
+ let url = base + index + '/' + object + '/' + region + '/';
+ if (month === null) {
+ url += year + '.json';
+ } else {
+ url += year + (1 + month) + '.json';
+ }
+ console.log(url);
+ console.log(region);
+ if (object == 'foundation' && region == 'chinese') {
+ dataSource = foundationChineseData;
+
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ showDetail: showDetail,
+ hasDetail: hasDetail,
+ data: dataSource,
+ });
+
+ }
+ // fetch 异步请求
+ else{fetch(url)
+ .then((res) => {
+ // Todo:最好的情况是在日期选择器中,只显示可以查询的日期,
+ if (res.status == 404) {
+ message.warning(t('no_result'));
+ return '';
+ }
+ return res.json();
+ })
+ .then((data) => {
+ data = data.data;
+ let dataSource = [];
+ // 预处理数据,对新上榜单数据进行特殊标记处理
+ data.map((obj) => {
+ obj = expandObject(obj);
+ if (obj.rankDelta == 0 && obj.value == obj.valueDelta) {
+ obj.rankDelta = -10000000;
+ obj.valueDelta = 0;
+ }
+ dataSource.push(obj);
+ });
+ console.log(dataSource);
+
+ //搜索特定数据
+ let queryData;
+ if (search) {
+ queryData = dataSource.filter((dataSource) => {
+ let reg = new RegExp(search.trim(), 'i');
+ return reg.test(dataSource.name);
+ });
+ if (queryData.length == 0) {
+ message.warning(t('no_result'));
+ } else {
+ dataSource = queryData;
+ }
+ }
+
+ // 更新属性和表格数据
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ showDetail: showDetail,
+ hasDetail: hasDetail,
+ data: dataSource,
+ });
+ })
+ .catch((err) => {
+ console.log('hi!' + err);
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ data: [],
+ });
+ });
+
+
+ };
+ }
+ const {
+ object,
+ index,
+ region,
+ data,
+ columns,
+ loading,
+ showSize,
+ showDetail,
+ hasDetail,
+ month,
+ year,
+ type,
+ category,
+ } = state;
+ return (
+
+
+
+
+ record.rank}
+ dataSource={data.slice(0, Math.min(showSize, data.length))}
+ pagination={false}
+ loading={loading}
+ scroll={{ x: 'max-content' }}
+ />
+
+
+
+
+ {showSize < data.length ? (
+
+ {t('showMore') + '>>'}
+
+ ) : (
+
+ {t('noMore')}
+
+ )}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+}
+
+export default MyTable;
diff --git a/.history/src/components/table_20240728144348.js b/.history/src/components/table_20240728144348.js
new file mode 100644
index 0000000..d1449bc
--- /dev/null
+++ b/.history/src/components/table_20240728144348.js
@@ -0,0 +1,601 @@
+import React, { useState, useEffect } from 'react';
+import { Col, message, Row, Table, Card } from 'antd';
+import MyAvatar from './avatar';
+import 'antd/dist/antd.css';
+import QAmiss from './QA2';
+import TablePanel from './TablePanel';
+import ArrowRender from './arrow';
+import PointRender from './changeNumber';
+import RoundFloat from './resolveFloat';
+import Trophy from './rankTrophy';
+import expandObject from '../util/expandObject';
+import { t } from 'i18next';
+import './table.css';
+import { foundationChineseData } from './data';
+
+const activityColumns = (object, t_month) => [
+ {
+ title: t('rank'),
+ dataIndex: 'rank',
+ width: '5%',
+ align: 'center',
+ render: Trophy,
+ fixed: 'left',
+ },
+ ...(object == 'actor'
+ ? [
+ {
+ title: t('avatar'),
+ dataIndex: 'id',
+ width: '5%',
+ align: 'center',
+ render: MyAvatar,
+ fixed: 'left',
+ },
+ ]
+ : []),
+ {
+ title: '',
+ dataIndex: 'rankDelta',
+ render: ArrowRender,
+ align: 'left',
+ width: '5%',
+ fixed: 'left',
+ },
+ {
+ title: t(object),
+ dataIndex: 'name',
+ align: 'center',
+ width: '20%',
+ render: function (text, row, index) {
+ if (object !== 'company') {
+ return (
+
+ {text}
+
+ );
+ } else {
+ return text;
+ }
+ },
+ },
+ ...(object == 'repo'
+ ? [
+ {
+ title: t('insight_board'),
+ dataIndex: 'name',
+ align: 'center',
+ width: '10%',
+ render: function (text, row, index) {
+ return dashboard(text, index, t_month);
+ },
+ },
+ ]
+ : []),
+ {
+ title: t('activity'),
+ dataIndex: 'value',
+ align: 'right',
+ width: '20%',
+ },
+ {
+ title: '',
+ dataIndex: 'valueDelta',
+ width: '10%',
+ align: 'left',
+ render: PointRender,
+ },
+];
+const activityDetailColumns = (object, t_month) => [
+ {
+ title: t('rank'),
+ dataIndex: 'rank',
+ width: '5%',
+ align: 'center',
+ render: Trophy,
+ fixed: 'left',
+ },
+ ...(object == 'actor'
+ ? [
+ {
+ title: t('avatar'),
+ dataIndex: 'id',
+ width: '5%',
+ align: 'center',
+ render: MyAvatar,
+ fixed: 'left',
+ },
+ ]
+ : []),
+ {
+ title: '',
+ dataIndex: 'rankDelta',
+ render: ArrowRender,
+ align: 'left',
+ width: '5%',
+ fixed: 'left',
+ },
+ {
+ title: t(object),
+ dataIndex: 'name',
+ align: 'center',
+ width: '5%',
+ render: function (text, row, index) {
+ if (object !== 'company') {
+ return (
+
+ {text}
+
+ );
+ } else {
+ return text;
+ }
+ },
+ },
+ ...(object == 'repo'
+ ? [
+ {
+ title: t('insight_board'),
+ dataIndex: 'name',
+ align: 'center',
+ width: '10%',
+ render: function (text, row, index) {
+ return dashboard(text, index, t_month);
+ },
+ },
+ ]
+ : []),
+ {
+ title: t('activity'),
+ dataIndex: 'value',
+ align: 'center',
+ width: '10%',
+ },
+ {
+ title: '',
+ dataIndex: 'valueDelta',
+ width: '10%',
+ align: 'left',
+ render: PointRender,
+ },
+ {
+ title: t('issue_comments'),
+ dataIndex: 'issue_comment',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('open_issues'),
+ dataIndex: 'open_issue',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('open_pulls'),
+ dataIndex: 'open_pull',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('merge_pulls'),
+ dataIndex: 'merged_pull',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('pr_reviews'),
+ dataIndex: 'review_comment',
+ width: '10%',
+ align: 'center',
+ },
+];
+const open_rankColumns = (object, t_month) => [
+ {
+ // 第一列:排名
+ title: t('rank'),
+ dataIndex: 'rank',
+ width: '5%',
+ render: Trophy,
+ align: 'center',
+ fixed: 'left',
+ },
+ // 如果 object 是 'actor',则添加头像列
+ ...(object == 'actor'
+ ? [
+ {
+ title: t('avatar'),
+ dataIndex: 'id',
+ width: '5%',
+ align: 'center',
+ render: MyAvatar,
+ fixed: 'left',
+ },
+ ]
+ : []),
+ // 第二列:排名变化
+ {
+ title: '',
+ dataIndex: 'rankDelta',
+ render: ArrowRender,
+ align: 'left',
+ width: '5%',
+ fixed: 'left',
+ },
+ // 第三列:对象名称(可能是 actor, repo 或 company)
+ {
+ title: t(object),
+ dataIndex: 'name',
+ width: '20%',
+ align: 'center',
+ render: function (text) {
+ if (object !== 'company') {
+ return (
+
+ {text}
+
+ );
+ } else {
+ return text;
+ }
+ },
+ },
+ // 如果 object 是 'repo',则添加 insight_board 列
+ ...(object == 'repo'
+ ? [
+ {
+ title: t('insight_board'),
+ dataIndex: 'name',
+ align: 'center',
+ width: '10%',
+ render: function (text, row, index) {
+ return dashboard(text, index, t_month);
+ },
+ },
+ ]
+ : []),
+ // 第四列:影响力
+ {
+ title: t('influence'),
+ dataIndex: 'value',
+ width: '20%',
+ align: 'right',
+ render: (text, row, index) => {
+ return RoundFloat(text);
+ },
+ },
+ // 第五列:影响力变化
+ {
+ title: '',
+ dataIndex: 'valueDelta',
+ width: '10%',
+ align: 'left',
+ render: (text, row, index) => {
+ text = RoundFloat(text);
+ return PointRender(text, row, index);
+ },
+ },
+];
+
+const solveDate = (year, month) => {
+ if (year === null && month === null) {
+ return 'not found';
+ }
+ if (month === null) {
+ return year + '年';
+ }
+ return year + '年' + (month + 1) + '月';
+};
+
+function dashboard(text, index, t_month) {
+ if (index < 300) {
+ let [org_name, repo_name] = text.split('/');
+ const t_month_copy = t_month + ' ' + '00:00:00';
+ let params = {
+ org_name,
+ repo_name,
+ t_month_copy,
+ t_month,
+ };
+ return (
+
+
+
+ );
+ }
+}
+
+function DateTitle(props) {
+ return {solveDate(props.year, props.month)}
;
+}
+
+function MyTable(props) {
+ const [state, setState] = useState({
+ object: 'technology',
+ index: 'open_rank',
+ region: 'global',
+ showDetail: false,
+ hasDetail: true,
+ data: [],
+ showSize: 25,
+ loading: true,
+ url: '', // base + index + object + region + yearmonth + .json
+ base: 'https://oss.x-lab.info/open_leaderboard/',
+ year: null, // 字符串格式
+ month: null, // 整数格式,0表示1月,1表示2月..., null for year type time
+ type: 'month',
+ search: null,
+ category: 'cloud-native',
+ });
+
+ // 请求一次数据更新表格。如果还没读取好配置文件则不请求数据。
+ useEffect(() => {
+ if (props.year == null && props.month == null) {
+ console.log('the first loading');
+ return;
+ }
+ updateDate({
+ year: String(props.year),
+ month: props.month,
+ });
+ }, [props]);
+
+ const expandData = () => {
+ setState({
+ ...state,
+ showSize: state.showSize + 25,
+ });
+ };
+ const updateDate = (newstate) => {
+ console.log('table update', newstate);
+ // 先获取原先的表格属性
+ let {
+ base,
+ object,
+ index,
+ region,
+ month,
+ year,
+ columns,
+ showDetail,
+ hasDetail,
+ type,
+ search,
+ category,
+ } = state;
+ // 然后把表格改为加载中的状态
+ setState({ ...state, ...newstate, loading: true });
+ // 如果 newstate 有对应的属性,则进行更新
+ if (newstate.hasOwnProperty('object')) object = newstate.object;
+ if (newstate.hasOwnProperty('index')) index = newstate.index;
+ if (newstate.hasOwnProperty('region')) region = newstate.region;
+ if (newstate.hasOwnProperty('month')) month = newstate.month;
+ if (newstate.hasOwnProperty('year')) year = newstate.year;
+ if (newstate.hasOwnProperty('showDetail')) showDetail = newstate.showDetail;
+ if (newstate.hasOwnProperty('type')) type = newstate.type;
+ if (newstate.hasOwnProperty('search')) search = newstate.search;
+ if (newstate.hasOwnProperty('category')) category = newstate.category;
+
+ //获取数据大屏的‘t_month’参数
+ let myyear = newstate.year == null ? state.year : newstate.year;
+ let mymonth = newstate.month == null ? state.month : newstate.month;
+
+ mymonth = ('' + (1 + mymonth)).padStart(2, '0');
+ let t_month = `${myyear}-${mymonth}-01`;
+
+ // 根据 index 和 showDetail 改变表格的 columns 格式
+ if (index == 'activity') {
+ columns = activityColumns(object, t_month);
+ hasDetail = true;
+ }
+ if (index == 'activity' && showDetail == true) {
+ columns = activityDetailColumns(object, t_month);
+ hasDetail = true;
+ }
+ if (index == 'open_rank') {
+ columns = open_rankColumns(object, t_month);
+ hasDetail = false;
+ showDetail = false;
+ }
+ // 如果是年份数据,则把 month 置为 null。
+ // TODO:待验证,如果从年份数据切换到月份数据,似乎会自动回到原来 month 值?
+ if (type == 'year') {
+ month = null;
+ }
+ // 以当前的属性构造请求 url
+ let url = base + index + '/' + object + '/' + region + '/';
+ if (month === null) {
+ url += year + '.json';
+ } else {
+ url += year + (1 + month) + '.json';
+ }
+ console.log(url);
+ console.log(region);
+ if (object == "foundation" && region == 'chinese') {
+ dataSource = foundationChineseData;
+
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ showDetail: showDetail,
+ hasDetail: hasDetail,
+ data: dataSource,
+ });
+
+ }
+ // fetch 异步请求
+ else{fetch(url)
+ .then((res) => {
+ // Todo:最好的情况是在日期选择器中,只显示可以查询的日期,
+ if (res.status == 404) {
+ message.warning(t('no_result'));
+ return '';
+ }
+ return res.json();
+ })
+ .then((data) => {
+ data = data.data;
+ let dataSource = [];
+ // 预处理数据,对新上榜单数据进行特殊标记处理
+ data.map((obj) => {
+ obj = expandObject(obj);
+ if (obj.rankDelta == 0 && obj.value == obj.valueDelta) {
+ obj.rankDelta = -10000000;
+ obj.valueDelta = 0;
+ }
+ dataSource.push(obj);
+ });
+ console.log(dataSource);
+
+ //搜索特定数据
+ let queryData;
+ if (search) {
+ queryData = dataSource.filter((dataSource) => {
+ let reg = new RegExp(search.trim(), 'i');
+ return reg.test(dataSource.name);
+ });
+ if (queryData.length == 0) {
+ message.warning(t('no_result'));
+ } else {
+ dataSource = queryData;
+ }
+ }
+
+ // 更新属性和表格数据
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ showDetail: showDetail,
+ hasDetail: hasDetail,
+ data: dataSource,
+ });
+ })
+ .catch((err) => {
+ console.log('hi!' + err);
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ data: [],
+ });
+ });
+
+
+ };
+ }
+ const {
+ object,
+ index,
+ region,
+ data,
+ columns,
+ loading,
+ showSize,
+ showDetail,
+ hasDetail,
+ month,
+ year,
+ type,
+ category,
+ } = state;
+ return (
+
+
+
+
+ record.rank}
+ dataSource={data.slice(0, Math.min(showSize, data.length))}
+ pagination={false}
+ loading={loading}
+ scroll={{ x: 'max-content' }}
+ />
+
+
+
+
+ {showSize < data.length ? (
+
+ {t('showMore') + '>>'}
+
+ ) : (
+
+ {t('noMore')}
+
+ )}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+}
+
+export default MyTable;
diff --git a/.history/src/components/table_20240728144514.js b/.history/src/components/table_20240728144514.js
new file mode 100644
index 0000000..9933683
--- /dev/null
+++ b/.history/src/components/table_20240728144514.js
@@ -0,0 +1,627 @@
+import React, { useState, useEffect } from 'react';
+import { Col, message, Row, Table, Card } from 'antd';
+import MyAvatar from './avatar';
+import 'antd/dist/antd.css';
+import QAmiss from './QA2';
+import TablePanel from './TablePanel';
+import ArrowRender from './arrow';
+import PointRender from './changeNumber';
+import RoundFloat from './resolveFloat';
+import Trophy from './rankTrophy';
+import expandObject from '../util/expandObject';
+import { t } from 'i18next';
+import './table.css';
+import { foundationChineseData } from './data';
+
+const activityColumns = (object, t_month) => [
+ {
+ title: t('rank'),
+ dataIndex: 'rank',
+ width: '5%',
+ align: 'center',
+ render: Trophy,
+ fixed: 'left',
+ },
+ ...(object == 'actor'
+ ? [
+ {
+ title: t('avatar'),
+ dataIndex: 'id',
+ width: '5%',
+ align: 'center',
+ render: MyAvatar,
+ fixed: 'left',
+ },
+ ]
+ : []),
+ {
+ title: '',
+ dataIndex: 'rankDelta',
+ render: ArrowRender,
+ align: 'left',
+ width: '5%',
+ fixed: 'left',
+ },
+ {
+ title: t(object),
+ dataIndex: 'name',
+ align: 'center',
+ width: '20%',
+ render: function (text, row, index) {
+ if (object !== 'company') {
+ return (
+
+ {text}
+
+ );
+ } else {
+ return text;
+ }
+ },
+ },
+ ...(object == 'repo'
+ ? [
+ {
+ title: t('insight_board'),
+ dataIndex: 'name',
+ align: 'center',
+ width: '10%',
+ render: function (text, row, index) {
+ return dashboard(text, index, t_month);
+ },
+ },
+ ]
+ : []),
+ {
+ title: t('activity'),
+ dataIndex: 'value',
+ align: 'right',
+ width: '20%',
+ },
+ {
+ title: '',
+ dataIndex: 'valueDelta',
+ width: '10%',
+ align: 'left',
+ render: PointRender,
+ },
+];
+const activityDetailColumns = (object, t_month) => [
+ {
+ title: t('rank'),
+ dataIndex: 'rank',
+ width: '5%',
+ align: 'center',
+ render: Trophy,
+ fixed: 'left',
+ },
+ ...(object == 'actor'
+ ? [
+ {
+ title: t('avatar'),
+ dataIndex: 'id',
+ width: '5%',
+ align: 'center',
+ render: MyAvatar,
+ fixed: 'left',
+ },
+ ]
+ : []),
+ {
+ title: '',
+ dataIndex: 'rankDelta',
+ render: ArrowRender,
+ align: 'left',
+ width: '5%',
+ fixed: 'left',
+ },
+ {
+ title: t(object),
+ dataIndex: 'name',
+ align: 'center',
+ width: '5%',
+ render: function (text, row, index) {
+ if (object !== 'company') {
+ return (
+
+ {text}
+
+ );
+ } else {
+ return text;
+ }
+ },
+ },
+ ...(object == 'repo'
+ ? [
+ {
+ title: t('insight_board'),
+ dataIndex: 'name',
+ align: 'center',
+ width: '10%',
+ render: function (text, row, index) {
+ return dashboard(text, index, t_month);
+ },
+ },
+ ]
+ : []),
+ {
+ title: t('activity'),
+ dataIndex: 'value',
+ align: 'center',
+ width: '10%',
+ },
+ {
+ title: '',
+ dataIndex: 'valueDelta',
+ width: '10%',
+ align: 'left',
+ render: PointRender,
+ },
+ {
+ title: t('issue_comments'),
+ dataIndex: 'issue_comment',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('open_issues'),
+ dataIndex: 'open_issue',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('open_pulls'),
+ dataIndex: 'open_pull',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('merge_pulls'),
+ dataIndex: 'merged_pull',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('pr_reviews'),
+ dataIndex: 'review_comment',
+ width: '10%',
+ align: 'center',
+ },
+];
+const open_rankColumns = (object, t_month) => [
+ {
+ // 第一列:排名
+ title: t('rank'),
+ dataIndex: 'rank',
+ width: '5%',
+ render: Trophy,
+ align: 'center',
+ fixed: 'left',
+ },
+ // 如果 object 是 'actor',则添加头像列
+ ...(object == 'actor'
+ ? [
+ {
+ title: t('avatar'),
+ dataIndex: 'id',
+ width: '5%',
+ align: 'center',
+ render: MyAvatar,
+ fixed: 'left',
+ },
+ ]
+ : []),
+ // 第二列:排名变化
+ {
+ title: '',
+ dataIndex: 'rankDelta',
+ render: ArrowRender,
+ align: 'left',
+ width: '5%',
+ fixed: 'left',
+ },
+ // 第三列:对象名称(可能是 actor, repo 或 company)
+ {
+ title: t(object),
+ dataIndex: 'name',
+ width: '20%',
+ align: 'center',
+ render: function (text) {
+ if (object !== 'company') {
+ return (
+
+ {text}
+
+ );
+ } else {
+ return text;
+ }
+ },
+ },
+ // 如果 object 是 'repo',则添加 insight_board 列
+ ...(object == 'repo'
+ ? [
+ {
+ title: t('insight_board'),
+ dataIndex: 'name',
+ align: 'center',
+ width: '10%',
+ render: function (text, row, index) {
+ return dashboard(text, index, t_month);
+ },
+ },
+ ]
+ : []),
+ // 第四列:影响力
+ {
+ title: t('influence'),
+ dataIndex: 'value',
+ width: '20%',
+ align: 'right',
+ render: (text, row, index) => {
+ return RoundFloat(text);
+ },
+ },
+ // 第五列:影响力变化
+ {
+ title: '',
+ dataIndex: 'valueDelta',
+ width: '10%',
+ align: 'left',
+ render: (text, row, index) => {
+ text = RoundFloat(text);
+ return PointRender(text, row, index);
+ },
+ },
+];
+
+const solveDate = (year, month) => {
+ if (year === null && month === null) {
+ return 'not found';
+ }
+ if (month === null) {
+ return year + '年';
+ }
+ return year + '年' + (month + 1) + '月';
+};
+
+function dashboard(text, index, t_month) {
+ if (index < 300) {
+ let [org_name, repo_name] = text.split('/');
+ const t_month_copy = t_month + ' ' + '00:00:00';
+ let params = {
+ org_name,
+ repo_name,
+ t_month_copy,
+ t_month,
+ };
+ return (
+
+
+
+ );
+ }
+}
+
+function DateTitle(props) {
+ return {solveDate(props.year, props.month)}
;
+}
+
+function MyTable(props) {
+ const [state, setState] = useState({
+ object: 'technology',
+ index: 'open_rank',
+ region: 'global',
+ showDetail: false,
+ hasDetail: true,
+ data: [],
+ showSize: 25,
+ loading: true,
+ url: '', // base + index + object + region + yearmonth + .json
+ base: 'https://oss.x-lab.info/open_leaderboard/',
+ year: null, // 字符串格式
+ month: null, // 整数格式,0表示1月,1表示2月..., null for year type time
+ type: 'month',
+ search: null,
+ category: 'cloud-native',
+ });
+
+ // 请求一次数据更新表格。如果还没读取好配置文件则不请求数据。
+ useEffect(() => {
+ if (props.year == null && props.month == null) {
+ console.log('the first loading');
+ return;
+ }
+ updateDate({
+ year: String(props.year),
+ month: props.month,
+ });
+ }, [props]);
+
+ const expandData = () => {
+ setState({
+ ...state,
+ showSize: state.showSize + 25,
+ });
+ };
+ const updateDate = (newstate) => {
+ console.log('table update', newstate);
+ // 先获取原先的表格属性
+ let {
+ base,
+ object,
+ index,
+ region,
+ month,
+ year,
+ columns,
+ showDetail,
+ hasDetail,
+ type,
+ search,
+ category,
+ } = state;
+ // 然后把表格改为加载中的状态
+ setState({ ...state, ...newstate, loading: true });
+ // 如果 newstate 有对应的属性,则进行更新
+ if (newstate.hasOwnProperty('object')) object = newstate.object;
+ if (newstate.hasOwnProperty('index')) index = newstate.index;
+ if (newstate.hasOwnProperty('region')) region = newstate.region;
+ if (newstate.hasOwnProperty('month')) month = newstate.month;
+ if (newstate.hasOwnProperty('year')) year = newstate.year;
+ if (newstate.hasOwnProperty('showDetail')) showDetail = newstate.showDetail;
+ if (newstate.hasOwnProperty('type')) type = newstate.type;
+ if (newstate.hasOwnProperty('search')) search = newstate.search;
+ if (newstate.hasOwnProperty('category')) category = newstate.category;
+
+ //获取数据大屏的‘t_month’参数
+ let myyear = newstate.year == null ? state.year : newstate.year;
+ let mymonth = newstate.month == null ? state.month : newstate.month;
+
+ mymonth = ('' + (1 + mymonth)).padStart(2, '0');
+ let t_month = `${myyear}-${mymonth}-01`;
+
+ // 根据 index 和 showDetail 改变表格的 columns 格式
+ if (index == 'activity') {
+ columns = activityColumns(object, t_month);
+ hasDetail = true;
+ }
+ if (index == 'activity' && showDetail == true) {
+ columns = activityDetailColumns(object, t_month);
+ hasDetail = true;
+ }
+ if (index == 'open_rank') {
+ columns = open_rankColumns(object, t_month);
+ hasDetail = false;
+ showDetail = false;
+ }
+ // 如果是年份数据,则把 month 置为 null。
+ // TODO:待验证,如果从年份数据切换到月份数据,似乎会自动回到原来 month 值?
+ if (type == 'year') {
+ month = null;
+ }
+ // 以当前的属性构造请求 url
+ let url = base + index + '/' + object + '/' + region + '/';
+ if (month === null) {
+ url += year + '.json';
+ } else {
+ url += year + (1 + month) + '.json';
+ }
+ console.log(url);
+ console.log(region);
+ if (object == "foundation" && region == 'chinese') {
+ data = foundationChineseData;
+
+ let dataSource = [];
+ // 预处理数据,对新上榜单数据进行特殊标记处理
+ data.map((obj) => {
+ obj = expandObject(obj);
+ if (obj.rankDelta == 0 && obj.value == obj.valueDelta) {
+ obj.rankDelta = -10000000;
+ obj.valueDelta = 0;
+ }
+ dataSource.push(obj);
+ });
+ console.log(dataSource);
+
+ //搜索特定数据
+ let queryData;
+ if (search) {
+ queryData = dataSource.filter((dataSource) => {
+ let reg = new RegExp(search.trim(), 'i');
+ return reg.test(dataSource.name);
+ });
+ if (queryData.length == 0) {
+ message.warning(t('no_result'));
+ } else {
+ dataSource = queryData;
+ }
+ }
+
+ // 更新属性和表格数据
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ showDetail: showDetail,
+ hasDetail: hasDetail,
+ data: dataSource,
+ });
+ }
+ // fetch 异步请求
+ else{fetch(url)
+ .then((res) => {
+ // Todo:最好的情况是在日期选择器中,只显示可以查询的日期,
+ if (res.status == 404) {
+ message.warning(t('no_result'));
+ return '';
+ }
+ return res.json();
+ })
+ .then((data) => {
+ data = data.data;
+ let dataSource = [];
+ // 预处理数据,对新上榜单数据进行特殊标记处理
+ data.map((obj) => {
+ obj = expandObject(obj);
+ if (obj.rankDelta == 0 && obj.value == obj.valueDelta) {
+ obj.rankDelta = -10000000;
+ obj.valueDelta = 0;
+ }
+ dataSource.push(obj);
+ });
+ console.log(dataSource);
+
+ //搜索特定数据
+ let queryData;
+ if (search) {
+ queryData = dataSource.filter((dataSource) => {
+ let reg = new RegExp(search.trim(), 'i');
+ return reg.test(dataSource.name);
+ });
+ if (queryData.length == 0) {
+ message.warning(t('no_result'));
+ } else {
+ dataSource = queryData;
+ }
+ }
+
+ // 更新属性和表格数据
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ showDetail: showDetail,
+ hasDetail: hasDetail,
+ data: dataSource,
+ });
+ })
+ .catch((err) => {
+ console.log('hi!' + err);
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ data: [],
+ });
+ });
+
+
+ };
+ }
+ const {
+ object,
+ index,
+ region,
+ data,
+ columns,
+ loading,
+ showSize,
+ showDetail,
+ hasDetail,
+ month,
+ year,
+ type,
+ category,
+ } = state;
+ return (
+
+
+
+
+ record.rank}
+ dataSource={data.slice(0, Math.min(showSize, data.length))}
+ pagination={false}
+ loading={loading}
+ scroll={{ x: 'max-content' }}
+ />
+
+
+
+
+ {showSize < data.length ? (
+
+ {t('showMore') + '>>'}
+
+ ) : (
+
+ {t('noMore')}
+
+ )}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+}
+
+export default MyTable;
diff --git a/.history/src/components/table_20240728144641.js b/.history/src/components/table_20240728144641.js
new file mode 100644
index 0000000..7fdb8c7
--- /dev/null
+++ b/.history/src/components/table_20240728144641.js
@@ -0,0 +1,615 @@
+import React, { useState, useEffect } from 'react';
+import { Col, message, Row, Table, Card } from 'antd';
+import MyAvatar from './avatar';
+import 'antd/dist/antd.css';
+import QAmiss from './QA2';
+import TablePanel from './TablePanel';
+import ArrowRender from './arrow';
+import PointRender from './changeNumber';
+import RoundFloat from './resolveFloat';
+import Trophy from './rankTrophy';
+import expandObject from '../util/expandObject';
+import { t } from 'i18next';
+import './table.css';
+import { foundationChineseData } from './data';
+
+const activityColumns = (object, t_month) => [
+ {
+ title: t('rank'),
+ dataIndex: 'rank',
+ width: '5%',
+ align: 'center',
+ render: Trophy,
+ fixed: 'left',
+ },
+ ...(object == 'actor'
+ ? [
+ {
+ title: t('avatar'),
+ dataIndex: 'id',
+ width: '5%',
+ align: 'center',
+ render: MyAvatar,
+ fixed: 'left',
+ },
+ ]
+ : []),
+ {
+ title: '',
+ dataIndex: 'rankDelta',
+ render: ArrowRender,
+ align: 'left',
+ width: '5%',
+ fixed: 'left',
+ },
+ {
+ title: t(object),
+ dataIndex: 'name',
+ align: 'center',
+ width: '20%',
+ render: function (text, row, index) {
+ if (object !== 'company') {
+ return (
+
+ {text}
+
+ );
+ } else {
+ return text;
+ }
+ },
+ },
+ ...(object == 'repo'
+ ? [
+ {
+ title: t('insight_board'),
+ dataIndex: 'name',
+ align: 'center',
+ width: '10%',
+ render: function (text, row, index) {
+ return dashboard(text, index, t_month);
+ },
+ },
+ ]
+ : []),
+ {
+ title: t('activity'),
+ dataIndex: 'value',
+ align: 'right',
+ width: '20%',
+ },
+ {
+ title: '',
+ dataIndex: 'valueDelta',
+ width: '10%',
+ align: 'left',
+ render: PointRender,
+ },
+];
+const activityDetailColumns = (object, t_month) => [
+ {
+ title: t('rank'),
+ dataIndex: 'rank',
+ width: '5%',
+ align: 'center',
+ render: Trophy,
+ fixed: 'left',
+ },
+ ...(object == 'actor'
+ ? [
+ {
+ title: t('avatar'),
+ dataIndex: 'id',
+ width: '5%',
+ align: 'center',
+ render: MyAvatar,
+ fixed: 'left',
+ },
+ ]
+ : []),
+ {
+ title: '',
+ dataIndex: 'rankDelta',
+ render: ArrowRender,
+ align: 'left',
+ width: '5%',
+ fixed: 'left',
+ },
+ {
+ title: t(object),
+ dataIndex: 'name',
+ align: 'center',
+ width: '5%',
+ render: function (text, row, index) {
+ if (object !== 'company') {
+ return (
+
+ {text}
+
+ );
+ } else {
+ return text;
+ }
+ },
+ },
+ ...(object == 'repo'
+ ? [
+ {
+ title: t('insight_board'),
+ dataIndex: 'name',
+ align: 'center',
+ width: '10%',
+ render: function (text, row, index) {
+ return dashboard(text, index, t_month);
+ },
+ },
+ ]
+ : []),
+ {
+ title: t('activity'),
+ dataIndex: 'value',
+ align: 'center',
+ width: '10%',
+ },
+ {
+ title: '',
+ dataIndex: 'valueDelta',
+ width: '10%',
+ align: 'left',
+ render: PointRender,
+ },
+ {
+ title: t('issue_comments'),
+ dataIndex: 'issue_comment',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('open_issues'),
+ dataIndex: 'open_issue',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('open_pulls'),
+ dataIndex: 'open_pull',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('merge_pulls'),
+ dataIndex: 'merged_pull',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('pr_reviews'),
+ dataIndex: 'review_comment',
+ width: '10%',
+ align: 'center',
+ },
+];
+const open_rankColumns = (object, t_month) => [
+ {
+ // 第一列:排名
+ title: t('rank'),
+ dataIndex: 'rank',
+ width: '5%',
+ render: Trophy,
+ align: 'center',
+ fixed: 'left',
+ },
+ // 如果 object 是 'actor',则添加头像列
+ ...(object == 'actor'
+ ? [
+ {
+ title: t('avatar'),
+ dataIndex: 'id',
+ width: '5%',
+ align: 'center',
+ render: MyAvatar,
+ fixed: 'left',
+ },
+ ]
+ : []),
+ // 第二列:排名变化
+ {
+ title: '',
+ dataIndex: 'rankDelta',
+ render: ArrowRender,
+ align: 'left',
+ width: '5%',
+ fixed: 'left',
+ },
+ // 第三列:对象名称(可能是 actor, repo 或 company)
+ {
+ title: t(object),
+ dataIndex: 'name',
+ width: '20%',
+ align: 'center',
+ render: function (text) {
+ if (object !== 'company') {
+ return (
+
+ {text}
+
+ );
+ } else {
+ return text;
+ }
+ },
+ },
+ // 如果 object 是 'repo',则添加 insight_board 列
+ ...(object == 'repo'
+ ? [
+ {
+ title: t('insight_board'),
+ dataIndex: 'name',
+ align: 'center',
+ width: '10%',
+ render: function (text, row, index) {
+ return dashboard(text, index, t_month);
+ },
+ },
+ ]
+ : []),
+ // 第四列:影响力
+ {
+ title: t('influence'),
+ dataIndex: 'value',
+ width: '20%',
+ align: 'right',
+ render: (text, row, index) => {
+ return RoundFloat(text);
+ },
+ },
+ // 第五列:影响力变化
+ {
+ title: '',
+ dataIndex: 'valueDelta',
+ width: '10%',
+ align: 'left',
+ render: (text, row, index) => {
+ text = RoundFloat(text);
+ return PointRender(text, row, index);
+ },
+ },
+];
+
+const solveDate = (year, month) => {
+ if (year === null && month === null) {
+ return 'not found';
+ }
+ if (month === null) {
+ return year + '年';
+ }
+ return year + '年' + (month + 1) + '月';
+};
+
+function dashboard(text, index, t_month) {
+ if (index < 300) {
+ let [org_name, repo_name] = text.split('/');
+ const t_month_copy = t_month + ' ' + '00:00:00';
+ let params = {
+ org_name,
+ repo_name,
+ t_month_copy,
+ t_month,
+ };
+ return (
+
+
+
+ );
+ }
+}
+
+function DateTitle(props) {
+ return {solveDate(props.year, props.month)}
;
+}
+
+function MyTable(props) {
+ const [state, setState] = useState({
+ object: 'technology',
+ index: 'open_rank',
+ region: 'global',
+ showDetail: false,
+ hasDetail: true,
+ data: [],
+ showSize: 25,
+ loading: true,
+ url: '', // base + index + object + region + yearmonth + .json
+ base: 'https://oss.x-lab.info/open_leaderboard/',
+ year: null, // 字符串格式
+ month: null, // 整数格式,0表示1月,1表示2月..., null for year type time
+ type: 'month',
+ search: null,
+ category: 'cloud-native',
+ });
+
+ // 请求一次数据更新表格。如果还没读取好配置文件则不请求数据。
+ useEffect(() => {
+ if (props.year == null && props.month == null) {
+ console.log('the first loading');
+ return;
+ }
+ updateDate({
+ year: String(props.year),
+ month: props.month,
+ });
+ }, [props]);
+
+ const expandData = () => {
+ setState({
+ ...state,
+ showSize: state.showSize + 25,
+ });
+ };
+ const updateDate = (newstate) => {
+ console.log('table update', newstate);
+ // 先获取原先的表格属性
+ let {
+ base,
+ object,
+ index,
+ region,
+ month,
+ year,
+ columns,
+ showDetail,
+ hasDetail,
+ type,
+ search,
+ category,
+ } = state;
+ // 然后把表格改为加载中的状态
+ setState({ ...state, ...newstate, loading: true });
+ // 如果 newstate 有对应的属性,则进行更新
+ if (newstate.hasOwnProperty('object')) object = newstate.object;
+ if (newstate.hasOwnProperty('index')) index = newstate.index;
+ if (newstate.hasOwnProperty('region')) region = newstate.region;
+ if (newstate.hasOwnProperty('month')) month = newstate.month;
+ if (newstate.hasOwnProperty('year')) year = newstate.year;
+ if (newstate.hasOwnProperty('showDetail')) showDetail = newstate.showDetail;
+ if (newstate.hasOwnProperty('type')) type = newstate.type;
+ if (newstate.hasOwnProperty('search')) search = newstate.search;
+ if (newstate.hasOwnProperty('category')) category = newstate.category;
+
+ //获取数据大屏的‘t_month’参数
+ let myyear = newstate.year == null ? state.year : newstate.year;
+ let mymonth = newstate.month == null ? state.month : newstate.month;
+
+ mymonth = ('' + (1 + mymonth)).padStart(2, '0');
+ let t_month = `${myyear}-${mymonth}-01`;
+
+ // 根据 index 和 showDetail 改变表格的 columns 格式
+ if (index == 'activity') {
+ columns = activityColumns(object, t_month);
+ hasDetail = true;
+ }
+ if (index == 'activity' && showDetail == true) {
+ columns = activityDetailColumns(object, t_month);
+ hasDetail = true;
+ }
+ if (index == 'open_rank') {
+ columns = open_rankColumns(object, t_month);
+ hasDetail = false;
+ showDetail = false;
+ }
+ // 如果是年份数据,则把 month 置为 null。
+ // TODO:待验证,如果从年份数据切换到月份数据,似乎会自动回到原来 month 值?
+ if (type == 'year') {
+ month = null;
+ }
+ // 以当前的属性构造请求 url
+ let url = base + index + '/' + object + '/' + region + '/';
+ if (month === null) {
+ url += year + '.json';
+ } else {
+ url += year + (1 + month) + '.json';
+ }
+ console.log(url);
+ console.log(region);
+ if (object == "foundation" && region == 'chinese') {
+ dataSource = foundationChineseData;
+
+ //搜索特定数据
+ let queryData;
+ if (search) {
+ queryData = dataSource.filter((dataSource) => {
+ let reg = new RegExp(search.trim(), 'i');
+ return reg.test(dataSource.name);
+ });
+ if (queryData.length == 0) {
+ message.warning(t('no_result'));
+ } else {
+ dataSource = queryData;
+ }
+ }
+
+ // 更新属性和表格数据
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ showDetail: showDetail,
+ hasDetail: hasDetail,
+ data: dataSource,
+ });
+ }
+ // fetch 异步请求
+ else{fetch(url)
+ .then((res) => {
+ // Todo:最好的情况是在日期选择器中,只显示可以查询的日期,
+ if (res.status == 404) {
+ message.warning(t('no_result'));
+ return '';
+ }
+ return res.json();
+ })
+ .then((data) => {
+ data = data.data;
+ let dataSource = [];
+ // 预处理数据,对新上榜单数据进行特殊标记处理
+ data.map((obj) => {
+ obj = expandObject(obj);
+ if (obj.rankDelta == 0 && obj.value == obj.valueDelta) {
+ obj.rankDelta = -10000000;
+ obj.valueDelta = 0;
+ }
+ dataSource.push(obj);
+ });
+ console.log(dataSource);
+
+ //搜索特定数据
+ let queryData;
+ if (search) {
+ queryData = dataSource.filter((dataSource) => {
+ let reg = new RegExp(search.trim(), 'i');
+ return reg.test(dataSource.name);
+ });
+ if (queryData.length == 0) {
+ message.warning(t('no_result'));
+ } else {
+ dataSource = queryData;
+ }
+ }
+
+ // 更新属性和表格数据
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ showDetail: showDetail,
+ hasDetail: hasDetail,
+ data: dataSource,
+ });
+ })
+ .catch((err) => {
+ console.log('hi!' + err);
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ data: [],
+ });
+ });
+
+
+ };
+ }
+ const {
+ object,
+ index,
+ region,
+ data,
+ columns,
+ loading,
+ showSize,
+ showDetail,
+ hasDetail,
+ month,
+ year,
+ type,
+ category,
+ } = state;
+ return (
+
+
+
+
+ record.rank}
+ dataSource={data.slice(0, Math.min(showSize, data.length))}
+ pagination={false}
+ loading={loading}
+ scroll={{ x: 'max-content' }}
+ />
+
+
+
+
+ {showSize < data.length ? (
+
+ {t('showMore') + '>>'}
+
+ ) : (
+
+ {t('noMore')}
+
+ )}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+}
+
+export default MyTable;
diff --git a/.history/src/components/table_20240728144736.js b/.history/src/components/table_20240728144736.js
new file mode 100644
index 0000000..0c81980
--- /dev/null
+++ b/.history/src/components/table_20240728144736.js
@@ -0,0 +1,601 @@
+import React, { useState, useEffect } from 'react';
+import { Col, message, Row, Table, Card } from 'antd';
+import MyAvatar from './avatar';
+import 'antd/dist/antd.css';
+import QAmiss from './QA2';
+import TablePanel from './TablePanel';
+import ArrowRender from './arrow';
+import PointRender from './changeNumber';
+import RoundFloat from './resolveFloat';
+import Trophy from './rankTrophy';
+import expandObject from '../util/expandObject';
+import { t } from 'i18next';
+import './table.css';
+import { foundationChineseData } from './data';
+
+const activityColumns = (object, t_month) => [
+ {
+ title: t('rank'),
+ dataIndex: 'rank',
+ width: '5%',
+ align: 'center',
+ render: Trophy,
+ fixed: 'left',
+ },
+ ...(object == 'actor'
+ ? [
+ {
+ title: t('avatar'),
+ dataIndex: 'id',
+ width: '5%',
+ align: 'center',
+ render: MyAvatar,
+ fixed: 'left',
+ },
+ ]
+ : []),
+ {
+ title: '',
+ dataIndex: 'rankDelta',
+ render: ArrowRender,
+ align: 'left',
+ width: '5%',
+ fixed: 'left',
+ },
+ {
+ title: t(object),
+ dataIndex: 'name',
+ align: 'center',
+ width: '20%',
+ render: function (text, row, index) {
+ if (object !== 'company') {
+ return (
+
+ {text}
+
+ );
+ } else {
+ return text;
+ }
+ },
+ },
+ ...(object == 'repo'
+ ? [
+ {
+ title: t('insight_board'),
+ dataIndex: 'name',
+ align: 'center',
+ width: '10%',
+ render: function (text, row, index) {
+ return dashboard(text, index, t_month);
+ },
+ },
+ ]
+ : []),
+ {
+ title: t('activity'),
+ dataIndex: 'value',
+ align: 'right',
+ width: '20%',
+ },
+ {
+ title: '',
+ dataIndex: 'valueDelta',
+ width: '10%',
+ align: 'left',
+ render: PointRender,
+ },
+];
+const activityDetailColumns = (object, t_month) => [
+ {
+ title: t('rank'),
+ dataIndex: 'rank',
+ width: '5%',
+ align: 'center',
+ render: Trophy,
+ fixed: 'left',
+ },
+ ...(object == 'actor'
+ ? [
+ {
+ title: t('avatar'),
+ dataIndex: 'id',
+ width: '5%',
+ align: 'center',
+ render: MyAvatar,
+ fixed: 'left',
+ },
+ ]
+ : []),
+ {
+ title: '',
+ dataIndex: 'rankDelta',
+ render: ArrowRender,
+ align: 'left',
+ width: '5%',
+ fixed: 'left',
+ },
+ {
+ title: t(object),
+ dataIndex: 'name',
+ align: 'center',
+ width: '5%',
+ render: function (text, row, index) {
+ if (object !== 'company') {
+ return (
+
+ {text}
+
+ );
+ } else {
+ return text;
+ }
+ },
+ },
+ ...(object == 'repo'
+ ? [
+ {
+ title: t('insight_board'),
+ dataIndex: 'name',
+ align: 'center',
+ width: '10%',
+ render: function (text, row, index) {
+ return dashboard(text, index, t_month);
+ },
+ },
+ ]
+ : []),
+ {
+ title: t('activity'),
+ dataIndex: 'value',
+ align: 'center',
+ width: '10%',
+ },
+ {
+ title: '',
+ dataIndex: 'valueDelta',
+ width: '10%',
+ align: 'left',
+ render: PointRender,
+ },
+ {
+ title: t('issue_comments'),
+ dataIndex: 'issue_comment',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('open_issues'),
+ dataIndex: 'open_issue',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('open_pulls'),
+ dataIndex: 'open_pull',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('merge_pulls'),
+ dataIndex: 'merged_pull',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('pr_reviews'),
+ dataIndex: 'review_comment',
+ width: '10%',
+ align: 'center',
+ },
+];
+const open_rankColumns = (object, t_month) => [
+ {
+ // 第一列:排名
+ title: t('rank'),
+ dataIndex: 'rank',
+ width: '5%',
+ render: Trophy,
+ align: 'center',
+ fixed: 'left',
+ },
+ // 如果 object 是 'actor',则添加头像列
+ ...(object == 'actor'
+ ? [
+ {
+ title: t('avatar'),
+ dataIndex: 'id',
+ width: '5%',
+ align: 'center',
+ render: MyAvatar,
+ fixed: 'left',
+ },
+ ]
+ : []),
+ // 第二列:排名变化
+ {
+ title: '',
+ dataIndex: 'rankDelta',
+ render: ArrowRender,
+ align: 'left',
+ width: '5%',
+ fixed: 'left',
+ },
+ // 第三列:对象名称(可能是 actor, repo 或 company)
+ {
+ title: t(object),
+ dataIndex: 'name',
+ width: '20%',
+ align: 'center',
+ render: function (text) {
+ if (object !== 'company') {
+ return (
+
+ {text}
+
+ );
+ } else {
+ return text;
+ }
+ },
+ },
+ // 如果 object 是 'repo',则添加 insight_board 列
+ ...(object == 'repo'
+ ? [
+ {
+ title: t('insight_board'),
+ dataIndex: 'name',
+ align: 'center',
+ width: '10%',
+ render: function (text, row, index) {
+ return dashboard(text, index, t_month);
+ },
+ },
+ ]
+ : []),
+ // 第四列:影响力
+ {
+ title: t('influence'),
+ dataIndex: 'value',
+ width: '20%',
+ align: 'right',
+ render: (text, row, index) => {
+ return RoundFloat(text);
+ },
+ },
+ // 第五列:影响力变化
+ {
+ title: '',
+ dataIndex: 'valueDelta',
+ width: '10%',
+ align: 'left',
+ render: (text, row, index) => {
+ text = RoundFloat(text);
+ return PointRender(text, row, index);
+ },
+ },
+];
+
+const solveDate = (year, month) => {
+ if (year === null && month === null) {
+ return 'not found';
+ }
+ if (month === null) {
+ return year + '年';
+ }
+ return year + '年' + (month + 1) + '月';
+};
+
+function dashboard(text, index, t_month) {
+ if (index < 300) {
+ let [org_name, repo_name] = text.split('/');
+ const t_month_copy = t_month + ' ' + '00:00:00';
+ let params = {
+ org_name,
+ repo_name,
+ t_month_copy,
+ t_month,
+ };
+ return (
+
+
+
+ );
+ }
+}
+
+function DateTitle(props) {
+ return {solveDate(props.year, props.month)}
;
+}
+
+function MyTable(props) {
+ const [state, setState] = useState({
+ object: 'technology',
+ index: 'open_rank',
+ region: 'global',
+ showDetail: false,
+ hasDetail: true,
+ data: [],
+ showSize: 25,
+ loading: true,
+ url: '', // base + index + object + region + yearmonth + .json
+ base: 'https://oss.x-lab.info/open_leaderboard/',
+ year: null, // 字符串格式
+ month: null, // 整数格式,0表示1月,1表示2月..., null for year type time
+ type: 'month',
+ search: null,
+ category: 'cloud-native',
+ });
+
+ // 请求一次数据更新表格。如果还没读取好配置文件则不请求数据。
+ useEffect(() => {
+ if (props.year == null && props.month == null) {
+ console.log('the first loading');
+ return;
+ }
+ updateDate({
+ year: String(props.year),
+ month: props.month,
+ });
+ }, [props]);
+
+ const expandData = () => {
+ setState({
+ ...state,
+ showSize: state.showSize + 25,
+ });
+ };
+ const updateDate = (newstate) => {
+ console.log('table update', newstate);
+ // 先获取原先的表格属性
+ let {
+ base,
+ object,
+ index,
+ region,
+ month,
+ year,
+ columns,
+ showDetail,
+ hasDetail,
+ type,
+ search,
+ category,
+ } = state;
+ // 然后把表格改为加载中的状态
+ setState({ ...state, ...newstate, loading: true });
+ // 如果 newstate 有对应的属性,则进行更新
+ if (newstate.hasOwnProperty('object')) object = newstate.object;
+ if (newstate.hasOwnProperty('index')) index = newstate.index;
+ if (newstate.hasOwnProperty('region')) region = newstate.region;
+ if (newstate.hasOwnProperty('month')) month = newstate.month;
+ if (newstate.hasOwnProperty('year')) year = newstate.year;
+ if (newstate.hasOwnProperty('showDetail')) showDetail = newstate.showDetail;
+ if (newstate.hasOwnProperty('type')) type = newstate.type;
+ if (newstate.hasOwnProperty('search')) search = newstate.search;
+ if (newstate.hasOwnProperty('category')) category = newstate.category;
+
+ //获取数据大屏的‘t_month’参数
+ let myyear = newstate.year == null ? state.year : newstate.year;
+ let mymonth = newstate.month == null ? state.month : newstate.month;
+
+ mymonth = ('' + (1 + mymonth)).padStart(2, '0');
+ let t_month = `${myyear}-${mymonth}-01`;
+
+ // 根据 index 和 showDetail 改变表格的 columns 格式
+ if (index == 'activity') {
+ columns = activityColumns(object, t_month);
+ hasDetail = true;
+ }
+ if (index == 'activity' && showDetail == true) {
+ columns = activityDetailColumns(object, t_month);
+ hasDetail = true;
+ }
+ if (index == 'open_rank') {
+ columns = open_rankColumns(object, t_month);
+ hasDetail = false;
+ showDetail = false;
+ }
+ // 如果是年份数据,则把 month 置为 null。
+ // TODO:待验证,如果从年份数据切换到月份数据,似乎会自动回到原来 month 值?
+ if (type == 'year') {
+ month = null;
+ }
+ // 以当前的属性构造请求 url
+ let url = base + index + '/' + object + '/' + region + '/';
+ if (month === null) {
+ url += year + '.json';
+ } else {
+ url += year + (1 + month) + '.json';
+ }
+ console.log(url);
+ console.log(region);
+ if (object == "foundation" && region == 'chinese') {
+ dataSource = foundationChineseData;
+
+ // 更新属性和表格数据
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ showDetail: showDetail,
+ hasDetail: hasDetail,
+ data: dataSource,
+ });
+ }
+ // fetch 异步请求
+ else{fetch(url)
+ .then((res) => {
+ // Todo:最好的情况是在日期选择器中,只显示可以查询的日期,
+ if (res.status == 404) {
+ message.warning(t('no_result'));
+ return '';
+ }
+ return res.json();
+ })
+ .then((data) => {
+ data = data.data;
+ let dataSource = [];
+ // 预处理数据,对新上榜单数据进行特殊标记处理
+ data.map((obj) => {
+ obj = expandObject(obj);
+ if (obj.rankDelta == 0 && obj.value == obj.valueDelta) {
+ obj.rankDelta = -10000000;
+ obj.valueDelta = 0;
+ }
+ dataSource.push(obj);
+ });
+ console.log(dataSource);
+
+ //搜索特定数据
+ let queryData;
+ if (search) {
+ queryData = dataSource.filter((dataSource) => {
+ let reg = new RegExp(search.trim(), 'i');
+ return reg.test(dataSource.name);
+ });
+ if (queryData.length == 0) {
+ message.warning(t('no_result'));
+ } else {
+ dataSource = queryData;
+ }
+ }
+
+ // 更新属性和表格数据
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ showDetail: showDetail,
+ hasDetail: hasDetail,
+ data: dataSource,
+ });
+ })
+ .catch((err) => {
+ console.log('hi!' + err);
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ data: [],
+ });
+ });
+
+
+ };
+ }
+ const {
+ object,
+ index,
+ region,
+ data,
+ columns,
+ loading,
+ showSize,
+ showDetail,
+ hasDetail,
+ month,
+ year,
+ type,
+ category,
+ } = state;
+ return (
+
+
+
+
+ record.rank}
+ dataSource={data.slice(0, Math.min(showSize, data.length))}
+ pagination={false}
+ loading={loading}
+ scroll={{ x: 'max-content' }}
+ />
+
+
+
+
+ {showSize < data.length ? (
+
+ {t('showMore') + '>>'}
+
+ ) : (
+
+ {t('noMore')}
+
+ )}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+}
+
+export default MyTable;
diff --git a/.history/src/components/table_20240728150221.js b/.history/src/components/table_20240728150221.js
new file mode 100644
index 0000000..260dad2
--- /dev/null
+++ b/.history/src/components/table_20240728150221.js
@@ -0,0 +1,627 @@
+import React, { useState, useEffect } from 'react';
+import { Col, message, Row, Table, Card } from 'antd';
+import MyAvatar from './avatar';
+import 'antd/dist/antd.css';
+import QAmiss from './QA2';
+import TablePanel from './TablePanel';
+import ArrowRender from './arrow';
+import PointRender from './changeNumber';
+import RoundFloat from './resolveFloat';
+import Trophy from './rankTrophy';
+import expandObject from '../util/expandObject';
+import { t } from 'i18next';
+import './table.css';
+import { foundationChineseData } from './data';
+
+const activityColumns = (object, t_month) => [
+ {
+ title: t('rank'),
+ dataIndex: 'rank',
+ width: '5%',
+ align: 'center',
+ render: Trophy,
+ fixed: 'left',
+ },
+ ...(object == 'actor'
+ ? [
+ {
+ title: t('avatar'),
+ dataIndex: 'id',
+ width: '5%',
+ align: 'center',
+ render: MyAvatar,
+ fixed: 'left',
+ },
+ ]
+ : []),
+ {
+ title: '',
+ dataIndex: 'rankDelta',
+ render: ArrowRender,
+ align: 'left',
+ width: '5%',
+ fixed: 'left',
+ },
+ {
+ title: t(object),
+ dataIndex: 'name',
+ align: 'center',
+ width: '20%',
+ render: function (text, row, index) {
+ if (object !== 'company') {
+ return (
+
+ {text}
+
+ );
+ } else {
+ return text;
+ }
+ },
+ },
+ ...(object == 'repo'
+ ? [
+ {
+ title: t('insight_board'),
+ dataIndex: 'name',
+ align: 'center',
+ width: '10%',
+ render: function (text, row, index) {
+ return dashboard(text, index, t_month);
+ },
+ },
+ ]
+ : []),
+ {
+ title: t('activity'),
+ dataIndex: 'value',
+ align: 'right',
+ width: '20%',
+ },
+ {
+ title: '',
+ dataIndex: 'valueDelta',
+ width: '10%',
+ align: 'left',
+ render: PointRender,
+ },
+];
+const activityDetailColumns = (object, t_month) => [
+ {
+ title: t('rank'),
+ dataIndex: 'rank',
+ width: '5%',
+ align: 'center',
+ render: Trophy,
+ fixed: 'left',
+ },
+ ...(object == 'actor'
+ ? [
+ {
+ title: t('avatar'),
+ dataIndex: 'id',
+ width: '5%',
+ align: 'center',
+ render: MyAvatar,
+ fixed: 'left',
+ },
+ ]
+ : []),
+ {
+ title: '',
+ dataIndex: 'rankDelta',
+ render: ArrowRender,
+ align: 'left',
+ width: '5%',
+ fixed: 'left',
+ },
+ {
+ title: t(object),
+ dataIndex: 'name',
+ align: 'center',
+ width: '5%',
+ render: function (text, row, index) {
+ if (object !== 'company') {
+ return (
+
+ {text}
+
+ );
+ } else {
+ return text;
+ }
+ },
+ },
+ ...(object == 'repo'
+ ? [
+ {
+ title: t('insight_board'),
+ dataIndex: 'name',
+ align: 'center',
+ width: '10%',
+ render: function (text, row, index) {
+ return dashboard(text, index, t_month);
+ },
+ },
+ ]
+ : []),
+ {
+ title: t('activity'),
+ dataIndex: 'value',
+ align: 'center',
+ width: '10%',
+ },
+ {
+ title: '',
+ dataIndex: 'valueDelta',
+ width: '10%',
+ align: 'left',
+ render: PointRender,
+ },
+ {
+ title: t('issue_comments'),
+ dataIndex: 'issue_comment',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('open_issues'),
+ dataIndex: 'open_issue',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('open_pulls'),
+ dataIndex: 'open_pull',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('merge_pulls'),
+ dataIndex: 'merged_pull',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('pr_reviews'),
+ dataIndex: 'review_comment',
+ width: '10%',
+ align: 'center',
+ },
+];
+const open_rankColumns = (object, t_month) => [
+ {
+ // 第一列:排名
+ title: t('rank'),
+ dataIndex: 'rank',
+ width: '5%',
+ render: Trophy,
+ align: 'center',
+ fixed: 'left',
+ },
+ // 如果 object 是 'actor',则添加头像列
+ ...(object == 'actor'
+ ? [
+ {
+ title: t('avatar'),
+ dataIndex: 'id',
+ width: '5%',
+ align: 'center',
+ render: MyAvatar,
+ fixed: 'left',
+ },
+ ]
+ : []),
+ // 第二列:排名变化
+ {
+ title: '',
+ dataIndex: 'rankDelta',
+ render: ArrowRender,
+ align: 'left',
+ width: '5%',
+ fixed: 'left',
+ },
+ // 第三列:对象名称(可能是 actor, repo 或 company)
+ {
+ title: t(object),
+ dataIndex: 'name',
+ width: '20%',
+ align: 'center',
+ render: function (text) {
+ if (object !== 'company') {
+ return (
+
+ {text}
+
+ );
+ } else {
+ return text;
+ }
+ },
+ },
+ // 如果 object 是 'repo',则添加 insight_board 列
+ ...(object == 'repo'
+ ? [
+ {
+ title: t('insight_board'),
+ dataIndex: 'name',
+ align: 'center',
+ width: '10%',
+ render: function (text, row, index) {
+ return dashboard(text, index, t_month);
+ },
+ },
+ ]
+ : []),
+ // 第四列:影响力
+ {
+ title: t('influence'),
+ dataIndex: 'value',
+ width: '20%',
+ align: 'right',
+ render: (text, row, index) => {
+ return RoundFloat(text);
+ },
+ },
+ // 第五列:影响力变化
+ {
+ title: '',
+ dataIndex: 'valueDelta',
+ width: '10%',
+ align: 'left',
+ render: (text, row, index) => {
+ text = RoundFloat(text);
+ return PointRender(text, row, index);
+ },
+ },
+];
+
+const solveDate = (year, month) => {
+ if (year === null && month === null) {
+ return 'not found';
+ }
+ if (month === null) {
+ return year + '年';
+ }
+ return year + '年' + (month + 1) + '月';
+};
+
+function dashboard(text, index, t_month) {
+ if (index < 300) {
+ let [org_name, repo_name] = text.split('/');
+ const t_month_copy = t_month + ' ' + '00:00:00';
+ let params = {
+ org_name,
+ repo_name,
+ t_month_copy,
+ t_month,
+ };
+ return (
+
+
+
+ );
+ }
+}
+
+function DateTitle(props) {
+ return {solveDate(props.year, props.month)}
;
+}
+
+function MyTable(props) {
+ const [state, setState] = useState({
+ object: 'technology',
+ index: 'open_rank',
+ region: 'global',
+ showDetail: false,
+ hasDetail: true,
+ data: [],
+ showSize: 25,
+ loading: true,
+ url: '', // base + index + object + region + yearmonth + .json
+ base: 'https://oss.x-lab.info/open_leaderboard/',
+ year: null, // 字符串格式
+ month: null, // 整数格式,0表示1月,1表示2月..., null for year type time
+ type: 'month',
+ search: null,
+ category: 'cloud-native',
+ });
+
+ // 请求一次数据更新表格。如果还没读取好配置文件则不请求数据。
+ useEffect(() => {
+ if (props.year == null && props.month == null) {
+ console.log('the first loading');
+ return;
+ }
+ updateDate({
+ year: String(props.year),
+ month: props.month,
+ });
+ }, [props]);
+
+ const expandData = () => {
+ setState({
+ ...state,
+ showSize: state.showSize + 25,
+ });
+ };
+ const updateDate = (newstate) => {
+ console.log('table update', newstate);
+ // 先获取原先的表格属性
+ let {
+ base,
+ object,
+ index,
+ region,
+ month,
+ year,
+ columns,
+ showDetail,
+ hasDetail,
+ type,
+ search,
+ category,
+ } = state;
+ // 然后把表格改为加载中的状态
+ setState({ ...state, ...newstate, loading: true });
+ // 如果 newstate 有对应的属性,则进行更新
+ if (newstate.hasOwnProperty('object')) object = newstate.object;
+ if (newstate.hasOwnProperty('index')) index = newstate.index;
+ if (newstate.hasOwnProperty('region')) region = newstate.region;
+ if (newstate.hasOwnProperty('month')) month = newstate.month;
+ if (newstate.hasOwnProperty('year')) year = newstate.year;
+ if (newstate.hasOwnProperty('showDetail')) showDetail = newstate.showDetail;
+ if (newstate.hasOwnProperty('type')) type = newstate.type;
+ if (newstate.hasOwnProperty('search')) search = newstate.search;
+ if (newstate.hasOwnProperty('category')) category = newstate.category;
+
+ //获取数据大屏的‘t_month’参数
+ let myyear = newstate.year == null ? state.year : newstate.year;
+ let mymonth = newstate.month == null ? state.month : newstate.month;
+
+ mymonth = ('' + (1 + mymonth)).padStart(2, '0');
+ let t_month = `${myyear}-${mymonth}-01`;
+
+ // 根据 index 和 showDetail 改变表格的 columns 格式
+ if (index == 'activity') {
+ columns = activityColumns(object, t_month);
+ hasDetail = true;
+ }
+ if (index == 'activity' && showDetail == true) {
+ columns = activityDetailColumns(object, t_month);
+ hasDetail = true;
+ }
+ if (index == 'open_rank') {
+ columns = open_rankColumns(object, t_month);
+ hasDetail = false;
+ showDetail = false;
+ }
+ // 如果是年份数据,则把 month 置为 null。
+ // TODO:待验证,如果从年份数据切换到月份数据,似乎会自动回到原来 month 值?
+ if (type == 'year') {
+ month = null;
+ }
+ // 以当前的属性构造请求 url
+ let url = base + index + '/' + object + '/' + region + '/';
+ if (month === null) {
+ url += year + '.json';
+ } else {
+ url += year + (1 + month) + '.json';
+ }
+ console.log(url);
+ console.log(region);
+ if (object == "foundation" && region == 'chinese') {
+ useEffect(() => {
+ // 这里可以进行数据请求
+ fetch('../lacales/foundationChinese.json')
+ .then(response => response.json())
+ .then(data => {
+ data = data.data;
+ let dataSource = [];
+ // 预处理数据,对新上榜单数据进行特殊标记处理
+ data.map((obj) => {
+ obj = expandObject(obj);
+ if (obj.rankDelta == 0 && obj.value == obj.valueDelta) {
+ obj.rankDelta = -10000000;
+ obj.valueDelta = 0;
+ }
+ dataSource.push(obj);
+ });
+ console.log(dataSource);
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ showDetail: showDetail,
+ hasDetail: hasDetail,
+ data: dataSource,
+ });
+ })
+ .catch((err) => {
+ console.log('hi!' + err);
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ data: [],
+ });
+ });
+ }, []);
+ }
+ // fetch 异步请求
+ else{fetch(url)
+ .then((res) => {
+ // Todo:最好的情况是在日期选择器中,只显示可以查询的日期,
+ if (res.status == 404) {
+ message.warning(t('no_result'));
+ return '';
+ }
+ return res.json();
+ })
+ .then((data) => {
+ data = data.data;
+ let dataSource = [];
+ // 预处理数据,对新上榜单数据进行特殊标记处理
+ data.map((obj) => {
+ obj = expandObject(obj);
+ if (obj.rankDelta == 0 && obj.value == obj.valueDelta) {
+ obj.rankDelta = -10000000;
+ obj.valueDelta = 0;
+ }
+ dataSource.push(obj);
+ });
+ console.log(dataSource);
+
+ //搜索特定数据
+ let queryData;
+ if (search) {
+ queryData = dataSource.filter((dataSource) => {
+ let reg = new RegExp(search.trim(), 'i');
+ return reg.test(dataSource.name);
+ });
+ if (queryData.length == 0) {
+ message.warning(t('no_result'));
+ } else {
+ dataSource = queryData;
+ }
+ }
+
+ // 更新属性和表格数据
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ showDetail: showDetail,
+ hasDetail: hasDetail,
+ data: dataSource,
+ });
+ })
+ .catch((err) => {
+ console.log('hi!' + err);
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ data: [],
+ });
+ });
+
+
+ };
+ }
+ const {
+ object,
+ index,
+ region,
+ data,
+ columns,
+ loading,
+ showSize,
+ showDetail,
+ hasDetail,
+ month,
+ year,
+ type,
+ category,
+ } = state;
+ return (
+
+
+
+
+ record.rank}
+ dataSource={data.slice(0, Math.min(showSize, data.length))}
+ pagination={false}
+ loading={loading}
+ scroll={{ x: 'max-content' }}
+ />
+
+
+
+
+ {showSize < data.length ? (
+
+ {t('showMore') + '>>'}
+
+ ) : (
+
+ {t('noMore')}
+
+ )}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+}
+
+export default MyTable;
diff --git a/.history/src/components/table_20240728150719.js b/.history/src/components/table_20240728150719.js
new file mode 100644
index 0000000..3b0d213
--- /dev/null
+++ b/.history/src/components/table_20240728150719.js
@@ -0,0 +1,627 @@
+import React, { useState, useEffect } from 'react';
+import { Col, message, Row, Table, Card } from 'antd';
+import MyAvatar from './avatar';
+import 'antd/dist/antd.css';
+import QAmiss from './QA2';
+import TablePanel from './TablePanel';
+import ArrowRender from './arrow';
+import PointRender from './changeNumber';
+import RoundFloat from './resolveFloat';
+import Trophy from './rankTrophy';
+import expandObject from '../util/expandObject';
+import { t } from 'i18next';
+import './table.css';
+import { foundationChineseData } from './data';
+
+const activityColumns = (object, t_month) => [
+ {
+ title: t('rank'),
+ dataIndex: 'rank',
+ width: '5%',
+ align: 'center',
+ render: Trophy,
+ fixed: 'left',
+ },
+ ...(object == 'actor'
+ ? [
+ {
+ title: t('avatar'),
+ dataIndex: 'id',
+ width: '5%',
+ align: 'center',
+ render: MyAvatar,
+ fixed: 'left',
+ },
+ ]
+ : []),
+ {
+ title: '',
+ dataIndex: 'rankDelta',
+ render: ArrowRender,
+ align: 'left',
+ width: '5%',
+ fixed: 'left',
+ },
+ {
+ title: t(object),
+ dataIndex: 'name',
+ align: 'center',
+ width: '20%',
+ render: function (text, row, index) {
+ if (object !== 'company') {
+ return (
+
+ {text}
+
+ );
+ } else {
+ return text;
+ }
+ },
+ },
+ ...(object == 'repo'
+ ? [
+ {
+ title: t('insight_board'),
+ dataIndex: 'name',
+ align: 'center',
+ width: '10%',
+ render: function (text, row, index) {
+ return dashboard(text, index, t_month);
+ },
+ },
+ ]
+ : []),
+ {
+ title: t('activity'),
+ dataIndex: 'value',
+ align: 'right',
+ width: '20%',
+ },
+ {
+ title: '',
+ dataIndex: 'valueDelta',
+ width: '10%',
+ align: 'left',
+ render: PointRender,
+ },
+];
+const activityDetailColumns = (object, t_month) => [
+ {
+ title: t('rank'),
+ dataIndex: 'rank',
+ width: '5%',
+ align: 'center',
+ render: Trophy,
+ fixed: 'left',
+ },
+ ...(object == 'actor'
+ ? [
+ {
+ title: t('avatar'),
+ dataIndex: 'id',
+ width: '5%',
+ align: 'center',
+ render: MyAvatar,
+ fixed: 'left',
+ },
+ ]
+ : []),
+ {
+ title: '',
+ dataIndex: 'rankDelta',
+ render: ArrowRender,
+ align: 'left',
+ width: '5%',
+ fixed: 'left',
+ },
+ {
+ title: t(object),
+ dataIndex: 'name',
+ align: 'center',
+ width: '5%',
+ render: function (text, row, index) {
+ if (object !== 'company') {
+ return (
+
+ {text}
+
+ );
+ } else {
+ return text;
+ }
+ },
+ },
+ ...(object == 'repo'
+ ? [
+ {
+ title: t('insight_board'),
+ dataIndex: 'name',
+ align: 'center',
+ width: '10%',
+ render: function (text, row, index) {
+ return dashboard(text, index, t_month);
+ },
+ },
+ ]
+ : []),
+ {
+ title: t('activity'),
+ dataIndex: 'value',
+ align: 'center',
+ width: '10%',
+ },
+ {
+ title: '',
+ dataIndex: 'valueDelta',
+ width: '10%',
+ align: 'left',
+ render: PointRender,
+ },
+ {
+ title: t('issue_comments'),
+ dataIndex: 'issue_comment',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('open_issues'),
+ dataIndex: 'open_issue',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('open_pulls'),
+ dataIndex: 'open_pull',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('merge_pulls'),
+ dataIndex: 'merged_pull',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('pr_reviews'),
+ dataIndex: 'review_comment',
+ width: '10%',
+ align: 'center',
+ },
+];
+const open_rankColumns = (object, t_month) => [
+ {
+ // 第一列:排名
+ title: t('rank'),
+ dataIndex: 'rank',
+ width: '5%',
+ render: Trophy,
+ align: 'center',
+ fixed: 'left',
+ },
+ // 如果 object 是 'actor',则添加头像列
+ ...(object == 'actor'
+ ? [
+ {
+ title: t('avatar'),
+ dataIndex: 'id',
+ width: '5%',
+ align: 'center',
+ render: MyAvatar,
+ fixed: 'left',
+ },
+ ]
+ : []),
+ // 第二列:排名变化
+ {
+ title: '',
+ dataIndex: 'rankDelta',
+ render: ArrowRender,
+ align: 'left',
+ width: '5%',
+ fixed: 'left',
+ },
+ // 第三列:对象名称(可能是 actor, repo 或 company)
+ {
+ title: t(object),
+ dataIndex: 'name',
+ width: '20%',
+ align: 'center',
+ render: function (text) {
+ if (object !== 'company') {
+ return (
+
+ {text}
+
+ );
+ } else {
+ return text;
+ }
+ },
+ },
+ // 如果 object 是 'repo',则添加 insight_board 列
+ ...(object == 'repo'
+ ? [
+ {
+ title: t('insight_board'),
+ dataIndex: 'name',
+ align: 'center',
+ width: '10%',
+ render: function (text, row, index) {
+ return dashboard(text, index, t_month);
+ },
+ },
+ ]
+ : []),
+ // 第四列:影响力
+ {
+ title: t('influence'),
+ dataIndex: 'value',
+ width: '20%',
+ align: 'right',
+ render: (text, row, index) => {
+ return RoundFloat(text);
+ },
+ },
+ // 第五列:影响力变化
+ {
+ title: '',
+ dataIndex: 'valueDelta',
+ width: '10%',
+ align: 'left',
+ render: (text, row, index) => {
+ text = RoundFloat(text);
+ return PointRender(text, row, index);
+ },
+ },
+];
+
+const solveDate = (year, month) => {
+ if (year === null && month === null) {
+ return 'not found';
+ }
+ if (month === null) {
+ return year + '年';
+ }
+ return year + '年' + (month + 1) + '月';
+};
+
+function dashboard(text, index, t_month) {
+ if (index < 300) {
+ let [org_name, repo_name] = text.split('/');
+ const t_month_copy = t_month + ' ' + '00:00:00';
+ let params = {
+ org_name,
+ repo_name,
+ t_month_copy,
+ t_month,
+ };
+ return (
+
+
+
+ );
+ }
+}
+
+function DateTitle(props) {
+ return {solveDate(props.year, props.month)}
;
+}
+
+function MyTable(props) {
+ const [state, setState] = useState({
+ object: 'technology',
+ index: 'open_rank',
+ region: 'global',
+ showDetail: false,
+ hasDetail: true,
+ data: [],
+ showSize: 25,
+ loading: true,
+ url: '', // base + index + object + region + yearmonth + .json
+ base: 'https://oss.x-lab.info/open_leaderboard/',
+ year: null, // 字符串格式
+ month: null, // 整数格式,0表示1月,1表示2月..., null for year type time
+ type: 'month',
+ search: null,
+ category: 'cloud-native',
+ });
+
+ // 请求一次数据更新表格。如果还没读取好配置文件则不请求数据。
+ useEffect(() => {
+ if (props.year == null && props.month == null) {
+ console.log('the first loading');
+ return;
+ }
+ updateDate({
+ year: String(props.year),
+ month: props.month,
+ });
+ }, [props]);
+
+ const expandData = () => {
+ setState({
+ ...state,
+ showSize: state.showSize + 25,
+ });
+ };
+ const updateDate = (newstate) => {
+ console.log('table update', newstate);
+ // 先获取原先的表格属性
+ let {
+ base,
+ object,
+ index,
+ region,
+ month,
+ year,
+ columns,
+ showDetail,
+ hasDetail,
+ type,
+ search,
+ category,
+ } = state;
+ // 然后把表格改为加载中的状态
+ setState({ ...state, ...newstate, loading: true });
+ // 如果 newstate 有对应的属性,则进行更新
+ if (newstate.hasOwnProperty('object')) object = newstate.object;
+ if (newstate.hasOwnProperty('index')) index = newstate.index;
+ if (newstate.hasOwnProperty('region')) region = newstate.region;
+ if (newstate.hasOwnProperty('month')) month = newstate.month;
+ if (newstate.hasOwnProperty('year')) year = newstate.year;
+ if (newstate.hasOwnProperty('showDetail')) showDetail = newstate.showDetail;
+ if (newstate.hasOwnProperty('type')) type = newstate.type;
+ if (newstate.hasOwnProperty('search')) search = newstate.search;
+ if (newstate.hasOwnProperty('category')) category = newstate.category;
+
+ //获取数据大屏的‘t_month’参数
+ let myyear = newstate.year == null ? state.year : newstate.year;
+ let mymonth = newstate.month == null ? state.month : newstate.month;
+
+ mymonth = ('' + (1 + mymonth)).padStart(2, '0');
+ let t_month = `${myyear}-${mymonth}-01`;
+
+ // 根据 index 和 showDetail 改变表格的 columns 格式
+ if (index == 'activity') {
+ columns = activityColumns(object, t_month);
+ hasDetail = true;
+ }
+ if (index == 'activity' && showDetail == true) {
+ columns = activityDetailColumns(object, t_month);
+ hasDetail = true;
+ }
+ if (index == 'open_rank') {
+ columns = open_rankColumns(object, t_month);
+ hasDetail = false;
+ showDetail = false;
+ }
+ // 如果是年份数据,则把 month 置为 null。
+ // TODO:待验证,如果从年份数据切换到月份数据,似乎会自动回到原来 month 值?
+ if (type == 'year') {
+ month = null;
+ }
+ // 以当前的属性构造请求 url
+ let url = base + index + '/' + object + '/' + region + '/';
+ if (month === null) {
+ url += year + '.json';
+ } else {
+ url += year + (1 + onth) + '.json';
+ }
+ console.log(url);
+ console.log(region);
+ if (object == "foundation" && region == 'chinese') {
+
+ // 这里可以进行数据请求
+ fetch('../lacales/foundationChinese.json')
+ .then(response => response.json())
+ .then(data => {
+ data = data.data;
+ let dataSource = [];
+ // 预处理数据,对新上榜单数据进行特殊标记处理
+ data.map((obj) => {
+ obj = expandObject(obj);
+ if (obj.rankDelta == 0 && obj.value == obj.valueDelta) {
+ obj.rankDelta = -10000000;
+ obj.valueDelta = 0;
+ }
+ dataSource.push(obj);
+ });
+ console.log(dataSource);
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ showDetail: showDetail,
+ hasDetail: hasDetail,
+ data: dataSource,
+ });
+ })
+ .catch((err) => {
+ console.log('hi!' + err);
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ data: [],
+ });
+ });
+
+ }
+ // fetch 异步请求
+ else{fetch(url)
+ .then((res) => {
+ // Todo:最好的情况是在日期选择器中,只显示可以查询的日期,
+ if (res.status == 404) {
+ message.warning(t('no_result'));
+ return '';
+ }
+ return res.json();
+ })
+ .then((data) => {
+ data = data.data;
+ let dataSource = [];
+ // 预处理数据,对新上榜单数据进行特殊标记处理
+ data.map((obj) => {
+ obj = expandObject(obj);
+ if (obj.rankDelta == 0 && obj.value == obj.valueDelta) {
+ obj.rankDelta = -10000000;
+ obj.valueDelta = 0;
+ }
+ dataSource.push(obj);
+ });
+ console.log(dataSource);
+
+ //搜索特定数据
+ let queryData;
+ if (search) {
+ queryData = dataSource.filter((dataSource) => {
+ let reg = new RegExp(search.trim(), 'i');
+ return reg.test(dataSource.name);
+ });
+ if (queryData.length == 0) {
+ message.warning(t('no_result'));
+ } else {
+ dataSource = queryData;
+ }
+ }
+
+ // 更新属性和表格数据
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ showDetail: showDetail,
+ hasDetail: hasDetail,
+ data: dataSource,
+ });
+ })
+ .catch((err) => {
+ console.log('hi!' + err);
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ data: [],
+ });
+ });
+
+
+ };
+ }
+ const {
+ object,
+ index,
+ region,
+ data,
+ columns,
+ loading,
+ showSize,
+ showDetail,
+ hasDetail,
+ month,
+ year,
+ type,
+ category,
+ } = state;
+ return (
+
+
+
+
+ record.rank}
+ dataSource={data.slice(0, Math.min(showSize, data.length))}
+ pagination={false}
+ loading={loading}
+ scroll={{ x: 'max-content' }}
+ />
+
+
+
+
+ {showSize < data.length ? (
+
+ {t('showMore') + '>>'}
+
+ ) : (
+
+ {t('noMore')}
+
+ )}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+}
+
+export default MyTable;
diff --git a/.history/src/components/table_20240728150811.js b/.history/src/components/table_20240728150811.js
new file mode 100644
index 0000000..5014bce
--- /dev/null
+++ b/.history/src/components/table_20240728150811.js
@@ -0,0 +1,627 @@
+import React, { useState, useEffect } from 'react';
+import { Col, message, Row, Table, Card } from 'antd';
+import MyAvatar from './avatar';
+import 'antd/dist/antd.css';
+import QAmiss from './QA2';
+import TablePanel from './TablePanel';
+import ArrowRender from './arrow';
+import PointRender from './changeNumber';
+import RoundFloat from './resolveFloat';
+import Trophy from './rankTrophy';
+import expandObject from '../util/expandObject';
+import { t } from 'i18next';
+import './table.css';
+import { foundationChineseData } from './data';
+
+const activityColumns = (object, t_month) => [
+ {
+ title: t('rank'),
+ dataIndex: 'rank',
+ width: '5%',
+ align: 'center',
+ render: Trophy,
+ fixed: 'left',
+ },
+ ...(object == 'actor'
+ ? [
+ {
+ title: t('avatar'),
+ dataIndex: 'id',
+ width: '5%',
+ align: 'center',
+ render: MyAvatar,
+ fixed: 'left',
+ },
+ ]
+ : []),
+ {
+ title: '',
+ dataIndex: 'rankDelta',
+ render: ArrowRender,
+ align: 'left',
+ width: '5%',
+ fixed: 'left',
+ },
+ {
+ title: t(object),
+ dataIndex: 'name',
+ align: 'center',
+ width: '20%',
+ render: function (text, row, index) {
+ if (object !== 'company') {
+ return (
+
+ {text}
+
+ );
+ } else {
+ return text;
+ }
+ },
+ },
+ ...(object == 'repo'
+ ? [
+ {
+ title: t('insight_board'),
+ dataIndex: 'name',
+ align: 'center',
+ width: '10%',
+ render: function (text, row, index) {
+ return dashboard(text, index, t_month);
+ },
+ },
+ ]
+ : []),
+ {
+ title: t('activity'),
+ dataIndex: 'value',
+ align: 'right',
+ width: '20%',
+ },
+ {
+ title: '',
+ dataIndex: 'valueDelta',
+ width: '10%',
+ align: 'left',
+ render: PointRender,
+ },
+];
+const activityDetailColumns = (object, t_month) => [
+ {
+ title: t('rank'),
+ dataIndex: 'rank',
+ width: '5%',
+ align: 'center',
+ render: Trophy,
+ fixed: 'left',
+ },
+ ...(object == 'actor'
+ ? [
+ {
+ title: t('avatar'),
+ dataIndex: 'id',
+ width: '5%',
+ align: 'center',
+ render: MyAvatar,
+ fixed: 'left',
+ },
+ ]
+ : []),
+ {
+ title: '',
+ dataIndex: 'rankDelta',
+ render: ArrowRender,
+ align: 'left',
+ width: '5%',
+ fixed: 'left',
+ },
+ {
+ title: t(object),
+ dataIndex: 'name',
+ align: 'center',
+ width: '5%',
+ render: function (text, row, index) {
+ if (object !== 'company') {
+ return (
+
+ {text}
+
+ );
+ } else {
+ return text;
+ }
+ },
+ },
+ ...(object == 'repo'
+ ? [
+ {
+ title: t('insight_board'),
+ dataIndex: 'name',
+ align: 'center',
+ width: '10%',
+ render: function (text, row, index) {
+ return dashboard(text, index, t_month);
+ },
+ },
+ ]
+ : []),
+ {
+ title: t('activity'),
+ dataIndex: 'value',
+ align: 'center',
+ width: '10%',
+ },
+ {
+ title: '',
+ dataIndex: 'valueDelta',
+ width: '10%',
+ align: 'left',
+ render: PointRender,
+ },
+ {
+ title: t('issue_comments'),
+ dataIndex: 'issue_comment',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('open_issues'),
+ dataIndex: 'open_issue',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('open_pulls'),
+ dataIndex: 'open_pull',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('merge_pulls'),
+ dataIndex: 'merged_pull',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('pr_reviews'),
+ dataIndex: 'review_comment',
+ width: '10%',
+ align: 'center',
+ },
+];
+const open_rankColumns = (object, t_month) => [
+ {
+ // 第一列:排名
+ title: t('rank'),
+ dataIndex: 'rank',
+ width: '5%',
+ render: Trophy,
+ align: 'center',
+ fixed: 'left',
+ },
+ // 如果 object 是 'actor',则添加头像列
+ ...(object == 'actor'
+ ? [
+ {
+ title: t('avatar'),
+ dataIndex: 'id',
+ width: '5%',
+ align: 'center',
+ render: MyAvatar,
+ fixed: 'left',
+ },
+ ]
+ : []),
+ // 第二列:排名变化
+ {
+ title: '',
+ dataIndex: 'rankDelta',
+ render: ArrowRender,
+ align: 'left',
+ width: '5%',
+ fixed: 'left',
+ },
+ // 第三列:对象名称(可能是 actor, repo 或 company)
+ {
+ title: t(object),
+ dataIndex: 'name',
+ width: '20%',
+ align: 'center',
+ render: function (text) {
+ if (object !== 'company') {
+ return (
+
+ {text}
+
+ );
+ } else {
+ return text;
+ }
+ },
+ },
+ // 如果 object 是 'repo',则添加 insight_board 列
+ ...(object == 'repo'
+ ? [
+ {
+ title: t('insight_board'),
+ dataIndex: 'name',
+ align: 'center',
+ width: '10%',
+ render: function (text, row, index) {
+ return dashboard(text, index, t_month);
+ },
+ },
+ ]
+ : []),
+ // 第四列:影响力
+ {
+ title: t('influence'),
+ dataIndex: 'value',
+ width: '20%',
+ align: 'right',
+ render: (text, row, index) => {
+ return RoundFloat(text);
+ },
+ },
+ // 第五列:影响力变化
+ {
+ title: '',
+ dataIndex: 'valueDelta',
+ width: '10%',
+ align: 'left',
+ render: (text, row, index) => {
+ text = RoundFloat(text);
+ return PointRender(text, row, index);
+ },
+ },
+];
+
+const solveDate = (year, month) => {
+ if (year === null && month === null) {
+ return 'not found';
+ }
+ if (month === null) {
+ return year + '年';
+ }
+ return year + '年' + (month + 1) + '月';
+};
+
+function dashboard(text, index, t_month) {
+ if (index < 300) {
+ let [org_name, repo_name] = text.split('/');
+ const t_month_copy = t_month + ' ' + '00:00:00';
+ let params = {
+ org_name,
+ repo_name,
+ t_month_copy,
+ t_month,
+ };
+ return (
+
+
+
+ );
+ }
+}
+
+function DateTitle(props) {
+ return {solveDate(props.year, props.month)}
;
+}
+
+function MyTable(props) {
+ const [state, setState] = useState({
+ object: 'technology',
+ index: 'open_rank',
+ region: 'global',
+ showDetail: false,
+ hasDetail: true,
+ data: [],
+ showSize: 25,
+ loading: true,
+ url: '', // base + index + object + region + yearmonth + .json
+ base: 'https://oss.x-lab.info/open_leaderboard/',
+ year: null, // 字符串格式
+ month: null, // 整数格式,0表示1月,1表示2月..., null for year type time
+ type: 'month',
+ search: null,
+ category: 'cloud-native',
+ });
+
+ // 请求一次数据更新表格。如果还没读取好配置文件则不请求数据。
+ useEffect(() => {
+ if (props.year == null && props.month == null) {
+ console.log('the first loading');
+ return;
+ }
+ updateDate({
+ year: String(props.year),
+ month: props.month,
+ });
+ }, [props]);
+
+ const expandData = () => {
+ setState({
+ ...state,
+ showSize: state.showSize + 25,
+ });
+ };
+ const updateDate = (newstate) => {
+ console.log('table update', newstate);
+ // 先获取原先的表格属性
+ let {
+ base,
+ object,
+ index,
+ region,
+ month,
+ year,
+ columns,
+ showDetail,
+ hasDetail,
+ type,
+ search,
+ category,
+ } = state;
+ // 然后把表格改为加载中的状态
+ setState({ ...state, ...newstate, loading: true });
+ // 如果 newstate 有对应的属性,则进行更新
+ if (newstate.hasOwnProperty('object')) object = newstate.object;
+ if (newstate.hasOwnProperty('index')) index = newstate.index;
+ if (newstate.hasOwnProperty('region')) region = newstate.region;
+ if (newstate.hasOwnProperty('month')) month = newstate.month;
+ if (newstate.hasOwnProperty('year')) year = newstate.year;
+ if (newstate.hasOwnProperty('showDetail')) showDetail = newstate.showDetail;
+ if (newstate.hasOwnProperty('type')) type = newstate.type;
+ if (newstate.hasOwnProperty('search')) search = newstate.search;
+ if (newstate.hasOwnProperty('category')) category = newstate.category;
+
+ //获取数据大屏的‘t_month’参数
+ let myyear = newstate.year == null ? state.year : newstate.year;
+ let mymonth = newstate.month == null ? state.month : newstate.month;
+
+ mymonth = ('' + (1 + mymonth)).padStart(2, '0');
+ let t_month = `${myyear}-${mymonth}-01`;
+
+ // 根据 index 和 showDetail 改变表格的 columns 格式
+ if (index == 'activity') {
+ columns = activityColumns(object, t_month);
+ hasDetail = true;
+ }
+ if (index == 'activity' && showDetail == true) {
+ columns = activityDetailColumns(object, t_month);
+ hasDetail = true;
+ }
+ if (index == 'open_rank') {
+ columns = open_rankColumns(object, t_month);
+ hasDetail = false;
+ showDetail = false;
+ }
+ // 如果是年份数据,则把 month 置为 null。
+ // TODO:待验证,如果从年份数据切换到月份数据,似乎会自动回到原来 month 值?
+ if (type == 'year') {
+ month = null;
+ }
+ // 以当前的属性构造请求 url
+ let url = base + index + '/' + object + '/' + region + '/';
+ if (month === null) {
+ url += year + '.json';
+ } else {
+ url += year + (1 + month) + '.json';
+ }
+ console.log(url);
+ console.log(region);
+ if (object == "foundation" && region == 'chinese') {
+
+ // 这里可以进行数据请求
+ fetch('../lacales/foundationChinese.json')
+ .then(response => response.json())
+ .then(data => {
+ data = data.data;
+ let dataSource = [];
+ // 预处理数据,对新上榜单数据进行特殊标记处理
+ data.map((obj) => {
+ obj = expandObject(obj);
+ if (obj.rankDelta == 0 && obj.value == obj.valueDelta) {
+ obj.rankDelta = -10000000;
+ obj.valueDelta = 0;
+ }
+ dataSource.push(obj);
+ });
+ console.log(dataSource);
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ showDetail: showDetail,
+ hasDetail: hasDetail,
+ data: dataSource,
+ });
+ })
+ .catch((err) => {
+ console.log('hi!' + err);
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ data: [],
+ });
+ });
+
+ }
+ // fetch 异步请求
+ else{fetch(url)
+ .then((res) => {
+ // Todo:最好的情况是在日期选择器中,只显示可以查询的日期,
+ if (res.status == 404) {
+ message.warning(t('no_result'));
+ return '';
+ }
+ return res.json();
+ })
+ .then((data) => {
+ data = data.data;
+ let dataSource = [];
+ // 预处理数据,对新上榜单数据进行特殊标记处理
+ data.map((obj) => {
+ obj = expandObject(obj);
+ if (obj.rankDelta == 0 && obj.value == obj.valueDelta) {
+ obj.rankDelta = -10000000;
+ obj.valueDelta = 0;
+ }
+ dataSource.push(obj);
+ });
+ console.log(dataSource);
+
+ //搜索特定数据
+ let queryData;
+ if (search) {
+ queryData = dataSource.filter((dataSource) => {
+ let reg = new RegExp(search.trim(), 'i');
+ return reg.test(dataSource.name);
+ });
+ if (queryData.length == 0) {
+ message.warning(t('no_result'));
+ } else {
+ dataSource = queryData;
+ }
+ }
+
+ // 更新属性和表格数据
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ showDetail: showDetail,
+ hasDetail: hasDetail,
+ data: dataSource,
+ });
+ })
+ .catch((err) => {
+ console.log('hi!' + err);
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ data: [],
+ });
+ });
+
+
+ };
+ }
+ const {
+ object,
+ index,
+ region,
+ data,
+ columns,
+ loading,
+ showSize,
+ showDetail,
+ hasDetail,
+ month,
+ year,
+ type,
+ category,
+ } = state;
+ return (
+
+
+
+
+ record.rank}
+ dataSource={data.slice(0, Math.min(showSize, data.length))}
+ pagination={false}
+ loading={loading}
+ scroll={{ x: 'max-content' }}
+ />
+
+
+
+
+ {showSize < data.length ? (
+
+ {t('showMore') + '>>'}
+
+ ) : (
+
+ {t('noMore')}
+
+ )}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+}
+
+export default MyTable;
diff --git a/.history/src/components/table_20240728150851.js b/.history/src/components/table_20240728150851.js
new file mode 100644
index 0000000..e63e7a0
--- /dev/null
+++ b/.history/src/components/table_20240728150851.js
@@ -0,0 +1,627 @@
+import React, { useState, useEffect } from 'react';
+import { Col, message, Row, Table, Card } from 'antd';
+import MyAvatar from './avatar';
+import 'antd/dist/antd.css';
+import QAmiss from './QA2';
+import TablePanel from './TablePanel';
+import ArrowRender from './arrow';
+import PointRender from './changeNumber';
+import RoundFloat from './resolveFloat';
+import Trophy from './rankTrophy';
+import expandObject from '../util/expandObject';
+import { t } from 'i18next';
+import './table.css';
+import { foundationChineseData } from './data';
+
+const activityColumns = (object, t_month) => [
+ {
+ title: t('rank'),
+ dataIndex: 'rank',
+ width: '5%',
+ align: 'center',
+ render: Trophy,
+ fixed: 'left',
+ },
+ ...(object == 'actor'
+ ? [
+ {
+ title: t('avatar'),
+ dataIndex: 'id',
+ width: '5%',
+ align: 'center',
+ render: MyAvatar,
+ fixed: 'left',
+ },
+ ]
+ : []),
+ {
+ title: '',
+ dataIndex: 'rankDelta',
+ render: ArrowRender,
+ align: 'left',
+ width: '5%',
+ fixed: 'left',
+ },
+ {
+ title: t(object),
+ dataIndex: 'name',
+ align: 'center',
+ width: '20%',
+ render: function (text, row, index) {
+ if (object !== 'company') {
+ return (
+
+ {text}
+
+ );
+ } else {
+ return text;
+ }
+ },
+ },
+ ...(object == 'repo'
+ ? [
+ {
+ title: t('insight_board'),
+ dataIndex: 'name',
+ align: 'center',
+ width: '10%',
+ render: function (text, row, index) {
+ return dashboard(text, index, t_month);
+ },
+ },
+ ]
+ : []),
+ {
+ title: t('activity'),
+ dataIndex: 'value',
+ align: 'right',
+ width: '20%',
+ },
+ {
+ title: '',
+ dataIndex: 'valueDelta',
+ width: '10%',
+ align: 'left',
+ render: PointRender,
+ },
+];
+const activityDetailColumns = (object, t_month) => [
+ {
+ title: t('rank'),
+ dataIndex: 'rank',
+ width: '5%',
+ align: 'center',
+ render: Trophy,
+ fixed: 'left',
+ },
+ ...(object == 'actor'
+ ? [
+ {
+ title: t('avatar'),
+ dataIndex: 'id',
+ width: '5%',
+ align: 'center',
+ render: MyAvatar,
+ fixed: 'left',
+ },
+ ]
+ : []),
+ {
+ title: '',
+ dataIndex: 'rankDelta',
+ render: ArrowRender,
+ align: 'left',
+ width: '5%',
+ fixed: 'left',
+ },
+ {
+ title: t(object),
+ dataIndex: 'name',
+ align: 'center',
+ width: '5%',
+ render: function (text, row, index) {
+ if (object !== 'company') {
+ return (
+
+ {text}
+
+ );
+ } else {
+ return text;
+ }
+ },
+ },
+ ...(object == 'repo'
+ ? [
+ {
+ title: t('insight_board'),
+ dataIndex: 'name',
+ align: 'center',
+ width: '10%',
+ render: function (text, row, index) {
+ return dashboard(text, index, t_month);
+ },
+ },
+ ]
+ : []),
+ {
+ title: t('activity'),
+ dataIndex: 'value',
+ align: 'center',
+ width: '10%',
+ },
+ {
+ title: '',
+ dataIndex: 'valueDelta',
+ width: '10%',
+ align: 'left',
+ render: PointRender,
+ },
+ {
+ title: t('issue_comments'),
+ dataIndex: 'issue_comment',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('open_issues'),
+ dataIndex: 'open_issue',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('open_pulls'),
+ dataIndex: 'open_pull',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('merge_pulls'),
+ dataIndex: 'merged_pull',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('pr_reviews'),
+ dataIndex: 'review_comment',
+ width: '10%',
+ align: 'center',
+ },
+];
+const open_rankColumns = (object, t_month) => [
+ {
+ // 第一列:排名
+ title: t('rank'),
+ dataIndex: 'rank',
+ width: '5%',
+ render: Trophy,
+ align: 'center',
+ fixed: 'left',
+ },
+ // 如果 object 是 'actor',则添加头像列
+ ...(object == 'actor'
+ ? [
+ {
+ title: t('avatar'),
+ dataIndex: 'id',
+ width: '5%',
+ align: 'center',
+ render: MyAvatar,
+ fixed: 'left',
+ },
+ ]
+ : []),
+ // 第二列:排名变化
+ {
+ title: '',
+ dataIndex: 'rankDelta',
+ render: ArrowRender,
+ align: 'left',
+ width: '5%',
+ fixed: 'left',
+ },
+ // 第三列:对象名称(可能是 actor, repo 或 company)
+ {
+ title: t(object),
+ dataIndex: 'name',
+ width: '20%',
+ align: 'center',
+ render: function (text) {
+ if (object !== 'company') {
+ return (
+
+ {text}
+
+ );
+ } else {
+ return text;
+ }
+ },
+ },
+ // 如果 object 是 'repo',则添加 insight_board 列
+ ...(object == 'repo'
+ ? [
+ {
+ title: t('insight_board'),
+ dataIndex: 'name',
+ align: 'center',
+ width: '10%',
+ render: function (text, row, index) {
+ return dashboard(text, index, t_month);
+ },
+ },
+ ]
+ : []),
+ // 第四列:影响力
+ {
+ title: t('influence'),
+ dataIndex: 'value',
+ width: '20%',
+ align: 'right',
+ render: (text, row, index) => {
+ return RoundFloat(text);
+ },
+ },
+ // 第五列:影响力变化
+ {
+ title: '',
+ dataIndex: 'valueDelta',
+ width: '10%',
+ align: 'left',
+ render: (text, row, index) => {
+ text = RoundFloat(text);
+ return PointRender(text, row, index);
+ },
+ },
+];
+
+const solveDate = (year, month) => {
+ if (year === null && month === null) {
+ return 'not found';
+ }
+ if (month === null) {
+ return year + '年';
+ }
+ return year + '年' + (month + 1) + '月';
+};
+
+function dashboard(text, index, t_month) {
+ if (index < 300) {
+ let [org_name, repo_name] = text.split('/');
+ const t_month_copy = t_month + ' ' + '00:00:00';
+ let params = {
+ org_name,
+ repo_name,
+ t_month_copy,
+ t_month,
+ };
+ return (
+
+
+
+ );
+ }
+}
+
+function DateTitle(props) {
+ return {solveDate(props.year, props.month)}
;
+}
+
+function MyTable(props) {
+ const [state, setState] = useState({
+ object: 'technology',
+ index: 'open_rank',
+ region: 'global',
+ showDetail: false,
+ hasDetail: true,
+ data: [],
+ showSize: 25,
+ loading: true,
+ url: '', // base + index + object + region + yearmonth + .json
+ base: 'https://oss.x-lab.info/open_leaderboard/',
+ year: null, // 字符串格式
+ month: null, // 整数格式,0表示1月,1表示2月..., null for year type time
+ type: 'month',
+ search: null,
+ category: 'cloud-native',
+ });
+
+ // 请求一次数据更新表格。如果还没读取好配置文件则不请求数据。
+ useEffect(() => {
+ if (props.year == null && props.month == null) {
+ console.log('the first loading');
+ return;
+ }
+ updateDate({
+ year: String(props.year),
+ month: props.month,
+ });
+ }, [props]);
+
+ const expandData = () => {
+ setState({
+ ...state,
+ showSize: state.showSize + 25,
+ });
+ };
+ const updateDate = (newstate) => {
+ console.log('table update', newstate);
+ // 先获取原先的表格属性
+ let {
+ base,
+ object,
+ index,
+ region,
+ month,
+ year,
+ columns,
+ showDetail,
+ hasDetail,
+ type,
+ search,
+ category,
+ } = state;
+ // 然后把表格改为加载中的状态
+ setState({ ...state, ...newstate, loading: true });
+ // 如果 newstate 有对应的属性,则进行更新
+ if (newstate.hasOwnProperty('object')) object = newstate.object;
+ if (newstate.hasOwnProperty('index')) index = newstate.index;
+ if (newstate.hasOwnProperty('region')) region = newstate.region;
+ if (newstate.hasOwnProperty('month')) month = newstate.month;
+ if (newstate.hasOwnProperty('year')) year = newstate.year;
+ if (newstate.hasOwnProperty('showDetail')) showDetail = newstate.showDetail;
+ if (newstate.hasOwnProperty('type')) type = newstate.type;
+ if (newstate.hasOwnProperty('search')) search = newstate.search;
+ if (newstate.hasOwnProperty('category')) category = newstate.category;
+
+ //获取数据大屏的‘t_month’参数
+ let myyear = newstate.year == null ? state.year : newstate.year;
+ let mymonth = newstate.month == null ? state.month : newstate.month;
+
+ mymonth = ('' + (1 + mymonth)).padStart(2, '0');
+ let t_month = `${myyear}-${mymonth}-01`;
+
+ // 根据 index 和 showDetail 改变表格的 columns 格式
+ if (index == 'activity') {
+ columns = activityColumns(object, t_month);
+ hasDetail = true;
+ }
+ if (index == 'activity' && showDetail == true) {
+ columns = activityDetailColumns(object, t_month);
+ hasDetail = true;
+ }
+ if (index == 'open_rank') {
+ columns = open_rankColumns(object, t_month);
+ hasDetail = false;
+ showDetail = false;
+ }
+ // 如果是年份数据,则把 month 置为 null。
+ // TODO:待验证,如果从年份数据切换到月份数据,似乎会自动回到原来 month 值?
+ if (type == 'year') {
+ month = null;
+ }
+ // 以当前的属性构造请求 url
+ let url = base + index + '/' + object + '/' + region + '/';
+ if (month === null) {
+ url += year + '.json';
+ } else {
+ url += year + (1 + month) + '.json';
+ }
+ console.log(url);
+ console.log(region);
+ if (object == "foundation" && region == 'chinese') {
+
+ // 这里可以进行数据请求
+ fetch('../locales/foundationChinese.json')
+ .then(response => response.json())
+ .then(data => {
+ data = data.data;
+ let dataSource = [];
+ // 预处理数据,对新上榜单数据进行特殊标记处理
+ data.map((obj) => {
+ obj = expandObject(obj);
+ if (obj.rankDelta == 0 && obj.value == obj.valueDelta) {
+ obj.rankDelta = -10000000;
+ obj.valueDelta = 0;
+ }
+ dataSource.push(obj);
+ });
+ console.log(dataSource);
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ showDetail: showDetail,
+ hasDetail: hasDetail,
+ data: dataSource,
+ });
+ })
+ .catch((err) => {
+ console.log('hi!' + err);
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ data: [],
+ });
+ });
+
+ }
+ // fetch 异步请求
+ else{fetch(url)
+ .then((res) => {
+ // Todo:最好的情况是在日期选择器中,只显示可以查询的日期,
+ if (res.status == 404) {
+ message.warning(t('no_result'));
+ return '';
+ }
+ return res.json();
+ })
+ .then((data) => {
+ data = data.data;
+ let dataSource = [];
+ // 预处理数据,对新上榜单数据进行特殊标记处理
+ data.map((obj) => {
+ obj = expandObject(obj);
+ if (obj.rankDelta == 0 && obj.value == obj.valueDelta) {
+ obj.rankDelta = -10000000;
+ obj.valueDelta = 0;
+ }
+ dataSource.push(obj);
+ });
+ console.log(dataSource);
+
+ //搜索特定数据
+ let queryData;
+ if (search) {
+ queryData = dataSource.filter((dataSource) => {
+ let reg = new RegExp(search.trim(), 'i');
+ return reg.test(dataSource.name);
+ });
+ if (queryData.length == 0) {
+ message.warning(t('no_result'));
+ } else {
+ dataSource = queryData;
+ }
+ }
+
+ // 更新属性和表格数据
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ showDetail: showDetail,
+ hasDetail: hasDetail,
+ data: dataSource,
+ });
+ })
+ .catch((err) => {
+ console.log('hi!' + err);
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ data: [],
+ });
+ });
+
+
+ };
+ }
+ const {
+ object,
+ index,
+ region,
+ data,
+ columns,
+ loading,
+ showSize,
+ showDetail,
+ hasDetail,
+ month,
+ year,
+ type,
+ category,
+ } = state;
+ return (
+
+
+
+
+ record.rank}
+ dataSource={data.slice(0, Math.min(showSize, data.length))}
+ pagination={false}
+ loading={loading}
+ scroll={{ x: 'max-content' }}
+ />
+
+
+
+
+ {showSize < data.length ? (
+
+ {t('showMore') + '>>'}
+
+ ) : (
+
+ {t('noMore')}
+
+ )}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+}
+
+export default MyTable;
diff --git a/.history/src/components/table_20240728151211.js b/.history/src/components/table_20240728151211.js
new file mode 100644
index 0000000..8dd2f0a
--- /dev/null
+++ b/.history/src/components/table_20240728151211.js
@@ -0,0 +1,650 @@
+import React, { useState, useEffect } from 'react';
+import { Col, message, Row, Table, Card } from 'antd';
+import MyAvatar from './avatar';
+import 'antd/dist/antd.css';
+import QAmiss from './QA2';
+import TablePanel from './TablePanel';
+import ArrowRender from './arrow';
+import PointRender from './changeNumber';
+import RoundFloat from './resolveFloat';
+import Trophy from './rankTrophy';
+import expandObject from '../util/expandObject';
+import { t } from 'i18next';
+import './table.css';
+import { foundationChineseData } from './data';
+
+const activityColumns = (object, t_month) => [
+ {
+ title: t('rank'),
+ dataIndex: 'rank',
+ width: '5%',
+ align: 'center',
+ render: Trophy,
+ fixed: 'left',
+ },
+ ...(object == 'actor'
+ ? [
+ {
+ title: t('avatar'),
+ dataIndex: 'id',
+ width: '5%',
+ align: 'center',
+ render: MyAvatar,
+ fixed: 'left',
+ },
+ ]
+ : []),
+ {
+ title: '',
+ dataIndex: 'rankDelta',
+ render: ArrowRender,
+ align: 'left',
+ width: '5%',
+ fixed: 'left',
+ },
+ {
+ title: t(object),
+ dataIndex: 'name',
+ align: 'center',
+ width: '20%',
+ render: function (text, row, index) {
+ if (object !== 'company') {
+ return (
+
+ {text}
+
+ );
+ } else {
+ return text;
+ }
+ },
+ },
+ ...(object == 'repo'
+ ? [
+ {
+ title: t('insight_board'),
+ dataIndex: 'name',
+ align: 'center',
+ width: '10%',
+ render: function (text, row, index) {
+ return dashboard(text, index, t_month);
+ },
+ },
+ ]
+ : []),
+ {
+ title: t('activity'),
+ dataIndex: 'value',
+ align: 'right',
+ width: '20%',
+ },
+ {
+ title: '',
+ dataIndex: 'valueDelta',
+ width: '10%',
+ align: 'left',
+ render: PointRender,
+ },
+];
+const activityDetailColumns = (object, t_month) => [
+ {
+ title: t('rank'),
+ dataIndex: 'rank',
+ width: '5%',
+ align: 'center',
+ render: Trophy,
+ fixed: 'left',
+ },
+ ...(object == 'actor'
+ ? [
+ {
+ title: t('avatar'),
+ dataIndex: 'id',
+ width: '5%',
+ align: 'center',
+ render: MyAvatar,
+ fixed: 'left',
+ },
+ ]
+ : []),
+ {
+ title: '',
+ dataIndex: 'rankDelta',
+ render: ArrowRender,
+ align: 'left',
+ width: '5%',
+ fixed: 'left',
+ },
+ {
+ title: t(object),
+ dataIndex: 'name',
+ align: 'center',
+ width: '5%',
+ render: function (text, row, index) {
+ if (object !== 'company') {
+ return (
+
+ {text}
+
+ );
+ } else {
+ return text;
+ }
+ },
+ },
+ ...(object == 'repo'
+ ? [
+ {
+ title: t('insight_board'),
+ dataIndex: 'name',
+ align: 'center',
+ width: '10%',
+ render: function (text, row, index) {
+ return dashboard(text, index, t_month);
+ },
+ },
+ ]
+ : []),
+ {
+ title: t('activity'),
+ dataIndex: 'value',
+ align: 'center',
+ width: '10%',
+ },
+ {
+ title: '',
+ dataIndex: 'valueDelta',
+ width: '10%',
+ align: 'left',
+ render: PointRender,
+ },
+ {
+ title: t('issue_comments'),
+ dataIndex: 'issue_comment',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('open_issues'),
+ dataIndex: 'open_issue',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('open_pulls'),
+ dataIndex: 'open_pull',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('merge_pulls'),
+ dataIndex: 'merged_pull',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('pr_reviews'),
+ dataIndex: 'review_comment',
+ width: '10%',
+ align: 'center',
+ },
+];
+const open_rankColumns = (object, t_month) => [
+ {
+ // 第一列:排名
+ title: t('rank'),
+ dataIndex: 'rank',
+ width: '5%',
+ render: Trophy,
+ align: 'center',
+ fixed: 'left',
+ },
+ // 如果 object 是 'actor',则添加头像列
+ ...(object == 'actor'
+ ? [
+ {
+ title: t('avatar'),
+ dataIndex: 'id',
+ width: '5%',
+ align: 'center',
+ render: MyAvatar,
+ fixed: 'left',
+ },
+ ]
+ : []),
+ // 第二列:排名变化
+ {
+ title: '',
+ dataIndex: 'rankDelta',
+ render: ArrowRender,
+ align: 'left',
+ width: '5%',
+ fixed: 'left',
+ },
+ // 第三列:对象名称(可能是 actor, repo 或 company)
+ {
+ title: t(object),
+ dataIndex: 'name',
+ width: '20%',
+ align: 'center',
+ render: function (text) {
+ if (object !== 'company') {
+ return (
+
+ {text}
+
+ );
+ } else {
+ return text;
+ }
+ },
+ },
+ // 如果 object 是 'repo',则添加 insight_board 列
+ ...(object == 'repo'
+ ? [
+ {
+ title: t('insight_board'),
+ dataIndex: 'name',
+ align: 'center',
+ width: '10%',
+ render: function (text, row, index) {
+ return dashboard(text, index, t_month);
+ },
+ },
+ ]
+ : []),
+ // 第四列:影响力
+ {
+ title: t('influence'),
+ dataIndex: 'value',
+ width: '20%',
+ align: 'right',
+ render: (text, row, index) => {
+ return RoundFloat(text);
+ },
+ },
+ // 第五列:影响力变化
+ {
+ title: '',
+ dataIndex: 'valueDelta',
+ width: '10%',
+ align: 'left',
+ render: (text, row, index) => {
+ text = RoundFloat(text);
+ return PointRender(text, row, index);
+ },
+ },
+];
+
+const solveDate = (year, month) => {
+ if (year === null && month === null) {
+ return 'not found';
+ }
+ if (month === null) {
+ return year + '年';
+ }
+ return year + '年' + (month + 1) + '月';
+};
+
+function dashboard(text, index, t_month) {
+ if (index < 300) {
+ let [org_name, repo_name] = text.split('/');
+ const t_month_copy = t_month + ' ' + '00:00:00';
+ let params = {
+ org_name,
+ repo_name,
+ t_month_copy,
+ t_month,
+ };
+ return (
+
+
+
+ );
+ }
+}
+
+function DateTitle(props) {
+ return {solveDate(props.year, props.month)}
;
+}
+
+function MyTable(props) {
+ const [state, setState] = useState({
+ object: 'technology',
+ index: 'open_rank',
+ region: 'global',
+ showDetail: false,
+ hasDetail: true,
+ data: [],
+ showSize: 25,
+ loading: true,
+ url: '', // base + index + object + region + yearmonth + .json
+ base: 'https://oss.x-lab.info/open_leaderboard/',
+ year: null, // 字符串格式
+ month: null, // 整数格式,0表示1月,1表示2月..., null for year type time
+ type: 'month',
+ search: null,
+ category: 'cloud-native',
+ });
+
+ // 请求一次数据更新表格。如果还没读取好配置文件则不请求数据。
+ useEffect(() => {
+ if (props.year == null && props.month == null) {
+ console.log('the first loading');
+ return;
+ }
+ updateDate({
+ year: String(props.year),
+ month: props.month,
+ });
+ }, [props]);
+
+ const expandData = () => {
+ setState({
+ ...state,
+ showSize: state.showSize + 25,
+ });
+ };
+ const updateDate = (newstate) => {
+ console.log('table update', newstate);
+ // 先获取原先的表格属性
+ let {
+ base,
+ object,
+ index,
+ region,
+ month,
+ year,
+ columns,
+ showDetail,
+ hasDetail,
+ type,
+ search,
+ category,
+ } = state;
+ // 然后把表格改为加载中的状态
+ setState({ ...state, ...newstate, loading: true });
+ // 如果 newstate 有对应的属性,则进行更新
+ if (newstate.hasOwnProperty('object')) object = newstate.object;
+ if (newstate.hasOwnProperty('index')) index = newstate.index;
+ if (newstate.hasOwnProperty('region')) region = newstate.region;
+ if (newstate.hasOwnProperty('month')) month = newstate.month;
+ if (newstate.hasOwnProperty('year')) year = newstate.year;
+ if (newstate.hasOwnProperty('showDetail')) showDetail = newstate.showDetail;
+ if (newstate.hasOwnProperty('type')) type = newstate.type;
+ if (newstate.hasOwnProperty('search')) search = newstate.search;
+ if (newstate.hasOwnProperty('category')) category = newstate.category;
+
+ //获取数据大屏的‘t_month’参数
+ let myyear = newstate.year == null ? state.year : newstate.year;
+ let mymonth = newstate.month == null ? state.month : newstate.month;
+
+ mymonth = ('' + (1 + mymonth)).padStart(2, '0');
+ let t_month = `${myyear}-${mymonth}-01`;
+
+ // 根据 index 和 showDetail 改变表格的 columns 格式
+ if (index == 'activity') {
+ columns = activityColumns(object, t_month);
+ hasDetail = true;
+ }
+ if (index == 'activity' && showDetail == true) {
+ columns = activityDetailColumns(object, t_month);
+ hasDetail = true;
+ }
+ if (index == 'open_rank') {
+ columns = open_rankColumns(object, t_month);
+ hasDetail = false;
+ showDetail = false;
+ }
+ // 如果是年份数据,则把 month 置为 null。
+ // TODO:待验证,如果从年份数据切换到月份数据,似乎会自动回到原来 month 值?
+ if (type == 'year') {
+ month = null;
+ }
+ // 以当前的属性构造请求 url
+ let url = base + index + '/' + object + '/' + region + '/';
+ if (month === null) {
+ url += year + '.json';
+ } else {
+ url += year + (1 + month) + '.json';
+ }
+ console.log(url);
+ console.log(region);
+ if (object == "foundation" && region == 'chinese') {
+
+ // 这里可以进行数据请求
+ fetch('../locales/foundationChinese.json')
+ ..then((res) => {
+ // Todo:最好的情况是在日期选择器中,只显示可以查询的日期,
+ if (res.status == 404) {
+ message.warning(t('no_result'));
+ return '';
+ }
+ return res.json();
+ })
+ .then((data) => {
+ data = data.data;
+ let dataSource = [];
+ // 预处理数据,对新上榜单数据进行特殊标记处理
+ data.map((obj) => {
+ obj = expandObject(obj);
+ if (obj.rankDelta == 0 && obj.value == obj.valueDelta) {
+ obj.rankDelta = -10000000;
+ obj.valueDelta = 0;
+ }
+ dataSource.push(obj);
+ });
+ console.log(dataSource);
+
+ //搜索特定数据
+ let queryData;
+ if (search) {
+ queryData = dataSource.filter((dataSource) => {
+ let reg = new RegExp(search.trim(), 'i');
+ return reg.test(dataSource.name);
+ });
+ if (queryData.length == 0) {
+ message.warning(t('no_result'));
+ } else {
+ dataSource = queryData;
+ }
+ }
+
+ // 更新属性和表格数据
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ showDetail: showDetail,
+ hasDetail: hasDetail,
+ data: dataSource,
+ });
+ })
+ .catch((err) => {
+ console.log('hi!' + err);
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ data: [],
+ });
+ });
+
+ }
+ // fetch 异步请求
+ else{fetch(url)
+ .then((res) => {
+ // Todo:最好的情况是在日期选择器中,只显示可以查询的日期,
+ if (res.status == 404) {
+ message.warning(t('no_result'));
+ return '';
+ }
+ return res.json();
+ })
+ .then((data) => {
+ data = data.data;
+ let dataSource = [];
+ // 预处理数据,对新上榜单数据进行特殊标记处理
+ data.map((obj) => {
+ obj = expandObject(obj);
+ if (obj.rankDelta == 0 && obj.value == obj.valueDelta) {
+ obj.rankDelta = -10000000;
+ obj.valueDelta = 0;
+ }
+ dataSource.push(obj);
+ });
+ console.log(dataSource);
+
+ //搜索特定数据
+ let queryData;
+ if (search) {
+ queryData = dataSource.filter((dataSource) => {
+ let reg = new RegExp(search.trim(), 'i');
+ return reg.test(dataSource.name);
+ });
+ if (queryData.length == 0) {
+ message.warning(t('no_result'));
+ } else {
+ dataSource = queryData;
+ }
+ }
+
+ // 更新属性和表格数据
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ showDetail: showDetail,
+ hasDetail: hasDetail,
+ data: dataSource,
+ });
+ })
+ .catch((err) => {
+ console.log('hi!' + err);
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ data: [],
+ });
+ });
+
+
+ };
+ }
+ const {
+ object,
+ index,
+ region,
+ data,
+ columns,
+ loading,
+ showSize,
+ showDetail,
+ hasDetail,
+ month,
+ year,
+ type,
+ category,
+ } = state;
+ return (
+
+
+
+
+ record.rank}
+ dataSource={data.slice(0, Math.min(showSize, data.length))}
+ pagination={false}
+ loading={loading}
+ scroll={{ x: 'max-content' }}
+ />
+
+
+
+
+ {showSize < data.length ? (
+
+ {t('showMore') + '>>'}
+
+ ) : (
+
+ {t('noMore')}
+
+ )}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+}
+
+export default MyTable;
diff --git a/.history/src/components/table_20240728151214.js b/.history/src/components/table_20240728151214.js
new file mode 100644
index 0000000..08497b8
--- /dev/null
+++ b/.history/src/components/table_20240728151214.js
@@ -0,0 +1,650 @@
+import React, { useState, useEffect } from 'react';
+import { Col, message, Row, Table, Card } from 'antd';
+import MyAvatar from './avatar';
+import 'antd/dist/antd.css';
+import QAmiss from './QA2';
+import TablePanel from './TablePanel';
+import ArrowRender from './arrow';
+import PointRender from './changeNumber';
+import RoundFloat from './resolveFloat';
+import Trophy from './rankTrophy';
+import expandObject from '../util/expandObject';
+import { t } from 'i18next';
+import './table.css';
+import { foundationChineseData } from './data';
+
+const activityColumns = (object, t_month) => [
+ {
+ title: t('rank'),
+ dataIndex: 'rank',
+ width: '5%',
+ align: 'center',
+ render: Trophy,
+ fixed: 'left',
+ },
+ ...(object == 'actor'
+ ? [
+ {
+ title: t('avatar'),
+ dataIndex: 'id',
+ width: '5%',
+ align: 'center',
+ render: MyAvatar,
+ fixed: 'left',
+ },
+ ]
+ : []),
+ {
+ title: '',
+ dataIndex: 'rankDelta',
+ render: ArrowRender,
+ align: 'left',
+ width: '5%',
+ fixed: 'left',
+ },
+ {
+ title: t(object),
+ dataIndex: 'name',
+ align: 'center',
+ width: '20%',
+ render: function (text, row, index) {
+ if (object !== 'company') {
+ return (
+
+ {text}
+
+ );
+ } else {
+ return text;
+ }
+ },
+ },
+ ...(object == 'repo'
+ ? [
+ {
+ title: t('insight_board'),
+ dataIndex: 'name',
+ align: 'center',
+ width: '10%',
+ render: function (text, row, index) {
+ return dashboard(text, index, t_month);
+ },
+ },
+ ]
+ : []),
+ {
+ title: t('activity'),
+ dataIndex: 'value',
+ align: 'right',
+ width: '20%',
+ },
+ {
+ title: '',
+ dataIndex: 'valueDelta',
+ width: '10%',
+ align: 'left',
+ render: PointRender,
+ },
+];
+const activityDetailColumns = (object, t_month) => [
+ {
+ title: t('rank'),
+ dataIndex: 'rank',
+ width: '5%',
+ align: 'center',
+ render: Trophy,
+ fixed: 'left',
+ },
+ ...(object == 'actor'
+ ? [
+ {
+ title: t('avatar'),
+ dataIndex: 'id',
+ width: '5%',
+ align: 'center',
+ render: MyAvatar,
+ fixed: 'left',
+ },
+ ]
+ : []),
+ {
+ title: '',
+ dataIndex: 'rankDelta',
+ render: ArrowRender,
+ align: 'left',
+ width: '5%',
+ fixed: 'left',
+ },
+ {
+ title: t(object),
+ dataIndex: 'name',
+ align: 'center',
+ width: '5%',
+ render: function (text, row, index) {
+ if (object !== 'company') {
+ return (
+
+ {text}
+
+ );
+ } else {
+ return text;
+ }
+ },
+ },
+ ...(object == 'repo'
+ ? [
+ {
+ title: t('insight_board'),
+ dataIndex: 'name',
+ align: 'center',
+ width: '10%',
+ render: function (text, row, index) {
+ return dashboard(text, index, t_month);
+ },
+ },
+ ]
+ : []),
+ {
+ title: t('activity'),
+ dataIndex: 'value',
+ align: 'center',
+ width: '10%',
+ },
+ {
+ title: '',
+ dataIndex: 'valueDelta',
+ width: '10%',
+ align: 'left',
+ render: PointRender,
+ },
+ {
+ title: t('issue_comments'),
+ dataIndex: 'issue_comment',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('open_issues'),
+ dataIndex: 'open_issue',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('open_pulls'),
+ dataIndex: 'open_pull',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('merge_pulls'),
+ dataIndex: 'merged_pull',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('pr_reviews'),
+ dataIndex: 'review_comment',
+ width: '10%',
+ align: 'center',
+ },
+];
+const open_rankColumns = (object, t_month) => [
+ {
+ // 第一列:排名
+ title: t('rank'),
+ dataIndex: 'rank',
+ width: '5%',
+ render: Trophy,
+ align: 'center',
+ fixed: 'left',
+ },
+ // 如果 object 是 'actor',则添加头像列
+ ...(object == 'actor'
+ ? [
+ {
+ title: t('avatar'),
+ dataIndex: 'id',
+ width: '5%',
+ align: 'center',
+ render: MyAvatar,
+ fixed: 'left',
+ },
+ ]
+ : []),
+ // 第二列:排名变化
+ {
+ title: '',
+ dataIndex: 'rankDelta',
+ render: ArrowRender,
+ align: 'left',
+ width: '5%',
+ fixed: 'left',
+ },
+ // 第三列:对象名称(可能是 actor, repo 或 company)
+ {
+ title: t(object),
+ dataIndex: 'name',
+ width: '20%',
+ align: 'center',
+ render: function (text) {
+ if (object !== 'company') {
+ return (
+
+ {text}
+
+ );
+ } else {
+ return text;
+ }
+ },
+ },
+ // 如果 object 是 'repo',则添加 insight_board 列
+ ...(object == 'repo'
+ ? [
+ {
+ title: t('insight_board'),
+ dataIndex: 'name',
+ align: 'center',
+ width: '10%',
+ render: function (text, row, index) {
+ return dashboard(text, index, t_month);
+ },
+ },
+ ]
+ : []),
+ // 第四列:影响力
+ {
+ title: t('influence'),
+ dataIndex: 'value',
+ width: '20%',
+ align: 'right',
+ render: (text, row, index) => {
+ return RoundFloat(text);
+ },
+ },
+ // 第五列:影响力变化
+ {
+ title: '',
+ dataIndex: 'valueDelta',
+ width: '10%',
+ align: 'left',
+ render: (text, row, index) => {
+ text = RoundFloat(text);
+ return PointRender(text, row, index);
+ },
+ },
+];
+
+const solveDate = (year, month) => {
+ if (year === null && month === null) {
+ return 'not found';
+ }
+ if (month === null) {
+ return year + '年';
+ }
+ return year + '年' + (month + 1) + '月';
+};
+
+function dashboard(text, index, t_month) {
+ if (index < 300) {
+ let [org_name, repo_name] = text.split('/');
+ const t_month_copy = t_month + ' ' + '00:00:00';
+ let params = {
+ org_name,
+ repo_name,
+ t_month_copy,
+ t_month,
+ };
+ return (
+
+
+
+ );
+ }
+}
+
+function DateTitle(props) {
+ return {solveDate(props.year, props.month)}
;
+}
+
+function MyTable(props) {
+ const [state, setState] = useState({
+ object: 'technology',
+ index: 'open_rank',
+ region: 'global',
+ showDetail: false,
+ hasDetail: true,
+ data: [],
+ showSize: 25,
+ loading: true,
+ url: '', // base + index + object + region + yearmonth + .json
+ base: 'https://oss.x-lab.info/open_leaderboard/',
+ year: null, // 字符串格式
+ month: null, // 整数格式,0表示1月,1表示2月..., null for year type time
+ type: 'month',
+ search: null,
+ category: 'cloud-native',
+ });
+
+ // 请求一次数据更新表格。如果还没读取好配置文件则不请求数据。
+ useEffect(() => {
+ if (props.year == null && props.month == null) {
+ console.log('the first loading');
+ return;
+ }
+ updateDate({
+ year: String(props.year),
+ month: props.month,
+ });
+ }, [props]);
+
+ const expandData = () => {
+ setState({
+ ...state,
+ showSize: state.showSize + 25,
+ });
+ };
+ const updateDate = (newstate) => {
+ console.log('table update', newstate);
+ // 先获取原先的表格属性
+ let {
+ base,
+ object,
+ index,
+ region,
+ month,
+ year,
+ columns,
+ showDetail,
+ hasDetail,
+ type,
+ search,
+ category,
+ } = state;
+ // 然后把表格改为加载中的状态
+ setState({ ...state, ...newstate, loading: true });
+ // 如果 newstate 有对应的属性,则进行更新
+ if (newstate.hasOwnProperty('object')) object = newstate.object;
+ if (newstate.hasOwnProperty('index')) index = newstate.index;
+ if (newstate.hasOwnProperty('region')) region = newstate.region;
+ if (newstate.hasOwnProperty('month')) month = newstate.month;
+ if (newstate.hasOwnProperty('year')) year = newstate.year;
+ if (newstate.hasOwnProperty('showDetail')) showDetail = newstate.showDetail;
+ if (newstate.hasOwnProperty('type')) type = newstate.type;
+ if (newstate.hasOwnProperty('search')) search = newstate.search;
+ if (newstate.hasOwnProperty('category')) category = newstate.category;
+
+ //获取数据大屏的‘t_month’参数
+ let myyear = newstate.year == null ? state.year : newstate.year;
+ let mymonth = newstate.month == null ? state.month : newstate.month;
+
+ mymonth = ('' + (1 + mymonth)).padStart(2, '0');
+ let t_month = `${myyear}-${mymonth}-01`;
+
+ // 根据 index 和 showDetail 改变表格的 columns 格式
+ if (index == 'activity') {
+ columns = activityColumns(object, t_month);
+ hasDetail = true;
+ }
+ if (index == 'activity' && showDetail == true) {
+ columns = activityDetailColumns(object, t_month);
+ hasDetail = true;
+ }
+ if (index == 'open_rank') {
+ columns = open_rankColumns(object, t_month);
+ hasDetail = false;
+ showDetail = false;
+ }
+ // 如果是年份数据,则把 month 置为 null。
+ // TODO:待验证,如果从年份数据切换到月份数据,似乎会自动回到原来 month 值?
+ if (type == 'year') {
+ month = null;
+ }
+ // 以当前的属性构造请求 url
+ let url = base + index + '/' + object + '/' + region + '/';
+ if (month === null) {
+ url += year + '.json';
+ } else {
+ url += year + (1 + month) + '.json';
+ }
+ console.log(url);
+ console.log(region);
+ if (object == "foundation" && region == 'chinese') {
+
+ // 这里可以进行数据请求
+ fetch('../locales/foundationChinese.json')
+ .then((res) => {
+ // Todo:最好的情况是在日期选择器中,只显示可以查询的日期,
+ if (res.status == 404) {
+ message.warning(t('no_result'));
+ return '';
+ }
+ return res.json();
+ })
+ .then((data) => {
+ data = data.data;
+ let dataSource = [];
+ // 预处理数据,对新上榜单数据进行特殊标记处理
+ data.map((obj) => {
+ obj = expandObject(obj);
+ if (obj.rankDelta == 0 && obj.value == obj.valueDelta) {
+ obj.rankDelta = -10000000;
+ obj.valueDelta = 0;
+ }
+ dataSource.push(obj);
+ });
+ console.log(dataSource);
+
+ //搜索特定数据
+ let queryData;
+ if (search) {
+ queryData = dataSource.filter((dataSource) => {
+ let reg = new RegExp(search.trim(), 'i');
+ return reg.test(dataSource.name);
+ });
+ if (queryData.length == 0) {
+ message.warning(t('no_result'));
+ } else {
+ dataSource = queryData;
+ }
+ }
+
+ // 更新属性和表格数据
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ showDetail: showDetail,
+ hasDetail: hasDetail,
+ data: dataSource,
+ });
+ })
+ .catch((err) => {
+ console.log('hi!' + err);
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ data: [],
+ });
+ });
+
+ }
+ // fetch 异步请求
+ else{fetch(url)
+ .then((res) => {
+ // Todo:最好的情况是在日期选择器中,只显示可以查询的日期,
+ if (res.status == 404) {
+ message.warning(t('no_result'));
+ return '';
+ }
+ return res.json();
+ })
+ .then((data) => {
+ data = data.data;
+ let dataSource = [];
+ // 预处理数据,对新上榜单数据进行特殊标记处理
+ data.map((obj) => {
+ obj = expandObject(obj);
+ if (obj.rankDelta == 0 && obj.value == obj.valueDelta) {
+ obj.rankDelta = -10000000;
+ obj.valueDelta = 0;
+ }
+ dataSource.push(obj);
+ });
+ console.log(dataSource);
+
+ //搜索特定数据
+ let queryData;
+ if (search) {
+ queryData = dataSource.filter((dataSource) => {
+ let reg = new RegExp(search.trim(), 'i');
+ return reg.test(dataSource.name);
+ });
+ if (queryData.length == 0) {
+ message.warning(t('no_result'));
+ } else {
+ dataSource = queryData;
+ }
+ }
+
+ // 更新属性和表格数据
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ showDetail: showDetail,
+ hasDetail: hasDetail,
+ data: dataSource,
+ });
+ })
+ .catch((err) => {
+ console.log('hi!' + err);
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ data: [],
+ });
+ });
+
+
+ };
+ }
+ const {
+ object,
+ index,
+ region,
+ data,
+ columns,
+ loading,
+ showSize,
+ showDetail,
+ hasDetail,
+ month,
+ year,
+ type,
+ category,
+ } = state;
+ return (
+
+
+
+
+ record.rank}
+ dataSource={data.slice(0, Math.min(showSize, data.length))}
+ pagination={false}
+ loading={loading}
+ scroll={{ x: 'max-content' }}
+ />
+
+
+
+
+ {showSize < data.length ? (
+
+ {t('showMore') + '>>'}
+
+ ) : (
+
+ {t('noMore')}
+
+ )}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+}
+
+export default MyTable;
diff --git a/.history/src/components/table_20240728151323.js b/.history/src/components/table_20240728151323.js
new file mode 100644
index 0000000..9b4ad7d
--- /dev/null
+++ b/.history/src/components/table_20240728151323.js
@@ -0,0 +1,651 @@
+import React, { useState, useEffect } from 'react';
+import { Col, message, Row, Table, Card } from 'antd';
+import MyAvatar from './avatar';
+import 'antd/dist/antd.css';
+import QAmiss from './QA2';
+import TablePanel from './TablePanel';
+import ArrowRender from './arrow';
+import PointRender from './changeNumber';
+import RoundFloat from './resolveFloat';
+import Trophy from './rankTrophy';
+import expandObject from '../util/expandObject';
+import { t } from 'i18next';
+import './table.css';
+import { foundationChineseData } from './data';
+
+const activityColumns = (object, t_month) => [
+ {
+ title: t('rank'),
+ dataIndex: 'rank',
+ width: '5%',
+ align: 'center',
+ render: Trophy,
+ fixed: 'left',
+ },
+ ...(object == 'actor'
+ ? [
+ {
+ title: t('avatar'),
+ dataIndex: 'id',
+ width: '5%',
+ align: 'center',
+ render: MyAvatar,
+ fixed: 'left',
+ },
+ ]
+ : []),
+ {
+ title: '',
+ dataIndex: 'rankDelta',
+ render: ArrowRender,
+ align: 'left',
+ width: '5%',
+ fixed: 'left',
+ },
+ {
+ title: t(object),
+ dataIndex: 'name',
+ align: 'center',
+ width: '20%',
+ render: function (text, row, index) {
+ if (object !== 'company') {
+ return (
+
+ {text}
+
+ );
+ } else {
+ return text;
+ }
+ },
+ },
+ ...(object == 'repo'
+ ? [
+ {
+ title: t('insight_board'),
+ dataIndex: 'name',
+ align: 'center',
+ width: '10%',
+ render: function (text, row, index) {
+ return dashboard(text, index, t_month);
+ },
+ },
+ ]
+ : []),
+ {
+ title: t('activity'),
+ dataIndex: 'value',
+ align: 'right',
+ width: '20%',
+ },
+ {
+ title: '',
+ dataIndex: 'valueDelta',
+ width: '10%',
+ align: 'left',
+ render: PointRender,
+ },
+];
+const activityDetailColumns = (object, t_month) => [
+ {
+ title: t('rank'),
+ dataIndex: 'rank',
+ width: '5%',
+ align: 'center',
+ render: Trophy,
+ fixed: 'left',
+ },
+ ...(object == 'actor'
+ ? [
+ {
+ title: t('avatar'),
+ dataIndex: 'id',
+ width: '5%',
+ align: 'center',
+ render: MyAvatar,
+ fixed: 'left',
+ },
+ ]
+ : []),
+ {
+ title: '',
+ dataIndex: 'rankDelta',
+ render: ArrowRender,
+ align: 'left',
+ width: '5%',
+ fixed: 'left',
+ },
+ {
+ title: t(object),
+ dataIndex: 'name',
+ align: 'center',
+ width: '5%',
+ render: function (text, row, index) {
+ if (object !== 'company') {
+ return (
+
+ {text}
+
+ );
+ } else {
+ return text;
+ }
+ },
+ },
+ ...(object == 'repo'
+ ? [
+ {
+ title: t('insight_board'),
+ dataIndex: 'name',
+ align: 'center',
+ width: '10%',
+ render: function (text, row, index) {
+ return dashboard(text, index, t_month);
+ },
+ },
+ ]
+ : []),
+ {
+ title: t('activity'),
+ dataIndex: 'value',
+ align: 'center',
+ width: '10%',
+ },
+ {
+ title: '',
+ dataIndex: 'valueDelta',
+ width: '10%',
+ align: 'left',
+ render: PointRender,
+ },
+ {
+ title: t('issue_comments'),
+ dataIndex: 'issue_comment',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('open_issues'),
+ dataIndex: 'open_issue',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('open_pulls'),
+ dataIndex: 'open_pull',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('merge_pulls'),
+ dataIndex: 'merged_pull',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('pr_reviews'),
+ dataIndex: 'review_comment',
+ width: '10%',
+ align: 'center',
+ },
+];
+const open_rankColumns = (object, t_month) => [
+ {
+ // 第一列:排名
+ title: t('rank'),
+ dataIndex: 'rank',
+ width: '5%',
+ render: Trophy,
+ align: 'center',
+ fixed: 'left',
+ },
+ // 如果 object 是 'actor',则添加头像列
+ ...(object == 'actor'
+ ? [
+ {
+ title: t('avatar'),
+ dataIndex: 'id',
+ width: '5%',
+ align: 'center',
+ render: MyAvatar,
+ fixed: 'left',
+ },
+ ]
+ : []),
+ // 第二列:排名变化
+ {
+ title: '',
+ dataIndex: 'rankDelta',
+ render: ArrowRender,
+ align: 'left',
+ width: '5%',
+ fixed: 'left',
+ },
+ // 第三列:对象名称(可能是 actor, repo 或 company)
+ {
+ title: t(object),
+ dataIndex: 'name',
+ width: '20%',
+ align: 'center',
+ render: function (text) {
+ if (object !== 'company') {
+ return (
+
+ {text}
+
+ );
+ } else {
+ return text;
+ }
+ },
+ },
+ // 如果 object 是 'repo',则添加 insight_board 列
+ ...(object == 'repo'
+ ? [
+ {
+ title: t('insight_board'),
+ dataIndex: 'name',
+ align: 'center',
+ width: '10%',
+ render: function (text, row, index) {
+ return dashboard(text, index, t_month);
+ },
+ },
+ ]
+ : []),
+ // 第四列:影响力
+ {
+ title: t('influence'),
+ dataIndex: 'value',
+ width: '20%',
+ align: 'right',
+ render: (text, row, index) => {
+ return RoundFloat(text);
+ },
+ },
+ // 第五列:影响力变化
+ {
+ title: '',
+ dataIndex: 'valueDelta',
+ width: '10%',
+ align: 'left',
+ render: (text, row, index) => {
+ text = RoundFloat(text);
+ return PointRender(text, row, index);
+ },
+ },
+];
+
+const solveDate = (year, month) => {
+ if (year === null && month === null) {
+ return 'not found';
+ }
+ if (month === null) {
+ return year + '年';
+ }
+ return year + '年' + (month + 1) + '月';
+};
+
+function dashboard(text, index, t_month) {
+ if (index < 300) {
+ let [org_name, repo_name] = text.split('/');
+ const t_month_copy = t_month + ' ' + '00:00:00';
+ let params = {
+ org_name,
+ repo_name,
+ t_month_copy,
+ t_month,
+ };
+ return (
+
+
+
+ );
+ }
+}
+
+function DateTitle(props) {
+ return {solveDate(props.year, props.month)}
;
+}
+
+function MyTable(props) {
+ const [state, setState] = useState({
+ object: 'technology',
+ index: 'open_rank',
+ region: 'global',
+ showDetail: false,
+ hasDetail: true,
+ data: [],
+ showSize: 25,
+ loading: true,
+ url: '', // base + index + object + region + yearmonth + .json
+ base: 'https://oss.x-lab.info/open_leaderboard/',
+ year: null, // 字符串格式
+ month: null, // 整数格式,0表示1月,1表示2月..., null for year type time
+ type: 'month',
+ search: null,
+ category: 'cloud-native',
+ });
+
+ // 请求一次数据更新表格。如果还没读取好配置文件则不请求数据。
+ useEffect(() => {
+ if (props.year == null && props.month == null) {
+ console.log('the first loading');
+ return;
+ }
+ updateDate({
+ year: String(props.year),
+ month: props.month,
+ });
+ }, [props]);
+
+ const expandData = () => {
+ setState({
+ ...state,
+ showSize: state.showSize + 25,
+ });
+ };
+ const updateDate = (newstate) => {
+ console.log('table update', newstate);
+ // 先获取原先的表格属性
+ let {
+ base,
+ object,
+ index,
+ region,
+ month,
+ year,
+ columns,
+ showDetail,
+ hasDetail,
+ type,
+ search,
+ category,
+ } = state;
+ // 然后把表格改为加载中的状态
+ setState({ ...state, ...newstate, loading: true });
+ // 如果 newstate 有对应的属性,则进行更新
+ if (newstate.hasOwnProperty('object')) object = newstate.object;
+ if (newstate.hasOwnProperty('index')) index = newstate.index;
+ if (newstate.hasOwnProperty('region')) region = newstate.region;
+ if (newstate.hasOwnProperty('month')) month = newstate.month;
+ if (newstate.hasOwnProperty('year')) year = newstate.year;
+ if (newstate.hasOwnProperty('showDetail')) showDetail = newstate.showDetail;
+ if (newstate.hasOwnProperty('type')) type = newstate.type;
+ if (newstate.hasOwnProperty('search')) search = newstate.search;
+ if (newstate.hasOwnProperty('category')) category = newstate.category;
+
+ //获取数据大屏的‘t_month’参数
+ let myyear = newstate.year == null ? state.year : newstate.year;
+ let mymonth = newstate.month == null ? state.month : newstate.month;
+
+ mymonth = ('' + (1 + mymonth)).padStart(2, '0');
+ let t_month = `${myyear}-${mymonth}-01`;
+
+ // 根据 index 和 showDetail 改变表格的 columns 格式
+ if (index == 'activity') {
+ columns = activityColumns(object, t_month);
+ hasDetail = true;
+ }
+ if (index == 'activity' && showDetail == true) {
+ columns = activityDetailColumns(object, t_month);
+ hasDetail = true;
+ }
+ if (index == 'open_rank') {
+ columns = open_rankColumns(object, t_month);
+ hasDetail = false;
+ showDetail = false;
+ }
+ // 如果是年份数据,则把 month 置为 null。
+ // TODO:待验证,如果从年份数据切换到月份数据,似乎会自动回到原来 month 值?
+ if (type == 'year') {
+ month = null;
+ }
+ // 以当前的属性构造请求 url
+ let url = base + index + '/' + object + '/' + region + '/';
+ if (month === null) {
+ url += year + '.json';
+ } else {
+ url += year + (1 + month) + '.json';
+ }
+ console.log(url);
+ console.log(region);
+ if (object == "foundation" && region == 'chinese') {
+
+ // 这里可以进行数据请求
+ fetch('../locales/foundationChinese.json')
+ .then((res) => {
+ console.log(res);
+ // Todo:最好的情况是在日期选择器中,只显示可以查询的日期,
+ if (res.status == 404) {
+ message.warning(t('no_result'));
+ return '';
+ }
+ return res.json();
+ })
+ .then((data) => {
+ data = data.data;
+ let dataSource = [];
+ // 预处理数据,对新上榜单数据进行特殊标记处理
+ data.map((obj) => {
+ obj = expandObject(obj);
+ if (obj.rankDelta == 0 && obj.value == obj.valueDelta) {
+ obj.rankDelta = -10000000;
+ obj.valueDelta = 0;
+ }
+ dataSource.push(obj);
+ });
+ console.log(dataSource);
+
+ //搜索特定数据
+ let queryData;
+ if (search) {
+ queryData = dataSource.filter((dataSource) => {
+ let reg = new RegExp(search.trim(), 'i');
+ return reg.test(dataSource.name);
+ });
+ if (queryData.length == 0) {
+ message.warning(t('no_result'));
+ } else {
+ dataSource = queryData;
+ }
+ }
+
+ // 更新属性和表格数据
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ showDetail: showDetail,
+ hasDetail: hasDetail,
+ data: dataSource,
+ });
+ })
+ .catch((err) => {
+ console.log('hi!' + err);
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ data: [],
+ });
+ });
+
+ }
+ // fetch 异步请求
+ else{fetch(url)
+ .then((res) => {
+ // Todo:最好的情况是在日期选择器中,只显示可以查询的日期,
+ if (res.status == 404) {
+ message.warning(t('no_result'));
+ return '';
+ }
+ return res.json();
+ })
+ .then((data) => {
+ data = data.data;
+ let dataSource = [];
+ // 预处理数据,对新上榜单数据进行特殊标记处理
+ data.map((obj) => {
+ obj = expandObject(obj);
+ if (obj.rankDelta == 0 && obj.value == obj.valueDelta) {
+ obj.rankDelta = -10000000;
+ obj.valueDelta = 0;
+ }
+ dataSource.push(obj);
+ });
+ console.log(dataSource);
+
+ //搜索特定数据
+ let queryData;
+ if (search) {
+ queryData = dataSource.filter((dataSource) => {
+ let reg = new RegExp(search.trim(), 'i');
+ return reg.test(dataSource.name);
+ });
+ if (queryData.length == 0) {
+ message.warning(t('no_result'));
+ } else {
+ dataSource = queryData;
+ }
+ }
+
+ // 更新属性和表格数据
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ showDetail: showDetail,
+ hasDetail: hasDetail,
+ data: dataSource,
+ });
+ })
+ .catch((err) => {
+ console.log('hi!' + err);
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ data: [],
+ });
+ });
+
+
+ };
+ }
+ const {
+ object,
+ index,
+ region,
+ data,
+ columns,
+ loading,
+ showSize,
+ showDetail,
+ hasDetail,
+ month,
+ year,
+ type,
+ category,
+ } = state;
+ return (
+
+
+
+
+ record.rank}
+ dataSource={data.slice(0, Math.min(showSize, data.length))}
+ pagination={false}
+ loading={loading}
+ scroll={{ x: 'max-content' }}
+ />
+
+
+
+
+ {showSize < data.length ? (
+
+ {t('showMore') + '>>'}
+
+ ) : (
+
+ {t('noMore')}
+
+ )}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+}
+
+export default MyTable;
diff --git a/.history/src/components/table_20240728151410.js b/.history/src/components/table_20240728151410.js
new file mode 100644
index 0000000..2e5f393
--- /dev/null
+++ b/.history/src/components/table_20240728151410.js
@@ -0,0 +1,651 @@
+import React, { useState, useEffect } from 'react';
+import { Col, message, Row, Table, Card } from 'antd';
+import MyAvatar from './avatar';
+import 'antd/dist/antd.css';
+import QAmiss from './QA2';
+import TablePanel from './TablePanel';
+import ArrowRender from './arrow';
+import PointRender from './changeNumber';
+import RoundFloat from './resolveFloat';
+import Trophy from './rankTrophy';
+import expandObject from '../util/expandObject';
+import { t } from 'i18next';
+import './table.css';
+import { foundationChineseData } from './data';
+
+const activityColumns = (object, t_month) => [
+ {
+ title: t('rank'),
+ dataIndex: 'rank',
+ width: '5%',
+ align: 'center',
+ render: Trophy,
+ fixed: 'left',
+ },
+ ...(object == 'actor'
+ ? [
+ {
+ title: t('avatar'),
+ dataIndex: 'id',
+ width: '5%',
+ align: 'center',
+ render: MyAvatar,
+ fixed: 'left',
+ },
+ ]
+ : []),
+ {
+ title: '',
+ dataIndex: 'rankDelta',
+ render: ArrowRender,
+ align: 'left',
+ width: '5%',
+ fixed: 'left',
+ },
+ {
+ title: t(object),
+ dataIndex: 'name',
+ align: 'center',
+ width: '20%',
+ render: function (text, row, index) {
+ if (object !== 'company') {
+ return (
+
+ {text}
+
+ );
+ } else {
+ return text;
+ }
+ },
+ },
+ ...(object == 'repo'
+ ? [
+ {
+ title: t('insight_board'),
+ dataIndex: 'name',
+ align: 'center',
+ width: '10%',
+ render: function (text, row, index) {
+ return dashboard(text, index, t_month);
+ },
+ },
+ ]
+ : []),
+ {
+ title: t('activity'),
+ dataIndex: 'value',
+ align: 'right',
+ width: '20%',
+ },
+ {
+ title: '',
+ dataIndex: 'valueDelta',
+ width: '10%',
+ align: 'left',
+ render: PointRender,
+ },
+];
+const activityDetailColumns = (object, t_month) => [
+ {
+ title: t('rank'),
+ dataIndex: 'rank',
+ width: '5%',
+ align: 'center',
+ render: Trophy,
+ fixed: 'left',
+ },
+ ...(object == 'actor'
+ ? [
+ {
+ title: t('avatar'),
+ dataIndex: 'id',
+ width: '5%',
+ align: 'center',
+ render: MyAvatar,
+ fixed: 'left',
+ },
+ ]
+ : []),
+ {
+ title: '',
+ dataIndex: 'rankDelta',
+ render: ArrowRender,
+ align: 'left',
+ width: '5%',
+ fixed: 'left',
+ },
+ {
+ title: t(object),
+ dataIndex: 'name',
+ align: 'center',
+ width: '5%',
+ render: function (text, row, index) {
+ if (object !== 'company') {
+ return (
+
+ {text}
+
+ );
+ } else {
+ return text;
+ }
+ },
+ },
+ ...(object == 'repo'
+ ? [
+ {
+ title: t('insight_board'),
+ dataIndex: 'name',
+ align: 'center',
+ width: '10%',
+ render: function (text, row, index) {
+ return dashboard(text, index, t_month);
+ },
+ },
+ ]
+ : []),
+ {
+ title: t('activity'),
+ dataIndex: 'value',
+ align: 'center',
+ width: '10%',
+ },
+ {
+ title: '',
+ dataIndex: 'valueDelta',
+ width: '10%',
+ align: 'left',
+ render: PointRender,
+ },
+ {
+ title: t('issue_comments'),
+ dataIndex: 'issue_comment',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('open_issues'),
+ dataIndex: 'open_issue',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('open_pulls'),
+ dataIndex: 'open_pull',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('merge_pulls'),
+ dataIndex: 'merged_pull',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('pr_reviews'),
+ dataIndex: 'review_comment',
+ width: '10%',
+ align: 'center',
+ },
+];
+const open_rankColumns = (object, t_month) => [
+ {
+ // 第一列:排名
+ title: t('rank'),
+ dataIndex: 'rank',
+ width: '5%',
+ render: Trophy,
+ align: 'center',
+ fixed: 'left',
+ },
+ // 如果 object 是 'actor',则添加头像列
+ ...(object == 'actor'
+ ? [
+ {
+ title: t('avatar'),
+ dataIndex: 'id',
+ width: '5%',
+ align: 'center',
+ render: MyAvatar,
+ fixed: 'left',
+ },
+ ]
+ : []),
+ // 第二列:排名变化
+ {
+ title: '',
+ dataIndex: 'rankDelta',
+ render: ArrowRender,
+ align: 'left',
+ width: '5%',
+ fixed: 'left',
+ },
+ // 第三列:对象名称(可能是 actor, repo 或 company)
+ {
+ title: t(object),
+ dataIndex: 'name',
+ width: '20%',
+ align: 'center',
+ render: function (text) {
+ if (object !== 'company') {
+ return (
+
+ {text}
+
+ );
+ } else {
+ return text;
+ }
+ },
+ },
+ // 如果 object 是 'repo',则添加 insight_board 列
+ ...(object == 'repo'
+ ? [
+ {
+ title: t('insight_board'),
+ dataIndex: 'name',
+ align: 'center',
+ width: '10%',
+ render: function (text, row, index) {
+ return dashboard(text, index, t_month);
+ },
+ },
+ ]
+ : []),
+ // 第四列:影响力
+ {
+ title: t('influence'),
+ dataIndex: 'value',
+ width: '20%',
+ align: 'right',
+ render: (text, row, index) => {
+ return RoundFloat(text);
+ },
+ },
+ // 第五列:影响力变化
+ {
+ title: '',
+ dataIndex: 'valueDelta',
+ width: '10%',
+ align: 'left',
+ render: (text, row, index) => {
+ text = RoundFloat(text);
+ return PointRender(text, row, index);
+ },
+ },
+];
+
+const solveDate = (year, month) => {
+ if (year === null && month === null) {
+ return 'not found';
+ }
+ if (month === null) {
+ return year + '年';
+ }
+ return year + '年' + (month + 1) + '月';
+};
+
+function dashboard(text, index, t_month) {
+ if (index < 300) {
+ let [org_name, repo_name] = text.split('/');
+ const t_month_copy = t_month + ' ' + '00:00:00';
+ let params = {
+ org_name,
+ repo_name,
+ t_month_copy,
+ t_month,
+ };
+ return (
+
+
+
+ );
+ }
+}
+
+function DateTitle(props) {
+ return {solveDate(props.year, props.month)}
;
+}
+
+function MyTable(props) {
+ const [state, setState] = useState({
+ object: 'technology',
+ index: 'open_rank',
+ region: 'global',
+ showDetail: false,
+ hasDetail: true,
+ data: [],
+ showSize: 25,
+ loading: true,
+ url: '', // base + index + object + region + yearmonth + .json
+ base: 'https://oss.x-lab.info/open_leaderboard/',
+ year: null, // 字符串格式
+ month: null, // 整数格式,0表示1月,1表示2月..., null for year type time
+ type: 'month',
+ search: null,
+ category: 'cloud-native',
+ });
+
+ // 请求一次数据更新表格。如果还没读取好配置文件则不请求数据。
+ useEffect(() => {
+ if (props.year == null && props.month == null) {
+ console.log('the first loading');
+ return;
+ }
+ updateDate({
+ year: String(props.year),
+ month: props.month,
+ });
+ }, [props]);
+
+ const expandData = () => {
+ setState({
+ ...state,
+ showSize: state.showSize + 25,
+ });
+ };
+ const updateDate = (newstate) => {
+ console.log('table update', newstate);
+ // 先获取原先的表格属性
+ let {
+ base,
+ object,
+ index,
+ region,
+ month,
+ year,
+ columns,
+ showDetail,
+ hasDetail,
+ type,
+ search,
+ category,
+ } = state;
+ // 然后把表格改为加载中的状态
+ setState({ ...state, ...newstate, loading: true });
+ // 如果 newstate 有对应的属性,则进行更新
+ if (newstate.hasOwnProperty('object')) object = newstate.object;
+ if (newstate.hasOwnProperty('index')) index = newstate.index;
+ if (newstate.hasOwnProperty('region')) region = newstate.region;
+ if (newstate.hasOwnProperty('month')) month = newstate.month;
+ if (newstate.hasOwnProperty('year')) year = newstate.year;
+ if (newstate.hasOwnProperty('showDetail')) showDetail = newstate.showDetail;
+ if (newstate.hasOwnProperty('type')) type = newstate.type;
+ if (newstate.hasOwnProperty('search')) search = newstate.search;
+ if (newstate.hasOwnProperty('category')) category = newstate.category;
+
+ //获取数据大屏的‘t_month’参数
+ let myyear = newstate.year == null ? state.year : newstate.year;
+ let mymonth = newstate.month == null ? state.month : newstate.month;
+
+ mymonth = ('' + (1 + mymonth)).padStart(2, '0');
+ let t_month = `${myyear}-${mymonth}-01`;
+
+ // 根据 index 和 showDetail 改变表格的 columns 格式
+ if (index == 'activity') {
+ columns = activityColumns(object, t_month);
+ hasDetail = true;
+ }
+ if (index == 'activity' && showDetail == true) {
+ columns = activityDetailColumns(object, t_month);
+ hasDetail = true;
+ }
+ if (index == 'open_rank') {
+ columns = open_rankColumns(object, t_month);
+ hasDetail = false;
+ showDetail = false;
+ }
+ // 如果是年份数据,则把 month 置为 null。
+ // TODO:待验证,如果从年份数据切换到月份数据,似乎会自动回到原来 month 值?
+ if (type == 'year') {
+ month = null;
+ }
+ // 以当前的属性构造请求 url
+ let url = base + index + '/' + object + '/' + region + '/';
+ if (month === null) {
+ url += year + '.json';
+ } else {
+ url += year + (1 + month) + '.json';
+ }
+ console.log(url);
+ console.log(region);
+ if (object == "foundation" && region == 'chinese') {
+
+ // 这里可以进行数据请求
+ fetch('../locales/foundationChinese.json')
+ .then((res) => {
+ console.log(res.json);
+ // Todo:最好的情况是在日期选择器中,只显示可以查询的日期,
+ if (res.status == 404) {
+ message.warning(t('no_result'));
+ return '';
+ }
+ return res.json();
+ })
+ .then((data) => {
+ data = data.data;
+ let dataSource = [];
+ // 预处理数据,对新上榜单数据进行特殊标记处理
+ data.map((obj) => {
+ obj = expandObject(obj);
+ if (obj.rankDelta == 0 && obj.value == obj.valueDelta) {
+ obj.rankDelta = -10000000;
+ obj.valueDelta = 0;
+ }
+ dataSource.push(obj);
+ });
+ console.log(dataSource);
+
+ //搜索特定数据
+ let queryData;
+ if (search) {
+ queryData = dataSource.filter((dataSource) => {
+ let reg = new RegExp(search.trim(), 'i');
+ return reg.test(dataSource.name);
+ });
+ if (queryData.length == 0) {
+ message.warning(t('no_result'));
+ } else {
+ dataSource = queryData;
+ }
+ }
+
+ // 更新属性和表格数据
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ showDetail: showDetail,
+ hasDetail: hasDetail,
+ data: dataSource,
+ });
+ })
+ .catch((err) => {
+ console.log('hi!' + err);
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ data: [],
+ });
+ });
+
+ }
+ // fetch 异步请求
+ else{fetch(url)
+ .then((res) => {
+ // Todo:最好的情况是在日期选择器中,只显示可以查询的日期,
+ if (res.status == 404) {
+ message.warning(t('no_result'));
+ return '';
+ }
+ return res.json();
+ })
+ .then((data) => {
+ data = data.data;
+ let dataSource = [];
+ // 预处理数据,对新上榜单数据进行特殊标记处理
+ data.map((obj) => {
+ obj = expandObject(obj);
+ if (obj.rankDelta == 0 && obj.value == obj.valueDelta) {
+ obj.rankDelta = -10000000;
+ obj.valueDelta = 0;
+ }
+ dataSource.push(obj);
+ });
+ console.log(dataSource);
+
+ //搜索特定数据
+ let queryData;
+ if (search) {
+ queryData = dataSource.filter((dataSource) => {
+ let reg = new RegExp(search.trim(), 'i');
+ return reg.test(dataSource.name);
+ });
+ if (queryData.length == 0) {
+ message.warning(t('no_result'));
+ } else {
+ dataSource = queryData;
+ }
+ }
+
+ // 更新属性和表格数据
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ showDetail: showDetail,
+ hasDetail: hasDetail,
+ data: dataSource,
+ });
+ })
+ .catch((err) => {
+ console.log('hi!' + err);
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ data: [],
+ });
+ });
+
+
+ };
+ }
+ const {
+ object,
+ index,
+ region,
+ data,
+ columns,
+ loading,
+ showSize,
+ showDetail,
+ hasDetail,
+ month,
+ year,
+ type,
+ category,
+ } = state;
+ return (
+
+
+
+
+ record.rank}
+ dataSource={data.slice(0, Math.min(showSize, data.length))}
+ pagination={false}
+ loading={loading}
+ scroll={{ x: 'max-content' }}
+ />
+
+
+
+
+ {showSize < data.length ? (
+
+ {t('showMore') + '>>'}
+
+ ) : (
+
+ {t('noMore')}
+
+ )}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+}
+
+export default MyTable;
diff --git a/.history/src/components/table_20240728151537.js b/.history/src/components/table_20240728151537.js
new file mode 100644
index 0000000..ddbedfb
--- /dev/null
+++ b/.history/src/components/table_20240728151537.js
@@ -0,0 +1,645 @@
+import React, { useState, useEffect } from 'react';
+import { Col, message, Row, Table, Card } from 'antd';
+import MyAvatar from './avatar';
+import 'antd/dist/antd.css';
+import QAmiss from './QA2';
+import TablePanel from './TablePanel';
+import ArrowRender from './arrow';
+import PointRender from './changeNumber';
+import RoundFloat from './resolveFloat';
+import Trophy from './rankTrophy';
+import expandObject from '../util/expandObject';
+import { t } from 'i18next';
+import './table.css';
+import { foundationChineseData } from './data';
+
+const activityColumns = (object, t_month) => [
+ {
+ title: t('rank'),
+ dataIndex: 'rank',
+ width: '5%',
+ align: 'center',
+ render: Trophy,
+ fixed: 'left',
+ },
+ ...(object == 'actor'
+ ? [
+ {
+ title: t('avatar'),
+ dataIndex: 'id',
+ width: '5%',
+ align: 'center',
+ render: MyAvatar,
+ fixed: 'left',
+ },
+ ]
+ : []),
+ {
+ title: '',
+ dataIndex: 'rankDelta',
+ render: ArrowRender,
+ align: 'left',
+ width: '5%',
+ fixed: 'left',
+ },
+ {
+ title: t(object),
+ dataIndex: 'name',
+ align: 'center',
+ width: '20%',
+ render: function (text, row, index) {
+ if (object !== 'company') {
+ return (
+
+ {text}
+
+ );
+ } else {
+ return text;
+ }
+ },
+ },
+ ...(object == 'repo'
+ ? [
+ {
+ title: t('insight_board'),
+ dataIndex: 'name',
+ align: 'center',
+ width: '10%',
+ render: function (text, row, index) {
+ return dashboard(text, index, t_month);
+ },
+ },
+ ]
+ : []),
+ {
+ title: t('activity'),
+ dataIndex: 'value',
+ align: 'right',
+ width: '20%',
+ },
+ {
+ title: '',
+ dataIndex: 'valueDelta',
+ width: '10%',
+ align: 'left',
+ render: PointRender,
+ },
+];
+const activityDetailColumns = (object, t_month) => [
+ {
+ title: t('rank'),
+ dataIndex: 'rank',
+ width: '5%',
+ align: 'center',
+ render: Trophy,
+ fixed: 'left',
+ },
+ ...(object == 'actor'
+ ? [
+ {
+ title: t('avatar'),
+ dataIndex: 'id',
+ width: '5%',
+ align: 'center',
+ render: MyAvatar,
+ fixed: 'left',
+ },
+ ]
+ : []),
+ {
+ title: '',
+ dataIndex: 'rankDelta',
+ render: ArrowRender,
+ align: 'left',
+ width: '5%',
+ fixed: 'left',
+ },
+ {
+ title: t(object),
+ dataIndex: 'name',
+ align: 'center',
+ width: '5%',
+ render: function (text, row, index) {
+ if (object !== 'company') {
+ return (
+
+ {text}
+
+ );
+ } else {
+ return text;
+ }
+ },
+ },
+ ...(object == 'repo'
+ ? [
+ {
+ title: t('insight_board'),
+ dataIndex: 'name',
+ align: 'center',
+ width: '10%',
+ render: function (text, row, index) {
+ return dashboard(text, index, t_month);
+ },
+ },
+ ]
+ : []),
+ {
+ title: t('activity'),
+ dataIndex: 'value',
+ align: 'center',
+ width: '10%',
+ },
+ {
+ title: '',
+ dataIndex: 'valueDelta',
+ width: '10%',
+ align: 'left',
+ render: PointRender,
+ },
+ {
+ title: t('issue_comments'),
+ dataIndex: 'issue_comment',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('open_issues'),
+ dataIndex: 'open_issue',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('open_pulls'),
+ dataIndex: 'open_pull',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('merge_pulls'),
+ dataIndex: 'merged_pull',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('pr_reviews'),
+ dataIndex: 'review_comment',
+ width: '10%',
+ align: 'center',
+ },
+];
+const open_rankColumns = (object, t_month) => [
+ {
+ // 第一列:排名
+ title: t('rank'),
+ dataIndex: 'rank',
+ width: '5%',
+ render: Trophy,
+ align: 'center',
+ fixed: 'left',
+ },
+ // 如果 object 是 'actor',则添加头像列
+ ...(object == 'actor'
+ ? [
+ {
+ title: t('avatar'),
+ dataIndex: 'id',
+ width: '5%',
+ align: 'center',
+ render: MyAvatar,
+ fixed: 'left',
+ },
+ ]
+ : []),
+ // 第二列:排名变化
+ {
+ title: '',
+ dataIndex: 'rankDelta',
+ render: ArrowRender,
+ align: 'left',
+ width: '5%',
+ fixed: 'left',
+ },
+ // 第三列:对象名称(可能是 actor, repo 或 company)
+ {
+ title: t(object),
+ dataIndex: 'name',
+ width: '20%',
+ align: 'center',
+ render: function (text) {
+ if (object !== 'company') {
+ return (
+
+ {text}
+
+ );
+ } else {
+ return text;
+ }
+ },
+ },
+ // 如果 object 是 'repo',则添加 insight_board 列
+ ...(object == 'repo'
+ ? [
+ {
+ title: t('insight_board'),
+ dataIndex: 'name',
+ align: 'center',
+ width: '10%',
+ render: function (text, row, index) {
+ return dashboard(text, index, t_month);
+ },
+ },
+ ]
+ : []),
+ // 第四列:影响力
+ {
+ title: t('influence'),
+ dataIndex: 'value',
+ width: '20%',
+ align: 'right',
+ render: (text, row, index) => {
+ return RoundFloat(text);
+ },
+ },
+ // 第五列:影响力变化
+ {
+ title: '',
+ dataIndex: 'valueDelta',
+ width: '10%',
+ align: 'left',
+ render: (text, row, index) => {
+ text = RoundFloat(text);
+ return PointRender(text, row, index);
+ },
+ },
+];
+
+const solveDate = (year, month) => {
+ if (year === null && month === null) {
+ return 'not found';
+ }
+ if (month === null) {
+ return year + '年';
+ }
+ return year + '年' + (month + 1) + '月';
+};
+
+function dashboard(text, index, t_month) {
+ if (index < 300) {
+ let [org_name, repo_name] = text.split('/');
+ const t_month_copy = t_month + ' ' + '00:00:00';
+ let params = {
+ org_name,
+ repo_name,
+ t_month_copy,
+ t_month,
+ };
+ return (
+
+
+
+ );
+ }
+}
+
+function DateTitle(props) {
+ return {solveDate(props.year, props.month)}
;
+}
+
+function MyTable(props) {
+ const [state, setState] = useState({
+ object: 'technology',
+ index: 'open_rank',
+ region: 'global',
+ showDetail: false,
+ hasDetail: true,
+ data: [],
+ showSize: 25,
+ loading: true,
+ url: '', // base + index + object + region + yearmonth + .json
+ base: 'https://oss.x-lab.info/open_leaderboard/',
+ year: null, // 字符串格式
+ month: null, // 整数格式,0表示1月,1表示2月..., null for year type time
+ type: 'month',
+ search: null,
+ category: 'cloud-native',
+ });
+
+ // 请求一次数据更新表格。如果还没读取好配置文件则不请求数据。
+ useEffect(() => {
+ if (props.year == null && props.month == null) {
+ console.log('the first loading');
+ return;
+ }
+ updateDate({
+ year: String(props.year),
+ month: props.month,
+ });
+ }, [props]);
+
+ const expandData = () => {
+ setState({
+ ...state,
+ showSize: state.showSize + 25,
+ });
+ };
+ const updateDate = (newstate) => {
+ console.log('table update', newstate);
+ // 先获取原先的表格属性
+ let {
+ base,
+ object,
+ index,
+ region,
+ month,
+ year,
+ columns,
+ showDetail,
+ hasDetail,
+ type,
+ search,
+ category,
+ } = state;
+ // 然后把表格改为加载中的状态
+ setState({ ...state, ...newstate, loading: true });
+ // 如果 newstate 有对应的属性,则进行更新
+ if (newstate.hasOwnProperty('object')) object = newstate.object;
+ if (newstate.hasOwnProperty('index')) index = newstate.index;
+ if (newstate.hasOwnProperty('region')) region = newstate.region;
+ if (newstate.hasOwnProperty('month')) month = newstate.month;
+ if (newstate.hasOwnProperty('year')) year = newstate.year;
+ if (newstate.hasOwnProperty('showDetail')) showDetail = newstate.showDetail;
+ if (newstate.hasOwnProperty('type')) type = newstate.type;
+ if (newstate.hasOwnProperty('search')) search = newstate.search;
+ if (newstate.hasOwnProperty('category')) category = newstate.category;
+
+ //获取数据大屏的‘t_month’参数
+ let myyear = newstate.year == null ? state.year : newstate.year;
+ let mymonth = newstate.month == null ? state.month : newstate.month;
+
+ mymonth = ('' + (1 + mymonth)).padStart(2, '0');
+ let t_month = `${myyear}-${mymonth}-01`;
+
+ // 根据 index 和 showDetail 改变表格的 columns 格式
+ if (index == 'activity') {
+ columns = activityColumns(object, t_month);
+ hasDetail = true;
+ }
+ if (index == 'activity' && showDetail == true) {
+ columns = activityDetailColumns(object, t_month);
+ hasDetail = true;
+ }
+ if (index == 'open_rank') {
+ columns = open_rankColumns(object, t_month);
+ hasDetail = false;
+ showDetail = false;
+ }
+ // 如果是年份数据,则把 month 置为 null。
+ // TODO:待验证,如果从年份数据切换到月份数据,似乎会自动回到原来 month 值?
+ if (type == 'year') {
+ month = null;
+ }
+ // 以当前的属性构造请求 url
+ let url = base + index + '/' + object + '/' + region + '/';
+ if (month === null) {
+ url += year + '.json';
+ } else {
+ url += year + (1 + month) + '.json';
+ }
+ console.log(url);
+ console.log(region);
+ if (object == "foundation" && region == 'chinese') {
+
+ // 这里可以进行数据请求
+ fetch('../locales/foundationChinese.json')
+ .then(response => {response.json()
+ console.log(response.json);
+ })
+ .then((data) => {
+ data = data.data;
+ let dataSource = [];
+ // 预处理数据,对新上榜单数据进行特殊标记处理
+ data.map((obj) => {
+ obj = expandObject(obj);
+ if (obj.rankDelta == 0 && obj.value == obj.valueDelta) {
+ obj.rankDelta = -10000000;
+ obj.valueDelta = 0;
+ }
+ dataSource.push(obj);
+ });
+ console.log(dataSource);
+
+ //搜索特定数据
+ let queryData;
+ if (search) {
+ queryData = dataSource.filter((dataSource) => {
+ let reg = new RegExp(search.trim(), 'i');
+ return reg.test(dataSource.name);
+ });
+ if (queryData.length == 0) {
+ message.warning(t('no_result'));
+ } else {
+ dataSource = queryData;
+ }
+ }
+
+ // 更新属性和表格数据
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ showDetail: showDetail,
+ hasDetail: hasDetail,
+ data: dataSource,
+ });
+ })
+ .catch((err) => {
+ console.log('hi!' + err);
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ data: [],
+ });
+ });
+
+ }
+ // fetch 异步请求
+ else{fetch(url)
+ .then((res) => {
+ // Todo:最好的情况是在日期选择器中,只显示可以查询的日期,
+ if (res.status == 404) {
+ message.warning(t('no_result'));
+ return '';
+ }
+ return res.json();
+ })
+ .then((data) => {
+ data = data.data;
+ let dataSource = [];
+ // 预处理数据,对新上榜单数据进行特殊标记处理
+ data.map((obj) => {
+ obj = expandObject(obj);
+ if (obj.rankDelta == 0 && obj.value == obj.valueDelta) {
+ obj.rankDelta = -10000000;
+ obj.valueDelta = 0;
+ }
+ dataSource.push(obj);
+ });
+ console.log(dataSource);
+
+ //搜索特定数据
+ let queryData;
+ if (search) {
+ queryData = dataSource.filter((dataSource) => {
+ let reg = new RegExp(search.trim(), 'i');
+ return reg.test(dataSource.name);
+ });
+ if (queryData.length == 0) {
+ message.warning(t('no_result'));
+ } else {
+ dataSource = queryData;
+ }
+ }
+
+ // 更新属性和表格数据
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ showDetail: showDetail,
+ hasDetail: hasDetail,
+ data: dataSource,
+ });
+ })
+ .catch((err) => {
+ console.log('hi!' + err);
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ data: [],
+ });
+ });
+
+
+ };
+ }
+ const {
+ object,
+ index,
+ region,
+ data,
+ columns,
+ loading,
+ showSize,
+ showDetail,
+ hasDetail,
+ month,
+ year,
+ type,
+ category,
+ } = state;
+ return (
+
+
+
+
+ record.rank}
+ dataSource={data.slice(0, Math.min(showSize, data.length))}
+ pagination={false}
+ loading={loading}
+ scroll={{ x: 'max-content' }}
+ />
+
+
+
+
+ {showSize < data.length ? (
+
+ {t('showMore') + '>>'}
+
+ ) : (
+
+ {t('noMore')}
+
+ )}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+}
+
+export default MyTable;
diff --git a/.history/src/components/table_20240728152336.js b/.history/src/components/table_20240728152336.js
new file mode 100644
index 0000000..7e65223
--- /dev/null
+++ b/.history/src/components/table_20240728152336.js
@@ -0,0 +1,645 @@
+import React, { useState, useEffect } from 'react';
+import { Col, message, Row, Table, Card } from 'antd';
+import MyAvatar from './avatar';
+import 'antd/dist/antd.css';
+import QAmiss from './QA2';
+import TablePanel from './TablePanel';
+import ArrowRender from './arrow';
+import PointRender from './changeNumber';
+import RoundFloat from './resolveFloat';
+import Trophy from './rankTrophy';
+import expandObject from '../util/expandObject';
+import { t } from 'i18next';
+import './table.css';
+import { foundationChineseData } from './data';
+
+const activityColumns = (object, t_month) => [
+ {
+ title: t('rank'),
+ dataIndex: 'rank',
+ width: '5%',
+ align: 'center',
+ render: Trophy,
+ fixed: 'left',
+ },
+ ...(object == 'actor'
+ ? [
+ {
+ title: t('avatar'),
+ dataIndex: 'id',
+ width: '5%',
+ align: 'center',
+ render: MyAvatar,
+ fixed: 'left',
+ },
+ ]
+ : []),
+ {
+ title: '',
+ dataIndex: 'rankDelta',
+ render: ArrowRender,
+ align: 'left',
+ width: '5%',
+ fixed: 'left',
+ },
+ {
+ title: t(object),
+ dataIndex: 'name',
+ align: 'center',
+ width: '20%',
+ render: function (text, row, index) {
+ if (object !== 'company') {
+ return (
+
+ {text}
+
+ );
+ } else {
+ return text;
+ }
+ },
+ },
+ ...(object == 'repo'
+ ? [
+ {
+ title: t('insight_board'),
+ dataIndex: 'name',
+ align: 'center',
+ width: '10%',
+ render: function (text, row, index) {
+ return dashboard(text, index, t_month);
+ },
+ },
+ ]
+ : []),
+ {
+ title: t('activity'),
+ dataIndex: 'value',
+ align: 'right',
+ width: '20%',
+ },
+ {
+ title: '',
+ dataIndex: 'valueDelta',
+ width: '10%',
+ align: 'left',
+ render: PointRender,
+ },
+];
+const activityDetailColumns = (object, t_month) => [
+ {
+ title: t('rank'),
+ dataIndex: 'rank',
+ width: '5%',
+ align: 'center',
+ render: Trophy,
+ fixed: 'left',
+ },
+ ...(object == 'actor'
+ ? [
+ {
+ title: t('avatar'),
+ dataIndex: 'id',
+ width: '5%',
+ align: 'center',
+ render: MyAvatar,
+ fixed: 'left',
+ },
+ ]
+ : []),
+ {
+ title: '',
+ dataIndex: 'rankDelta',
+ render: ArrowRender,
+ align: 'left',
+ width: '5%',
+ fixed: 'left',
+ },
+ {
+ title: t(object),
+ dataIndex: 'name',
+ align: 'center',
+ width: '5%',
+ render: function (text, row, index) {
+ if (object !== 'company') {
+ return (
+
+ {text}
+
+ );
+ } else {
+ return text;
+ }
+ },
+ },
+ ...(object == 'repo'
+ ? [
+ {
+ title: t('insight_board'),
+ dataIndex: 'name',
+ align: 'center',
+ width: '10%',
+ render: function (text, row, index) {
+ return dashboard(text, index, t_month);
+ },
+ },
+ ]
+ : []),
+ {
+ title: t('activity'),
+ dataIndex: 'value',
+ align: 'center',
+ width: '10%',
+ },
+ {
+ title: '',
+ dataIndex: 'valueDelta',
+ width: '10%',
+ align: 'left',
+ render: PointRender,
+ },
+ {
+ title: t('issue_comments'),
+ dataIndex: 'issue_comment',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('open_issues'),
+ dataIndex: 'open_issue',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('open_pulls'),
+ dataIndex: 'open_pull',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('merge_pulls'),
+ dataIndex: 'merged_pull',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('pr_reviews'),
+ dataIndex: 'review_comment',
+ width: '10%',
+ align: 'center',
+ },
+];
+const open_rankColumns = (object, t_month) => [
+ {
+ // 第一列:排名
+ title: t('rank'),
+ dataIndex: 'rank',
+ width: '5%',
+ render: Trophy,
+ align: 'center',
+ fixed: 'left',
+ },
+ // 如果 object 是 'actor',则添加头像列
+ ...(object == 'actor'
+ ? [
+ {
+ title: t('avatar'),
+ dataIndex: 'id',
+ width: '5%',
+ align: 'center',
+ render: MyAvatar,
+ fixed: 'left',
+ },
+ ]
+ : []),
+ // 第二列:排名变化
+ {
+ title: '',
+ dataIndex: 'rankDelta',
+ render: ArrowRender,
+ align: 'left',
+ width: '5%',
+ fixed: 'left',
+ },
+ // 第三列:对象名称(可能是 actor, repo 或 company)
+ {
+ title: t(object),
+ dataIndex: 'name',
+ width: '20%',
+ align: 'center',
+ render: function (text) {
+ if (object !== 'company') {
+ return (
+
+ {text}
+
+ );
+ } else {
+ return text;
+ }
+ },
+ },
+ // 如果 object 是 'repo',则添加 insight_board 列
+ ...(object == 'repo'
+ ? [
+ {
+ title: t('insight_board'),
+ dataIndex: 'name',
+ align: 'center',
+ width: '10%',
+ render: function (text, row, index) {
+ return dashboard(text, index, t_month);
+ },
+ },
+ ]
+ : []),
+ // 第四列:影响力
+ {
+ title: t('influence'),
+ dataIndex: 'value',
+ width: '20%',
+ align: 'right',
+ render: (text, row, index) => {
+ return RoundFloat(text);
+ },
+ },
+ // 第五列:影响力变化
+ {
+ title: '',
+ dataIndex: 'valueDelta',
+ width: '10%',
+ align: 'left',
+ render: (text, row, index) => {
+ text = RoundFloat(text);
+ return PointRender(text, row, index);
+ },
+ },
+];
+
+const solveDate = (year, month) => {
+ if (year === null && month === null) {
+ return 'not found';
+ }
+ if (month === null) {
+ return year + '年';
+ }
+ return year + '年' + (month + 1) + '月';
+};
+
+function dashboard(text, index, t_month) {
+ if (index < 300) {
+ let [org_name, repo_name] = text.split('/');
+ const t_month_copy = t_month + ' ' + '00:00:00';
+ let params = {
+ org_name,
+ repo_name,
+ t_month_copy,
+ t_month,
+ };
+ return (
+
+
+
+ );
+ }
+}
+
+function DateTitle(props) {
+ return {solveDate(props.year, props.month)}
;
+}
+
+function MyTable(props) {
+ const [state, setState] = useState({
+ object: 'technology',
+ index: 'open_rank',
+ region: 'global',
+ showDetail: false,
+ hasDetail: true,
+ data: [],
+ showSize: 25,
+ loading: true,
+ url: '', // base + index + object + region + yearmonth + .json
+ base: 'https://oss.x-lab.info/open_leaderboard/',
+ year: null, // 字符串格式
+ month: null, // 整数格式,0表示1月,1表示2月..., null for year type time
+ type: 'month',
+ search: null,
+ category: 'cloud-native',
+ });
+
+ // 请求一次数据更新表格。如果还没读取好配置文件则不请求数据。
+ useEffect(() => {
+ if (props.year == null && props.month == null) {
+ console.log('the first loading');
+ return;
+ }
+ updateDate({
+ year: String(props.year),
+ month: props.month,
+ });
+ }, [props]);
+
+ const expandData = () => {
+ setState({
+ ...state,
+ showSize: state.showSize + 25,
+ });
+ };
+ const updateDate = (newstate) => {
+ console.log('table update', newstate);
+ // 先获取原先的表格属性
+ let {
+ base,
+ object,
+ index,
+ region,
+ month,
+ year,
+ columns,
+ showDetail,
+ hasDetail,
+ type,
+ search,
+ category,
+ } = state;
+ // 然后把表格改为加载中的状态
+ setState({ ...state, ...newstate, loading: true });
+ // 如果 newstate 有对应的属性,则进行更新
+ if (newstate.hasOwnProperty('object')) object = newstate.object;
+ if (newstate.hasOwnProperty('index')) index = newstate.index;
+ if (newstate.hasOwnProperty('region')) region = newstate.region;
+ if (newstate.hasOwnProperty('month')) month = newstate.month;
+ if (newstate.hasOwnProperty('year')) year = newstate.year;
+ if (newstate.hasOwnProperty('showDetail')) showDetail = newstate.showDetail;
+ if (newstate.hasOwnProperty('type')) type = newstate.type;
+ if (newstate.hasOwnProperty('search')) search = newstate.search;
+ if (newstate.hasOwnProperty('category')) category = newstate.category;
+
+ //获取数据大屏的‘t_month’参数
+ let myyear = newstate.year == null ? state.year : newstate.year;
+ let mymonth = newstate.month == null ? state.month : newstate.month;
+
+ mymonth = ('' + (1 + mymonth)).padStart(2, '0');
+ let t_month = `${myyear}-${mymonth}-01`;
+
+ // 根据 index 和 showDetail 改变表格的 columns 格式
+ if (index == 'activity') {
+ columns = activityColumns(object, t_month);
+ hasDetail = true;
+ }
+ if (index == 'activity' && showDetail == true) {
+ columns = activityDetailColumns(object, t_month);
+ hasDetail = true;
+ }
+ if (index == 'open_rank') {
+ columns = open_rankColumns(object, t_month);
+ hasDetail = false;
+ showDetail = false;
+ }
+ // 如果是年份数据,则把 month 置为 null。
+ // TODO:待验证,如果从年份数据切换到月份数据,似乎会自动回到原来 month 值?
+ if (type == 'year') {
+ month = null;
+ }
+ // 以当前的属性构造请求 url
+ let url = base + index + '/' + object + '/' + region + '/';
+ if (month === null) {
+ url += year + '.json';
+ } else {
+ url += year + (1 + month) + '.json';
+ }
+ console.log(url);
+ console.log(region);
+ if (object == "foundation" && region == 'chinese') {
+
+ // 这里可以进行数据请求
+ fetch('../foundationChinese.json')
+ .then(response => {response.json()
+ console.log(response.json);
+ })
+ .then((data) => {
+ data = data.data;
+ let dataSource = [];
+ // 预处理数据,对新上榜单数据进行特殊标记处理
+ data.map((obj) => {
+ obj = expandObject(obj);
+ if (obj.rankDelta == 0 && obj.value == obj.valueDelta) {
+ obj.rankDelta = -10000000;
+ obj.valueDelta = 0;
+ }
+ dataSource.push(obj);
+ });
+ console.log(dataSource);
+
+ //搜索特定数据
+ let queryData;
+ if (search) {
+ queryData = dataSource.filter((dataSource) => {
+ let reg = new RegExp(search.trim(), 'i');
+ return reg.test(dataSource.name);
+ });
+ if (queryData.length == 0) {
+ message.warning(t('no_result'));
+ } else {
+ dataSource = queryData;
+ }
+ }
+
+ // 更新属性和表格数据
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ showDetail: showDetail,
+ hasDetail: hasDetail,
+ data: dataSource,
+ });
+ })
+ .catch((err) => {
+ console.log('hi!' + err);
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ data: [],
+ });
+ });
+
+ }
+ // fetch 异步请求
+ else{fetch(url)
+ .then((res) => {
+ // Todo:最好的情况是在日期选择器中,只显示可以查询的日期,
+ if (res.status == 404) {
+ message.warning(t('no_result'));
+ return '';
+ }
+ return res.json();
+ })
+ .then((data) => {
+ data = data.data;
+ let dataSource = [];
+ // 预处理数据,对新上榜单数据进行特殊标记处理
+ data.map((obj) => {
+ obj = expandObject(obj);
+ if (obj.rankDelta == 0 && obj.value == obj.valueDelta) {
+ obj.rankDelta = -10000000;
+ obj.valueDelta = 0;
+ }
+ dataSource.push(obj);
+ });
+ console.log(dataSource);
+
+ //搜索特定数据
+ let queryData;
+ if (search) {
+ queryData = dataSource.filter((dataSource) => {
+ let reg = new RegExp(search.trim(), 'i');
+ return reg.test(dataSource.name);
+ });
+ if (queryData.length == 0) {
+ message.warning(t('no_result'));
+ } else {
+ dataSource = queryData;
+ }
+ }
+
+ // 更新属性和表格数据
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ showDetail: showDetail,
+ hasDetail: hasDetail,
+ data: dataSource,
+ });
+ })
+ .catch((err) => {
+ console.log('hi!' + err);
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ data: [],
+ });
+ });
+
+
+ };
+ }
+ const {
+ object,
+ index,
+ region,
+ data,
+ columns,
+ loading,
+ showSize,
+ showDetail,
+ hasDetail,
+ month,
+ year,
+ type,
+ category,
+ } = state;
+ return (
+
+
+
+
+ record.rank}
+ dataSource={data.slice(0, Math.min(showSize, data.length))}
+ pagination={false}
+ loading={loading}
+ scroll={{ x: 'max-content' }}
+ />
+
+
+
+
+ {showSize < data.length ? (
+
+ {t('showMore') + '>>'}
+
+ ) : (
+
+ {t('noMore')}
+
+ )}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+}
+
+export default MyTable;
diff --git a/.history/src/components/table_20240728152433.js b/.history/src/components/table_20240728152433.js
new file mode 100644
index 0000000..1d1294c
--- /dev/null
+++ b/.history/src/components/table_20240728152433.js
@@ -0,0 +1,645 @@
+import React, { useState, useEffect } from 'react';
+import { Col, message, Row, Table, Card } from 'antd';
+import MyAvatar from './avatar';
+import 'antd/dist/antd.css';
+import QAmiss from './QA2';
+import TablePanel from './TablePanel';
+import ArrowRender from './arrow';
+import PointRender from './changeNumber';
+import RoundFloat from './resolveFloat';
+import Trophy from './rankTrophy';
+import expandObject from '../util/expandObject';
+import { t } from 'i18next';
+import './table.css';
+import { foundationChineseData } from './data';
+
+const activityColumns = (object, t_month) => [
+ {
+ title: t('rank'),
+ dataIndex: 'rank',
+ width: '5%',
+ align: 'center',
+ render: Trophy,
+ fixed: 'left',
+ },
+ ...(object == 'actor'
+ ? [
+ {
+ title: t('avatar'),
+ dataIndex: 'id',
+ width: '5%',
+ align: 'center',
+ render: MyAvatar,
+ fixed: 'left',
+ },
+ ]
+ : []),
+ {
+ title: '',
+ dataIndex: 'rankDelta',
+ render: ArrowRender,
+ align: 'left',
+ width: '5%',
+ fixed: 'left',
+ },
+ {
+ title: t(object),
+ dataIndex: 'name',
+ align: 'center',
+ width: '20%',
+ render: function (text, row, index) {
+ if (object !== 'company') {
+ return (
+
+ {text}
+
+ );
+ } else {
+ return text;
+ }
+ },
+ },
+ ...(object == 'repo'
+ ? [
+ {
+ title: t('insight_board'),
+ dataIndex: 'name',
+ align: 'center',
+ width: '10%',
+ render: function (text, row, index) {
+ return dashboard(text, index, t_month);
+ },
+ },
+ ]
+ : []),
+ {
+ title: t('activity'),
+ dataIndex: 'value',
+ align: 'right',
+ width: '20%',
+ },
+ {
+ title: '',
+ dataIndex: 'valueDelta',
+ width: '10%',
+ align: 'left',
+ render: PointRender,
+ },
+];
+const activityDetailColumns = (object, t_month) => [
+ {
+ title: t('rank'),
+ dataIndex: 'rank',
+ width: '5%',
+ align: 'center',
+ render: Trophy,
+ fixed: 'left',
+ },
+ ...(object == 'actor'
+ ? [
+ {
+ title: t('avatar'),
+ dataIndex: 'id',
+ width: '5%',
+ align: 'center',
+ render: MyAvatar,
+ fixed: 'left',
+ },
+ ]
+ : []),
+ {
+ title: '',
+ dataIndex: 'rankDelta',
+ render: ArrowRender,
+ align: 'left',
+ width: '5%',
+ fixed: 'left',
+ },
+ {
+ title: t(object),
+ dataIndex: 'name',
+ align: 'center',
+ width: '5%',
+ render: function (text, row, index) {
+ if (object !== 'company') {
+ return (
+
+ {text}
+
+ );
+ } else {
+ return text;
+ }
+ },
+ },
+ ...(object == 'repo'
+ ? [
+ {
+ title: t('insight_board'),
+ dataIndex: 'name',
+ align: 'center',
+ width: '10%',
+ render: function (text, row, index) {
+ return dashboard(text, index, t_month);
+ },
+ },
+ ]
+ : []),
+ {
+ title: t('activity'),
+ dataIndex: 'value',
+ align: 'center',
+ width: '10%',
+ },
+ {
+ title: '',
+ dataIndex: 'valueDelta',
+ width: '10%',
+ align: 'left',
+ render: PointRender,
+ },
+ {
+ title: t('issue_comments'),
+ dataIndex: 'issue_comment',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('open_issues'),
+ dataIndex: 'open_issue',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('open_pulls'),
+ dataIndex: 'open_pull',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('merge_pulls'),
+ dataIndex: 'merged_pull',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('pr_reviews'),
+ dataIndex: 'review_comment',
+ width: '10%',
+ align: 'center',
+ },
+];
+const open_rankColumns = (object, t_month) => [
+ {
+ // 第一列:排名
+ title: t('rank'),
+ dataIndex: 'rank',
+ width: '5%',
+ render: Trophy,
+ align: 'center',
+ fixed: 'left',
+ },
+ // 如果 object 是 'actor',则添加头像列
+ ...(object == 'actor'
+ ? [
+ {
+ title: t('avatar'),
+ dataIndex: 'id',
+ width: '5%',
+ align: 'center',
+ render: MyAvatar,
+ fixed: 'left',
+ },
+ ]
+ : []),
+ // 第二列:排名变化
+ {
+ title: '',
+ dataIndex: 'rankDelta',
+ render: ArrowRender,
+ align: 'left',
+ width: '5%',
+ fixed: 'left',
+ },
+ // 第三列:对象名称(可能是 actor, repo 或 company)
+ {
+ title: t(object),
+ dataIndex: 'name',
+ width: '20%',
+ align: 'center',
+ render: function (text) {
+ if (object !== 'company') {
+ return (
+
+ {text}
+
+ );
+ } else {
+ return text;
+ }
+ },
+ },
+ // 如果 object 是 'repo',则添加 insight_board 列
+ ...(object == 'repo'
+ ? [
+ {
+ title: t('insight_board'),
+ dataIndex: 'name',
+ align: 'center',
+ width: '10%',
+ render: function (text, row, index) {
+ return dashboard(text, index, t_month);
+ },
+ },
+ ]
+ : []),
+ // 第四列:影响力
+ {
+ title: t('influence'),
+ dataIndex: 'value',
+ width: '20%',
+ align: 'right',
+ render: (text, row, index) => {
+ return RoundFloat(text);
+ },
+ },
+ // 第五列:影响力变化
+ {
+ title: '',
+ dataIndex: 'valueDelta',
+ width: '10%',
+ align: 'left',
+ render: (text, row, index) => {
+ text = RoundFloat(text);
+ return PointRender(text, row, index);
+ },
+ },
+];
+
+const solveDate = (year, month) => {
+ if (year === null && month === null) {
+ return 'not found';
+ }
+ if (month === null) {
+ return year + '年';
+ }
+ return year + '年' + (month + 1) + '月';
+};
+
+function dashboard(text, index, t_month) {
+ if (index < 300) {
+ let [org_name, repo_name] = text.split('/');
+ const t_month_copy = t_month + ' ' + '00:00:00';
+ let params = {
+ org_name,
+ repo_name,
+ t_month_copy,
+ t_month,
+ };
+ return (
+
+
+
+ );
+ }
+}
+
+function DateTitle(props) {
+ return {solveDate(props.year, props.month)}
;
+}
+
+function MyTable(props) {
+ const [state, setState] = useState({
+ object: 'technology',
+ index: 'open_rank',
+ region: 'global',
+ showDetail: false,
+ hasDetail: true,
+ data: [],
+ showSize: 25,
+ loading: true,
+ url: '', // base + index + object + region + yearmonth + .json
+ base: 'https://oss.x-lab.info/open_leaderboard/',
+ year: null, // 字符串格式
+ month: null, // 整数格式,0表示1月,1表示2月..., null for year type time
+ type: 'month',
+ search: null,
+ category: 'cloud-native',
+ });
+
+ // 请求一次数据更新表格。如果还没读取好配置文件则不请求数据。
+ useEffect(() => {
+ if (props.year == null && props.month == null) {
+ console.log('the first loading');
+ return;
+ }
+ updateDate({
+ year: String(props.year),
+ month: props.month,
+ });
+ }, [props]);
+
+ const expandData = () => {
+ setState({
+ ...state,
+ showSize: state.showSize + 25,
+ });
+ };
+ const updateDate = (newstate) => {
+ console.log('table update', newstate);
+ // 先获取原先的表格属性
+ let {
+ base,
+ object,
+ index,
+ region,
+ month,
+ year,
+ columns,
+ showDetail,
+ hasDetail,
+ type,
+ search,
+ category,
+ } = state;
+ // 然后把表格改为加载中的状态
+ setState({ ...state, ...newstate, loading: true });
+ // 如果 newstate 有对应的属性,则进行更新
+ if (newstate.hasOwnProperty('object')) object = newstate.object;
+ if (newstate.hasOwnProperty('index')) index = newstate.index;
+ if (newstate.hasOwnProperty('region')) region = newstate.region;
+ if (newstate.hasOwnProperty('month')) month = newstate.month;
+ if (newstate.hasOwnProperty('year')) year = newstate.year;
+ if (newstate.hasOwnProperty('showDetail')) showDetail = newstate.showDetail;
+ if (newstate.hasOwnProperty('type')) type = newstate.type;
+ if (newstate.hasOwnProperty('search')) search = newstate.search;
+ if (newstate.hasOwnProperty('category')) category = newstate.category;
+
+ //获取数据大屏的‘t_month’参数
+ let myyear = newstate.year == null ? state.year : newstate.year;
+ let mymonth = newstate.month == null ? state.month : newstate.month;
+
+ mymonth = ('' + (1 + mymonth)).padStart(2, '0');
+ let t_month = `${myyear}-${mymonth}-01`;
+
+ // 根据 index 和 showDetail 改变表格的 columns 格式
+ if (index == 'activity') {
+ columns = activityColumns(object, t_month);
+ hasDetail = true;
+ }
+ if (index == 'activity' && showDetail == true) {
+ columns = activityDetailColumns(object, t_month);
+ hasDetail = true;
+ }
+ if (index == 'open_rank') {
+ columns = open_rankColumns(object, t_month);
+ hasDetail = false;
+ showDetail = false;
+ }
+ // 如果是年份数据,则把 month 置为 null。
+ // TODO:待验证,如果从年份数据切换到月份数据,似乎会自动回到原来 month 值?
+ if (type == 'year') {
+ month = null;
+ }
+ // 以当前的属性构造请求 url
+ let url = base + index + '/' + object + '/' + region + '/';
+ if (month === null) {
+ url += year + '.json';
+ } else {
+ url += year + (1 + month) + '.json';
+ }
+ console.log(url);
+ console.log(region);
+ if (object == "foundation" && region == 'chinese') {
+
+ // 这里可以进行数据请求
+ fetch('./foundationChinese.json')
+ .then(response => {response.json()
+ console.log(response.json);
+ })
+ .then((data) => {
+ data = data.data;
+ let dataSource = [];
+ // 预处理数据,对新上榜单数据进行特殊标记处理
+ data.map((obj) => {
+ obj = expandObject(obj);
+ if (obj.rankDelta == 0 && obj.value == obj.valueDelta) {
+ obj.rankDelta = -10000000;
+ obj.valueDelta = 0;
+ }
+ dataSource.push(obj);
+ });
+ console.log(dataSource);
+
+ //搜索特定数据
+ let queryData;
+ if (search) {
+ queryData = dataSource.filter((dataSource) => {
+ let reg = new RegExp(search.trim(), 'i');
+ return reg.test(dataSource.name);
+ });
+ if (queryData.length == 0) {
+ message.warning(t('no_result'));
+ } else {
+ dataSource = queryData;
+ }
+ }
+
+ // 更新属性和表格数据
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ showDetail: showDetail,
+ hasDetail: hasDetail,
+ data: dataSource,
+ });
+ })
+ .catch((err) => {
+ console.log('hi!' + err);
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ data: [],
+ });
+ });
+
+ }
+ // fetch 异步请求
+ else{fetch(url)
+ .then((res) => {
+ // Todo:最好的情况是在日期选择器中,只显示可以查询的日期,
+ if (res.status == 404) {
+ message.warning(t('no_result'));
+ return '';
+ }
+ return res.json();
+ })
+ .then((data) => {
+ data = data.data;
+ let dataSource = [];
+ // 预处理数据,对新上榜单数据进行特殊标记处理
+ data.map((obj) => {
+ obj = expandObject(obj);
+ if (obj.rankDelta == 0 && obj.value == obj.valueDelta) {
+ obj.rankDelta = -10000000;
+ obj.valueDelta = 0;
+ }
+ dataSource.push(obj);
+ });
+ console.log(dataSource);
+
+ //搜索特定数据
+ let queryData;
+ if (search) {
+ queryData = dataSource.filter((dataSource) => {
+ let reg = new RegExp(search.trim(), 'i');
+ return reg.test(dataSource.name);
+ });
+ if (queryData.length == 0) {
+ message.warning(t('no_result'));
+ } else {
+ dataSource = queryData;
+ }
+ }
+
+ // 更新属性和表格数据
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ showDetail: showDetail,
+ hasDetail: hasDetail,
+ data: dataSource,
+ });
+ })
+ .catch((err) => {
+ console.log('hi!' + err);
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ data: [],
+ });
+ });
+
+
+ };
+ }
+ const {
+ object,
+ index,
+ region,
+ data,
+ columns,
+ loading,
+ showSize,
+ showDetail,
+ hasDetail,
+ month,
+ year,
+ type,
+ category,
+ } = state;
+ return (
+
+
+
+
+ record.rank}
+ dataSource={data.slice(0, Math.min(showSize, data.length))}
+ pagination={false}
+ loading={loading}
+ scroll={{ x: 'max-content' }}
+ />
+
+
+
+
+ {showSize < data.length ? (
+
+ {t('showMore') + '>>'}
+
+ ) : (
+
+ {t('noMore')}
+
+ )}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+}
+
+export default MyTable;
diff --git a/.history/src/components/table_20240728152504.js b/.history/src/components/table_20240728152504.js
new file mode 100644
index 0000000..7e7825c
--- /dev/null
+++ b/.history/src/components/table_20240728152504.js
@@ -0,0 +1,645 @@
+import React, { useState, useEffect } from 'react';
+import { Col, message, Row, Table, Card } from 'antd';
+import MyAvatar from './avatar';
+import 'antd/dist/antd.css';
+import QAmiss from './QA2';
+import TablePanel from './TablePanel';
+import ArrowRender from './arrow';
+import PointRender from './changeNumber';
+import RoundFloat from './resolveFloat';
+import Trophy from './rankTrophy';
+import expandObject from '../util/expandObject';
+import { t } from 'i18next';
+import './table.css';
+import { foundationChineseData } from './data';
+
+const activityColumns = (object, t_month) => [
+ {
+ title: t('rank'),
+ dataIndex: 'rank',
+ width: '5%',
+ align: 'center',
+ render: Trophy,
+ fixed: 'left',
+ },
+ ...(object == 'actor'
+ ? [
+ {
+ title: t('avatar'),
+ dataIndex: 'id',
+ width: '5%',
+ align: 'center',
+ render: MyAvatar,
+ fixed: 'left',
+ },
+ ]
+ : []),
+ {
+ title: '',
+ dataIndex: 'rankDelta',
+ render: ArrowRender,
+ align: 'left',
+ width: '5%',
+ fixed: 'left',
+ },
+ {
+ title: t(object),
+ dataIndex: 'name',
+ align: 'center',
+ width: '20%',
+ render: function (text, row, index) {
+ if (object !== 'company') {
+ return (
+
+ {text}
+
+ );
+ } else {
+ return text;
+ }
+ },
+ },
+ ...(object == 'repo'
+ ? [
+ {
+ title: t('insight_board'),
+ dataIndex: 'name',
+ align: 'center',
+ width: '10%',
+ render: function (text, row, index) {
+ return dashboard(text, index, t_month);
+ },
+ },
+ ]
+ : []),
+ {
+ title: t('activity'),
+ dataIndex: 'value',
+ align: 'right',
+ width: '20%',
+ },
+ {
+ title: '',
+ dataIndex: 'valueDelta',
+ width: '10%',
+ align: 'left',
+ render: PointRender,
+ },
+];
+const activityDetailColumns = (object, t_month) => [
+ {
+ title: t('rank'),
+ dataIndex: 'rank',
+ width: '5%',
+ align: 'center',
+ render: Trophy,
+ fixed: 'left',
+ },
+ ...(object == 'actor'
+ ? [
+ {
+ title: t('avatar'),
+ dataIndex: 'id',
+ width: '5%',
+ align: 'center',
+ render: MyAvatar,
+ fixed: 'left',
+ },
+ ]
+ : []),
+ {
+ title: '',
+ dataIndex: 'rankDelta',
+ render: ArrowRender,
+ align: 'left',
+ width: '5%',
+ fixed: 'left',
+ },
+ {
+ title: t(object),
+ dataIndex: 'name',
+ align: 'center',
+ width: '5%',
+ render: function (text, row, index) {
+ if (object !== 'company') {
+ return (
+
+ {text}
+
+ );
+ } else {
+ return text;
+ }
+ },
+ },
+ ...(object == 'repo'
+ ? [
+ {
+ title: t('insight_board'),
+ dataIndex: 'name',
+ align: 'center',
+ width: '10%',
+ render: function (text, row, index) {
+ return dashboard(text, index, t_month);
+ },
+ },
+ ]
+ : []),
+ {
+ title: t('activity'),
+ dataIndex: 'value',
+ align: 'center',
+ width: '10%',
+ },
+ {
+ title: '',
+ dataIndex: 'valueDelta',
+ width: '10%',
+ align: 'left',
+ render: PointRender,
+ },
+ {
+ title: t('issue_comments'),
+ dataIndex: 'issue_comment',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('open_issues'),
+ dataIndex: 'open_issue',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('open_pulls'),
+ dataIndex: 'open_pull',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('merge_pulls'),
+ dataIndex: 'merged_pull',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('pr_reviews'),
+ dataIndex: 'review_comment',
+ width: '10%',
+ align: 'center',
+ },
+];
+const open_rankColumns = (object, t_month) => [
+ {
+ // 第一列:排名
+ title: t('rank'),
+ dataIndex: 'rank',
+ width: '5%',
+ render: Trophy,
+ align: 'center',
+ fixed: 'left',
+ },
+ // 如果 object 是 'actor',则添加头像列
+ ...(object == 'actor'
+ ? [
+ {
+ title: t('avatar'),
+ dataIndex: 'id',
+ width: '5%',
+ align: 'center',
+ render: MyAvatar,
+ fixed: 'left',
+ },
+ ]
+ : []),
+ // 第二列:排名变化
+ {
+ title: '',
+ dataIndex: 'rankDelta',
+ render: ArrowRender,
+ align: 'left',
+ width: '5%',
+ fixed: 'left',
+ },
+ // 第三列:对象名称(可能是 actor, repo 或 company)
+ {
+ title: t(object),
+ dataIndex: 'name',
+ width: '20%',
+ align: 'center',
+ render: function (text) {
+ if (object !== 'company') {
+ return (
+
+ {text}
+
+ );
+ } else {
+ return text;
+ }
+ },
+ },
+ // 如果 object 是 'repo',则添加 insight_board 列
+ ...(object == 'repo'
+ ? [
+ {
+ title: t('insight_board'),
+ dataIndex: 'name',
+ align: 'center',
+ width: '10%',
+ render: function (text, row, index) {
+ return dashboard(text, index, t_month);
+ },
+ },
+ ]
+ : []),
+ // 第四列:影响力
+ {
+ title: t('influence'),
+ dataIndex: 'value',
+ width: '20%',
+ align: 'right',
+ render: (text, row, index) => {
+ return RoundFloat(text);
+ },
+ },
+ // 第五列:影响力变化
+ {
+ title: '',
+ dataIndex: 'valueDelta',
+ width: '10%',
+ align: 'left',
+ render: (text, row, index) => {
+ text = RoundFloat(text);
+ return PointRender(text, row, index);
+ },
+ },
+];
+
+const solveDate = (year, month) => {
+ if (year === null && month === null) {
+ return 'not found';
+ }
+ if (month === null) {
+ return year + '年';
+ }
+ return year + '年' + (month + 1) + '月';
+};
+
+function dashboard(text, index, t_month) {
+ if (index < 300) {
+ let [org_name, repo_name] = text.split('/');
+ const t_month_copy = t_month + ' ' + '00:00:00';
+ let params = {
+ org_name,
+ repo_name,
+ t_month_copy,
+ t_month,
+ };
+ return (
+
+
+
+ );
+ }
+}
+
+function DateTitle(props) {
+ return {solveDate(props.year, props.month)}
;
+}
+
+function MyTable(props) {
+ const [state, setState] = useState({
+ object: 'technology',
+ index: 'open_rank',
+ region: 'global',
+ showDetail: false,
+ hasDetail: true,
+ data: [],
+ showSize: 25,
+ loading: true,
+ url: '', // base + index + object + region + yearmonth + .json
+ base: 'https://oss.x-lab.info/open_leaderboard/',
+ year: null, // 字符串格式
+ month: null, // 整数格式,0表示1月,1表示2月..., null for year type time
+ type: 'month',
+ search: null,
+ category: 'cloud-native',
+ });
+
+ // 请求一次数据更新表格。如果还没读取好配置文件则不请求数据。
+ useEffect(() => {
+ if (props.year == null && props.month == null) {
+ console.log('the first loading');
+ return;
+ }
+ updateDate({
+ year: String(props.year),
+ month: props.month,
+ });
+ }, [props]);
+
+ const expandData = () => {
+ setState({
+ ...state,
+ showSize: state.showSize + 25,
+ });
+ };
+ const updateDate = (newstate) => {
+ console.log('table update', newstate);
+ // 先获取原先的表格属性
+ let {
+ base,
+ object,
+ index,
+ region,
+ month,
+ year,
+ columns,
+ showDetail,
+ hasDetail,
+ type,
+ search,
+ category,
+ } = state;
+ // 然后把表格改为加载中的状态
+ setState({ ...state, ...newstate, loading: true });
+ // 如果 newstate 有对应的属性,则进行更新
+ if (newstate.hasOwnProperty('object')) object = newstate.object;
+ if (newstate.hasOwnProperty('index')) index = newstate.index;
+ if (newstate.hasOwnProperty('region')) region = newstate.region;
+ if (newstate.hasOwnProperty('month')) month = newstate.month;
+ if (newstate.hasOwnProperty('year')) year = newstate.year;
+ if (newstate.hasOwnProperty('showDetail')) showDetail = newstate.showDetail;
+ if (newstate.hasOwnProperty('type')) type = newstate.type;
+ if (newstate.hasOwnProperty('search')) search = newstate.search;
+ if (newstate.hasOwnProperty('category')) category = newstate.category;
+
+ //获取数据大屏的‘t_month’参数
+ let myyear = newstate.year == null ? state.year : newstate.year;
+ let mymonth = newstate.month == null ? state.month : newstate.month;
+
+ mymonth = ('' + (1 + mymonth)).padStart(2, '0');
+ let t_month = `${myyear}-${mymonth}-01`;
+
+ // 根据 index 和 showDetail 改变表格的 columns 格式
+ if (index == 'activity') {
+ columns = activityColumns(object, t_month);
+ hasDetail = true;
+ }
+ if (index == 'activity' && showDetail == true) {
+ columns = activityDetailColumns(object, t_month);
+ hasDetail = true;
+ }
+ if (index == 'open_rank') {
+ columns = open_rankColumns(object, t_month);
+ hasDetail = false;
+ showDetail = false;
+ }
+ // 如果是年份数据,则把 month 置为 null。
+ // TODO:待验证,如果从年份数据切换到月份数据,似乎会自动回到原来 month 值?
+ if (type == 'year') {
+ month = null;
+ }
+ // 以当前的属性构造请求 url
+ let url = base + index + '/' + object + '/' + region + '/';
+ if (month === null) {
+ url += year + '.json';
+ } else {
+ url += year + (1 + month) + '.json';
+ }
+ console.log(url);
+ console.log(region);
+ if (object == "foundation" && region == 'chinese') {
+
+ // 这里可以进行数据请求
+ fetch('/foundationChinese.json')
+ .then(response => {response.json()
+ console.log(response.json);
+ })
+ .then((data) => {
+ data = data.data;
+ let dataSource = [];
+ // 预处理数据,对新上榜单数据进行特殊标记处理
+ data.map((obj) => {
+ obj = expandObject(obj);
+ if (obj.rankDelta == 0 && obj.value == obj.valueDelta) {
+ obj.rankDelta = -10000000;
+ obj.valueDelta = 0;
+ }
+ dataSource.push(obj);
+ });
+ console.log(dataSource);
+
+ //搜索特定数据
+ let queryData;
+ if (search) {
+ queryData = dataSource.filter((dataSource) => {
+ let reg = new RegExp(search.trim(), 'i');
+ return reg.test(dataSource.name);
+ });
+ if (queryData.length == 0) {
+ message.warning(t('no_result'));
+ } else {
+ dataSource = queryData;
+ }
+ }
+
+ // 更新属性和表格数据
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ showDetail: showDetail,
+ hasDetail: hasDetail,
+ data: dataSource,
+ });
+ })
+ .catch((err) => {
+ console.log('hi!' + err);
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ data: [],
+ });
+ });
+
+ }
+ // fetch 异步请求
+ else{fetch(url)
+ .then((res) => {
+ // Todo:最好的情况是在日期选择器中,只显示可以查询的日期,
+ if (res.status == 404) {
+ message.warning(t('no_result'));
+ return '';
+ }
+ return res.json();
+ })
+ .then((data) => {
+ data = data.data;
+ let dataSource = [];
+ // 预处理数据,对新上榜单数据进行特殊标记处理
+ data.map((obj) => {
+ obj = expandObject(obj);
+ if (obj.rankDelta == 0 && obj.value == obj.valueDelta) {
+ obj.rankDelta = -10000000;
+ obj.valueDelta = 0;
+ }
+ dataSource.push(obj);
+ });
+ console.log(dataSource);
+
+ //搜索特定数据
+ let queryData;
+ if (search) {
+ queryData = dataSource.filter((dataSource) => {
+ let reg = new RegExp(search.trim(), 'i');
+ return reg.test(dataSource.name);
+ });
+ if (queryData.length == 0) {
+ message.warning(t('no_result'));
+ } else {
+ dataSource = queryData;
+ }
+ }
+
+ // 更新属性和表格数据
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ showDetail: showDetail,
+ hasDetail: hasDetail,
+ data: dataSource,
+ });
+ })
+ .catch((err) => {
+ console.log('hi!' + err);
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ data: [],
+ });
+ });
+
+
+ };
+ }
+ const {
+ object,
+ index,
+ region,
+ data,
+ columns,
+ loading,
+ showSize,
+ showDetail,
+ hasDetail,
+ month,
+ year,
+ type,
+ category,
+ } = state;
+ return (
+
+
+
+
+ record.rank}
+ dataSource={data.slice(0, Math.min(showSize, data.length))}
+ pagination={false}
+ loading={loading}
+ scroll={{ x: 'max-content' }}
+ />
+
+
+
+
+ {showSize < data.length ? (
+
+ {t('showMore') + '>>'}
+
+ ) : (
+
+ {t('noMore')}
+
+ )}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+}
+
+export default MyTable;
diff --git a/.history/src/components/table_20240728152539.js b/.history/src/components/table_20240728152539.js
new file mode 100644
index 0000000..1d1294c
--- /dev/null
+++ b/.history/src/components/table_20240728152539.js
@@ -0,0 +1,645 @@
+import React, { useState, useEffect } from 'react';
+import { Col, message, Row, Table, Card } from 'antd';
+import MyAvatar from './avatar';
+import 'antd/dist/antd.css';
+import QAmiss from './QA2';
+import TablePanel from './TablePanel';
+import ArrowRender from './arrow';
+import PointRender from './changeNumber';
+import RoundFloat from './resolveFloat';
+import Trophy from './rankTrophy';
+import expandObject from '../util/expandObject';
+import { t } from 'i18next';
+import './table.css';
+import { foundationChineseData } from './data';
+
+const activityColumns = (object, t_month) => [
+ {
+ title: t('rank'),
+ dataIndex: 'rank',
+ width: '5%',
+ align: 'center',
+ render: Trophy,
+ fixed: 'left',
+ },
+ ...(object == 'actor'
+ ? [
+ {
+ title: t('avatar'),
+ dataIndex: 'id',
+ width: '5%',
+ align: 'center',
+ render: MyAvatar,
+ fixed: 'left',
+ },
+ ]
+ : []),
+ {
+ title: '',
+ dataIndex: 'rankDelta',
+ render: ArrowRender,
+ align: 'left',
+ width: '5%',
+ fixed: 'left',
+ },
+ {
+ title: t(object),
+ dataIndex: 'name',
+ align: 'center',
+ width: '20%',
+ render: function (text, row, index) {
+ if (object !== 'company') {
+ return (
+
+ {text}
+
+ );
+ } else {
+ return text;
+ }
+ },
+ },
+ ...(object == 'repo'
+ ? [
+ {
+ title: t('insight_board'),
+ dataIndex: 'name',
+ align: 'center',
+ width: '10%',
+ render: function (text, row, index) {
+ return dashboard(text, index, t_month);
+ },
+ },
+ ]
+ : []),
+ {
+ title: t('activity'),
+ dataIndex: 'value',
+ align: 'right',
+ width: '20%',
+ },
+ {
+ title: '',
+ dataIndex: 'valueDelta',
+ width: '10%',
+ align: 'left',
+ render: PointRender,
+ },
+];
+const activityDetailColumns = (object, t_month) => [
+ {
+ title: t('rank'),
+ dataIndex: 'rank',
+ width: '5%',
+ align: 'center',
+ render: Trophy,
+ fixed: 'left',
+ },
+ ...(object == 'actor'
+ ? [
+ {
+ title: t('avatar'),
+ dataIndex: 'id',
+ width: '5%',
+ align: 'center',
+ render: MyAvatar,
+ fixed: 'left',
+ },
+ ]
+ : []),
+ {
+ title: '',
+ dataIndex: 'rankDelta',
+ render: ArrowRender,
+ align: 'left',
+ width: '5%',
+ fixed: 'left',
+ },
+ {
+ title: t(object),
+ dataIndex: 'name',
+ align: 'center',
+ width: '5%',
+ render: function (text, row, index) {
+ if (object !== 'company') {
+ return (
+
+ {text}
+
+ );
+ } else {
+ return text;
+ }
+ },
+ },
+ ...(object == 'repo'
+ ? [
+ {
+ title: t('insight_board'),
+ dataIndex: 'name',
+ align: 'center',
+ width: '10%',
+ render: function (text, row, index) {
+ return dashboard(text, index, t_month);
+ },
+ },
+ ]
+ : []),
+ {
+ title: t('activity'),
+ dataIndex: 'value',
+ align: 'center',
+ width: '10%',
+ },
+ {
+ title: '',
+ dataIndex: 'valueDelta',
+ width: '10%',
+ align: 'left',
+ render: PointRender,
+ },
+ {
+ title: t('issue_comments'),
+ dataIndex: 'issue_comment',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('open_issues'),
+ dataIndex: 'open_issue',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('open_pulls'),
+ dataIndex: 'open_pull',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('merge_pulls'),
+ dataIndex: 'merged_pull',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('pr_reviews'),
+ dataIndex: 'review_comment',
+ width: '10%',
+ align: 'center',
+ },
+];
+const open_rankColumns = (object, t_month) => [
+ {
+ // 第一列:排名
+ title: t('rank'),
+ dataIndex: 'rank',
+ width: '5%',
+ render: Trophy,
+ align: 'center',
+ fixed: 'left',
+ },
+ // 如果 object 是 'actor',则添加头像列
+ ...(object == 'actor'
+ ? [
+ {
+ title: t('avatar'),
+ dataIndex: 'id',
+ width: '5%',
+ align: 'center',
+ render: MyAvatar,
+ fixed: 'left',
+ },
+ ]
+ : []),
+ // 第二列:排名变化
+ {
+ title: '',
+ dataIndex: 'rankDelta',
+ render: ArrowRender,
+ align: 'left',
+ width: '5%',
+ fixed: 'left',
+ },
+ // 第三列:对象名称(可能是 actor, repo 或 company)
+ {
+ title: t(object),
+ dataIndex: 'name',
+ width: '20%',
+ align: 'center',
+ render: function (text) {
+ if (object !== 'company') {
+ return (
+
+ {text}
+
+ );
+ } else {
+ return text;
+ }
+ },
+ },
+ // 如果 object 是 'repo',则添加 insight_board 列
+ ...(object == 'repo'
+ ? [
+ {
+ title: t('insight_board'),
+ dataIndex: 'name',
+ align: 'center',
+ width: '10%',
+ render: function (text, row, index) {
+ return dashboard(text, index, t_month);
+ },
+ },
+ ]
+ : []),
+ // 第四列:影响力
+ {
+ title: t('influence'),
+ dataIndex: 'value',
+ width: '20%',
+ align: 'right',
+ render: (text, row, index) => {
+ return RoundFloat(text);
+ },
+ },
+ // 第五列:影响力变化
+ {
+ title: '',
+ dataIndex: 'valueDelta',
+ width: '10%',
+ align: 'left',
+ render: (text, row, index) => {
+ text = RoundFloat(text);
+ return PointRender(text, row, index);
+ },
+ },
+];
+
+const solveDate = (year, month) => {
+ if (year === null && month === null) {
+ return 'not found';
+ }
+ if (month === null) {
+ return year + '年';
+ }
+ return year + '年' + (month + 1) + '月';
+};
+
+function dashboard(text, index, t_month) {
+ if (index < 300) {
+ let [org_name, repo_name] = text.split('/');
+ const t_month_copy = t_month + ' ' + '00:00:00';
+ let params = {
+ org_name,
+ repo_name,
+ t_month_copy,
+ t_month,
+ };
+ return (
+
+
+
+ );
+ }
+}
+
+function DateTitle(props) {
+ return {solveDate(props.year, props.month)}
;
+}
+
+function MyTable(props) {
+ const [state, setState] = useState({
+ object: 'technology',
+ index: 'open_rank',
+ region: 'global',
+ showDetail: false,
+ hasDetail: true,
+ data: [],
+ showSize: 25,
+ loading: true,
+ url: '', // base + index + object + region + yearmonth + .json
+ base: 'https://oss.x-lab.info/open_leaderboard/',
+ year: null, // 字符串格式
+ month: null, // 整数格式,0表示1月,1表示2月..., null for year type time
+ type: 'month',
+ search: null,
+ category: 'cloud-native',
+ });
+
+ // 请求一次数据更新表格。如果还没读取好配置文件则不请求数据。
+ useEffect(() => {
+ if (props.year == null && props.month == null) {
+ console.log('the first loading');
+ return;
+ }
+ updateDate({
+ year: String(props.year),
+ month: props.month,
+ });
+ }, [props]);
+
+ const expandData = () => {
+ setState({
+ ...state,
+ showSize: state.showSize + 25,
+ });
+ };
+ const updateDate = (newstate) => {
+ console.log('table update', newstate);
+ // 先获取原先的表格属性
+ let {
+ base,
+ object,
+ index,
+ region,
+ month,
+ year,
+ columns,
+ showDetail,
+ hasDetail,
+ type,
+ search,
+ category,
+ } = state;
+ // 然后把表格改为加载中的状态
+ setState({ ...state, ...newstate, loading: true });
+ // 如果 newstate 有对应的属性,则进行更新
+ if (newstate.hasOwnProperty('object')) object = newstate.object;
+ if (newstate.hasOwnProperty('index')) index = newstate.index;
+ if (newstate.hasOwnProperty('region')) region = newstate.region;
+ if (newstate.hasOwnProperty('month')) month = newstate.month;
+ if (newstate.hasOwnProperty('year')) year = newstate.year;
+ if (newstate.hasOwnProperty('showDetail')) showDetail = newstate.showDetail;
+ if (newstate.hasOwnProperty('type')) type = newstate.type;
+ if (newstate.hasOwnProperty('search')) search = newstate.search;
+ if (newstate.hasOwnProperty('category')) category = newstate.category;
+
+ //获取数据大屏的‘t_month’参数
+ let myyear = newstate.year == null ? state.year : newstate.year;
+ let mymonth = newstate.month == null ? state.month : newstate.month;
+
+ mymonth = ('' + (1 + mymonth)).padStart(2, '0');
+ let t_month = `${myyear}-${mymonth}-01`;
+
+ // 根据 index 和 showDetail 改变表格的 columns 格式
+ if (index == 'activity') {
+ columns = activityColumns(object, t_month);
+ hasDetail = true;
+ }
+ if (index == 'activity' && showDetail == true) {
+ columns = activityDetailColumns(object, t_month);
+ hasDetail = true;
+ }
+ if (index == 'open_rank') {
+ columns = open_rankColumns(object, t_month);
+ hasDetail = false;
+ showDetail = false;
+ }
+ // 如果是年份数据,则把 month 置为 null。
+ // TODO:待验证,如果从年份数据切换到月份数据,似乎会自动回到原来 month 值?
+ if (type == 'year') {
+ month = null;
+ }
+ // 以当前的属性构造请求 url
+ let url = base + index + '/' + object + '/' + region + '/';
+ if (month === null) {
+ url += year + '.json';
+ } else {
+ url += year + (1 + month) + '.json';
+ }
+ console.log(url);
+ console.log(region);
+ if (object == "foundation" && region == 'chinese') {
+
+ // 这里可以进行数据请求
+ fetch('./foundationChinese.json')
+ .then(response => {response.json()
+ console.log(response.json);
+ })
+ .then((data) => {
+ data = data.data;
+ let dataSource = [];
+ // 预处理数据,对新上榜单数据进行特殊标记处理
+ data.map((obj) => {
+ obj = expandObject(obj);
+ if (obj.rankDelta == 0 && obj.value == obj.valueDelta) {
+ obj.rankDelta = -10000000;
+ obj.valueDelta = 0;
+ }
+ dataSource.push(obj);
+ });
+ console.log(dataSource);
+
+ //搜索特定数据
+ let queryData;
+ if (search) {
+ queryData = dataSource.filter((dataSource) => {
+ let reg = new RegExp(search.trim(), 'i');
+ return reg.test(dataSource.name);
+ });
+ if (queryData.length == 0) {
+ message.warning(t('no_result'));
+ } else {
+ dataSource = queryData;
+ }
+ }
+
+ // 更新属性和表格数据
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ showDetail: showDetail,
+ hasDetail: hasDetail,
+ data: dataSource,
+ });
+ })
+ .catch((err) => {
+ console.log('hi!' + err);
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ data: [],
+ });
+ });
+
+ }
+ // fetch 异步请求
+ else{fetch(url)
+ .then((res) => {
+ // Todo:最好的情况是在日期选择器中,只显示可以查询的日期,
+ if (res.status == 404) {
+ message.warning(t('no_result'));
+ return '';
+ }
+ return res.json();
+ })
+ .then((data) => {
+ data = data.data;
+ let dataSource = [];
+ // 预处理数据,对新上榜单数据进行特殊标记处理
+ data.map((obj) => {
+ obj = expandObject(obj);
+ if (obj.rankDelta == 0 && obj.value == obj.valueDelta) {
+ obj.rankDelta = -10000000;
+ obj.valueDelta = 0;
+ }
+ dataSource.push(obj);
+ });
+ console.log(dataSource);
+
+ //搜索特定数据
+ let queryData;
+ if (search) {
+ queryData = dataSource.filter((dataSource) => {
+ let reg = new RegExp(search.trim(), 'i');
+ return reg.test(dataSource.name);
+ });
+ if (queryData.length == 0) {
+ message.warning(t('no_result'));
+ } else {
+ dataSource = queryData;
+ }
+ }
+
+ // 更新属性和表格数据
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ showDetail: showDetail,
+ hasDetail: hasDetail,
+ data: dataSource,
+ });
+ })
+ .catch((err) => {
+ console.log('hi!' + err);
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ data: [],
+ });
+ });
+
+
+ };
+ }
+ const {
+ object,
+ index,
+ region,
+ data,
+ columns,
+ loading,
+ showSize,
+ showDetail,
+ hasDetail,
+ month,
+ year,
+ type,
+ category,
+ } = state;
+ return (
+
+
+
+
+ record.rank}
+ dataSource={data.slice(0, Math.min(showSize, data.length))}
+ pagination={false}
+ loading={loading}
+ scroll={{ x: 'max-content' }}
+ />
+
+
+
+
+ {showSize < data.length ? (
+
+ {t('showMore') + '>>'}
+
+ ) : (
+
+ {t('noMore')}
+
+ )}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+}
+
+export default MyTable;
diff --git a/.history/src/components/table_20240728152542.js b/.history/src/components/table_20240728152542.js
new file mode 100644
index 0000000..1d1294c
--- /dev/null
+++ b/.history/src/components/table_20240728152542.js
@@ -0,0 +1,645 @@
+import React, { useState, useEffect } from 'react';
+import { Col, message, Row, Table, Card } from 'antd';
+import MyAvatar from './avatar';
+import 'antd/dist/antd.css';
+import QAmiss from './QA2';
+import TablePanel from './TablePanel';
+import ArrowRender from './arrow';
+import PointRender from './changeNumber';
+import RoundFloat from './resolveFloat';
+import Trophy from './rankTrophy';
+import expandObject from '../util/expandObject';
+import { t } from 'i18next';
+import './table.css';
+import { foundationChineseData } from './data';
+
+const activityColumns = (object, t_month) => [
+ {
+ title: t('rank'),
+ dataIndex: 'rank',
+ width: '5%',
+ align: 'center',
+ render: Trophy,
+ fixed: 'left',
+ },
+ ...(object == 'actor'
+ ? [
+ {
+ title: t('avatar'),
+ dataIndex: 'id',
+ width: '5%',
+ align: 'center',
+ render: MyAvatar,
+ fixed: 'left',
+ },
+ ]
+ : []),
+ {
+ title: '',
+ dataIndex: 'rankDelta',
+ render: ArrowRender,
+ align: 'left',
+ width: '5%',
+ fixed: 'left',
+ },
+ {
+ title: t(object),
+ dataIndex: 'name',
+ align: 'center',
+ width: '20%',
+ render: function (text, row, index) {
+ if (object !== 'company') {
+ return (
+
+ {text}
+
+ );
+ } else {
+ return text;
+ }
+ },
+ },
+ ...(object == 'repo'
+ ? [
+ {
+ title: t('insight_board'),
+ dataIndex: 'name',
+ align: 'center',
+ width: '10%',
+ render: function (text, row, index) {
+ return dashboard(text, index, t_month);
+ },
+ },
+ ]
+ : []),
+ {
+ title: t('activity'),
+ dataIndex: 'value',
+ align: 'right',
+ width: '20%',
+ },
+ {
+ title: '',
+ dataIndex: 'valueDelta',
+ width: '10%',
+ align: 'left',
+ render: PointRender,
+ },
+];
+const activityDetailColumns = (object, t_month) => [
+ {
+ title: t('rank'),
+ dataIndex: 'rank',
+ width: '5%',
+ align: 'center',
+ render: Trophy,
+ fixed: 'left',
+ },
+ ...(object == 'actor'
+ ? [
+ {
+ title: t('avatar'),
+ dataIndex: 'id',
+ width: '5%',
+ align: 'center',
+ render: MyAvatar,
+ fixed: 'left',
+ },
+ ]
+ : []),
+ {
+ title: '',
+ dataIndex: 'rankDelta',
+ render: ArrowRender,
+ align: 'left',
+ width: '5%',
+ fixed: 'left',
+ },
+ {
+ title: t(object),
+ dataIndex: 'name',
+ align: 'center',
+ width: '5%',
+ render: function (text, row, index) {
+ if (object !== 'company') {
+ return (
+
+ {text}
+
+ );
+ } else {
+ return text;
+ }
+ },
+ },
+ ...(object == 'repo'
+ ? [
+ {
+ title: t('insight_board'),
+ dataIndex: 'name',
+ align: 'center',
+ width: '10%',
+ render: function (text, row, index) {
+ return dashboard(text, index, t_month);
+ },
+ },
+ ]
+ : []),
+ {
+ title: t('activity'),
+ dataIndex: 'value',
+ align: 'center',
+ width: '10%',
+ },
+ {
+ title: '',
+ dataIndex: 'valueDelta',
+ width: '10%',
+ align: 'left',
+ render: PointRender,
+ },
+ {
+ title: t('issue_comments'),
+ dataIndex: 'issue_comment',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('open_issues'),
+ dataIndex: 'open_issue',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('open_pulls'),
+ dataIndex: 'open_pull',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('merge_pulls'),
+ dataIndex: 'merged_pull',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('pr_reviews'),
+ dataIndex: 'review_comment',
+ width: '10%',
+ align: 'center',
+ },
+];
+const open_rankColumns = (object, t_month) => [
+ {
+ // 第一列:排名
+ title: t('rank'),
+ dataIndex: 'rank',
+ width: '5%',
+ render: Trophy,
+ align: 'center',
+ fixed: 'left',
+ },
+ // 如果 object 是 'actor',则添加头像列
+ ...(object == 'actor'
+ ? [
+ {
+ title: t('avatar'),
+ dataIndex: 'id',
+ width: '5%',
+ align: 'center',
+ render: MyAvatar,
+ fixed: 'left',
+ },
+ ]
+ : []),
+ // 第二列:排名变化
+ {
+ title: '',
+ dataIndex: 'rankDelta',
+ render: ArrowRender,
+ align: 'left',
+ width: '5%',
+ fixed: 'left',
+ },
+ // 第三列:对象名称(可能是 actor, repo 或 company)
+ {
+ title: t(object),
+ dataIndex: 'name',
+ width: '20%',
+ align: 'center',
+ render: function (text) {
+ if (object !== 'company') {
+ return (
+
+ {text}
+
+ );
+ } else {
+ return text;
+ }
+ },
+ },
+ // 如果 object 是 'repo',则添加 insight_board 列
+ ...(object == 'repo'
+ ? [
+ {
+ title: t('insight_board'),
+ dataIndex: 'name',
+ align: 'center',
+ width: '10%',
+ render: function (text, row, index) {
+ return dashboard(text, index, t_month);
+ },
+ },
+ ]
+ : []),
+ // 第四列:影响力
+ {
+ title: t('influence'),
+ dataIndex: 'value',
+ width: '20%',
+ align: 'right',
+ render: (text, row, index) => {
+ return RoundFloat(text);
+ },
+ },
+ // 第五列:影响力变化
+ {
+ title: '',
+ dataIndex: 'valueDelta',
+ width: '10%',
+ align: 'left',
+ render: (text, row, index) => {
+ text = RoundFloat(text);
+ return PointRender(text, row, index);
+ },
+ },
+];
+
+const solveDate = (year, month) => {
+ if (year === null && month === null) {
+ return 'not found';
+ }
+ if (month === null) {
+ return year + '年';
+ }
+ return year + '年' + (month + 1) + '月';
+};
+
+function dashboard(text, index, t_month) {
+ if (index < 300) {
+ let [org_name, repo_name] = text.split('/');
+ const t_month_copy = t_month + ' ' + '00:00:00';
+ let params = {
+ org_name,
+ repo_name,
+ t_month_copy,
+ t_month,
+ };
+ return (
+
+
+
+ );
+ }
+}
+
+function DateTitle(props) {
+ return {solveDate(props.year, props.month)}
;
+}
+
+function MyTable(props) {
+ const [state, setState] = useState({
+ object: 'technology',
+ index: 'open_rank',
+ region: 'global',
+ showDetail: false,
+ hasDetail: true,
+ data: [],
+ showSize: 25,
+ loading: true,
+ url: '', // base + index + object + region + yearmonth + .json
+ base: 'https://oss.x-lab.info/open_leaderboard/',
+ year: null, // 字符串格式
+ month: null, // 整数格式,0表示1月,1表示2月..., null for year type time
+ type: 'month',
+ search: null,
+ category: 'cloud-native',
+ });
+
+ // 请求一次数据更新表格。如果还没读取好配置文件则不请求数据。
+ useEffect(() => {
+ if (props.year == null && props.month == null) {
+ console.log('the first loading');
+ return;
+ }
+ updateDate({
+ year: String(props.year),
+ month: props.month,
+ });
+ }, [props]);
+
+ const expandData = () => {
+ setState({
+ ...state,
+ showSize: state.showSize + 25,
+ });
+ };
+ const updateDate = (newstate) => {
+ console.log('table update', newstate);
+ // 先获取原先的表格属性
+ let {
+ base,
+ object,
+ index,
+ region,
+ month,
+ year,
+ columns,
+ showDetail,
+ hasDetail,
+ type,
+ search,
+ category,
+ } = state;
+ // 然后把表格改为加载中的状态
+ setState({ ...state, ...newstate, loading: true });
+ // 如果 newstate 有对应的属性,则进行更新
+ if (newstate.hasOwnProperty('object')) object = newstate.object;
+ if (newstate.hasOwnProperty('index')) index = newstate.index;
+ if (newstate.hasOwnProperty('region')) region = newstate.region;
+ if (newstate.hasOwnProperty('month')) month = newstate.month;
+ if (newstate.hasOwnProperty('year')) year = newstate.year;
+ if (newstate.hasOwnProperty('showDetail')) showDetail = newstate.showDetail;
+ if (newstate.hasOwnProperty('type')) type = newstate.type;
+ if (newstate.hasOwnProperty('search')) search = newstate.search;
+ if (newstate.hasOwnProperty('category')) category = newstate.category;
+
+ //获取数据大屏的‘t_month’参数
+ let myyear = newstate.year == null ? state.year : newstate.year;
+ let mymonth = newstate.month == null ? state.month : newstate.month;
+
+ mymonth = ('' + (1 + mymonth)).padStart(2, '0');
+ let t_month = `${myyear}-${mymonth}-01`;
+
+ // 根据 index 和 showDetail 改变表格的 columns 格式
+ if (index == 'activity') {
+ columns = activityColumns(object, t_month);
+ hasDetail = true;
+ }
+ if (index == 'activity' && showDetail == true) {
+ columns = activityDetailColumns(object, t_month);
+ hasDetail = true;
+ }
+ if (index == 'open_rank') {
+ columns = open_rankColumns(object, t_month);
+ hasDetail = false;
+ showDetail = false;
+ }
+ // 如果是年份数据,则把 month 置为 null。
+ // TODO:待验证,如果从年份数据切换到月份数据,似乎会自动回到原来 month 值?
+ if (type == 'year') {
+ month = null;
+ }
+ // 以当前的属性构造请求 url
+ let url = base + index + '/' + object + '/' + region + '/';
+ if (month === null) {
+ url += year + '.json';
+ } else {
+ url += year + (1 + month) + '.json';
+ }
+ console.log(url);
+ console.log(region);
+ if (object == "foundation" && region == 'chinese') {
+
+ // 这里可以进行数据请求
+ fetch('./foundationChinese.json')
+ .then(response => {response.json()
+ console.log(response.json);
+ })
+ .then((data) => {
+ data = data.data;
+ let dataSource = [];
+ // 预处理数据,对新上榜单数据进行特殊标记处理
+ data.map((obj) => {
+ obj = expandObject(obj);
+ if (obj.rankDelta == 0 && obj.value == obj.valueDelta) {
+ obj.rankDelta = -10000000;
+ obj.valueDelta = 0;
+ }
+ dataSource.push(obj);
+ });
+ console.log(dataSource);
+
+ //搜索特定数据
+ let queryData;
+ if (search) {
+ queryData = dataSource.filter((dataSource) => {
+ let reg = new RegExp(search.trim(), 'i');
+ return reg.test(dataSource.name);
+ });
+ if (queryData.length == 0) {
+ message.warning(t('no_result'));
+ } else {
+ dataSource = queryData;
+ }
+ }
+
+ // 更新属性和表格数据
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ showDetail: showDetail,
+ hasDetail: hasDetail,
+ data: dataSource,
+ });
+ })
+ .catch((err) => {
+ console.log('hi!' + err);
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ data: [],
+ });
+ });
+
+ }
+ // fetch 异步请求
+ else{fetch(url)
+ .then((res) => {
+ // Todo:最好的情况是在日期选择器中,只显示可以查询的日期,
+ if (res.status == 404) {
+ message.warning(t('no_result'));
+ return '';
+ }
+ return res.json();
+ })
+ .then((data) => {
+ data = data.data;
+ let dataSource = [];
+ // 预处理数据,对新上榜单数据进行特殊标记处理
+ data.map((obj) => {
+ obj = expandObject(obj);
+ if (obj.rankDelta == 0 && obj.value == obj.valueDelta) {
+ obj.rankDelta = -10000000;
+ obj.valueDelta = 0;
+ }
+ dataSource.push(obj);
+ });
+ console.log(dataSource);
+
+ //搜索特定数据
+ let queryData;
+ if (search) {
+ queryData = dataSource.filter((dataSource) => {
+ let reg = new RegExp(search.trim(), 'i');
+ return reg.test(dataSource.name);
+ });
+ if (queryData.length == 0) {
+ message.warning(t('no_result'));
+ } else {
+ dataSource = queryData;
+ }
+ }
+
+ // 更新属性和表格数据
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ showDetail: showDetail,
+ hasDetail: hasDetail,
+ data: dataSource,
+ });
+ })
+ .catch((err) => {
+ console.log('hi!' + err);
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ data: [],
+ });
+ });
+
+
+ };
+ }
+ const {
+ object,
+ index,
+ region,
+ data,
+ columns,
+ loading,
+ showSize,
+ showDetail,
+ hasDetail,
+ month,
+ year,
+ type,
+ category,
+ } = state;
+ return (
+
+
+
+
+ record.rank}
+ dataSource={data.slice(0, Math.min(showSize, data.length))}
+ pagination={false}
+ loading={loading}
+ scroll={{ x: 'max-content' }}
+ />
+
+
+
+
+ {showSize < data.length ? (
+
+ {t('showMore') + '>>'}
+
+ ) : (
+
+ {t('noMore')}
+
+ )}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+}
+
+export default MyTable;
diff --git a/.history/src/components/table_20240728152647.js b/.history/src/components/table_20240728152647.js
new file mode 100644
index 0000000..defa9c4
--- /dev/null
+++ b/.history/src/components/table_20240728152647.js
@@ -0,0 +1,650 @@
+import React, { useState, useEffect } from 'react';
+import { Col, message, Row, Table, Card } from 'antd';
+import MyAvatar from './avatar';
+import 'antd/dist/antd.css';
+import QAmiss from './QA2';
+import TablePanel from './TablePanel';
+import ArrowRender from './arrow';
+import PointRender from './changeNumber';
+import RoundFloat from './resolveFloat';
+import Trophy from './rankTrophy';
+import expandObject from '../util/expandObject';
+import { t } from 'i18next';
+import './table.css';
+import { foundationChineseData } from './data';
+
+const activityColumns = (object, t_month) => [
+ {
+ title: t('rank'),
+ dataIndex: 'rank',
+ width: '5%',
+ align: 'center',
+ render: Trophy,
+ fixed: 'left',
+ },
+ ...(object == 'actor'
+ ? [
+ {
+ title: t('avatar'),
+ dataIndex: 'id',
+ width: '5%',
+ align: 'center',
+ render: MyAvatar,
+ fixed: 'left',
+ },
+ ]
+ : []),
+ {
+ title: '',
+ dataIndex: 'rankDelta',
+ render: ArrowRender,
+ align: 'left',
+ width: '5%',
+ fixed: 'left',
+ },
+ {
+ title: t(object),
+ dataIndex: 'name',
+ align: 'center',
+ width: '20%',
+ render: function (text, row, index) {
+ if (object !== 'company') {
+ return (
+
+ {text}
+
+ );
+ } else {
+ return text;
+ }
+ },
+ },
+ ...(object == 'repo'
+ ? [
+ {
+ title: t('insight_board'),
+ dataIndex: 'name',
+ align: 'center',
+ width: '10%',
+ render: function (text, row, index) {
+ return dashboard(text, index, t_month);
+ },
+ },
+ ]
+ : []),
+ {
+ title: t('activity'),
+ dataIndex: 'value',
+ align: 'right',
+ width: '20%',
+ },
+ {
+ title: '',
+ dataIndex: 'valueDelta',
+ width: '10%',
+ align: 'left',
+ render: PointRender,
+ },
+];
+const activityDetailColumns = (object, t_month) => [
+ {
+ title: t('rank'),
+ dataIndex: 'rank',
+ width: '5%',
+ align: 'center',
+ render: Trophy,
+ fixed: 'left',
+ },
+ ...(object == 'actor'
+ ? [
+ {
+ title: t('avatar'),
+ dataIndex: 'id',
+ width: '5%',
+ align: 'center',
+ render: MyAvatar,
+ fixed: 'left',
+ },
+ ]
+ : []),
+ {
+ title: '',
+ dataIndex: 'rankDelta',
+ render: ArrowRender,
+ align: 'left',
+ width: '5%',
+ fixed: 'left',
+ },
+ {
+ title: t(object),
+ dataIndex: 'name',
+ align: 'center',
+ width: '5%',
+ render: function (text, row, index) {
+ if (object !== 'company') {
+ return (
+
+ {text}
+
+ );
+ } else {
+ return text;
+ }
+ },
+ },
+ ...(object == 'repo'
+ ? [
+ {
+ title: t('insight_board'),
+ dataIndex: 'name',
+ align: 'center',
+ width: '10%',
+ render: function (text, row, index) {
+ return dashboard(text, index, t_month);
+ },
+ },
+ ]
+ : []),
+ {
+ title: t('activity'),
+ dataIndex: 'value',
+ align: 'center',
+ width: '10%',
+ },
+ {
+ title: '',
+ dataIndex: 'valueDelta',
+ width: '10%',
+ align: 'left',
+ render: PointRender,
+ },
+ {
+ title: t('issue_comments'),
+ dataIndex: 'issue_comment',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('open_issues'),
+ dataIndex: 'open_issue',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('open_pulls'),
+ dataIndex: 'open_pull',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('merge_pulls'),
+ dataIndex: 'merged_pull',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('pr_reviews'),
+ dataIndex: 'review_comment',
+ width: '10%',
+ align: 'center',
+ },
+];
+const open_rankColumns = (object, t_month) => [
+ {
+ // 第一列:排名
+ title: t('rank'),
+ dataIndex: 'rank',
+ width: '5%',
+ render: Trophy,
+ align: 'center',
+ fixed: 'left',
+ },
+ // 如果 object 是 'actor',则添加头像列
+ ...(object == 'actor'
+ ? [
+ {
+ title: t('avatar'),
+ dataIndex: 'id',
+ width: '5%',
+ align: 'center',
+ render: MyAvatar,
+ fixed: 'left',
+ },
+ ]
+ : []),
+ // 第二列:排名变化
+ {
+ title: '',
+ dataIndex: 'rankDelta',
+ render: ArrowRender,
+ align: 'left',
+ width: '5%',
+ fixed: 'left',
+ },
+ // 第三列:对象名称(可能是 actor, repo 或 company)
+ {
+ title: t(object),
+ dataIndex: 'name',
+ width: '20%',
+ align: 'center',
+ render: function (text) {
+ if (object !== 'company') {
+ return (
+
+ {text}
+
+ );
+ } else {
+ return text;
+ }
+ },
+ },
+ // 如果 object 是 'repo',则添加 insight_board 列
+ ...(object == 'repo'
+ ? [
+ {
+ title: t('insight_board'),
+ dataIndex: 'name',
+ align: 'center',
+ width: '10%',
+ render: function (text, row, index) {
+ return dashboard(text, index, t_month);
+ },
+ },
+ ]
+ : []),
+ // 第四列:影响力
+ {
+ title: t('influence'),
+ dataIndex: 'value',
+ width: '20%',
+ align: 'right',
+ render: (text, row, index) => {
+ return RoundFloat(text);
+ },
+ },
+ // 第五列:影响力变化
+ {
+ title: '',
+ dataIndex: 'valueDelta',
+ width: '10%',
+ align: 'left',
+ render: (text, row, index) => {
+ text = RoundFloat(text);
+ return PointRender(text, row, index);
+ },
+ },
+];
+
+const solveDate = (year, month) => {
+ if (year === null && month === null) {
+ return 'not found';
+ }
+ if (month === null) {
+ return year + '年';
+ }
+ return year + '年' + (month + 1) + '月';
+};
+
+function dashboard(text, index, t_month) {
+ if (index < 300) {
+ let [org_name, repo_name] = text.split('/');
+ const t_month_copy = t_month + ' ' + '00:00:00';
+ let params = {
+ org_name,
+ repo_name,
+ t_month_copy,
+ t_month,
+ };
+ return (
+
+
+
+ );
+ }
+}
+
+function DateTitle(props) {
+ return {solveDate(props.year, props.month)}
;
+}
+
+function MyTable(props) {
+ const [state, setState] = useState({
+ object: 'technology',
+ index: 'open_rank',
+ region: 'global',
+ showDetail: false,
+ hasDetail: true,
+ data: [],
+ showSize: 25,
+ loading: true,
+ url: '', // base + index + object + region + yearmonth + .json
+ base: 'https://oss.x-lab.info/open_leaderboard/',
+ year: null, // 字符串格式
+ month: null, // 整数格式,0表示1月,1表示2月..., null for year type time
+ type: 'month',
+ search: null,
+ category: 'cloud-native',
+ });
+
+ // 请求一次数据更新表格。如果还没读取好配置文件则不请求数据。
+ useEffect(() => {
+ if (props.year == null && props.month == null) {
+ console.log('the first loading');
+ return;
+ }
+ updateDate({
+ year: String(props.year),
+ month: props.month,
+ });
+ }, [props]);
+
+ const expandData = () => {
+ setState({
+ ...state,
+ showSize: state.showSize + 25,
+ });
+ };
+ const updateDate = (newstate) => {
+ console.log('table update', newstate);
+ // 先获取原先的表格属性
+ let {
+ base,
+ object,
+ index,
+ region,
+ month,
+ year,
+ columns,
+ showDetail,
+ hasDetail,
+ type,
+ search,
+ category,
+ } = state;
+ // 然后把表格改为加载中的状态
+ setState({ ...state, ...newstate, loading: true });
+ // 如果 newstate 有对应的属性,则进行更新
+ if (newstate.hasOwnProperty('object')) object = newstate.object;
+ if (newstate.hasOwnProperty('index')) index = newstate.index;
+ if (newstate.hasOwnProperty('region')) region = newstate.region;
+ if (newstate.hasOwnProperty('month')) month = newstate.month;
+ if (newstate.hasOwnProperty('year')) year = newstate.year;
+ if (newstate.hasOwnProperty('showDetail')) showDetail = newstate.showDetail;
+ if (newstate.hasOwnProperty('type')) type = newstate.type;
+ if (newstate.hasOwnProperty('search')) search = newstate.search;
+ if (newstate.hasOwnProperty('category')) category = newstate.category;
+
+ //获取数据大屏的‘t_month’参数
+ let myyear = newstate.year == null ? state.year : newstate.year;
+ let mymonth = newstate.month == null ? state.month : newstate.month;
+
+ mymonth = ('' + (1 + mymonth)).padStart(2, '0');
+ let t_month = `${myyear}-${mymonth}-01`;
+
+ // 根据 index 和 showDetail 改变表格的 columns 格式
+ if (index == 'activity') {
+ columns = activityColumns(object, t_month);
+ hasDetail = true;
+ }
+ if (index == 'activity' && showDetail == true) {
+ columns = activityDetailColumns(object, t_month);
+ hasDetail = true;
+ }
+ if (index == 'open_rank') {
+ columns = open_rankColumns(object, t_month);
+ hasDetail = false;
+ showDetail = false;
+ }
+ // 如果是年份数据,则把 month 置为 null。
+ // TODO:待验证,如果从年份数据切换到月份数据,似乎会自动回到原来 month 值?
+ if (type == 'year') {
+ month = null;
+ }
+ // 以当前的属性构造请求 url
+ let url = base + index + '/' + object + '/' + region + '/';
+ if (month === null) {
+ url += year + '.json';
+ } else {
+ url += year + (1 + month) + '.json';
+ }
+ console.log(url);
+ console.log(region);
+ if (object == "foundation" && region == 'chinese') {
+
+ // 这里可以进行数据请求
+ fetch('./foundationChinese.json')
+ .then((res) => {
+ // Todo:最好的情况是在日期选择器中,只显示可以查询的日期,
+ if (res.status == 404) {
+ message.warning(t('no_result'));
+ return '';
+ }
+ return res.json();
+ })
+ .then((data) => {
+ data = data.data;
+ let dataSource = [];
+ // 预处理数据,对新上榜单数据进行特殊标记处理
+ data.map((obj) => {
+ obj = expandObject(obj);
+ if (obj.rankDelta == 0 && obj.value == obj.valueDelta) {
+ obj.rankDelta = -10000000;
+ obj.valueDelta = 0;
+ }
+ dataSource.push(obj);
+ });
+ console.log(dataSource);
+
+ //搜索特定数据
+ let queryData;
+ if (search) {
+ queryData = dataSource.filter((dataSource) => {
+ let reg = new RegExp(search.trim(), 'i');
+ return reg.test(dataSource.name);
+ });
+ if (queryData.length == 0) {
+ message.warning(t('no_result'));
+ } else {
+ dataSource = queryData;
+ }
+ }
+
+ // 更新属性和表格数据
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ showDetail: showDetail,
+ hasDetail: hasDetail,
+ data: dataSource,
+ });
+ })
+ .catch((err) => {
+ console.log('hi!' + err);
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ data: [],
+ });
+ });
+
+ }
+ // fetch 异步请求
+ else{fetch(url)
+ .then((res) => {
+ // Todo:最好的情况是在日期选择器中,只显示可以查询的日期,
+ if (res.status == 404) {
+ message.warning(t('no_result'));
+ return '';
+ }
+ return res.json();
+ })
+ .then((data) => {
+ data = data.data;
+ let dataSource = [];
+ // 预处理数据,对新上榜单数据进行特殊标记处理
+ data.map((obj) => {
+ obj = expandObject(obj);
+ if (obj.rankDelta == 0 && obj.value == obj.valueDelta) {
+ obj.rankDelta = -10000000;
+ obj.valueDelta = 0;
+ }
+ dataSource.push(obj);
+ });
+ console.log(dataSource);
+
+ //搜索特定数据
+ let queryData;
+ if (search) {
+ queryData = dataSource.filter((dataSource) => {
+ let reg = new RegExp(search.trim(), 'i');
+ return reg.test(dataSource.name);
+ });
+ if (queryData.length == 0) {
+ message.warning(t('no_result'));
+ } else {
+ dataSource = queryData;
+ }
+ }
+
+ // 更新属性和表格数据
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ showDetail: showDetail,
+ hasDetail: hasDetail,
+ data: dataSource,
+ });
+ })
+ .catch((err) => {
+ console.log('hi!' + err);
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ data: [],
+ });
+ });
+
+
+ };
+ }
+ const {
+ object,
+ index,
+ region,
+ data,
+ columns,
+ loading,
+ showSize,
+ showDetail,
+ hasDetail,
+ month,
+ year,
+ type,
+ category,
+ } = state;
+ return (
+
+
+
+
+ record.rank}
+ dataSource={data.slice(0, Math.min(showSize, data.length))}
+ pagination={false}
+ loading={loading}
+ scroll={{ x: 'max-content' }}
+ />
+
+
+
+
+ {showSize < data.length ? (
+
+ {t('showMore') + '>>'}
+
+ ) : (
+
+ {t('noMore')}
+
+ )}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+}
+
+export default MyTable;
diff --git a/.history/src/components/table_20240728153148.js b/.history/src/components/table_20240728153148.js
new file mode 100644
index 0000000..fb4a8fa
--- /dev/null
+++ b/.history/src/components/table_20240728153148.js
@@ -0,0 +1,650 @@
+import React, { useState, useEffect } from 'react';
+import { Col, message, Row, Table, Card } from 'antd';
+import MyAvatar from './avatar';
+import 'antd/dist/antd.css';
+import QAmiss from './QA2';
+import TablePanel from './TablePanel';
+import ArrowRender from './arrow';
+import PointRender from './changeNumber';
+import RoundFloat from './resolveFloat';
+import Trophy from './rankTrophy';
+import expandObject from '../util/expandObject';
+import { t } from 'i18next';
+import './table.css';
+import { foundationChineseData } from './data';
+
+const activityColumns = (object, t_month) => [
+ {
+ title: t('rank'),
+ dataIndex: 'rank',
+ width: '5%',
+ align: 'center',
+ render: Trophy,
+ fixed: 'left',
+ },
+ ...(object == 'actor'
+ ? [
+ {
+ title: t('avatar'),
+ dataIndex: 'id',
+ width: '5%',
+ align: 'center',
+ render: MyAvatar,
+ fixed: 'left',
+ },
+ ]
+ : []),
+ {
+ title: '',
+ dataIndex: 'rankDelta',
+ render: ArrowRender,
+ align: 'left',
+ width: '5%',
+ fixed: 'left',
+ },
+ {
+ title: t(object),
+ dataIndex: 'name',
+ align: 'center',
+ width: '20%',
+ render: function (text, row, index) {
+ if (object !== 'company') {
+ return (
+
+ {text}
+
+ );
+ } else {
+ return text;
+ }
+ },
+ },
+ ...(object == 'repo'
+ ? [
+ {
+ title: t('insight_board'),
+ dataIndex: 'name',
+ align: 'center',
+ width: '10%',
+ render: function (text, row, index) {
+ return dashboard(text, index, t_month);
+ },
+ },
+ ]
+ : []),
+ {
+ title: t('activity'),
+ dataIndex: 'value',
+ align: 'right',
+ width: '20%',
+ },
+ {
+ title: '',
+ dataIndex: 'valueDelta',
+ width: '10%',
+ align: 'left',
+ render: PointRender,
+ },
+];
+const activityDetailColumns = (object, t_month) => [
+ {
+ title: t('rank'),
+ dataIndex: 'rank',
+ width: '5%',
+ align: 'center',
+ render: Trophy,
+ fixed: 'left',
+ },
+ ...(object == 'actor'
+ ? [
+ {
+ title: t('avatar'),
+ dataIndex: 'id',
+ width: '5%',
+ align: 'center',
+ render: MyAvatar,
+ fixed: 'left',
+ },
+ ]
+ : []),
+ {
+ title: '',
+ dataIndex: 'rankDelta',
+ render: ArrowRender,
+ align: 'left',
+ width: '5%',
+ fixed: 'left',
+ },
+ {
+ title: t(object),
+ dataIndex: 'name',
+ align: 'center',
+ width: '5%',
+ render: function (text, row, index) {
+ if (object !== 'company') {
+ return (
+
+ {text}
+
+ );
+ } else {
+ return text;
+ }
+ },
+ },
+ ...(object == 'repo'
+ ? [
+ {
+ title: t('insight_board'),
+ dataIndex: 'name',
+ align: 'center',
+ width: '10%',
+ render: function (text, row, index) {
+ return dashboard(text, index, t_month);
+ },
+ },
+ ]
+ : []),
+ {
+ title: t('activity'),
+ dataIndex: 'value',
+ align: 'center',
+ width: '10%',
+ },
+ {
+ title: '',
+ dataIndex: 'valueDelta',
+ width: '10%',
+ align: 'left',
+ render: PointRender,
+ },
+ {
+ title: t('issue_comments'),
+ dataIndex: 'issue_comment',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('open_issues'),
+ dataIndex: 'open_issue',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('open_pulls'),
+ dataIndex: 'open_pull',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('merge_pulls'),
+ dataIndex: 'merged_pull',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('pr_reviews'),
+ dataIndex: 'review_comment',
+ width: '10%',
+ align: 'center',
+ },
+];
+const open_rankColumns = (object, t_month) => [
+ {
+ // 第一列:排名
+ title: t('rank'),
+ dataIndex: 'rank',
+ width: '5%',
+ render: Trophy,
+ align: 'center',
+ fixed: 'left',
+ },
+ // 如果 object 是 'actor',则添加头像列
+ ...(object == 'actor'
+ ? [
+ {
+ title: t('avatar'),
+ dataIndex: 'id',
+ width: '5%',
+ align: 'center',
+ render: MyAvatar,
+ fixed: 'left',
+ },
+ ]
+ : []),
+ // 第二列:排名变化
+ {
+ title: '',
+ dataIndex: 'rankDelta',
+ render: ArrowRender,
+ align: 'left',
+ width: '5%',
+ fixed: 'left',
+ },
+ // 第三列:对象名称(可能是 actor, repo 或 company)
+ {
+ title: t(object),
+ dataIndex: 'name',
+ width: '20%',
+ align: 'center',
+ render: function (text) {
+ if (object !== 'company') {
+ return (
+
+ {text}
+
+ );
+ } else {
+ return text;
+ }
+ },
+ },
+ // 如果 object 是 'repo',则添加 insight_board 列
+ ...(object == 'repo'
+ ? [
+ {
+ title: t('insight_board'),
+ dataIndex: 'name',
+ align: 'center',
+ width: '10%',
+ render: function (text, row, index) {
+ return dashboard(text, index, t_month);
+ },
+ },
+ ]
+ : []),
+ // 第四列:影响力
+ {
+ title: t('influence'),
+ dataIndex: 'value',
+ width: '20%',
+ align: 'right',
+ render: (text, row, index) => {
+ return RoundFloat(text);
+ },
+ },
+ // 第五列:影响力变化
+ {
+ title: '',
+ dataIndex: 'valueDelta',
+ width: '10%',
+ align: 'left',
+ render: (text, row, index) => {
+ text = RoundFloat(text);
+ return PointRender(text, row, index);
+ },
+ },
+];
+
+const solveDate = (year, month) => {
+ if (year === null && month === null) {
+ return 'not found';
+ }
+ if (month === null) {
+ return year + '年';
+ }
+ return year + '年' + (month + 1) + '月';
+};
+
+function dashboard(text, index, t_month) {
+ if (index < 300) {
+ let [org_name, repo_name] = text.split('/');
+ const t_month_copy = t_month + ' ' + '00:00:00';
+ let params = {
+ org_name,
+ repo_name,
+ t_month_copy,
+ t_month,
+ };
+ return (
+
+
+
+ );
+ }
+}
+
+function DateTitle(props) {
+ return {solveDate(props.year, props.month)}
;
+}
+
+function MyTable(props) {
+ const [state, setState] = useState({
+ object: 'technology',
+ index: 'open_rank',
+ region: 'global',
+ showDetail: false,
+ hasDetail: true,
+ data: [],
+ showSize: 25,
+ loading: true,
+ url: '', // base + index + object + region + yearmonth + .json
+ base: 'https://oss.x-lab.info/open_leaderboard/',
+ year: null, // 字符串格式
+ month: null, // 整数格式,0表示1月,1表示2月..., null for year type time
+ type: 'month',
+ search: null,
+ category: 'cloud-native',
+ });
+
+ // 请求一次数据更新表格。如果还没读取好配置文件则不请求数据。
+ useEffect(() => {
+ if (props.year == null && props.month == null) {
+ console.log('the first loading');
+ return;
+ }
+ updateDate({
+ year: String(props.year),
+ month: props.month,
+ });
+ }, [props]);
+
+ const expandData = () => {
+ setState({
+ ...state,
+ showSize: state.showSize + 25,
+ });
+ };
+ const updateDate = (newstate) => {
+ console.log('table update', newstate);
+ // 先获取原先的表格属性
+ let {
+ base,
+ object,
+ index,
+ region,
+ month,
+ year,
+ columns,
+ showDetail,
+ hasDetail,
+ type,
+ search,
+ category,
+ } = state;
+ // 然后把表格改为加载中的状态
+ setState({ ...state, ...newstate, loading: true });
+ // 如果 newstate 有对应的属性,则进行更新
+ if (newstate.hasOwnProperty('object')) object = newstate.object;
+ if (newstate.hasOwnProperty('index')) index = newstate.index;
+ if (newstate.hasOwnProperty('region')) region = newstate.region;
+ if (newstate.hasOwnProperty('month')) month = newstate.month;
+ if (newstate.hasOwnProperty('year')) year = newstate.year;
+ if (newstate.hasOwnProperty('showDetail')) showDetail = newstate.showDetail;
+ if (newstate.hasOwnProperty('type')) type = newstate.type;
+ if (newstate.hasOwnProperty('search')) search = newstate.search;
+ if (newstate.hasOwnProperty('category')) category = newstate.category;
+
+ //获取数据大屏的‘t_month’参数
+ let myyear = newstate.year == null ? state.year : newstate.year;
+ let mymonth = newstate.month == null ? state.month : newstate.month;
+
+ mymonth = ('' + (1 + mymonth)).padStart(2, '0');
+ let t_month = `${myyear}-${mymonth}-01`;
+
+ // 根据 index 和 showDetail 改变表格的 columns 格式
+ if (index == 'activity') {
+ columns = activityColumns(object, t_month);
+ hasDetail = true;
+ }
+ if (index == 'activity' && showDetail == true) {
+ columns = activityDetailColumns(object, t_month);
+ hasDetail = true;
+ }
+ if (index == 'open_rank') {
+ columns = open_rankColumns(object, t_month);
+ hasDetail = false;
+ showDetail = false;
+ }
+ // 如果是年份数据,则把 month 置为 null。
+ // TODO:待验证,如果从年份数据切换到月份数据,似乎会自动回到原来 month 值?
+ if (type == 'year') {
+ month = null;
+ }
+ // 以当前的属性构造请求 url
+ let url = base + index + '/' + object + '/' + region + '/';
+ if (month === null) {
+ url += year + '.json';
+ } else {
+ url += year + (1 + month) + '.json';
+ }
+ console.log(url);
+ console.log(region);
+ if (object == "foundation" && region == 'chinese') {
+ url = './'+ object + region +'.json'
+ // 这里可以进行数据请求
+ fetch(url)
+ .then((res) => {
+ // Todo:最好的情况是在日期选择器中,只显示可以查询的日期,
+ if (res.status == 404) {
+ message.warning(t('no_result'));
+ return '';
+ }
+ return res.json();
+ })
+ .then((data) => {
+ data = data.data;
+ let dataSource = [];
+ // 预处理数据,对新上榜单数据进行特殊标记处理
+ data.map((obj) => {
+ obj = expandObject(obj);
+ if (obj.rankDelta == 0 && obj.value == obj.valueDelta) {
+ obj.rankDelta = -10000000;
+ obj.valueDelta = 0;
+ }
+ dataSource.push(obj);
+ });
+ console.log(dataSource);
+
+ //搜索特定数据
+ let queryData;
+ if (search) {
+ queryData = dataSource.filter((dataSource) => {
+ let reg = new RegExp(search.trim(), 'i');
+ return reg.test(dataSource.name);
+ });
+ if (queryData.length == 0) {
+ message.warning(t('no_result'));
+ } else {
+ dataSource = queryData;
+ }
+ }
+
+ // 更新属性和表格数据
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ showDetail: showDetail,
+ hasDetail: hasDetail,
+ data: dataSource,
+ });
+ })
+ .catch((err) => {
+ console.log('hi!' + err);
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ data: [],
+ });
+ });
+
+ }
+ // fetch 异步请求
+ else{fetch(url)
+ .then((res) => {
+ // Todo:最好的情况是在日期选择器中,只显示可以查询的日期,
+ if (res.status == 404) {
+ message.warning(t('no_result'));
+ return '';
+ }
+ return res.json();
+ })
+ .then((data) => {
+ data = data.data;
+ let dataSource = [];
+ // 预处理数据,对新上榜单数据进行特殊标记处理
+ data.map((obj) => {
+ obj = expandObject(obj);
+ if (obj.rankDelta == 0 && obj.value == obj.valueDelta) {
+ obj.rankDelta = -10000000;
+ obj.valueDelta = 0;
+ }
+ dataSource.push(obj);
+ });
+ console.log(dataSource);
+
+ //搜索特定数据
+ let queryData;
+ if (search) {
+ queryData = dataSource.filter((dataSource) => {
+ let reg = new RegExp(search.trim(), 'i');
+ return reg.test(dataSource.name);
+ });
+ if (queryData.length == 0) {
+ message.warning(t('no_result'));
+ } else {
+ dataSource = queryData;
+ }
+ }
+
+ // 更新属性和表格数据
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ showDetail: showDetail,
+ hasDetail: hasDetail,
+ data: dataSource,
+ });
+ })
+ .catch((err) => {
+ console.log('hi!' + err);
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ data: [],
+ });
+ });
+
+
+ };
+ }
+ const {
+ object,
+ index,
+ region,
+ data,
+ columns,
+ loading,
+ showSize,
+ showDetail,
+ hasDetail,
+ month,
+ year,
+ type,
+ category,
+ } = state;
+ return (
+
+
+
+
+ record.rank}
+ dataSource={data.slice(0, Math.min(showSize, data.length))}
+ pagination={false}
+ loading={loading}
+ scroll={{ x: 'max-content' }}
+ />
+
+
+
+
+ {showSize < data.length ? (
+
+ {t('showMore') + '>>'}
+
+ ) : (
+
+ {t('noMore')}
+
+ )}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+}
+
+export default MyTable;
diff --git a/.history/src/components/table_20240728153150.js b/.history/src/components/table_20240728153150.js
new file mode 100644
index 0000000..fb4a8fa
--- /dev/null
+++ b/.history/src/components/table_20240728153150.js
@@ -0,0 +1,650 @@
+import React, { useState, useEffect } from 'react';
+import { Col, message, Row, Table, Card } from 'antd';
+import MyAvatar from './avatar';
+import 'antd/dist/antd.css';
+import QAmiss from './QA2';
+import TablePanel from './TablePanel';
+import ArrowRender from './arrow';
+import PointRender from './changeNumber';
+import RoundFloat from './resolveFloat';
+import Trophy from './rankTrophy';
+import expandObject from '../util/expandObject';
+import { t } from 'i18next';
+import './table.css';
+import { foundationChineseData } from './data';
+
+const activityColumns = (object, t_month) => [
+ {
+ title: t('rank'),
+ dataIndex: 'rank',
+ width: '5%',
+ align: 'center',
+ render: Trophy,
+ fixed: 'left',
+ },
+ ...(object == 'actor'
+ ? [
+ {
+ title: t('avatar'),
+ dataIndex: 'id',
+ width: '5%',
+ align: 'center',
+ render: MyAvatar,
+ fixed: 'left',
+ },
+ ]
+ : []),
+ {
+ title: '',
+ dataIndex: 'rankDelta',
+ render: ArrowRender,
+ align: 'left',
+ width: '5%',
+ fixed: 'left',
+ },
+ {
+ title: t(object),
+ dataIndex: 'name',
+ align: 'center',
+ width: '20%',
+ render: function (text, row, index) {
+ if (object !== 'company') {
+ return (
+
+ {text}
+
+ );
+ } else {
+ return text;
+ }
+ },
+ },
+ ...(object == 'repo'
+ ? [
+ {
+ title: t('insight_board'),
+ dataIndex: 'name',
+ align: 'center',
+ width: '10%',
+ render: function (text, row, index) {
+ return dashboard(text, index, t_month);
+ },
+ },
+ ]
+ : []),
+ {
+ title: t('activity'),
+ dataIndex: 'value',
+ align: 'right',
+ width: '20%',
+ },
+ {
+ title: '',
+ dataIndex: 'valueDelta',
+ width: '10%',
+ align: 'left',
+ render: PointRender,
+ },
+];
+const activityDetailColumns = (object, t_month) => [
+ {
+ title: t('rank'),
+ dataIndex: 'rank',
+ width: '5%',
+ align: 'center',
+ render: Trophy,
+ fixed: 'left',
+ },
+ ...(object == 'actor'
+ ? [
+ {
+ title: t('avatar'),
+ dataIndex: 'id',
+ width: '5%',
+ align: 'center',
+ render: MyAvatar,
+ fixed: 'left',
+ },
+ ]
+ : []),
+ {
+ title: '',
+ dataIndex: 'rankDelta',
+ render: ArrowRender,
+ align: 'left',
+ width: '5%',
+ fixed: 'left',
+ },
+ {
+ title: t(object),
+ dataIndex: 'name',
+ align: 'center',
+ width: '5%',
+ render: function (text, row, index) {
+ if (object !== 'company') {
+ return (
+
+ {text}
+
+ );
+ } else {
+ return text;
+ }
+ },
+ },
+ ...(object == 'repo'
+ ? [
+ {
+ title: t('insight_board'),
+ dataIndex: 'name',
+ align: 'center',
+ width: '10%',
+ render: function (text, row, index) {
+ return dashboard(text, index, t_month);
+ },
+ },
+ ]
+ : []),
+ {
+ title: t('activity'),
+ dataIndex: 'value',
+ align: 'center',
+ width: '10%',
+ },
+ {
+ title: '',
+ dataIndex: 'valueDelta',
+ width: '10%',
+ align: 'left',
+ render: PointRender,
+ },
+ {
+ title: t('issue_comments'),
+ dataIndex: 'issue_comment',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('open_issues'),
+ dataIndex: 'open_issue',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('open_pulls'),
+ dataIndex: 'open_pull',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('merge_pulls'),
+ dataIndex: 'merged_pull',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('pr_reviews'),
+ dataIndex: 'review_comment',
+ width: '10%',
+ align: 'center',
+ },
+];
+const open_rankColumns = (object, t_month) => [
+ {
+ // 第一列:排名
+ title: t('rank'),
+ dataIndex: 'rank',
+ width: '5%',
+ render: Trophy,
+ align: 'center',
+ fixed: 'left',
+ },
+ // 如果 object 是 'actor',则添加头像列
+ ...(object == 'actor'
+ ? [
+ {
+ title: t('avatar'),
+ dataIndex: 'id',
+ width: '5%',
+ align: 'center',
+ render: MyAvatar,
+ fixed: 'left',
+ },
+ ]
+ : []),
+ // 第二列:排名变化
+ {
+ title: '',
+ dataIndex: 'rankDelta',
+ render: ArrowRender,
+ align: 'left',
+ width: '5%',
+ fixed: 'left',
+ },
+ // 第三列:对象名称(可能是 actor, repo 或 company)
+ {
+ title: t(object),
+ dataIndex: 'name',
+ width: '20%',
+ align: 'center',
+ render: function (text) {
+ if (object !== 'company') {
+ return (
+
+ {text}
+
+ );
+ } else {
+ return text;
+ }
+ },
+ },
+ // 如果 object 是 'repo',则添加 insight_board 列
+ ...(object == 'repo'
+ ? [
+ {
+ title: t('insight_board'),
+ dataIndex: 'name',
+ align: 'center',
+ width: '10%',
+ render: function (text, row, index) {
+ return dashboard(text, index, t_month);
+ },
+ },
+ ]
+ : []),
+ // 第四列:影响力
+ {
+ title: t('influence'),
+ dataIndex: 'value',
+ width: '20%',
+ align: 'right',
+ render: (text, row, index) => {
+ return RoundFloat(text);
+ },
+ },
+ // 第五列:影响力变化
+ {
+ title: '',
+ dataIndex: 'valueDelta',
+ width: '10%',
+ align: 'left',
+ render: (text, row, index) => {
+ text = RoundFloat(text);
+ return PointRender(text, row, index);
+ },
+ },
+];
+
+const solveDate = (year, month) => {
+ if (year === null && month === null) {
+ return 'not found';
+ }
+ if (month === null) {
+ return year + '年';
+ }
+ return year + '年' + (month + 1) + '月';
+};
+
+function dashboard(text, index, t_month) {
+ if (index < 300) {
+ let [org_name, repo_name] = text.split('/');
+ const t_month_copy = t_month + ' ' + '00:00:00';
+ let params = {
+ org_name,
+ repo_name,
+ t_month_copy,
+ t_month,
+ };
+ return (
+
+
+
+ );
+ }
+}
+
+function DateTitle(props) {
+ return {solveDate(props.year, props.month)}
;
+}
+
+function MyTable(props) {
+ const [state, setState] = useState({
+ object: 'technology',
+ index: 'open_rank',
+ region: 'global',
+ showDetail: false,
+ hasDetail: true,
+ data: [],
+ showSize: 25,
+ loading: true,
+ url: '', // base + index + object + region + yearmonth + .json
+ base: 'https://oss.x-lab.info/open_leaderboard/',
+ year: null, // 字符串格式
+ month: null, // 整数格式,0表示1月,1表示2月..., null for year type time
+ type: 'month',
+ search: null,
+ category: 'cloud-native',
+ });
+
+ // 请求一次数据更新表格。如果还没读取好配置文件则不请求数据。
+ useEffect(() => {
+ if (props.year == null && props.month == null) {
+ console.log('the first loading');
+ return;
+ }
+ updateDate({
+ year: String(props.year),
+ month: props.month,
+ });
+ }, [props]);
+
+ const expandData = () => {
+ setState({
+ ...state,
+ showSize: state.showSize + 25,
+ });
+ };
+ const updateDate = (newstate) => {
+ console.log('table update', newstate);
+ // 先获取原先的表格属性
+ let {
+ base,
+ object,
+ index,
+ region,
+ month,
+ year,
+ columns,
+ showDetail,
+ hasDetail,
+ type,
+ search,
+ category,
+ } = state;
+ // 然后把表格改为加载中的状态
+ setState({ ...state, ...newstate, loading: true });
+ // 如果 newstate 有对应的属性,则进行更新
+ if (newstate.hasOwnProperty('object')) object = newstate.object;
+ if (newstate.hasOwnProperty('index')) index = newstate.index;
+ if (newstate.hasOwnProperty('region')) region = newstate.region;
+ if (newstate.hasOwnProperty('month')) month = newstate.month;
+ if (newstate.hasOwnProperty('year')) year = newstate.year;
+ if (newstate.hasOwnProperty('showDetail')) showDetail = newstate.showDetail;
+ if (newstate.hasOwnProperty('type')) type = newstate.type;
+ if (newstate.hasOwnProperty('search')) search = newstate.search;
+ if (newstate.hasOwnProperty('category')) category = newstate.category;
+
+ //获取数据大屏的‘t_month’参数
+ let myyear = newstate.year == null ? state.year : newstate.year;
+ let mymonth = newstate.month == null ? state.month : newstate.month;
+
+ mymonth = ('' + (1 + mymonth)).padStart(2, '0');
+ let t_month = `${myyear}-${mymonth}-01`;
+
+ // 根据 index 和 showDetail 改变表格的 columns 格式
+ if (index == 'activity') {
+ columns = activityColumns(object, t_month);
+ hasDetail = true;
+ }
+ if (index == 'activity' && showDetail == true) {
+ columns = activityDetailColumns(object, t_month);
+ hasDetail = true;
+ }
+ if (index == 'open_rank') {
+ columns = open_rankColumns(object, t_month);
+ hasDetail = false;
+ showDetail = false;
+ }
+ // 如果是年份数据,则把 month 置为 null。
+ // TODO:待验证,如果从年份数据切换到月份数据,似乎会自动回到原来 month 值?
+ if (type == 'year') {
+ month = null;
+ }
+ // 以当前的属性构造请求 url
+ let url = base + index + '/' + object + '/' + region + '/';
+ if (month === null) {
+ url += year + '.json';
+ } else {
+ url += year + (1 + month) + '.json';
+ }
+ console.log(url);
+ console.log(region);
+ if (object == "foundation" && region == 'chinese') {
+ url = './'+ object + region +'.json'
+ // 这里可以进行数据请求
+ fetch(url)
+ .then((res) => {
+ // Todo:最好的情况是在日期选择器中,只显示可以查询的日期,
+ if (res.status == 404) {
+ message.warning(t('no_result'));
+ return '';
+ }
+ return res.json();
+ })
+ .then((data) => {
+ data = data.data;
+ let dataSource = [];
+ // 预处理数据,对新上榜单数据进行特殊标记处理
+ data.map((obj) => {
+ obj = expandObject(obj);
+ if (obj.rankDelta == 0 && obj.value == obj.valueDelta) {
+ obj.rankDelta = -10000000;
+ obj.valueDelta = 0;
+ }
+ dataSource.push(obj);
+ });
+ console.log(dataSource);
+
+ //搜索特定数据
+ let queryData;
+ if (search) {
+ queryData = dataSource.filter((dataSource) => {
+ let reg = new RegExp(search.trim(), 'i');
+ return reg.test(dataSource.name);
+ });
+ if (queryData.length == 0) {
+ message.warning(t('no_result'));
+ } else {
+ dataSource = queryData;
+ }
+ }
+
+ // 更新属性和表格数据
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ showDetail: showDetail,
+ hasDetail: hasDetail,
+ data: dataSource,
+ });
+ })
+ .catch((err) => {
+ console.log('hi!' + err);
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ data: [],
+ });
+ });
+
+ }
+ // fetch 异步请求
+ else{fetch(url)
+ .then((res) => {
+ // Todo:最好的情况是在日期选择器中,只显示可以查询的日期,
+ if (res.status == 404) {
+ message.warning(t('no_result'));
+ return '';
+ }
+ return res.json();
+ })
+ .then((data) => {
+ data = data.data;
+ let dataSource = [];
+ // 预处理数据,对新上榜单数据进行特殊标记处理
+ data.map((obj) => {
+ obj = expandObject(obj);
+ if (obj.rankDelta == 0 && obj.value == obj.valueDelta) {
+ obj.rankDelta = -10000000;
+ obj.valueDelta = 0;
+ }
+ dataSource.push(obj);
+ });
+ console.log(dataSource);
+
+ //搜索特定数据
+ let queryData;
+ if (search) {
+ queryData = dataSource.filter((dataSource) => {
+ let reg = new RegExp(search.trim(), 'i');
+ return reg.test(dataSource.name);
+ });
+ if (queryData.length == 0) {
+ message.warning(t('no_result'));
+ } else {
+ dataSource = queryData;
+ }
+ }
+
+ // 更新属性和表格数据
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ showDetail: showDetail,
+ hasDetail: hasDetail,
+ data: dataSource,
+ });
+ })
+ .catch((err) => {
+ console.log('hi!' + err);
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ data: [],
+ });
+ });
+
+
+ };
+ }
+ const {
+ object,
+ index,
+ region,
+ data,
+ columns,
+ loading,
+ showSize,
+ showDetail,
+ hasDetail,
+ month,
+ year,
+ type,
+ category,
+ } = state;
+ return (
+
+
+
+
+ record.rank}
+ dataSource={data.slice(0, Math.min(showSize, data.length))}
+ pagination={false}
+ loading={loading}
+ scroll={{ x: 'max-content' }}
+ />
+
+
+
+
+ {showSize < data.length ? (
+
+ {t('showMore') + '>>'}
+
+ ) : (
+
+ {t('noMore')}
+
+ )}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+}
+
+export default MyTable;
diff --git a/.history/src/components/table_20240728153730.js b/.history/src/components/table_20240728153730.js
new file mode 100644
index 0000000..690efe4
--- /dev/null
+++ b/.history/src/components/table_20240728153730.js
@@ -0,0 +1,594 @@
+import React, { useState, useEffect } from 'react';
+import { Col, message, Row, Table, Card } from 'antd';
+import MyAvatar from './avatar';
+import 'antd/dist/antd.css';
+import QAmiss from './QA2';
+import TablePanel from './TablePanel';
+import ArrowRender from './arrow';
+import PointRender from './changeNumber';
+import RoundFloat from './resolveFloat';
+import Trophy from './rankTrophy';
+import expandObject from '../util/expandObject';
+import { t } from 'i18next';
+import './table.css';
+import { foundationChineseData } from './data';
+
+const activityColumns = (object, t_month) => [
+ {
+ title: t('rank'),
+ dataIndex: 'rank',
+ width: '5%',
+ align: 'center',
+ render: Trophy,
+ fixed: 'left',
+ },
+ ...(object == 'actor'
+ ? [
+ {
+ title: t('avatar'),
+ dataIndex: 'id',
+ width: '5%',
+ align: 'center',
+ render: MyAvatar,
+ fixed: 'left',
+ },
+ ]
+ : []),
+ {
+ title: '',
+ dataIndex: 'rankDelta',
+ render: ArrowRender,
+ align: 'left',
+ width: '5%',
+ fixed: 'left',
+ },
+ {
+ title: t(object),
+ dataIndex: 'name',
+ align: 'center',
+ width: '20%',
+ render: function (text, row, index) {
+ if (object !== 'company') {
+ return (
+
+ {text}
+
+ );
+ } else {
+ return text;
+ }
+ },
+ },
+ ...(object == 'repo'
+ ? [
+ {
+ title: t('insight_board'),
+ dataIndex: 'name',
+ align: 'center',
+ width: '10%',
+ render: function (text, row, index) {
+ return dashboard(text, index, t_month);
+ },
+ },
+ ]
+ : []),
+ {
+ title: t('activity'),
+ dataIndex: 'value',
+ align: 'right',
+ width: '20%',
+ },
+ {
+ title: '',
+ dataIndex: 'valueDelta',
+ width: '10%',
+ align: 'left',
+ render: PointRender,
+ },
+];
+const activityDetailColumns = (object, t_month) => [
+ {
+ title: t('rank'),
+ dataIndex: 'rank',
+ width: '5%',
+ align: 'center',
+ render: Trophy,
+ fixed: 'left',
+ },
+ ...(object == 'actor'
+ ? [
+ {
+ title: t('avatar'),
+ dataIndex: 'id',
+ width: '5%',
+ align: 'center',
+ render: MyAvatar,
+ fixed: 'left',
+ },
+ ]
+ : []),
+ {
+ title: '',
+ dataIndex: 'rankDelta',
+ render: ArrowRender,
+ align: 'left',
+ width: '5%',
+ fixed: 'left',
+ },
+ {
+ title: t(object),
+ dataIndex: 'name',
+ align: 'center',
+ width: '5%',
+ render: function (text, row, index) {
+ if (object !== 'company') {
+ return (
+
+ {text}
+
+ );
+ } else {
+ return text;
+ }
+ },
+ },
+ ...(object == 'repo'
+ ? [
+ {
+ title: t('insight_board'),
+ dataIndex: 'name',
+ align: 'center',
+ width: '10%',
+ render: function (text, row, index) {
+ return dashboard(text, index, t_month);
+ },
+ },
+ ]
+ : []),
+ {
+ title: t('activity'),
+ dataIndex: 'value',
+ align: 'center',
+ width: '10%',
+ },
+ {
+ title: '',
+ dataIndex: 'valueDelta',
+ width: '10%',
+ align: 'left',
+ render: PointRender,
+ },
+ {
+ title: t('issue_comments'),
+ dataIndex: 'issue_comment',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('open_issues'),
+ dataIndex: 'open_issue',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('open_pulls'),
+ dataIndex: 'open_pull',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('merge_pulls'),
+ dataIndex: 'merged_pull',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('pr_reviews'),
+ dataIndex: 'review_comment',
+ width: '10%',
+ align: 'center',
+ },
+];
+const open_rankColumns = (object, t_month) => [
+ {
+ // 第一列:排名
+ title: t('rank'),
+ dataIndex: 'rank',
+ width: '5%',
+ render: Trophy,
+ align: 'center',
+ fixed: 'left',
+ },
+ // 如果 object 是 'actor',则添加头像列
+ ...(object == 'actor'
+ ? [
+ {
+ title: t('avatar'),
+ dataIndex: 'id',
+ width: '5%',
+ align: 'center',
+ render: MyAvatar,
+ fixed: 'left',
+ },
+ ]
+ : []),
+ // 第二列:排名变化
+ {
+ title: '',
+ dataIndex: 'rankDelta',
+ render: ArrowRender,
+ align: 'left',
+ width: '5%',
+ fixed: 'left',
+ },
+ // 第三列:对象名称(可能是 actor, repo 或 company)
+ {
+ title: t(object),
+ dataIndex: 'name',
+ width: '20%',
+ align: 'center',
+ render: function (text) {
+ if (object !== 'company') {
+ return (
+
+ {text}
+
+ );
+ } else {
+ return text;
+ }
+ },
+ },
+ // 如果 object 是 'repo',则添加 insight_board 列
+ ...(object == 'repo'
+ ? [
+ {
+ title: t('insight_board'),
+ dataIndex: 'name',
+ align: 'center',
+ width: '10%',
+ render: function (text, row, index) {
+ return dashboard(text, index, t_month);
+ },
+ },
+ ]
+ : []),
+ // 第四列:影响力
+ {
+ title: t('influence'),
+ dataIndex: 'value',
+ width: '20%',
+ align: 'right',
+ render: (text, row, index) => {
+ return RoundFloat(text);
+ },
+ },
+ // 第五列:影响力变化
+ {
+ title: '',
+ dataIndex: 'valueDelta',
+ width: '10%',
+ align: 'left',
+ render: (text, row, index) => {
+ text = RoundFloat(text);
+ return PointRender(text, row, index);
+ },
+ },
+];
+
+const solveDate = (year, month) => {
+ if (year === null && month === null) {
+ return 'not found';
+ }
+ if (month === null) {
+ return year + '年';
+ }
+ return year + '年' + (month + 1) + '月';
+};
+
+function dashboard(text, index, t_month) {
+ if (index < 300) {
+ let [org_name, repo_name] = text.split('/');
+ const t_month_copy = t_month + ' ' + '00:00:00';
+ let params = {
+ org_name,
+ repo_name,
+ t_month_copy,
+ t_month,
+ };
+ return (
+
+
+
+ );
+ }
+}
+
+function DateTitle(props) {
+ return {solveDate(props.year, props.month)}
;
+}
+
+function MyTable(props) {
+ const [state, setState] = useState({
+ object: 'technology',
+ index: 'open_rank',
+ region: 'global',
+ showDetail: false,
+ hasDetail: true,
+ data: [],
+ showSize: 25,
+ loading: true,
+ url: '', // base + index + object + region + yearmonth + .json
+ base: 'https://oss.x-lab.info/open_leaderboard/',
+ year: null, // 字符串格式
+ month: null, // 整数格式,0表示1月,1表示2月..., null for year type time
+ type: 'month',
+ search: null,
+ category: 'cloud-native',
+ });
+
+ // 请求一次数据更新表格。如果还没读取好配置文件则不请求数据。
+ useEffect(() => {
+ if (props.year == null && props.month == null) {
+ console.log('the first loading');
+ return;
+ }
+ updateDate({
+ year: String(props.year),
+ month: props.month,
+ });
+ }, [props]);
+
+ const expandData = () => {
+ setState({
+ ...state,
+ showSize: state.showSize + 25,
+ });
+ };
+ const updateDate = (newstate) => {
+ console.log('table update', newstate);
+ // 先获取原先的表格属性
+ let {
+ base,
+ object,
+ index,
+ region,
+ month,
+ year,
+ columns,
+ showDetail,
+ hasDetail,
+ type,
+ search,
+ category,
+ } = state;
+ // 然后把表格改为加载中的状态
+ setState({ ...state, ...newstate, loading: true });
+ // 如果 newstate 有对应的属性,则进行更新
+ if (newstate.hasOwnProperty('object')) object = newstate.object;
+ if (newstate.hasOwnProperty('index')) index = newstate.index;
+ if (newstate.hasOwnProperty('region')) region = newstate.region;
+ if (newstate.hasOwnProperty('month')) month = newstate.month;
+ if (newstate.hasOwnProperty('year')) year = newstate.year;
+ if (newstate.hasOwnProperty('showDetail')) showDetail = newstate.showDetail;
+ if (newstate.hasOwnProperty('type')) type = newstate.type;
+ if (newstate.hasOwnProperty('search')) search = newstate.search;
+ if (newstate.hasOwnProperty('category')) category = newstate.category;
+
+ //获取数据大屏的‘t_month’参数
+ let myyear = newstate.year == null ? state.year : newstate.year;
+ let mymonth = newstate.month == null ? state.month : newstate.month;
+
+ mymonth = ('' + (1 + mymonth)).padStart(2, '0');
+ let t_month = `${myyear}-${mymonth}-01`;
+
+ // 根据 index 和 showDetail 改变表格的 columns 格式
+ if (index == 'activity') {
+ columns = activityColumns(object, t_month);
+ hasDetail = true;
+ }
+ if (index == 'activity' && showDetail == true) {
+ columns = activityDetailColumns(object, t_month);
+ hasDetail = true;
+ }
+ if (index == 'open_rank') {
+ columns = open_rankColumns(object, t_month);
+ hasDetail = false;
+ showDetail = false;
+ }
+ // 如果是年份数据,则把 month 置为 null。
+ // TODO:待验证,如果从年份数据切换到月份数据,似乎会自动回到原来 month 值?
+ if (type == 'year') {
+ month = null;
+ }
+ // 以当前的属性构造请求 url
+ let url = base + index + '/' + object + '/' + region + '/';
+ if (month === null) {
+ url += year + '.json';
+ } else {
+ url += year + (1 + month) + '.json';
+ }
+ console.log(url);
+ console.log(region);
+ if (object == "foundation") {
+ url = './'+ object + region +'.json'
+ }
+ else if (object == "technology") {
+ url = './'+ object + category +'.json'
+ }
+
+ // fetch 异步请求
+ fetch(url)
+ .then((res) => {
+ // Todo:最好的情况是在日期选择器中,只显示可以查询的日期,
+ if (res.status == 404) {
+ message.warning(t('no_result'));
+ return '';
+ }
+ return res.json();
+ })
+ .then((data) => {
+ data = data.data;
+ let dataSource = [];
+ // 预处理数据,对新上榜单数据进行特殊标记处理
+ data.map((obj) => {
+ obj = expandObject(obj);
+ if (obj.rankDelta == 0 && obj.value == obj.valueDelta) {
+ obj.rankDelta = -10000000;
+ obj.valueDelta = 0;
+ }
+ dataSource.push(obj);
+ });
+ console.log(dataSource);
+
+ //搜索特定数据
+ let queryData;
+ if (search) {
+ queryData = dataSource.filter((dataSource) => {
+ let reg = new RegExp(search.trim(), 'i');
+ return reg.test(dataSource.name);
+ });
+ if (queryData.length == 0) {
+ message.warning(t('no_result'));
+ } else {
+ dataSource = queryData;
+ }
+ }
+
+ // 更新属性和表格数据
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ showDetail: showDetail,
+ hasDetail: hasDetail,
+ data: dataSource,
+ });
+ })
+ .catch((err) => {
+ console.log('hi!' + err);
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ data: [],
+ });
+ });
+
+
+ };
+
+ const {
+ object,
+ index,
+ region,
+ data,
+ columns,
+ loading,
+ showSize,
+ showDetail,
+ hasDetail,
+ month,
+ year,
+ type,
+ category,
+ } = state;
+ return (
+
+
+
+
+ record.rank}
+ dataSource={data.slice(0, Math.min(showSize, data.length))}
+ pagination={false}
+ loading={loading}
+ scroll={{ x: 'max-content' }}
+ />
+
+
+
+
+ {showSize < data.length ? (
+
+ {t('showMore') + '>>'}
+
+ ) : (
+
+ {t('noMore')}
+
+ )}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+}
+
+export default MyTable;
diff --git a/.history/src/components/table_20240728171435.js b/.history/src/components/table_20240728171435.js
new file mode 100644
index 0000000..690efe4
--- /dev/null
+++ b/.history/src/components/table_20240728171435.js
@@ -0,0 +1,594 @@
+import React, { useState, useEffect } from 'react';
+import { Col, message, Row, Table, Card } from 'antd';
+import MyAvatar from './avatar';
+import 'antd/dist/antd.css';
+import QAmiss from './QA2';
+import TablePanel from './TablePanel';
+import ArrowRender from './arrow';
+import PointRender from './changeNumber';
+import RoundFloat from './resolveFloat';
+import Trophy from './rankTrophy';
+import expandObject from '../util/expandObject';
+import { t } from 'i18next';
+import './table.css';
+import { foundationChineseData } from './data';
+
+const activityColumns = (object, t_month) => [
+ {
+ title: t('rank'),
+ dataIndex: 'rank',
+ width: '5%',
+ align: 'center',
+ render: Trophy,
+ fixed: 'left',
+ },
+ ...(object == 'actor'
+ ? [
+ {
+ title: t('avatar'),
+ dataIndex: 'id',
+ width: '5%',
+ align: 'center',
+ render: MyAvatar,
+ fixed: 'left',
+ },
+ ]
+ : []),
+ {
+ title: '',
+ dataIndex: 'rankDelta',
+ render: ArrowRender,
+ align: 'left',
+ width: '5%',
+ fixed: 'left',
+ },
+ {
+ title: t(object),
+ dataIndex: 'name',
+ align: 'center',
+ width: '20%',
+ render: function (text, row, index) {
+ if (object !== 'company') {
+ return (
+
+ {text}
+
+ );
+ } else {
+ return text;
+ }
+ },
+ },
+ ...(object == 'repo'
+ ? [
+ {
+ title: t('insight_board'),
+ dataIndex: 'name',
+ align: 'center',
+ width: '10%',
+ render: function (text, row, index) {
+ return dashboard(text, index, t_month);
+ },
+ },
+ ]
+ : []),
+ {
+ title: t('activity'),
+ dataIndex: 'value',
+ align: 'right',
+ width: '20%',
+ },
+ {
+ title: '',
+ dataIndex: 'valueDelta',
+ width: '10%',
+ align: 'left',
+ render: PointRender,
+ },
+];
+const activityDetailColumns = (object, t_month) => [
+ {
+ title: t('rank'),
+ dataIndex: 'rank',
+ width: '5%',
+ align: 'center',
+ render: Trophy,
+ fixed: 'left',
+ },
+ ...(object == 'actor'
+ ? [
+ {
+ title: t('avatar'),
+ dataIndex: 'id',
+ width: '5%',
+ align: 'center',
+ render: MyAvatar,
+ fixed: 'left',
+ },
+ ]
+ : []),
+ {
+ title: '',
+ dataIndex: 'rankDelta',
+ render: ArrowRender,
+ align: 'left',
+ width: '5%',
+ fixed: 'left',
+ },
+ {
+ title: t(object),
+ dataIndex: 'name',
+ align: 'center',
+ width: '5%',
+ render: function (text, row, index) {
+ if (object !== 'company') {
+ return (
+
+ {text}
+
+ );
+ } else {
+ return text;
+ }
+ },
+ },
+ ...(object == 'repo'
+ ? [
+ {
+ title: t('insight_board'),
+ dataIndex: 'name',
+ align: 'center',
+ width: '10%',
+ render: function (text, row, index) {
+ return dashboard(text, index, t_month);
+ },
+ },
+ ]
+ : []),
+ {
+ title: t('activity'),
+ dataIndex: 'value',
+ align: 'center',
+ width: '10%',
+ },
+ {
+ title: '',
+ dataIndex: 'valueDelta',
+ width: '10%',
+ align: 'left',
+ render: PointRender,
+ },
+ {
+ title: t('issue_comments'),
+ dataIndex: 'issue_comment',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('open_issues'),
+ dataIndex: 'open_issue',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('open_pulls'),
+ dataIndex: 'open_pull',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('merge_pulls'),
+ dataIndex: 'merged_pull',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('pr_reviews'),
+ dataIndex: 'review_comment',
+ width: '10%',
+ align: 'center',
+ },
+];
+const open_rankColumns = (object, t_month) => [
+ {
+ // 第一列:排名
+ title: t('rank'),
+ dataIndex: 'rank',
+ width: '5%',
+ render: Trophy,
+ align: 'center',
+ fixed: 'left',
+ },
+ // 如果 object 是 'actor',则添加头像列
+ ...(object == 'actor'
+ ? [
+ {
+ title: t('avatar'),
+ dataIndex: 'id',
+ width: '5%',
+ align: 'center',
+ render: MyAvatar,
+ fixed: 'left',
+ },
+ ]
+ : []),
+ // 第二列:排名变化
+ {
+ title: '',
+ dataIndex: 'rankDelta',
+ render: ArrowRender,
+ align: 'left',
+ width: '5%',
+ fixed: 'left',
+ },
+ // 第三列:对象名称(可能是 actor, repo 或 company)
+ {
+ title: t(object),
+ dataIndex: 'name',
+ width: '20%',
+ align: 'center',
+ render: function (text) {
+ if (object !== 'company') {
+ return (
+
+ {text}
+
+ );
+ } else {
+ return text;
+ }
+ },
+ },
+ // 如果 object 是 'repo',则添加 insight_board 列
+ ...(object == 'repo'
+ ? [
+ {
+ title: t('insight_board'),
+ dataIndex: 'name',
+ align: 'center',
+ width: '10%',
+ render: function (text, row, index) {
+ return dashboard(text, index, t_month);
+ },
+ },
+ ]
+ : []),
+ // 第四列:影响力
+ {
+ title: t('influence'),
+ dataIndex: 'value',
+ width: '20%',
+ align: 'right',
+ render: (text, row, index) => {
+ return RoundFloat(text);
+ },
+ },
+ // 第五列:影响力变化
+ {
+ title: '',
+ dataIndex: 'valueDelta',
+ width: '10%',
+ align: 'left',
+ render: (text, row, index) => {
+ text = RoundFloat(text);
+ return PointRender(text, row, index);
+ },
+ },
+];
+
+const solveDate = (year, month) => {
+ if (year === null && month === null) {
+ return 'not found';
+ }
+ if (month === null) {
+ return year + '年';
+ }
+ return year + '年' + (month + 1) + '月';
+};
+
+function dashboard(text, index, t_month) {
+ if (index < 300) {
+ let [org_name, repo_name] = text.split('/');
+ const t_month_copy = t_month + ' ' + '00:00:00';
+ let params = {
+ org_name,
+ repo_name,
+ t_month_copy,
+ t_month,
+ };
+ return (
+
+
+
+ );
+ }
+}
+
+function DateTitle(props) {
+ return {solveDate(props.year, props.month)}
;
+}
+
+function MyTable(props) {
+ const [state, setState] = useState({
+ object: 'technology',
+ index: 'open_rank',
+ region: 'global',
+ showDetail: false,
+ hasDetail: true,
+ data: [],
+ showSize: 25,
+ loading: true,
+ url: '', // base + index + object + region + yearmonth + .json
+ base: 'https://oss.x-lab.info/open_leaderboard/',
+ year: null, // 字符串格式
+ month: null, // 整数格式,0表示1月,1表示2月..., null for year type time
+ type: 'month',
+ search: null,
+ category: 'cloud-native',
+ });
+
+ // 请求一次数据更新表格。如果还没读取好配置文件则不请求数据。
+ useEffect(() => {
+ if (props.year == null && props.month == null) {
+ console.log('the first loading');
+ return;
+ }
+ updateDate({
+ year: String(props.year),
+ month: props.month,
+ });
+ }, [props]);
+
+ const expandData = () => {
+ setState({
+ ...state,
+ showSize: state.showSize + 25,
+ });
+ };
+ const updateDate = (newstate) => {
+ console.log('table update', newstate);
+ // 先获取原先的表格属性
+ let {
+ base,
+ object,
+ index,
+ region,
+ month,
+ year,
+ columns,
+ showDetail,
+ hasDetail,
+ type,
+ search,
+ category,
+ } = state;
+ // 然后把表格改为加载中的状态
+ setState({ ...state, ...newstate, loading: true });
+ // 如果 newstate 有对应的属性,则进行更新
+ if (newstate.hasOwnProperty('object')) object = newstate.object;
+ if (newstate.hasOwnProperty('index')) index = newstate.index;
+ if (newstate.hasOwnProperty('region')) region = newstate.region;
+ if (newstate.hasOwnProperty('month')) month = newstate.month;
+ if (newstate.hasOwnProperty('year')) year = newstate.year;
+ if (newstate.hasOwnProperty('showDetail')) showDetail = newstate.showDetail;
+ if (newstate.hasOwnProperty('type')) type = newstate.type;
+ if (newstate.hasOwnProperty('search')) search = newstate.search;
+ if (newstate.hasOwnProperty('category')) category = newstate.category;
+
+ //获取数据大屏的‘t_month’参数
+ let myyear = newstate.year == null ? state.year : newstate.year;
+ let mymonth = newstate.month == null ? state.month : newstate.month;
+
+ mymonth = ('' + (1 + mymonth)).padStart(2, '0');
+ let t_month = `${myyear}-${mymonth}-01`;
+
+ // 根据 index 和 showDetail 改变表格的 columns 格式
+ if (index == 'activity') {
+ columns = activityColumns(object, t_month);
+ hasDetail = true;
+ }
+ if (index == 'activity' && showDetail == true) {
+ columns = activityDetailColumns(object, t_month);
+ hasDetail = true;
+ }
+ if (index == 'open_rank') {
+ columns = open_rankColumns(object, t_month);
+ hasDetail = false;
+ showDetail = false;
+ }
+ // 如果是年份数据,则把 month 置为 null。
+ // TODO:待验证,如果从年份数据切换到月份数据,似乎会自动回到原来 month 值?
+ if (type == 'year') {
+ month = null;
+ }
+ // 以当前的属性构造请求 url
+ let url = base + index + '/' + object + '/' + region + '/';
+ if (month === null) {
+ url += year + '.json';
+ } else {
+ url += year + (1 + month) + '.json';
+ }
+ console.log(url);
+ console.log(region);
+ if (object == "foundation") {
+ url = './'+ object + region +'.json'
+ }
+ else if (object == "technology") {
+ url = './'+ object + category +'.json'
+ }
+
+ // fetch 异步请求
+ fetch(url)
+ .then((res) => {
+ // Todo:最好的情况是在日期选择器中,只显示可以查询的日期,
+ if (res.status == 404) {
+ message.warning(t('no_result'));
+ return '';
+ }
+ return res.json();
+ })
+ .then((data) => {
+ data = data.data;
+ let dataSource = [];
+ // 预处理数据,对新上榜单数据进行特殊标记处理
+ data.map((obj) => {
+ obj = expandObject(obj);
+ if (obj.rankDelta == 0 && obj.value == obj.valueDelta) {
+ obj.rankDelta = -10000000;
+ obj.valueDelta = 0;
+ }
+ dataSource.push(obj);
+ });
+ console.log(dataSource);
+
+ //搜索特定数据
+ let queryData;
+ if (search) {
+ queryData = dataSource.filter((dataSource) => {
+ let reg = new RegExp(search.trim(), 'i');
+ return reg.test(dataSource.name);
+ });
+ if (queryData.length == 0) {
+ message.warning(t('no_result'));
+ } else {
+ dataSource = queryData;
+ }
+ }
+
+ // 更新属性和表格数据
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ showDetail: showDetail,
+ hasDetail: hasDetail,
+ data: dataSource,
+ });
+ })
+ .catch((err) => {
+ console.log('hi!' + err);
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ data: [],
+ });
+ });
+
+
+ };
+
+ const {
+ object,
+ index,
+ region,
+ data,
+ columns,
+ loading,
+ showSize,
+ showDetail,
+ hasDetail,
+ month,
+ year,
+ type,
+ category,
+ } = state;
+ return (
+
+
+
+
+ record.rank}
+ dataSource={data.slice(0, Math.min(showSize, data.length))}
+ pagination={false}
+ loading={loading}
+ scroll={{ x: 'max-content' }}
+ />
+
+
+
+
+ {showSize < data.length ? (
+
+ {t('showMore') + '>>'}
+
+ ) : (
+
+ {t('noMore')}
+
+ )}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+}
+
+export default MyTable;
diff --git a/.history/src/components/table_20240728173002.js b/.history/src/components/table_20240728173002.js
new file mode 100644
index 0000000..0ee7e71
--- /dev/null
+++ b/.history/src/components/table_20240728173002.js
@@ -0,0 +1,594 @@
+import React, { useState, useEffect } from 'react';
+import { Col, message, Row, Table, Card } from 'antd';
+import MyAvatar from './avatar';
+import 'antd/dist/antd.css';
+import QAmiss from './QA2';
+import TablePanel from './TablePanel';
+import ArrowRender from './arrow';
+import PointRender from './changeNumber';
+import RoundFloat from './resolveFloat';
+import Trophy from './rankTrophy';
+import expandObject from '../util/expandObject';
+import { t } from 'i18next';
+import './table.css';
+import { foundationChineseData } from './data';
+
+const activityColumns = (object, t_month) => [
+ {
+ title: t('rank'),
+ dataIndex: 'rank',
+ width: '5%',
+ align: 'center',
+ render: Trophy,
+ fixed: 'left',
+ },
+ ...(object == 'actor'
+ ? [
+ {
+ title: t('avatar'),
+ dataIndex: 'id',
+ width: '5%',
+ align: 'center',
+ render: MyAvatar,
+ fixed: 'left',
+ },
+ ]
+ : []),
+ {
+ title: '',
+ dataIndex: 'rankDelta',
+ render: ArrowRender,
+ align: 'left',
+ width: '5%',
+ fixed: 'left',
+ },
+ {
+ title: t(object),
+ dataIndex: 'name',
+ align: 'center',
+ width: '20%',
+ render: function (text, row, index) {
+ if (object !== 'company') {
+ return (
+
+ {text}
+
+ );
+ } else {
+ return text;
+ }
+ },
+ },
+ ...(object == 'repo'
+ ? [
+ {
+ title: t('insight_board'),
+ dataIndex: 'name',
+ align: 'center',
+ width: '10%',
+ render: function (text, row, index) {
+ return dashboard(text, index, t_month);
+ },
+ },
+ ]
+ : []),
+ {
+ title: t('activity'),
+ dataIndex: 'value',
+ align: 'right',
+ width: '20%',
+ },
+ {
+ title: '',
+ dataIndex: 'valueDelta',
+ width: '10%',
+ align: 'left',
+ render: PointRender,
+ },
+];
+const activityDetailColumns = (object, t_month) => [
+ {
+ title: t('rank'),
+ dataIndex: 'rank',
+ width: '5%',
+ align: 'center',
+ render: Trophy,
+ fixed: 'left',
+ },
+ ...(object == 'actor'
+ ? [
+ {
+ title: t('avatar'),
+ dataIndex: 'id',
+ width: '5%',
+ align: 'center',
+ render: MyAvatar,
+ fixed: 'left',
+ },
+ ]
+ : []),
+ {
+ title: '',
+ dataIndex: 'rankDelta',
+ render: ArrowRender,
+ align: 'left',
+ width: '5%',
+ fixed: 'left',
+ },
+ {
+ title: t(object),
+ dataIndex: 'name',
+ align: 'center',
+ width: '5%',
+ render: function (text, row, index) {
+ if (object !== 'company') {
+ return (
+
+ {text}
+
+ );
+ } else {
+ return text;
+ }
+ },
+ },
+ ...(object == 'repo'
+ ? [
+ {
+ title: t('insight_board'),
+ dataIndex: 'name',
+ align: 'center',
+ width: '10%',
+ render: function (text, row, index) {
+ return dashboard(text, index, t_month);
+ },
+ },
+ ]
+ : []),
+ {
+ title: t('activity'),
+ dataIndex: 'value',
+ align: 'center',
+ width: '10%',
+ },
+ {
+ title: '',
+ dataIndex: 'valueDelta',
+ width: '10%',
+ align: 'left',
+ render: PointRender,
+ },
+ {
+ title: t('issue_comments'),
+ dataIndex: 'issue_comment',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('open_issues'),
+ dataIndex: 'open_issue',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('open_pulls'),
+ dataIndex: 'open_pull',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('merge_pulls'),
+ dataIndex: 'merged_pull',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('pr_reviews'),
+ dataIndex: 'review_comment',
+ width: '10%',
+ align: 'center',
+ },
+];
+const open_rankColumns = (object, t_month) => [
+ {
+ // 第一列:排名
+ title: t('rank'),
+ dataIndex: 'rank',
+ width: '5%',
+ render: Trophy,
+ align: 'center',
+ fixed: 'left',
+ },
+ // 如果 object 是 'actor',则添加头像列
+ ...(object == 'actor'
+ ? [
+ {
+ title: t('avatar'),
+ dataIndex: 'id',
+ width: '5%',
+ align: 'center',
+ render: MyAvatar,
+ fixed: 'left',
+ },
+ ]
+ : []),
+ // 第二列:排名变化
+ {
+ title: '',
+ dataIndex: 'rankDelta',
+ render: ArrowRender,
+ align: 'left',
+ width: '5%',
+ fixed: 'left',
+ },
+ // 第三列:对象名称(可能是 actor, repo 或 company)
+ {
+ title: t(object),
+ dataIndex: 'name',
+ width: '20%',
+ align: 'center',
+ render: function (text) {
+ if (object !== 'company') {
+ return (
+
+ {text}
+
+ );
+ } else {
+ return text;
+ }
+ },
+ },
+ // 如果 object 是 'repo',则添加 insight_board 列
+ ...(object == 'repo'
+ ? [
+ {
+ title: t('insight_board'),
+ dataIndex: 'name',
+ align: 'center',
+ width: '10%',
+ render: function (text, row, index) {
+ return dashboard(text, index, t_month);
+ },
+ },
+ ]
+ : []),
+ // 第四列:影响力
+ {
+ title: t('influence'),
+ dataIndex: 'value',
+ width: '20%',
+ align: 'right',
+ render: (text, row, index) => {
+ return RoundFloat(text);
+ },
+ },
+ // 第五列:影响力变化
+ {
+ title: '',
+ dataIndex: 'valueDelta',
+ width: '10%',
+ align: 'left',
+ render: (text, row, index) => {
+ text = RoundFloat(text);
+ return PointRender(text, row, index);
+ },
+ },
+];
+
+const solveDate = (year, month) => {
+ if (year === null && month === null) {
+ return 'not found';
+ }
+ if (month === null) {
+ return year + '年';
+ }
+ return year + '年' + (month + 1) + '月';
+};
+
+function dashboard(text, index, t_month) {
+ if (index < 300) {
+ let [org_name, repo_name] = text.split('/');
+ const t_month_copy = t_month + ' ' + '00:00:00';
+ let params = {
+ org_name,
+ repo_name,
+ t_month_copy,
+ t_month,
+ };
+ return (
+
+
+
+ );
+ }
+}
+
+function DateTitle(props) {
+ return {solveDate(props.year, props.month)}
;
+}
+
+function MyTable(props) {
+ const [state, setState] = useState({
+ object: 'technology',
+ index: 'open_rank',
+ region: 'global',
+ showDetail: false,
+ hasDetail: true,
+ data: [],
+ showSize: 25,
+ loading: true,
+ url: '', // base + index + object + region + yearmonth + .json
+ base: 'https://oss.x-lab.info/open_leaderboard/',
+ year: null, // 字符串格式
+ month: null, // 整数格式,0表示1月,1表示2月..., null for year type time
+ type: 'month',
+ search: null,
+ category: 'cloud-native',
+ });
+
+ // 请求一次数据更新表格。如果还没读取好配置文件则不请求数据。
+ useEffect(() => {
+ if (props.year == null && props.month == null) {
+ console.log('the first loading');
+ return;
+ }
+ updateDate({
+ year: String(props.year),
+ month: props.month,
+ });
+ }, [props]);
+
+ const expandData = () => {
+ setState({
+ ...state,
+ showSize: state.showSize + 25,
+ });
+ };
+ const updateDate = (newstate) => {
+ console.log('table update', newstate);
+ // 先获取原先的表格属性
+ let {
+ base,
+ object,
+ index,
+ region,
+ month,
+ year,
+ columns,
+ showDetail,
+ hasDetail,
+ type,
+ search,
+ category,
+ } = state;
+ // 然后把表格改为加载中的状态
+ setState({ ...state, ...newstate, loading: true });
+ // 如果 newstate 有对应的属性,则进行更新
+ if (newstate.hasOwnProperty('object')) object = newstate.object;
+ if (newstate.hasOwnProperty('index')) index = newstate.index;
+ if (newstate.hasOwnProperty('region')) region = newstate.region;
+ if (newstate.hasOwnProperty('month')) month = newstate.month;
+ if (newstate.hasOwnProperty('year')) year = newstate.year;
+ if (newstate.hasOwnProperty('showDetail')) showDetail = newstate.showDetail;
+ if (newstate.hasOwnProperty('type')) type = newstate.type;
+ if (newstate.hasOwnProperty('search')) search = newstate.search;
+ if (newstate.hasOwnProperty('category')) category = newstate.category;
+
+ //获取数据大屏的‘t_month’参数
+ let myyear = newstate.year == null ? state.year : newstate.year;
+ let mymonth = newstate.month == null ? state.month : newstate.month;
+
+ mymonth = ('' + (1 + mymonth)).padStart(2, '0');
+ let t_month = `${myyear}-${mymonth}-01`;
+
+ // 根据 index 和 showDetail 改变表格的 columns 格式
+ if (index == 'activity') {
+ columns = activityColumns(object, t_month);
+ hasDetail = true;
+ }
+ if (index == 'activity' && showDetail == true) {
+ columns = activityDetailColumns(object, t_month);
+ hasDetail = true;
+ }
+ if (index == 'open_rank') {
+ columns = open_rankColumns(object, t_month);
+ hasDetail = false;
+ showDetail = false;
+ }
+ // 如果是年份数据,则把 month 置为 null。
+ // TODO:待验证,如果从年份数据切换到月份数据,似乎会自动回到原来 month 值?
+ if (type == 'year') {
+ month = null;
+ }
+ // 以当前的属性构造请求 url
+ let url = base + index + '/' + object + '/' + region + '/';
+ if (month === null) {
+ url += year + '.json';
+ } else {
+ url += year + (1 + month) + '.json';
+ }
+ console.log(url);
+ console.log(region);
+ if (object == "foundation") {
+ url = './tech-foundation'+ object + region +'.json'
+ }
+ else if (object == "technology") {
+ url = './'+ object + category +'.json'
+ }
+
+ // fetch 异步请求
+ fetch(url)
+ .then((res) => {
+ // Todo:最好的情况是在日期选择器中,只显示可以查询的日期,
+ if (res.status == 404) {
+ message.warning(t('no_result'));
+ return '';
+ }
+ return res.json();
+ })
+ .then((data) => {
+ data = data.data;
+ let dataSource = [];
+ // 预处理数据,对新上榜单数据进行特殊标记处理
+ data.map((obj) => {
+ obj = expandObject(obj);
+ if (obj.rankDelta == 0 && obj.value == obj.valueDelta) {
+ obj.rankDelta = -10000000;
+ obj.valueDelta = 0;
+ }
+ dataSource.push(obj);
+ });
+ console.log(dataSource);
+
+ //搜索特定数据
+ let queryData;
+ if (search) {
+ queryData = dataSource.filter((dataSource) => {
+ let reg = new RegExp(search.trim(), 'i');
+ return reg.test(dataSource.name);
+ });
+ if (queryData.length == 0) {
+ message.warning(t('no_result'));
+ } else {
+ dataSource = queryData;
+ }
+ }
+
+ // 更新属性和表格数据
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ showDetail: showDetail,
+ hasDetail: hasDetail,
+ data: dataSource,
+ });
+ })
+ .catch((err) => {
+ console.log('hi!' + err);
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ data: [],
+ });
+ });
+
+
+ };
+
+ const {
+ object,
+ index,
+ region,
+ data,
+ columns,
+ loading,
+ showSize,
+ showDetail,
+ hasDetail,
+ month,
+ year,
+ type,
+ category,
+ } = state;
+ return (
+
+
+
+
+ record.rank}
+ dataSource={data.slice(0, Math.min(showSize, data.length))}
+ pagination={false}
+ loading={loading}
+ scroll={{ x: 'max-content' }}
+ />
+
+
+
+
+ {showSize < data.length ? (
+
+ {t('showMore') + '>>'}
+
+ ) : (
+
+ {t('noMore')}
+
+ )}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+}
+
+export default MyTable;
diff --git a/.history/src/components/table_20240728173032.js b/.history/src/components/table_20240728173032.js
new file mode 100644
index 0000000..07e2ae2
--- /dev/null
+++ b/.history/src/components/table_20240728173032.js
@@ -0,0 +1,594 @@
+import React, { useState, useEffect } from 'react';
+import { Col, message, Row, Table, Card } from 'antd';
+import MyAvatar from './avatar';
+import 'antd/dist/antd.css';
+import QAmiss from './QA2';
+import TablePanel from './TablePanel';
+import ArrowRender from './arrow';
+import PointRender from './changeNumber';
+import RoundFloat from './resolveFloat';
+import Trophy from './rankTrophy';
+import expandObject from '../util/expandObject';
+import { t } from 'i18next';
+import './table.css';
+import { foundationChineseData } from './data';
+
+const activityColumns = (object, t_month) => [
+ {
+ title: t('rank'),
+ dataIndex: 'rank',
+ width: '5%',
+ align: 'center',
+ render: Trophy,
+ fixed: 'left',
+ },
+ ...(object == 'actor'
+ ? [
+ {
+ title: t('avatar'),
+ dataIndex: 'id',
+ width: '5%',
+ align: 'center',
+ render: MyAvatar,
+ fixed: 'left',
+ },
+ ]
+ : []),
+ {
+ title: '',
+ dataIndex: 'rankDelta',
+ render: ArrowRender,
+ align: 'left',
+ width: '5%',
+ fixed: 'left',
+ },
+ {
+ title: t(object),
+ dataIndex: 'name',
+ align: 'center',
+ width: '20%',
+ render: function (text, row, index) {
+ if (object !== 'company') {
+ return (
+
+ {text}
+
+ );
+ } else {
+ return text;
+ }
+ },
+ },
+ ...(object == 'repo'
+ ? [
+ {
+ title: t('insight_board'),
+ dataIndex: 'name',
+ align: 'center',
+ width: '10%',
+ render: function (text, row, index) {
+ return dashboard(text, index, t_month);
+ },
+ },
+ ]
+ : []),
+ {
+ title: t('activity'),
+ dataIndex: 'value',
+ align: 'right',
+ width: '20%',
+ },
+ {
+ title: '',
+ dataIndex: 'valueDelta',
+ width: '10%',
+ align: 'left',
+ render: PointRender,
+ },
+];
+const activityDetailColumns = (object, t_month) => [
+ {
+ title: t('rank'),
+ dataIndex: 'rank',
+ width: '5%',
+ align: 'center',
+ render: Trophy,
+ fixed: 'left',
+ },
+ ...(object == 'actor'
+ ? [
+ {
+ title: t('avatar'),
+ dataIndex: 'id',
+ width: '5%',
+ align: 'center',
+ render: MyAvatar,
+ fixed: 'left',
+ },
+ ]
+ : []),
+ {
+ title: '',
+ dataIndex: 'rankDelta',
+ render: ArrowRender,
+ align: 'left',
+ width: '5%',
+ fixed: 'left',
+ },
+ {
+ title: t(object),
+ dataIndex: 'name',
+ align: 'center',
+ width: '5%',
+ render: function (text, row, index) {
+ if (object !== 'company') {
+ return (
+
+ {text}
+
+ );
+ } else {
+ return text;
+ }
+ },
+ },
+ ...(object == 'repo'
+ ? [
+ {
+ title: t('insight_board'),
+ dataIndex: 'name',
+ align: 'center',
+ width: '10%',
+ render: function (text, row, index) {
+ return dashboard(text, index, t_month);
+ },
+ },
+ ]
+ : []),
+ {
+ title: t('activity'),
+ dataIndex: 'value',
+ align: 'center',
+ width: '10%',
+ },
+ {
+ title: '',
+ dataIndex: 'valueDelta',
+ width: '10%',
+ align: 'left',
+ render: PointRender,
+ },
+ {
+ title: t('issue_comments'),
+ dataIndex: 'issue_comment',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('open_issues'),
+ dataIndex: 'open_issue',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('open_pulls'),
+ dataIndex: 'open_pull',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('merge_pulls'),
+ dataIndex: 'merged_pull',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('pr_reviews'),
+ dataIndex: 'review_comment',
+ width: '10%',
+ align: 'center',
+ },
+];
+const open_rankColumns = (object, t_month) => [
+ {
+ // 第一列:排名
+ title: t('rank'),
+ dataIndex: 'rank',
+ width: '5%',
+ render: Trophy,
+ align: 'center',
+ fixed: 'left',
+ },
+ // 如果 object 是 'actor',则添加头像列
+ ...(object == 'actor'
+ ? [
+ {
+ title: t('avatar'),
+ dataIndex: 'id',
+ width: '5%',
+ align: 'center',
+ render: MyAvatar,
+ fixed: 'left',
+ },
+ ]
+ : []),
+ // 第二列:排名变化
+ {
+ title: '',
+ dataIndex: 'rankDelta',
+ render: ArrowRender,
+ align: 'left',
+ width: '5%',
+ fixed: 'left',
+ },
+ // 第三列:对象名称(可能是 actor, repo 或 company)
+ {
+ title: t(object),
+ dataIndex: 'name',
+ width: '20%',
+ align: 'center',
+ render: function (text) {
+ if (object !== 'company') {
+ return (
+
+ {text}
+
+ );
+ } else {
+ return text;
+ }
+ },
+ },
+ // 如果 object 是 'repo',则添加 insight_board 列
+ ...(object == 'repo'
+ ? [
+ {
+ title: t('insight_board'),
+ dataIndex: 'name',
+ align: 'center',
+ width: '10%',
+ render: function (text, row, index) {
+ return dashboard(text, index, t_month);
+ },
+ },
+ ]
+ : []),
+ // 第四列:影响力
+ {
+ title: t('influence'),
+ dataIndex: 'value',
+ width: '20%',
+ align: 'right',
+ render: (text, row, index) => {
+ return RoundFloat(text);
+ },
+ },
+ // 第五列:影响力变化
+ {
+ title: '',
+ dataIndex: 'valueDelta',
+ width: '10%',
+ align: 'left',
+ render: (text, row, index) => {
+ text = RoundFloat(text);
+ return PointRender(text, row, index);
+ },
+ },
+];
+
+const solveDate = (year, month) => {
+ if (year === null && month === null) {
+ return 'not found';
+ }
+ if (month === null) {
+ return year + '年';
+ }
+ return year + '年' + (month + 1) + '月';
+};
+
+function dashboard(text, index, t_month) {
+ if (index < 300) {
+ let [org_name, repo_name] = text.split('/');
+ const t_month_copy = t_month + ' ' + '00:00:00';
+ let params = {
+ org_name,
+ repo_name,
+ t_month_copy,
+ t_month,
+ };
+ return (
+
+
+
+ );
+ }
+}
+
+function DateTitle(props) {
+ return {solveDate(props.year, props.month)}
;
+}
+
+function MyTable(props) {
+ const [state, setState] = useState({
+ object: 'technology',
+ index: 'open_rank',
+ region: 'global',
+ showDetail: false,
+ hasDetail: true,
+ data: [],
+ showSize: 25,
+ loading: true,
+ url: '', // base + index + object + region + yearmonth + .json
+ base: 'https://oss.x-lab.info/open_leaderboard/',
+ year: null, // 字符串格式
+ month: null, // 整数格式,0表示1月,1表示2月..., null for year type time
+ type: 'month',
+ search: null,
+ category: 'cloud-native',
+ });
+
+ // 请求一次数据更新表格。如果还没读取好配置文件则不请求数据。
+ useEffect(() => {
+ if (props.year == null && props.month == null) {
+ console.log('the first loading');
+ return;
+ }
+ updateDate({
+ year: String(props.year),
+ month: props.month,
+ });
+ }, [props]);
+
+ const expandData = () => {
+ setState({
+ ...state,
+ showSize: state.showSize + 25,
+ });
+ };
+ const updateDate = (newstate) => {
+ console.log('table update', newstate);
+ // 先获取原先的表格属性
+ let {
+ base,
+ object,
+ index,
+ region,
+ month,
+ year,
+ columns,
+ showDetail,
+ hasDetail,
+ type,
+ search,
+ category,
+ } = state;
+ // 然后把表格改为加载中的状态
+ setState({ ...state, ...newstate, loading: true });
+ // 如果 newstate 有对应的属性,则进行更新
+ if (newstate.hasOwnProperty('object')) object = newstate.object;
+ if (newstate.hasOwnProperty('index')) index = newstate.index;
+ if (newstate.hasOwnProperty('region')) region = newstate.region;
+ if (newstate.hasOwnProperty('month')) month = newstate.month;
+ if (newstate.hasOwnProperty('year')) year = newstate.year;
+ if (newstate.hasOwnProperty('showDetail')) showDetail = newstate.showDetail;
+ if (newstate.hasOwnProperty('type')) type = newstate.type;
+ if (newstate.hasOwnProperty('search')) search = newstate.search;
+ if (newstate.hasOwnProperty('category')) category = newstate.category;
+
+ //获取数据大屏的‘t_month’参数
+ let myyear = newstate.year == null ? state.year : newstate.year;
+ let mymonth = newstate.month == null ? state.month : newstate.month;
+
+ mymonth = ('' + (1 + mymonth)).padStart(2, '0');
+ let t_month = `${myyear}-${mymonth}-01`;
+
+ // 根据 index 和 showDetail 改变表格的 columns 格式
+ if (index == 'activity') {
+ columns = activityColumns(object, t_month);
+ hasDetail = true;
+ }
+ if (index == 'activity' && showDetail == true) {
+ columns = activityDetailColumns(object, t_month);
+ hasDetail = true;
+ }
+ if (index == 'open_rank') {
+ columns = open_rankColumns(object, t_month);
+ hasDetail = false;
+ showDetail = false;
+ }
+ // 如果是年份数据,则把 month 置为 null。
+ // TODO:待验证,如果从年份数据切换到月份数据,似乎会自动回到原来 month 值?
+ if (type == 'year') {
+ month = null;
+ }
+ // 以当前的属性构造请求 url
+ let url = base + index + '/' + object + '/' + region + '/';
+ if (month === null) {
+ url += year + '.json';
+ } else {
+ url += year + (1 + month) + '.json';
+ }
+ console.log(url);
+ console.log(region);
+ if (object == "foundation") {
+ url = './tech-foundation/'+ object + region +'.json'
+ }
+ else if (object == "technology") {
+ url = './'+ object + category +'.json'
+ }
+
+ // fetch 异步请求
+ fetch(url)
+ .then((res) => {
+ // Todo:最好的情况是在日期选择器中,只显示可以查询的日期,
+ if (res.status == 404) {
+ message.warning(t('no_result'));
+ return '';
+ }
+ return res.json();
+ })
+ .then((data) => {
+ data = data.data;
+ let dataSource = [];
+ // 预处理数据,对新上榜单数据进行特殊标记处理
+ data.map((obj) => {
+ obj = expandObject(obj);
+ if (obj.rankDelta == 0 && obj.value == obj.valueDelta) {
+ obj.rankDelta = -10000000;
+ obj.valueDelta = 0;
+ }
+ dataSource.push(obj);
+ });
+ console.log(dataSource);
+
+ //搜索特定数据
+ let queryData;
+ if (search) {
+ queryData = dataSource.filter((dataSource) => {
+ let reg = new RegExp(search.trim(), 'i');
+ return reg.test(dataSource.name);
+ });
+ if (queryData.length == 0) {
+ message.warning(t('no_result'));
+ } else {
+ dataSource = queryData;
+ }
+ }
+
+ // 更新属性和表格数据
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ showDetail: showDetail,
+ hasDetail: hasDetail,
+ data: dataSource,
+ });
+ })
+ .catch((err) => {
+ console.log('hi!' + err);
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ data: [],
+ });
+ });
+
+
+ };
+
+ const {
+ object,
+ index,
+ region,
+ data,
+ columns,
+ loading,
+ showSize,
+ showDetail,
+ hasDetail,
+ month,
+ year,
+ type,
+ category,
+ } = state;
+ return (
+
+
+
+
+ record.rank}
+ dataSource={data.slice(0, Math.min(showSize, data.length))}
+ pagination={false}
+ loading={loading}
+ scroll={{ x: 'max-content' }}
+ />
+
+
+
+
+ {showSize < data.length ? (
+
+ {t('showMore') + '>>'}
+
+ ) : (
+
+ {t('noMore')}
+
+ )}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+}
+
+export default MyTable;
diff --git a/.history/src/components/table_20240728173107.js b/.history/src/components/table_20240728173107.js
new file mode 100644
index 0000000..84ae65c
--- /dev/null
+++ b/.history/src/components/table_20240728173107.js
@@ -0,0 +1,594 @@
+import React, { useState, useEffect } from 'react';
+import { Col, message, Row, Table, Card } from 'antd';
+import MyAvatar from './avatar';
+import 'antd/dist/antd.css';
+import QAmiss from './QA2';
+import TablePanel from './TablePanel';
+import ArrowRender from './arrow';
+import PointRender from './changeNumber';
+import RoundFloat from './resolveFloat';
+import Trophy from './rankTrophy';
+import expandObject from '../util/expandObject';
+import { t } from 'i18next';
+import './table.css';
+import { foundationChineseData } from './data';
+
+const activityColumns = (object, t_month) => [
+ {
+ title: t('rank'),
+ dataIndex: 'rank',
+ width: '5%',
+ align: 'center',
+ render: Trophy,
+ fixed: 'left',
+ },
+ ...(object == 'actor'
+ ? [
+ {
+ title: t('avatar'),
+ dataIndex: 'id',
+ width: '5%',
+ align: 'center',
+ render: MyAvatar,
+ fixed: 'left',
+ },
+ ]
+ : []),
+ {
+ title: '',
+ dataIndex: 'rankDelta',
+ render: ArrowRender,
+ align: 'left',
+ width: '5%',
+ fixed: 'left',
+ },
+ {
+ title: t(object),
+ dataIndex: 'name',
+ align: 'center',
+ width: '20%',
+ render: function (text, row, index) {
+ if (object !== 'company') {
+ return (
+
+ {text}
+
+ );
+ } else {
+ return text;
+ }
+ },
+ },
+ ...(object == 'repo'
+ ? [
+ {
+ title: t('insight_board'),
+ dataIndex: 'name',
+ align: 'center',
+ width: '10%',
+ render: function (text, row, index) {
+ return dashboard(text, index, t_month);
+ },
+ },
+ ]
+ : []),
+ {
+ title: t('activity'),
+ dataIndex: 'value',
+ align: 'right',
+ width: '20%',
+ },
+ {
+ title: '',
+ dataIndex: 'valueDelta',
+ width: '10%',
+ align: 'left',
+ render: PointRender,
+ },
+];
+const activityDetailColumns = (object, t_month) => [
+ {
+ title: t('rank'),
+ dataIndex: 'rank',
+ width: '5%',
+ align: 'center',
+ render: Trophy,
+ fixed: 'left',
+ },
+ ...(object == 'actor'
+ ? [
+ {
+ title: t('avatar'),
+ dataIndex: 'id',
+ width: '5%',
+ align: 'center',
+ render: MyAvatar,
+ fixed: 'left',
+ },
+ ]
+ : []),
+ {
+ title: '',
+ dataIndex: 'rankDelta',
+ render: ArrowRender,
+ align: 'left',
+ width: '5%',
+ fixed: 'left',
+ },
+ {
+ title: t(object),
+ dataIndex: 'name',
+ align: 'center',
+ width: '5%',
+ render: function (text, row, index) {
+ if (object !== 'company') {
+ return (
+
+ {text}
+
+ );
+ } else {
+ return text;
+ }
+ },
+ },
+ ...(object == 'repo'
+ ? [
+ {
+ title: t('insight_board'),
+ dataIndex: 'name',
+ align: 'center',
+ width: '10%',
+ render: function (text, row, index) {
+ return dashboard(text, index, t_month);
+ },
+ },
+ ]
+ : []),
+ {
+ title: t('activity'),
+ dataIndex: 'value',
+ align: 'center',
+ width: '10%',
+ },
+ {
+ title: '',
+ dataIndex: 'valueDelta',
+ width: '10%',
+ align: 'left',
+ render: PointRender,
+ },
+ {
+ title: t('issue_comments'),
+ dataIndex: 'issue_comment',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('open_issues'),
+ dataIndex: 'open_issue',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('open_pulls'),
+ dataIndex: 'open_pull',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('merge_pulls'),
+ dataIndex: 'merged_pull',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('pr_reviews'),
+ dataIndex: 'review_comment',
+ width: '10%',
+ align: 'center',
+ },
+];
+const open_rankColumns = (object, t_month) => [
+ {
+ // 第一列:排名
+ title: t('rank'),
+ dataIndex: 'rank',
+ width: '5%',
+ render: Trophy,
+ align: 'center',
+ fixed: 'left',
+ },
+ // 如果 object 是 'actor',则添加头像列
+ ...(object == 'actor'
+ ? [
+ {
+ title: t('avatar'),
+ dataIndex: 'id',
+ width: '5%',
+ align: 'center',
+ render: MyAvatar,
+ fixed: 'left',
+ },
+ ]
+ : []),
+ // 第二列:排名变化
+ {
+ title: '',
+ dataIndex: 'rankDelta',
+ render: ArrowRender,
+ align: 'left',
+ width: '5%',
+ fixed: 'left',
+ },
+ // 第三列:对象名称(可能是 actor, repo 或 company)
+ {
+ title: t(object),
+ dataIndex: 'name',
+ width: '20%',
+ align: 'center',
+ render: function (text) {
+ if (object !== 'company') {
+ return (
+
+ {text}
+
+ );
+ } else {
+ return text;
+ }
+ },
+ },
+ // 如果 object 是 'repo',则添加 insight_board 列
+ ...(object == 'repo'
+ ? [
+ {
+ title: t('insight_board'),
+ dataIndex: 'name',
+ align: 'center',
+ width: '10%',
+ render: function (text, row, index) {
+ return dashboard(text, index, t_month);
+ },
+ },
+ ]
+ : []),
+ // 第四列:影响力
+ {
+ title: t('influence'),
+ dataIndex: 'value',
+ width: '20%',
+ align: 'right',
+ render: (text, row, index) => {
+ return RoundFloat(text);
+ },
+ },
+ // 第五列:影响力变化
+ {
+ title: '',
+ dataIndex: 'valueDelta',
+ width: '10%',
+ align: 'left',
+ render: (text, row, index) => {
+ text = RoundFloat(text);
+ return PointRender(text, row, index);
+ },
+ },
+];
+
+const solveDate = (year, month) => {
+ if (year === null && month === null) {
+ return 'not found';
+ }
+ if (month === null) {
+ return year + '年';
+ }
+ return year + '年' + (month + 1) + '月';
+};
+
+function dashboard(text, index, t_month) {
+ if (index < 300) {
+ let [org_name, repo_name] = text.split('/');
+ const t_month_copy = t_month + ' ' + '00:00:00';
+ let params = {
+ org_name,
+ repo_name,
+ t_month_copy,
+ t_month,
+ };
+ return (
+
+
+
+ );
+ }
+}
+
+function DateTitle(props) {
+ return {solveDate(props.year, props.month)}
;
+}
+
+function MyTable(props) {
+ const [state, setState] = useState({
+ object: 'technology',
+ index: 'open_rank',
+ region: 'global',
+ showDetail: false,
+ hasDetail: true,
+ data: [],
+ showSize: 25,
+ loading: true,
+ url: '', // base + index + object + region + yearmonth + .json
+ base: 'https://oss.x-lab.info/open_leaderboard/',
+ year: null, // 字符串格式
+ month: null, // 整数格式,0表示1月,1表示2月..., null for year type time
+ type: 'month',
+ search: null,
+ category: 'cloud-native',
+ });
+
+ // 请求一次数据更新表格。如果还没读取好配置文件则不请求数据。
+ useEffect(() => {
+ if (props.year == null && props.month == null) {
+ console.log('the first loading');
+ return;
+ }
+ updateDate({
+ year: String(props.year),
+ month: props.month,
+ });
+ }, [props]);
+
+ const expandData = () => {
+ setState({
+ ...state,
+ showSize: state.showSize + 25,
+ });
+ };
+ const updateDate = (newstate) => {
+ console.log('table update', newstate);
+ // 先获取原先的表格属性
+ let {
+ base,
+ object,
+ index,
+ region,
+ month,
+ year,
+ columns,
+ showDetail,
+ hasDetail,
+ type,
+ search,
+ category,
+ } = state;
+ // 然后把表格改为加载中的状态
+ setState({ ...state, ...newstate, loading: true });
+ // 如果 newstate 有对应的属性,则进行更新
+ if (newstate.hasOwnProperty('object')) object = newstate.object;
+ if (newstate.hasOwnProperty('index')) index = newstate.index;
+ if (newstate.hasOwnProperty('region')) region = newstate.region;
+ if (newstate.hasOwnProperty('month')) month = newstate.month;
+ if (newstate.hasOwnProperty('year')) year = newstate.year;
+ if (newstate.hasOwnProperty('showDetail')) showDetail = newstate.showDetail;
+ if (newstate.hasOwnProperty('type')) type = newstate.type;
+ if (newstate.hasOwnProperty('search')) search = newstate.search;
+ if (newstate.hasOwnProperty('category')) category = newstate.category;
+
+ //获取数据大屏的‘t_month’参数
+ let myyear = newstate.year == null ? state.year : newstate.year;
+ let mymonth = newstate.month == null ? state.month : newstate.month;
+
+ mymonth = ('' + (1 + mymonth)).padStart(2, '0');
+ let t_month = `${myyear}-${mymonth}-01`;
+
+ // 根据 index 和 showDetail 改变表格的 columns 格式
+ if (index == 'activity') {
+ columns = activityColumns(object, t_month);
+ hasDetail = true;
+ }
+ if (index == 'activity' && showDetail == true) {
+ columns = activityDetailColumns(object, t_month);
+ hasDetail = true;
+ }
+ if (index == 'open_rank') {
+ columns = open_rankColumns(object, t_month);
+ hasDetail = false;
+ showDetail = false;
+ }
+ // 如果是年份数据,则把 month 置为 null。
+ // TODO:待验证,如果从年份数据切换到月份数据,似乎会自动回到原来 month 值?
+ if (type == 'year') {
+ month = null;
+ }
+ // 以当前的属性构造请求 url
+ let url = base + index + '/' + object + '/' + region + '/';
+ if (month === null) {
+ url += year + '.json';
+ } else {
+ url += year + (1 + month) + '.json';
+ }
+ console.log(url);
+ console.log(region);
+ if (object == "foundation") {
+ url = './tech-foundation/'+ object + region +'.json'
+ }
+ else if (object == "technology") {
+ url = './tech-foundation/'+ object + category +'.json'
+ }
+
+ // fetch 异步请求
+ fetch(url)
+ .then((res) => {
+ // Todo:最好的情况是在日期选择器中,只显示可以查询的日期,
+ if (res.status == 404) {
+ message.warning(t('no_result'));
+ return '';
+ }
+ return res.json();
+ })
+ .then((data) => {
+ data = data.data;
+ let dataSource = [];
+ // 预处理数据,对新上榜单数据进行特殊标记处理
+ data.map((obj) => {
+ obj = expandObject(obj);
+ if (obj.rankDelta == 0 && obj.value == obj.valueDelta) {
+ obj.rankDelta = -10000000;
+ obj.valueDelta = 0;
+ }
+ dataSource.push(obj);
+ });
+ console.log(dataSource);
+
+ //搜索特定数据
+ let queryData;
+ if (search) {
+ queryData = dataSource.filter((dataSource) => {
+ let reg = new RegExp(search.trim(), 'i');
+ return reg.test(dataSource.name);
+ });
+ if (queryData.length == 0) {
+ message.warning(t('no_result'));
+ } else {
+ dataSource = queryData;
+ }
+ }
+
+ // 更新属性和表格数据
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ showDetail: showDetail,
+ hasDetail: hasDetail,
+ data: dataSource,
+ });
+ })
+ .catch((err) => {
+ console.log('hi!' + err);
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ data: [],
+ });
+ });
+
+
+ };
+
+ const {
+ object,
+ index,
+ region,
+ data,
+ columns,
+ loading,
+ showSize,
+ showDetail,
+ hasDetail,
+ month,
+ year,
+ type,
+ category,
+ } = state;
+ return (
+
+
+
+
+ record.rank}
+ dataSource={data.slice(0, Math.min(showSize, data.length))}
+ pagination={false}
+ loading={loading}
+ scroll={{ x: 'max-content' }}
+ />
+
+
+
+
+ {showSize < data.length ? (
+
+ {t('showMore') + '>>'}
+
+ ) : (
+
+ {t('noMore')}
+
+ )}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+}
+
+export default MyTable;
diff --git a/.history/src/components/table_20240728173113.js b/.history/src/components/table_20240728173113.js
new file mode 100644
index 0000000..24f1e5d
--- /dev/null
+++ b/.history/src/components/table_20240728173113.js
@@ -0,0 +1,593 @@
+import React, { useState, useEffect } from 'react';
+import { Col, message, Row, Table, Card } from 'antd';
+import MyAvatar from './avatar';
+import 'antd/dist/antd.css';
+import QAmiss from './QA2';
+import TablePanel from './TablePanel';
+import ArrowRender from './arrow';
+import PointRender from './changeNumber';
+import RoundFloat from './resolveFloat';
+import Trophy from './rankTrophy';
+import expandObject from '../util/expandObject';
+import { t } from 'i18next';
+import './table.css';
+import { foundationChineseData } from './data';
+
+const activityColumns = (object, t_month) => [
+ {
+ title: t('rank'),
+ dataIndex: 'rank',
+ width: '5%',
+ align: 'center',
+ render: Trophy,
+ fixed: 'left',
+ },
+ ...(object == 'actor'
+ ? [
+ {
+ title: t('avatar'),
+ dataIndex: 'id',
+ width: '5%',
+ align: 'center',
+ render: MyAvatar,
+ fixed: 'left',
+ },
+ ]
+ : []),
+ {
+ title: '',
+ dataIndex: 'rankDelta',
+ render: ArrowRender,
+ align: 'left',
+ width: '5%',
+ fixed: 'left',
+ },
+ {
+ title: t(object),
+ dataIndex: 'name',
+ align: 'center',
+ width: '20%',
+ render: function (text, row, index) {
+ if (object !== 'company') {
+ return (
+
+ {text}
+
+ );
+ } else {
+ return text;
+ }
+ },
+ },
+ ...(object == 'repo'
+ ? [
+ {
+ title: t('insight_board'),
+ dataIndex: 'name',
+ align: 'center',
+ width: '10%',
+ render: function (text, row, index) {
+ return dashboard(text, index, t_month);
+ },
+ },
+ ]
+ : []),
+ {
+ title: t('activity'),
+ dataIndex: 'value',
+ align: 'right',
+ width: '20%',
+ },
+ {
+ title: '',
+ dataIndex: 'valueDelta',
+ width: '10%',
+ align: 'left',
+ render: PointRender,
+ },
+];
+const activityDetailColumns = (object, t_month) => [
+ {
+ title: t('rank'),
+ dataIndex: 'rank',
+ width: '5%',
+ align: 'center',
+ render: Trophy,
+ fixed: 'left',
+ },
+ ...(object == 'actor'
+ ? [
+ {
+ title: t('avatar'),
+ dataIndex: 'id',
+ width: '5%',
+ align: 'center',
+ render: MyAvatar,
+ fixed: 'left',
+ },
+ ]
+ : []),
+ {
+ title: '',
+ dataIndex: 'rankDelta',
+ render: ArrowRender,
+ align: 'left',
+ width: '5%',
+ fixed: 'left',
+ },
+ {
+ title: t(object),
+ dataIndex: 'name',
+ align: 'center',
+ width: '5%',
+ render: function (text, row, index) {
+ if (object !== 'company') {
+ return (
+
+ {text}
+
+ );
+ } else {
+ return text;
+ }
+ },
+ },
+ ...(object == 'repo'
+ ? [
+ {
+ title: t('insight_board'),
+ dataIndex: 'name',
+ align: 'center',
+ width: '10%',
+ render: function (text, row, index) {
+ return dashboard(text, index, t_month);
+ },
+ },
+ ]
+ : []),
+ {
+ title: t('activity'),
+ dataIndex: 'value',
+ align: 'center',
+ width: '10%',
+ },
+ {
+ title: '',
+ dataIndex: 'valueDelta',
+ width: '10%',
+ align: 'left',
+ render: PointRender,
+ },
+ {
+ title: t('issue_comments'),
+ dataIndex: 'issue_comment',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('open_issues'),
+ dataIndex: 'open_issue',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('open_pulls'),
+ dataIndex: 'open_pull',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('merge_pulls'),
+ dataIndex: 'merged_pull',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('pr_reviews'),
+ dataIndex: 'review_comment',
+ width: '10%',
+ align: 'center',
+ },
+];
+const open_rankColumns = (object, t_month) => [
+ {
+ // 第一列:排名
+ title: t('rank'),
+ dataIndex: 'rank',
+ width: '5%',
+ render: Trophy,
+ align: 'center',
+ fixed: 'left',
+ },
+ // 如果 object 是 'actor',则添加头像列
+ ...(object == 'actor'
+ ? [
+ {
+ title: t('avatar'),
+ dataIndex: 'id',
+ width: '5%',
+ align: 'center',
+ render: MyAvatar,
+ fixed: 'left',
+ },
+ ]
+ : []),
+ // 第二列:排名变化
+ {
+ title: '',
+ dataIndex: 'rankDelta',
+ render: ArrowRender,
+ align: 'left',
+ width: '5%',
+ fixed: 'left',
+ },
+ // 第三列:对象名称(可能是 actor, repo 或 company)
+ {
+ title: t(object),
+ dataIndex: 'name',
+ width: '20%',
+ align: 'center',
+ render: function (text) {
+ if (object !== 'company') {
+ return (
+
+ {text}
+
+ );
+ } else {
+ return text;
+ }
+ },
+ },
+ // 如果 object 是 'repo',则添加 insight_board 列
+ ...(object == 'repo'
+ ? [
+ {
+ title: t('insight_board'),
+ dataIndex: 'name',
+ align: 'center',
+ width: '10%',
+ render: function (text, row, index) {
+ return dashboard(text, index, t_month);
+ },
+ },
+ ]
+ : []),
+ // 第四列:影响力
+ {
+ title: t('influence'),
+ dataIndex: 'value',
+ width: '20%',
+ align: 'right',
+ render: (text, row, index) => {
+ return RoundFloat(text);
+ },
+ },
+ // 第五列:影响力变化
+ {
+ title: '',
+ dataIndex: 'valueDelta',
+ width: '10%',
+ align: 'left',
+ render: (text, row, index) => {
+ text = RoundFloat(text);
+ return PointRender(text, row, index);
+ },
+ },
+];
+
+const solveDate = (year, month) => {
+ if (year === null && month === null) {
+ return 'not found';
+ }
+ if (month === null) {
+ return year + '年';
+ }
+ return year + '年' + (month + 1) + '月';
+};
+
+function dashboard(text, index, t_month) {
+ if (index < 300) {
+ let [org_name, repo_name] = text.split('/');
+ const t_month_copy = t_month + ' ' + '00:00:00';
+ let params = {
+ org_name,
+ repo_name,
+ t_month_copy,
+ t_month,
+ };
+ return (
+
+
+
+ );
+ }
+}
+
+function DateTitle(props) {
+ return {solveDate(props.year, props.month)}
;
+}
+
+function MyTable(props) {
+ const [state, setState] = useState({
+ object: 'technology',
+ index: 'open_rank',
+ region: 'global',
+ showDetail: false,
+ hasDetail: true,
+ data: [],
+ showSize: 25,
+ loading: true,
+ url: '', // base + index + object + region + yearmonth + .json
+ base: 'https://oss.x-lab.info/open_leaderboard/',
+ year: null, // 字符串格式
+ month: null, // 整数格式,0表示1月,1表示2月..., null for year type time
+ type: 'month',
+ search: null,
+ category: 'cloud-native',
+ });
+
+ // 请求一次数据更新表格。如果还没读取好配置文件则不请求数据。
+ useEffect(() => {
+ if (props.year == null && props.month == null) {
+ console.log('the first loading');
+ return;
+ }
+ updateDate({
+ year: String(props.year),
+ month: props.month,
+ });
+ }, [props]);
+
+ const expandData = () => {
+ setState({
+ ...state,
+ showSize: state.showSize + 25,
+ });
+ };
+ const updateDate = (newstate) => {
+ console.log('table update', newstate);
+ // 先获取原先的表格属性
+ let {
+ base,
+ object,
+ index,
+ region,
+ month,
+ year,
+ columns,
+ showDetail,
+ hasDetail,
+ type,
+ search,
+ category,
+ } = state;
+ // 然后把表格改为加载中的状态
+ setState({ ...state, ...newstate, loading: true });
+ // 如果 newstate 有对应的属性,则进行更新
+ if (newstate.hasOwnProperty('object')) object = newstate.object;
+ if (newstate.hasOwnProperty('index')) index = newstate.index;
+ if (newstate.hasOwnProperty('region')) region = newstate.region;
+ if (newstate.hasOwnProperty('month')) month = newstate.month;
+ if (newstate.hasOwnProperty('year')) year = newstate.year;
+ if (newstate.hasOwnProperty('showDetail')) showDetail = newstate.showDetail;
+ if (newstate.hasOwnProperty('type')) type = newstate.type;
+ if (newstate.hasOwnProperty('search')) search = newstate.search;
+ if (newstate.hasOwnProperty('category')) category = newstate.category;
+
+ //获取数据大屏的‘t_month’参数
+ let myyear = newstate.year == null ? state.year : newstate.year;
+ let mymonth = newstate.month == null ? state.month : newstate.month;
+
+ mymonth = ('' + (1 + mymonth)).padStart(2, '0');
+ let t_month = `${myyear}-${mymonth}-01`;
+
+ // 根据 index 和 showDetail 改变表格的 columns 格式
+ if (index == 'activity') {
+ columns = activityColumns(object, t_month);
+ hasDetail = true;
+ }
+ if (index == 'activity' && showDetail == true) {
+ columns = activityDetailColumns(object, t_month);
+ hasDetail = true;
+ }
+ if (index == 'open_rank') {
+ columns = open_rankColumns(object, t_month);
+ hasDetail = false;
+ showDetail = false;
+ }
+ // 如果是年份数据,则把 month 置为 null。
+ // TODO:待验证,如果从年份数据切换到月份数据,似乎会自动回到原来 month 值?
+ if (type == 'year') {
+ month = null;
+ }
+ // 以当前的属性构造请求 url
+ let url = base + index + '/' + object + '/' + region + '/';
+ if (month === null) {
+ url += year + '.json';
+ } else {
+ url += year + (1 + month) + '.json';
+ }
+ console.log(url);
+ console.log(region);
+ if (object == "foundation") {
+ url = './tech-foundation/'+ object + region +'.json'
+ }
+ else if (object == "technology") {
+ url = './tech-foundation/'+ object + category +'.json'
+ }
+ // fetch 异步请求
+ fetch(url)
+ .then((res) => {
+ // Todo:最好的情况是在日期选择器中,只显示可以查询的日期,
+ if (res.status == 404) {
+ message.warning(t('no_result'));
+ return '';
+ }
+ return res.json();
+ })
+ .then((data) => {
+ data = data.data;
+ let dataSource = [];
+ // 预处理数据,对新上榜单数据进行特殊标记处理
+ data.map((obj) => {
+ obj = expandObject(obj);
+ if (obj.rankDelta == 0 && obj.value == obj.valueDelta) {
+ obj.rankDelta = -10000000;
+ obj.valueDelta = 0;
+ }
+ dataSource.push(obj);
+ });
+ console.log(dataSource);
+
+ //搜索特定数据
+ let queryData;
+ if (search) {
+ queryData = dataSource.filter((dataSource) => {
+ let reg = new RegExp(search.trim(), 'i');
+ return reg.test(dataSource.name);
+ });
+ if (queryData.length == 0) {
+ message.warning(t('no_result'));
+ } else {
+ dataSource = queryData;
+ }
+ }
+
+ // 更新属性和表格数据
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ showDetail: showDetail,
+ hasDetail: hasDetail,
+ data: dataSource,
+ });
+ })
+ .catch((err) => {
+ console.log('hi!' + err);
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ data: [],
+ });
+ });
+
+
+ };
+
+ const {
+ object,
+ index,
+ region,
+ data,
+ columns,
+ loading,
+ showSize,
+ showDetail,
+ hasDetail,
+ month,
+ year,
+ type,
+ category,
+ } = state;
+ return (
+
+
+
+
+ record.rank}
+ dataSource={data.slice(0, Math.min(showSize, data.length))}
+ pagination={false}
+ loading={loading}
+ scroll={{ x: 'max-content' }}
+ />
+
+
+
+
+ {showSize < data.length ? (
+
+ {t('showMore') + '>>'}
+
+ ) : (
+
+ {t('noMore')}
+
+ )}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+}
+
+export default MyTable;
diff --git a/.history/src/components/table_20240728195002.js b/.history/src/components/table_20240728195002.js
new file mode 100644
index 0000000..24f1e5d
--- /dev/null
+++ b/.history/src/components/table_20240728195002.js
@@ -0,0 +1,593 @@
+import React, { useState, useEffect } from 'react';
+import { Col, message, Row, Table, Card } from 'antd';
+import MyAvatar from './avatar';
+import 'antd/dist/antd.css';
+import QAmiss from './QA2';
+import TablePanel from './TablePanel';
+import ArrowRender from './arrow';
+import PointRender from './changeNumber';
+import RoundFloat from './resolveFloat';
+import Trophy from './rankTrophy';
+import expandObject from '../util/expandObject';
+import { t } from 'i18next';
+import './table.css';
+import { foundationChineseData } from './data';
+
+const activityColumns = (object, t_month) => [
+ {
+ title: t('rank'),
+ dataIndex: 'rank',
+ width: '5%',
+ align: 'center',
+ render: Trophy,
+ fixed: 'left',
+ },
+ ...(object == 'actor'
+ ? [
+ {
+ title: t('avatar'),
+ dataIndex: 'id',
+ width: '5%',
+ align: 'center',
+ render: MyAvatar,
+ fixed: 'left',
+ },
+ ]
+ : []),
+ {
+ title: '',
+ dataIndex: 'rankDelta',
+ render: ArrowRender,
+ align: 'left',
+ width: '5%',
+ fixed: 'left',
+ },
+ {
+ title: t(object),
+ dataIndex: 'name',
+ align: 'center',
+ width: '20%',
+ render: function (text, row, index) {
+ if (object !== 'company') {
+ return (
+
+ {text}
+
+ );
+ } else {
+ return text;
+ }
+ },
+ },
+ ...(object == 'repo'
+ ? [
+ {
+ title: t('insight_board'),
+ dataIndex: 'name',
+ align: 'center',
+ width: '10%',
+ render: function (text, row, index) {
+ return dashboard(text, index, t_month);
+ },
+ },
+ ]
+ : []),
+ {
+ title: t('activity'),
+ dataIndex: 'value',
+ align: 'right',
+ width: '20%',
+ },
+ {
+ title: '',
+ dataIndex: 'valueDelta',
+ width: '10%',
+ align: 'left',
+ render: PointRender,
+ },
+];
+const activityDetailColumns = (object, t_month) => [
+ {
+ title: t('rank'),
+ dataIndex: 'rank',
+ width: '5%',
+ align: 'center',
+ render: Trophy,
+ fixed: 'left',
+ },
+ ...(object == 'actor'
+ ? [
+ {
+ title: t('avatar'),
+ dataIndex: 'id',
+ width: '5%',
+ align: 'center',
+ render: MyAvatar,
+ fixed: 'left',
+ },
+ ]
+ : []),
+ {
+ title: '',
+ dataIndex: 'rankDelta',
+ render: ArrowRender,
+ align: 'left',
+ width: '5%',
+ fixed: 'left',
+ },
+ {
+ title: t(object),
+ dataIndex: 'name',
+ align: 'center',
+ width: '5%',
+ render: function (text, row, index) {
+ if (object !== 'company') {
+ return (
+
+ {text}
+
+ );
+ } else {
+ return text;
+ }
+ },
+ },
+ ...(object == 'repo'
+ ? [
+ {
+ title: t('insight_board'),
+ dataIndex: 'name',
+ align: 'center',
+ width: '10%',
+ render: function (text, row, index) {
+ return dashboard(text, index, t_month);
+ },
+ },
+ ]
+ : []),
+ {
+ title: t('activity'),
+ dataIndex: 'value',
+ align: 'center',
+ width: '10%',
+ },
+ {
+ title: '',
+ dataIndex: 'valueDelta',
+ width: '10%',
+ align: 'left',
+ render: PointRender,
+ },
+ {
+ title: t('issue_comments'),
+ dataIndex: 'issue_comment',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('open_issues'),
+ dataIndex: 'open_issue',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('open_pulls'),
+ dataIndex: 'open_pull',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('merge_pulls'),
+ dataIndex: 'merged_pull',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('pr_reviews'),
+ dataIndex: 'review_comment',
+ width: '10%',
+ align: 'center',
+ },
+];
+const open_rankColumns = (object, t_month) => [
+ {
+ // 第一列:排名
+ title: t('rank'),
+ dataIndex: 'rank',
+ width: '5%',
+ render: Trophy,
+ align: 'center',
+ fixed: 'left',
+ },
+ // 如果 object 是 'actor',则添加头像列
+ ...(object == 'actor'
+ ? [
+ {
+ title: t('avatar'),
+ dataIndex: 'id',
+ width: '5%',
+ align: 'center',
+ render: MyAvatar,
+ fixed: 'left',
+ },
+ ]
+ : []),
+ // 第二列:排名变化
+ {
+ title: '',
+ dataIndex: 'rankDelta',
+ render: ArrowRender,
+ align: 'left',
+ width: '5%',
+ fixed: 'left',
+ },
+ // 第三列:对象名称(可能是 actor, repo 或 company)
+ {
+ title: t(object),
+ dataIndex: 'name',
+ width: '20%',
+ align: 'center',
+ render: function (text) {
+ if (object !== 'company') {
+ return (
+
+ {text}
+
+ );
+ } else {
+ return text;
+ }
+ },
+ },
+ // 如果 object 是 'repo',则添加 insight_board 列
+ ...(object == 'repo'
+ ? [
+ {
+ title: t('insight_board'),
+ dataIndex: 'name',
+ align: 'center',
+ width: '10%',
+ render: function (text, row, index) {
+ return dashboard(text, index, t_month);
+ },
+ },
+ ]
+ : []),
+ // 第四列:影响力
+ {
+ title: t('influence'),
+ dataIndex: 'value',
+ width: '20%',
+ align: 'right',
+ render: (text, row, index) => {
+ return RoundFloat(text);
+ },
+ },
+ // 第五列:影响力变化
+ {
+ title: '',
+ dataIndex: 'valueDelta',
+ width: '10%',
+ align: 'left',
+ render: (text, row, index) => {
+ text = RoundFloat(text);
+ return PointRender(text, row, index);
+ },
+ },
+];
+
+const solveDate = (year, month) => {
+ if (year === null && month === null) {
+ return 'not found';
+ }
+ if (month === null) {
+ return year + '年';
+ }
+ return year + '年' + (month + 1) + '月';
+};
+
+function dashboard(text, index, t_month) {
+ if (index < 300) {
+ let [org_name, repo_name] = text.split('/');
+ const t_month_copy = t_month + ' ' + '00:00:00';
+ let params = {
+ org_name,
+ repo_name,
+ t_month_copy,
+ t_month,
+ };
+ return (
+
+
+
+ );
+ }
+}
+
+function DateTitle(props) {
+ return {solveDate(props.year, props.month)}
;
+}
+
+function MyTable(props) {
+ const [state, setState] = useState({
+ object: 'technology',
+ index: 'open_rank',
+ region: 'global',
+ showDetail: false,
+ hasDetail: true,
+ data: [],
+ showSize: 25,
+ loading: true,
+ url: '', // base + index + object + region + yearmonth + .json
+ base: 'https://oss.x-lab.info/open_leaderboard/',
+ year: null, // 字符串格式
+ month: null, // 整数格式,0表示1月,1表示2月..., null for year type time
+ type: 'month',
+ search: null,
+ category: 'cloud-native',
+ });
+
+ // 请求一次数据更新表格。如果还没读取好配置文件则不请求数据。
+ useEffect(() => {
+ if (props.year == null && props.month == null) {
+ console.log('the first loading');
+ return;
+ }
+ updateDate({
+ year: String(props.year),
+ month: props.month,
+ });
+ }, [props]);
+
+ const expandData = () => {
+ setState({
+ ...state,
+ showSize: state.showSize + 25,
+ });
+ };
+ const updateDate = (newstate) => {
+ console.log('table update', newstate);
+ // 先获取原先的表格属性
+ let {
+ base,
+ object,
+ index,
+ region,
+ month,
+ year,
+ columns,
+ showDetail,
+ hasDetail,
+ type,
+ search,
+ category,
+ } = state;
+ // 然后把表格改为加载中的状态
+ setState({ ...state, ...newstate, loading: true });
+ // 如果 newstate 有对应的属性,则进行更新
+ if (newstate.hasOwnProperty('object')) object = newstate.object;
+ if (newstate.hasOwnProperty('index')) index = newstate.index;
+ if (newstate.hasOwnProperty('region')) region = newstate.region;
+ if (newstate.hasOwnProperty('month')) month = newstate.month;
+ if (newstate.hasOwnProperty('year')) year = newstate.year;
+ if (newstate.hasOwnProperty('showDetail')) showDetail = newstate.showDetail;
+ if (newstate.hasOwnProperty('type')) type = newstate.type;
+ if (newstate.hasOwnProperty('search')) search = newstate.search;
+ if (newstate.hasOwnProperty('category')) category = newstate.category;
+
+ //获取数据大屏的‘t_month’参数
+ let myyear = newstate.year == null ? state.year : newstate.year;
+ let mymonth = newstate.month == null ? state.month : newstate.month;
+
+ mymonth = ('' + (1 + mymonth)).padStart(2, '0');
+ let t_month = `${myyear}-${mymonth}-01`;
+
+ // 根据 index 和 showDetail 改变表格的 columns 格式
+ if (index == 'activity') {
+ columns = activityColumns(object, t_month);
+ hasDetail = true;
+ }
+ if (index == 'activity' && showDetail == true) {
+ columns = activityDetailColumns(object, t_month);
+ hasDetail = true;
+ }
+ if (index == 'open_rank') {
+ columns = open_rankColumns(object, t_month);
+ hasDetail = false;
+ showDetail = false;
+ }
+ // 如果是年份数据,则把 month 置为 null。
+ // TODO:待验证,如果从年份数据切换到月份数据,似乎会自动回到原来 month 值?
+ if (type == 'year') {
+ month = null;
+ }
+ // 以当前的属性构造请求 url
+ let url = base + index + '/' + object + '/' + region + '/';
+ if (month === null) {
+ url += year + '.json';
+ } else {
+ url += year + (1 + month) + '.json';
+ }
+ console.log(url);
+ console.log(region);
+ if (object == "foundation") {
+ url = './tech-foundation/'+ object + region +'.json'
+ }
+ else if (object == "technology") {
+ url = './tech-foundation/'+ object + category +'.json'
+ }
+ // fetch 异步请求
+ fetch(url)
+ .then((res) => {
+ // Todo:最好的情况是在日期选择器中,只显示可以查询的日期,
+ if (res.status == 404) {
+ message.warning(t('no_result'));
+ return '';
+ }
+ return res.json();
+ })
+ .then((data) => {
+ data = data.data;
+ let dataSource = [];
+ // 预处理数据,对新上榜单数据进行特殊标记处理
+ data.map((obj) => {
+ obj = expandObject(obj);
+ if (obj.rankDelta == 0 && obj.value == obj.valueDelta) {
+ obj.rankDelta = -10000000;
+ obj.valueDelta = 0;
+ }
+ dataSource.push(obj);
+ });
+ console.log(dataSource);
+
+ //搜索特定数据
+ let queryData;
+ if (search) {
+ queryData = dataSource.filter((dataSource) => {
+ let reg = new RegExp(search.trim(), 'i');
+ return reg.test(dataSource.name);
+ });
+ if (queryData.length == 0) {
+ message.warning(t('no_result'));
+ } else {
+ dataSource = queryData;
+ }
+ }
+
+ // 更新属性和表格数据
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ showDetail: showDetail,
+ hasDetail: hasDetail,
+ data: dataSource,
+ });
+ })
+ .catch((err) => {
+ console.log('hi!' + err);
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ data: [],
+ });
+ });
+
+
+ };
+
+ const {
+ object,
+ index,
+ region,
+ data,
+ columns,
+ loading,
+ showSize,
+ showDetail,
+ hasDetail,
+ month,
+ year,
+ type,
+ category,
+ } = state;
+ return (
+
+
+
+
+ record.rank}
+ dataSource={data.slice(0, Math.min(showSize, data.length))}
+ pagination={false}
+ loading={loading}
+ scroll={{ x: 'max-content' }}
+ />
+
+
+
+
+ {showSize < data.length ? (
+
+ {t('showMore') + '>>'}
+
+ ) : (
+
+ {t('noMore')}
+
+ )}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+}
+
+export default MyTable;
diff --git a/.history/src/components/table_20240728195126.js b/.history/src/components/table_20240728195126.js
new file mode 100644
index 0000000..24f1e5d
--- /dev/null
+++ b/.history/src/components/table_20240728195126.js
@@ -0,0 +1,593 @@
+import React, { useState, useEffect } from 'react';
+import { Col, message, Row, Table, Card } from 'antd';
+import MyAvatar from './avatar';
+import 'antd/dist/antd.css';
+import QAmiss from './QA2';
+import TablePanel from './TablePanel';
+import ArrowRender from './arrow';
+import PointRender from './changeNumber';
+import RoundFloat from './resolveFloat';
+import Trophy from './rankTrophy';
+import expandObject from '../util/expandObject';
+import { t } from 'i18next';
+import './table.css';
+import { foundationChineseData } from './data';
+
+const activityColumns = (object, t_month) => [
+ {
+ title: t('rank'),
+ dataIndex: 'rank',
+ width: '5%',
+ align: 'center',
+ render: Trophy,
+ fixed: 'left',
+ },
+ ...(object == 'actor'
+ ? [
+ {
+ title: t('avatar'),
+ dataIndex: 'id',
+ width: '5%',
+ align: 'center',
+ render: MyAvatar,
+ fixed: 'left',
+ },
+ ]
+ : []),
+ {
+ title: '',
+ dataIndex: 'rankDelta',
+ render: ArrowRender,
+ align: 'left',
+ width: '5%',
+ fixed: 'left',
+ },
+ {
+ title: t(object),
+ dataIndex: 'name',
+ align: 'center',
+ width: '20%',
+ render: function (text, row, index) {
+ if (object !== 'company') {
+ return (
+
+ {text}
+
+ );
+ } else {
+ return text;
+ }
+ },
+ },
+ ...(object == 'repo'
+ ? [
+ {
+ title: t('insight_board'),
+ dataIndex: 'name',
+ align: 'center',
+ width: '10%',
+ render: function (text, row, index) {
+ return dashboard(text, index, t_month);
+ },
+ },
+ ]
+ : []),
+ {
+ title: t('activity'),
+ dataIndex: 'value',
+ align: 'right',
+ width: '20%',
+ },
+ {
+ title: '',
+ dataIndex: 'valueDelta',
+ width: '10%',
+ align: 'left',
+ render: PointRender,
+ },
+];
+const activityDetailColumns = (object, t_month) => [
+ {
+ title: t('rank'),
+ dataIndex: 'rank',
+ width: '5%',
+ align: 'center',
+ render: Trophy,
+ fixed: 'left',
+ },
+ ...(object == 'actor'
+ ? [
+ {
+ title: t('avatar'),
+ dataIndex: 'id',
+ width: '5%',
+ align: 'center',
+ render: MyAvatar,
+ fixed: 'left',
+ },
+ ]
+ : []),
+ {
+ title: '',
+ dataIndex: 'rankDelta',
+ render: ArrowRender,
+ align: 'left',
+ width: '5%',
+ fixed: 'left',
+ },
+ {
+ title: t(object),
+ dataIndex: 'name',
+ align: 'center',
+ width: '5%',
+ render: function (text, row, index) {
+ if (object !== 'company') {
+ return (
+
+ {text}
+
+ );
+ } else {
+ return text;
+ }
+ },
+ },
+ ...(object == 'repo'
+ ? [
+ {
+ title: t('insight_board'),
+ dataIndex: 'name',
+ align: 'center',
+ width: '10%',
+ render: function (text, row, index) {
+ return dashboard(text, index, t_month);
+ },
+ },
+ ]
+ : []),
+ {
+ title: t('activity'),
+ dataIndex: 'value',
+ align: 'center',
+ width: '10%',
+ },
+ {
+ title: '',
+ dataIndex: 'valueDelta',
+ width: '10%',
+ align: 'left',
+ render: PointRender,
+ },
+ {
+ title: t('issue_comments'),
+ dataIndex: 'issue_comment',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('open_issues'),
+ dataIndex: 'open_issue',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('open_pulls'),
+ dataIndex: 'open_pull',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('merge_pulls'),
+ dataIndex: 'merged_pull',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('pr_reviews'),
+ dataIndex: 'review_comment',
+ width: '10%',
+ align: 'center',
+ },
+];
+const open_rankColumns = (object, t_month) => [
+ {
+ // 第一列:排名
+ title: t('rank'),
+ dataIndex: 'rank',
+ width: '5%',
+ render: Trophy,
+ align: 'center',
+ fixed: 'left',
+ },
+ // 如果 object 是 'actor',则添加头像列
+ ...(object == 'actor'
+ ? [
+ {
+ title: t('avatar'),
+ dataIndex: 'id',
+ width: '5%',
+ align: 'center',
+ render: MyAvatar,
+ fixed: 'left',
+ },
+ ]
+ : []),
+ // 第二列:排名变化
+ {
+ title: '',
+ dataIndex: 'rankDelta',
+ render: ArrowRender,
+ align: 'left',
+ width: '5%',
+ fixed: 'left',
+ },
+ // 第三列:对象名称(可能是 actor, repo 或 company)
+ {
+ title: t(object),
+ dataIndex: 'name',
+ width: '20%',
+ align: 'center',
+ render: function (text) {
+ if (object !== 'company') {
+ return (
+
+ {text}
+
+ );
+ } else {
+ return text;
+ }
+ },
+ },
+ // 如果 object 是 'repo',则添加 insight_board 列
+ ...(object == 'repo'
+ ? [
+ {
+ title: t('insight_board'),
+ dataIndex: 'name',
+ align: 'center',
+ width: '10%',
+ render: function (text, row, index) {
+ return dashboard(text, index, t_month);
+ },
+ },
+ ]
+ : []),
+ // 第四列:影响力
+ {
+ title: t('influence'),
+ dataIndex: 'value',
+ width: '20%',
+ align: 'right',
+ render: (text, row, index) => {
+ return RoundFloat(text);
+ },
+ },
+ // 第五列:影响力变化
+ {
+ title: '',
+ dataIndex: 'valueDelta',
+ width: '10%',
+ align: 'left',
+ render: (text, row, index) => {
+ text = RoundFloat(text);
+ return PointRender(text, row, index);
+ },
+ },
+];
+
+const solveDate = (year, month) => {
+ if (year === null && month === null) {
+ return 'not found';
+ }
+ if (month === null) {
+ return year + '年';
+ }
+ return year + '年' + (month + 1) + '月';
+};
+
+function dashboard(text, index, t_month) {
+ if (index < 300) {
+ let [org_name, repo_name] = text.split('/');
+ const t_month_copy = t_month + ' ' + '00:00:00';
+ let params = {
+ org_name,
+ repo_name,
+ t_month_copy,
+ t_month,
+ };
+ return (
+
+
+
+ );
+ }
+}
+
+function DateTitle(props) {
+ return {solveDate(props.year, props.month)}
;
+}
+
+function MyTable(props) {
+ const [state, setState] = useState({
+ object: 'technology',
+ index: 'open_rank',
+ region: 'global',
+ showDetail: false,
+ hasDetail: true,
+ data: [],
+ showSize: 25,
+ loading: true,
+ url: '', // base + index + object + region + yearmonth + .json
+ base: 'https://oss.x-lab.info/open_leaderboard/',
+ year: null, // 字符串格式
+ month: null, // 整数格式,0表示1月,1表示2月..., null for year type time
+ type: 'month',
+ search: null,
+ category: 'cloud-native',
+ });
+
+ // 请求一次数据更新表格。如果还没读取好配置文件则不请求数据。
+ useEffect(() => {
+ if (props.year == null && props.month == null) {
+ console.log('the first loading');
+ return;
+ }
+ updateDate({
+ year: String(props.year),
+ month: props.month,
+ });
+ }, [props]);
+
+ const expandData = () => {
+ setState({
+ ...state,
+ showSize: state.showSize + 25,
+ });
+ };
+ const updateDate = (newstate) => {
+ console.log('table update', newstate);
+ // 先获取原先的表格属性
+ let {
+ base,
+ object,
+ index,
+ region,
+ month,
+ year,
+ columns,
+ showDetail,
+ hasDetail,
+ type,
+ search,
+ category,
+ } = state;
+ // 然后把表格改为加载中的状态
+ setState({ ...state, ...newstate, loading: true });
+ // 如果 newstate 有对应的属性,则进行更新
+ if (newstate.hasOwnProperty('object')) object = newstate.object;
+ if (newstate.hasOwnProperty('index')) index = newstate.index;
+ if (newstate.hasOwnProperty('region')) region = newstate.region;
+ if (newstate.hasOwnProperty('month')) month = newstate.month;
+ if (newstate.hasOwnProperty('year')) year = newstate.year;
+ if (newstate.hasOwnProperty('showDetail')) showDetail = newstate.showDetail;
+ if (newstate.hasOwnProperty('type')) type = newstate.type;
+ if (newstate.hasOwnProperty('search')) search = newstate.search;
+ if (newstate.hasOwnProperty('category')) category = newstate.category;
+
+ //获取数据大屏的‘t_month’参数
+ let myyear = newstate.year == null ? state.year : newstate.year;
+ let mymonth = newstate.month == null ? state.month : newstate.month;
+
+ mymonth = ('' + (1 + mymonth)).padStart(2, '0');
+ let t_month = `${myyear}-${mymonth}-01`;
+
+ // 根据 index 和 showDetail 改变表格的 columns 格式
+ if (index == 'activity') {
+ columns = activityColumns(object, t_month);
+ hasDetail = true;
+ }
+ if (index == 'activity' && showDetail == true) {
+ columns = activityDetailColumns(object, t_month);
+ hasDetail = true;
+ }
+ if (index == 'open_rank') {
+ columns = open_rankColumns(object, t_month);
+ hasDetail = false;
+ showDetail = false;
+ }
+ // 如果是年份数据,则把 month 置为 null。
+ // TODO:待验证,如果从年份数据切换到月份数据,似乎会自动回到原来 month 值?
+ if (type == 'year') {
+ month = null;
+ }
+ // 以当前的属性构造请求 url
+ let url = base + index + '/' + object + '/' + region + '/';
+ if (month === null) {
+ url += year + '.json';
+ } else {
+ url += year + (1 + month) + '.json';
+ }
+ console.log(url);
+ console.log(region);
+ if (object == "foundation") {
+ url = './tech-foundation/'+ object + region +'.json'
+ }
+ else if (object == "technology") {
+ url = './tech-foundation/'+ object + category +'.json'
+ }
+ // fetch 异步请求
+ fetch(url)
+ .then((res) => {
+ // Todo:最好的情况是在日期选择器中,只显示可以查询的日期,
+ if (res.status == 404) {
+ message.warning(t('no_result'));
+ return '';
+ }
+ return res.json();
+ })
+ .then((data) => {
+ data = data.data;
+ let dataSource = [];
+ // 预处理数据,对新上榜单数据进行特殊标记处理
+ data.map((obj) => {
+ obj = expandObject(obj);
+ if (obj.rankDelta == 0 && obj.value == obj.valueDelta) {
+ obj.rankDelta = -10000000;
+ obj.valueDelta = 0;
+ }
+ dataSource.push(obj);
+ });
+ console.log(dataSource);
+
+ //搜索特定数据
+ let queryData;
+ if (search) {
+ queryData = dataSource.filter((dataSource) => {
+ let reg = new RegExp(search.trim(), 'i');
+ return reg.test(dataSource.name);
+ });
+ if (queryData.length == 0) {
+ message.warning(t('no_result'));
+ } else {
+ dataSource = queryData;
+ }
+ }
+
+ // 更新属性和表格数据
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ showDetail: showDetail,
+ hasDetail: hasDetail,
+ data: dataSource,
+ });
+ })
+ .catch((err) => {
+ console.log('hi!' + err);
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ data: [],
+ });
+ });
+
+
+ };
+
+ const {
+ object,
+ index,
+ region,
+ data,
+ columns,
+ loading,
+ showSize,
+ showDetail,
+ hasDetail,
+ month,
+ year,
+ type,
+ category,
+ } = state;
+ return (
+
+
+
+
+ record.rank}
+ dataSource={data.slice(0, Math.min(showSize, data.length))}
+ pagination={false}
+ loading={loading}
+ scroll={{ x: 'max-content' }}
+ />
+
+
+
+
+ {showSize < data.length ? (
+
+ {t('showMore') + '>>'}
+
+ ) : (
+
+ {t('noMore')}
+
+ )}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+}
+
+export default MyTable;
diff --git a/.history/src/components/table_20240728195614.js b/.history/src/components/table_20240728195614.js
new file mode 100644
index 0000000..a4b0fc6
--- /dev/null
+++ b/.history/src/components/table_20240728195614.js
@@ -0,0 +1,592 @@
+import React, { useState, useEffect } from 'react';
+import { Col, message, Row, Table, Card } from 'antd';
+import MyAvatar from './avatar';
+import 'antd/dist/antd.css';
+import QAmiss from './QA2';
+import TablePanel from './TablePanel';
+import ArrowRender from './arrow';
+import PointRender from './changeNumber';
+import RoundFloat from './resolveFloat';
+import Trophy from './rankTrophy';
+import expandObject from '../util/expandObject';
+import { t } from 'i18next';
+import './table.css';
+
+const activityColumns = (object, t_month) => [
+ {
+ title: t('rank'),
+ dataIndex: 'rank',
+ width: '5%',
+ align: 'center',
+ render: Trophy,
+ fixed: 'left',
+ },
+ ...(object == 'actor'
+ ? [
+ {
+ title: t('avatar'),
+ dataIndex: 'id',
+ width: '5%',
+ align: 'center',
+ render: MyAvatar,
+ fixed: 'left',
+ },
+ ]
+ : []),
+ {
+ title: '',
+ dataIndex: 'rankDelta',
+ render: ArrowRender,
+ align: 'left',
+ width: '5%',
+ fixed: 'left',
+ },
+ {
+ title: t(object),
+ dataIndex: 'name',
+ align: 'center',
+ width: '20%',
+ render: function (text, row, index) {
+ if (object !== 'company') {
+ return (
+
+ {text}
+
+ );
+ } else {
+ return text;
+ }
+ },
+ },
+ ...(object == 'repo'
+ ? [
+ {
+ title: t('insight_board'),
+ dataIndex: 'name',
+ align: 'center',
+ width: '10%',
+ render: function (text, row, index) {
+ return dashboard(text, index, t_month);
+ },
+ },
+ ]
+ : []),
+ {
+ title: t('activity'),
+ dataIndex: 'value',
+ align: 'right',
+ width: '20%',
+ },
+ {
+ title: '',
+ dataIndex: 'valueDelta',
+ width: '10%',
+ align: 'left',
+ render: PointRender,
+ },
+];
+const activityDetailColumns = (object, t_month) => [
+ {
+ title: t('rank'),
+ dataIndex: 'rank',
+ width: '5%',
+ align: 'center',
+ render: Trophy,
+ fixed: 'left',
+ },
+ ...(object == 'actor'
+ ? [
+ {
+ title: t('avatar'),
+ dataIndex: 'id',
+ width: '5%',
+ align: 'center',
+ render: MyAvatar,
+ fixed: 'left',
+ },
+ ]
+ : []),
+ {
+ title: '',
+ dataIndex: 'rankDelta',
+ render: ArrowRender,
+ align: 'left',
+ width: '5%',
+ fixed: 'left',
+ },
+ {
+ title: t(object),
+ dataIndex: 'name',
+ align: 'center',
+ width: '5%',
+ render: function (text, row, index) {
+ if (object !== 'company') {
+ return (
+
+ {text}
+
+ );
+ } else {
+ return text;
+ }
+ },
+ },
+ ...(object == 'repo'
+ ? [
+ {
+ title: t('insight_board'),
+ dataIndex: 'name',
+ align: 'center',
+ width: '10%',
+ render: function (text, row, index) {
+ return dashboard(text, index, t_month);
+ },
+ },
+ ]
+ : []),
+ {
+ title: t('activity'),
+ dataIndex: 'value',
+ align: 'center',
+ width: '10%',
+ },
+ {
+ title: '',
+ dataIndex: 'valueDelta',
+ width: '10%',
+ align: 'left',
+ render: PointRender,
+ },
+ {
+ title: t('issue_comments'),
+ dataIndex: 'issue_comment',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('open_issues'),
+ dataIndex: 'open_issue',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('open_pulls'),
+ dataIndex: 'open_pull',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('merge_pulls'),
+ dataIndex: 'merged_pull',
+ width: '10%',
+ align: 'center',
+ },
+ {
+ title: t('pr_reviews'),
+ dataIndex: 'review_comment',
+ width: '10%',
+ align: 'center',
+ },
+];
+const open_rankColumns = (object, t_month) => [
+ {
+ // 第一列:排名
+ title: t('rank'),
+ dataIndex: 'rank',
+ width: '5%',
+ render: Trophy,
+ align: 'center',
+ fixed: 'left',
+ },
+ // 如果 object 是 'actor',则添加头像列
+ ...(object == 'actor'
+ ? [
+ {
+ title: t('avatar'),
+ dataIndex: 'id',
+ width: '5%',
+ align: 'center',
+ render: MyAvatar,
+ fixed: 'left',
+ },
+ ]
+ : []),
+ // 第二列:排名变化
+ {
+ title: '',
+ dataIndex: 'rankDelta',
+ render: ArrowRender,
+ align: 'left',
+ width: '5%',
+ fixed: 'left',
+ },
+ // 第三列:对象名称(可能是 actor, repo 或 company)
+ {
+ title: t(object),
+ dataIndex: 'name',
+ width: '20%',
+ align: 'center',
+ render: function (text) {
+ if (object !== 'company') {
+ return (
+
+ {text}
+
+ );
+ } else {
+ return text;
+ }
+ },
+ },
+ // 如果 object 是 'repo',则添加 insight_board 列
+ ...(object == 'repo'
+ ? [
+ {
+ title: t('insight_board'),
+ dataIndex: 'name',
+ align: 'center',
+ width: '10%',
+ render: function (text, row, index) {
+ return dashboard(text, index, t_month);
+ },
+ },
+ ]
+ : []),
+ // 第四列:影响力
+ {
+ title: t('influence'),
+ dataIndex: 'value',
+ width: '20%',
+ align: 'right',
+ render: (text, row, index) => {
+ return RoundFloat(text);
+ },
+ },
+ // 第五列:影响力变化
+ {
+ title: '',
+ dataIndex: 'valueDelta',
+ width: '10%',
+ align: 'left',
+ render: (text, row, index) => {
+ text = RoundFloat(text);
+ return PointRender(text, row, index);
+ },
+ },
+];
+
+const solveDate = (year, month) => {
+ if (year === null && month === null) {
+ return 'not found';
+ }
+ if (month === null) {
+ return year + '年';
+ }
+ return year + '年' + (month + 1) + '月';
+};
+
+function dashboard(text, index, t_month) {
+ if (index < 300) {
+ let [org_name, repo_name] = text.split('/');
+ const t_month_copy = t_month + ' ' + '00:00:00';
+ let params = {
+ org_name,
+ repo_name,
+ t_month_copy,
+ t_month,
+ };
+ return (
+
+
+
+ );
+ }
+}
+
+function DateTitle(props) {
+ return {solveDate(props.year, props.month)}
;
+}
+
+function MyTable(props) {
+ const [state, setState] = useState({
+ object: 'technology',
+ index: 'open_rank',
+ region: 'global',
+ showDetail: false,
+ hasDetail: true,
+ data: [],
+ showSize: 25,
+ loading: true,
+ url: '', // base + index + object + region + yearmonth + .json
+ base: 'https://oss.x-lab.info/open_leaderboard/',
+ year: null, // 字符串格式
+ month: null, // 整数格式,0表示1月,1表示2月..., null for year type time
+ type: 'month',
+ search: null,
+ category: 'cloud-native',
+ });
+
+ // 请求一次数据更新表格。如果还没读取好配置文件则不请求数据。
+ useEffect(() => {
+ if (props.year == null && props.month == null) {
+ console.log('the first loading');
+ return;
+ }
+ updateDate({
+ year: String(props.year),
+ month: props.month,
+ });
+ }, [props]);
+
+ const expandData = () => {
+ setState({
+ ...state,
+ showSize: state.showSize + 25,
+ });
+ };
+ const updateDate = (newstate) => {
+ console.log('table update', newstate);
+ // 先获取原先的表格属性
+ let {
+ base,
+ object,
+ index,
+ region,
+ month,
+ year,
+ columns,
+ showDetail,
+ hasDetail,
+ type,
+ search,
+ category,
+ } = state;
+ // 然后把表格改为加载中的状态
+ setState({ ...state, ...newstate, loading: true });
+ // 如果 newstate 有对应的属性,则进行更新
+ if (newstate.hasOwnProperty('object')) object = newstate.object;
+ if (newstate.hasOwnProperty('index')) index = newstate.index;
+ if (newstate.hasOwnProperty('region')) region = newstate.region;
+ if (newstate.hasOwnProperty('month')) month = newstate.month;
+ if (newstate.hasOwnProperty('year')) year = newstate.year;
+ if (newstate.hasOwnProperty('showDetail')) showDetail = newstate.showDetail;
+ if (newstate.hasOwnProperty('type')) type = newstate.type;
+ if (newstate.hasOwnProperty('search')) search = newstate.search;
+ if (newstate.hasOwnProperty('category')) category = newstate.category;
+
+ //获取数据大屏的‘t_month’参数
+ let myyear = newstate.year == null ? state.year : newstate.year;
+ let mymonth = newstate.month == null ? state.month : newstate.month;
+
+ mymonth = ('' + (1 + mymonth)).padStart(2, '0');
+ let t_month = `${myyear}-${mymonth}-01`;
+
+ // 根据 index 和 showDetail 改变表格的 columns 格式
+ if (index == 'activity') {
+ columns = activityColumns(object, t_month);
+ hasDetail = true;
+ }
+ if (index == 'activity' && showDetail == true) {
+ columns = activityDetailColumns(object, t_month);
+ hasDetail = true;
+ }
+ if (index == 'open_rank') {
+ columns = open_rankColumns(object, t_month);
+ hasDetail = false;
+ showDetail = false;
+ }
+ // 如果是年份数据,则把 month 置为 null。
+ // TODO:待验证,如果从年份数据切换到月份数据,似乎会自动回到原来 month 值?
+ if (type == 'year') {
+ month = null;
+ }
+ // 以当前的属性构造请求 url
+ let url = base + index + '/' + object + '/' + region + '/';
+ if (month === null) {
+ url += year + '.json';
+ } else {
+ url += year + (1 + month) + '.json';
+ }
+ console.log(url);
+ console.log(region);
+ if (object == "foundation") {
+ url = './tech-foundation/'+ object + region +'.json'
+ }
+ else if (object == "technology") {
+ url = './tech-foundation/'+ object + category +'.json'
+ }
+ // fetch 异步请求
+ fetch(url)
+ .then((res) => {
+ // Todo:最好的情况是在日期选择器中,只显示可以查询的日期,
+ if (res.status == 404) {
+ message.warning(t('no_result'));
+ return '';
+ }
+ return res.json();
+ })
+ .then((data) => {
+ data = data.data;
+ let dataSource = [];
+ // 预处理数据,对新上榜单数据进行特殊标记处理
+ data.map((obj) => {
+ obj = expandObject(obj);
+ if (obj.rankDelta == 0 && obj.value == obj.valueDelta) {
+ obj.rankDelta = -10000000;
+ obj.valueDelta = 0;
+ }
+ dataSource.push(obj);
+ });
+ console.log(dataSource);
+
+ //搜索特定数据
+ let queryData;
+ if (search) {
+ queryData = dataSource.filter((dataSource) => {
+ let reg = new RegExp(search.trim(), 'i');
+ return reg.test(dataSource.name);
+ });
+ if (queryData.length == 0) {
+ message.warning(t('no_result'));
+ } else {
+ dataSource = queryData;
+ }
+ }
+
+ // 更新属性和表格数据
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ showDetail: showDetail,
+ hasDetail: hasDetail,
+ data: dataSource,
+ });
+ })
+ .catch((err) => {
+ console.log('hi!' + err);
+ setState({
+ ...state,
+ ...newstate,
+ loading: false,
+ columns: columns,
+ data: [],
+ });
+ });
+
+
+ };
+
+ const {
+ object,
+ index,
+ region,
+ data,
+ columns,
+ loading,
+ showSize,
+ showDetail,
+ hasDetail,
+ month,
+ year,
+ type,
+ category,
+ } = state;
+ return (
+
+
+
+
+ record.rank}
+ dataSource={data.slice(0, Math.min(showSize, data.length))}
+ pagination={false}
+ loading={loading}
+ scroll={{ x: 'max-content' }}
+ />
+
+
+
+
+ {showSize < data.length ? (
+
+ {t('showMore') + '>>'}
+
+ ) : (
+
+ {t('noMore')}
+
+ )}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+}
+
+export default MyTable;
diff --git a/.history/src/locales/foundationChinese_20240728145456.json b/.history/src/locales/foundationChinese_20240728145456.json
new file mode 100644
index 0000000..e69de29
diff --git a/.history/src/locales/foundationChinese_20240728145600.json b/.history/src/locales/foundationChinese_20240728145600.json
new file mode 100644
index 0000000..8156e09
--- /dev/null
+++ b/.history/src/locales/foundationChinese_20240728145600.json
@@ -0,0 +1,76 @@
+{
+ "type": 'Foundation_China',
+ "time": '2024',
+ "data": [
+ {
+ rank: '1',
+ name: 'apache/doris',
+ value: '4307.26',
+ rankDelta: 1,
+ valueDelta: +100,
+ },
+ {
+ rank: '2',
+ name: 'openharmony/docs',
+ value: '3277.69',
+ rankDelta: 0,
+ valueDelta: 0,
+ },
+ {
+ rank: '3',
+ name: 'openharmony/arkui_ace_engine',
+ value: '2818.09',
+ rankDelta: -1,
+ valueDelta: -3,
+ },
+ {
+ rank: '4',
+ name: 'milvus-io/milvus',
+ value: '2001.11',
+ rankDelta: 3,
+ valueDelta: -100,
+ },
+ {
+ rank: '5',
+ name: 'apache/flink',
+ value: '1816.72',
+ rankDelta: 0,
+ valueDelta: 0,
+ },
+ {
+ rank: '6',
+ name: 'apache/shardingsphere',
+ value: '1662.8',
+ rankDelta: 0,
+ valueDelta: 0,
+ },
+ {
+ rank: '7',
+ name: 'apache/ozone',
+ value: '1281.57',
+ rankDelta: 0,
+ valueDelta: 0,
+ },
+ {
+ rank: '8',
+ name: 'apache/iotdb',
+ value: '1265.72',
+ rankDelta: 0,
+ valueDelta: 0,
+ },
+ {
+ rank: '9',
+ name: 'openharmony/graphic_graphic_2d',
+ value: '1239.6',
+ rankDelta: 0,
+ valueDelta: 0,
+ },
+ {
+ rank: '10',
+ name: 'apache/pulsar',
+ value: '1227.93',
+ rankDelta: 0,
+ valueDelta: 0,
+ },
+ ],
+ }
\ No newline at end of file
diff --git a/.history/src/locales/foundationChinese_20240728145848.json b/.history/src/locales/foundationChinese_20240728145848.json
new file mode 100644
index 0000000..ce7dab2
--- /dev/null
+++ b/.history/src/locales/foundationChinese_20240728145848.json
@@ -0,0 +1,76 @@
+{
+ "type": "Foundation_China",
+ "time": "2024",
+ "data": [
+ {
+ "rank": "1",
+ "name": "apache/doris",
+ "value": "4307.26",
+ "rankDelta": 1,
+ "valueDelta": 100
+ },
+ {
+ "rank": "2",
+ "name": "openharmony/docs",
+ "value": "3277.69",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "3",
+ "name": "openharmony/arkui_ace_engine",
+ "value": "2818.09",
+ "rankDelta": -1,
+ "valueDelta": -3
+ },
+ {
+ "rank": "4",
+ "name": "milvus-io/milvus",
+ "value": "2001.11",
+ "rankDelta": 3,
+ "valueDelta": -100
+ },
+ {
+ "rank": "5",
+ "name": "apache/flink",
+ "value": "1816.72",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "6",
+ "name": "apache/shardingsphere",
+ "value": "1662.8",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "7",
+ "name": "apache/ozone",
+ "value": "1281.57",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "8",
+ "name": "apache/iotdb",
+ "value": "1265.72",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "9",
+ "name": "openharmony/graphic_graphic_2d",
+ "value": "1239.6",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "10",
+ "name": "apache/pulsar",
+ "value": "1227.93",
+ "rankDelta": 0,
+ "valueDelta": 0
+ }
+ ]
+ }
\ No newline at end of file
diff --git a/public/tech-foundation/foundationchinese.json b/public/tech-foundation/foundationchinese.json
new file mode 100644
index 0000000..ce7dab2
--- /dev/null
+++ b/public/tech-foundation/foundationchinese.json
@@ -0,0 +1,76 @@
+{
+ "type": "Foundation_China",
+ "time": "2024",
+ "data": [
+ {
+ "rank": "1",
+ "name": "apache/doris",
+ "value": "4307.26",
+ "rankDelta": 1,
+ "valueDelta": 100
+ },
+ {
+ "rank": "2",
+ "name": "openharmony/docs",
+ "value": "3277.69",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "3",
+ "name": "openharmony/arkui_ace_engine",
+ "value": "2818.09",
+ "rankDelta": -1,
+ "valueDelta": -3
+ },
+ {
+ "rank": "4",
+ "name": "milvus-io/milvus",
+ "value": "2001.11",
+ "rankDelta": 3,
+ "valueDelta": -100
+ },
+ {
+ "rank": "5",
+ "name": "apache/flink",
+ "value": "1816.72",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "6",
+ "name": "apache/shardingsphere",
+ "value": "1662.8",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "7",
+ "name": "apache/ozone",
+ "value": "1281.57",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "8",
+ "name": "apache/iotdb",
+ "value": "1265.72",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "9",
+ "name": "openharmony/graphic_graphic_2d",
+ "value": "1239.6",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "10",
+ "name": "apache/pulsar",
+ "value": "1227.93",
+ "rankDelta": 0,
+ "valueDelta": 0
+ }
+ ]
+ }
\ No newline at end of file
diff --git a/public/tech-foundation/foundationglobal.json b/public/tech-foundation/foundationglobal.json
new file mode 100644
index 0000000..1b2502b
--- /dev/null
+++ b/public/tech-foundation/foundationglobal.json
@@ -0,0 +1,76 @@
+{
+ "type": "Foundation_Global",
+ "time": "2024",
+ "data": [
+ {
+ "rank": "1",
+ "name": "kubernetes/kubernetes",
+ "value": "5374.14",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "2",
+ "name": "apache/doris",
+ "value": "4307.26",
+ "rankDelta": 2,
+ "valueDelta": 3
+ },
+ {
+ "rank": "3",
+ "name": "apache/airflow",
+ "value": "3642.9",
+ "rankDelta": -1,
+ "valueDelta": -3
+ },
+ {
+ "rank": "4",
+ "name": "openharmony/docs",
+ "value": "3277.69",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "5",
+ "name": "openharmony/arkui_ace_engine",
+ "value": "2818.09",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "6",
+ "name": "nodejs/node",
+ "value": "2736.37",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "7",
+ "name": "apache/spark",
+ "value": "2654.02",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "8",
+ "name": "apache/arrow",
+ "value": "2219.95",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "9",
+ "name": "apache/beam",
+ "value": "2188.52",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "10",
+ "name": "apache/hudi",
+ "value": "2124.67",
+ "rankDelta": 0,
+ "valueDelta": 0
+ }
+ ]
+}
\ No newline at end of file
diff --git a/public/tech-foundation/technologyai.json b/public/tech-foundation/technologyai.json
new file mode 100644
index 0000000..5b5d101
--- /dev/null
+++ b/public/tech-foundation/technologyai.json
@@ -0,0 +1,76 @@
+{
+ "type": "Technology_ai",
+ "time": "2024",
+ "data": [
+ {
+ "rank": "1",
+ "name": "pytorch/pytorch",
+ "value": "10182.45",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "2",
+ "name": "langchain-ai/langchain",
+ "value": "6080.25",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "3",
+ "name": "PaddlePaddle/Paddle",
+ "value": "5408.62",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "4",
+ "name": "huggingface/transformers",
+ "value": "4422.84",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "5",
+ "name": "AUTOMATIC1111/stable-diffusion-webui",
+ "value": "3881.6",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "6",
+ "name": "openvinotoolkit/openvino",
+ "value": "3857.31",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "7",
+ "name": "microsoft/onnxruntime",
+ "value": "3006.75",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "8",
+ "name": "tensorflow/tensorflow",
+ "value": "2723.26",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "9",
+ "name": "Significant-Gravitas/AutoGPT",
+ "value": "2664.85",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "10",
+ "name": "ggerganov/llama.cpp",
+ "value": "2339.8",
+ "rankDelta": 0,
+ "valueDelta": 0
+ }
+ ]
+}
\ No newline at end of file
diff --git a/public/tech-foundation/technologybig-data.json b/public/tech-foundation/technologybig-data.json
new file mode 100644
index 0000000..08dd4a7
--- /dev/null
+++ b/public/tech-foundation/technologybig-data.json
@@ -0,0 +1,76 @@
+{
+ "type": "Technology_big-data",
+ "time": "2024",
+ "data": [
+ {
+ "rank": "1",
+ "name": "elastic/kibana",
+ "value": "7601.04",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "2",
+ "name": "grafana/grafana",
+ "value": "7134.37",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "3",
+ "name": "ClickHouse/ClickHouse",
+ "value": "4941.99",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "4",
+ "name": "airbytehq/airbyte",
+ "value": "4658.86",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "5",
+ "name": "apache/doris",
+ "value": "4307.26",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "6",
+ "name": "elastic/elasticsearch",
+ "value": "3729.39",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "7",
+ "name": "apache/airflow",
+ "value": "3642.9",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "8",
+ "name": "StarRocks/starrocks",
+ "value": "3194.56",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "9",
+ "name": "trinodb/trino",
+ "value": "2703.4",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "10",
+ "name": "apache/spark",
+ "value": "2654.02",
+ "rankDelta": 0,
+ "valueDelta": 0
+ }
+ ]
+}
\ No newline at end of file
diff --git a/public/tech-foundation/technologycloud-native.json b/public/tech-foundation/technologycloud-native.json
new file mode 100644
index 0000000..c6d4351
--- /dev/null
+++ b/public/tech-foundation/technologycloud-native.json
@@ -0,0 +1,76 @@
+{
+ "type": "Technology_cloud-native",
+ "time": "2024",
+ "data": [
+ {
+ "rank": "1",
+ "name": "grafana/grafana",
+ "value": "7134.37",
+ "rankDelta": 1,
+ "valueDelta": 100
+ },
+ {
+ "rank": "2",
+ "name": "llvm/llvm-project",
+ "value": "7049.62",
+ "rankDelta": -2,
+ "valueDelta": -220
+ },
+ {
+ "rank": "3",
+ "name": "kubernetes/kubernetes",
+ "value": "5374.14",
+ "rankDelta": 3,
+ "valueDelta": 300
+ },
+ {
+ "rank": "4",
+ "name": "ClickHouse/ClickHouse",
+ "value": "4941.99",
+ "rankDelta": -4,
+ "valueDelta": 400
+ },
+ {
+ "rank": "5",
+ "name": "cilium/cilium",
+ "value": "3215.42",
+ "rankDelta": 5,
+ "valueDelta": -500
+ },
+ {
+ "rank": "6",
+ "name": "ceph/ceph",
+ "value": "3172.49",
+ "rankDelta": -6,
+ "valueDelta": 600
+ },
+ {
+ "rank": "7",
+ "name": "keycloak/keycloak",
+ "value": "3095.56",
+ "rankDelta": 7,
+ "valueDelta": 700
+ },
+ {
+ "rank": "8",
+ "name": "gravitational/teleport",
+ "value": "3082.18",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "9",
+ "name": "envoyproxy/envoy",
+ "value": "2929.08",
+ "rankDelta": 9,
+ "valueDelta": -900
+ },
+ {
+ "rank": "10",
+ "name": "backstage/backstage",
+ "value": "2903.39",
+ "rankDelta": 10,
+ "valueDelta": 100
+ }
+ ]
+ }
\ No newline at end of file
diff --git a/public/tech-foundation/technologydatabase.json b/public/tech-foundation/technologydatabase.json
new file mode 100644
index 0000000..2d6a2a7
--- /dev/null
+++ b/public/tech-foundation/technologydatabase.json
@@ -0,0 +1,76 @@
+{
+ "type": "Technology_database",
+ "time": "2024",
+ "data": [
+ {
+ "rank": "1",
+ "name": "ClickHouse/ClickHouse",
+ "value": "4941.99",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "2",
+ "name": "apache/doris",
+ "value": "4307.26",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "3",
+ "name": "elastic/elasticsearch",
+ "value": "3729.39",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "4",
+ "name": "cockroachdb/cockroach",
+ "value": "3443.7",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "5",
+ "name": "StarRocks/starrocks",
+ "value": "3194.56",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "6",
+ "name": "trinodb/trino",
+ "value": "2703.4",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "7",
+ "name": "apache/spark",
+ "value": "2654.02",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "8",
+ "name": "pingcap/tidb",
+ "value": "2200.38",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "9",
+ "name": "milvus-io/milvus",
+ "value": "2001.11",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "10",
+ "name": "yugabyte/yugabyte-db",
+ "value": "1940.75",
+ "rankDelta": 0,
+ "valueDelta": 0
+ }
+ ]
+}
\ No newline at end of file
diff --git a/public/tech-foundation/technologyfront-end.json b/public/tech-foundation/technologyfront-end.json
new file mode 100644
index 0000000..88e549f
--- /dev/null
+++ b/public/tech-foundation/technologyfront-end.json
@@ -0,0 +1,76 @@
+{
+ "type": "Technology_front-end",
+ "time": "2024",
+ "data": [
+ {
+ "rank": "1",
+ "name": "flutter/flutter",
+ "value": "9361.81",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "2",
+ "name": "vercel/next.js",
+ "value": "6638.65",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "3",
+ "name": "appsmithorg/appsmith",
+ "value": "3474.07",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "4",
+ "name": "nuxt/nuxt",
+ "value": "3387.23",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "5",
+ "name": "facebook/react-native",
+ "value": "3260.55",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "6",
+ "name": "ant-design/ant-design",
+ "value": "3053.25",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "7",
+ "name": "nodejs/node",
+ "value": "2736.37",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "8",
+ "name": "angular/angular",
+ "value": "2273.82",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "9",
+ "name": "electron/electron",
+ "value": "1773.31",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "10",
+ "name": "denoland/deno",
+ "value": "1654.01",
+ "rankDelta": 0,
+ "valueDelta": 0
+ }
+ ]
+}
\ No newline at end of file
diff --git a/public/tech-foundation/technologyos.json b/public/tech-foundation/technologyos.json
new file mode 100644
index 0000000..93a8e86
--- /dev/null
+++ b/public/tech-foundation/technologyos.json
@@ -0,0 +1,76 @@
+{
+ "type": "Technology_os",
+ "time": "2024",
+ "data": [
+ {
+ "rank": "1",
+ "name": "openharmony/docs",
+ "value": "3277.69",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "2",
+ "name": "openharmony/arkui_ace_engine",
+ "value": "2818.09",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "3",
+ "name": "SerenityOS/serenity",
+ "value": "2257.68",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "4",
+ "name": "openharmony/graphic_graphic_2d",
+ "value": "1239.6",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "5",
+ "name": "openeuler/docs",
+ "value": "1206.9",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "6",
+ "name": "openharmony/xts_acts",
+ "value": "1186.06",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "7",
+ "name": "openharmony/arkcompiler_ets_runtime",
+ "value": "961.99",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "8",
+ "name": "openharmony/interface_sdk-js",
+ "value": "910.91",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "9",
+ "name": "reactos/reactos",
+ "value": "745.23",
+ "rankDelta": 0,
+ "valueDelta": 0
+ },
+ {
+ "rank": "10",
+ "name": "armbian/build",
+ "value": "679.1",
+ "rankDelta": 0,
+ "valueDelta": 0
+ }
+ ]
+}
\ No newline at end of file
diff --git a/src/components/table.js b/src/components/table.js
index 841cabc..a4b0fc6 100644
--- a/src/components/table.js
+++ b/src/components/table.js
@@ -432,817 +432,14 @@ function MyTable(props) {
}
console.log(url);
console.log(region);
- if (object == 'foundation' && region == 'chinese') {
- let data = new Array();
-
- // 预处理数据,对新上榜单数据进行特殊标记处理
- data = {
- type: 'Foundation_China',
- time: '2024',
- data: [
- {
- rank: '1',
- name: 'apache/doris',
- value: '4307.26',
- rankDelta: 1,
- valueDelta: +100,
- },
- {
- rank: '2',
- name: 'openharmony/docs',
- value: '3277.69',
- rankDelta: 0,
- valueDelta: 0,
- },
- {
- rank: '3',
- name: 'openharmony/arkui_ace_engine',
- value: '2818.09',
- rankDelta: -1,
- valueDelta: -3,
- },
- {
- rank: '4',
- name: 'milvus-io/milvus',
- value: '2001.11',
- rankDelta: 3,
- valueDelta: -100,
- },
- {
- rank: '5',
- name: 'apache/flink',
- value: '1816.72',
- rankDelta: 0,
- valueDelta: 0,
- },
- {
- rank: '6',
- name: 'apache/shardingsphere',
- value: '1662.8',
- rankDelta: 0,
- valueDelta: 0,
- },
- {
- rank: '7',
- name: 'apache/ozone',
- value: '1281.57',
- rankDelta: 0,
- valueDelta: 0,
- },
- {
- rank: '8',
- name: 'apache/iotdb',
- value: '1265.72',
- rankDelta: 0,
- valueDelta: 0,
- },
- {
- rank: '9',
- name: 'openharmony/graphic_graphic_2d',
- value: '1239.6',
- rankDelta: 0,
- valueDelta: 0,
- },
- {
- rank: '10',
- name: 'apache/pulsar',
- value: '1227.93',
- rankDelta: 0,
- valueDelta: 0,
- },
- ],
- };
- data = data.data;
- let dataSource = [];
- data.map((obj) => {
- obj = expandObject(obj);
- if (obj.rankDelta == 0 && obj.value == obj.valueDelta) {
- obj.rankDelta = -10000000;
- obj.valueDelta = 0;
- }
- dataSource.push(obj);
- });
- console.log(dataSource);
-
- // 更新属性和表格数据
- setState({
- ...state,
- ...newstate,
- loading: false,
- columns: columns,
- showDetail: showDetail,
- hasDetail: hasDetail,
- data: dataSource,
- });
- } else if (object == 'foundation' && region == 'global') {
- let data = new Array();
- // 预处理数据,对新上榜单数据进行特殊标记处理
- data = {
- type: 'Foundation_China',
- time: '2024',
- data: [
- {
- rank: '1',
- name: 'kubernetes/kubernetes',
- value: '5374.14',
- rankDelta: 0,
- valueDelta: 0,
- },
- {
- rank: '2',
- name: 'apache/doris',
- value: '4307.26',
- rankDelta: 2,
- valueDelta: 3,
- },
- {
- rank: '3',
- name: 'apache/airflow',
- value: '3642.9',
- rankDelta: -1,
- valueDelta: -3,
- },
- {
- rank: '4',
- name: 'openharmony/docs',
- value: '3277.69',
- rankDelta: 0,
- valueDelta: 0,
- },
- {
- rank: '5',
- name: 'openharmony/arkui_ace_engine',
- value: '2818.09',
- rankDelta: 0,
- valueDelta: 0,
- },
- {
- rank: '6',
- name: 'nodejs/node',
- value: '2736.37',
- rankDelta: 0,
- valueDelta: 0,
- },
- {
- rank: '7',
- name: 'apache/spark',
- value: '2654.02',
- rankDelta: 0,
- valueDelta: 0,
- },
- {
- rank: '8',
- name: 'apache/arrow',
- value: '2219.95',
- rankDelta: 0,
- valueDelta: 0,
- },
- {
- rank: '9',
- name: 'apache/beam',
- value: '2188.52',
- rankDelta: 0,
- valueDelta: 0,
- },
- {
- rank: '10',
- name: 'apache/hudi',
- value: '2124.67',
- rankDelta: 0,
- valueDelta: 0,
- },
- ],
- };
- data = data.data;
- let dataSource = [];
- data.map((obj) => {
- obj = expandObject(obj);
- if (obj.rankDelta == 0 && obj.value == obj.valueDelta) {
- obj.rankDelta = -10000000;
- obj.valueDelta = 0;
- }
- dataSource.push(obj);
- });
- console.log(dataSource);
-
- // 更新属性和表格数据
- setState({
- ...state,
- ...newstate,
- loading: false,
- columns: columns,
- showDetail: showDetail,
- hasDetail: hasDetail,
- data: dataSource,
- });
- } else if (object == 'technology' && category == 'cloud-native') {
- let data = new Array();
- // 预处理数据,对新上榜单数据进行特殊标记处理
- data = {
- type: 'Foundation_China',
- time: '2024',
- data: [
- {
- rank: '1',
- name: 'grafana/grafana',
- value: '7134.37',
- rankDelta: 1,
- valueDelta: 100,
- },
- {
- rank: '2',
- name: 'llvm/llvm-project',
- value: '7049.62',
- rankDelta: -2,
- valueDelta: -220,
- },
- {
- rank: '3',
- name: 'kubernetes/kubernetes',
- value: '5374.14',
- rankDelta: 3,
- valueDelta: 300,
- },
- {
- rank: '4',
- name: 'ClickHouse/ClickHouse',
- value: '4941.99',
- rankDelta: -4,
- valueDelta: 400,
- },
- {
- rank: '5',
- name: 'cilium/cilium',
- value: '3215.42',
- rankDelta: 5,
- valueDelta: -500,
- },
- {
- rank: '6',
- name: 'ceph/ceph',
- value: '3172.49',
- rankDelta: -6,
- valueDelta: 600,
- },
- {
- rank: '7',
- name: 'keycloak/keycloak',
- value: '3095.56',
- rankDelta: 7,
- valueDelta: 700,
- },
- {
- rank: '8',
- name: 'gravitational/teleport',
- value: '3082.18',
- rankDelta: 0,
- valueDelta: 0,
- },
- {
- rank: '9',
- name: 'envoyproxy/envoy',
- value: '2929.08',
- rankDelta: 9,
- valueDelta: -900,
- },
- {
- rank: '10',
- name: 'backstage/backstage',
- value: '2903.39',
- rankDelta: 10,
- valueDelta: 100,
- },
- ],
- };
- data = data.data;
- let dataSource = [];
- data.map((obj) => {
- obj = expandObject(obj);
- if (obj.rankDelta == 0 && obj.value == obj.valueDelta) {
- obj.rankDelta = -10000000;
- obj.valueDelta = 0;
- }
- dataSource.push(obj);
- });
- console.log(dataSource);
-
- // 更新属性和表格数据
- setState({
- ...state,
- ...newstate,
- loading: false,
- columns: columns,
- showDetail: showDetail,
- hasDetail: hasDetail,
- data: dataSource,
- });
- } else if (object == 'technology' && category == 'ai') {
- let data = new Array();
- // 预处理数据,对新上榜单数据进行特殊标记处理
- data = {
- type: 'Foundation_China',
- time: '2024',
- data: [
- {
- rank: '1',
- name: 'pytorch/pytorch',
- value: '10182.45',
- rankDelta: 0,
- valueDelta: 0,
- },
- {
- rank: '2',
- name: 'langchain-ai/langchain',
- value: '6080.25',
- rankDelta: 0,
- valueDelta: 0,
- },
- {
- rank: '3',
- name: 'PaddlePaddle/Paddle',
- value: '5408.62',
- rankDelta: 0,
- valueDelta: 0,
- },
- {
- rank: '4',
- name: 'huggingface/transformers',
- value: '4422.84',
- rankDelta: 0,
- valueDelta: 0,
- },
- {
- rank: '5',
- name: 'AUTOMATIC1111/stable-diffusion-webui',
- value: '3881.6',
- rankDelta: 0,
- valueDelta: 0,
- },
- {
- rank: '6',
- name: 'openvinotoolkit/openvino',
- value: '3857.31',
- rankDelta: 0,
- valueDelta: 0,
- },
- {
- rank: '7',
- name: 'microsoft/onnxruntime',
- value: '3006.75',
- rankDelta: 0,
- valueDelta: 0,
- },
- {
- rank: '8',
- name: 'tensorflow/tensorflow',
- value: '2723.26',
- rankDelta: 0,
- valueDelta: 0,
- },
- {
- rank: '9',
- name: 'Significant-Gravitas/AutoGPT',
- value: '2664.85',
- rankDelta: 0,
- valueDelta: 0,
- },
- {
- rank: '10',
- name: 'ggerganov/llama.cpp',
- value: '2339.8',
- rankDelta: 0,
- valueDelta: 0,
- },
- ],
- };
- data = data.data;
- let dataSource = [];
- data.map((obj) => {
- obj = expandObject(obj);
- if (obj.rankDelta == 0 && obj.value == obj.valueDelta) {
- obj.rankDelta = -10000000;
- obj.valueDelta = 0;
- }
- dataSource.push(obj);
- });
- console.log(dataSource);
-
- // 更新属性和表格数据
- setState({
- ...state,
- ...newstate,
- loading: false,
- columns: columns,
- showDetail: showDetail,
- hasDetail: hasDetail,
- data: dataSource,
- });
- } else if (object == 'technology' && category == 'big-data') {
- let data = new Array();
- // 预处理数据,对新上榜单数据进行特殊标记处理
- data = {
- type: 'Foundation_China',
- time: '2024',
- data: [
- {
- rank: '1',
- name: 'elastic/kibana',
- value: '7601.04',
- rankDelta: 0,
- valueDelta: 0,
- },
- {
- rank: '2',
- name: 'grafana/grafana',
- value: '7134.37',
- rankDelta: 0,
- valueDelta: 0,
- },
- {
- rank: '3',
- name: 'ClickHouse/ClickHouse',
- value: '4941.99',
- rankDelta: 0,
- valueDelta: 0,
- },
- {
- rank: '4',
- name: 'airbytehq/airbyte',
- value: '4658.86',
- rankDelta: 0,
- valueDelta: 0,
- },
- {
- rank: '5',
- name: 'apache/doris',
- value: '4307.26',
- rankDelta: 0,
- valueDelta: 0,
- },
- {
- rank: '6',
- name: 'elastic/elasticsearch',
- value: '3729.39',
- rankDelta: 0,
- valueDelta: 0,
- },
- {
- rank: '7',
- name: 'apache/airflow',
- value: '3642.9',
- rankDelta: 0,
- valueDelta: 0,
- },
- {
- rank: '8',
- name: 'StarRocks/starrocks',
- value: '3194.56',
- rankDelta: 0,
- valueDelta: 0,
- },
- {
- rank: '9',
- name: 'trinodb/trino',
- value: '2703.4',
- rankDelta: 0,
- valueDelta: 0,
- },
- {
- rank: '10',
- name: 'apache/spark',
- value: '2654.02',
- rankDelta: 0,
- valueDelta: 0,
- },
- ],
- };
- data = data.data;
- let dataSource = [];
- data.map((obj) => {
- obj = expandObject(obj);
- if (obj.rankDelta == 0 && obj.value == obj.valueDelta) {
- obj.rankDelta = -10000000;
- obj.valueDelta = 0;
- }
- dataSource.push(obj);
- });
- console.log(dataSource);
-
- // 更新属性和表格数据
- setState({
- ...state,
- ...newstate,
- loading: false,
- columns: columns,
- showDetail: showDetail,
- hasDetail: hasDetail,
- data: dataSource,
- });
- } else if (object == 'technology' && category == 'database') {
- let data = new Array();
- // 预处理数据,对新上榜单数据进行特殊标记处理
- data = {
- type: 'Foundation_China',
- time: '2024',
- data: [
- {
- rank: '1',
- name: 'ClickHouse/ClickHouse',
- value: '4941.99',
- rankDelta: 0,
- valueDelta: 0,
- },
- {
- rank: '2',
- name: 'apache/doris',
- value: '4307.26',
- rankDelta: 0,
- valueDelta: 0,
- },
- {
- rank: '3',
- name: 'elastic/elasticsearch',
- value: '3729.39',
- rankDelta: 0,
- valueDelta: 0,
- },
- {
- rank: '4',
- name: 'cockroachdb/cockroach',
- value: '3443.7',
- rankDelta: 0,
- valueDelta: 0,
- },
- {
- rank: '5',
- name: 'StarRocks/starrocks',
- value: '3194.56',
- rankDelta: 0,
- valueDelta: 0,
- },
- {
- rank: '6',
- name: 'trinodb/trino',
- value: '2703.4',
- rankDelta: 0,
- valueDelta: 0,
- },
- {
- rank: '7',
- name: 'apache/spark',
- value: '2654.02',
- rankDelta: 0,
- valueDelta: 0,
- },
- {
- rank: '8',
- name: 'pingcap/tidb',
- value: '2200.38',
- rankDelta: 0,
- valueDelta: 0,
- },
- {
- rank: '9',
- name: 'milvus-io/milvus',
- value: '2001.11',
- rankDelta: 0,
- valueDelta: 0,
- },
- {
- rank: '10',
- name: 'yugabyte/yugabyte-db',
- value: '1940.75',
- rankDelta: 0,
- valueDelta: 0,
- },
- ],
- };
- data = data.data;
- let dataSource = [];
- data.map((obj) => {
- obj = expandObject(obj);
- if (obj.rankDelta == 0 && obj.value == obj.valueDelta) {
- obj.rankDelta = -10000000;
- obj.valueDelta = 0;
- }
- dataSource.push(obj);
- });
- console.log(dataSource);
- // 更新属性和表格数据
- setState({
- ...state,
- ...newstate,
- loading: false,
- columns: columns,
- showDetail: showDetail,
- hasDetail: hasDetail,
- data: dataSource,
- });
- } else if (object == 'technology' && category == 'front-end') {
- let data = new Array();
- // 预处理数据,对新上榜单数据进行特殊标记处理
- data = {
- type: 'Foundation_China',
- time: '2024',
- data: [
- {
- rank: '1',
- name: 'flutter/flutter',
- value: '9361.81',
- rankDelta: 0,
- valueDelta: 0,
- },
- {
- rank: '2',
- name: 'vercel/next.js',
- value: '6638.65',
- rankDelta: 0,
- valueDelta: 0,
- },
- {
- rank: '3',
- name: 'appsmithorg/appsmith',
- value: '3474.07',
- rankDelta: 0,
- valueDelta: 0,
- },
- {
- rank: '4',
- name: 'nuxt/nuxt',
- value: '3387.23',
- rankDelta: 0,
- valueDelta: 0,
- },
- {
- rank: '5',
- name: 'facebook/react-native',
- value: '3260.55',
- rankDelta: 0,
- valueDelta: 0,
- },
- {
- rank: '6',
- name: 'ant-design/ant-design',
- value: '3053.25',
- rankDelta: 0,
- valueDelta: 0,
- },
- {
- rank: '7',
- name: 'nodejs/node',
- value: '2736.37',
- rankDelta: 0,
- valueDelta: 0,
- },
- {
- rank: '8',
- name: 'angular/angular',
- value: '2273.82',
- rankDelta: 0,
- valueDelta: 0,
- },
- {
- rank: '9',
- name: 'electron/electron',
- value: '1773.31',
- rankDelta: 0,
- valueDelta: 0,
- },
- {
- rank: '10',
- name: 'denoland/deno',
- value: '1654.01',
- rankDelta: 0,
- valueDelta: 0,
- },
- ],
- };
- data = data.data;
- let dataSource = [];
- data.map((obj) => {
- obj = expandObject(obj);
- if (obj.rankDelta == 0 && obj.value == obj.valueDelta) {
- obj.rankDelta = -10000000;
- obj.valueDelta = 0;
- }
- dataSource.push(obj);
- });
- console.log(dataSource);
-
- // 更新属性和表格数据
- setState({
- ...state,
- ...newstate,
- loading: false,
- columns: columns,
- showDetail: showDetail,
- hasDetail: hasDetail,
- data: dataSource,
- });
- } else if (object == 'technology' && category == 'os') {
- let data = new Array();
- // 预处理数据,对新上榜单数据进行特殊标记处理
- data = {
- type: 'Foundation_China',
- time: '2024',
- data: [
- {
- rank: '1',
- name: 'openharmony/docs',
- value: '3277.69',
- rankDelta: 0,
- valueDelta: 0,
- },
- {
- rank: '2',
- name: 'openharmony/arkui_ace_engine',
- value: '2818.09',
- rankDelta: 0,
- valueDelta: 0,
- },
- {
- rank: '3',
- name: 'SerenityOS/serenity',
- value: '2257.68',
- rankDelta: 0,
- valueDelta: 0,
- },
- {
- rank: '4',
- name: 'openharmony/graphic_graphic_2d',
- value: '1239.6',
- rankDelta: 0,
- valueDelta: 0,
- },
- {
- rank: '5',
- name: 'openeuler/docs',
- value: '1206.9',
- rankDelta: 0,
- valueDelta: 0,
- },
- {
- rank: '6',
- name: 'openharmony/xts_acts',
- value: '1186.06',
- rankDelta: 0,
- valueDelta: 0,
- },
- {
- rank: '7',
- name: 'openharmony/arkcompiler_ets_runtime',
- value: '961.99',
- rankDelta: 0,
- valueDelta: 0,
- },
- {
- rank: '8',
- name: 'openharmony/interface_sdk-js',
- value: '910.91',
- rankDelta: 0,
- valueDelta: 0,
- },
- {
- rank: '9',
- name: 'reactos/reactos',
- value: '745.23',
- rankDelta: 0,
- valueDelta: 0,
- },
- {
- rank: '10',
- name: 'armbian/build',
- value: '679.1',
- rankDelta: 0,
- valueDelta: 0,
- },
- ],
- };
- data = data.data;
- let dataSource = [];
- data.map((obj) => {
- obj = expandObject(obj);
- if (obj.rankDelta == 0 && obj.value == obj.valueDelta) {
- obj.rankDelta = -10000000;
- obj.valueDelta = 0;
- }
- dataSource.push(obj);
- });
- console.log(dataSource);
-
- // 更新属性和表格数据
- setState({
- ...state,
- ...newstate,
- loading: false,
- columns: columns,
- showDetail: showDetail,
- hasDetail: hasDetail,
- data: dataSource,
- });
- } else {
+ if (object == "foundation") {
+ url = './tech-foundation/'+ object + region +'.json'
+ }
+ else if (object == "technology") {
+ url = './tech-foundation/'+ object + category +'.json'
+ }
// fetch 异步请求
- fetch(url)
+ fetch(url)
.then((res) => {
// Todo:最好的情况是在日期选择器中,只显示可以查询的日期,
if (res.status == 404) {
@@ -1300,7 +497,8 @@ function MyTable(props) {
data: [],
});
});
- }
+
+
};
const {
diff --git a/src/data/2023_field_ranking_top10.xlsx b/src/data/2023_field_ranking_top10.xlsx
deleted file mode 100644
index c93d73c..0000000
Binary files a/src/data/2023_field_ranking_top10.xlsx and /dev/null differ
diff --git a/src/data/2023_foundation_ranking_top10.xlsx b/src/data/2023_foundation_ranking_top10.xlsx
deleted file mode 100644
index 6bc1cb2..0000000
Binary files a/src/data/2023_foundation_ranking_top10.xlsx and /dev/null differ