我正在尝试实现一个条形图,其中有一个选择下拉列表,其中包含 3 个值:按日期、按周、按月(默认情况下为“按日期”)。
“ByDate”后端的数据有很多数据点(大约 50 个)。因此,当我绘制该图时,x 轴点会挤压,并且我无法在其上应用水平滚动。
我尝试在 stackblitz 中创建一个演示,但存在依赖问题,无法解决。虽然所有代码都在这里:Link
实际上我需要像这样的条形图:示例
因此,很抱歉我无法提供有效的演示,但请在此提供帮助。
我的功能:
createGraphData() {
const margin = { top: 20, right: 30, bottom: 50, left: 60 };
const width = 800 - margin.left - margin.right;
const height = 400 - margin.top - margin.bottom;
d3.select('#bar-chart').select('svg').remove(); // Remove existing chart
const svg = d3
.select('#bar-chart')
.append('svg')
.attr('width', width + margin.left + margin.right)
.attr('height', height + margin.top + margin.bottom)
.append('g')
.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');
// Choose the appropriate dataset based on the selected option
const dataset =
this.graphRespId === 1
? this.graphDetails.lstByDateList
: this.graphRespId === 2
? this.graphDetails.lstByWeekDateList
: this.graphDetails.lstByMonthList;
// Extract x-axis and y-axis values from the dataset
const xValues = this.getXValues(dataset);
const yValues = dataset.map((data) => data.CountName);
// Set up x-axis and y-axis scales
const xScale = d3.scaleBand().domain(xValues).range([0, width]).padding(0.1);
const yScale = d3.scaleLinear().domain([0, Math.ceil(d3.max(yValues) / 10) * 10 + 5]).range([height, 0]);
// Draw x-axis
svg.append('g')
.attr('transform', 'translate(0,' + height + ')')
.call(d3.axisBottom(xScale));
// Draw y-axis
svg.append('g').call(d3.axisLeft(yScale));
// Draw bars
svg.selectAll('rect')
.data(dataset)
.enter()
.append('rect')
.attr('x', (data) => xScale(data[this.getXAxisKey()]))
.attr('y', (data) => yScale(data.CountName))
.attr('width', xScale.bandwidth())
.attr('height', (data) => height - yScale(data.CountName))
.attr('fill', () => this.getRandomColor());
}
getXAxisKey() {
return this.graphRespId === 1
? 'ByDate'
: this.graphRespId === 2
? 'StartDate'
: 'ByMonth';
}
// Generate a random color for the bars
getRandomColor() {
return '#' + Math.floor(Math.random() * 16777215).toString(16);
}
getXValues(dataset: any[]): any[] {
if (dataset === this.graphDetails.lstByDateList || dataset === this.graphDetails.lstByWeekDateList) {
dataset.sort((a, b) => d3.timeParse('%Y-%m-%dT%H:%M:%S')(a[this.getXAxisKey()]).getTime() - d3.timeParse('%Y-%m-%dT%H:%M:%S')(b[this.getXAxisKey()]).getTime());
return dataset.map((data) => {
const originalDate = new Date(data[this.getXAxisKey()]);
return this.datePipe.transform(originalDate, 'MM/dd/yyyy') || '';
});
}
return dataset.map((data) => data[this.getXAxisKey()]);
}
我记得两年前与 D3 合作过,所以我可能不记得所有的事情,但我很确定它与你试图暗示的图表相同。
import { getAllLifecycleHooks } from '@angular/compiler/src/lifecycle_reflector';
import { Component, OnDestroy, Pipe } from '@angular/core';
import { NbColorHelper, NbThemeService } from '@nebular/theme';
import { FactureAdcaisse } from '../../../@core/data/FactureAf';
import { FactureService } from '../../../@core/mock/facture.service';
@Component({
selector: 'ngx-d3-bar',
template: `
<chart echarts [options]="options" class="echart"></chart>
`,
})
export class D3BarComponent implements OnDestroy {
listfacture : FactureAf[];
facture :FactureAf= new FactureAf()
options: any = {};
themeSubscription: any;
totalpric_Y : any[]=[] ;
totalpric_X : any ;
constructor(private theme: NbThemeService , private facttureservice : FactureService) {
}
ngAfterViewInit() {
this.facttureservice.getAllActiveFacture().subscribe((data) => {
this.listfacture = data;
console.log("Invoices list",this.listfacture);
this.totalpric_Y = this.listfacture.map(x=>x.totalprice) ;
this.totalpric_X = this.listfacture.map(x=>x.name) ;
console.log("les x",this.totalpric_X)
console.log("les y",this.totalpric_Y)
this.themeSubscription = this.theme.getJsTheme().subscribe(config => {
const colors: any = config.variables;
const echarts: any = config.variables.echarts;
this.options = {
backgroundColor: echarts.bg,
color: [colors.primaryLight],
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'shadow',
},
},
grid: {
left: '3%',
right: '4%',
bottom: '3%',
containLabel: true,
},
xAxis: [
{
name: 'Partenaire :',
type: 'category',
data:this.totalpric_X,
axisTick: {
alignWithLabel: true,
},
axisLine: {
lineStyle: {
color: echarts.axisLineColor,
},
},
axisLabel: {
textStyle: {
color: echarts.textColor,
},
},
},
],
yAxis: [
{
type: 'value',
axisLine: {
lineStyle: {
color: echarts.axisLineColor,
},
},
splitLine: {
lineStyle: {
color: echarts.splitLineColor,
},
},
axisLabel: {
textStyle: {
color: echarts.textColor,
},
},
},
],
series: [
{
name: 'Total(DT)',
type: 'bar',
barWidth: '60%',
data: this.totalpric_Y,
},
console.log('whyyyyyyyyyyyyy',this.totalpric_Y)
],
};
});
});
console.log("les facture active",this.listfacture);
}
ngOnDestroy(): void {
this.themeSubscription.unsubscribe();
}
}
我认为这个例子很简单,因为您所需要做的就是获取数据并将其映射到 X 和 Y