如何在d3js svg图像的堆叠条形图中将动画添加到y轴和条形图?

时间:2020-03-02 12:23:49

标签: d3.js

您好,我现在正在显示堆积的条形图。我正在尝试添加动画,这给了一些问题。

这是绘制堆积条形图的代码

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()      
          .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");  
      }

    );

但是,当我向条形图添加动画时,它不显示x和y轴

这就是我尝试添加动画和过渡的内容

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")
    .transition()
    .duration(1000)
    .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()      
          .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");  
      }

    );

此外,当我尝试向y轴添加动画时,控制台中也会出现一些错误

这是我尝试过的

g.append("g")
  .attr("class", "axis")
  .transition()
  .duration(1000)
  .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");

它给我错误

webpack-internal:///../../../core/esm5/core.js:1655 ERROR TypeError: g.append(...).attr(...).transition(...).duration(...).call(...).append is not a function
    at PerformanceComponent.drawSvg (webpack-internal:///../../../../../src/app/reporting/performance/performance.component.ts:305)
    at SafeSubscriber.eval [as _next] (webpack-internal:///../../../../../src/app/reporting/performance/performance.component.ts:131)
    at SafeSubscriber.__tryOrUnsub (webpack-internal:///../../../../rxjs/_esm5/Subscriber.js:245)
    at SafeSubscriber.next (webpack-internal:///../../../../rxjs/_esm5/Subscriber.js:192)
    at Subscriber._next (webpack-internal:///../../../../rxjs/_esm5/Subscriber.js:133)
    at Subscriber.next (webpack-internal:///../../../../rxjs/_esm5/Subscriber.js:97)
    at ReplaySubject.Subject.next (webpack-internal:///../../../../rxjs/_esm5/Subject.js:66)
    at ReplaySubject.next (webpack-internal:///../../../../rxjs/_esm5/ReplaySubject.js:45)
    at Object.next (webpack-internal:///../../../../rxjs/_esm5/operators/shareReplay.js:24)

以下是绘制堆叠条形图的完整源代码。 x轴上的动画有效,但是条形图和y轴上的动画无效。谢谢,如果您可以给它照亮。

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 = 800 - margin.left - margin.right,
height = 400 - 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()      
          .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) ; });
}

顺便说一句,我正在使用d3js v5 非常感谢任何帮助 谢谢

0 个答案:

没有答案