如何用.NET Core、HTML/JS或Kendo UI创建多级标签柱状图?
解决方案:.NET Core实现多级标签柱状图(兼容Kendo UI/HTML JS)
针对你需要实现的多级标签柱状图需求,结合你的.NET Core+Kendo UI技术栈,提供以下两种可行方案:
一、基于Kendo UI的变通实现
Kendo UI原生无多级分类轴,但可通过调整数据结构+自定义轴标签模板模拟效果:
调整数据源结构
修改后端DTO,拆分原合并字段CompanyName_Product为独立的BrandName(品牌)和ProductName(产品)字段,确保接口返回包含这两个层级的数据。修改Kendo Chart代码
通过分类轴分组+自定义标签模板渲染多级内容:
@(Html.Kendo().Chart<Commsights.Data.DataTransferObject.DashbroadDataTransfer>() .Name("ChartTopProductByBrand") .HtmlAttributes(new { style = "width: 100%; height: 400px;" }) .Title(t => t.Text("Top Product by Brand").Color("#0000ff").Font("20px sans-serif")) .DataSource(dataSource => dataSource .Read(read => read.Action("sp_loadTopProduct_byBrandTolist", "Dashbroad").Data("FilterCompany")) ) .Legend(legend => legend.Position(ChartLegendPosition.Bottom)) .ChartArea(chartArea => chartArea.Background("#ffffff")) .Events(events => events.SeriesClick("onSeriesClick")) .Theme("material") .SeriesColors("#1a8cdc", "#f9a83a", "#cc3e3e", "#00a36a", "#7f58af", "#e54d42", "#2f83c3", "#f3bd42" , "#bf3e8f", "#60bd68", "#e44b23", "#6d9cbb", "#e6a9b8", "#76923c", "#ac4f47", "#4c6d8f", "#d1a154", "#9074a5" , "#c5b62c", "#5c5c5c", "#8fb0d9", "#c69c6d", "#69a8c3", "#e7d26f", "#bca7a7", "#77bc43", "#ab9d95", "#b6d957", "#dd6262", "#e0a646") .SeriesDefaults(seriesDefaults => seriesDefaults.Bar().Stack(true)) .Series(series => { series.Bar(model => model.ProductName_ProjectNameCount) .Name("Product") .Opacity(0.7) .CategoryField("ProductName") .Tooltip(tooltip => tooltip.Visible(true).Template("#= dataItem.BrandName # - #= dataItem.ProductName # - #= value # article")); }) .CategoryAxis(axis => axis .Groups(groups => groups.Add().Field("BrandName")) .Labels(labels => labels .Template("#= dataItem.BrandName #<br/><small>#= dataItem.ProductName #</small>") .Align(ChartAxisLabelAlign.Center) ) .MajorGridLines(lines => lines.Visible(false)) ) .ValueAxis(axis => axis.Numeric()) .Tooltip(tooltip => tooltip.Visible(true).Format("{0:N0}")) .Pannable(pannable => pannable.Lock(ChartAxisLock.Y)) )
- 添加CSS优化样式
让层级标签更清晰:
.k-chart .k-axis-labels .k-label { white-space: normal; text-align: center; } .k-chart .k-axis-labels small { font-size: 11px; opacity: 0.8; }
二、纯HTML+JavaScript实现(Chart.js)
若Kendo的变通方案无法满足需求,可直接用Chart.js实现完全自定义的多级标签:
- 引入Chart.js
在视图中添加CDN引用:
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
- 渲染图表代码
通过AJAX获取后端数据并渲染:
<canvas id="multiLevelBarChart" style="width:100%;height:400px;"></canvas> <script> // 调用后端接口获取数据 fetch('/Dashbroad/sp_loadTopProduct_byBrandTolist', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(FilterCompany()) }) .then(res => res.json()) .then(data => { // 整理数据结构 const brandMap = {}; data.forEach(item => { if (!brandMap[item.BrandName]) brandMap[item.BrandName] = []; brandMap[item.BrandName].push({ product: item.ProductName, count: item.ProductName_ProjectNameCount }); }); // 提取所有产品标签和数据集 const allProducts = data.map(item => item.ProductName); const datasets = Object.keys(brandMap).map((brand, idx) => ({ label: brand, data: data.map(item => item.BrandName === brand ? item.ProductName_ProjectNameCount : 0), backgroundColor: `hsl(${idx * 360 / Object.keys(brandMap).length}, 70%, 60%)` })); // 初始化图表 new Chart(document.getElementById('multiLevelBarChart'), { type: 'bar', data: { labels: allProducts, datasets }, options: { responsive: true, scales: { x: { ticks: { callback: (val, idx) => { const item = data[idx]; return [`${item.BrandName}`, `${item.ProductName}`]; }, maxRotation: 0, minRotation: 0 }, grid: { display: false } }, y: { beginAtZero: true, title: { display: true, text: '数量' } } }, plugins: { title: { display: true, text: 'Top Product by Brand', font: { size: 20, color: '#0000ff' } }, tooltip: { callbacks: { label: ctx => `${data[ctx.dataIndex].BrandName} - ${data[ctx.dataIndex].ProductName}: ${ctx.raw} article` } } } } }); }); </script>
关键说明
- Kendo方案需后端配合拆分数据字段,利用分组和模板模拟多级标签,保留Kendo生态的一致性。
- Chart.js方案完全脱离Kendo限制,灵活性更高,适合复杂的层级可视化需求。
- 两种方案均兼容.NET Core,只需确保后端接口返回包含品牌、产品、数值的结构化数据。
内容的提问来源于stack exchange,提问作者Nhật Tân
相关产品推荐
相关产品推荐

