D3.js 我如何将过渡和持续时间应用于;rect";在svg代码中?

D3.js 我如何将过渡和持续时间应用于;rect";在svg代码中?,d3.js,D3.js,嗨,我有一个代码片段,我想做动画。它是用d3v5编写的 const svg = d3.select("div#histogramHolder").append("svg") .attr("width", width + margin.left + margin.right) .attr("height", height + margin.top + margin.bottom); const g = svg.append("g"); g.att

嗨,我有一个代码片段,我想做动画。它是用d3v5编写的

const svg = d3.select("div#histogramHolder").append("svg")
            .attr("width", width + margin.left + margin.right)
            .attr("height", height + margin.top + margin.bottom);

const g = svg.append("g");

g.attr("transform", "translate(" + margin.left + "," + margin.top + ")");

g.append("g")
.selectAll("g")
.data(d3.stack().keys(keys)(data))
.enter().append("g")
.attr("class", function(d) { 
  return z(d.key);
 }) 
.selectAll("rect") .
    .data(function(d) { return d; })
    .enter().append("rect")
    .attr("x", function(d) { 
      return x(d.data.dateRange); }
      )
    .attr("y", function(d) { 
      return y(d[1]); }
      )
    .attr("height", function(d) { return y(d[0]) - y(d[1]); })
    .attr("width", x.bandwidth())
    .attr('y', (d: any) => {
      return y(d[1])
    })
    .on("mouseover", function(d) {  
      const hist:HistogramDistribution = this.__data__.data
      const xPosition = d3.mouse(this)[0] -5;
      const yPosition = d3.mouse(this)[1] -5;
如何将动画应用于.selectAll(“rect”)元素? 我试图追加
selectAll(“rect”).transition().duration(1000)
,但它给出了以下错误

core.js:1440 ERROR TypeError: g.append(...).selectAll(...).data(...).enter(...).append(...).attr(...).selectAll(...).transition(...).duration(...).data is not a function
    at PerformanceComponent.drawSvg (performance.component.ts:395)
    at SafeSubscriber.eval [as _next] (performance.component.ts:235)
    at SafeSubscriber.__tryOrUnsub (Subscriber.js:240)
    at SafeSubscriber.next (Subscriber.js:187)
    at Subscriber._next (Subscriber.js:128)
    at Subscriber.next (Subscriber.js:92)
    at ReplaySubject.Subject.next (Subject.js:56)
    at ReplaySubject.next (ReplaySubject.js:37)
    at Object.next (shareReplay.js:22)
    at SafeSubscriber.__tryOrUnsub (Subscriber.js:240)
这是我的方法

drawSvg( data:HistogramDistribution[]) {

// data = [ { "dateRange" : "2019-12-12" ,total: 450, delivered : 200, failed:150, processing:100}];

d3.selectAll('div#histogramHolder svg').remove();

// set the dimensions and margins of the graph
const margin = {top: 10, right: 20, bottom: 60, left: 60},
width = 900 - margin.left - margin.right,
height = 250 - margin.top - margin.bottom;

const svg = d3.select("div#histogramHolder").append("svg")
            .attr("width", width + margin.left + margin.right)
            .attr("height", height + margin.top + margin.bottom);

const g = svg.append("g");
g.attr("transform", "translate(" + margin.left + "," + margin.top + ")");

// set x scale
const x = d3.scaleBand().rangeRound([0, width]).paddingInner(0.1).paddingOuter(0.5).align(0.1);

// set y scale
const y = d3.scaleLinear().rangeRound([height, 0]);

// set the colors
const z = d3.scaleOrdinal().range([ "msgdelivered" ,  "msgprocessing","msgfailed" ]);
const keys = [ "delivered", "processing","failed" ];

x.domain(data.map(function(d) { return d.dateRange; }));
y.domain([0, d3.max(data, function(d) { return d.total; })]).nice();
z.domain(keys);


// Define the div for the tooltip
let div = d3.select("body").append("div")   
    .attr("class", "tooltip")               
    .style("opacity", 0);


g.append("g")
.selectAll("g")
.data(d3.stack().keys(keys)(data))
.enter().append("g")
.attr("class", function(d) { 
  return z(d.key);
 })
.selectAll("rect")
    .data(function(d) { return d; })
    .enter().append("rect")
    .attr("x", function(d) { 
      return x(d.data.dateRange); }
      )
    .attr("y", function(d) { 
      return y(d[1]); }
      )
    .attr("height", function(d) { return y(d[0]) - y(d[1]); })
    .attr("width", x.bandwidth())
    .attr('y', (d: any) => {
      return y(d[1])
    })
    .on("mouseover", function(d) {  
      const hist:HistogramDistribution = this.__data__.data
      const xPosition = d3.mouse(this)[0] -5;
      const yPosition = d3.mouse(this)[1] -5;

      div.transition()      
          .duration(10)     
          .style("opacity", .9);        
          div.html( "<span>"+ "Date : "  + hist.dateRange +"</span><br>" +
          "<span>"+ "Delivered : "  + hist.delivered +"</span><br>" + 
          "<span>"+ "Processing : "  + hist.processing +"</span><br>" + 
          "<span>"+ "Failed : "  + hist.failed +"</span><br>" + 
          "<span>"+ "Total : "  + hist.total +"</span>"
          ) 
          .style("left", (d3.event.pageX) - 45 + "px")      
          .style("top", (d3.event.pageY - 80) + "px");  
      }
    )
    .on("mouseout", function(d) {       
      div.transition()      
          .durdrawSvg( data:HistogramDistribution[]) {

            // data = [ { "dateRange" : "2019-12-12" ,total: 450, delivered : 200, failed:150, processing:100}];

            d3.selectAll('div#histogramHolder svg').remove();

            // set the dimensions and margins of the graph
            const margin = {top: 10, right: 20, bottom: 60, left: 60},
            width = 900 - margin.left - margin.right,
            height = 250 - margin.top - margin.bottom;

            const svg = d3.select("div#histogramHolder").append("svg")
                        .attr("width", width + margin.left + margin.right)
                        .attr("height", height + margin.top + margin.bottom);

            const g = svg.append("g");
            g.attr("transform", "translate(" + margin.left + "," + margin.top + ")");

            // set x scale
            const x = d3.scaleBand().rangeRound([0, width]).paddingInner(0.1).paddingOuter(0.5).align(0.1);

            // set y scale
            const y = d3.scaleLinear().rangeRound([height, 0]);

            // set the colors
            const z = d3.scaleOrdinal().range([ "msgdelivered" ,  "msgprocessing","msgfailed" ]);
            const keys = [ "delivered", "processing","failed" ];

            x.domain(data.map(function(d) { return d.dateRange; }));
            y.domain([0, d3.max(data, function(d) { return d.total; })]).nice();
            z.domain(keys);


            // Define the div for the tooltip
            let div = d3.select("body").append("div")   
                .attr("class", "tooltip")               
                .style("opacity", 0);


            g.append("g")
            .selectAll("g")
            .data(d3.stack().keys(keys)(data))
            .enter().append("g")
            .attr("class", function(d) { 
              return z(d.key);
             })
            .selectAll("rect")
                .data(function(d) { return d; })
                .enter().append("rect")
                .attr("x", function(d) { 
                  return x(d.data.dateRange); }
                  )
                .attr("y", function(d) { 
                  return y(d[1]); }
                  )
                .attr("height", function(d) { return y(d[0]) - y(d[1]); })
                .attr("width", x.bandwidth())
                .attr('y', (d: any) => {
                  return y(d[1])
                })
                .on("mouseover", function(d) {  
                  const hist:HistogramDistribution = this.__data__.data
                  const xPosition = d3.mouse(this)[0] -5;
                  const yPosition = d3.mouse(this)[1] -5;

                  div.transition()      
                      .duration(500)        
          .style("opacity", 0); 
    })
    .on("mousemove", function(d) {

     const hist:HistogramDistribution = this.__data__.data
     const xPosition = d3.mouse(this)[0] -5;
     const yPosition = d3.mouse(this)[1] -5;

     div.transition()       
          .duration(10)     
          .style("opacity", .9);        
          div.html( "<span>"+ "Date : "  + hist.dateRange +"</span><br>" +
          "<span>"+ "Delivered : "  + hist.delivered +"</span><br>" + 
          "<span>"+ "Processing : "  + hist.processing +"</span><br>" + 
          "<span>"+ "Failed : "  + hist.failed +"</span><br>" + 
          "<span>"+ "Total : "  + hist.total +"</span>"
          ) 
          .style("left", (d3.event.pageX) - 45 + "px")      
          .style("top", (d3.event.pageY - 80) + "px");  
      }

    );

g.append("g")
    .attr("class", "axis")
    .attr("transform", "translate(0," + height + ")")
    .transition()
    .duration(1000)
    .call(d3.axisBottom(x))
    .selectAll("text")  
      .style("text-anchor", "middle")
      .attr("dx", "3em")
      .attr("dy", "1em")
      .attr("transform", "rotate(30)");


g.append("g")
  .attr("class", "axis")
  .call(d3.axisLeft(y).ticks())
  .append("text")
  .attr("x", 2)
  .attr("y", y(y.ticks().pop()) + 0.5)
  .attr("dy", "0.32em")
  .attr("fill", "#000")
  .attr("font-weight", "bold")
  .attr("text-anchor", "start");

const legend = g.append("g")
  .attr("font-family", "sans-serif")
  .attr("font-size", 10)
  .attr("text-anchor", "end")
  .selectAll("g")
  .data(keys.slice())
  .enter().append("g")
  .attr("transform", function(d, i) { return "translate(0," + i * 20 + ")"; });

legend.append("rect")
  .attr("x", width - 19)
  .attr("width", 19)
  .attr("height", 19)
  .attr("class", function(d) { 
    return z(d);
  });

legend.append("text")
  .attr("x", width - 24)
  .attr("y", 9.5)
  .attr("dy", "0.32em")
  .text(function(d) { 
   return d.charAt(0).toUpperCase() + d.slice(1) ; });

  // text label for the x axis
  // svg.append("text")             
  //     .attr("transform",
  //           "translate(" + (width/2) + " ," + 
  //                          (height + margin.top + 20) + ")")
  //     .style("text-anchor", "middle")
  //     .text("Date");

    // text label for the y axis
    g.append("text")
        .attr("transform", "rotate(-90)")
        .attr("y", 0 - margin.left)
        .attr("x",0 - (height / 2))
        .attr("dy", "1em")
        .style("text-anchor", "middle")
        .text("Count");

}
drawSvg(数据:historogramdistribution[]{
//数据=[{“日期范围”:“2019-12-12”,总计:450,交付:200,失败:150,处理:100}];
d3.选择All('div#historogramholder svg')。删除();
//设置图形的尺寸和边距
常量边距={top:10,right:20,bottom:60,left:60},
宽度=900-边距。左侧-边距。右侧,
高度=250-margin.top-margin.bottom;
const svg=d3.select(“div#historogramholder”).append(“svg”)
.attr(“宽度”,宽度+边距。左侧+边距。右侧)
.attr(“高度”,高度+边距。顶部+边距。底部);
常量g=svg.append(“g”);
g、 属性(“变换”、“平移”(+margin.left+)、“+margin.top+”);
//设置x刻度
常量x=d3.scaleBand().rangeRound([0,宽度]).PaddingIner(0.1).paddingOuter(0.5).align(0.1);
//设置y刻度
常数y=d3.scaleLinear().rangeRound([height,0]);
//设置颜色
常量z=d3.scaleOrdinal().range([“msgdelivered”、“msgprocessing”、“msgfailed”]);
常量键=[“已传递”、“正在处理”、“失败”];
x、 域(data.map(函数(d){returnd.dateRange;}));
y、 域([0,d3.max(数据,函数(d){return d.total;})]).nice();
z、 域(密钥);
//定义工具提示的div
让div=d3。选择(“body”)。追加(“div”)
.attr(“类”、“工具提示”)
.样式(“不透明度”,0);
g、 附加(“g”)
.全选(“g”)
.data(d3.stack().key(key)(数据))
.enter().append(“g”)
.attr(“类”,函数(d){
返回z(d键);
})
.selectAll(“rect”)
.data(函数(d){return d;})
.enter().append(“rect”)
.attr(“x”,函数(d){
返回x(d.data.dateRange);}
)
.attr(“y”,函数(d){
返回y(d[1]);}
)
.attr(“height”,函数(d){返回y(d[0])-y(d[1]);})
.attr(“宽度”,x.带宽())
.attr('y',(d:any)=>{
返回y(d[1])
})
.on(“鼠标悬停”,函数(d){
常量hist:historogramdistribution=this.\u数据\u.data
const xPosition=d3.鼠标(this)[0]-5;
const yPosition=d3.鼠标(this)[1]-5;
过渡部()
.期限(10)
.样式(“不透明度”,.9);
div.html(“+”日期:“+hist.dateRange+”
”+ “+”已送达:“+hist.Delivered+”
“+ “+”处理:“+hist.Processing+”
“+ “+”失败:“+hist.Failed+”
“+ “+”总计“+hist.Total+” ) .style(“左”(d3.event.pageX)-45+“px”) .style(“top”,(d3.event.pageY-80)+“px”); } ) .on(“mouseout”),函数(d){ 过渡部() .durdrawSvg(数据:HistorogramDistribution[]{ //数据=[{“日期范围”:“2019-12-12”,总计:450,交付:200,失败:150,处理:100}]; d3.选择All('div#historogramholder svg')。删除(); //设置图形的尺寸和边距 常量边距={top:10,right:20,bottom:60,left:60}, 宽度=900-边距。左侧-边距。右侧, 高度=250-margin.top-margin.bottom; const svg=d3.select(“div#historogramholder”).append(“svg”) .attr(“宽度”,宽度+边距。左侧+边距。右侧) .attr(“高度”,高度+边距。顶部+边距。底部); 常量g=svg.append(“g”); g、 属性(“变换”、“平移”(+margin.left+)、“+margin.top+”); //设置x刻度 常量x=d3.scaleBand().rangeRound([0,宽度]).PaddingIner(0.1).paddingOuter(0.5).align(0.1); //设置y刻度 常数y=d3.scaleLinear().rangeRound([height,0]); //设置颜色 常量z=d3.scaleOrdinal().range([“msgdelivered”、“msgprocessing”、“msgfailed”]); 常量键=[“已传递”、“正在处理”、“失败”]; x、 域(data.map(函数(d){returnd.dateRange;})); y、 域([0,d3.max(数据,函数(d){return d.total;})]).nice(); z、 域(密钥); //定义工具提示的div 让div=d3。选择(“body”)。追加(“div”) .attr(“类”、“工具提示”) .样式(“不透明度”,0); g、 附加(“g”) .全选(“g”) .data(d3.stack().key(key)(数据)) .enter().append(“g”) .attr(“类”,函数(d){ 返回z(d键); }) .selectAll(“rect”) .data(函数(d){return d;}) .enter().append(“rect”) .attr(“x”,函数(d){ 返回x(d.data.dateRange);} ) .attr(“y”,函数(d){ 返回y(d[1]);} ) .attr(“height”,函数(d){返回y(d[0])-y(d[1]);}) .attr(“宽度”,x.带宽()) .attr('y',(d:any)=>{ 返回y(d[1]) }) .on(“鼠标悬停”,函数(d){ 常量hist:historogramdistribution=this.\u数据\u.data const xPosition=d3.鼠标(this)[0]-5; const yPosition=d3.鼠标(this)[1]-5; 过渡部() .持续时间(500) .样式(“不透明度”,0); }) .on(“mousemove”,函数(d){ 常量hist:historogramdistribution=this.\u数据\u.data const xPosition=d3.鼠标(this)[0]-5; const yPosition=d3.鼠标(this)[1]-5; 过渡部() .期限(10) .样式(“不透明度”,.9);