console
const data = [{type:'起运港滞留',days:10,route:'深圳➡️美西FBA'},{type:'起运港滞留',days:10,route:'深圳➡️海外仓➡️美西FBA'},{type:'起运港滞留',days:3,route:'上海➡️美西FBA'},{type:'起运港滞留',days:3,route:'上海➡️海外仓➡️美西FBA'},{type:'起运港滞留',days:3,route:'宁波➡️美西FBA'},{type:'起运港滞留',days:3,route:'宁波➡️海外仓➡️美西FBA'},{type:'海运',days:17,route:'深圳➡️美西FBA'},{type:'海运',days:17,route:'深圳➡️海外仓➡️美西FBA'},{type:'海运',days:17,route:'上海➡️美西FBA'},{type:'海运',days:17,route:'上海➡️海外仓➡️美西FBA'},{type:'海运',days:17,route:'宁波➡️美西FBA'},{type:'海运',days:17,route:'宁波➡️海外仓➡️美西FBA'},{type:'目的港滞留',days:14,route:'深圳➡️美西FBA'},{type:'目的港滞留',days:14,route:'深圳➡️海外仓➡️美西FBA'},{type:'目的港滞留',days:14,route:'上海➡️美西FBA'},{type:'目的港滞留',days:14,route:'上海➡️海外仓➡️美西FBA'},{type:'目的港滞留',days:14,route:'宁波➡️美西FBA'},{type:'目的港滞留',days:14,route:'宁波➡️海外仓➡️美西FBA'},{type:'目的港发最终仓',days:3,route:'深圳➡️美西FBA'},{type:'目的港发最终仓',days:3,route:'上海➡️美西FBA'},{type:'目的港发最终仓',days:3,route:'宁波➡️美西FBA'},{type:'目的港发中转仓',days:3,route:'深圳➡️海外仓➡️美西FBA'},{type:'目的港发中转仓',days:3,route:'上海➡️海外仓➡️美西FBA'},{type:'目的港发中转仓',days:3,route:'宁波➡️海外仓➡️美西FBA'},{type:'中转仓处理',days:2,route:'深圳➡️海外仓➡️美西FBA'},{type:'中转仓处理',days:2,route:'上海➡️海外仓➡️美西FBA'},{type:'中转仓处理',days:2,route:'宁波➡️海外仓➡️美西FBA'},{type:'中转仓发最终仓',days:1,route:'深圳➡️海外仓➡️美西FBA'},{type:'中转仓发最终仓',days:1,route:'上海➡️海外仓➡️美西FBA'},{type:'中转仓发最终仓',days:1,route:'宁波➡️海外仓➡️美西FBA'},{type:'起运港滞留',days:7,route:'深圳➡️日本FBA'},{type:'起运港滞留',days:7,route:'深圳➡️海外仓➡️日本FBA'},{type:'起运港滞留',days:3,route:'上海➡️日本FBA'},{type:'起运港滞留',days:3,route:'上海➡️海外仓➡️日本FBA'},{type:'海运',days:5,route:'深圳➡️日本FBA'},{type:'海运',days:5,route:'深圳➡️海外仓➡️日本FBA'},{type:'海运',days:5,route:'上海➡️日本FBA'},{type:'海运',days:5,route:'上海➡️海外仓➡️日本FBA'},{type:'目的港滞留',days:2,route:'深圳➡️日本FBA'},{type:'目的港滞留',days:2,route:'深圳➡️海外仓➡️日本FBA'},{type:'目的港滞留',days:2,route:'上海➡️日本FBA'},{type:'目的港滞留',days:2,route:'上海➡️海外仓➡️日本FBA'},{type:'目的港发最终仓',days:7,route:'深圳➡️日本FBA'},{type:'目的港发最终仓',days:7,route:'上海➡️日本FBA'},{type:'目的港发中转仓',days:1,route:'深圳➡️海外仓➡️日本FBA'},{type:'目的港发中转仓',days:1,route:'上海➡️海外仓➡️日本FBA'},{type:'中转仓处理',days:1,route:'深圳➡️海外仓➡️日本FBA'},{type:'中转仓处理',days:1,route:'上海➡️海外仓➡️日本FBA'},{type:'中转仓发最终仓',days:4,route:'深圳➡️海外仓➡️日本FBA'},{type:'中转仓发最终仓',days:4,route:'上海➡️海外仓➡️日本FBA'},{type:'起运港滞留',days:7,route:'深圳➡️日本乐天'},{type:'起运港滞留',days:3,route:'上海➡️日本乐天'},{type:'海运',days:5,route:'深圳➡️日本乐天'},{type:'海运',days:5,route:'上海➡️日本乐天'},{type:'目的港滞留',days:2,route:'深圳➡️日本乐天'},{type:'目的港滞留',days:2,route:'上海➡️日本乐天'},{type:'目的港发最终仓',days:1,route:'深圳➡️日本乐天'},{type:'目的港发最终仓',days:1,route:'上海➡️日本乐天'}]
const uniq = (arr, key) => [...new Set(arr.map(x => x[key]))]
const routes = uniq(data, 'route')
const routesDays = routes.map(r => data.filter(d => d.route === r).map(d => d.days).reduce((x, y) => x + y))
const types = uniq(data, 'type')
const colors = [{ backgroundColor: 'rgba(255,99,132,0.5)', borderColor: 'rgb(255,99,132)' }, { backgroundColor: 'rgba(255,159,64,0.5)', borderColor: 'rgb(255,159,64)' }, { backgroundColor: 'rgba(255,205,86,0.5)', borderColor: 'rgb(255,205,86)' }, { backgroundColor: 'rgba(75,192,192,0.5)', borderColor: 'rgb(75,192,192)' }, { backgroundColor: 'rgba(54,162,235,0.5)', borderColor: 'rgb(54,162,235)' }, { backgroundColor: 'rgba(153,102,255,0.5)', borderColor: 'rgb(153,102,255)' }]
const config = {
type: 'bar',
data: {
labels: routes.map((r, i) => `${r} (${routesDays[i]}天)`),
datasets: types.map((t, i) => ({
label: t,
stack: 'a',
...colors[i],
data: routes.map(r => (data.find(d => d.type === t && d.route === r) || {}).days)
}))
},
options: {
indexAxis: 'y',
plugins: {
legend: {
labels: {
font: {
size: 14
}
}
},
title: {
display: true,
text: '21KEG物流时效图',
font: {
size: 24,
weight: 'bold'
}
},
subtitle: {
display: true,
text: 'Custom Chart Subtitle'
}
},
scales: {
xAxes: [{
ticks: {
fontSize: 10
},
scaleLabel: {
display: true,
labelString: '天数',
fontSize: 10
}
}],
yAxes: [{
ticks: {
fontSize: 10
},
scaleLabel: {
display: true,
labelString: '物流方式',
fontSize: 10
}
}]
},
plugins1: {
datalabels: {
display: true,
color: 'white',
font: {
size: 10,
}
}
}
}
}
var myChart = new Chart(
document.getElementById('myChart'),
config
);
<div>
<canvas id="myChart"></canvas>
</div>