【发布时间】:2021-07-02 07:39:00
【问题描述】:
我是 d3.js 的新手,我的任务是创建如下图所示的脚。我有它的 X 和 Y 坐标,我正在使用散点图和线图来创建它,但我无法在连接点的边界上画一条线。这是Stackblitz Link
下面是我的代码
export class ScatterPlotComponent implements OnChanges {
@Input() data = [];
private width = 350;
private height = 500;
private margin = 30;
public svg;
public svgInner;
public yScale;
public xScale;
public xAxis;
public yAxis;
public tooltip;
public lineGroup;
constructor() {}
public ngOnChanges(changes): void {
if (changes.hasOwnProperty('data') && this.data) {
console.log(this.data);
this.data.forEach((element: { insoleX: number; insoleY: number }) => {
element.insoleX = +element.insoleX.toFixed(2);
element.insoleY = +element.insoleY.toFixed(2);
});
this.initializeChart();
}
}
createDomain() {
const minY = d3.min(
this.data,
(d: { insoleX: number; insoleY: number }) => {
return d.insoleY;
}
);
const maxY = d3.max(
this.data,
(d: { insoleX: number; insoleY: number }) => {
return d.insoleY;
}
);
const nonNegativeAxis = minY >= 0 && maxY >= 0;
const positiveAndNegativeAxis = minY < 0 && maxY > 0;
let yScaleDomain: any[], xScaleDomain;
if (nonNegativeAxis) {
yScaleDomain = [
0,
d3.max(this.data, (d: { insoleX: number; insoleY: number }) => {
return d.insoleY;
}),
];
} else {
yScaleDomain = d3.extent(
this.data,
(d: { insoleX: number; insoleY: number }) => {
return d.insoleY;
}
);
}
xScaleDomain = d3.extent(
this.data,
function (d: { insoleX: number; insoleY: number }) {
return d.insoleX;
}
);
xScaleDomain[1] = xScaleDomain[1] + 2;
return { xScaleDomain, yScaleDomain };
}
initializeChart() {
const { xScaleDomain, yScaleDomain } = this.createDomain();
this.svg = d3
.select('#my_dataviz')
.append('svg')
.attr('width', this.width + this.margin + this.margin)
.attr('height', this.height + this.margin + this.margin)
.append('g')
.attr('transform', 'translate(' + this.margin + ',' + this.margin + ')');
this.xScale = d3
.scaleLinear()
.domain(xScaleDomain)
.rangeRound([0, this.width - 2 * this.margin]);
this.xAxis = this.svg
.append('g')
.attr('transform', 'translate(0,' + this.height + ')');
this.yScale = d3
.scaleLinear()
.domain([yScaleDomain[1] + 2, yScaleDomain[0]])
.rangeRound([0, this.height - 2 * this.margin]);
this.yAxis = this.svg.append('g').attr('id', 'y-axis');
const xAxis = d3.axisBottom(this.xScale);
this.xAxis.call(xAxis);
const yAxis = d3.axisLeft(this.yScale);
this.yAxis.call(yAxis);
const line = d3
.line()
.x((d) => d[0])
.y((d) => d[1])
.curve(d3.curveMonotoneX);
const points: [number, number][] = this.data.map((d) => [
this.xScale(d.insoleX),
this.yScale(d.insoleY),
]);
this.svg
.append('path')
.datum(points)
.attr('fill', 'none')
.attr('stroke', '#69b3a2')
.attr('stroke-width', 1.5)
.attr(
'd',
d3
.line()
.x((d) => d[0])
.y((d) => d[1])
);
// Add the points
this.svg
.append('g')
.selectAll('dot')
.data(this.data)
.enter()
.append('circle')
.attr('class', 'dot')
.classed('filled', true)
.attr('fill', '#83B9EE')
.attr('data-xvalue', (d: { insoleX: any }) => d.insoleX)
.attr('data-yvalue', (d: { insoleY: any }) => d.insoleY)
.attr('cx', (d: { insoleX: any }) => this.xScale(d.insoleX))
.attr('cy', (d: { insoleY: any }) => this.yScale(d.insoleY))
.attr('r', 4);
}
还有其他方法可以做到这一点吗?或者我怎样才能折射这个?请帮忙。
【问题讨论】:
-
您的积分顺序错误。您必须对它们进行排序以确保序列中的前一个点和下一个点最接近当前点
-
@MichaelRovinsky 我按升序对 y 轴进行了排序,图形得到了改善,但有些点仍然没有形成正确的线 [![在此处输入图像描述][1]][1] [1 ]:i.stack.imgur.com/Y57hD.png
-
@MichaelRovinsky 我设法在 stackblitz 上复制了代码,你能看一下吗? stackblitz.com/edit/angular-ni3mp4?file=src/app/scatter-plot/…
标签: javascript html reactjs angular d3.js