te')); return $arr; } /* 遍历用户所有主题 * @param $uid 用户ID * @param int $page 页数 * @param int $pagesize 每页记录条数 * @param bool $desc 排序方式 TRUE降序 FALSE升序 * @param string $key 返回的数组用那一列的值作为 key * @param array $col 查询哪些列 */ function thread_tid_find_by_uid($uid, $page = 1, $pagesize = 1000, $desc = TRUE, $key = 'tid', $col = array()) { if (empty($uid)) return array(); $orderby = TRUE == $desc ? -1 : 1; $arr = thread_tid__find($cond = array('uid' => $uid), array('tid' => $orderby), $page, $pagesize, $key, $col); return $arr; } // 遍历栏目下tid 支持数组 $fid = array(1,2,3) function thread_tid_find_by_fid($fid, $page = 1, $pagesize = 1000, $desc = TRUE) { if (empty($fid)) return array(); $orderby = TRUE == $desc ? -1 : 1; $arr = thread_tid__find($cond = array('fid' => $fid), array('tid' => $orderby), $page, $pagesize, 'tid', array('tid', 'verify_date')); return $arr; } function thread_tid_delete($tid) { if (empty($tid)) return FALSE; $r = thread_tid__delete(array('tid' => $tid)); return $r; } function thread_tid_count() { $n = thread_tid__count(); return $n; } // 统计用户主题数 大数量下严谨使用非主键统计 function thread_uid_count($uid) { $n = thread_tid__count(array('uid' => $uid)); return $n; } // 统计栏目主题数 大数量下严谨使用非主键统计 function thread_fid_count($fid) { $n = thread_tid__count(array('fid' => $fid)); return $n; } ?>javascript - Argument of type '[string, string] error? (in Angular and d3) - Stack Overflow
最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Argument of type '[string, string] error? (in Angular and d3) - Stack Overflow

programmeradmin3浏览0评论

I am using d3 (version 4) with Angular 5 and am running into some errors that I can't find much information on. In my nameponent.ts I have my d3 code, and am getting errors under certain lines.

var x = d3.scaleTime()
  .rangeRound([0, width])
  .domain(d3.extent(this.data, function (d) { return d.date; }));

var y = d3.scaleLinear()
  .rangeRound([height, 0])
  .domain(d3.extent(this.data, function (d) { return d.ratio; }));

For both of these lines, I get the red line under everything inside the domain (d3.extent(this.data, function (d) { return d.ratio; })).

The error is:

Argument of type '[string, string] | [undefined, undefined]' is not 
assignable to parameter of type '(number | Date | { valueOf(): number;}) []'.
Type '[string, string]' is not assignable to type '(number | Date | 
{valueOf(): number; })[]'.
Types of property 'push' are inpatible.
  Type '(...items: string[]) => number' is not assignable to type 
'(...items: (number | Date | { valueOf(): number; })[]) => number'.
    Types of parameters 'items' and 'items' are inpatible.
      Type 'number | Date | { valueOf(): number; }' is not assignable 
to type 'string'.
        Type 'number' is not assignable to type 'string'.

My guess is that there's a clash in date type, but can't figure it out. Any thoughts?

If this helps, here is my entire .ts file:

import { Component, OnInit, Input } from '@angular/core';
import { DataService } from '../data.service';
import { Http } from '@angular/http';
import * as d3 from 'd3';

@Component({
 selector: 'app-name',
 templateUrl: './nameponent.html',
 styleUrls: ['./nameponent.css']
})
export class Name implements OnInit {
  @Input() site1;

constructor(private _dataService: DataService, private http: Http) { }

date: Date;
dates: any;
value: Number;
eachobj: any;
data: any;
average: any;
values: any;
name: any;
ngOnInit() {

this.data = this.site1
this.dates = Object.keys(this.data.historical_data)
this.values = Object.values(this.data.historical_data)
this.values.forEach((obj, i) => obj.date = this.dates[i]);
this.data = this.values        


var svg = d3.selectAll("#watertemp_graph"),
  margin = { top: 20, right: 20, bottom: 30, left: 0 },
  width = +svg.attr("width") - margin.left - margin.right,
  height = +svg.attr("height") - margin.top - margin.bottom
var parse = d3.timeParse("%Y-%m-%d")
var first = this.data[0].date
var last = this.data[(this.data.length) - 1].date

var g = svg.append("g")
  .attr("transform", "translate(" + margin.left + "," + margin.top + ")");
var baseValue = +this.data[0].avg_water_temp;
this.data.forEach(function (d) {
  d.date = parse(d.date);
  d.ratio = +(d.avg_water_temp / baseValue);
});

var x = d3.scaleTime()
  .rangeRound([0, width])
  .domain(d3.extent(this.data, function (d) { return d.date; }));
//ERROR

var y = d3.scaleLinear()
  .rangeRound([height, 0])
  .domain(d3.extent(this.data, function (d) { return d.ratio; }));
//ERROR

var line = d3.line()
  .x(function (d) { return x(d['date']); })
  .y(function (d) { return y(d['ratio']); });


// plot first and last dates on x axis
svg.append('g')
  .attr("class", "axis--x")
  .append("text")
  .attr("fill", "#000")
  .attr("x", (width / 2) - 80)
  .attr("y", height + 40)
  .text(first)
  .style("font-size", "09")
  .style("font-family", "Roboto")
  .style('fill', '#5a5a5a');
svg.append('g')
  .attr("class", "axis--x")
  .append("text")
  .attr("fill", "#000")
  .attr("x", (width / 2) + 45)
  .attr("y", height + 40)
  .text(last)
  .style("font-size", "09")
  .style("font-family", "Roboto")
  .style('fill', '#5a5a5a');


g.append("g")
  .call(d3.axisLeft(y))
  .remove();

g.append("path")
  .datum(this.data)
  .attr("fill", "none")
  .attr("stroke", "#26aae2")
  .attr("stroke-width", 1.5)
  .attr("d", line);

 }

}

I am using d3 (version 4) with Angular 5 and am running into some errors that I can't find much information on. In my name.ponent.ts I have my d3 code, and am getting errors under certain lines.

var x = d3.scaleTime()
  .rangeRound([0, width])
  .domain(d3.extent(this.data, function (d) { return d.date; }));

var y = d3.scaleLinear()
  .rangeRound([height, 0])
  .domain(d3.extent(this.data, function (d) { return d.ratio; }));

For both of these lines, I get the red line under everything inside the domain (d3.extent(this.data, function (d) { return d.ratio; })).

The error is:

Argument of type '[string, string] | [undefined, undefined]' is not 
assignable to parameter of type '(number | Date | { valueOf(): number;}) []'.
Type '[string, string]' is not assignable to type '(number | Date | 
{valueOf(): number; })[]'.
Types of property 'push' are inpatible.
  Type '(...items: string[]) => number' is not assignable to type 
'(...items: (number | Date | { valueOf(): number; })[]) => number'.
    Types of parameters 'items' and 'items' are inpatible.
      Type 'number | Date | { valueOf(): number; }' is not assignable 
to type 'string'.
        Type 'number' is not assignable to type 'string'.

My guess is that there's a clash in date type, but can't figure it out. Any thoughts?

If this helps, here is my entire .ts file:

import { Component, OnInit, Input } from '@angular/core';
import { DataService } from '../data.service';
import { Http } from '@angular/http';
import * as d3 from 'd3';

@Component({
 selector: 'app-name',
 templateUrl: './name.ponent.html',
 styleUrls: ['./name.ponent.css']
})
export class Name implements OnInit {
  @Input() site1;

constructor(private _dataService: DataService, private http: Http) { }

date: Date;
dates: any;
value: Number;
eachobj: any;
data: any;
average: any;
values: any;
name: any;
ngOnInit() {

this.data = this.site1
this.dates = Object.keys(this.data.historical_data)
this.values = Object.values(this.data.historical_data)
this.values.forEach((obj, i) => obj.date = this.dates[i]);
this.data = this.values        


var svg = d3.selectAll("#watertemp_graph"),
  margin = { top: 20, right: 20, bottom: 30, left: 0 },
  width = +svg.attr("width") - margin.left - margin.right,
  height = +svg.attr("height") - margin.top - margin.bottom
var parse = d3.timeParse("%Y-%m-%d")
var first = this.data[0].date
var last = this.data[(this.data.length) - 1].date

var g = svg.append("g")
  .attr("transform", "translate(" + margin.left + "," + margin.top + ")");
var baseValue = +this.data[0].avg_water_temp;
this.data.forEach(function (d) {
  d.date = parse(d.date);
  d.ratio = +(d.avg_water_temp / baseValue);
});

var x = d3.scaleTime()
  .rangeRound([0, width])
  .domain(d3.extent(this.data, function (d) { return d.date; }));
//ERROR

var y = d3.scaleLinear()
  .rangeRound([height, 0])
  .domain(d3.extent(this.data, function (d) { return d.ratio; }));
//ERROR

var line = d3.line()
  .x(function (d) { return x(d['date']); })
  .y(function (d) { return y(d['ratio']); });


// plot first and last dates on x axis
svg.append('g')
  .attr("class", "axis--x")
  .append("text")
  .attr("fill", "#000")
  .attr("x", (width / 2) - 80)
  .attr("y", height + 40)
  .text(first)
  .style("font-size", "09")
  .style("font-family", "Roboto")
  .style('fill', '#5a5a5a');
svg.append('g')
  .attr("class", "axis--x")
  .append("text")
  .attr("fill", "#000")
  .attr("x", (width / 2) + 45)
  .attr("y", height + 40)
  .text(last)
  .style("font-size", "09")
  .style("font-family", "Roboto")
  .style('fill', '#5a5a5a');


g.append("g")
  .call(d3.axisLeft(y))
  .remove();

g.append("path")
  .datum(this.data)
  .attr("fill", "none")
  .attr("stroke", "#26aae2")
  .attr("stroke-width", 1.5)
  .attr("d", line);

 }

}
Share Improve this question asked Sep 1, 2018 at 3:45 Devstar34Devstar34 1,0972 gold badges27 silver badges57 bronze badges 6
  • can you isolate the issue and post it using stackblitz. ? – solimanware Commented Sep 1, 2018 at 4:07
  • @Microsmsm here: stackblitz./edit/angular-mfgnfg The weird thing is... no sign of the error on stackblitz! Just within my IDE (vscode) on my local project. Perhaps that would indicate something – Devstar34 Commented Sep 1, 2018 at 4:20
  • the only thing of type [string, string] is the extent. console.log your this.data and the extent after the this.data.forEach() – rioV8 Commented Sep 1, 2018 at 4:54
  • Done, so is extent expecting an array of stings? Currently it thinks extent is an object. Would the best way to prevent that be declaring it as a string/array prior? Or converting after I assign data to it? – Devstar34 Commented Sep 1, 2018 at 5:01
  • 1 No. [string, string] can be the result of d3.extent() if the input is strings, or does TypeScript think that d3.extent() returns [string, string] and that .domain() wants type (number | Date | { valueOf(): number;}) [], an array of number, Date or something that can be converted to number(??) – rioV8 Commented Sep 1, 2018 at 11:13
 |  Show 1 more ment

1 Answer 1

Reset to default 17

d3.extent has two overloads that take two parameters:

export function extent<T>(array: ArrayLike<T>,
  accessor: (datum: T, index: number, array: ArrayLike<T>) => string | undefined | null):
  [string, string] | [undefined, undefined];

export function extent<T, U extends Numeric>(array: ArrayLike<T>,
  accessor: (datum: T, index: number, array: ArrayLike<T>) => U | undefined | null):
  [U, U] | [undefined, undefined];

TypeScript always resolves a call to the first matching overload, and since this.data is declared as type any, TypeScript is unable to rule out that the first overload matches. This is where the [string, string] is ing from. If you specify a more precise type for this.data, the first call should resolve to the second overload and the return type should e out as the expected [Date, Date] | [undefined, undefined]. You'll still need a type assertion to assert that the result is [Date, Date] and not [undefined, undefined]; I'm not aware of any reasonable way to do this with narrowing. So your code would look like:

var x = d3.scaleTime()
  .rangeRound([0, width])
  .domain(<[Date, Date]>d3.extent(this.data, function (d) { return d.date; }));

Given that you need the type assertion, you could leave this.data as any, though it would be better practice in general to give it a proper type. Analogous remarks apply to the second call to d3.extent.

发布评论

评论列表(0)

  1. 暂无评论