From 0eb6833f560908610011769a46d6d6287ad009b7 Mon Sep 17 00:00:00 2001
From: xiaoAugenstern <1014708671@qq.com>
Date: Sun, 28 Jul 2024 20:03:49 +0800
Subject: [PATCH] move data to ./public/tech-foundation
---
.history/package_20240725151341.json | 52 +
.history/package_20240728145142.json | 55 +
.history/package_20240728195511.json | 52 +
.../foundationchinese_20240728172909.json | 0
.../foundationchinese_20240728172930.json | 76 +
.../foundationglobal_20240728172918.json | 0
.../foundationglobal_20240728173949.json | 5 +
.../foundationglobal_20240728182812.json | 76 +
.../foundationglobal_20240728182818.json | 76 +
.../foundationglobal_20240728195837.json | 76 +
.../technologyai_20240728172713.json | 0
.../technologyai_20240728173532.json | 77 +
.../technologyai_20240728173534.json | 76 +
.../technologyai_20240728173542.json | 76 +
.../technologyai_20240728173926.json | 76 +
.../technologybig-data_20240728172727.json | 0
.../technologybig-data_20240728173618.json | 77 +
.../technologybig-data_20240728173633.json | 76 +
.../technologybig-data_20240728195750.json | 76 +
...technologycloud-native_20240728172857.json | 0
...technologycloud-native_20240728173058.json | 76 +
...technologycloud-native_20240728173847.json | 76 +
.../technologydatabase_20240728172821.json | 0
.../technologydatabase_20240728173704.json | 77 +
.../technologydatabase_20240728173710.json | 76 +
.../technologydatabase_20240728195805.json | 76 +
.../technologyfront-end_20240728172808.json | 0
.../technologyfront-end_20240728173446.json | 7 +
.../technologyfront-end_20240728173736.json | 77 +
.../technologyfront-end_20240728173741.json | 76 +
.../technologyfront-end_20240728195817.json | 76 +
.../technologyos_20240728172838.json | 0
.../technologyos_20240728173806.json | 77 +
.../technologyos_20240728173810.json | 76 +
.../technologyos_20240728195829.json | 76 +
...technologycloud-native_20240728153801.json | 0
...technologycloud-native_20240728154040.json | 76 +
...technologycloud-native_20240728154042.json | 76 +
.../src/components/data_20240728143018.js | 0
.../src/components/data_20240728171418.js | 218 +++
.../src/components/table_20240727221129.js | 1319 +++++++++++++++++
.../src/components/table_20240727221246.js | 1297 ++++++++++++++++
.../src/components/table_20240727224142.js | 653 ++++++++
.../src/components/table_20240727224145.js | 653 ++++++++
.../src/components/table_20240727224820.js | 651 ++++++++
.../src/components/table_20240727225058.js | 651 ++++++++
.../src/components/table_20240727225519.js | 651 ++++++++
.../src/components/table_20240727230659.js | 652 ++++++++
.../src/components/table_20240727230905.js | 653 ++++++++
.../src/components/table_20240727230907.js | 653 ++++++++
.../src/components/table_20240727230943.js | 653 ++++++++
.../src/components/table_20240727231007.js | 653 ++++++++
.../src/components/table_20240727231113.js | 653 ++++++++
.../src/components/table_20240727231156.js | 589 ++++++++
.../src/components/table_20240727231303.js | 589 ++++++++
.../src/components/table_20240727231305.js | 589 ++++++++
.../src/components/table_20240727231408.js | 589 ++++++++
.../src/components/table_20240727231449.js | 589 ++++++++
.../src/components/table_20240727231623.js | 589 ++++++++
.../src/components/table_20240728144201.js | 601 ++++++++
.../src/components/table_20240728144210.js | 601 ++++++++
.../src/components/table_20240728144254.js | 601 ++++++++
.../src/components/table_20240728144348.js | 601 ++++++++
.../src/components/table_20240728144514.js | 627 ++++++++
.../src/components/table_20240728144641.js | 615 ++++++++
.../src/components/table_20240728144736.js | 601 ++++++++
.../src/components/table_20240728150221.js | 627 ++++++++
.../src/components/table_20240728150719.js | 627 ++++++++
.../src/components/table_20240728150811.js | 627 ++++++++
.../src/components/table_20240728150851.js | 627 ++++++++
.../src/components/table_20240728151211.js | 650 ++++++++
.../src/components/table_20240728151214.js | 650 ++++++++
.../src/components/table_20240728151323.js | 651 ++++++++
.../src/components/table_20240728151410.js | 651 ++++++++
.../src/components/table_20240728151537.js | 645 ++++++++
.../src/components/table_20240728152336.js | 645 ++++++++
.../src/components/table_20240728152433.js | 645 ++++++++
.../src/components/table_20240728152504.js | 645 ++++++++
.../src/components/table_20240728152539.js | 645 ++++++++
.../src/components/table_20240728152542.js | 645 ++++++++
.../src/components/table_20240728152647.js | 650 ++++++++
.../src/components/table_20240728153148.js | 650 ++++++++
.../src/components/table_20240728153150.js | 650 ++++++++
.../src/components/table_20240728153730.js | 594 ++++++++
.../src/components/table_20240728171435.js | 594 ++++++++
.../src/components/table_20240728173002.js | 594 ++++++++
.../src/components/table_20240728173032.js | 594 ++++++++
.../src/components/table_20240728173107.js | 594 ++++++++
.../src/components/table_20240728173113.js | 593 ++++++++
.../src/components/table_20240728195002.js | 593 ++++++++
.../src/components/table_20240728195126.js | 593 ++++++++
.../src/components/table_20240728195614.js | 592 ++++++++
.../foundationChinese_20240728145456.json | 0
.../foundationChinese_20240728145600.json | 76 +
.../foundationChinese_20240728145848.json | 76 +
public/tech-foundation/foundationchinese.json | 76 +
public/tech-foundation/foundationglobal.json | 76 +
public/tech-foundation/technologyai.json | 76 +
.../tech-foundation/technologybig-data.json | 76 +
.../technologycloud-native.json | 76 +
.../tech-foundation/technologydatabase.json | 76 +
.../tech-foundation/technologyfront-end.json | 76 +
public/tech-foundation/technologyos.json | 76 +
src/components/table.js | 820 +---------
src/data/2023_field_ranking_top10.xlsx | Bin 14755 -> 0 bytes
src/data/2023_foundation_ranking_top10.xlsx | Bin 10475 -> 0 bytes
106 files changed, 36831 insertions(+), 811 deletions(-)
create mode 100644 .history/package_20240725151341.json
create mode 100644 .history/package_20240728145142.json
create mode 100644 .history/package_20240728195511.json
create mode 100644 .history/public/tech-foundation/foundationchinese_20240728172909.json
create mode 100644 .history/public/tech-foundation/foundationchinese_20240728172930.json
create mode 100644 .history/public/tech-foundation/foundationglobal_20240728172918.json
create mode 100644 .history/public/tech-foundation/foundationglobal_20240728173949.json
create mode 100644 .history/public/tech-foundation/foundationglobal_20240728182812.json
create mode 100644 .history/public/tech-foundation/foundationglobal_20240728182818.json
create mode 100644 .history/public/tech-foundation/foundationglobal_20240728195837.json
create mode 100644 .history/public/tech-foundation/technologyai_20240728172713.json
create mode 100644 .history/public/tech-foundation/technologyai_20240728173532.json
create mode 100644 .history/public/tech-foundation/technologyai_20240728173534.json
create mode 100644 .history/public/tech-foundation/technologyai_20240728173542.json
create mode 100644 .history/public/tech-foundation/technologyai_20240728173926.json
create mode 100644 .history/public/tech-foundation/technologybig-data_20240728172727.json
create mode 100644 .history/public/tech-foundation/technologybig-data_20240728173618.json
create mode 100644 .history/public/tech-foundation/technologybig-data_20240728173633.json
create mode 100644 .history/public/tech-foundation/technologybig-data_20240728195750.json
create mode 100644 .history/public/tech-foundation/technologycloud-native_20240728172857.json
create mode 100644 .history/public/tech-foundation/technologycloud-native_20240728173058.json
create mode 100644 .history/public/tech-foundation/technologycloud-native_20240728173847.json
create mode 100644 .history/public/tech-foundation/technologydatabase_20240728172821.json
create mode 100644 .history/public/tech-foundation/technologydatabase_20240728173704.json
create mode 100644 .history/public/tech-foundation/technologydatabase_20240728173710.json
create mode 100644 .history/public/tech-foundation/technologydatabase_20240728195805.json
create mode 100644 .history/public/tech-foundation/technologyfront-end_20240728172808.json
create mode 100644 .history/public/tech-foundation/technologyfront-end_20240728173446.json
create mode 100644 .history/public/tech-foundation/technologyfront-end_20240728173736.json
create mode 100644 .history/public/tech-foundation/technologyfront-end_20240728173741.json
create mode 100644 .history/public/tech-foundation/technologyfront-end_20240728195817.json
create mode 100644 .history/public/tech-foundation/technologyos_20240728172838.json
create mode 100644 .history/public/tech-foundation/technologyos_20240728173806.json
create mode 100644 .history/public/tech-foundation/technologyos_20240728173810.json
create mode 100644 .history/public/tech-foundation/technologyos_20240728195829.json
create mode 100644 .history/public/technologycloud-native_20240728153801.json
create mode 100644 .history/public/technologycloud-native_20240728154040.json
create mode 100644 .history/public/technologycloud-native_20240728154042.json
create mode 100644 .history/src/components/data_20240728143018.js
create mode 100644 .history/src/components/data_20240728171418.js
create mode 100644 .history/src/components/table_20240727221129.js
create mode 100644 .history/src/components/table_20240727221246.js
create mode 100644 .history/src/components/table_20240727224142.js
create mode 100644 .history/src/components/table_20240727224145.js
create mode 100644 .history/src/components/table_20240727224820.js
create mode 100644 .history/src/components/table_20240727225058.js
create mode 100644 .history/src/components/table_20240727225519.js
create mode 100644 .history/src/components/table_20240727230659.js
create mode 100644 .history/src/components/table_20240727230905.js
create mode 100644 .history/src/components/table_20240727230907.js
create mode 100644 .history/src/components/table_20240727230943.js
create mode 100644 .history/src/components/table_20240727231007.js
create mode 100644 .history/src/components/table_20240727231113.js
create mode 100644 .history/src/components/table_20240727231156.js
create mode 100644 .history/src/components/table_20240727231303.js
create mode 100644 .history/src/components/table_20240727231305.js
create mode 100644 .history/src/components/table_20240727231408.js
create mode 100644 .history/src/components/table_20240727231449.js
create mode 100644 .history/src/components/table_20240727231623.js
create mode 100644 .history/src/components/table_20240728144201.js
create mode 100644 .history/src/components/table_20240728144210.js
create mode 100644 .history/src/components/table_20240728144254.js
create mode 100644 .history/src/components/table_20240728144348.js
create mode 100644 .history/src/components/table_20240728144514.js
create mode 100644 .history/src/components/table_20240728144641.js
create mode 100644 .history/src/components/table_20240728144736.js
create mode 100644 .history/src/components/table_20240728150221.js
create mode 100644 .history/src/components/table_20240728150719.js
create mode 100644 .history/src/components/table_20240728150811.js
create mode 100644 .history/src/components/table_20240728150851.js
create mode 100644 .history/src/components/table_20240728151211.js
create mode 100644 .history/src/components/table_20240728151214.js
create mode 100644 .history/src/components/table_20240728151323.js
create mode 100644 .history/src/components/table_20240728151410.js
create mode 100644 .history/src/components/table_20240728151537.js
create mode 100644 .history/src/components/table_20240728152336.js
create mode 100644 .history/src/components/table_20240728152433.js
create mode 100644 .history/src/components/table_20240728152504.js
create mode 100644 .history/src/components/table_20240728152539.js
create mode 100644 .history/src/components/table_20240728152542.js
create mode 100644 .history/src/components/table_20240728152647.js
create mode 100644 .history/src/components/table_20240728153148.js
create mode 100644 .history/src/components/table_20240728153150.js
create mode 100644 .history/src/components/table_20240728153730.js
create mode 100644 .history/src/components/table_20240728171435.js
create mode 100644 .history/src/components/table_20240728173002.js
create mode 100644 .history/src/components/table_20240728173032.js
create mode 100644 .history/src/components/table_20240728173107.js
create mode 100644 .history/src/components/table_20240728173113.js
create mode 100644 .history/src/components/table_20240728195002.js
create mode 100644 .history/src/components/table_20240728195126.js
create mode 100644 .history/src/components/table_20240728195614.js
create mode 100644 .history/src/locales/foundationChinese_20240728145456.json
create mode 100644 .history/src/locales/foundationChinese_20240728145600.json
create mode 100644 .history/src/locales/foundationChinese_20240728145848.json
create mode 100644 public/tech-foundation/foundationchinese.json
create mode 100644 public/tech-foundation/foundationglobal.json
create mode 100644 public/tech-foundation/technologyai.json
create mode 100644 public/tech-foundation/technologybig-data.json
create mode 100644 public/tech-foundation/technologycloud-native.json
create mode 100644 public/tech-foundation/technologydatabase.json
create mode 100644 public/tech-foundation/technologyfront-end.json
create mode 100644 public/tech-foundation/technologyos.json
delete mode 100644 src/data/2023_field_ranking_top10.xlsx
delete mode 100644 src/data/2023_foundation_ranking_top10.xlsx
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 c93d73c59f7be3306800938b88c4c95e08eeb80b..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 14755
zcmaJ|1y~*3uEpK0IF#b(XhRDemr2oZ{~8?(XgscXxL$1s-kRy}j-G?;F04b2yW%
z%p_;+gguF@1TY8`z>gzPdW-kR>%R`jw>O`x^kr?WtnFxI-^5VfK7jZsmVU8oYy$`Y
zFaZPrfbgGUde+v|&KBlr(R>m;wAg*;KI>UK?FMid^hG~;_-ppiTlqo7Q
zxWt1u_z()RC?Keu5NS`$W-SqVOWh~ABv!9GT-u)JGB;m4?`sk4_|Ta;h1&obB`x+4
zmKZwqoEqvu8Q&v1L=KQLcOpPf(9O@=htvSriB(Q0f}nyONMO{yM{&e^5}k>YjN76=
z`%o0#3Z8U~gmq5)G&7*sZJ0CZ^tBrsv;MI&(6%>zECw80#_=H7Iiucf>
z1e}BZh>z6LQ0#`>69L`7mJhy
z+(%rlo?JD1n5q^UDr3v0LrFIQ?vcmnkb)ZogL91Ch#Rhs!n?|SW?kLMIJe568P}=6
zBYVMdRi{{g&j+F%=y=t#<7n^5osrG?en?I-CGi
zct7wKTx7%AlMcZv*q^R%Y`pFwd2>D7o9mJPaJ_?_y_Lle=jTOfy^-UG^IrvqJdz`*
z>u@XvmMrnLS*_37a}Sk`qoZ@D-@iC9?4i)KPLA}rxHzxbRri%(`{dBp&y#}__TnQ1
zAJ?lqVRKr|(*k-sgqf!BQAGL1RO-sDtbM}D5z*76G2cKO-rLw%VHFv?@{J6GeO7;z
zDhM-A#T&ytEI)24WXi~ug_8@_?;(v6N>%t
z8#A~SQ^`@X9@rsy8Gcu;pGoW*U#hO8gnHTZ?hy{iHk%}0Cgx$ux(dfQd-Ef0yQ)zz
z2m`ak7X6nG%pYP2582g~9Y*8P3+#m$ZqmjkW;ZjKCujFI4<{4MNzR6g@RrhOd3Hz*
zQIL?nMFgx-8FnmYUKdeEP;vwO@asP>Ou%n`bvFOGB>l4h+%EwqD_b)=V*>;Gzn3re
z&?9`MHSSLo6}H4$+Re~v~f
zo9xJBAvgea6G(RBd3!fzi*TiOiarha=|IujQT^UYudo=$tf)KN2uGEfzh1GYWF??D
zA#{$p(4w0)*icWxB~UYfoJ*q4%%ZZ&7fZ&HyepUW4&Pobl>1(+^4A4h
z8J|SlYnYzTf!dqJ9L20=2uXpG75CyHcj>0V$`VhY?Zeh}rEK<-?%#N;rM$T#TbSNM
zz|8HE82Pfh!7+Nceu6DwEYVYz)ivA@3o_b%fQ%=ISz%9%t)2SbIag`|r5KH}chHcR
zXvFK6Zu8>4#kJ7%NbZ|#anL?#Hu-(4ZVi=Gq@d2~>~1+o*G>Pkj5rtM3T9QDW~9fee~lyx=1?Xq?47qA?ayGo^Bk$+jt3
zA3|pkAC{ub7#O}2jO
z;zRL^TY997ui~05L2P33siSSDKyfRAN#yV)a%oa3J{2N)+-U+$K`ya-&dmK+e|kafA7S-dM;l$sgM
zCLWf!xGlVNYXoZ!A|%F;)-l1CJPj+}Lt~QDezQTXAooN2KXh;x8l>
zo3L>#r_cU&qH>!)H4KRc6C&jqjJ)BO@nA{j)g^zzNrL`QFs-_XjZc=Hx{ISvg6<}*
zA}gP^%Odz}aQ9hV!|sPC`6#W_`5?isF|1R8<|QhZw30+1rG?ANd7WmO^-Bsg?)-3>mCE+T~$VPIXR`TX;DZC`HyHUHB1Qspvx5~WkErxQ?;Dl}T7)XFxQ^{TWD-olv#
zkc-jR`wYF0M%NE(Giymh=^@M_AmD@g7G&gWxVAUvJT!RpJGa60sAWPUwl}`F2R2Xp
zcqx2?4KIUj+4Y
zzxh~UO@_Iy-cn(ET0!E#yqh+`UxP`$F1-qlaF*GqqHTBE6YIv*8#|2=00^%YF><%H
zmCr|bo3xbXN|bC=OuA$_iuFMGe44*CA@qF2HFU@3N&wHnk3g9iX_X55JXTk*{#b%w
z<+`a5m%|%Ul^oangzI0yuw2#rRSvOS&+>(#_!}nSv)uLFx8m22dpk8ZZgLw
zX(~sF9}t>3p9lgXLh-_(z?ixzcD}?EyNtYiG*TAe59fy^7lJLmIAp>$WEa#HSRcFB
zMcoD{Fo`E76dh!j29Qm@)BKzd*sesE?yy{sMFs{h9L%eQGYc$(OHkM`1D~-$)_An}
z(hAG`f+0>xW7cFkqM=K4#LI*jN-i8_|5G=gd9DSqHI~?0iuX{861|*`)
z`gD3~E}j^G2&W}LObH~i1_Xn9oRyJ8V_)0Tq`WBBO6V_!w0-ift_!SX@I!!zAu0;{
z3gD`<&Sz$d&}=5hu&Ucd*m+BB9IncaBF>BYd((Pwz6IbYl2c35^0ytc}{n
zHJr@}!^$C0bk9q-_cOO(cj{$NaYYLI4z>DM6t8$MA3CuRqkAsRrFXF%_{qhZrc!E9
z-RQ`_$)djsn|lHMS+3M=B7YEiqhHW}rys*F`mMiZ!Z-SnoOhLVA!6ch7tZHKd-=P^uD|-Z~DWgk~`6Ou5qvMreth6>?!-mLKw{zWer7E)W!~b{!Hj0U}N1-^yoSFvN6y<2zJ}eUR
z!GB6e^6Avg|Grmh@iiT%ZI6b()wE}xlP?`jA9Te276-};JiaVLF
zF_9vJ7Is%C*dCbRu@QMNyp}250AmmMNw(77^pFDa8V=imBm*@n_w|;J)N6`PvQNl^
zToo5tI@81Bze>V$cajRuc0TDHQmp{zCgNC>*kLu*=It|g)HHP-eMWeNm|!XNUV++k
z)O+A7F#0H2Cc${Cn-G|G>Vq0uZJ!)yfR`Sn(X|rJB&Ze<1o9p(+a~rb;+Q=Ej4AT%
zV>qVM9dqTm51|4;Axn$Y)jrY~d{QvQG=5`mh@@V+k`dI?LonmtSgBQ~<>qE8iM5>L
zLG9e;Iuq3sXfFs()^&w)N(U=l-;MY*ahd79Sx0!JgR`8G)d8L#VPYut^rwQ}yDRmk
ztE28>yt#x$IT=7yG?%U6gVeK(z(iL#Mv7$Zjp5!6*(I=E59`!bZE(lSl#(1jvjH}9
zwZHm6)9JCVxn-G(+q*G1J7nX@2?AWgT{PC7D$Rd#+cFJwYGNi+o@}}3MBdP9n(AYL
z4-7BBBkC5LY(!+r0CoCGfTD?7(15eD03*!`-{ZLsktI!IJz=_Plz&&JFr7SP^a9U~
zpeyv2`dCsZ*!b!q#pTOyhRpkL!-Crpo2`O&z5b-0|H}7amN)9@|99#!{$J|R=;9+}
zM;6N}rPPYe*5Zv*CxW2TGDsi1JiRdwoIkIfv2*n&^HxuvH54>RhM$7#AiL{BD3|t1
z3zs~6JfGd0H9nNQ%cT+>Q%}zHsuj6!8PBK(-mZA|me=#r|PxM4mv
zhK`TE41jRnbt^b$CGv+dH65^9oiGudB`B-h#GBMLP}{wU+8qd}=MS+~M+SVn4=g^W
zF}3Ooyn&JiE4+;!R|<|;qCeW)AnwQ?W;<3RJ4s~aAz+4gorD5kjuxZMUb+`b7~QFmcEst_r!^hd2`=oiG0KiXxLhd`Q#!W}?Pba8~&$YGu#v@|^{H=)b!zya-!
zmpk=EU|keCe8HUCaR$&UR`4%;NQ0x|N-WbJ
zi}Avh<%kBU&+1cQ(In9W=s5`X@vPj9MW}hWJ5>gY1MjE5uCkL9vhplXnPH_bRhy--
zEMe=0@eXj(~!%W%Y`MN4!!3A&WX$<)}3
zZnQ+5CUFv%>PDfG#`DBUbj??WrW>XS5YW^=I~_&mxU?8j^g$U?Uf`&`ly)S+UHW!5
znu~p_+;mp?F(i)mWOH&Fu3^v=j%3b
zC$-_{zxhq$bC(g@bq#mk)bfU*LUNifK%j*=vC**G{zGSQpwX)Mrg=M1a^2*uw~`^`
zhpnY33~Jb!f(q_t_UeLl$aNJ9tJzvVq)!0VjogyAA-ZYotJ;a5Qv|qhH}3MSTbr&b
zsW6Ze-mx0gor-zH20lNWcb)P4Nw$DFD`AE=vKjt&vN8Q4o5im@C$r?l>#5`Gk`Gk`
zrBx@EqA2C&eCiXE31qn8cei|QPGW}Fwl-1#kQ%OV)UF|u#T
zCqb!2YVuqsf`zUcjBh!5uGN6dRUf!n!|SCM)8&=^1RWWTv{oS4k>9?do(qLzZUXQ+
zyiRxVqCE@9@~Mo=o+~Hsjcm&fsS}pQZ)CGx_7e29Vpi(Hb*{2frKlAhHzmh^)l+fk
z5j(B>9;v-JjcCfXYZtZUTc3IxWMLz05l%;7>Lq=&cd!IeV}k8?AXd1AnZ|AMBo{Nw$4Y8^?{+6O
zxR!Gd(pUEU@M%dCcu=tdL(C-79~t&(rY_1PqdxShjzKMYgmlk)@0OM;-1LR%TE37e
zxxhx>sa;=v%Y7}}+bL=gug`i?-)Vi(i2In34Z>lG{$PXN#E0&h>1O{pG*D5xbOth7
z76|<5vaPTr-opr7S-?G5bBM|r7U7{b8A^CXNLfH<_P!9XJTS&Dvh&hoJ|Y`L&HrdF
zs^XiT8LE=c$(HNv^`sBv2U$ar-S06P@Jn)of%g|E)tDPEm5$1HfaKKS^(Rxp`SstY
z_R=kwE5H7v8~GdEfY$ry!YJEA6Ou!OpNo#1qI|v%Wl30oowzzl>UON=KEsk9(%7H5PZvd<&N8C
zGAc#9NlQ7jJM744a=HM{maujZ7cy%Rv}ZJQsbH0%NVIo_-dF(R{Cnz7YjbmCG;fxT
zx0-XLC<8~FxDEDe=x6FvbU}g*m;5ub^E6m~l!#GjV&7YLz*N{0%{6)npeG~_yG-p)
zS2qXy5zh%vjXGbY8ray44G7`3`6tD7h_xcn`%%zV&Y4{}?F|@a>{0w`=G2gBSW0yZ
zH%0i}cAi%O)mQL8iH3tgtwZ@nH0}RRH0GZ~Q(pZ+G_Q=>SHQRIPg|Z
z7PK%`yYi)^D!1yp1$}X)tUuzyIykL*lwIL*DcoJnakj%vIYhRiTbaNkAeM)0&^%!_@
z6%My?o4qf-l@lK7+}kp#lAt!=rVWvLximLrsU_^lc&TQ@!V5iCY;x~veh$zGYDZ(B
z6zny8CWL?t_LkE)Yq`EA*94bek!Z
z-oC+8#O88Vnu>a(`XyGyYgiNeBZ}Stth*JCUpXE~34)fq=fx&8#r<1KYw6~$evnf%
z=xMJ)F3IE;F5ek*1|_^OnI#Hs3@J@+FFNN#E+xQr_7>>I4~76tm1H`WtXR@BL)hhI
zwrMzh(Czw+XuT-U_VTI5$MVzFCNL+c9M?*QV_E6T}s{CR5(&Qpm51QqECRhBF$
zv?3rOCXOf&Ti7_0nEWZCUI!p^eq{0oJ<3KX)Ht~UExt3+-Em^ZSt7qu;FH8|$b|1U
z>*3GpHe+yv-kLp3Sd)qgf`DC<9QD~k#iDX!Uq5(j3NWQiynWi+6(vV!Beb#GpbL#V
z@`dG_J-k7^UdouUD>W1sUJEgEo|};if{=*eKy>HF_N|n$BF$y_PYA-!XVNsdQmtga%f%h$
z;(1|Mc>c+-f8OZ)@rdSaC)D29z{23KM>G#F*a%@@0042p?khGYuUlK9>-m3*V!f
zz7P3D&$3s@54AN|*M#%}a3XAB$~LdM8AT7%jkF&zvW**4E+ccF=jGmK|^pTM?Hay&~Q0L#5FHjits$
zzxin)Nh(zh)p@22d#z?&R&8cZA=<$t<(9gB|FYC}Kw74VV|(^fX{G`rfQ5TL1qz8M
z!?G4-3j;=I{3lkK7Of%`Q|fkJF9Yd4;gZ>67I`&FIpFGuI=1iX26gpKCmXPXTgP?}
z>Si^o+71_BpDs)69?tyxO~?AMWCx8o(*?`|9b3q5vFW$WTTt4;F6zXgGP3Y7uMVat
zg*lZ&K2mizG#vo(0%IsM3Y#WJBHq1ETxP|D2xbCqmA2OFhkLZO6usu3ddDayb>0Ia
z@Nx8@&GYW`*hpsL*eC-2oQtdVzGw6KDe%6%p*GcjnH4S=TF2vg2v284sDtP6YPM&5
z__8|a^|l3k{H;F0hQMHqIq2Ju@N)b1(3caT<9S^P(oS}f32{ChBx)aqoympkZP`y-
zzViuRx*;3y<56kn`w8mzt8!Vut;~I;F!KcEmzGeZxCWggG0WklZL*RmRGaQZq1YR6
z`=xzCMS$hT+Mv+)BsQ{NH6?=^xkB$poEvOT8tWOvGEEKn4j0;SkVHnc0`&cXk&yjw
zu-PvsbCaaazt~b*zU(pjNXB{Y{F*zS(bpOqowIhjr3S)2DUKhFdsVW}_Jys9QyO
zyn}@FR{L_{(T&ZZ-H+^_Lm%ydU6tKc@ews1axn#}Bj{KZG#w6NyO4oUKEAApns?o2
zx5CC_qQZ+cJ&N@&1+iR;;GN(WA;OHbn}2SQEmcMdMf!CB(R0ljxi
z`PboS%xfQpRb`|wn#iTjsq}y`9ra`@7>s11@p_{Xa2<$&fx+KFn9t#N&59`cw;_;B
zG^lV%5k`_7@@D%dw9RH~CD*;8i9PRc&89#NVjX5P1@bt%V$*_-qG3dY9+qO9#d-C+p3
zk25+byS)01)Gp+*Tdi3%z*$rt&!lbNLy<{(_@jX|Vp$+8n1>^0zbU9CtkfM