图表适用于Chrome但不适用于Firefox

时间:2016-12-29 08:13:32

标签: angular d3.js typescript

我想在D3上使用这个graph。我遇到的问题是我必须将JS中的代码传递给Angular2-Typescript应用程序,示例代码在D3 v3中。我使用v4。

我的代码在Chromium(Linux Chrome)上运行良好,但在Firefox上它不显示波形动画(它显示为图像):

enter image description here

我创建了一个plunker,在Plunker中,它可以正常使用Firefox。

我的问题是为什么它适用于Chromium而不适用于Firefox?

项目是使用ng-cli创建的,D3 v4库由npm获取,在 angular-cli.json 中引用,如下例所示,并像这样导入import * as d3 from 'd3';

"scripts": [
        "../node_modules/jquery/dist/jquery.min.js",
        "../node_modules/bootstrap/dist/js/bootstrap.min.js",
        "../node_modules/d3/build/d3.min.js"
      ],

代码:

import { Component,  OnInit } from 'angular2/core';
import * as d3 from 'd3';

@Component({
  selector: 'my-app',
  template: `
    <svg id="chart" width="97%" height="250">
        </svg>
  `
})

export class Angular2TutorialComponent implements OnInit {
  config = {
    minValue: 0, // The gauge minimum value.
    maxValue: 100, // The gauge maximum value.
    circleThickness: 0.05, // The outer circle thickness as a percentage of it's radius.
    circleFillGap: 0.05, // The size of the gap between the outer circle and wave circle as a percentage of the outer circles radius.
    circleColor: "#178BCA", // The color of the outer circle.
    waveHeight: 0.05, // The wave height as a percentage of the radius of the wave circle.
    waveCount: 1, // The number of full waves per width of the wave circle.
    waveRiseTime: 1000, // The amount of time in milliseconds for the wave to rise from 0 to it's final height.
    waveAnimateTime: 18000, // The amount of time in milliseconds for a full wave to enter the wave circle.
    waveRise: true, // Control if the wave should rise from 0 to it's full height, or start at it's full height.
    waveHeightScaling: true, // Controls wave size scaling at low and high fill percentages. When true, wave height reaches it's maximum at 50% fill, and minimum at 0% and 100% fill. This helps to prevent the wave from making the wave circle from appear totally full or empty when near it's minimum or maximum fill.
    waveAnimate: true, // Controls if the wave scrolls or is static.
    waveColor: "#178BCA", // The color of the fill wave.
    waveOffset: 0, // The amount to initially offset the wave. 0 = no offset. 1 = offset of one full wave.
    textVertPosition: .5, // The height at which to display the percentage text withing the wave circle. 0 = bottom, 1 = top.
    textSize: 1, // The relative height of the text to display in the wave circle. 1 = 50%
    valueCountUp: true, // If true, the displayed value counts up from 0 to it's final value upon loading. If false, the final value is displayed.
    displayPercent: true, // If true, a % symbol is displayed after the value.
    textColor: "#045681", // The color of the value text when the wave does not overlap it.
    waveTextColor: "#A4DBf8" // The color of the value text when the wave overlaps it.
  };


  constructor() {}

  ngOnInit(): void {
    this.loadLiquidFillGauge('chart', 50, null);
  }

  loadLiquidFillGauge(elementId, value, config): void {
    if (config == null) config = this.config;

    let gauge = d3.select("#" + elementId);
    let radius = Math.min(parseInt(gauge.style("width")), parseInt(gauge.style("height"))) / 2;
    let locationX = parseInt(gauge.style("width")) / 2 - radius;
    let locationY = parseInt(gauge.style("height")) / 2 - radius;
    let fillPercent = Math.max(config.minValue, Math.min(config.maxValue, value)) / config.maxValue;

    let waveHeightScale;
    if (config.waveHeightScaling) {
      waveHeightScale = d3.scaleLinear()
        .range([0, config.waveHeight, 0])
        .domain([0, 50, 100]);
    } else {
      waveHeightScale = d3.scaleLinear()
        .range([config.waveHeight, config.waveHeight])
        .domain([0, 100]);
    }

    let textPixels = (config.textSize * radius / 2);
    let textFinalValue = parseFloat(value).toFixed(2);
    let textStartValue = config.valueCountUp ? config.minValue : textFinalValue;
    let percentText = config.displayPercent ? "%" : "";
    let circleThickness = config.circleThickness * radius;
    let circleFillGap = config.circleFillGap * radius;
    let fillCircleMargin = circleThickness + circleFillGap;
    let fillCircleRadius = radius - fillCircleMargin;
    let waveHeight = fillCircleRadius * waveHeightScale(fillPercent * 100);

    let waveLength = fillCircleRadius * 2 / config.waveCount;
    let waveClipCount = 1 + config.waveCount;
    let waveClipWidth = waveLength * waveClipCount;

    // Rounding functions so that the correct number of decimal places is always displayed as the value counts up.
    let textRounder: any = function(value) {
      return Math.round(value);
    };
    if (parseFloat(textFinalValue) != (textRounder(textFinalValue))) {
      textRounder = function(value) {
        return parseFloat(value).toFixed(1);
      };
    }
    if (parseFloat(textFinalValue) != (textRounder(textFinalValue))) {
      textRounder = function(value) {
        return parseFloat(value).toFixed(2);
      };
    }

    // Data for building the clip wave area.
    let data = [];
    for (let i = 0; i <= 40 * waveClipCount; i++) {
      data.push({
        x: i / (40 * waveClipCount),
        y: (i / (40))
      });
    }

    // Scales for drawing the outer circle.
    let gaugeCircleX = d3.scaleLinear().range([0, 2 * Math.PI]).domain([0, 1]);
    let gaugeCircleY = d3.scaleLinear().range([0, radius]).domain([0, radius]);

    // Scales for controlling the size of the clipping path.
    let waveScaleX = d3.scaleLinear().range([0, waveClipWidth]).domain([0, 1]);
    let waveScaleY = d3.scaleLinear().range([0, waveHeight]).domain([0, 1]);

    // Scales for controlling the position of the clipping path.
    let waveRiseScale = d3.scaleLinear()
      // The clipping area size is the height of the fill circle + the wave height, so we position the clip wave
      // such that the it will overlap the fill circle at all when at 0%, and will totally cover the fill
      // circle at 100%.
      .range([(fillCircleMargin + fillCircleRadius * 2 + waveHeight), (fillCircleMargin - waveHeight)])
      .domain([0, 1]);
    let waveAnimateScale = d3.scaleLinear()
      .range([0, waveClipWidth - fillCircleRadius * 2]) // Push the clip area one full wave then snap back.
      .domain([0, 1]);

    // Scale for controlling the position of the text within the gauge.
    let textRiseScaleY = d3.scaleLinear()
      .range([fillCircleMargin + fillCircleRadius * 2, (fillCircleMargin + textPixels * 0.7)])
      .domain([0, 1]);

    // Center the gauge within the parent SVG.
    let gaugeGroup = gauge.append("g")
      .attr('transform', 'translate(' + locationX + ',' + locationY + ')');

    // Draw the outer circle.
    let gaugeCircleArc = d3.arc()
      .startAngle(gaugeCircleX(0))
      .endAngle(gaugeCircleX(1))
      .outerRadius(gaugeCircleY(radius))
      .innerRadius(gaugeCircleY(radius - circleThickness));
    gaugeGroup.append("path")
      .attr("d", gaugeCircleArc)
      .style("fill", config.circleColor)
      .attr('transform', 'translate(' + radius + ',' + radius + ')');

    // Text where the wave does not overlap.
    let text1 = gaugeGroup.append("text")
      .text(textRounder(textStartValue) + percentText)
      .attr("class", "liquidFillGaugeText")
      .attr("text-anchor", "middle")
      .attr("font-size", textPixels + "px")
      .style("fill", config.textColor)
      .attr('transform', 'translate(' + radius + ',' + textRiseScaleY(config.textVertPosition) + ')');

    // The clipping wave area.
    let clipArea = d3.area()
      .x( < any > function(d) {
        return waveScaleX(d.x);
      })
      .y0( < any > function(d) {
        return waveScaleY(Math.sin(Math.PI * 2 * config.waveOffset * -1 + Math.PI * 2 * (1 - config.waveCount) + d.y * 2 * Math.PI));
      })
      .y1(function(d) {
        return (fillCircleRadius * 2 + waveHeight);
      });
    let waveGroup = gaugeGroup.append("defs")
      .append("clipPath")
      .attr("id", "clipWave" + elementId);
    let wave = waveGroup.append("path")
      .datum(data)
      .attr("d", clipArea)
      .attr("T", 0);

    // The inner circle with the clipping wave attached.
    let fillCircleGroup = gaugeGroup.append("g")
      .attr("clip-path", "url(#clipWave" + elementId + ")");
    fillCircleGroup.append("circle")
      .attr("cx", radius)
      .attr("cy", radius)
      .attr("r", fillCircleRadius)
      .style("fill", config.waveColor);

    // Text where the wave does overlap.
    let text2 = fillCircleGroup.append("text")
      .text(textRounder(textStartValue) + percentText)
      .attr("class", "liquidFillGaugeText")
      .attr("text-anchor", "middle")
      .attr("font-size", textPixels + "px")
      .style("fill", config.waveTextColor)
      .attr('transform', 'translate(' + radius + ',' + textRiseScaleY(config.textVertPosition) + ')');

    // Make the value count up.
    if (config.valueCountUp) {
      let textTween = function() {
        let i = d3.interpolate(this.textContent, textFinalValue);
        let temp = this;
        return function(t) {
          temp.textContent = textRounder(i(t)) + percentText;
        }
      };
      text1.transition()
        .duration(config.waveRiseTime)
        .tween("text", textTween);
      text2.transition()
        .duration(config.waveRiseTime)
        .tween("text", textTween);
    }

    // Make the wave rise. wave and waveGroup are separate so that horizontal and vertical movement can be controlled independently.
    let waveGroupXPosition = fillCircleMargin + fillCircleRadius * 2 - waveClipWidth;
    if (config.waveRise) {
      waveGroup.attr('transform', 'translate(' + waveGroupXPosition + ',' + waveRiseScale(0) + ')')
        .transition()
        .duration(config.waveRiseTime)
        .attr('transform', 'translate(' + waveGroupXPosition + ',' + waveRiseScale(fillPercent) + ')')
        .on("start", function() {
          wave.attr('transform', 'translate(1,0)');
        }); // This transform is necessary to get the clip wave positioned correctly when waveRise=true and waveAnimate=false. The wave will not position correctly without this, but it's not clear why this is actually necessary.
    } else {
      waveGroup.attr('transform', 'translate(' + waveGroupXPosition + ',' + waveRiseScale(fillPercent) + ')');
    }

    if (config.waveAnimate) animateWave();

    function animateWave() {
      wave.attr('transform', 'translate(' + waveAnimateScale(+wave.attr('T')) + ',0)');
      wave.transition()
        .duration(config.waveAnimateTime * (1 - +wave.attr('T')))
        .ease(d3.easeLinear)
        .attr('transform', 'translate(' + waveAnimateScale(1) + ',0)')
        .attr('T', 1)
        .on('end', function() {
          wave.attr('T', 0);
          animateWave();
        });
    }
  }
}

1 个答案:

答案 0 :(得分:0)

this works fine :

add d3v4 script cdn like this in index.html:-
--------------------------------------------
      index.html
        -------------
            <script src="https://d3js.org/d3.v4.min.js"></script>



    beaker-chart.component.html
        -------------------------------
        <svg id="fillgauge1" width="97%" height="250"></svg>

        beaker-chart.component.ts
        ------------------------------
        import { AfterViewInit, Component, OnInit, Input, Renderer,ViewChildren, ElementRef, ViewEncapsulation, HostListener, EventEmitter, Injector, Output } from '@angular/core';

        declare var d3:any;




        @Component({
          selector: 'app-beaker-chart',
          templateUrl: './beaker-chart.component.html',
          styleUrls: ['./beaker-chart.component.css'],
            encapsulation: ViewEncapsulation.None
        })

        export class BeakerChartComponent implements OnInit {
            gauge1: any;
            config0: any;
            jsonData: any;
            errorMessage: any;
            elemetsRef: any;
          loadLiquidFillGauge: any;

          liquidFillGaugeDefaultSettings: any;


            constructor(public renderer: Renderer, public elementRef: ElementRef,public injector: Injector,public jsonDataService: JsonDataService) { 
                this.elemetsRef = ElementRef;

          }

         ngOnInit() {
                this.beakerChart();
          }


        beakerChart(){
       (function(d3) {
    var idGenerator = (function() {
        var count = 0;
        return function(prefix) {
            return prefix + "-" + count++;
        };
    })();

    var defaultConfig = {
        // Values
        minValue: 0, // The gauge minimum value.
        maxValue: 100, // The gauge maximum value.

        // Styles
        circleThickness: 0.05, // The outer circle thickness as a percentage of it's radius.
        circleFillGap: 0.05, // The size of the gap between the outer circle and wave circle as a percentage of the outer circles radius.
        circleColor: "#178BCA", // The color of the outer circle.
        backgroundColor: null, // The color of the background
        waveColor: "#178BCA", // The color of the fill wave.
        width: 0, // You might want to set the width and height if it is not detected properly by the plugin
        height: 0,

        // Gradient
        fillWithGradient: false, // Controls if the wave should be filled with gradient
        gradientPoints: [0, 0, 1., 1.], //  [x1, y1, x2, y2], coordinates for gradient start point(x1,y1) and final point(x2,y2)
        gradientFromColor: "#FFF",
        gradientToColor: "#000",

        // Waves
        waveHeight: 0.05, // The wave height as a percentage of the radius of the wave circle.
        waveCount: 1, // The number of full waves per width of the wave circle.
        waveOffset: 0, // The amount to initially offset the wave. 0 = no offset. 1 = offset of one full wave.

        // Animations
        waveRise: true, // Control if the wave should rise from 0 to it's full height, or start at it's full height.
        waveRiseTime: 1000, // The amount of time in milliseconds for the wave to rise from 0 to it's final height.
        waveRiseAtStart: true, // If set to false and waveRise at true, will disable only the initial animation
        waveAnimate: true, // Controls if the wave scrolls or is static.
        waveAnimateTime: 18000, // The amount of time in milliseconds for a full wave to enter the wave circle.
        waveHeightScaling: true, // Controls wave size scaling at low and high fill percentages. When true, wave height reaches it's maximum at 50% fill, and minimum at 0% and 100% fill. This helps to prevent the wave from making the wave circle from appear totally full or empty when near it's minimum or maximum fill.
        valueCountUp: true, // If true, the displayed value counts up from 0 to it's final value upon loading and updating. If false, the final value is displayed.
        valueCountUpAtStart: true, // If set to false and valueCountUp at true, will disable only the initial animation

        // Text
        textVertPosition: 0.5, // The height at which to display the percentage text withing the wave circle. 0 = bottom, 1 = top.
        textSize: 1, // The relative height of the text to display in the wave circle. 1 = 50%
        displayPercent: true, // If true, a % symbol is displayed after the value.
        textColor: "#045681", // The color of the value text when the wave does not overlap it.
        waveTextColor: "#A4DBf8", // The color of the value text when the wave overlaps it.
    };

    d3.liquidfillgauge = function(g, value, settings) {
        // Handle configuration
        var config = d3.map(defaultConfig);
        d3.map(settings).each(function(val, key) {
            config.set(key, val);
        });

        g.each(function(d) {
            var gauge = d3.select(this);

            var width = config.get("width") !== 0 ? config.get("width") : parseInt(gauge.style("width"));
            var height = config.get("height") !== 0 ? config.get("height") : parseInt(gauge.style("height"));
            var radius = Math.min(width, height) / 2;
            var locationX = width / 2 - radius;
            var locationY = height / 2 - radius;
            var fillPercent = Math.max(config.get("minValue"), Math.min(config.get("maxValue"), value)) / config.get("maxValue");

            var waveHeightScale;
            if (config.get("waveHeightScaling")) {
              waveHeightScale = d3.scaleLinear()
                  .range([0, config.get("waveHeight"), 0])
                  .domain([0, 50, 100]);
            } else {
                waveHeightScale = d3.scaleLinear()
                  .range([config.get("waveHeight"), config.get("waveHeight")])
                  .domain([0, 100]);
            }

            var textPixels = (config.get("textSize") * radius / 2);
            var textFinalValue = parseFloat(value).toFixed(2);
            var textStartValue = config.get("valueCountUp") ? config.get("minValue") : textFinalValue;
            var percentText = config.get("displayPercent") ? "%" : "";
            var circleThickness = config.get("circleThickness") * radius;
            var circleFillGap = config.get("circleFillGap") * radius;
            var fillCircleMargin = circleThickness + circleFillGap;
            var fillCircleRadius = radius - fillCircleMargin;
            var waveHeight = fillCircleRadius * waveHeightScale(fillPercent * 100);

            var waveLength = fillCircleRadius * 2 / config.get("waveCount");
            var waveClipCount = 1 + config.get("waveCount");
            var waveClipWidth = waveLength * waveClipCount;

            // Rounding functions so that the correct number of decimal places is always displayed as the value counts up.
            var textRounder = function(value) {
                return Math.round(value);
            };
            if (parseFloat(textFinalValue) != parseFloat(textRounder(textFinalValue))) {
                textRounder = function(value) {
                    return parseFloat(value).toFixed(1);
                };
            }
            if (parseFloat(textFinalValue) != parseFloat(textRounder(textFinalValue))) {
                textRounder = function(value) {
                    return parseFloat(value).toFixed(2);
                };
            }

            // Data for building the clip wave area.
            var data = [];
            for (var i = 0; i <= 40 * waveClipCount; i++) {
                data.push({
                    x: i / (40 * waveClipCount),
                    y: (i / (40))
                });
            }

            // Scales for drawing the outer circle.
            var gaugeCircleX = d3.scaleLinear().range([0, 2 * Math.PI]).domain([0, 1]);
            var gaugeCircleY = d3.scaleLinear().range([0, radius]).domain([0, radius]);

            // Scales for controlling the size of the clipping path.
            var waveScaleX = d3.scaleLinear().range([0, waveClipWidth]).domain([0, 1]);
            var waveScaleY = d3.scaleLinear().range([0, waveHeight]).domain([0, 1]);

            // Scales for controlling the position of the clipping path.
            var waveRiseScale = d3.scaleLinear()
            // The clipping area size is the height of the fill circle + the wave height, so we position the clip wave
            // such that the it will won't overlap the fill circle at all when at 0%, and will totally cover the fill
            // circle at 100%.
              .range([(fillCircleMargin + fillCircleRadius * 2 + waveHeight), (fillCircleMargin - waveHeight)])
              .domain([0, 1]);
            var waveAnimateScale = d3.scaleLinear()
              .range([0, waveClipWidth - fillCircleRadius * 2]) // Push the clip area one full wave then snap back.
              .domain([0, 1]);

            // Scale for controlling the position of the text within the gauge.
            var textRiseScaleY = d3.scaleLinear()
              .range([fillCircleMargin + fillCircleRadius * 2, (fillCircleMargin + textPixels * 0.7)])
              .domain([0, 1]);

            // Center the gauge within the parent
            var gaugeGroup = gauge.append("g")
              .attr('transform', 'translate(' + locationX + ',' + locationY + ')');

            // Draw the background circle
            if (config.get("backgroundColor")) {
                gaugeGroup.append("circle")
                  .attr("r", radius)
                  .style("fill", config.get("backgroundColor"))
                  .attr('transform', 'translate(' + radius + ',' + radius + ')');
            }

            // Draw the outer circle.
            var gaugeCircleArc = d3.arc()
              .startAngle(gaugeCircleX(0))
              .endAngle(gaugeCircleX(1))
              .outerRadius(gaugeCircleY(radius))
              .innerRadius(gaugeCircleY(radius - circleThickness));
            gaugeGroup.append("path")
              .attr("d", gaugeCircleArc)
              .style("fill", config.get("circleColor"))
              .attr('transform', 'translate(' + radius + ',' + radius + ')');

            // Text where the wave does not overlap.
            var text1 = gaugeGroup.append("text")
              .attr("class", "liquidFillGaugeText")
              .attr("text-anchor", "middle")
              .attr("font-size", textPixels + "px")
              .style("fill", config.get("textColor"))
              .attr('transform', 'translate(' + radius + ',' + textRiseScaleY(config.get("textVertPosition")) + ')');

            // The clipping wave area.
            var clipArea = d3.area()
              .x(function(d) {
                  return waveScaleX(d.x);
              })
              .y0(function(d) {
                  return waveScaleY(Math.sin(Math.PI * 2 * config.get("waveOffset") * -1 + Math.PI * 2 * (1 - config.get("waveCount")) + d.y * 2 * Math.PI));
              })
              .y1(function(d) {
                  return (fillCircleRadius * 2 + waveHeight);
              });

            var gaugeGroupDefs = gaugeGroup.append("defs");

            var clipId = idGenerator("clipWave");
            var waveGroup = gaugeGroupDefs
              .append("clipPath")
              .attr("id", clipId);
            var wave = waveGroup.append("path")
              .datum(data)
              .attr("d", clipArea);

            // The inner circle with the clipping wave attached.
            var fillCircleGroup = gaugeGroup.append("g")
              .attr("clip-path", "url(#" + clipId + ")");
            fillCircleGroup.append("circle")
              .attr("cx", radius)
              .attr("cy", radius)
              .attr("r", fillCircleRadius);

            if (config.get("fillWithGradient")) {
                var points = config.get("gradientPoints");
                var gradientId = idGenerator("linearGradient");
                var grad = gaugeGroupDefs.append("linearGradient")
                  .attr("id", gradientId)
                  .attr("x1", points[0])
                  .attr("y1", points[1])
                  .attr("x2", points[2])
                  .attr("y2", points[3]);
                grad.append("stop")
                  .attr("offset", "0")
                  .attr("stop-color", config.get("gradientFromColor"));
                grad.append("stop")
                  .attr("offset", "1")
                  .attr("stop-color", config.get("gradientToColor"));

                fillCircleGroup.style("fill", "url(#" + gradientId + ")");
            } else {
                fillCircleGroup.style("fill", config.get("waveColor"));
            }

            // Text where the wave does overlap.
            var text2 = fillCircleGroup.append("text")
              .attr("class", "liquidFillGaugeText")
              .attr("text-anchor", "middle")
              .attr("font-size", textPixels + "px")
              .style("fill", config.get("waveTextColor"))
              .attr('transform', 'translate(' + radius + ',' + textRiseScaleY(config.get("textVertPosition")) + ')');

            // Make the wave rise. wave and waveGroup are separate so that horizontal and vertical movement can be controlled independently.
            var waveGroupXPosition = fillCircleMargin + fillCircleRadius * 2 - waveClipWidth;

            if (config.get("waveAnimate")) {
                var animateWave = function() {
                    wave.transition()
                      .duration(config.get("waveAnimateTime"))
                      .ease(d3.easeLinear)
                      .attr('transform', 'translate(' + waveAnimateScale(1) + ',0)')
                      .on("end", function() {
                          wave.attr('transform', 'translate(' + waveAnimateScale(0) + ',0)');
                          animateWave();
                      });
                };
                animateWave();
            }

            var transition = function(from, to, riseWave, animateText) {
                // Update texts and animate
                if (animateText) {
                    var textTween = function() {
                        var that = d3.select(this);
                        var i = d3.interpolate(from, to);
                        return function(t) {
                            that.text(textRounder(i(t)) + percentText);
                        };
                    };
                    text1.transition()
                      .duration(config.get("waveRiseTime"))
                      .tween("text", textTween);
                    text2.transition()
                      .duration(config.get("waveRiseTime"))
                      .tween("text", textTween);
                } else {
                    text1.text(textRounder(to) + percentText);
                    text2.text(textRounder(to) + percentText);
                }

                // Update the wave
                toPercent = Math.max(config.get("minValue"), Math.min(config.get("maxValue"), to)) / config.get("maxValue");
                fromPercent = Math.max(config.get("minValue"), Math.min(config.get("maxValue"), from)) / config.get("maxValue");

                if (riseWave) {
                    waveGroup.attr('transform', 'translate(' + waveGroupXPosition + ',' + waveRiseScale(fromPercent) + ')')
                      .transition()
                      .duration(config.get("waveRiseTime"))
                      .attr('transform', 'translate(' + waveGroupXPosition + ',' + waveRiseScale(toPercent) + ')');
                } else {
                    waveGroup.attr('transform', 'translate(' + waveGroupXPosition + ',' + waveRiseScale(toPercent) + ')');
                }
            };

            transition(
              textStartValue,
              textFinalValue,
              config.get("waveRise") && config.get("waveRiseAtStart"),
              config.get("valueCountUp") && config.get("valueCountUpAtStart")
            );

            // Event to update the value
            gauge.on("valueChanged", function(newValue) {
                transition(value, newValue, config.get("waveRise"), config.get("valueCountUp"));
                value = newValue;
            });

            gauge.on("destroy", function() {
                // Stop all the transitions
                text1.interrupt().transition();
                text2.interrupt().transition();
                waveGroup.interrupt().transition();
                wave.interrupt().transition();

                // Unattach events
                gauge.on("valueChanged", null);
                gauge.on("destroy", null);
            });
        });
    };
})(d3);

             d3.select("#fillgauge1").call(d3.liquidfillgauge, 55);
                setInterval(function() {
              d3.select("#fillgauge1").on("valueChanged")(Math.floor(Math.random() * 100));
            }, 2000);

        }
        }