gpt4 book ai didi

javascript - d3 v4 TypeScript DefinitelyTyped Angular2 线与 X 轴上的 ScaleTime

转载 作者:行者123 更新时间:2023-11-30 11:35:33 25 4
gpt4 key购买 nike

我正在 angular2 组件中实现以下 block (一个简单的折线图): https://bl.ocks.org/d3noob/6f082f0e3b820b6bf68b78f2f7786084

我做过:npm install d3 --savenpm install @types/d3 --save

我已经在 SystemJS 中加载了 d3.min.js 和 d3.node.js。我在下面包含了我的 component.ts 文件。

import { Component, Input, ElementRef, OnInit } from '@angular/core';
import { TimelineChartConfig } from "./timeline";
import * as D3 from 'd3';


@Component({
moduleId: module.id,
selector: 'timeline',
templateUrl: 'timeline.component.html',
styles: [`
:host {
width: 100%;
display:block;
}
:host .axis path,
:host .axis line {
fill: none;
stroke: rgba(0, 0, 0, 0.2);
color: rgba(0, 0, 0, 0.2);
shape-rendering: crispEdges;
}

:host .axis text {
font-size: 20px;
fill: rgba(0, 0, 0, 0.9);
}

:host .color-label{
display: inline;
}
:host(.timeline) {
fill: none;
stroke: steelblue;
stroke-width: 2px;
}
`],
})

export class TimelineChartComponent implements OnInit {
private host; // D3 object referencing host dom object
private svg; // SVG in which we will print our chart
private margin; // Space between the svg borders and the actual chart graphic
private width; // Component width
private height; // Component height
private xScale; // D3 scale in X
private yScale; // D3 scale in Y
private xAxis; // D3 X Axis
private yAxis; // D3 Y Axis
private htmlElement: HTMLElement; // Host HTMLElement
config: Array<TimelineChartConfig> = [];

/* Constructor, needed to get @Injectables */
constructor(private element: ElementRef) {
this.htmlElement = this.element.nativeElement;
this.host = D3.select(this.element.nativeElement);
let incomeTimeline = new TimelineChartConfig();
incomeTimeline.settings = {
interpolation: 'monotone'
}
let data = [
{ x: "1-May-12", y: 58.13},
{ x: "30-Apr-12", y: 53.98},
{ x: "27-Apr-12", y: 67.00},
{ x: "26-Apr-12", y: 89.70},
{ x: "25-Apr-12", y: 99.00},
{ x: "24-Apr-12", y: 130.28},
{ x: "23-Apr-12", y: 166.70},
{ x: "20-Apr-12", y: 234.98},
{ x: "19-Apr-12", y: 345.44},
{ x: "18-Apr-12", y: 443.34},
{ x: "17-Apr-12", y: 543.70},
{ x: "16-Apr-12", y: 580.13},
{ x: "13-Apr-12", y: 605.23},
{ x: "12-Apr-12", y: 622.77},
{ x: "11-Apr-12", y: 626.20},
{ x: "10-Apr-12", y: 628.44},
{ x: "9-Apr-12", y: 636.23},
{ x: "5-Apr-12", y: 633.68},
{ x: "4-Apr-12", y: 624.31},
{ x: "3-Apr-12", y: 629.32},
{ x: "2-Apr-12", y: 618.63},
{ x: "30-Mar-12", y: 599.55},
{ x: "29-Mar-12", y: 609.86},
{ x: "28-Mar-12", y: 617.62},
{ x: "27-Mar-12", y: 614.48},
{ x: "26-Mar-12", y: 606.98},
];
incomeTimeline.dataset = data;
this.config.push(incomeTimeline);
}

ngOnInit(): void {
if (!this.config || this.config.length === 0) return;
this.setup();
this.buildSVG();
this.populate();
this.drawXAxis();
this.drawYAxis();
}

/* Will setup the chart container */
private setup(): void {
this.margin = { top: 20, right: 20, bottom: 40, left: 40 };
this.width = this.htmlElement.clientWidth - this.margin.left - this.margin.right;
this.height = this.width * 0.5 - this.margin.top - this.margin.bottom;
this.xScale = D3.scaleTime().range([0, this.width]);
this.yScale = D3.scaleLinear().range([this.height, 0]);
}

/* Will build the SVG Element */
private buildSVG(): void {
this.host.html('');
this.svg = this.host.append('svg')
.attr('width', this.width + this.margin.left + this.margin.right)
.attr('height', this.height + this.margin.top + this.margin.bottom)
.append('g')
.attr('transform', 'translate(' + this.margin.left + ',' + this.margin.top + ')');
}
/* Will draw the X Axis */
private drawXAxis(): void {
this.xAxis = D3.axisBottom(this.xScale);
this.svg.append('g')
.attr('class', 'x axis')
.attr('transform', 'translate(0,' + this.height + ')')
.call(this.xAxis);
}

/* Will draw the Y Axis */
private drawYAxis(): void {
this.yAxis = D3.axisLeft(this.yScale)
.tickPadding(10);
this.svg.append('g')
.attr('class', 'y axis')
.call(this.yAxis)
.append('text')
.attr('transform', 'rotate(-90)');
}

/* Will get the Maximum value in Y */
private getMaxY(): number {
let maxValuesOfCharts = [];
this.config.forEach(data => maxValuesOfCharts.push(Math.max.apply(Math, data.dataset.map(d => d.y))));
return Math.max(...maxValuesOfCharts);
}

/* Will populate datasets into areas*/
private populate(): void {
let parseTime = D3.timeParse("%d-%b-%y");
this.config.forEach((timeline: any) => {
console.log("timeline config", timeline);
timeline.dataset.forEach((d: any) => d.x = parseTime(d.x));
this.xScale.domain(D3.extent(timeline.dataset, (d: any) => d.x));
this.yScale.domain([0, this.getMaxY()]);

let valueline = D3.line()
.x((d) => this.xScale(d.x))
.y((d) => this.yScale(d.y))

this.svg.append('path')
.datum(timeline.dataset)
.attr('class', 'timeline')
.attr('d', valueline);
});
}
}

这是@types/d3-shape/index.d.ts 的 Line 部分,我认为这是合适的部分?但我不知道如何解释这一点。

export interface Line<Datum> {
/**
* Generates a line for the given array of data. Depending on this line generator’s associated curve,
* the given input data may need to be sorted by x-value before being passed to the line generator.
*
* IMPORTANT: If the rendering context of the line generator is null,
* then the line is returned as a path data string.
*
* @param data Array of data elements.
*/
(data: Datum[]): string | null;
/**
* Generates a line for the given array of data. Depending on this line generator’s associated curve,
* the given input data may need to be sorted by x-value before being passed to the line generator.
*
* IMPORTANT: If the line generator has been configured with a rendering context,
* then the line is rendered to this context as a sequence of path method calls and this function returns void.
*
* @param data Array of data elements.
*/
(data: Datum[]): void;

/**
* Returns the current x-coordinate accessor function, which defaults to a function returning first element of a two-element array of numbers.
*/
x(): (d: Datum, index: number, data: Datum[]) => number;
/**
* Sets the x accessor to the specified number and returns this line generator.
*
* @param x A constant x-coordinate value.
*/
x(x: number): this;
/**
* Sets the x accessor to the specified function and returns this line generator.
*
* When a line is generated, the x accessor will be invoked for each defined element in the input data array.
*
* The default x accessor assumes that the input data are two-element arrays of numbers. If your data are in a different format, or if you wish to transform the data before rendering,
* then you should specify a custom accessor.
*
* @param x A coordinate accessor function which returns the x-coordinate value. The x accessor will be invoked for each defined element in the input data array,
* being passed the element d, the index i, and the array data as three arguments.
x(x: (d: Datum, index: number, data: Datum[]) => number): this;

/**
* Returns the current y-coordinate accessor function, which defaults to a function returning second element of a two-element array of numbers.
*/
y(): (d: Datum, index: number, data: Datum[]) => number;
/**
* Sets the y accessor to the specified number and returns this line generator.
*
* @param y A constant y-coordinate value.
*/
y(y: number): this;
/**
* Sets the y accessor to the specified function and returns this line generator.
*
* When a line is generated, the y accessor will be invoked for each defined element in the input data array.
*
* The default y accessor assumes that the input data are two-element arrays of numbers. If your data are in a different format, or if you wish to transform the data before rendering,
* then you should specify a custom accessor.
*
* @param y A coordinate accessor function which returns the y-coordinate value. The y accessor will be invoked for each defined element in the input data array,
* being passed the element d, the index i, and the array data as three arguments.
*/
y(y: (d: Datum, index: number, data: Datum[]) => number): this;

图形已加载,但线路径已填充。

这是一个笨蛋:http://plnkr.co/edit/KwcgHsc7aPpE1tjv8mlb?p=preview

问题一:

为什么我会收到以下 TypeScript 错误:

错误 TS2339:类型“[number, number]”上不存在属性“x”。

错误 TS2339:类型“[number, number]”上不存在属性“y”。

问题二:

为什么我的 :host(.timeline) 样式没有被应用?

最佳答案

您需要将类型传递给 d3.line

例如,如果您的模型接口(interface)称为 Data

interface Data {
x: number;
y: number;
}

然后使用

d3.line<Data>()
.x(d => scaleX(d.x))
.y(d => scaleY(d.y));

这应该可以解决问题 #1

关于javascript - d3 v4 TypeScript DefinitelyTyped Angular2 线与 X 轴上的 ScaleTime,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44599129/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com