ChartJS 如何在图表js中将正值定位在堆叠条形图的顶部,将负值定位在底部

siv3szwd  于 2023-08-05  发布在  Chart.js
关注(0)|答案(2)|浏览(191)

formatter函数给出了每组堆叠条形图的总和,我试图执行datalabels,如果总和为正,则将其定位在上,如果总和为负,则将其定位在下。请任何帮助将不胜感激。


的数据

  1. datalabels: {
  2. anchor: (context) =>{
  3. const anchor = [];
  4. let sum = ?;
  5. if(parseFloat(sum) >=0){
  6. anchor.push('end');
  7. }else{
  8. anchor.push('start');
  9. }
  10. return anchor;
  11. },
  12. align: (context) =>{
  13. const align = [];
  14. let sum = ?;
  15. if(parseFloat(sum) >=0){
  16. align.push('end');
  17. }else{
  18. align.push('bottom');
  19. }
  20. return align;
  21. },
  22. formatter:(value, context) =>{
  23. const datasetArray = [];
  24. context.chart.data.datasets.forEach((dataset) =>{
  25. if(dataset.data[context.dataIndex] != undefined){
  26. datasetArray.push(dataset.data[context.dataIndex]);
  27. }
  28. });
  29. function totalSum(total, datapoint){
  30. return +total + +datapoint;
  31. }
  32. let sum = datasetArray.reduce(totalSum);
  33. if(context.datasetIndex === datasetArray.length - 1){
  34. return parseFloat(sum).toFixed(2) ;
  35. }else{
  36. return '';
  37. }
  38. },
  39. }

字符串

jtoj6r0c

jtoj6r0c1#

目前还不清楚这些酒吧是如何堆叠的-有许多未知的选择。基于图像图表的视觉外观的可能组合可以是以下:

  1. const N = 10;
  2. const dataGenerator = (plus = 600, minus = 400, pNull = 1) =>
  3. Array.from({length: N}, ()=>Math.random() < pNull ?
  4. Math.round(Math.random()*(plus+minus)-minus)/4 : null)
  5. const ctx1 = document.getElementById('chart1');
  6. new Chart(ctx1, {
  7. type: "bar",
  8. plugins: [ChartDataLabels],
  9. data: {
  10. labels: Array.from({length: N}, (_, i)=>'l'+(i+1)),
  11. datasets: [
  12. {
  13. data: dataGenerator(),
  14. stack: 'a',
  15. },
  16. {
  17. data: dataGenerator() ,
  18. stack: 'a',
  19. },
  20. {
  21. data: dataGenerator(100, 50, 0.5),
  22. stack: 'a',
  23. },
  24. ]
  25. },
  26. options: {
  27. indexAxis: 'x',
  28. layout: {
  29. padding: {
  30. top: 20,
  31. bottom: 20
  32. }
  33. },
  34. animation: {
  35. duration: 0
  36. },
  37. scales: {
  38. x: {
  39. ticks:{
  40. display: false
  41. }
  42. },
  43. y: {
  44. stacked: true,
  45. beginAtZero: true
  46. }
  47. },
  48. plugins:{
  49. legend:{
  50. display: false
  51. },
  52. datalabels:{
  53. formatter: (value, context) => {
  54. const {dataIndex, datasetIndex, chart} = context;
  55. const dataForDataIndex = chart.data.datasets.map(
  56. dataset=>dataset.data[dataIndex] ?? 0
  57. );
  58. const total = dataForDataIndex.reduce((s, x)=>s+x)
  59. // the index of the dataset that contains the last point (at dataIndex)
  60. // with the same sign as the total - that is the one that should carry
  61. // the total label
  62. const datasetIndexLast = dataForDataIndex.findLastIndex(x => x * total > 0);
  63. context.total = total;
  64. return datasetIndexLast === datasetIndex ? total.toFixed(2) : null
  65. },
  66. anchor: (context) => {
  67. return context.total > 0 ? 'end' : 'start'
  68. },
  69. align: (context) => {
  70. return context.total > 0 ? 'top' : 'bottom';
  71. },
  72. clip: false
  73. }
  74. }
  75. }
  76. });

个字符
这背后的想法是为数据集中的所有条启用数据标签,但选择正确定位的一个来表示formatter的总和-即最后一个数据集,其值(对于当前dataIndex)与总和具有相同的符号。如果使用order选项,情况可能会有所不同。
这段代码还使用了这样一个事实,即context对象在formatteralignanchor方法之间是共享的,* 对于同一个datasetIndex *,formatter总是第一个--如果formatter返回null,则其他方法甚至不会被调用。因此,它将当前datasetIndex的和保存在context对象中,以供调用alignanchor的唯一一个点(每个datasetIndex)使用。对于一个更安全的解决方案,即不使用这个未记录的事实,可以重新计算alignanchor中的总和,或者使用外部对象缓存总和,这可以是一种通过只计算一次总和来优化计算的解决方案,第一次为数据集调用formatter

展开查看全部
kyks70gy

kyks70gy2#

您可以使用chartjs-plugin-datalabels,如here所示。

  1. Chart.defaults.set('plugins.datalabels', {
  2. color: '#FE777B'
  3. });
  4. var chart = new Chart(ctx, {
  5. options: {
  6. plugins: {
  7. // Change options for ALL labels of THIS CHART
  8. datalabels: {
  9. color: '#36A2EB',
  10. anchor: ()=>/*your condition here*/
  11. }
  12. }
  13. },
  14. data: {
  15. datasets: [{
  16. // Change options only for labels of THIS DATASET
  17. datalabels: {
  18. color: '#FFCE56'
  19. }
  20. }]
  21. }
  22. });

字符串
同时检出定位属性。

展开查看全部

相关问题