|
@@ -1,12 +1,478 @@
|
|
-import React from "react";
|
|
|
|
|
|
+import React, { useCallback, useEffect, useState } from "react";
|
|
|
|
+import { ExclamationCircleFilled, CalendarOutlined } from "@ant-design/icons";
|
|
import styles from "./index.module.scss";
|
|
import styles from "./index.module.scss";
|
|
- function Hot() {
|
|
|
|
-
|
|
|
|
|
|
+import { Select, Tooltip } from "antd";
|
|
|
|
+
|
|
|
|
+import * as echarts from "echarts/core";
|
|
|
|
+import { GridComponent } from "echarts/components";
|
|
|
|
+import { LineChart } from "echarts/charts";
|
|
|
|
+import { UniversalTransition } from "echarts/features";
|
|
|
|
+import { CanvasRenderer } from "echarts/renderers";
|
|
|
|
+import { TooltipComponent, LegendComponent } from "echarts/components";
|
|
|
|
+
|
|
|
|
+import { PieChart } from "echarts/charts";
|
|
|
|
+import { LabelLayout } from "echarts/features";
|
|
|
|
+import HotMap from "./HotMap";
|
|
|
|
+
|
|
|
|
+echarts.use([
|
|
|
|
+ GridComponent,
|
|
|
|
+ LineChart,
|
|
|
|
+ CanvasRenderer,
|
|
|
|
+ UniversalTransition,
|
|
|
|
+ TooltipComponent,
|
|
|
|
+ LegendComponent,
|
|
|
|
+ PieChart,
|
|
|
|
+ LabelLayout,
|
|
|
|
+]);
|
|
|
|
+
|
|
|
|
+function Hot() {
|
|
|
|
+ // 获取echarts图表的函数
|
|
|
|
+
|
|
|
|
+ // 折线图
|
|
|
|
+ const echartsFu1 = useCallback(
|
|
|
|
+ (dom: string, data1: string[], data2: number[]) => {
|
|
|
|
+ const chartDom1: any = document.querySelector(dom)!;
|
|
|
|
+ const myChart1 = echarts.init(chartDom1);
|
|
|
|
+ const option1 = {
|
|
|
|
+ grid: {
|
|
|
|
+ left: "-24", //距左边边框的距离
|
|
|
|
+ right: "0%", //距右边边框的距离
|
|
|
|
+ bottom: "10", //距下面边框的距离
|
|
|
|
+ top: "15", //距上面边框的距离
|
|
|
|
+ containLabel: true,
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ xAxis: {
|
|
|
|
+ type: "category",
|
|
|
|
+ data: data1,
|
|
|
|
+ axisLine: {
|
|
|
|
+ show: false, //隐藏X轴
|
|
|
|
+ },
|
|
|
|
+ axisTick: {
|
|
|
|
+ show: false, //隐藏刻度线
|
|
|
|
+ },
|
|
|
|
+ axisLabel: {
|
|
|
|
+ show: false, //隐藏X轴文字
|
|
|
|
+ },
|
|
|
|
+ },
|
|
|
|
+ yAxis: {
|
|
|
|
+ type: "value",
|
|
|
|
+ },
|
|
|
|
+ series: [
|
|
|
|
+ {
|
|
|
|
+ data: data2,
|
|
|
|
+ type: "line",
|
|
|
|
+ },
|
|
|
|
+ ],
|
|
|
|
+ tooltip: {
|
|
|
|
+ trigger: "axis",
|
|
|
|
+ axisPointer: {
|
|
|
|
+ type: "cross",
|
|
|
|
+ label: {
|
|
|
|
+ backgroundColor: "#6a7985",
|
|
|
|
+ },
|
|
|
|
+ },
|
|
|
|
+ // formatter: "{a} <br/>{b} : {c}"
|
|
|
|
+ },
|
|
|
|
+ };
|
|
|
|
+ option1 && myChart1.setOption(option1);
|
|
|
|
+ },
|
|
|
|
+ []
|
|
|
|
+ );
|
|
|
|
+
|
|
|
|
+ // 饼图
|
|
|
|
+ const echartsFu2 = useCallback(
|
|
|
|
+ (dom: any, data: { value: number; name: string }[], obj: any) => {
|
|
|
|
+ let chartDom2: any = document.querySelector(dom);
|
|
|
|
+ let myChart2 = echarts.init(chartDom2);
|
|
|
|
+ let option2 = {
|
|
|
|
+ tooltip: {
|
|
|
|
+ trigger: "item",
|
|
|
|
+ },
|
|
|
|
+ legend: {
|
|
|
|
+ orient: "vertical",
|
|
|
|
+ ...obj.legend,
|
|
|
|
+ data,
|
|
|
|
+ formatter: (name: string) => {
|
|
|
|
+ let resName = "";
|
|
|
|
+ data.forEach((v) => {
|
|
|
|
+ if (name === v.name) {
|
|
|
|
+ if (name.length > 4)
|
|
|
|
+ resName = name.slice(0, 4) + "... " + v.value;
|
|
|
|
+ else resName = name + " " + v.value;
|
|
|
|
+ }
|
|
|
|
+ });
|
|
|
|
+
|
|
|
|
+ return resName;
|
|
|
|
+ },
|
|
|
|
+ },
|
|
|
|
+ series: [
|
|
|
|
+ {
|
|
|
|
+ name: "",
|
|
|
|
+ type: "pie",
|
|
|
|
+ ...obj.series,
|
|
|
|
+ avoidLabelOverlap: false,
|
|
|
|
+ // 设置圆角
|
|
|
|
+ itemStyle: {
|
|
|
|
+ borderRadius: 6,
|
|
|
|
+ borderColor: "#fff",
|
|
|
|
+ borderWidth: 1,
|
|
|
|
+ },
|
|
|
|
+ label: {
|
|
|
|
+ show: false,
|
|
|
|
+ position: "center",
|
|
|
|
+ },
|
|
|
|
+ emphasis: {
|
|
|
|
+ label: {
|
|
|
|
+ show: false,
|
|
|
|
+ },
|
|
|
|
+ },
|
|
|
|
+ labelLine: {
|
|
|
|
+ show: false,
|
|
|
|
+ },
|
|
|
|
+ data,
|
|
|
|
+ },
|
|
|
|
+ ],
|
|
|
|
+ };
|
|
|
|
+ option2 && myChart2.setOption(option2);
|
|
|
|
+ },
|
|
|
|
+ []
|
|
|
|
+ );
|
|
|
|
+
|
|
|
|
+ const getInfoFu = useCallback(() => {
|
|
|
|
+ // 第一个折线 echarts----------------------------
|
|
|
|
+ const data1_1 = [
|
|
|
|
+ "2023-2-01",
|
|
|
|
+ "2023-2-02",
|
|
|
|
+ "2023-2-03",
|
|
|
|
+ "2023-2-04",
|
|
|
|
+ "2023-2-05",
|
|
|
|
+ "2023-2-06",
|
|
|
|
+ "2023-2-07",
|
|
|
|
+ "2023-2-08",
|
|
|
|
+ "2023-2-09",
|
|
|
|
+ "2023-2-10",
|
|
|
|
+ "2023-2-11",
|
|
|
|
+ "2023-2-12",
|
|
|
|
+ "2023-2-13",
|
|
|
|
+ "2023-2-14",
|
|
|
|
+ ];
|
|
|
|
+ const data1_2 = [0, 5, 6, 8, 11, 0, 3, 1, 5, 6, 1, 7, 5, 2];
|
|
|
|
+ echartsFu1("#echarts1", data1_1, data1_2);
|
|
|
|
+
|
|
|
|
+ // 第二个折线 echarts----------------------------
|
|
|
|
+ const data2_1 = [
|
|
|
|
+ "2023-2-08",
|
|
|
|
+ "2023-2-09",
|
|
|
|
+ "2023-2-10",
|
|
|
|
+ "2023-2-11",
|
|
|
|
+ "2023-2-12",
|
|
|
|
+ "2023-2-13",
|
|
|
|
+ "2023-2-14",
|
|
|
|
+ ];
|
|
|
|
+ const data2_2 = [5, 6, 8, 11, 0, 5, 2];
|
|
|
|
+ echartsFu1("#echarts2", data2_1, data2_2);
|
|
|
|
+
|
|
|
|
+ // 第三个折线 echarts----------------------------
|
|
|
|
+ const data3_1 = [
|
|
|
|
+ "2023-2-08",
|
|
|
|
+ "2023-2-09",
|
|
|
|
+ "2023-2-10",
|
|
|
|
+ "2023-2-11",
|
|
|
|
+ "2023-2-12",
|
|
|
|
+ "2023-2-13",
|
|
|
|
+ "2023-2-14",
|
|
|
|
+ ];
|
|
|
|
+ const data3_2 = [0, 5, 6, 8, 11, 20, 1];
|
|
|
|
+ echartsFu1("#echarts3", data3_1, data3_2);
|
|
|
|
+
|
|
|
|
+ // 第一个饼图
|
|
|
|
+ const data4 = [
|
|
|
|
+ {
|
|
|
|
+ icon: "circle",
|
|
|
|
+ value: 10,
|
|
|
|
+ name: "拖拉机",
|
|
|
|
+ },
|
|
|
|
+ {
|
|
|
|
+ icon: "circle",
|
|
|
|
+ value: 1,
|
|
|
|
+ name: "火车",
|
|
|
|
+ },
|
|
|
|
+ {
|
|
|
|
+ icon: "circle",
|
|
|
|
+ value: 30,
|
|
|
|
+ name: "板车",
|
|
|
|
+ },
|
|
|
|
+ ];
|
|
|
|
+ // 左边饼图配置文件
|
|
|
|
+ const data4Obj = {
|
|
|
|
+ legend: { top: "center", right: 45 },
|
|
|
|
+ series: { center: ["34%", "50%"], radius: ["60%", "80%"] },
|
|
|
|
+ };
|
|
|
|
+
|
|
|
|
+ // 第一个饼图
|
|
|
|
+ const data7 = [
|
|
|
|
+ {
|
|
|
|
+ icon: "circle",
|
|
|
|
+ value: 10,
|
|
|
|
+ name: "拖拉机",
|
|
|
|
+ },
|
|
|
|
+ {
|
|
|
|
+ icon: "circle",
|
|
|
|
+ value: 3,
|
|
|
|
+ name: "火车",
|
|
|
|
+ },
|
|
|
|
+ {
|
|
|
|
+ icon: "circle",
|
|
|
|
+ value: 30,
|
|
|
|
+ name: "板车",
|
|
|
|
+ },
|
|
|
|
+ {
|
|
|
|
+ icon: "circle",
|
|
|
|
+ value: 3,
|
|
|
|
+ name: "火车1",
|
|
|
|
+ },
|
|
|
|
+ {
|
|
|
|
+ icon: "circle",
|
|
|
|
+ value: 30,
|
|
|
|
+ name: "板车1",
|
|
|
|
+ },
|
|
|
|
+ ];
|
|
|
|
+ // 右边饼图配置文件
|
|
|
|
+ const data7Obj = {
|
|
|
|
+ legend: { left: "center", bottom: 15 },
|
|
|
|
+ series: { center: ["50%", "35%"], radius: ["40%", "60%"] },
|
|
|
|
+ };
|
|
|
|
+ echartsFu2("#echarts4", data4, data4Obj);
|
|
|
|
+ echartsFu2("#echarts5", data4, data4Obj);
|
|
|
|
+ echartsFu2("#echarts6", data4, data4Obj);
|
|
|
|
+ echartsFu2("#echarts7", data7, data7Obj);
|
|
|
|
+ }, [echartsFu1, echartsFu2]);
|
|
|
|
+
|
|
|
|
+ useEffect(() => {
|
|
|
|
+ getInfoFu();
|
|
|
|
+ }, [getInfoFu]);
|
|
|
|
+
|
|
|
|
+ // 日期下拉框
|
|
|
|
+ const [select1, setSelect1] = useState<1 | 7 | 30 | "">(7);
|
|
|
|
+ // 藏品排行下拉框
|
|
|
|
+ const [select2, setSelect2] = useState(0);
|
|
|
|
+ // 场景排行下拉框
|
|
|
|
+ const [select3, setSelect3] = useState(0);
|
|
|
|
+ // 馆藏统计下拉框
|
|
|
|
+ const [select4, setSelect4] = useState(0);
|
|
|
|
+
|
|
|
|
+ const [likeData, setLikeData] = useState([
|
|
|
|
+ { name: "啊实打实大苏打", pcs: 10 },
|
|
|
|
+ {
|
|
|
|
+ name: "啊实打实大苏打啊实打实大苏打实打实啊实打实大苏打啊实打实大苏打实打实",
|
|
|
|
+ pcs: 10,
|
|
|
|
+ },
|
|
|
|
+ { name: "啊实打实大苏打", pcs: 10 },
|
|
|
|
+ { name: "啊实打实大苏打", pcs: 10 },
|
|
|
|
+ ]);
|
|
|
|
+
|
|
return (
|
|
return (
|
|
<div className={styles.Hot}>
|
|
<div className={styles.Hot}>
|
|
- <h1>Hot</h1>
|
|
|
|
|
|
+ <div className="pageTitlt">热度统计</div>
|
|
|
|
+ <div className="hotMainBox">
|
|
|
|
+ {/* 上面 */}
|
|
|
|
+ <div className="topBox">
|
|
|
|
+ <div className="topBoxL">
|
|
|
|
+ {/* 线上访问次数盒子 */}
|
|
|
|
+ <div className="topBoxL1">
|
|
|
|
+ <div className="hotTit">
|
|
|
|
+ 线上访问次数 58
|
|
|
|
+ <Tooltip title="近14个自然日的访客数;一天内同一访客多次访问记为1">
|
|
|
|
+ <div className="inco">
|
|
|
|
+ <ExclamationCircleFilled />
|
|
|
|
+ </div>
|
|
|
|
+ </Tooltip>
|
|
|
|
+ </div>
|
|
|
|
+ {/* 第一个echarts盒子 */}
|
|
|
|
+ <div id="echarts1"></div>
|
|
|
|
+ <div className="hotTime">近十四天数据</div>
|
|
|
|
+ </div>
|
|
|
|
+ <div className="topBoxL2">
|
|
|
|
+ {/* 大屏热度盒子 */}
|
|
|
|
+ <div className="topBoxL2L">
|
|
|
|
+ <div className="hotTit">
|
|
|
|
+ 大屏热度 264
|
|
|
|
+ <Tooltip title="查看馆藏/场景/视频信息时,记为1点热度">
|
|
|
|
+ <div className="inco">
|
|
|
|
+ <ExclamationCircleFilled />
|
|
|
|
+ </div>
|
|
|
|
+ </Tooltip>
|
|
|
|
+ </div>
|
|
|
|
+ {/* 第二个echarts盒子 */}
|
|
|
|
+ <div id="echarts2"></div>
|
|
|
|
+ <div className="hotTime">近七天数据</div>
|
|
|
|
+ </div>
|
|
|
|
+ {/* 穿戴设备热度盒子 */}
|
|
|
|
+ <div className="topBoxL2R">
|
|
|
|
+ <div className="hotTit">
|
|
|
|
+ 穿戴设备热度 14
|
|
|
|
+ <Tooltip title="穿戴设备每次启动,记为1点热度">
|
|
|
|
+ <div className="inco">
|
|
|
|
+ <ExclamationCircleFilled />
|
|
|
|
+ </div>
|
|
|
|
+ </Tooltip>
|
|
|
|
+ </div>
|
|
|
|
+ {/* 第三个echarts盒子 */}
|
|
|
|
+ <div id="echarts3"></div>
|
|
|
|
+ <div className="hotTime">近七天数据</div>
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+ {/* 地图盒子 */}
|
|
|
|
+ <div className="topBoxR">
|
|
|
|
+ <div className="hotTit">
|
|
|
|
+ 线上访问热力图
|
|
|
|
+ <Tooltip title="根据近30天访问情况进行统计">
|
|
|
|
+ <div className="inco">
|
|
|
|
+ <ExclamationCircleFilled />
|
|
|
|
+ </div>
|
|
|
|
+ </Tooltip>
|
|
|
|
+ </div>
|
|
|
|
+ <HotMap />
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+ {/* 下面 */}
|
|
|
|
+ <div className="downBox">
|
|
|
|
+ <div className="downBoxL">
|
|
|
|
+ <div className="downBoxLTop">
|
|
|
|
+ <div className="downBoxLTopInco">
|
|
|
|
+ <CalendarOutlined />
|
|
|
|
+ </div>
|
|
|
|
+ <Select
|
|
|
|
+ value={select1}
|
|
|
|
+ style={{ width: 100 }}
|
|
|
|
+ onChange={(e) => setSelect1(e)}
|
|
|
|
+ options={[
|
|
|
|
+ { value: 1, label: "今日" },
|
|
|
|
+ { value: 7, label: "近七日" },
|
|
|
|
+ { value: 30, label: "近三十日" },
|
|
|
|
+ { value: "", label: "所有时间" },
|
|
|
|
+ ]}
|
|
|
|
+ />
|
|
|
|
+ <div className="downBoxLTopTit">
|
|
|
|
+ 注:数据的统计,需定时从数据库中获取,因此可能产生一定延迟
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+ <div className="downBoxLMain">
|
|
|
|
+ <div className="downBoxLMain1">
|
|
|
|
+ <div className="hotTit">
|
|
|
|
+ 浏览总数
|
|
|
|
+ <Tooltip title="对文物或场景的访问记为1">
|
|
|
|
+ <div className="inco">
|
|
|
|
+ <ExclamationCircleFilled />
|
|
|
|
+ </div>
|
|
|
|
+ </Tooltip>
|
|
|
|
+ </div>
|
|
|
|
+ <div className="downBoxLMain1echartsBox">
|
|
|
|
+ <div className="downBoxLMain1echartsBoxRow">
|
|
|
|
+ <div className="echartsBox" id="echarts4"></div>
|
|
|
|
+ <div className="downBoxLMain1echartsBoxTxt">
|
|
|
|
+ <div>文物</div>
|
|
|
|
+ <p>124</p>
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+ <div className="downBoxLMain1echartsBoxRow">
|
|
|
|
+ <div className="echartsBox" id="echarts5"></div>
|
|
|
|
+ <div className="downBoxLMain1echartsBoxTxt">
|
|
|
|
+ <div>vr展馆</div>
|
|
|
|
+ <p>58</p>
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+ <div className="downBoxLMain1echartsBoxRow">
|
|
|
|
+ <div className="echartsBox" id="echarts6"></div>
|
|
|
|
+ <div className="downBoxLMain1echartsBoxTxt">
|
|
|
|
+ <div>全景</div>
|
|
|
|
+ <p>2</p>
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+ <div className="downBoxLMain2">
|
|
|
|
+ <div className="downBoxLMain2L">
|
|
|
|
+ <div className="hotTitSelect">
|
|
|
|
+ <div>藏品排行</div>
|
|
|
|
+ <Select
|
|
|
|
+ value={select2}
|
|
|
|
+ style={{ width: 100 }}
|
|
|
|
+ onChange={(e) => setSelect2(e)}
|
|
|
|
+ options={[
|
|
|
|
+ { value: 0, label: "按浏览" },
|
|
|
|
+ { value: 1, label: "按弹幕" },
|
|
|
|
+ { value: 2, label: "按点赞" },
|
|
|
|
+ ]}
|
|
|
|
+ />
|
|
|
|
+ </div>
|
|
|
|
+ <div className="downBoxLMain2LRowBox">
|
|
|
|
+ {likeData.map((v, i) => (
|
|
|
|
+ <div className="downBoxLMain2LRow" key={i}>
|
|
|
|
+ <div className="downBoxLMain2LRow1" title={v.name}>
|
|
|
|
+ {i + 1}. {v.name}
|
|
|
|
+ </div>
|
|
|
|
+ <div className="downBoxLMain2LRow2">{v.pcs}</div>
|
|
|
|
+ </div>
|
|
|
|
+ ))}
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+ <div className="downBoxLMain2R">
|
|
|
|
+ <div className="hotTitSelect">
|
|
|
|
+ <div>场景排行</div>
|
|
|
|
+ <Select
|
|
|
|
+ value={select3}
|
|
|
|
+ style={{ width: 100 }}
|
|
|
|
+ onChange={(e) => setSelect3(e)}
|
|
|
|
+ options={[
|
|
|
|
+ { value: 0, label: "按浏览" },
|
|
|
|
+ { value: 1, label: "按弹幕" },
|
|
|
|
+ ]}
|
|
|
|
+ />
|
|
|
|
+ </div>
|
|
|
|
+ <div className="downBoxLMain2LRowBox">
|
|
|
|
+ {likeData.map((v, i) => (
|
|
|
|
+ <div className="downBoxLMain2LRow" key={i}>
|
|
|
|
+ <div className="downBoxLMain2LRow1" title={v.name}>
|
|
|
|
+ {i + 1}. {v.name}
|
|
|
|
+ </div>
|
|
|
|
+ <div className="downBoxLMain2LRow2">{v.pcs}</div>
|
|
|
|
+ </div>
|
|
|
|
+ ))}
|
|
|
|
+ </div>
|
|
|
|
+ <div className="downBoxLMain2LRow"></div>
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+ <div className="downBoxR">
|
|
|
|
+ <div className="hotTitSelect">
|
|
|
|
+ <div>馆藏统计</div>
|
|
|
|
+ <Select
|
|
|
|
+ value={select4}
|
|
|
|
+ style={{ width: 100 }}
|
|
|
|
+ onChange={(e) => setSelect4(e)}
|
|
|
|
+ options={[
|
|
|
|
+ { value: 0, label: "按类别" },
|
|
|
|
+ { value: 1, label: "按年代" },
|
|
|
|
+ { value: 2, label: "按级别" },
|
|
|
|
+ ]}
|
|
|
|
+ />
|
|
|
|
+ </div>
|
|
|
|
+ <div className="downBoxRBox">
|
|
|
|
+ <div id="echarts7"></div>
|
|
|
|
+ <div className="downBoxRBoxTxt">
|
|
|
|
+ <div>总数</div>
|
|
|
|
+ <p>9</p>
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
</div>
|
|
</div>
|
|
- )
|
|
|
|
|
|
+ );
|
|
}
|
|
}
|
|
|
|
|
|
const MemoHot = React.memo(Hot);
|
|
const MemoHot = React.memo(Hot);
|