实现功能, 点击排序按钮,按照表格的高度依次排序

再次点击按钮,按照底部的label(01A, 02B...排序)

主要难点,修改完数据后,页面的chart不刷新

解决方案 React.useRef和chart的ref绑定,然后调用chart.update方法

代码如下

import * as React from "react";
import {Chart} from "react-chartjs-2";
import {Chart as ChartJS,Title,Tooltip,Legend,CategoryScale,BarController,BarElement,ActiveElement,ChartData,
} from "chart.js";
import {ILogger} from "../logging/ILogger";
import {from} from "linq-to-typescript";
import {IChartDataList} from "./IChartDataList";
import {ITranslator} from "../translations/ITranslator";
import {ILinkPosition} from "./common";
import {ILink} from "./ILink";
import {ItemWithLoading} from "./ItemWithLoading";// Register the elements to display ChartJs. Enables tree-shaking reducing bundle size.
// See https://www.chartjs.org/docs/latest/getting-started/integration.html#bundlers-webpack-rollup-etc
ChartJS.register(Title, Tooltip, Legend, CategoryScale, BarController, BarElement);export interface ISum {subscript: number;totalReject: number[];label: string;sumOfTotalReject?: number;
}export interface IBarChartProps {logger: ILogger;translator: ITranslator;/** The state of showing loading icon while sending request */showLoading: boolean;/** get link box position */handleLinkPosition: (linksPosition: ILinkPosition) => void;/** get link words of link box */getLinksList: (linksList: ILink[]) => void;/** height of chart */chartHeight: number;/** current bar data */itemData: IChartDataList;/** sort data by label or total reject, if true, sort by total reject */sortByReject: boolean;
}export const BarChart: React.FC<IBarChartProps> = (props: IBarChartProps) => {const chartRef = React.useRef<ChartJS>(null);const comparer = (x: number, y: number) => y - x;//这个库的方法来排序linq-to-typescriptconst sortByRejectOrLabel = (list: any[]) => {if (props.sortByReject) {// sort data by sum of total reject (按照高度排序)list = from(list).orderBy<number>((x) => x.sumOfTotalReject as number, comparer).toArray();} else {// sort data by label(按照label排序(字母顺序))list = from(list).orderBy<string>((x) => x.label).toArray();}props.logger.debug("sorted list is", list);return list;};/**这里是最复杂的逻辑* @param chartData 当前chart* @returns 排好序的新的表格数据*/const handleSortByReject = (chart) => {if (chart.data.labels !== undefined &&chart.data.labels.length !== 0 &&chart.data.datasets !== undefined &&chart.data.datasets.length !== 0) {let labelAndRejectArr: {label: string; sumOfTotalReject: number}[] = [];//  表格只有一个颜色的数据if (chart.data.datasets.length === 1) {chart.data.datasets[0].data.forEach((e, i) => {const label = chart.data.labels ? (chart.data.labels[i] as string) : "";const totalRejectValue = e === null ? 0 : (e as number);labelAndRejectArr.push({sumOfTotalReject: totalRejectValue, label});});labelAndRejectArr = sortByRejectOrLabel(labelAndRejectArr);const labels: string[] = [];const totalRejects: number[] = [];labelAndRejectArr.forEach((e) => {labels.push(e.label);totalRejects.push(e.sumOfTotalReject);});// re-set labelchart.data.labels = labels;props.logger.debug("new labels is", chart.data.labels);// re-set datachart.data.datasets[0].data = totalRejects;props.logger.debug("new data is", chart.data.datasets);} else {//表格有多个颜色的数据handleSortByRejectForMultipleArray(chart);}}return chart;};/*** 数据整合* * eg:* 两个数组:* ```* [11, null, null]* [null, 2, 8]* ```* 变成下面这样:** ```* [* {subscript: 0, totalReject: [11, 0], label: "1A"},* {subscript: 1, totalReject: [0, 2], label: "2A"},* {subscript: 2, totalReject: [0, 8], label: "4D"},* ]** ```*/const integrateTotalReject = (chart: {data: {labels?: string[]; datasets?: any}}) => {const {datasets} = chart.data;const newArr: ISum[] = [];datasets.forEach((e) => {if (e.data.length !== 0) {e.data.forEach((j, k) => {const totalReject = j === null ? 0 : (j as number);let label = "";if (chart.data.labels) {label = chart.data.labels[k];}// new item include subscript and totalRejectconst values: ISum = {subscript: k,totalReject: [totalReject],label,};const sameSubscript = newArr.findIndex((c) => c.subscript === k);if (sameSubscript !== -1) {newArr[sameSubscript].totalReject.push(totalReject);} else {newArr.push(values);}});}});props.logger.debug("integrate totalReject list is", newArr);return newArr;};/** 求和* ```* [* {subscript: 0, totalReject: [11, 0], label: "1A"},* {subscript: 1, totalReject: [0, 2], label: "2A"},* {subscript: 2, totalReject: [0, 8], label: "4D"},* ]* ```* 变成* ```* [* {subscript: 0, totalReject: [11, 0], label: "1A", sumOfTotalReject: 11},* {subscript: 1, totalReject: [0, 2], label: "2A", sumOfTotalReject: 2},* {subscript: 2, totalReject: [0, 8], label: "4D", sumOfTotalReject: 8},* ]* ```*/const sumTotalReject = (newArr: ISum[]): ISum[] => {return newArr.map((e) => {const sum = e.totalReject.reduce((total, num) => total + num);return {...e, sumOfTotalReject: sum};});};/*** 分开数据* * eg:* 下面是原数组:** ```* [* {subscript: 0, totalReject: [11, 0], label: "1A", sumOfTotalReject: 11},* {subscript: 1, totalReject: [0, 2], label: "2A", sumOfTotalReject: 2},* {subscript: 2, totalReject: [0, 8], label: "4D", sumOfTotalReject: 8},* ]** ```* 变成下面这样:* ```* [11, null, null]* [null, 2, 8]* ```*/const partTotalReject = (sumArrWithLabels: ISum[]) => {const arr: {subscript: number; data: (null | number)[]}[] = [];sumArrWithLabels.forEach((e) => {e.totalReject.forEach((j, k) => {const data = j === 0 ? null : j;const values = {subscript: k,data: [data],};const sameSubscript = arr.findIndex((c) => c.subscript === k);if (sameSubscript !== -1) {arr[sameSubscript].data.push(data);} else {arr.push(values);}});});props.logger.debug("part totalReject list is", arr);return arr;};/*** @param chart 当前chart*/const handleSortByRejectForMultipleArray = (chart) => {const newData = integrateTotalReject(chart);let sumArrWithLabels = sumTotalReject(newData);sumArrWithLabels = sortByRejectOrLabel(sumArrWithLabels);const labels: string[] = [];sumArrWithLabels.forEach((e) => {labels.push(e.label);});// re-set labelchart.data.labels = labels;props.logger.debug("new labels is", chart.data.labels);const arr = partTotalReject(sumArrWithLabels);// re-set datachart.data.datasets.forEach((e, i) => {e.data = arr[i].data;});props.logger.debug("new data is", chart.data.datasets);};/*** @returns options property or bar chart*/const getOptionBarChart = (titleKey?: string) => {return {maintainAspectRatio: false,scales: {x: {stacked: true,},y: {stacked: true,},},plugins: {title: {display: true,text: props.translator.translate(titleKey as string),},},};};/*** 官方方法* 1. [update.html](https://www.chartjs.org/docs/latest/developers/updates.html)* 2. [chartRef-demo](https://react-chartjs-2.netlify.app/examples/chart-ref/)*/const updateChartData = (chart) => {if (chart.data !== null && chart.data !== undefined) {chart = handleSortByReject(chart);props.logger.debug("new chart is", chart);chart.update();}};React.useEffect(() => {const chart = chartRef.current;if (chart !== null) {updateChartData(chart);}}, [props.sortByReject, props.itemData.chartData.labels, props.showLoading, props.chartHeight]);return (<>{/** 发送请求时,显示loading, 获取到请求结果后,显示ele中的元素*/}<ItemWithLoadingheight={props.chartHeight}showLoading={props.showLoading}ele={props.itemData.chartData !== undefined &&props.itemData.chartData.labels &&props.itemData.chartData.labels.length !== 0 &&props.itemData.chartData.datasets.length !== 0 && (/** 表格,可以参考官网* [chartRef-demo](https://react-chartjs-2.netlify.app/examples/chart-ref/)*/<Charttype="bar"ref={chartRef}height={props.chartHeight}data={props.itemData.chartData}options={getOptionBarChart(props.itemData.titleKey)}/>)}/></>);
};

这是ItemWithLoading

import * as React from "react";
import {AppContext} from "../app/IAppContext";
import {Loading} from "../app/Loading";
import "../public/style/datalight/ItemWithLoading.scss";export interface IItemWithLoadingProps {height: number;/** if true, show loading icon */showLoading: boolean;ele?: JSX.Element | boolean;
}/** render no data */
export const ItemWithLoading: React.FC<IItemWithLoadingProps> = (props: IItemWithLoadingProps) => (// before render element, show loading<AppContext.Consumer>{(ctx) =>props.showLoading ? (<Loading />) : props.ele ? (props.ele) : (//  if ele not available, show 'no data'<div className="tes-datalight-noData" style={{height: props.height}}>{ctx.translator.translate("tes_fe_gallery_filter_nodata")}</div>)}</AppContext.Consumer>
);

chartjs 表格刷新相关推荐

  1. 关于excel表格刷新问题

    这段时间以来一直被一个问题困扰着,不得安宁. 公司文件服务器上的一个excel表格刷新出错,所有有刷新需求的客户端出现同样的问题.提示"D:\MY DATA SOURCES\--找不到(数据 ...

  2. vue表格刷新数据_Vue.js+Layer表格数据绑定与实现更新的实例

    一:先使用Vue.js绑定好数据与更新事件 使用v-on绑定好事件,在事件里边直接把该行数据传递进去,在更新方法里边就可以直接取出需要更新的数据 选择 用户名 学号 班级 操作 {{item.User ...

  3. vue 表单验证,表格刷新问题

    1.表格数据更新,页面不更新处理: (1) this.$set(row, row.children, (row.children = row.children)); (注意:上面是改变了childre ...

  4. 解决表格刷新时抖动闪烁问题

    vue+element+el-table渲染数据闪烁 功能需求 由后端进行分页,前端使用element+el-table+el-pagination(分页).使用axios请求后端数据,实现分页加载表 ...

  5. Table表格刷新内容后

    今天遇到了一个问题,Table表格显示两页,第一页五条记录,第二页少于五条纪录,然后点下一页翻页到第二页的时候,table最下面的边框还是会存在,排查了各种情况,终于发现是将box-sizing设置为 ...

  6. HTML chartjs如何自适应屏幕,关于chartjs表格的大小问题

    我创建出来的表格总是和自定义的canvas大小无关呢 //html //js(这就是官网的示例) var ctx = $('#chartTest')[0].getContext('2d'); var ...

  7. vue表格刷新数据_vue+element-ui实现表格某个数据弹窗添加数据,保存后数据更新,再次打开弹窗,数据回显...

    实现功能: 1.生成数据插入table 2.修改table的某个数据,保存后该数据进行更新 3.点击table的btn,选择的数据仍是选中状态,数据回显 示例-1-选择地址插入表格 示例-2-选择指定 ...

  8. vue表格刷新数据_Vue.js的列表数据的同步更新方法

    这次给大家带来Vue.js的列表数据的同步更新方法,Vue.js列表数据同步更新方法的注意事项有哪些,下面就是实战案例,一起来看一下. 数组的 push(),pop(),shift(),unshift ...

  9. php mysql刷新表格_PHP和AJAMYSQL数据库刷新表格

    好文网为大家准备了关于PHP和AJAMYSQL数据库刷新表格的文章,好文网里面收集了五十多篇关于好PHP和AJAMYSQL数据库刷新表格好文,希望可以帮助大家.更多关于PHP和AJAMYSQL数据库刷 ...

最新文章

  1. SpringMVC详细示例实战教程
  2. 华为手机有没有html,华为手机,到底有没有自己的核心技术?看内行人怎么说...
  3. Kubernetes 最佳安全实践指南
  4. java发布sevlet_发布一个java Servlet (静态发布)
  5. Redis中事务的实现流程
  6. 魔兽世界---屠夫(Just a Hook)
  7. 《四世同堂》金句摘抄(十一)
  8. 前端基础_认识前端.md
  9. devc++不兼容_Mac压缩文件Win不支持?BetterZip帮你解决!
  10. 网络核心之数据交换-电路交换
  11. 关于ibatis中sqlMap配置文件中使用到,的处理
  12. 【弃】Selenium官方文档中文版
  13. 洛谷 P1538 迎春舞会之数字舞蹈
  14. Qt水波进度条Demo
  15. MacOS 使用SwitchHosts修改 hosts 不生效的原因及解决方法
  16. 牛客练习赛41 b 666RPG (01背包)
  17. Mac安装Adobe Zii5.3.0过程
  18. 雅虎网宣布将关闭“站长天下”服务功能
  19. html导航栏点击之后变色,鼠标滑过字体加粗、背景变色的CSS导航栏
  20. Java基础学习(11)---Java注解和反射

热门文章

  1. 无意看到这款小软件:RunAsDate,非常有创意
  2. 深入Nodejs技术栈
  3. 21-12-05周总结
  4. 洛谷 P1629 - 邮递员送信(往返两遍dijkstra)
  5. office2010安装教程
  6. Windows2008R2 打补丁后重启,系统无法正常启动
  7. pypinyin切换字典
  8. Python入门 NUMECA计算文件处理(一)
  9. 初用VScode并配置,自定义代码片段(快捷键),自动格式化代码快捷键,保存格式化代码快捷键
  10. 【C4D教程】全网最好的C4D常用插件分享!错过就没有了!