实施现金流时间表 结果

问题描述

我正在尝试为现金流入和流出制定时间表,如下所示:

Cash flow

我不知道是否有任何可能有帮助的图表类型。有没有可能实现这样的图表?

解决方法

没有任何图表类型可以立即生成所需的图表。然而,它可以使用条形图和一些自定义代码来创建。

Plugin Core API 提供了不同的挂钩,可让您执行自定义代码。您可以定义一个 inline plugin 并通过 CanvasRenderingContext2D 直接在画布上绘制所需的线条、形状和文本。我将使用 beforeDraw 钩子,如下面的可运行代码片段所示:

function drawVerticalTriangle(ctx,x,y1,y2) {
  ctx.beginPath();
  ctx.moveTo(x,y1);
  ctx.lineTo(x + 6,y2);
  ctx.lineTo(x - 6,y2);
  ctx.fill();
};

function drawRightArrow(ctx,xLeft,xRight,y) {
  ctx.lineWidth = 3;
  ctx.beginPath(); 
  ctx.moveTo(xLeft,y);
  ctx.lineTo(xRight - 5,y);
  ctx.stroke();      
  ctx.beginPath();      
  ctx.moveTo(xRight,y);
  ctx.lineTo(xRight - 10,y + 6);
  ctx.lineTo(xRight - 10,y - 6);
  ctx.fill();
};

function drawTopArrow(ctx,yBottom,yTop) {
  ctx.lineWidth = 3;
  ctx.beginPath(); 
  ctx.moveTo(x,yBottom);
  ctx.lineTo(x,yTop - 5);
  ctx.stroke();      
  drawVerticalTriangle(ctx,yTop -10,yTop);
};

new Chart('myChart',{
  type: 'bar',plugins: [{
    beforeDraw: chart => {      
      let ctx = chart.ctx; 
      let xAxis = chart.scales.x;
      let yAxis = chart.scales.y;
      xAxis.ticks.forEach((v,i) => {       
        let x = xAxis.getPixelForTick(i);      
        let y = yAxis.getPixelForValue(chart.data.datasets[0].data[i]) - 3; 
        ctx.fillStyle = chart.data.datasets[0].borderColor;
        drawVerticalTriangle(ctx,y,y + 10);
        y = yAxis.getPixelForValue(chart.data.datasets[1].data[i]) + 3; 
        ctx.fillStyle = chart.data.datasets[1].borderColor;
        drawVerticalTriangle(ctx,y - 10);
      }); 
      ctx.strokeStyle = '#9999FF';
      ctx.fillStyle = '#9999FF';      
      let y = yAxis.getPixelForValue(0);
      drawRightArrow(ctx,xAxis.left - 5,xAxis.right + 40,y);
      ctx.font = '12px Arial';
      ctx.textAlign = 'right';
      ctx.fillText('PERIOD',xAxis.right + 30,y + 20);
      drawTopArrow(ctx,xAxis.left,yAxis.bottom + 10,yAxis.top - 10);
    }    
  }],data: {
    labels: ['1st year','2nd year','3rd year','4th year'],datasets: [
      {
        label: 'Cash inflow',data: [560,590,520,620],backgroundColor: '#0F9D58',borderColor: '#0F9D58',barThickness: 4
      },{
        label: 'Cash outflow',data: [-600,-550,-410,-570],backgroundColor: '#DB4437',borderColor: '#DB4437',barThickness: 4        
      }     
    ]
  },options: {
    animation: {
      duration: 100      
    },layout: {
      padding: {
        right: 40
      }
    },scales: {
      y: {
        grid: {  
          display: false,}        
      },x: {
        stacked: true,grid: {
          display: false,drawBorder: false
        }   
      }
    }
  }
});
canvas {
  max-width: 400px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.4.0/chart.min.js"></script>
<canvas id="myChart" height="110"></canvas>

,

到目前为止我能做的最好的是:

// Import from the chart.js npm module.
import { Chart } from "chart.js"; 

// Get the context of the canvas element in our HTML file.
let ctx = document.querySelector("canvas#chart").getContext("2d"); 

// Create a chart.
var chrt = new Chart(ctx,{
  type: "bar",data: {
    labels: ["1st year","2nd year","3rd year"],datasets: [
      {
        data: [-y1out.value,-y2out.value,-y3out.value],backgroundColor: ["#DB4437","#DB4437","#DB4437"],label: 'Cash outflow',},{
        data: [y1in.value,y2in.value,y3in.value],backgroundColor: ["#0F9D58","#0F9D58","#0F9D58"],label: 'Cash inflow',}
    ]
  }
});

// Update chart when user modifies input values
var els = document.getElementsByTagName("input");
for (var i = 0; i < els.length; i++) {
  els[i].addEventListener('input',function() {
    chrt.data.datasets[0].data = [-y1out.value,-y3out.value]
    chrt.data.datasets[1].data = [y1in.value,y3in.value]
    chrt.update();
  });
}

结果

Result screenshot

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...