Javascript D3.js伪三维条形图
我开始研究d3,并尝试创建一个具有3D效果的直方图。正确计算了所有面的位置,但它们仅在浏览器的检查器中清晰可见。我的代码怎么了?(参见方法“updateChart”) 上图中,有东西干扰了显示。但我不知道到底是什么Javascript D3.js伪三维条形图,javascript,d3.js,3d,Javascript,D3.js,3d,我开始研究d3,并尝试创建一个具有3D效果的直方图。正确计算了所有面的位置,但它们仅在浏览器的检查器中清晰可见。我的代码怎么了?(参见方法“updateChart”) 上图中,有东西干扰了显示。但我不知道到底是什么 类条形图扩展了React.Component{ //跳过代码。。。 updateChart(){ 此文件为.updateCales(); const{data,width,height,connectFauxDOM}=this.props; const{xAxisLength,y
类条形图扩展了React.Component{
//跳过代码。。。
updateChart(){
此文件为.updateCales();
const{data,width,height,connectFauxDOM}=this.props;
const{xAxisLength,yAxisLength}=this.getAxisLength();
const faux=connectFauxDOM('div','chart');
常量svg=d3
.选择(人造)
.append('svg')
.attr('viewBox','0 0${width}${height}`)
.attr('preserveAspectRatio','xMinYMin');
const xAxis=d3.axisBottom().scale(this.xScale);
const yAxis=d3.axisLeft().scale(this.yScale);
svg
.append('g')
.attr('class','x轴')
艾特先生(
“转换”,
`翻译(${this.margin},${height-this.margin})`,
)
.呼叫(xAxis);
svg
.append('g')
.attr('class','y轴')
艾特先生(
“转换”,
`翻译(${this.margin},${this.margin})`,
)
.呼叫(yAxis);
svg
.选择全部('g.y轴g.tick')
.append('行')
.classed('网格线',真)
.attr('x1',0)
.attr('y1',0)
.attr('x2',xAxisLength)
.attr('y2',0);
常量g=svg.append('g').attr('class','body').attr(
“转换”,
`翻译(${this.margin},0)`,
);
g、 selectAll('svg.bar')
.数据(数据)
.输入()
.append('svg')
.attr('class','bar');
恒角=45;
常量矩形宽度=()=>
Math.floor(xAxisLength/data.length)-this.padding;
const rectHeight=(值)=>yAxisLength-this.yScale(值);
常量rectX=(值)=>this.xScale(值);
const rectY=(value)=>this.yScale(value)+this.margin;
常数棒=g
.selectAll('svg.bar')
.数据(数据)
.attr('x',(d)=>rectX(d.label))
.attr('y',(d)=>rectY(d.value));
酒吧
.数据(数据)
.append('rect')
.attr('class','forward bar')
.attr('height',(d)=>rectHeight(d.value))
.attr('width',()=>rectWidth());
//侧面
酒吧
.数据(数据)
.append('rect')
.attr('class','side bar')
.attr('width',rectWidth()/2)
.attr('height',(d)=>rectHeight(d.value))
.attr('transform','translate(${rectWidth()},0)skewY(${-angle})`);
酒吧
.数据(数据)
.append('rect')
.attr('class','top bar')
.attr('width',rectWidth())
.attr('height',rectWidth()/2)
艾特先生(
“转换”,
`translate(${rectWidth()/2},${-rectWidth()/2})skewX(${-angle})`,
);
}
render(){
const{chart,classes}=this.props;
返回{chart};
}
}
我认为扭曲的
不起作用,
更适合您的任务
下面是一个简单的函数add3DBar:
const add3DBar=(父级、XPO、YPO、宽度、高度、深度)=>{
const g=parent.append('g').attr('transform','translate(${xPos},${yPos})`);
g、 append('path').attr('d','m0,0v${height}H${width}v0h0z`).style('fill','#000080');
g、 追加('path').attr('d','m0,${height}L${depth},${height-depth}H${depth+width}L${width},${height}Z`).style('fill','#0000FF');
g、 append('path').attr('d','M${width},0l${width+depth},${-depth},V${-height-depth}L${width}${-height}Z`)style('fill','#0000C0');
}
,在哪里
xPos和yPos-条左下角的坐标
宽度,高度,深度-钢筋尺寸
看看它在小提琴中是如何工作的:
const add3DBar=(父级、XPO、YPO、宽度、高度、深度)=>{
const g=parent.append('g').attr('transform','translate(${xPos},${yPos})`);
g、 append('path').attr('d','m0,0v${height}H${width}v0h0z`).style('fill','#000080');
g、 追加('path').attr('d','m0,${height}L${depth},${height-depth}H${depth+width}L${width},${height}Z`).style('fill','#0000FF');
g、 append('path').attr('d','M${width},0l${width+depth},${-depth},V${-height-depth}L${width}${-height}Z`)style('fill','#0000C0');
}
const svg=d3.select('svg');
添加3DBAR(svg,30,150,30,100,10);
添加3dbar(svg,70,150,30,70,10);
添加3DBAR(svg,110、150、30、120、10)代码>
感谢您以这种方式构建3D。但是“成长”动画呢?很难?我认为这是可行的。请你发一个新问题,我会尽力回答的。。完成)
class BarChart extends React.Component {
//skip code...
updateChart() {
this.updateScales();
const { data, width, height, connectFauxDOM } = this.props;
const { xAxisLength, yAxisLength } = this.getAxisLength();
const faux = connectFauxDOM('div', 'chart');
const svg = d3
.select(faux)
.append('svg')
.attr('viewBox', `0 0 ${width} ${height}`)
.attr('preserveAspectRatio', 'xMinYMin');
const xAxis = d3.axisBottom().scale(this.xScale);
const yAxis = d3.axisLeft().scale(this.yScale);
svg
.append('g')
.attr('class', 'x-axis')
.attr(
'transform',
`translate(${this.margin},${height - this.margin})`,
)
.call(xAxis);
svg
.append('g')
.attr('class', 'y-axis')
.attr(
'transform',
`translate(${this.margin},${this.margin})`,
)
.call(yAxis);
svg
.selectAll('g.y-axis g.tick')
.append('line')
.classed('grid-line', true)
.attr('x1', 0)
.attr('y1', 0)
.attr('x2', xAxisLength)
.attr('y2', 0);
const g = svg.append('g').attr('class', 'body').attr(
'transform',
`translate(${this.margin}, 0 )`,
);
g.selectAll('svg.bar')
.data(data)
.enter()
.append('svg')
.attr('class', 'bar');
const angel = 45;
const rectWidth = () =>
Math.floor(xAxisLength / data.length) - this.padding;
const rectHeight = (value) => yAxisLength - this.yScale(value);
const rectX = (value) => this.xScale(value);
const rectY = (value) => this.yScale(value) + this.margin;
const bars = g
.selectAll('svg.bar')
.data(data)
.attr('x', (d) => rectX(d.label))
.attr('y', (d) => rectY(d.value));
bars
.data(data)
.append('rect')
.attr('class', 'forward-bar')
.attr('height', (d) => rectHeight(d.value))
.attr('width', () => rectWidth());
// side
bars
.data(data)
.append('rect')
.attr('class', 'side-bar')
.attr('width', rectWidth() / 2)
.attr('height', (d) => rectHeight(d.value))
.attr('transform', `translate (${rectWidth()}, 0) skewY(${-angel})`);
bars
.data(data)
.append('rect')
.attr('class', 'top-bar')
.attr('width', rectWidth())
.attr('height', rectWidth() / 2)
.attr(
'transform',
`translate (${rectWidth() / 2},${-rectWidth() / 2}) skewX(${-angel})`,
);
}
render() {
const { chart, classes } = this.props;
return <div className={classes.svg}>{chart}</div>;
}
}