我已经使用d3版本5制作了折线图。我现在面临的问题是,如果我有10条记录,那么如果我有30条记录,它将在折线图中的x轴上显示所有记录的日期。记录,然后它将在x轴上显示所有30条记录的日期。但是我想做的是,最初它应该只显示7个记录的日期,而当我们平移时,应该可以看到另一个日期。我也已经在其中实现了平移。我如何才能使这件事最初加载少量记录,然后在平移时显示更多记录?我已经在角度2做到了。
margin = { top: 50, right: 50, bottom: 50, left: 50 };
svg: any;
xScale: any;
xScaleCopy: any;
yScale: any;
xAxis: any;
yAxis: any;
line: any;
width: number;
height: number;
toolTipDiv: any;
timeParse: any;
ngOnInit() {
this.createLineChart();
}
private createLineChart() {
// Take date of format '01-25-2019'
this.timeParse = d3.timeParse('%m-%d-%Y');
this.width = (18 * 75) - this.margin.left - this.margin.right;
this.height = 600 - this.margin.top - this.margin.bottom;
// X AXIS
this.xScale = d3.scalePoint()
.domain(this.dataset[0].fluencyData.map((data) => {
return this.timeParse(data.date);
}).sort((a, b) => {
return a - b; // As We have dates, you still need to order your entries.
}))
.range([0, this.width]);
this.xScaleCopy = this.xScale.copy();
// Y AXIS
this.yScale = d3.scaleLinear()
.domain([0, 110])
.range([this.height, 0]);
this.xAxis = d3.axisBottom().scale(this.xScale).tickSizeOuter(0).tickFormat(d3.timeFormat('%b %d'));
this.yAxis = d3.axisLeft().scale(this.yScale).tickSize(-(this.width + (this.margin.left + this.margin.right) / 2 + 20));
// Line Generator
this.line = d3.line()
.x((data) => this.xScale(this.timeParse(data.date)))
.y((data) => this.yScale(data.wcpm));
const zoom = d3.zoom()
.scaleExtent([1, 30]) // This control how much you can unzoom and zoom
// .translateExtent([[0, -Infinity], [2 * this.width, Infinity]])
.extent([[0, 0], [this.width, this.height]])
.translateExtent([[0, 0], [this.width, this.height]])
.on('zoom', () => {
this.xAxis.scale(this.xScale);
groupX.call(this.xAxis);
// Rescale X Axis
this.xScale.range(this.xScaleCopy.range().map((d) => {
return d3.event.transform.applyX(d);
}));
// Redraw the line:
path.attr('d', this.line);
// Redraw the circles:
this.svg.selectAll('circle')
.attr('cx', (data) => {
return this.xScale(this.timeParse(data.date));
});
});
// Add SVG to Div
this.svg = d3.select('#displayChart').append('svg')
// .attr('preserveAspectRatio', 'xMidYMid meet')
// .attr(
// 'viewBox',
// '0 0 ' +
// (this.width + this.margin.left + this.margin.right) +
// ' ' +
// (this.height + this.margin.top + this.margin.bottom))
.attr('width', this.width + this.margin.left + this.margin.right + 20)
.attr('height', this.height + this.margin.top + this.margin.bottom)
.call(zoom)
.append('g')
.attr('transform', 'translate(' + this.margin.left + ',' + this.margin.top + ')');
// Set up a clip path for the circles and the path - so when we zoom we don't have overflow:
const clipPath = this.svg.append('clipPath')
.attr('id', 'clip')
.append('rect')
.attr('x', -(this.margin.left + this.margin.right) / 2)
.attr('y', -((this.margin.left + this.margin.right) / 2))
.attr('width', this.width + (this.margin.left + this.margin.right) / 2 + 20)
.attr('height', this.height + (this.margin.left + this.margin.right) / 2)
.attr('fill', 'none')
.style('pointer-events', 'none'); // we don't want mouse interaction.
// Append YAXIS to SVG
const groupY = this.svg.append('g')
.attr('class', 'yAxis')
.call(this.yAxis);
// Append XAXIS to the SVG
const groupX = this.svg.append('g')
.attr('class', 'xAxis')
.attr('transform', 'translate(' + ((this.margin.left + this.margin.right) / 2) + ',' + (this.height) + ')')
// .attr('transform', 'translate(0,' + this.height + ')')
.call(this.xAxis)
.attr('clip-path', 'url(#clip)');
// Make a Path for Dataset
const path = this.svg.append('path')
.datum(this.dataset[0].fluencyData)
.attr('class', 'line')
.attr('d', this.line)
.attr('transform', 'translate(' + ((this.margin.left + this.margin.right) / 2) + ',0 )')
.attr('clip-path', 'url(#clip)'); // apply the clip path.;
// Append Circles in chart with different Colors
this.appendCircles();
this.setToolTips();
// Text Heading of DATE in chart
this.svg.append('text')
.attr('transform', 'translate(' + (-20) + ',' + (this.height + 13) + ')')
.attr('dy', '.35em')
.attr('class', ' xAxis')
.text('Date');
}
private setToolTips() {
// Define the div for the tooltip
this.toolTipDiv = d3.select('#displayChart').append('div')
.attr('class', 'tooltip')
.style('opacity', 0);
this.svg.selectAll('circle').on('mouseover', (data) => {
this.toolTipDiv.transition()
.duration(200).ease(d3.easeSinInOut)
.style('opacity', .9);
this.toolTipDiv.html(data.wcpm + '<br/>' + data.type + '<br/>' + data.date)
.style('left', (d3.event.pageX - 50) + 'px')
.style('top', (d3.event.pageY - 50) + 'px');
})
.on('mouseout', () => {
this.toolTipDiv.transition()
.duration(500)
.style('opacity', 0);
});
}
private appendCircles() {
this.svg.selectAll('.developing')
.data(this.dataset[0].fluencyData)
.enter().append('circle')
.attr('class', (data) => data.type)
.attr('cx', (data) => {
return this.xScale(this.timeParse(data.date));
})
.attr('cy', (data) => this.yScale(data.wcpm))
.attr('r', 5)
.attr('transform', 'translate(' + ((this.margin.left + this.margin.right) / 2) + ',0)')
.attr('clip-path', 'url(#clip)'); // apply the clip path.
}
ngOnDestroy() {
d3.select('svg').remove();
}