1. 程式人生 > 實用技巧 >原創 - react + d3.js + TS 堆疊條形圖 報錯解決

原創 - react + d3.js + TS 堆疊條形圖 報錯解決

react + d3.js + TS 堆疊條形圖 報錯解決

1. 結構

結構請看之前的文章,這裡記錄部分報錯解決的方式。能力受限無法解決方式不會優雅。

2. 報錯

2.1 stack生成器報錯

var naiveStack = d3.stack().keys(naiveKeys).order(d3.stackOrderNone)(naiveDaa);

Argument of type 'IDatum[]' is not assignable to parameter of type '{ [key: string]: number; }[]'

解決方式,補全泛型引數

var naiveStack = d3.stack<IDatum, string>().keys(naiveKeys).order(d3.stackOrderNone)(naiveData);

index.d.ts 中 stack宣告為:

export funcion stack<Datum, Key>(): Stack<any, Datum, Key>;

The first generic corresponds to the data type of an element in the data array passed into the stack generator.

The second generic corresponds to the data type of key used to identify a series.

Datum: 傳遞給stack生成器的資料陣列的中元素的資料型別。
Key: 用於標識序列的鍵的資料型別。

2.2 accessor儲存器報錯

letmaxDatumSubd=d3.max(naiveStack,(d:IDatum)=>
//d3.max(d,(subd:)=>subd[1])
d3.max(d,(subd:IDatum)=>subd[1])
);

Argument of type 'Series<IDatum, string>[]' is not assignable to parameter of type 'ArrayLike'

Argument of type 'IDatum' is not assignable to parameter of type 'ArrayLike'

兩個報錯都是說value型別和accessor讀取的引數型別不一致。

解決方法,根據Stack的資料型別正確指明引數型別。

letmaxDatumSubd=d3.max(naiveStack,(d:d3.Series<IDatum,string>)=>
//d3.max(d,(subd:)=>subd[1])
d3.max(d,(subd:SeriesPoint<IDatum>)=>subd[1])
);

index.d.ts下,關於stack重要的兩個型別介面

2.2.1 SeriesPoint<Datum> extends Array<number>

export interface SeriesPoint<Datum> extends Array<number> {
    0: number;
    1: number;
    data: Datum;
}

Each series point j in a stack chart corresponds to the jth element in the input data

堆疊中的每個點j系列圖對應於第j元素輸入資料。

Each point is represented as an array [y0, y1] where y0 is the lower value(baseline) and y1 is the upper value(topline); the difference between y0 and y1 corresponds to the computed value for this point

每個點代表一個數組 [y0, y1],y1為下部值(基線),y2為上部值(背線)。y0和y1的差對應於這個點的計算值。

SeriesPoint is a [number, number] two-element Array with added data and index properties related to the data element which formed the basis for theSeriesPoint.

序列點是一個[number, number]兩元素陣列,其中添加了於資料元素相關的資料和索引屬性,這些資料元素構成了該序列化點的基礎。

2.2.2 Series<Datum, Key> exends Array<SeriesPoint>

export interface Series<Datum, key> extends Array<SeriesPoint<Datum>> {
    key: key;
    index: number;
}

The series are determined by the keys accessor; each series i in the returned array corrsponds to the ith key.

序列由鍵訪問器決定,每個序列i對應第i個鍵。

Each series is an array of points, where each point j corresponds to the jth element in the input data.

每個序列是由點組成的陣列,每個點j對應輸出資料的第j個元素

The key for each series is available as series.key, and the index as series.index.

每個系列的鍵可作為系列鍵使用。索引為series.index。

所以對於IDatum【】而言, 第一層為Series<IDatum, string>,第二層為SeriesPoint

3. 程式碼

importReact,{useState,useEffect,useRef}from"react";
import*asd3from"d3";
importmomentfrom"moment";
import{Series,SeriesPoint}from"d3";
interfaceIDatum{
month:Date;
apples:number;
bananas:number;
cherries:number;
dates:number;
}
constStackBarChart:React.FC=()=>{
const[width]=useState(1600);
const[height]=useState(800);
const[margin]=useState({
left:160,
top:80,
right:80,
bottom:160,
});
constinnerWidth=width-margin.left-margin.right;
constinnerHeight=height-margin.top-margin.bottom;
constsvg=useRef<SVGSVGElement>(null);
useEffect(()=>{
constsvgSelection=d3
.select(svg.current)
.attr("width",width)
.attr("height",height);
constg=svgSelection
.append("g")
.attr("id","maingroup")
.attr("transform",`translate(${margin.left},${margin.right})`);
constnaiveData:IDatum[]=[
{
month:newDate(2015,0,1),
apples:3840,
bananas:1920,
cherries:960,
dates:400,
},
{
month:newDate(2015,1,1),
apples:1600,
bananas:1440,
cherries:960,
dates:400,
},
{
month:newDate(2015,2,1),
apples:640,
bananas:960,
cherries:640,
dates:400,
},
{
month:newDate(2015,3,1),
apples:320,
bananas:480,
cherries:640,
dates:400,
},
];
constnaiveKeys=["apples","banans","cherries","dates"];
//rememberthefollowingapisareabletomodifythe'offset'thedata;
//.offset(d3.stackOffsetNone)
//.offset(d3.stackOffsetWiggle)
varnaiveStack=d3
.stack<IDatum,string>()
.keys(naiveKeys)
.order(d3.stackOrderNone)(naiveData);
constxValue=(d:IDatum)=>{
returnmoment(d.month.toISOString()).format("YYYY-M-D");
};
//
letmaxDatumSubd=d3.max(naiveStack,(d:d3.Series<IDatum,string>)=>
//d3.max(d,(subd:)=>subd[1])
d3.max(d,(subd:SeriesPoint<IDatum>)=>subd[1])
);
constyScale=d3
.scaleLinear()
.domain([0,maxDatumSubd||0])
.range([innerHeight,0])
.nice();
constxScale=d3
.scaleBand()
.domain(naiveData.map((d:any)=>xValue(d)))
.range([0,innerWidth])
.padding(0.5);
constnaiveAxes=function(){
constxAxis=d3.axisBottom(xScale).tickSize(-innerHeight);
constxAxisGroup=g
.append("g")
.attr("id","xaxis")
.call(xAxis)
.attr("transform",`translate(0,${innerHeight})`);
constyAxis=d3
.axisLeft(yScale)
//.tickFormat(d3.format('.2r'))
.tickFormat(d3.format(".1s"))
//.tickFormat(d3.format('.2s'))
//.tickFormat(d3.format('.2f'))
.tickSize(-innerWidth);
constyAxisGroup=g.append("g").attr("id","yaxis").call(yAxis);
return{xAxisGroup:xAxisGroup,yAxisGroup:yAxisGroup};
};
naiveAxes();
constcolor=d3
.scaleOrdinal<string,string>()
.domain(naiveKeys)
.range(d3.schemeSet3);
//return;
//console.log(naiveStack);
constgroupRect=g
.append("g")
.selectAll("g")
.data(naiveStack)
.enter()
.append("g")
.attr("fill",(d:any,i:any)=>{
returncolor(i);
})
.selectAll("rect")
.data((d)=>d)
.enter()
.append("rect")
.attr("y",(d:any)=>{
returnyScale(d[1])||0;
})
.attr("x",(d:any)=>{
returnxScale(xValue(d.data))||0;
})
.attr("height",(d:any)=>{
leta=yScale(d[0])||0;
letb=yScale(d[1])||0;
returna-b;
})
.attr("width",xScale.bandwidth());
return;
//starttododata-join;
groupRect
.selectAll("rect")
.data(naiveStack)
.join("g")
.attr("class","maingroup")
.attr("fill",(d:Series<IDatum,string>)=>color(d.key))
.selectAll(".datarect")
.attr("y",(d:any)=>{
returnyScale(d[1])||0;
})
.attr("x",(d:any)=>{
returnxScale(xValue(d.data))||0;
})
.attr("height",(d:any)=>{
leta=yScale(d[0])||0;
letb=yScale(d[1])||0;
returna-b;
})
.attr("width",xScale.bandwidth());
d3.selectAll(".ticktext").attr("font-size","2em");
d3.selectAll("#xaxistext").attr("y","10");
});
return(
<>
<svgref={svg}></svg>
</>
);
};
export{StackBarChart};

原文地址:https://www.cnblogs.com/xiaoxu-xmy/p/13767293.html
GitHub: https://github.com/lemon-Xu/Learning-d3.-Js
作者: lemon