diff --git a/experiment_5/task4/data/iris.csv b/experiment_5/task4/data/iris.csv
deleted file mode 100755
index 15a9f97..0000000
--- a/experiment_5/task4/data/iris.csv
+++ /dev/null
@@ -1,151 +0,0 @@
-Id,PetalLength,PetalWidth,SepalLength,SepalWidth,Species
-1,5.1,3.5,1.4,0.2,setosa
-2,4.9,3,1.4,0.2,setosa
-3,4.7,3.2,1.3,0.2,setosa
-4,4.6,3.1,1.5,0.2,setosa
-5,5,3.6,1.4,0.2,setosa
-6,5.4,3.9,1.7,0.4,setosa
-7,4.6,3.4,1.4,0.3,setosa
-8,5,3.4,1.5,0.2,setosa
-9,4.4,2.9,1.4,0.2,setosa
-10,4.9,3.1,1.5,0.1,setosa
-11,5.4,3.7,1.5,0.2,setosa
-12,4.8,3.4,1.6,0.2,setosa
-13,4.8,3,1.4,0.1,setosa
-14,4.3,3,1.1,0.1,setosa
-15,5.8,4,1.2,0.2,setosa
-16,5.7,4.4,1.5,0.4,setosa
-17,5.4,3.9,1.3,0.4,setosa
-18,5.1,3.5,1.4,0.3,setosa
-19,5.7,3.8,1.7,0.3,setosa
-20,5.1,3.8,1.5,0.3,setosa
-21,5.4,3.4,1.7,0.2,setosa
-22,5.1,3.7,1.5,0.4,setosa
-23,4.6,3.6,1,0.2,setosa
-24,5.1,3.3,1.7,0.5,setosa
-25,4.8,3.4,1.9,0.2,setosa
-26,5,3,1.6,0.2,setosa
-27,5,3.4,1.6,0.4,setosa
-28,5.2,3.5,1.5,0.2,setosa
-29,5.2,3.4,1.4,0.2,setosa
-30,4.7,3.2,1.6,0.2,setosa
-31,4.8,3.1,1.6,0.2,setosa
-32,5.4,3.4,1.5,0.4,setosa
-33,5.2,4.1,1.5,0.1,setosa
-34,5.5,4.2,1.4,0.2,setosa
-35,4.9,3.1,1.5,0.2,setosa
-36,5,3.2,1.2,0.2,setosa
-37,5.5,3.5,1.3,0.2,setosa
-38,4.9,3.6,1.4,0.1,setosa
-39,4.4,3,1.3,0.2,setosa
-40,5.1,3.4,1.5,0.2,setosa
-41,5,3.5,1.3,0.3,setosa
-42,4.5,2.3,1.3,0.3,setosa
-43,4.4,3.2,1.3,0.2,setosa
-44,5,3.5,1.6,0.6,setosa
-45,5.1,3.8,1.9,0.4,setosa
-46,4.8,3,1.4,0.3,setosa
-47,5.1,3.8,1.6,0.2,setosa
-48,4.6,3.2,1.4,0.2,setosa
-49,5.3,3.7,1.5,0.2,setosa
-50,5,3.3,1.4,0.2,setosa
-51,7,3.2,4.7,1.4,versicolor
-52,6.4,3.2,4.5,1.5,versicolor
-53,6.9,3.1,4.9,1.5,versicolor
-54,5.5,2.3,4,1.3,versicolor
-55,6.5,2.8,4.6,1.5,versicolor
-56,5.7,2.8,4.5,1.3,versicolor
-57,6.3,3.3,4.7,1.6,versicolor
-58,4.9,2.4,3.3,1,versicolor
-59,6.6,2.9,4.6,1.3,versicolor
-60,5.2,2.7,3.9,1.4,versicolor
-61,5,2,3.5,1,versicolor
-62,5.9,3,4.2,1.5,versicolor
-63,6,2.2,4,1,versicolor
-64,6.1,2.9,4.7,1.4,versicolor
-65,5.6,2.9,3.6,1.3,versicolor
-66,6.7,3.1,4.4,1.4,versicolor
-67,5.6,3,4.5,1.5,versicolor
-68,5.8,2.7,4.1,1,versicolor
-69,6.2,2.2,4.5,1.5,versicolor
-70,5.6,2.5,3.9,1.1,versicolor
-71,5.9,3.2,4.8,1.8,versicolor
-72,6.1,2.8,4,1.3,versicolor
-73,6.3,2.5,4.9,1.5,versicolor
-74,6.1,2.8,4.7,1.2,versicolor
-75,6.4,2.9,4.3,1.3,versicolor
-76,6.6,3,4.4,1.4,versicolor
-77,6.8,2.8,4.8,1.4,versicolor
-78,6.7,3,5,1.7,versicolor
-79,6,2.9,4.5,1.5,versicolor
-80,5.7,2.6,3.5,1,versicolor
-81,5.5,2.4,3.8,1.1,versicolor
-82,5.5,2.4,3.7,1,versicolor
-83,5.8,2.7,3.9,1.2,versicolor
-84,6,2.7,5.1,1.6,versicolor
-85,5.4,3,4.5,1.5,versicolor
-86,6,3.4,4.5,1.6,versicolor
-87,6.7,3.1,4.7,1.5,versicolor
-88,6.3,2.3,4.4,1.3,versicolor
-89,5.6,3,4.1,1.3,versicolor
-90,5.5,2.5,4,1.3,versicolor
-91,5.5,2.6,4.4,1.2,versicolor
-92,6.1,3,4.6,1.4,versicolor
-93,5.8,2.6,4,1.2,versicolor
-94,5,2.3,3.3,1,versicolor
-95,5.6,2.7,4.2,1.3,versicolor
-96,5.7,3,4.2,1.2,versicolor
-97,5.7,2.9,4.2,1.3,versicolor
-98,6.2,2.9,4.3,1.3,versicolor
-99,5.1,2.5,3,1.1,versicolor
-100,5.7,2.8,4.1,1.3,versicolor
-101,6.3,3.3,6,2.5,virginica
-102,5.8,2.7,5.1,1.9,virginica
-103,7.1,3,5.9,2.1,virginica
-104,6.3,2.9,5.6,1.8,virginica
-105,6.5,3,5.8,2.2,virginica
-106,7.6,3,6.6,2.1,virginica
-107,4.9,2.5,4.5,1.7,virginica
-108,7.3,2.9,6.3,1.8,virginica
-109,6.7,2.5,5.8,1.8,virginica
-110,7.2,3.6,6.1,2.5,virginica
-111,6.5,3.2,5.1,2,virginica
-112,6.4,2.7,5.3,1.9,virginica
-113,6.8,3,5.5,2.1,virginica
-114,5.7,2.5,5,2,virginica
-115,5.8,2.8,5.1,2.4,virginica
-116,6.4,3.2,5.3,2.3,virginica
-117,6.5,3,5.5,1.8,virginica
-118,7.7,3.8,6.7,2.2,virginica
-119,7.7,2.6,6.9,2.3,virginica
-120,6,2.2,5,1.5,virginica
-121,6.9,3.2,5.7,2.3,virginica
-122,5.6,2.8,4.9,2,virginica
-123,7.7,2.8,6.7,2,virginica
-124,6.3,2.7,4.9,1.8,virginica
-125,6.7,3.3,5.7,2.1,virginica
-126,7.2,3.2,6,1.8,virginica
-127,6.2,2.8,4.8,1.8,virginica
-128,6.1,3,4.9,1.8,virginica
-129,6.4,2.8,5.6,2.1,virginica
-130,7.2,3,5.8,1.6,virginica
-131,7.4,2.8,6.1,1.9,virginica
-132,7.9,3.8,6.4,2,virginica
-133,6.4,2.8,5.6,2.2,virginica
-134,6.3,2.8,5.1,1.5,virginica
-135,6.1,2.6,5.6,1.4,virginica
-136,7.7,3,6.1,2.3,virginica
-137,6.3,3.4,5.6,2.4,virginica
-138,6.4,3.1,5.5,1.8,virginica
-139,6,3,4.8,1.8,virginica
-140,6.9,3.1,5.4,2.1,virginica
-141,6.7,3.1,5.6,2.4,virginica
-142,6.9,3.1,5.1,2.3,virginica
-143,5.8,2.7,5.1,1.9,virginica
-144,6.8,3.2,5.9,2.3,virginica
-145,6.7,3.3,5.7,2.5,virginica
-146,6.7,3,5.2,2.3,virginica
-147,6.3,2.5,5,1.9,virginica
-148,6.5,3,5.2,2,virginica
-149,6.2,3.4,5.4,2.3,virginica
-150,5.9,3,5.1,1.8,virginica
diff --git a/experiment_5/task4/data/marketing.sql b/experiment_5/task4/data/marketing.sql
deleted file mode 100755
index e8299c5..0000000
--- a/experiment_5/task4/data/marketing.sql
+++ /dev/null
@@ -1,183 +0,0 @@
-/*
- Navicat Premium Data Transfer
-
- Source Server : localhost_3306
- Source Server Type : MySQL
- Source Server Version : 80020
- Source Host : localhost:3306
- Source Schema : marketing
-
- Target Server Type : MySQL
- Target Server Version : 80020
- File Encoding : 65001
-
- Date: 20/04/2025 00:05:44
-*/
-
-SET NAMES utf8mb4;
-SET FOREIGN_KEY_CHECKS = 0;
-
--- ----------------------------
--- Table structure for main_categories
--- ----------------------------
-DROP TABLE IF EXISTS `main_categories`;
-CREATE TABLE `main_categories` (
- `id` int NOT NULL AUTO_INCREMENT,
- `name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
- `value` decimal(10, 3) NULL DEFAULT NULL,
- PRIMARY KEY (`id`) USING BTREE
-) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;
-
--- ----------------------------
--- Records of main_categories
--- ----------------------------
-INSERT INTO `main_categories` VALUES (1, '办公用品', 949270.224);
-INSERT INTO `main_categories` VALUES (2, '技术', 937985.552);
-INSERT INTO `main_categories` VALUES (3, '家具', 1028418.503);
-
--- ----------------------------
--- Table structure for sales_manager
--- ----------------------------
-DROP TABLE IF EXISTS `sales_manager`;
-CREATE TABLE `sales_manager` (
- `sales_manager` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
- `sales` decimal(10, 3) NULL DEFAULT NULL,
- `profit` decimal(10, 3) NULL DEFAULT NULL
-) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;
-
--- ----------------------------
--- Records of sales_manager
--- ----------------------------
-INSERT INTO `sales_manager` VALUES ('郝杰', 502667.277, 55300.637);
-INSERT INTO `sales_manager` VALUES ('江奕健', 179421.480, 11725.000);
-INSERT INTO `sales_manager` VALUES ('姜伟', 222300.092, 19919.872);
-INSERT INTO `sales_manager` VALUES ('王倩倩', 691845.854, 92687.014);
-INSERT INTO `sales_manager` VALUES ('杨洪光', 761143.054, 96180.574);
-INSERT INTO `sales_manager` VALUES ('张怡莲', 558296.522, 93976.162);
-
--- ----------------------------
--- Table structure for sales_month
--- ----------------------------
-DROP TABLE IF EXISTS `sales_month`;
-CREATE TABLE `sales_month` (
- `month` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
- `sales` decimal(10, 3) NULL DEFAULT NULL,
- `profit` decimal(10, 3) NULL DEFAULT NULL
-) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;
-
--- ----------------------------
--- Records of sales_month
--- ----------------------------
-INSERT INTO `sales_month` VALUES ('1月', 226678.830, 37233.770);
-INSERT INTO `sales_month` VALUES ('2月', 109855.158, 19834.458);
-INSERT INTO `sales_month` VALUES ('3月', 167173.727, 18748.247);
-INSERT INTO `sales_month` VALUES ('4月', 96984.692, 16501.352);
-INSERT INTO `sales_month` VALUES ('5月', 232199.107, 23984.947);
-INSERT INTO `sales_month` VALUES ('6月', 339729.698, 39157.118);
-INSERT INTO `sales_month` VALUES ('7月', 140050.918, 11800.698);
-INSERT INTO `sales_month` VALUES ('8月', 356128.507, 66818.087);
-INSERT INTO `sales_month` VALUES ('9月', 322759.367, 24133.207);
-INSERT INTO `sales_month` VALUES ('10月', 289269.169, 33635.329);
-INSERT INTO `sales_month` VALUES ('11月', 342142.150, 42611.870);
-INSERT INTO `sales_month` VALUES ('12月', 292702.956, 35330.176);
-
--- ----------------------------
--- Table structure for sales_province
--- ----------------------------
-DROP TABLE IF EXISTS `sales_province`;
-CREATE TABLE `sales_province` (
- `province` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
- `sales` decimal(10, 3) NULL DEFAULT NULL,
- `profit` decimal(10, 3) NULL DEFAULT NULL
-) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;
-
--- ----------------------------
--- Records of sales_province
--- ----------------------------
-INSERT INTO `sales_province` VALUES ('安徽', 113742.734, 32222.834);
-INSERT INTO `sales_province` VALUES ('北京', 76154.540, 19854.240);
-INSERT INTO `sales_province` VALUES ('福建', 102315.080, 32774.700);
-INSERT INTO `sales_province` VALUES ('甘肃', 47267.444, -13210.036);
-INSERT INTO `sales_province` VALUES ('广东', 254769.725, 58887.605);
-INSERT INTO `sales_province` VALUES ('广西', 48349.532, 14036.932);
-INSERT INTO `sales_province` VALUES ('贵州', 15893.136, 287.616);
-INSERT INTO `sales_province` VALUES ('海南', 10995.880, 4132.940);
-INSERT INTO `sales_province` VALUES ('河北', 227145.800, 43675.380);
-INSERT INTO `sales_province` VALUES ('河南', 79220.540, 17722.600);
-INSERT INTO `sales_province` VALUES ('黑龙江', 273877.632, 66982.132);
-INSERT INTO `sales_province` VALUES ('湖北', 135006.900, -33492.340);
-INSERT INTO `sales_province` VALUES ('湖南', 163503.277, 31399.277);
-INSERT INTO `sales_province` VALUES ('吉林', 76539.617, 17712.317);
-INSERT INTO `sales_province` VALUES ('江苏', 128183.776, -16801.764);
-INSERT INTO `sales_province` VALUES ('江西', 29987.860, 7944.720);
-INSERT INTO `sales_province` VALUES ('辽宁', 152250.028, -29393.812);
-INSERT INTO `sales_province` VALUES ('内蒙古', 59787.252, -15047.368);
-INSERT INTO `sales_province` VALUES ('宁夏', 12685.988, -900.592);
-INSERT INTO `sales_province` VALUES ('山东', 192400.460, 49812.560);
-INSERT INTO `sales_province` VALUES ('山西', 99782.900, 25386.900);
-INSERT INTO `sales_province` VALUES ('陕西', 102767.168, 21152.628);
-INSERT INTO `sales_province` VALUES ('上海', 99893.584, 17668.784);
-INSERT INTO `sales_province` VALUES ('四川', 60567.584, -9514.876);
-INSERT INTO `sales_province` VALUES ('天津', 95426.030, 20107.010);
-INSERT INTO `sales_province` VALUES ('西藏', 1144.920, 400.260);
-INSERT INTO `sales_province` VALUES ('新疆', 16700.880, 4683.000);
-INSERT INTO `sales_province` VALUES ('云南', 79432.052, 16937.032);
-INSERT INTO `sales_province` VALUES ('浙江', 94619.560, -27441.260);
-INSERT INTO `sales_province` VALUES ('重庆', 65262.400, 11809.840);
-
--- ----------------------------
--- Table structure for sales_region
--- ----------------------------
-DROP TABLE IF EXISTS `sales_region`;
-CREATE TABLE `sales_region` (
- `region` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
- `sales` decimal(10, 3) NULL DEFAULT NULL,
- `profit` decimal(10, 3) NULL DEFAULT NULL
-) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;
-
--- ----------------------------
--- Records of sales_region
--- ----------------------------
-INSERT INTO `sales_region` VALUES ('东北', 502667.277, 55300.637);
-INSERT INTO `sales_region` VALUES ('华北', 558296.522, 93976.162);
-INSERT INTO `sales_region` VALUES ('华东', 761143.054, 96180.574);
-INSERT INTO `sales_region` VALUES ('西北', 179421.480, 11725.000);
-INSERT INTO `sales_region` VALUES ('西南', 222300.092, 19919.872);
-INSERT INTO `sales_region` VALUES ('中南', 691845.854, 92687.014);
-
--- ----------------------------
--- Table structure for sub_categories
--- ----------------------------
-DROP TABLE IF EXISTS `sub_categories`;
-CREATE TABLE `sub_categories` (
- `id` int NOT NULL AUTO_INCREMENT,
- `main_category_id` int NULL DEFAULT NULL,
- `name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
- `value` decimal(10, 3) NULL DEFAULT NULL,
- PRIMARY KEY (`id`) USING BTREE,
- INDEX `main_category_id`(`main_category_id`) USING BTREE,
- CONSTRAINT `sub_categories_ibfk_1` FOREIGN KEY (`main_category_id`) REFERENCES `main_categories` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT
-) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;
-
--- ----------------------------
--- Records of sub_categories
--- ----------------------------
-INSERT INTO `sub_categories` VALUES (1, 1, '标签', 18936.540);
-INSERT INTO `sub_categories` VALUES (2, 1, '美术', 33038.096);
-INSERT INTO `sub_categories` VALUES (3, 1, '器具', 449744.764);
-INSERT INTO `sub_categories` VALUES (4, 1, '收纳具', 214582.200);
-INSERT INTO `sub_categories` VALUES (5, 1, '系固件', 20045.480);
-INSERT INTO `sub_categories` VALUES (6, 1, '信封', 51941.960);
-INSERT INTO `sub_categories` VALUES (7, 1, '用品', 47070.128);
-INSERT INTO `sub_categories` VALUES (8, 1, '纸张', 51413.740);
-INSERT INTO `sub_categories` VALUES (9, 1, '装订机', 62497.316);
-INSERT INTO `sub_categories` VALUES (10, 2, '电话', 330951.320);
-INSERT INTO `sub_categories` VALUES (11, 2, '复印机', 347513.264);
-INSERT INTO `sub_categories` VALUES (12, 2, '配件', 150562.664);
-INSERT INTO `sub_categories` VALUES (13, 2, '设备', 108958.304);
-INSERT INTO `sub_categories` VALUES (14, 3, '书架', 366969.540);
-INSERT INTO `sub_categories` VALUES (15, 3, '椅子', 409393.054);
-INSERT INTO `sub_categories` VALUES (16, 3, '用具', 83848.996);
-INSERT INTO `sub_categories` VALUES (17, 3, '桌子', 168206.913);
-
-SET FOREIGN_KEY_CHECKS = 1;
diff --git a/experiment_5/task4/data/sales_manager.csv b/experiment_5/task4/data/sales_manager.csv
new file mode 100644
index 0000000..21f7038
--- /dev/null
+++ b/experiment_5/task4/data/sales_manager.csv
@@ -0,0 +1,7 @@
+sales_manager,sales,profit
+郝杰,502667.277,55300.637
+江奕健,179421.48,11725
+姜伟,222300.092,19919.872
+王倩倩,691845.854,92687.014
+杨洪光,761143.054,96180.574
+张怡莲,558296.522,93976.162
diff --git a/experiment_5/task4/data/sales_month.csv b/experiment_5/task4/data/sales_month.csv
new file mode 100644
index 0000000..b8f3ec8
--- /dev/null
+++ b/experiment_5/task4/data/sales_month.csv
@@ -0,0 +1,13 @@
+month,sales,profit
+1月,226678.83,37233.77
+2月,109855.158,19834.458
+3月,167173.727,18748.247
+4月,96984.692,16501.352
+5月,232199.107,23984.947
+6月,339729.698,39157.118
+7月,140050.918,11800.698
+8月,356128.507,66818.087
+9月,322759.367,24133.207
+10月,289269.169,33635.329
+11月,342142.15,42611.87
+12月,292702.956,35330.176
diff --git a/experiment_5/task4/data/sales_product.json b/experiment_5/task4/data/sales_product.json
new file mode 100644
index 0000000..b7221b9
--- /dev/null
+++ b/experiment_5/task4/data/sales_product.json
@@ -0,0 +1,65 @@
+[
+ {
+ "name": "办公用品",
+ "value": 949270.224,
+ "children": [{
+ "name": "标签",
+ "value": 18936.54
+ }, {
+ "name": "美术",
+ "value": 33038.096
+ }, {
+ "name": "器具",
+ "value": 449744.764
+ }, {
+ "name": "收纳具",
+ "value": 214582.2
+ }, {
+ "name": "系固件",
+ "value": 20045.48
+ }, {
+ "name": "信封",
+ "value": 51941.96
+ }, {
+ "name": "用品",
+ "value": 47070.128
+ }, {
+ "name": "纸张",
+ "value": 51413.74
+ },{
+ "name": "装订机",
+ "value": 62497.316
+ }]
+}, {
+ "name": "技术",
+ "value": 937985.552,
+ "children": [{
+ "name": "电话",
+ "value": 330951.32
+ }, {
+ "name": "复印机",
+ "value": 347513.264
+ }, {
+ "name": "配件",
+ "value": 150562.664
+ }, {
+ "name": "设备",
+ "value": 108958.304
+ }]
+}, {
+ "name": "家具",
+ "value": 1028418.503,
+ "children": [{
+ "name": "书架",
+ "value": 366969.54
+ }, {
+ "name": "椅子",
+ "value": 409393.054
+ }, {
+ "name": "用具",
+ "value": 83848.996
+ }, {
+ "name": "桌子",
+ "value": 168206.913
+ }]
+}]
\ No newline at end of file
diff --git a/experiment_5/task4/data/sales_province.csv b/experiment_5/task4/data/sales_province.csv
new file mode 100644
index 0000000..c610d25
--- /dev/null
+++ b/experiment_5/task4/data/sales_province.csv
@@ -0,0 +1,31 @@
+province,sales,profit
+安徽,113742.734,32222.834
+北京,76154.54,19854.24
+福建,102315.08,32774.7
+甘肃,47267.444,-13210.036
+广东,254769.725,58887.605
+广西,48349.532,14036.932
+贵州,15893.136,287.616
+海南,10995.88,4132.94
+河北,227145.8,43675.38
+河南,79220.54,17722.6
+黑龙江,273877.632,66982.132
+湖北,135006.9,-33492.34
+湖南,163503.277,31399.277
+吉林,76539.617,17712.317
+江苏,128183.776,-16801.764
+江西,29987.86,7944.72
+辽宁,152250.028,-29393.812
+内蒙古,59787.252,-15047.368
+宁夏,12685.988,-900.592
+山东,192400.46,49812.56
+山西,99782.9,25386.9
+陕西,102767.168,21152.628
+上海,99893.584,17668.784
+四川,60567.584,-9514.876
+天津,95426.03,20107.01
+西藏,1144.92,400.26
+新疆,16700.88,4683
+云南,79432.052,16937.032
+浙江,94619.56,-27441.26
+重庆,65262.4,11809.84
diff --git a/experiment_5/task4/data/sales_region.csv b/experiment_5/task4/data/sales_region.csv
new file mode 100644
index 0000000..f502e3b
--- /dev/null
+++ b/experiment_5/task4/data/sales_region.csv
@@ -0,0 +1,7 @@
+region,sales,profit
+东北,502667.277,55300.637
+华北,558296.522,93976.162
+华东,761143.054,96180.574
+西北,179421.48,11725
+西南,222300.092,19919.872
+中南,691845.854,92687.014
diff --git a/experiment_5/task4/data/网店运营数据.xlsx b/experiment_5/task4/data/网店运营数据.xlsx
deleted file mode 100755
index 4a1c1fe..0000000
Binary files a/experiment_5/task4/data/网店运营数据.xlsx and /dev/null differ
diff --git a/experiment_5/task4/js/sales_manager.js b/experiment_5/task4/js/sales_manager.js
new file mode 100644
index 0000000..2518e34
--- /dev/null
+++ b/experiment_5/task4/js/sales_manager.js
@@ -0,0 +1,180 @@
+d3.csv("data/sales_manager.csv", function (error, data) {
+ // console.log(data);
+
+ var sales_data = []
+ var profit_data = []
+ var names = []
+
+ for ( i = 0; i < data.length; i++) {
+ var temp = {}
+ var temp1 = {}
+
+ temp['value'] = parseFloat(data[i].sales);
+ temp['name'] = data[i].sales_manager;
+
+ temp1['value'] = parseFloat(data[i].profit);
+ temp1['name'] = data[i].sales_manager;
+
+ sales_data.push(temp);
+ profit_data.push(temp1);
+ names.push(data[i].sales_manager)
+ }
+
+ // console.log(sales_data)
+ // console.log(profit_data)
+ // console.log(names)
+
+
+ var myChart = echarts.init(document.getElementById('data_manager')); // 初始化一个图表实例
+
+ option = {
+ // 颜色数组,包括6种不同的颜色值
+ color: ["#EAEA26", "#906BF9", "#FE5656", "#01E17E", "#3DD1F9", "#FFAD05"],
+ // 图表的标题,文本为"销售情况 利润情况",位置在左侧,字体颜色为蓝色(#0099FF),字体大小为10。
+ title: {
+ text: ' 销售情况 利润情况',
+ left: 'left',
+ textStyle: {
+ color: '#0099FF',
+ fontSize: 10,
+ }
+ },
+ // 提示框配置
+ tooltip: {
+ // 表示当鼠标悬停在数据项上时触发提示框
+ trigger: 'item',
+ // 定义了提示框的显示格式,包括数据系列的名称({a})、数据项的名称({b})、数值({c})和百分比({d}%)
+ formatter: '{a}
{b} : {c} ({d}%)'
+ },
+ legend: {
+ left: 'center', // 图例水平居中显示
+ top: 'bottom', // 图例位于图表底部
+ data: names, // 图例的数据项为names数组,即每个数据项的名称
+ // 图例文本的样式,包括颜色数组
+ textStyle: {
+ color: ["#EAEA26", "#906BF9", "#FE5656", "#01E17E", "#3DD1F9", "#FFAD05"],
+ },
+ padding: 0, // 图例的内边距为0
+ itemGap: 3, // 图例项之间的间距为3
+ itemWidth: 30, // 图例项的宽度为30
+ },
+ series: [
+ {
+ name: '销售额', // 图表的名称
+ type: 'pie', // 饼图
+ radius: [5, 85], // 饼图的半径范围,从5到85
+ center: ['30%', '50%'], // 饼图的中心位置在容器的30%宽度和50%高度处
+ roseType: 'area', // 使用面积模式绘制玫瑰图
+ // 标签的显示方式,这里设置为不显示标签
+ label: {
+ show: false
+ },
+ // 标签线的显示方式,这里设置为不显示标签线
+ labelLine: {
+ normal: {
+ show: false,
+ },
+ emphasis: {
+ show: false
+ }
+ },
+ // 高亮状态下的样式,这里设置为不显示高亮状态下的标签
+ emphasis: {
+ label: {
+ show: false
+ }
+ },
+ data: sales_data, // 饼图的数据为sales_data数组
+ },
+ {
+ name: '利润', // 图表的名称
+ type: 'pie', // 饼图
+ radius: [5, 85], // 饼图的半径范围,从5到85
+ center: ['80%', '50%'], // 饼图的中心位置在容器的80%宽度和50%高度处
+ roseType: 'area', // 使用面积模式绘制玫瑰图
+ // 标签的显示方式,这里设置为不显示标签
+ label: {
+ show: false,
+ },
+ // 标签线的显示方式,这里设置为不显示标签线
+ labelLine: {
+ normal: {
+ show: false,
+ },
+ emphasis: {
+ show: false
+ }
+ },
+ data: profit_data, // 饼图的数据为profit_data数组
+ }
+ ]
+ };
+ myChart.setOption(option);
+
+ // 这段代码是用于在 ECharts 图表中实现自动轮播的效果。
+ // 每隔2秒钟,图表会自动切换到下一个数据项,并高亮显示当前数据项以及显示对应的提示框(tooltip)。
+ var currentIndex = -1;
+ var pie_index = -1;
+ var pie_index1 = 0
+ setInterval(function () {
+ var dataLen = option.series[1].data.length;
+ console.log(option.series[1].data);
+ console.log(dataLen); // 6
+ /*
+ pie_index
+ -1 0
+ 0 1
+ 1 2
+ ...
+ 10 11
+ 11 0
+ */
+ pie_index = pie_index == 11 ? 0 : (pie_index + 1)
+ // console.log(currentIndex1)
+ // 取消之前高亮的图形
+ myChart.dispatchAction({
+ type: 'downplay',
+ /*
+ seriesIndex
+ 0
+ */
+ seriesIndex: pie_index1,
+ dataIndex: currentIndex
+ });
+ /*
+ currentIndex
+ -1 0
+ 0 1
+ 1 2
+ ...
+ 5 0
+ */
+ currentIndex = (currentIndex + 1) % dataLen;
+ /*
+ pie_index
+ 0 0
+ 1 0
+ ...
+ 5 0
+ 6 1
+ ...
+ 11 1
+ */
+ pie_index1 = parseInt(pie_index / 6)
+ // 高亮当前图形
+ myChart.dispatchAction({
+ type: 'highlight',
+ seriesIndex: pie_index1,
+ dataIndex: currentIndex
+ });
+ // 显示提示框
+ myChart.dispatchAction({
+ type: 'showTip',
+ seriesIndex: pie_index1,
+ dataIndex: currentIndex
+ });
+ }, 2000);
+
+
+
+})
\ No newline at end of file
diff --git a/experiment_5/task4/js/sales_month.js b/experiment_5/task4/js/sales_month.js
new file mode 100644
index 0000000..45a991a
--- /dev/null
+++ b/experiment_5/task4/js/sales_month.js
@@ -0,0 +1,227 @@
+d3.csv("data/sales_month.csv", function (error, data) {
+ // console.log(data);
+ var month = [];
+ var sales = [];
+ var profit = [];
+ for (i = 0; i < data.length; i++) {
+ month.push(data[i].month);
+ sales.push(Math.round(data[i].sales / 100) / 100);
+ profit.push(Math.round(data[i].profit / 100) / 100);
+ }
+ // console.log("---month---")
+ // console.log(month)
+ // console.log("---sales---")
+ // console.log(sales)
+ // console.log("---profit---")
+ // console.log(profit)
+
+ var myChart = echarts.init(document.getElementById('data_month'));
+ var option = {
+ legend: {
+ data: ['销售额(万元)', '利润(万元)'], // 图例的数据为两个指标,注册总量和访问总量
+ x: 'center', // 图例的水平位置为居中
+ y: 'top', // 图例的垂直位置为顶部
+ padding: [5, 0, 0, 0], // 图例的内边距,分别为上、右、下、左,这里设置为上边距为5。
+ textStyle: { // 设置图例文字的样式
+ // color: '00F1F3', // 图例文字的颜色
+ color: ['#E78932', '#2094CA'],
+ fontSize: 10, // 图例文字的字体大小为10
+ },
+ itemWidth: 28, // 图例项的宽度为28
+ itemHeight: 12, // 图例项的高度为12
+ },
+ grid: {
+ show: false, // 表示不显示网格
+ left: 0, // 网格距离容器左侧的距离为0
+ right: 20, // 网格距离容器右侧的距离为20
+ bottom: 0, // 网格距离容器底部的距离为0
+ top: '15%', // 网格距离容器顶部的距离为容器高度的15%
+ containLabel: true, // 网格区域包含数据标签
+ },
+ tooltip: {
+ show: true, // 显示提示框
+ trigger: 'axis', // 提示框的触发方式为坐标轴触发,即当鼠标悬停在坐标轴上时,提示框会显示相关信息
+
+ // 设置坐标轴指示器的样式
+ axisPointer: {
+ type: 'line', // 坐标轴指示器的类型为直线,即在触发点处显示一条直线标记
+ // 设置坐标轴指示器标签的样式
+ label: {
+ show: true, // 显示坐标轴指示器标签
+ // color:'none',
+ fontSize: 8, // 坐标轴指示器标签的字体大小为8
+ },
+ // 设置坐标轴指示器线条的样式
+ lineStyle: {
+ color: '#2094CA', // 坐标轴指示器线条的颜色为蓝色
+ type: 'dotted', // 坐标轴指示器线条的类型为虚线
+ },
+ },
+
+ textStyle: {
+ fontSize: 10, // 提示框文字的字体大小为10
+ },
+ },
+ // 设置x轴的样式和数据
+ xAxis: [
+ {
+ type: 'category', // x轴的类型为类别型,即显示的是离散的数据点。
+ boundaryGap: false, // 表示x轴两端不留空白
+ // 设置x轴标签的样式
+ axisLabel: {
+ fontSize: 8, // x轴标签的字体大小为8
+ color: '#2094CA', // x轴标签的颜色为蓝色
+ },
+ data: month, // x轴的数据为['A', 'B', 'C', 'D', 'E', 'F']
+ }
+ ],
+ // 设置y轴的样式
+ yAxis: [
+ {
+ splitLine: {show: false}, // 不显示y轴的分割线
+ type: 'value', // y轴的类型为数值型,即显示的是连续的数据值
+ // 设置y轴标签的样式
+ axisLabel: {
+ fontSize: 8, // y轴标签的字体大小为8
+ color: '#2094CA', // y轴标签的颜色为蓝色
+ },
+ }
+ ],
+ series: [
+ {
+ name: '销售额(万元)', // 该图表的名称为"注册总量"
+ type: 'line', // 图表类型为折线图
+ symbol: 'circle', // 数据点的形状为圆形
+ symbolSize: 4, // 数据点的大小为4
+ // 设置数据点的样式
+ itemStyle: {
+ normal: {// 正常状态下的数据点样式
+ color: '#E78932', // 数据点的颜色为橙色
+ },
+ },
+ lineStyle: {// 设置线条的样式
+ color: '#E78932', // 线条的颜色为橙色
+ width: 1, // 线条的宽度为1
+ },
+ label: {// 设置标签的样式
+ show: false, // 表示显示标签
+ position: 'top', // 标签的位置在数据点的上方
+ // 设置标签文字的样式
+ textStyle: {
+ color: '#E78932', // 标签文字的颜色为橙色
+ },
+ fontSize: 8, // 标签文字的字体大小为8
+ },
+ // 设置区域填充的样式
+ areaStyle: {
+ // 区域填充的颜色渐变
+ color: {
+ type: 'linear', // 颜色渐变的类型为线性渐变
+ // 渐变的起点和终点坐标
+ x: 0,
+ y: 0,
+ x2: 0,
+ y2: 1,
+ // 渐变的颜色停止点,颜色渐变是从上到下,从深橙色(#D98234)过渡到深灰色(#33313C)
+ colorStops: [{
+ offset: 0, color: '#D98234' // 0% 处的颜色 表示第一个颜色停止点,偏移量为0,颜色为深橙色
+ }, {
+ offset: 1, color: '#33313C' // 100% 处的颜色 表示第二个颜色停止点,偏移量为1,颜色为深灰色
+ }],
+ global: false // 渐变不全局应用
+ },
+
+ // color:'#CE7E35',
+ // color:'#1C7DEE',
+ // color:'#5FB397',
+ opacity: 0.5, // 区域的透明度为0.5
+ },
+ data: sales, // 折线图的数据
+ showAllSymbol: true, // 显示所有数据点
+ },
+ {
+ name: '利润(万元)', // 图表的名称为"访问总量"
+ type: 'line', // 图表类型为折线图
+ symbol: 'circle', // 数据点的形状为圆形
+ symbolSize: 4, // 数据点的大小为4
+ itemStyle: {// 设置数据点的样式
+ normal: {// 正常状态下的数据点样式
+ // borderColor:'#0099FF',
+ color: '#0099FF', // 数据点的颜色为蓝色
+ },
+ },
+ label: {// 设置标签的样式
+ show: false, // 显示标签
+ position: 'top', // 标签的位置在数据点的上方
+ textStyle: {// 设置标签文字的样式
+ color: '#0099FF', // 标签文字的颜色为蓝色
+ },
+ fontSize: 8, // 标签文字的字体大小为8
+ },
+ lineStyle: {// 设置线条的样式
+ color: '#0099FF', // 线条的颜色为蓝色
+ width: 0, // 线条的宽度为0
+ },
+ areaStyle: {// 设置区域填充的样式
+ color: {// 区域填充的颜色渐变
+ type: 'linear', // 颜色渐变的类型为线性渐变
+ // 渐变的起点和终点坐标
+ x: 0,
+ y: 0,
+ x2: 0,
+ y2: 1,
+ // 渐变的颜色停止点
+ colorStops: [{
+ offset: 0, color: '#0099FF' // 0% 处的颜色 表示第一个颜色停止点,偏移量为0,颜色为蓝色
+ }, {
+ offset: 1, color: '#394E7F' // 100% 处的颜色 表示第二个颜色停止点,偏移量为1,颜色为深蓝色
+ }],
+ global: false // 渐变不全局应用
+ },
+ opacity: 0.3, // 区域的透明度为0.3
+ },
+ data: profit, // 折线图的数据
+ showAllSymbol: true, // 显示所有数据点
+ },
+ ]
+ };
+ // 将配置项和数据应用到图表上
+ myChart.setOption(option)
+
+ // 用于在图表中周期性地高亮显示数据点并显示相应的提示框(tooltip)
+ var currentIndex = -1; // 初始化当前索引为-1
+ // 设置一个定时器,每隔2000毫秒执行一次函数内的代码块
+ setInterval(function () {
+ var dataLen = option.series[0].data.length; // 获取图表中第一个系列的数据长度
+ console.log(option.series[0].data);
+ console.log(dataLen); // 6
+ // 调用 dispatchAction 方法来执行特定的操作,包括取消之前高亮的图形、高亮当前图形和显示提示框。
+ // 取消之前高亮的图形
+ myChart.dispatchAction({
+ type: 'downplay',
+ seriesIndex: 0, // 表示操作第一个系列
+ dataIndex: currentIndex // 表示操作的数据索引为当前索引
+ });
+ /*
+ -1 0
+ 0 1
+ 1 2
+ ...
+ 5 0
+ */
+ currentIndex = (currentIndex + 1) % dataLen; // 更新当前索引,使其循环递增,直到达到数据长度
+ // 高亮当前图形
+ myChart.dispatchAction({
+ type: 'highlight',
+ seriesIndex: 0,
+ dataIndex: currentIndex
+ });
+ // 显示提示框
+ myChart.dispatchAction({
+ type: 'showTip',
+ seriesIndex: 0,
+ dataIndex: currentIndex
+ });
+ }, 2000);
+
+})
\ No newline at end of file
diff --git a/experiment_5/task4/js/sales_product.js b/experiment_5/task4/js/sales_product.js
new file mode 100644
index 0000000..93013b4
--- /dev/null
+++ b/experiment_5/task4/js/sales_product.js
@@ -0,0 +1,81 @@
+d3.json("data/sales_product.json", function (error, data) {
+ // console.log(data);
+ var myChart = echarts.init(document.getElementById('data_product'));
+
+ var color = [
+ "#00C6FB",
+ "#5781FD",
+ "#4DB1CB",
+ // "#3EBD7C",
+ // "#F7A925",
+ // "#bda29a",
+ // "#ca8622",
+ // "#749f83",
+ // "#6e7074",
+ // "#546570",
+ // "#c4ccd3"
+ ];
+
+ option = {
+ tooltip: {},
+ series: [{
+ name: '销售额', // 图表的名称
+ type: 'treemap', // 图表的类型树状图
+ roam: false, // 是否允许鼠标缩放和平移,这里设置为false,表示不允许
+ nodeClick: false, // 是否允许点击节点进行交互,这里设置为false,表示不允许
+ breadcrumb: false, // 是否显示导航路径,这里设置为false,表示不显示
+ // 分别设置图表的左边距、右边距、上边距和下边距,这里都设置为0。
+ left: 0,
+ right: 0,
+ top: 0,
+ bottom: 0,
+ itemStyle: {
+ borderColor: '#062e62' // 定义节点的样式,这里设置了边框颜色为'#062e62'
+ },
+ // 定义节点标签的样式,这里设置了字体大小为8,颜色为白色
+ label: {
+ fontSize: 8,
+ color: '#fff',
+ },
+ // 用于定义树状图的层级样式
+ levels: [{// 定义了多个层级的样式
+ color: color, // 设置节点的颜色
+ itemStyle: {// 定义节点的样式
+ normal: {// 正常状态下的样式
+ borderWidth: 0, // 边框宽度,这里设置为0,表示无边框
+ borderColor: '#062e62', // 设置边框颜色
+ gapWidth: 5 // 设置节点之间的间隔宽度
+ }
+ }
+ },
+ {
+ //colorSaturation: [0.35, 0.6],
+ colorAlpha: [1, 0.5], // 节点颜色的透明度,这里设置为[1, 0.5],表示正常状态下节点的颜色透明度为1,鼠标悬停时透明度为0.5。
+ upperLabel: {// 定义上层节点标签的样式
+ normal: {// 定义正常状态下的样式
+ color: '#00C6FB', // 设置标签颜色
+ fontSize: 10, // 设置标签字体大小
+ show: true, // 是否显示标签,这里设置为true,表示显示
+ height: 15 // 设置标签高度
+ }
+ },
+ itemStyle: {// 定义节点的样式
+ normal: {// 定义正常状态下的样式
+ borderWidth: 5, // 设置边框宽度
+ borderColor: '#062e62', // 设置边框颜色
+ gapWidth: 1, // 设置节点之间的间隔宽度
+ },
+ emphasis: {// 定义鼠标悬停时的样式
+ borderColor: '#ccc' // 设置边框颜色
+ }
+ }
+ }
+ ],
+ leafDepth: 2, // 树的叶子节点深度,其值为2
+ data: data// 数据源
+ }]
+ };
+ myChart.setOption(option)
+
+
+})
\ No newline at end of file
diff --git a/experiment_5/task4/js/sales_province.js b/experiment_5/task4/js/sales_province.js
new file mode 100644
index 0000000..f055c16
--- /dev/null
+++ b/experiment_5/task4/js/sales_province.js
@@ -0,0 +1,316 @@
+d3.csv("data/sales_province.csv", function (error, data) {
+ console.log(data);
+
+ var sales_province = [];
+ var profit_province = [];
+ var sales = [];
+
+ for (i = 0; i < data.length; i++) {
+ var temp = {};
+ var temp1 = {};
+ temp['name'] = data[i].province;
+ temp['value'] = parseFloat(data[i].sales);
+ temp1['name'] = data[i].province;
+ temp1['value'] = parseFloat(data[i].profit);
+
+ sales_province.push(temp);
+ profit_province.push(temp1);
+ sales.push(parseFloat(data[i].sales));
+ }
+ var sales_total = Math.round(d3.sum(sales) / 10000);
+
+ console.log(sales_province);
+ console.log(profit_province);
+ console.log(sales);
+
+
+
+ var myChart = echarts.init(document.getElementById('data_province'));
+ // 使用ECharts库创建一个中国地图,并显示各个省份的销售数据
+ var mapName = 'china'
+
+
+ var geoCoordMap = {}; // 空对象,用于存储地理坐标信息
+
+ /*获取地图数据*/
+ myChart.showLoading(); // 显示加载动画
+ var mapFeatures = echarts.getMap(mapName).geoJson.features; // 获取地图的地理信息数据
+ console.log("========mapFeatures=========");
+ console.log(mapFeatures);
+ myChart.hideLoading(); // 隐藏加载动画
+ // 遍历地理信息数据中的每个地区,将地区名称和经纬度存储到 geoCoordMap 对象中。
+ // 对于每个地区,首先获取其名称和经纬度,然后将名称作为键,经纬度作为值存储到 geoCoordMap 对象中。
+ mapFeatures.forEach(function (v) {
+ console.log("==========v===========");
+ console.log(v);
+ // 地区名称
+ var name = v.properties.name;
+ // 地区经纬度
+ geoCoordMap[name] = v.properties.cp;
+
+ });
+ console.log("===========geoCoordMap=============");
+ console.log(geoCoordMap);
+ var max = 480,
+ min = 9; // todo
+ var maxSize4Pin = 100,
+ minSize4Pin = 20;
+
+ // 该函数的作用是将输入的数据转换为特定格式的数组。
+ var convertData = function (data) {
+ console.log("=======data========");
+ console.log(data);
+ var res = []; // 创建一个空数组 res
+ // 遍历输入数据 data 中的每个元素
+ for (var i = 0; i < data.length; i++) {
+ var geoCoord = geoCoordMap[data[i].name];
+ console.log("========geoCoord========");
+ console.log(geoCoord);
+ // 将该元素的名称和值(以及经纬度信息)组成一个新的对象,并将其添加到 res 数组中
+ if (geoCoord) {
+ res.push({
+ name: data[i].name,
+ value: geoCoord.concat(data[i].value),
+ });
+ }
+ }
+ console.log("========res=======");
+ console.log(res);
+ return res;
+ };
+ option = {
+ // backgroundColor: '#013954',
+ // title: {
+ // text: "2019年各省份销售和利润情况", // 标题的文本为 "2019年各省份销售和利润情况"
+ // // 标题文本的样式信息,包括对齐方式(居中)、颜色(白色)和字体大小(20)
+ // textStyle: {
+ // align: 'center',
+ // color: '#fff',
+ // fontSize: 20,
+ // },
+ // top: '5%', // 标题的位置在垂直方向上为距离顶部5%
+ // left: 'center', // 标题的位置在水平方向上为居中
+ // },
+ tooltip: {
+ padding: 0, // 提示框内边距为0
+ enterable: true, // 提示框可以鼠标进入
+ transitionDuration: 1, // 提示框显示和隐藏的过渡时间为1秒
+ // 提示框文本的样式信息,包括颜色(黑色)、装饰(无)
+ textStyle: {
+ color: '#000',
+ decoration: 'none',
+ },
+ // 用于自定义提示框的内容
+ // 通过传入的参数params获取当前数据的名称、销售额和利润,然后拼接成一个HTML字符串作为提示框的内容。
+ formatter: function (params) {
+ console.log("========params========");
+ console.log(params);
+ var tipHtml = '';
+ tipHtml = '
' + '' + '' + + '销售额:' + '' + sales_province[params.dataIndex].value + '' + '元' + '
' + + '' + '' + '' + + '利润:' + '' + profit_province[params.dataIndex].value + '' + '元' + '
' + + '