|
|
@@ -270,7 +270,7 @@
|
|
|
grid: {
|
|
|
left: '3%',
|
|
|
right: '5%',
|
|
|
- top: 50,
|
|
|
+ top: 60,
|
|
|
bottom: '3%',
|
|
|
containLabel: true
|
|
|
},
|
|
|
@@ -299,6 +299,7 @@
|
|
|
type: 'value',
|
|
|
// name:'金额',
|
|
|
position: 'left',
|
|
|
+ boundaryGap: [0, '18%'],
|
|
|
axisLabel : {
|
|
|
color: '#fff',
|
|
|
formatter: formatInvestmentAmount
|
|
|
@@ -319,7 +320,7 @@
|
|
|
type: 'bar',
|
|
|
data: [],
|
|
|
barMaxWidth: 24,
|
|
|
- barGap: '0%',
|
|
|
+ barGap: '20%',
|
|
|
label: {
|
|
|
show: true,
|
|
|
position: 'top',
|
|
|
@@ -336,13 +337,12 @@
|
|
|
type: 'bar',
|
|
|
data: [],
|
|
|
barMaxWidth: 24,
|
|
|
- barGap: '0%',
|
|
|
+ barGap: '20%',
|
|
|
label: {
|
|
|
show: true,
|
|
|
position: 'top',
|
|
|
color: '#fff',
|
|
|
fontSize: 12,
|
|
|
- offset: [0, -10],
|
|
|
formatter: formatInvestmentBarLabel
|
|
|
},
|
|
|
// itemStyle: {
|
|
|
@@ -363,6 +363,11 @@
|
|
|
yusjOption.series[0].name = '施工图预算';
|
|
|
const yusjChart1 = echarts.init(document.getElementById('yusjchart'));
|
|
|
yusjChart1.setOption(yusjOption);
|
|
|
+ [gusjChart1, yusjChart1, mbsjChart1].forEach(function (chart) {
|
|
|
+ chart.on('legendselectchanged', function () {
|
|
|
+ fitInvestmentComparisonLabels(chart);
|
|
|
+ });
|
|
|
+ });
|
|
|
|
|
|
|
|
|
const tenderoption = {
|
|
|
@@ -1033,7 +1038,10 @@
|
|
|
return value.substring(0, length) + '\n' + (remaining.length > length ? remaining.substring(0, length - 1) + '…' : remaining);
|
|
|
}
|
|
|
}
|
|
|
- }]
|
|
|
+ }],
|
|
|
+ series: option.series.map(function () {
|
|
|
+ return { labelLayout: createInvestmentComparisonLabelLayout(chart, option) };
|
|
|
+ })
|
|
|
});
|
|
|
}
|
|
|
|
|
|
@@ -1041,4 +1049,64 @@
|
|
|
const amount = Number(params.value) || 0;
|
|
|
return amount === 0 ? '' : formatInvestmentAmount(amount);
|
|
|
}
|
|
|
+
|
|
|
+ function createInvestmentComparisonLabelLayout(chart, option) {
|
|
|
+ const selected = option.legend[0].selected || {};
|
|
|
+ const visibleSeries = option.series.map((series, index) => ({ series, index }))
|
|
|
+ .filter(item => selected[item.series.name] !== false);
|
|
|
+ let layouts = null;
|
|
|
+ return function (params) {
|
|
|
+ if (!layouts) {
|
|
|
+ const labels = [];
|
|
|
+ const barStep = params.rect.width * 1.2;
|
|
|
+ const zeroY = chart.convertToPixel({ yAxisIndex: 0 }, 0);
|
|
|
+ visibleSeries.forEach(function (item, seriesPosition) {
|
|
|
+ item.series.data.forEach(function (value, dataIndex) {
|
|
|
+ const amount = Number(value) || 0;
|
|
|
+ if (!amount) return;
|
|
|
+ const textRect = echarts.format.getTextRect(String(formatInvestmentAmount(amount)), '12px sans-serif');
|
|
|
+ const centerX = chart.convertToPixel({ xAxisIndex: 0 }, dataIndex) +
|
|
|
+ (seriesPosition - (visibleSeries.length - 1) / 2) * barStep;
|
|
|
+ labels.push({
|
|
|
+ key: item.index + ':' + dataIndex,
|
|
|
+ dataIndex,
|
|
|
+ amount,
|
|
|
+ seriesIndex: item.index,
|
|
|
+ x: centerX - textRect.width / 2,
|
|
|
+ y: Math.min(zeroY, chart.convertToPixel({ yAxisIndex: 0 }, amount)) - textRect.height - 5,
|
|
|
+ width: textRect.width,
|
|
|
+ height: textRect.height,
|
|
|
+ });
|
|
|
+ });
|
|
|
+ });
|
|
|
+ // 先保留较小金额的位置,再把与其相交的较大金额向上避让。
|
|
|
+ // 同时检查相邻分类,避免窄屏时跨分类的金额标签重叠。
|
|
|
+ labels.sort((a, b) => a.amount - b.amount || b.seriesIndex - a.seriesIndex);
|
|
|
+ const placed = [];
|
|
|
+ layouts = {};
|
|
|
+ labels.forEach(function (label) {
|
|
|
+ for (let i = 0; i < placed.length; i++) {
|
|
|
+ const other = placed[i];
|
|
|
+ const sameCategory = label.dataIndex === other.dataIndex;
|
|
|
+ const overlaps = label.x < other.x + other.width + 4 && label.x + label.width + 4 > other.x &&
|
|
|
+ label.y < other.y + other.height + 4;
|
|
|
+ if ((sameCategory || overlaps) && label.y + label.height + 4 > other.y) {
|
|
|
+ label.y = other.y - label.height - 4;
|
|
|
+ i = -1;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ placed.push(label);
|
|
|
+ layouts[label.key] = label;
|
|
|
+ });
|
|
|
+ }
|
|
|
+ const layout = layouts[params.seriesIndex + ':' + params.dataIndex];
|
|
|
+ return layout ? {
|
|
|
+ x: params.rect.x + params.rect.width / 2,
|
|
|
+ y: layout.y,
|
|
|
+ align: 'center',
|
|
|
+ verticalAlign: 'top',
|
|
|
+ hideOverlap: false,
|
|
|
+ } : {};
|
|
|
+ };
|
|
|
+ }
|
|
|
</script>
|