无法在 table 个单元格中呈现 d3 图表
Unable to render d3 chart in table cells
目前使用 angular 7 和 d3 v7。
尝试在 table 的每个单元格中渲染面积图(如下图所示)。但是使用 angular 方法渲染的 svg 保持循环渲染。不确定我在这里做错了什么
HTML代码
<tr [id]="'row' + '-' + fleet" *ngFor="let fleet of fleetcolumn">
<td>{{ fleet }}</td>
<ng-container *ngFor="let station of formattedBaseStations | slice: 1">
<td style="width: 28em;">
<div [id]="'demandChartInTable1-' + station + '-' + fleet + '-A'"> {{d3DemandChartIntable(station, fleet, 'A')}} </div>
</mat-grid-tile>
<mat-grid-tile class="FOChart">
<div [id]="'demandChartInTable1-' + station + '-' + fleet + '-B'"> {{d3DemandChartIntable(station, fleet, 'A')}} </div>
</mat-grid-tile>
</mat-grid-list>
</td>
</ng-container>
</tr>
.ts代码
d3DemandChartIntable(station, code, position) {
// set data
let temp1 = this.data
.filter(d => d.baseCode == station && d.code == code && d.position == position)
.map(d => {
return {
date: d3.timeParse('%Y-%m-%d')(d.date),
hours: d.hours
};
});
const e = document.querySelector('.captainChart');
// set the dimensions and margins of the graph
const margin = { top: 0, right: 0, bottom: 1, left: 1 },
width = 120 - margin.left - margin.right,
height = 90 - margin.top - margin.bottom;
// append the svg object to the body of the page
const svg = d3
.select(`#demandChartInTable1-${station}-${fleet}-${position}`)
.append('svg')
.attr('width', e.clientWidth + margin.left + margin.right)
.attr('height', e.clientHeight + margin.bottom)
.append('g')
.attr('transform', `translate(${margin.left},${margin.top})`);
const x = d3
.scaleTime()
.domain(d3.extent(data, d => d.date))
.range([0, e.clientWidth]);
// Y axis
const y = d3
.scaleLinear()
.domain([0, 500])
.range([e.clientHeight + margin.bottom, 0]);
// Add the area
return svg
.append('path')
.datum(temp1)
.attr('fill', '#cce5df')
.attr('stroke', '#69b3a2')
.attr('stroke-width', 1.5)
.attr(
'd',
d3
.area()
.x(d => x(d.date))
.y0(y(0))
.y1(d => y(d.hours))
);
}
以上代码在每个单元格中渲染重复的 svg 而不是只渲染一次
任何帮助将不胜感激
症结在下面的代码中:
const svg = d3
.select(`#demandChartInTable1-${station}-${fleet}-${position}`)
.append('svg')
它选择 table 单元格,然后附加一个 SVG 元素。这意味着如果 SVG 已经存在,则会在其旁边添加另一个。如果你想解决这个问题,你可以
- Select 并更新现有的 SVG 并且只创建一次(例如
ngOnInit
或 ngAfterViewInit
);
- 删除任何现有的 SVG 并绘制一个新的,使用
const cell = d3.select(`#demandChartInTable1-${station}-${fleet}-${position}`);
cell.remove('*');
const svg = cell.append('svg')
目前使用 angular 7 和 d3 v7。
尝试在 table 的每个单元格中渲染面积图(如下图所示)。但是使用 angular 方法渲染的 svg 保持循环渲染。不确定我在这里做错了什么
HTML代码
<tr [id]="'row' + '-' + fleet" *ngFor="let fleet of fleetcolumn">
<td>{{ fleet }}</td>
<ng-container *ngFor="let station of formattedBaseStations | slice: 1">
<td style="width: 28em;">
<div [id]="'demandChartInTable1-' + station + '-' + fleet + '-A'"> {{d3DemandChartIntable(station, fleet, 'A')}} </div>
</mat-grid-tile>
<mat-grid-tile class="FOChart">
<div [id]="'demandChartInTable1-' + station + '-' + fleet + '-B'"> {{d3DemandChartIntable(station, fleet, 'A')}} </div>
</mat-grid-tile>
</mat-grid-list>
</td>
</ng-container>
</tr>
.ts代码
d3DemandChartIntable(station, code, position) {
// set data
let temp1 = this.data
.filter(d => d.baseCode == station && d.code == code && d.position == position)
.map(d => {
return {
date: d3.timeParse('%Y-%m-%d')(d.date),
hours: d.hours
};
});
const e = document.querySelector('.captainChart');
// set the dimensions and margins of the graph
const margin = { top: 0, right: 0, bottom: 1, left: 1 },
width = 120 - margin.left - margin.right,
height = 90 - margin.top - margin.bottom;
// append the svg object to the body of the page
const svg = d3
.select(`#demandChartInTable1-${station}-${fleet}-${position}`)
.append('svg')
.attr('width', e.clientWidth + margin.left + margin.right)
.attr('height', e.clientHeight + margin.bottom)
.append('g')
.attr('transform', `translate(${margin.left},${margin.top})`);
const x = d3
.scaleTime()
.domain(d3.extent(data, d => d.date))
.range([0, e.clientWidth]);
// Y axis
const y = d3
.scaleLinear()
.domain([0, 500])
.range([e.clientHeight + margin.bottom, 0]);
// Add the area
return svg
.append('path')
.datum(temp1)
.attr('fill', '#cce5df')
.attr('stroke', '#69b3a2')
.attr('stroke-width', 1.5)
.attr(
'd',
d3
.area()
.x(d => x(d.date))
.y0(y(0))
.y1(d => y(d.hours))
);
}
以上代码在每个单元格中渲染重复的 svg 而不是只渲染一次
任何帮助将不胜感激
症结在下面的代码中:
const svg = d3
.select(`#demandChartInTable1-${station}-${fleet}-${position}`)
.append('svg')
它选择 table 单元格,然后附加一个 SVG 元素。这意味着如果 SVG 已经存在,则会在其旁边添加另一个。如果你想解决这个问题,你可以
- Select 并更新现有的 SVG 并且只创建一次(例如
ngOnInit
或ngAfterViewInit
); - 删除任何现有的 SVG 并绘制一个新的,使用
const cell = d3.select(`#demandChartInTable1-${station}-${fleet}-${position}`);
cell.remove('*');
const svg = cell.append('svg')