初始 10w, 每月定投 5000
初始 10w 不定投
代码
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>复利投资增长图表</title>
<script src="https://cdn.jsdelivr.net/npm/echarts@5.4.3/dist/echarts.min.js"></script>
<style>
#main {
width: 1200px;
height: 700px;
margin: 30px auto;
}
.center {
text-align: center;
margin: 10px;
}
input {
margin-right: 30px;
}
</style>
</head>
<body>
<div class="center">
初始资金(元)
<input type="number" id="initialCapital" placeholder="初始资金(元)" value="100000"/>
年化收益率(%)
<input type="number" id="annualReturn" placeholder="年化收益率(%)" value="12"/>
投资期限(年)
<input type="number" id="years" placeholder="投资期限(年)" value="30"/>
</div>
<div class="center">
每月定投金额(元)
<input type="number" id="monthlyInvestment" placeholder="每月定投金额" value="5000"/>
定投期限(年)
<input type="number" id="yearInvestmentCount" placeholder="定投期限(年)" value="10"/>
</div>
<div id="main"></div>
<script>
// 投资参数
var initialCapital = 100000; // 初始资金10万
var monthlyInvestment = 5000; // 每月定投5000元
var yearInvestmentCount = 10; // 定投期限(年), 0 代表不定投
var years = 30; // 投资期限
var annualReturn = 0.12; // 年化收益率12%
updateParams()
render()
Array.from(document.querySelectorAll('input')).forEach(input => {
input.addEventListener('input', function () {
updateParams()
render()
})
})
// 监听输入框输入, 然后更新投资参数
function updateParams() {
initialCapital = +document.getElementById('initialCapital').value;
annualReturn = +document.getElementById('annualReturn').value / 100;
years = +document.getElementById('years').value;
monthlyInvestment = +document.getElementById('monthlyInvestment').value;
yearInvestmentCount = +document.getElementById('yearInvestmentCount').value;
}
function render() {
// 初始化ECharts实例
var chartDom = document.getElementById('main');
var myChart = window.echarts.init(chartDom);
var monthlyReturn = Math.pow(1 + annualReturn, 1/12) - 1; // 月收益率
var totalMonths = years * 12;
// 计算数据
var yearData = [];
var totalValueData = [];
var profitData = [];
var totalInvestmentData = [];
var monthlyData = [];
var currentTotal = initialCapital;
var totalInvested = initialCapital;
var addMonthlyInvestment = monthlyInvestment;
// 按月计算复利
for (var month = 0; month <= totalMonths; month++) {
if (typeof yearInvestmentCount === 'number' && month > yearInvestmentCount * 12) {
addMonthlyInvestment = 0;
}
if (month > 0) {
// 每月先计算收益,再追加投资
currentTotal = currentTotal * (1 + monthlyReturn);
currentTotal += addMonthlyInvestment;
totalInvested += addMonthlyInvestment;
}
// 每年记录一次数据
if (month % 12 === 0) {
var year = month / 12;
var profit = currentTotal - totalInvested;
yearData.push('第' + year + '年');
totalValueData.push(parseFloat(currentTotal.toFixed(2)));
profitData.push(parseFloat(profit.toFixed(2)));
totalInvestmentData.push(parseFloat(totalInvested.toFixed(2)));
monthlyData.push(month);
}
}
// 关键年份数据
var keyYears = [5, 10, 15, 20, 25, 30, 35, 40, 45, 50].filter(year => year <= years);
var keyYearData = keyYears.map(year => {
var index = year;
return {
year: year,
total: totalValueData[index],
profit: profitData[index],
invested: totalInvestmentData[index]
};
});
var monthlyInvestmentText = (monthlyInvestment && yearInvestmentCount) ? ` + 每月定投${monthlyInvestment}元,定投期限${yearInvestmentCount}年` : '';
// 配置项
var option = {
title: {
text: `初始${initialCapital}${monthlyInvestmentText},年化收益率${annualReturn*100}%,${years}年复利增长`,
subtext: '复利的惊人效应',
left: 'center'
},
tooltip: {
trigger: 'axis',
formatter: function(params) {
var year = params[0].name;
var total = parseFloat(params[0].value).toLocaleString();
var profit = parseFloat(params[1].value).toLocaleString();
var invested = parseFloat(params[2].value).toLocaleString();
var returnRate = ((parseFloat(params[0].value) / parseFloat(params[2].value) - 1) * 100).toFixed(1);
return year + '<br/>' +
'总资产: ¥' + total + '元<br/>' +
'总投资: ¥' + invested + '元<br/>' +
'总收益: ¥' + profit + '元<br/>' +
'累计收益率: ' + returnRate + '%';
}
},
legend: {
data: ['总资产', '投资收益', '总投资本金'],
top: '8%'
},
xAxis: {
type: 'category',
data: yearData,
axisLabel: {
interval: 3,
rotate: 45
}
},
yAxis: {
type: 'value',
name: '金额 (万元)',
axisLabel: {
formatter: function(value) {
return (value / 10000).toFixed(0);
}
}
},
series: [
{
name: '总资产',
type: 'line',
data: totalValueData,
lineStyle: {
width: 4
},
itemStyle: {
color: '#5470c6'
},
areaStyle: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{ offset: 0, color: 'rgba(84, 112, 198, 0.6)' },
{ offset: 1, color: 'rgba(84, 112, 198, 0.1)' }
])
},
smooth: true
},
{
name: '投资收益',
type: 'line',
data: profitData,
lineStyle: {
width: 3,
type: 'dashed'
},
itemStyle: {
color: '#91cc75'
},
smooth: true
},
{
name: '总投资本金',
type: 'line',
data: totalInvestmentData,
lineStyle: {
width: 2,
type: 'dotted'
},
itemStyle: {
color: '#ee6666'
},
smooth: true
}
],
grid: {
left: '3%',
right: '4%',
bottom: '12%',
top: '18%',
containLabel: true
},
dataZoom: [
{
type: 'inside',
start: 0,
end: 100
},
{
start: 0,
end: 100,
bottom: '5%'
}
],
graphic: {
type: 'text',
left: 'center',
top: '12%',
style: {
text: '关键年份数据:\n' + keyYearData.map(item =>
`第${item.year}年: 总资产${(item.total/10000).toFixed(0)}万 (收益${(item.profit/10000).toFixed(0)}万)`
).join('\n'),
font: '12px Arial',
fill: '#333',
width: 400,
overflow: 'break'
}
}
};
// 使用配置项和数据显示图表
myChart.setOption(option);
// 响应窗口大小变化
window.addEventListener('resize', function() {
myChart.resize();
});
}
</script>
</body>
</html>