|
@@ -0,0 +1,352 @@
|
|
|
+import React, { useCallback, useEffect, useState } from "react";
|
|
|
+import styles from "./index.module.scss";
|
|
|
+import { ExclamationOutlined } from "@ant-design/icons";
|
|
|
+
|
|
|
+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 { Button, Empty, message, Select, Tooltip } from "antd";
|
|
|
+import ExportJsonExcel from "js-export-excel";
|
|
|
+import dayjs from "dayjs";
|
|
|
+
|
|
|
+echarts.use([
|
|
|
+ GridComponent,
|
|
|
+ LineChart,
|
|
|
+ CanvasRenderer,
|
|
|
+ UniversalTransition,
|
|
|
+ TooltipComponent,
|
|
|
+ LegendComponent,
|
|
|
+ PieChart,
|
|
|
+ LabelLayout,
|
|
|
+]);
|
|
|
+
|
|
|
+function Hot() {
|
|
|
+ // 生成4个饼图的方法
|
|
|
+ const echFu2 = useCallback(
|
|
|
+ (
|
|
|
+ dom: any,
|
|
|
+ data: { value: number; name: string }[],
|
|
|
+ data2: { name: string; icon: string }[]
|
|
|
+ ) => {
|
|
|
+ let chartDom2: any = document.querySelector(dom);
|
|
|
+ let myChart2 = echarts.init(chartDom2);
|
|
|
+ let option2 = {
|
|
|
+ tooltip: {
|
|
|
+ trigger: "item",
|
|
|
+ },
|
|
|
+ legend: {
|
|
|
+ orient: "vertical",
|
|
|
+ top: "center",
|
|
|
+ right: 30,
|
|
|
+ data: data2,
|
|
|
+ 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",
|
|
|
+ center: ["34%", "50%"],
|
|
|
+ radius: ["40%", "70%"],
|
|
|
+ avoidLabelOverlap: false,
|
|
|
+ label: {
|
|
|
+ show: false,
|
|
|
+ position: "center",
|
|
|
+ },
|
|
|
+ emphasis: {
|
|
|
+ label: {
|
|
|
+ show: false,
|
|
|
+ },
|
|
|
+ },
|
|
|
+ labelLine: {
|
|
|
+ show: false,
|
|
|
+ },
|
|
|
+ data,
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ };
|
|
|
+ option2 && myChart2.setOption(option2);
|
|
|
+ },
|
|
|
+ []
|
|
|
+ );
|
|
|
+
|
|
|
+ // 获取图表数据
|
|
|
+ const getHotInfo = useCallback(async () => {
|
|
|
+ // 设置折线图图表
|
|
|
+ const chartDom1: any = document.querySelector(".hotEch1")!;
|
|
|
+ const myChart1 = echarts.init(chartDom1);
|
|
|
+ const option1 = {
|
|
|
+ grid: {
|
|
|
+ left: "-24", //距左边边框的距离
|
|
|
+ right: "0%", //距右边边框的距离
|
|
|
+ bottom: "10", //距下面边框的距离
|
|
|
+ top: "15", //距上面边框的距离
|
|
|
+ containLabel: true,
|
|
|
+ },
|
|
|
+
|
|
|
+ xAxis: {
|
|
|
+ type: "category",
|
|
|
+ data: [
|
|
|
+ "1月1日",
|
|
|
+ "1月2日",
|
|
|
+ "1月3日",
|
|
|
+ "1月4日",
|
|
|
+ "1月5日",
|
|
|
+ "1月6日",
|
|
|
+ "1月7日",
|
|
|
+ "1月8日",
|
|
|
+ "1月9日",
|
|
|
+ "1月10日",
|
|
|
+ "1月11日",
|
|
|
+ "1月12日",
|
|
|
+ "1月13日",
|
|
|
+ "1月14日",
|
|
|
+ ],
|
|
|
+ axisLine: {
|
|
|
+ show: false, //隐藏X轴
|
|
|
+ },
|
|
|
+ axisTick: {
|
|
|
+ show: false, //隐藏刻度线
|
|
|
+ },
|
|
|
+ axisLabel: {
|
|
|
+ show: false, //隐藏X轴文字
|
|
|
+ },
|
|
|
+ },
|
|
|
+ yAxis: {
|
|
|
+ type: "value",
|
|
|
+ },
|
|
|
+ series: [
|
|
|
+ {
|
|
|
+ data: [
|
|
|
+ 150, 230, 224, 218, 135, 147, 260, 150, 230, 224, 218, 135, 147,
|
|
|
+ 100,
|
|
|
+ ],
|
|
|
+ type: "line",
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ tooltip: {
|
|
|
+ trigger: "axis",
|
|
|
+ axisPointer: {
|
|
|
+ type: "cross",
|
|
|
+ label: {
|
|
|
+ backgroundColor: "#6a7985",
|
|
|
+ },
|
|
|
+ },
|
|
|
+ // formatter: "{a} <br/>{b} : {c}"
|
|
|
+ },
|
|
|
+ };
|
|
|
+ option1 && myChart1.setOption(option1);
|
|
|
+
|
|
|
+ const data = [
|
|
|
+ { value: 1048, name: "石头" },
|
|
|
+ { value: 735, name: "玉器" },
|
|
|
+ { value: 580, name: "陶器" },
|
|
|
+ { value: 484, name: "快乐的小青蛙" },
|
|
|
+ { value: 300, name: "其他" },
|
|
|
+ ];
|
|
|
+ const data2 = [
|
|
|
+ { icon: "circle", name: "石头" },
|
|
|
+ { icon: "circle", name: "玉器" },
|
|
|
+ { icon: "circle", name: "陶器" },
|
|
|
+ { icon: "circle", name: "快乐的小青蛙" },
|
|
|
+ { icon: "circle", name: "其他" },
|
|
|
+ ];
|
|
|
+ // 4个饼图
|
|
|
+ echFu2(".hotEch2", data, data2);
|
|
|
+ echFu2(".hotEch3", data, data2);
|
|
|
+ echFu2(".hotEch4", data, data2);
|
|
|
+ echFu2(".hotEch5", data, data2);
|
|
|
+ }, [echFu2]);
|
|
|
+
|
|
|
+ useEffect(() => {
|
|
|
+ getHotInfo();
|
|
|
+ }, [getHotInfo]);
|
|
|
+
|
|
|
+ // 馆藏点赞的时间筛选
|
|
|
+ const [value, setValue] = useState(2);
|
|
|
+
|
|
|
+ useEffect(() => {
|
|
|
+ const dom: any = document.querySelector(".hotRightMain");
|
|
|
+ if (dom) dom.scrollTop = 0;
|
|
|
+ if (value === 0) {
|
|
|
+ setLikeData([
|
|
|
+ { name: "民国制林则徐手迹玻璃底片", num: 99 },
|
|
|
+ { name: "民国制林则徐手迹玻璃底片sssssssssssssssssssss", num: 99 },
|
|
|
+ { name: "民国制林则徐手迹玻璃底片", num: 99 },
|
|
|
+ ]);
|
|
|
+ }
|
|
|
+ }, [value]);
|
|
|
+
|
|
|
+ // 馆藏点赞数据
|
|
|
+ const [likeData, setLikeData] = useState([
|
|
|
+ { name: "民国制林则徐手迹玻璃底片", num: 99999 },
|
|
|
+ { name: "民国制林则徐手迹玻璃底片", num: 99 },
|
|
|
+ { name: "民国制林则徐手迹玻璃底片", num: 99 },
|
|
|
+ { name: "民国制林则徐手迹玻璃底片", num: 99 },
|
|
|
+ { name: "民国制林则徐手迹玻璃底片sssssssssssssssssssss", num: 99 },
|
|
|
+ { name: "民国制林则徐手迹玻璃底片", num: 99 },
|
|
|
+ { name: "民国制林则徐手迹玻璃底片", num: 99 },
|
|
|
+ { name: "民国制林则徐手迹玻璃底片", num: 99 },
|
|
|
+ { name: "民国制林则徐手迹玻璃底片", num: 99 },
|
|
|
+ { name: "民国制林则徐手迹玻璃底片", num: 99 },
|
|
|
+ { name: "民国制林则徐手迹玻璃底片", num: 99 },
|
|
|
+ { name: "民国制林则徐手迹玻璃底片", num: 99 },
|
|
|
+ { name: "民国制林则徐手迹玻璃底片", num: 99 },
|
|
|
+ { name: "民国制林则徐手迹玻璃底片", num: 99 },
|
|
|
+ { name: "民国制林则徐手迹玻璃底片", num: 99 },
|
|
|
+ { name: "民国制林则徐手迹玻璃底片", num: 99 },
|
|
|
+ { name: "民国制林则徐手迹玻璃底片", num: 99 },
|
|
|
+ { name: "民国制林则徐手迹玻璃底片", num: 99 },
|
|
|
+ { name: "民国制林则徐手迹玻璃底片", num: 99 },
|
|
|
+ { name: "民国制林则徐手迹玻璃底片", num: 99 },
|
|
|
+ { name: "民国制林则徐手迹玻璃底片", num: 99 },
|
|
|
+ { name: "民国制林则徐手迹玻璃底片", num: 99 },
|
|
|
+ { name: "民国制林则徐手迹玻璃底片", num: 99 },
|
|
|
+ { name: "民国制林则徐手迹玻璃底片", num: 99 },
|
|
|
+ { name: "民国制林则徐手迹玻璃底片", num: 99 },
|
|
|
+ { name: "民国制林则徐手迹玻璃底片", num: 99 },
|
|
|
+ { name: "民国制林则徐手迹玻璃底片", num: 99 },
|
|
|
+ { name: "民国制林则徐手迹玻璃底片", num: 99 },
|
|
|
+ { name: "民国制林则徐手迹玻璃底片", num: 99 },
|
|
|
+ { name: "民国制林则徐手迹玻璃底片", num: 99 },
|
|
|
+ { name: "民国制林则徐手迹玻璃底片", num: 99 },
|
|
|
+ { name: "民国制林则徐手迹玻璃底片", num: 99 },
|
|
|
+ { name: "民国制林则徐手迹玻璃底片", num: 99 },
|
|
|
+ ]);
|
|
|
+
|
|
|
+ // 点击导出
|
|
|
+ const deriveFu = useCallback(async () => {
|
|
|
+ if (likeData.length === 0) return message.warning("当前搜索条件没有数据!");
|
|
|
+ const name = dayjs(new Date()).format("YYYYMMDD");
|
|
|
+
|
|
|
+ const option = {
|
|
|
+ fileName: name,
|
|
|
+ datas: [
|
|
|
+ {
|
|
|
+ sheetData: likeData.map((v, i) => {
|
|
|
+ return {
|
|
|
+ index: i + 1,
|
|
|
+ ...v,
|
|
|
+ };
|
|
|
+ }),
|
|
|
+ sheetName: name,
|
|
|
+ sheetFilter: ["index", "name", "num"],
|
|
|
+ sheetHeader: ["排序", "藏品名称", "点赞数"],
|
|
|
+ columnWidths: [5, 20, 5],
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ };
|
|
|
+
|
|
|
+ const toExcel = new ExportJsonExcel(option); //new
|
|
|
+ toExcel.saveExcel(); //保存
|
|
|
+ }, [likeData]);
|
|
|
+
|
|
|
+ return (
|
|
|
+ <div className={styles.Hot}>
|
|
|
+ <div className="hotLeft">
|
|
|
+ {/* 第一个盒子 */}
|
|
|
+ <div className="hotLeft_1">
|
|
|
+ {/* 标题和!提示 */}
|
|
|
+ <div className="hotTitle">
|
|
|
+ <div className="hotTitle1">万物墙使用热度 58</div>
|
|
|
+ <div className="hotTitleInco">
|
|
|
+ <Tooltip title=" 游客通过万物墙每查看一次数据,热度值记为1">
|
|
|
+ <div className="hotTitleInco1">
|
|
|
+ <ExclamationOutlined />
|
|
|
+ </div>{" "}
|
|
|
+ </Tooltip>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ {/* 折线图 */}
|
|
|
+ <div className="hotEch1"></div>
|
|
|
+ {/* 近十四天数据文字 */}
|
|
|
+ <div className="hotLeft_1Txt">近十四天数据</div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ {/* 第二个盒子 */}
|
|
|
+ <div className="hotLeft_2">
|
|
|
+ <div className="hotTitle">
|
|
|
+ <div className="hotTitle1">馆藏统计</div>
|
|
|
+ <div className="hotTitle2">当前文物合计共 124 件</div>
|
|
|
+ </div>
|
|
|
+ {/* 4个饼图 */}
|
|
|
+ <div className="hotEch2Box">
|
|
|
+ <div className="hotEch2BoxSon">
|
|
|
+ <div className="txt">类别</div>
|
|
|
+ <div className="hotEch2 ech2BoxCake"></div>
|
|
|
+ </div>
|
|
|
+ <div className="hotEch2BoxSon">
|
|
|
+ <div className="txt">年代</div>
|
|
|
+ <div className="hotEch3 ech2BoxCake"></div>
|
|
|
+ </div>
|
|
|
+ <div className="hotEch2BoxSon">
|
|
|
+ <div className="txt">级别</div>
|
|
|
+ <div className="hotEch4 ech2BoxCake"></div>
|
|
|
+ </div>
|
|
|
+ <div className="hotEch2BoxSon">
|
|
|
+ <div className="txt">来源</div>
|
|
|
+ <div className="hotEch5 ech2BoxCake"></div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div className="hotRight">
|
|
|
+ <div className="hotRightTitle">
|
|
|
+ <div className="hotRightTitle1">馆藏点赞</div>
|
|
|
+   
|
|
|
+ <div>
|
|
|
+ <Button onClick={deriveFu}>导出数据</Button>
|
|
|
+  
|
|
|
+ <Select
|
|
|
+ value={value}
|
|
|
+ style={{ width: 120 }}
|
|
|
+ onChange={(e) => setValue(e)}
|
|
|
+ options={[
|
|
|
+ { value: 0, label: "今日" },
|
|
|
+ { value: 1, label: "近七日" },
|
|
|
+ { value: 2, label: "近三十日" },
|
|
|
+ { value: 3, label: "所有时间" },
|
|
|
+ ]}
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ {1 + 1 === 2 ? (
|
|
|
+ <div className="hotRightMain">
|
|
|
+ {likeData.map((v, i) => (
|
|
|
+ <div className="hotRightMainRow" key={i}>
|
|
|
+ <div className="hotRightMainRow1" title="666666">
|
|
|
+ {i + 1}. {v.name}
|
|
|
+ </div>
|
|
|
+ <div className="hotRightMainRow2">{v.num}</div>
|
|
|
+ </div>
|
|
|
+ ))}
|
|
|
+ </div>
|
|
|
+ ) : (
|
|
|
+ <div className="noneInfo">
|
|
|
+ <Empty image={Empty.PRESENTED_IMAGE_SIMPLE} />
|
|
|
+ </div>
|
|
|
+ )}
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ );
|
|
|
+}
|
|
|
+
|
|
|
+const MemoHot = React.memo(Hot);
|
|
|
+
|
|
|
+export default MemoHot;
|