I'm currently working on implementing a bar graph with a selection dropdown that includes 3 values: By Date, By Week, By Month (where 'By Date' is the default option).
When retrieving data from the backend for 'ByDate', I have a large number of data points (around 50). As a result, when plotting these points, the x-axis becomes crowded and it's difficult to apply horizontal scrolling.
I attempted to create a demo on Stackblitz, but encountered a dependency issue that I couldn't resolve. However, you can view all the code here: Link
I was aiming for the bar graph to look something like this: Example
Apologies for not providing a functional demo, but I would appreciate any guidance on this matter.
Here is my function:
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()]);
}