Задача сделать из d3 svg картинку и засунуть в pdf.
Все хорошо работает, кроме одного момента. Картинка png с графика d3.js получается в момент, когда анимация еще не закончилась (пробовал ставить на 0 все эфекты, не помогло)
import React, { Component } from 'react';
import { render, findDOMNode } from 'react-dom';
import { Table, Input } from 'react-bootstrap';
import d3 from 'd3';
export default class ConvertPDFSubReport extends Component {
constructor(...props) {
super(...props);
this.state = {
comments: [],
width: this.props.width,
data: this.props.data,
chartName: this.props.chartName,
tableBody: '',
date_start: this.props.date_start,
date_finish: this.props.date_finish,
docSub:'',
imgData:''
};
}
componentDidMount() {
var dataArray=this.state.data;
var that = this;
var max = d3.max(dataArray, function(d) { return d.number;} );
var margin = {top: 20, right: 5, bottom: 30, left: 53},
width = this.state.width*0.98 - margin.left - margin.right,
height = ( (width*0.75) - margin.top - margin.bottom );
var yScale = d3.scale.linear()
.domain([0, max])
.range([0, height]);
var xScale = d3.scale.ordinal()
.domain(d3.range(0, dataArray.length))
.rangeBands([0, width]);
var colors = d3.scale.linear()
.domain([0, max])
.range(["#269", "#fa1"]);
var animateDuration =0,
animateDelay = 0;
//SVG element
var myMChartSub = d3.select(this.refs.modalchart).append("svg")
.attr("id", 'myMChartSub').attr("class", 'myChartSub')
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.style("background", 'rgba(200, 200, 200, 0.04)')
.append('g')
.attr('transform', 'translate('+margin.left+','+margin.top+')')
.selectAll("rect")
.data(dataArray)
.enter().append("rect")
.style("fill", function (d) { return colors(d.number) })
.attr("width", xScale.rangeBand()-2 )
.attr("height", function (d) { return yScale(d.number) })
.attr("x", function (d, i) { return xScale(i) })
.attr("y", height)
.attr("id", function(d,i){ return ('rectM'+ i); });// each rect has unique id
//Animation
myMChartSub.transition()
.attr('height', function(d){ return yScale(d.number) })
.attr('y', function(d){ return height - yScale(d.number) })
.duration(animateDuration)
.delay(function (d, i) { return i*animateDelay })
.ease('InBack');
var vScale = d3.scale.linear()
.domain([0, max])
.range([height, 0]);
var hScale = d3.scale.ordinal()
.domain(d3.range(1, dataArray.length+1))
.rangeBands([0, width]);
var vAxis = d3.svg.axis()
.scale(vScale)
.orient('left')
.ticks(5)
.tickFormat(d3.format("d"))
.tickSubdivide(0)
.tickPadding(5);
var vGuide = d3.select('#myMChartSub')
.append('g');
vAxis(vGuide);
vGuide.attr('transform', 'translate('+ margin.left + ','+margin.top+')' );
vGuide.selectAll('path')
.style('fill', 'none')
.style('stroke', '#ffffff');
vGuide.selectAll('line')
.style('fill', '#ffffff');
var hAxis = d3.svg.axis()
.scale(hScale)
.orient('bottom');
var hGuide = d3.select('#myMChartSub')
.append('g');
hAxis(hGuide);
hGuide.attr('transform', 'translate('+ margin.left + ','+(height + margin.top)+')' );
hGuide.selectAll('path')
.style('fill', 'none')
.style('stroke', '#ffffff');
hGuide.selectAll('line')
.style('fill', '#ffffff');
var svg = document.querySelector(".myChartSub"),
serializer = new XMLSerializer(),
svgStr = serializer.serializeToString(svg);
var img = new Image();
var canvas = document.createElement("canvas");
canvas.setAttribute("id", "canvas");
document.body.appendChild(canvas);
img.onload = function() {
canvas.style.display="none";
canvas.width = img.width ;
canvas.height = img.height ;
canvas.getContext("2d").drawImage(img, 0, 0, canvas.width, canvas.height);
};
img.src = 'data:image/svg+xml;base64,' + window.btoa(svgStr);
//вот тут цепляю картинку из канваса, все работает но не успевает дорисовать даже без анимации
setTimeout(function(){
var imgData = document.querySelector("#canvas");
imgData = imgData.toDataURL("image/png");
that.setState({imgData:imgData});
//Del canvas
var elem = document.getElementById("canvas");
elem.parentNode.removeChild(elem);
}, 2000);
}
subComments(){
var that=this,
table="",
item = that.props.data;
item.map( function(item, index){
var num = 1 + index;
if(that.state.comments[index] != null){
table=table+ "" + num + " " + item.name + " " + item.number + "\n"+that.state.comments[index] + "\n\n"
}
else table=table+ "" + num + " " + item.name + " " + item.number + "\n\n";
});
//структура pdf ничего важного, все работает
var docSub = {
stack: [
{
image: that.state.imgData,
width: 400,
height: 300,
margin: [47, 3, 0, 11]
},
{
stack: [
{ text: [
table
]
}
],
fontSize: 10
}
],
styles: {
header: {
fontSize: 15,
bold: true,
alignment: 'right',
margin: [10,10,10,10]
},
footer: {
fontSize: 10,
bold: true,
alignment: 'right',
margin: [10,10,10,10]
},
link: {
fontSize: 6,
bold: false,
alignment: 'left',
margin: [20,10,10,5]
},
subheader: {
fontSize: 9,
bold: false
}
}
};
that.setState({docSub: docSub}, that.props.setSudReportString(that.state.docSub));
}
render() {
var tabl = this.props.data;
var that = this;
return (
<div id='mychart'>
<h2>{this.state.chartName}</h2>
<div ref='modalchart'></div>
<Table responsive striped bordered condensed hover>
<thead>
<tr >
<th>#</th>
<th>Name</th>
<th>Quantity</th>
</tr>
</thead>
<tbody>
{
tabl.map( function(item,index)
{
return(
<tr>
<th>{1+index}</th>
<th>{item.name}</th>
<th>{item.number}</th>
<tr >
<th colSpan="3">
<Input key={index} type="textarea"
onChange={ (event)=> {
var comment = that.state.comments;
comment[index] = event.target.value;
that.setState({ comments: comment }, ()=>that.subComments());
}
}
/>
</th>
</tr>
</tr>
)
}
)
}
</tbody>
</Table>
</div>
);
}
}