'use strict';
define(function() {
  var element = function(
    ConfigFactory,
    gcPopup,
    $http,
    $translate,
    chartFactory,
    $filter,
    gaBrowserSniffer,
    ngTableParams,
    $timeout
  ) {
    return {
      templateUrl: 'js/XG/widgets/utilities/chart/views/chartViewerHpo.html',
      restrict: 'A',
      scope: {
        fti: '=fti',
        where: '=where',
        features: '=features',
        fromSelected: '=selected',
        chartOpt: '=?options',
        chartdata: '=?data',
        configChart: '=?config',
        attrChoices: '=?attrchoice',
        ctrlType: '=?ctrltype',
        runcalc: '=?',
        hideExport: '=?',
        authorisedAttributes: '=?',
      },

      controller: [
        '$scope',
        '$element',
        '$attrs',
        function($scope, $element, $attrs) {},
      ],

      link: function(scope, element, attrs, ctrl) {
        scope.graphid = 'gcsvg' + Math.floor(Math.random() * 10000000000);

        var getdata = false;
        if (scope.chartOpt) getdata = true;

        scope.chartOpt = scope.chartOpt || {
          chart: {
            type: 'discreteBarChart',
            //width: Math.round(window.outerWidth * 0.5),
            height: 400,
            margin: {
              top: 20,
              right: 20,
              bottom: 50,
              left: 20,
            },
            x: function(d) {
              return d.label;
            },
            y: function(d) {
              return d.value;
            },
            showValues: true,
            valueFormat: function(d) {
              return d3.format(',.4f')(d);
            },
            duration: 500,
            xAxis: {
              //axisLabel: 'X Axis'
            },
            yAxis: {
              //axisLabel: 'Y Axis',
              axisLabelDistance: -10,
            },
          },
          title: {
            enable: true,
            text: '',
            className: 'h4',
            css: {
              width: 'auto',
              textAlign: 'center',
              'padding-top': '10px',
            },
          },
        };

        scope.chartdata = scope.chartdata || [
          {
            key: 'Cumulative Return',
            values: [
              {
                label: 'A',
                value: -29.765957771107,
              },
              {
                label: 'B',
                value: 0,
              },
              {
                label: 'C',
                value: 32.807804682612,
              },
              {
                label: 'D',
                value: 196.45946739256,
              },
              {
                label: 'E',
                value: 0.19434030906893,
              },
              {
                label: 'F',
                value: -98.079782601442,
              },
              {
                label: 'G',
                value: -13.925743130903,
              },
              {
                label: 'H',
                value: -5.1387322875705,
              },
            ],
          },
        ];

        scope.showTable = false;
        scope.chartOpt.affichage = angular.isDefined(scope.chartOpt.affichage)
          ? scope.chartOpt.affichage
          : 'graph';
        scope.chartOpt.showColonneNumber = angular.isDefined(
          scope.chartOpt.showColonneNumber
        )
          ? scope.chartOpt.showColonneNumber
          : true;
        scope.chartOpt.showColonnePercentage = angular.isDefined(
          scope.chartOpt.showColonnePercentage
        )
          ? scope.chartOpt.showColonnePercentage
          : true;

        scope.tableParamsResults = new ngTableParams(
          {
            page: 1, // show first page
            count: 10, // count per page
          },
          {
            total: 0, // length of data
            getData: function($defer, params) {
              try {
                switch (scope.configChart.choice.type) {
                  case 'pieChart':
                  case 'multiBarChart':
                    var displayedTab = scope.chartdata.slice(
                      (params.page() - 1) * params.count(),
                      params.page() * params.count()
                    );
                    params.total(scope.chartdata.length); // set total for recalc pagination
                    $defer.resolve(displayedTab);
                    break;
                  case 'discreteBarChart':
                    displayedTab = scope.chartdata[0].values.slice(
                      (params.page() - 1) * params.count(),
                      params.page() * params.count()
                    );
                    params.total(scope.chartdata[0].values.length); // set total for recalc pagination
                    $defer.resolve(displayedTab);
                    break;
                }
              } catch (e) {
                e.stack;
              }
            },
          }
        );

        /**
         * exportCsv if scope.exportCsv
         */
        scope.exportCsvFile = function() {
          if (!scope.tableParamsResults.data.length) return;

          var toExport = [];
          var headers = [];
          // push headers
          switch (scope.configChart.choice.type) {
            case 'pieChart':
            case 'discreteBarChart':
              headers = [
                $filter('translate')('chart.label'),
                $filter('translate')('chart.count'),
                $filter('translate')('chart.percentage'),
              ];
              break;
            case 'multiBarChart':
              headers = [
                scope.res2.alias + '/' + scope.res.alias,
                $filter('translate')('chart.count'),
                $filter('translate')('chart.percentage'),
              ];
              break;
          }
          toExport.push(headers);

          // push values
          scope.tableParamsResults.data.forEach(function(d) {
            var tmpObj = [];
            switch (scope.configChart.choice.type) {
              case 'pieChart':
                tmpObj = [
                  d.label,
                  scope.integerFilter(d.count),
                  scope.DecimalFilter(d.value),
                ];
                toExport.push(tmpObj);
                break;
              case 'discreteBarChart':
                tmpObj = [
                  d.label,
                  scope.integerFilter(d.count),
                  scope.DecimalFilter(d.value),
                ];
                toExport.push(tmpObj);
                break;
              case 'multiBarChart':
                tmpObj.push(d.key);
                var count = [],
                  percentage = [];
                d.values.map(function(x) {
                  count.push(x.x + '-' + scope.integerFilter(x.count));
                  percentage.push(x.x + '-' + scope.DecimalFilter(x.y));
                });
                tmpObj.push(count.join('/'));
                tmpObj.push(percentage.join('/'));
                toExport.push(tmpObj);
                break;
            }
          });
          return toExport;
        };
        var attributes = angular.copy(scope.fti.attributes);
        if (scope.authorisedAttributes) {
          attributes = scope.authorisedAttributes;
        }
        if (!attributes) {
          attributes = [];
        }
        var dateattributes = attributes
          .map(function(x) {
            if (
              ['java.sql.Timestamp', 'java.sql.Date', 'java.util.Date'].indexOf(
                x.type
              ) !== -1
            )
              return x.name;
          })
          .filter(function(x) {
            if (x !== undefined) return x;
          });

        var stringattributes = attributes
          .map(function(x) {
            if (['java.lang.String'].indexOf(x.type) !== -1) return x.name;
          })
          .filter(function(x) {
            if (x !== undefined) return x;
          });

        var w =
          scope.ctrlType === 'configDashboard'
            ? Math.round(
                (document.getElementsByClassName('graphid')[0].clientWidth *
                  8) /
                  12
              )
            : document.getElementsByClassName('graphid')[0].clientWidth;
        var h = 350;
        scope.h = Math.round((window.innerHeight * 0.9) / 2);

        if (
          scope.chartOpt &&
          scope.chartOpt.chart &&
          scope.chartOpt.chart.type === 'pieChart'
        )
          scope.chartOpt.chart.width = w;

        d3.selectAll('#waitImg').attr(
          'style',
          'margin-top:' + h / 3 + 'px;margin-left:' + w * 0.2 + 'px'
        );

        /*
         * Choix du titre et labels de l'axe des abcisses
         * et de l'axe des ordonnées
         */
        scope.configChart = scope.configChart || {
          values: '',
          choice: {
            type: '',
          },
          title: {
            enable: true,
            text:
              scope.configChart &&
              scope.configChart.title &&
              scope.configChart.title.text
                ? scope.configChart.title.text
                : 'titre',
            className: 'h4',
            css: {
              //"width": "auto",
              textAlign: 'center',
              //"padding-top":"10px"
            },
          },
          xAxis: 'axe X',
          yAxis: 'axe Y',
          changed: false,
          axisType: 'percent',
          labelType: 'key',
        };
        $translate('configChart.title.text').then(function(res) {
          scope.configChart.title.text = res;
        });
        $translate('configChart.xAxis').then(function(res) {
          scope.configChart.xAxis = res;
        });
        $translate('configChart.yAxis').then(function(res) {
          scope.configChart.yAxis = res;
        });

        /*
         * Récupération des attributs et triés pour l'axe des ordonnées
         */
        scope.attrChoices = scope.attrChoices || {
          attributes: [],
          choice: {
            x: {},
            y: [],
          },
          visible: false,
          total: true,
        };
        var sortAttributes = new Array();
        var arrtibutesNames = new Array();
        attributes.forEach(function(elem) {
          if (sortAttributes.indexOf(elem.name) === -1) {
            sortAttributes.push(elem.name);
            arrtibutesNames.push(elem.alias);
          }
        });
        var arrtibutesNameswithoutsort = angular.copy(arrtibutesNames);
        var sortAttributeswithoutsort = angular.copy(sortAttributes);
        //arrtibutesNames.sort();
        scope.attrChoices.attributes = [];
        sortAttributes.forEach(function(elem, i) {
          if (
            scope.attrChoices.attributes
              .map(function(x) {
                return x.name;
              })
              .indexOf(elem) === -1
          )
            scope.attrChoices.attributes.push({
              name: elem,
              nametosearch: arrtibutesNames[i],
            });
        });
        scope.attrChoices.attributes.sort(function(a, b) {
          if (a.nametosearch.toLowerCase() >= b.nametosearch.toLowerCase())
            return 1;
          if (a.nametosearch.toLowerCase() < b.nametosearch.toLowerCase())
            return -1;
        });

        /*
         * Préciser le type de chart et les options qui vont avec
         */
        var checkTypeChanged = {
          type: '',
          changed: false,
        };
        scope.legendVisible = false;
        scope.labelVisible = false;
        scope.donutVisible = false;
        var first = true;
        scope.setChartType = function(str) {
          if (!first) scope.chartOpt.affichage = 'graph';
          first = false;
          scope.configChart.choice.type = str;
          scope.configChart.changed = false;
          if (str === 'pieChart') {
            scope.clicked = {
              pieclicked: true,
              discrete: false,
              line: false,
              stacked: false,
              multi: false,
              scatter: false,
            };
            chartConfig.options = chartFactory.getPieOption(
              w,
              h,
              dateattributes,
              scope.attrChoices.choice.x.name
            );
            scope.attrChoices.visible = false;
            scope.attrChoices.visibleSingle = false;
          } else if (str === 'lineChart') {
            scope.clicked = {
              pieclicked: false,
              discrete: false,
              line: true,
              stacked: false,
              multi: false,
              scatter: false,
            };
            chartConfig.options = chartFactory.getLineOption(
              w,
              h,
              dateattributes,
              scope.attrChoices.choice.x.name
            );
            scope.attrChoices.visible = true;
            scope.attrChoices.visibleSingle = false;
          } else if (str === 'multiBarChart') {
            scope.clicked = {
              pieclicked: false,
              discrete: false,
              line: false,
              stacked: false,
              multi: true,
              scatter: false,
            };
            chartConfig.options = chartFactory.getmultiBarOption(
              w,
              h,
              dateattributes,
              scope.attrChoices.choice.x.name
            );
            scope.attrChoices.visible = false;
            scope.attrChoices.visibleSingle = true;
          } else if (str === 'discreteBarChart') {
            scope.clicked = {
              pieclicked: false,
              discrete: true,
              line: false,
              stacked: false,
              multi: false,
              scatter: false,
            };
            chartConfig.options = chartFactory.getDiscreteBarOption(
              w,
              h,
              dateattributes,
              scope.attrChoices.choice.x.name
            );
            scope.attrChoices.visible = false;
            scope.attrChoices.visibleSingle = false;
          } else if (str === 'stackedAreaChart') {
            scope.clicked = {
              pieclicked: false,
              discrete: false,
              line: false,
              stacked: true,
              multi: false,
              scatter: false,
            };
            chartConfig.options = chartFactory.getstackedAreaOption(
              w,
              h,
              dateattributes,
              scope.attrChoices.choice.x.name
            );
            scope.attrChoices.visible = true;
            scope.attrChoices.visibleSingle = false;
          } else if (str === 'scatterChart') {
            scope.clicked = {
              pieclicked: false,
              discrete: false,
              line: false,
              stacked: false,
              multi: false,
              scatter: true,
            };
            chartConfig.options = chartFactory.getscatterChartOption(
              w,
              h,
              dateattributes,
              scope.attrChoices.choice.x.name
            );
            scope.attrChoices.visible = true;
            scope.attrChoices.visibleSingle = false;
          }

          try {
            if (
              scope.chartOpt &&
              scope.chartOpt.chart &&
              scope.chartOpt.chart.showLegend
            )
              chartConfig.options.chart.showLegend =
                scope.chartOpt.chart.showLegend;

            if (
              scope.chartOpt &&
              scope.chartOpt.chart &&
              scope.chartOpt.chart.donut
            )
              chartConfig.options.chart.donut = scope.chartOpt.chart.donut;

            if (
              scope.chartOpt &&
              scope.chartOpt.chart &&
              scope.chartOpt.chart.axisType
            ) {
              chartConfig.options.chart.axisType =
                scope.chartOpt.chart.axisType;
              scope.chartOpt.chart.y =
                scope.typesAndcounts[scope.configChart.choice.type][
                  scope.chartOpt.chart.axisType
                ];
            }

            if (
              scope.chartOpt &&
              scope.chartOpt.chart &&
              scope.chartOpt.chart.labelType
            )
              chartConfig.options.chart.labelType =
                scope.chartOpt.chart.labelType;
          } catch (e) {
            console.error(e.stack);
          }

          chartConfig.options.chart.type == 'multiBarChart'
            ? (scope.legendVisibleForMultiBar = true)
            : (scope.legendVisibleForMultiBar = false);
          chartConfig.options.chart.type == 'discreteBarChart'
            ? (scope.legendVisible = false)
            : (scope.legendVisible = true);
          if (chartConfig.options.chart.type == 'pieChart') {
            scope.labelVisible = true;
            scope.donutVisible = true;
          } else {
            scope.labelVisible = false;
            scope.donutVisible = false;
          }
          if (
            chartConfig.options.chart.type == 'lineChart' ||
            chartConfig.options.chart.type == 'stackedAreaChart'
          ) {
            scope.sommeVisiblelineStack = true;
          } else {
            scope.sommeVisiblelineStack = false;
          }
        };

        var firstLoad1 = true;
        var firstLoad2 = true;

        scope.savedElement = function() {
          for (var i = 0; i < scope.attrChoices.attributes.length; i++) {
            if (
              scope.attrChoices.attributes[i].nametosearch ===
              scope.attrChoices.res.nametosearch
            )
              scope.attrChoices.res = scope.attrChoices.attributes[i];
          }
        };
        if (scope.attrChoices.res) {
          scope.savedElement();
        } else {
          scope.modifOpt = false;
        }

        scope.savedElement2 = function() {
          for (var i = 0; i < scope.attrChoices.attributes.length; i++) {
            if (
              scope.attrChoices.attributes[i].nametosearch ===
              scope.attrChoices.res2.nametosearch
            ) {
              scope.attrChoices.res2 = scope.attrChoices.attributes[i];
            }
          }
        };
        if (scope.attrChoices.res2) {
          scope.savedElement2();
        } else {
          scope.modifOpt = false;
        }

        var parseDate = d3.time.format('yyyy-MM-dd HH:mm:ss').parse;

        scope.modified = true;
        // Définition des types de charts disponible
        scope.typeCharts = [
          {
            name: $filter('translate')('chart.secteur'),
            type: 'pieChart',
            x: function(d) {
              if (
                d &&
                ((d.label && d.value) || d.label === 0 || d.value === 0)
              ) {
                if (
                  dateattributes.indexOf(scope.attrChoices.choice.x.name) !== -1
                ) {
                  return gaBrowserSniffer
                    .parseDateSpecIEchart(d.label)
                    .toLocaleDateString();
                } else {
                  if (d.label !== '') return d.label;
                  else return $filter('translate')('chart.emptystring');
                }
              }
            },
            count: function(d) {
              if (
                d &&
                ((d.label && d.value) || d.label === 0 || d.value === 0)
              ) {
                return d.count;
              }
            },
            y: function(d) {
              if (
                d &&
                ((d.label && d.value) || d.label === 0 || d.value === 0)
              ) {
                return d.value;
              }
            },
            format: function(d, i) {
              if (d || d === 0) return d3.format(',.2f')(d) + '%';
            },
          },
          {
            name: $filter('translate')('chart.line'),
            type: 'lineChart',
            x: function(d) {
              if (d && ((d.x && d.y) || d.x === 0 || d.y === 0)) {
                if (
                  dateattributes.indexOf(scope.attrChoices.choice.x.name) !== -1
                ) {
                  return gaBrowserSniffer
                    .parseDateSpecIEchart(d.x)
                    .toLocaleDateString();
                } else {
                  return d.x;
                }
              }
            },
            y: function(d) {
              if (d && ((d.x && d.y) || d.x === 0 || d.y === 0)) return d.y;
            },
          },
          {
            name: $filter('translate')('chart.multi_bar'),
            type: 'multiBarChart',
            x: function(d) {
              if (d && ((d.x && d.y) || d.x === 0 || d.y === 0)) {
                if (
                  dateattributes.indexOf(scope.attrChoices.choice.x.name) !== -1
                ) {
                  return gaBrowserSniffer
                    .parseDateSpecIEchart(d.x)
                    .toLocaleDateString();
                } else {
                  if (d.x !== '') return d.x;
                  else return $filter('translate')('chart.emptystring');
                }
              }
            },
            count: function(d) {
              if (d && ((d.x && d.y) || d.x === 0 || d.y === 0)) {
                return d.count;
              }
            },
            y: function(d) {
              if (d && ((d.x && d.y) || d.x === 0 || d.y === 0)) {
                return d.y;
              }
            },
          },
          {
            name: $filter('translate')('chart.discrete'),
            type: 'discreteBarChart',
            x: function(d) {
              if (
                d &&
                ((d.label && d.value) || d.label === 0 || d.value === 0)
              ) {
                if (
                  dateattributes.indexOf(scope.attrChoices.choice.x.name) !== -1
                ) {
                  return gaBrowserSniffer
                    .parseDateSpecIEchart(d.label)
                    .toLocaleDateString();
                } else {
                  if (d.label !== '') return d.label;
                  else return $filter('translate')('chart.emptystring');
                }
              }
            },
            count: function(d) {
              if (
                d &&
                ((d.label && d.value) || d.label === 0 || d.value === 0)
              ) {
                return d.count;
              }
            },
            y: function(d) {
              if (
                d &&
                ((d.label && d.value) || d.label === 0 || d.value === 0)
              ) {
                return d.value;
              }
            },
            format: function(d, i) {
              if (d || d === 0) return d3.format(',.2f')(d) + '%';
            },
          },
          {
            name: $filter('translate')('chart.stacked'),
            type: 'stackedAreaChart',
            x: function(d) {
              if (d && ((d[0] && d[1]) || d[0] === 0 || d[1] === 0)) {
                if (
                  dateattributes.indexOf(scope.attrChoices.choice.x.name) !== -1
                ) {
                  d.x = gaBrowserSniffer
                    .parseDateSpecIEchart(d[0])
                    .toLocaleDateString();
                  return d.x;
                } else {
                  d.x = d[0];
                  if (d.x !== '') return d.x;
                  else return $filter('translate')('chart.emptystring');
                }
              }
            },
            y: function(d) {
              if (d && ((d[0] && d[1]) || d[0] === 0 || d[1] === 0)) {
                d.y = d[1];
                return d.y;
              }
            },
          },
          {
            name: $filter('translate')('chart.scatter'),
            type: 'scatterChart',
            x: function(d) {
              if (d && ((d.x && d.y) || d.x === 0 || d.y === 0)) {
                if (
                  dateattributes.indexOf(scope.attrChoices.choice.x.name) !== -1
                ) {
                  return gaBrowserSniffer
                    .parseDateSpecIEchart(d.x)
                    .toLocaleDateString();
                } else {
                  if (d.x !== '') return d.x;
                  else return $filter('translate')('chart.emptystring');
                }
              }
            },
            y: function(d) {
              if (d && ((d.x && d.y) || d.x === 0 || d.y === 0)) {
                return d.y;
              }
            },
          },
        ];

        scope.typesAndcounts = {};
        scope.typeCharts.map(function(x) {
          scope.typesAndcounts[x.type] = {
            number: x.count,
            percent: x.y,
          };
        });

        // Création de l'objet qui regroupe :
        //      - Description de la couche
        //      - Attribut et filtre
        //      - les options du chart
        //      - les données à récupérer coté serveur
        var chartConfig = {
          source: {
            fti: scope.fti,
            featureCollection: {},
            selected: scope.fromSelected,
          },
          cql_filter: {
            attribute: scope.attrChoices.choice,
            where: scope.where,
            total: scope.attrChoices.total,
          },
          options: {},
          data: [],
        };

        /*
         * si les features sont selectionnées par le client
         * certains attributs dont la valeur est null sont supprimés du geojson
         * il faut les rajoutés sinon ça ne marche pas côté serveur
         */
        if (scope.fromSelected) {
          var attrArray = new Array();
          scope.attrChoices.attributes.forEach(function(element) {
            if (attrArray.indexOf(element.name) === -1)
              attrArray.push(element.name);
          });
          scope.features.features.forEach(function(feature) {
            var propKeys = Object.keys(feature.properties);
            if (propKeys.length != attrArray.length) {
              var diff = $.grep(attrArray, function(el) {
                return $.inArray(el, propKeys) == -1;
              });
              diff.forEach(function(el) {
                feature.properties[el] = null;
              });
            }
          });
          chartConfig.source.featureCollection = scope.features;
        }

        /*
         * Set camemeber graph par défault
         */
        scope.setChartType(scope.chartOpt.chart.type);

        if (
          scope.chartOpt.chart.x ||
          angular.isUndefined(scope.chartOpt.chart.x)
        ) {
          scope.chartOpt.chart.x = scope.typeCharts
            .map(function(x) {
              if (x.type === scope.chartOpt.chart.type) {
                return x.x;
              }
            })
            .filter(function(x) {
              if (x !== undefined) return x;
            })[0];
          scope.chartOpt.chart.y = scope.typeCharts
            .map(function(x) {
              if (x.type === scope.chartOpt.chart.type) {
                return x.y;
              }
            })
            .filter(function(x) {
              if (x !== undefined) return x;
            })[0];
        }

        if (
          scope.chartOpt.chart.tooltip ||
          angular.isUndefined(scope.chartOpt.chart.tooltip)
        ) {
          var configdefault = chartFactory.getOptionsByType(
            scope.chartOpt.chart.type,
            dateattributes,
            scope.attrChoices.choice.x.name
          );
          scope.chartOpt.chart.tooltip = configdefault.chart.tooltip;
        }

        /*
         * Récupération des données à affichées du côté serveur
         * envoie de chartConfig
         * récupération de chartConfig avec les data
         */
        var resdata;
        scope.chartBuild = function() {
          if (!angular.isUndefined(scope.attrChoices.res)) {
            scope.attrChoices.choice.x = {
              name: scope.attrChoices.res.name,
            };
            chartConfig.cql_filter.attribute = scope.attrChoices.choice;
          }

          if (scope.configChart.choice.type == 'multiBarChart') {
            chartConfig.cql_filter.total = scope.attrChoices.total;
            scope.attrChoices.choice.y = [
              { name: scope.attrChoices.res2.name },
            ];
          }

          if (!angular.isUndefined(scope.configChart.choice)) {
            chartConfig.options.chart.type = scope.configChart.choice.type;
            scope.typeCharts.forEach(function(object) {
              if (object.type === chartConfig.options.chart.type) {
                chartConfig.options.chart.x = object.x;
                chartConfig.options.chart.y = object.y;
                if (object.format) {
                  chartConfig.options.chart.tooltip.valueFormatter =
                    object.format;
                }
              }
            });
          }

          var bool = true;
          if (
            chartConfig.options.chart.type === 'stackedAreaChart' ||
            chartConfig.options.chart.type === 'lineChart' ||
            chartConfig.options.chart.type === 'scatterChart'
          ) {
            if (
              dateattributes.indexOf(scope.attrChoices.choice.x.name) !== -1 ||
              stringattributes.indexOf(scope.attrChoices.choice.x.name) !== -1
            ) {
              require('toastr').error(
                $filter('translate')('elastic.search.datenotaccepted')
              );
              return;
            } else {
              scope.attrChoices.choice.y.map(function(x) {
                if (
                  dateattributes.indexOf(x.name) !== -1 ||
                  stringattributes.indexOf(x.name) !== -1
                )
                  bool = false;
              });
              if (!bool) {
                require('toastr').error(
                  $filter('translate')('elastic.search.datenotaccepted')
                );
                return;
              }
            }
          }
          var resulttype = scope.chartOpt.affichage || 'graph';
          var showColonneNumber = scope.chartOpt.showColonneNumber;
          var showColonnePercentage = scope.chartOpt.showColonnePercentage;
          var url = '/services/{portalid}/stats/charts/getChartData';
          scope.wait = true;
          //d3.selectAll("svg > *").remove();
          $http
            .post(url, chartConfig, { timeout: 100000000000 })
            .then(function(response) {
              var title = undefined;
              if (scope.chartOpt.title) title = scope.chartOpt.title;

              var xAxis = undefined;
              if (
                scope.chartOpt.chart &&
                scope.chartOpt.chart.xAxis &&
                scope.chartOpt.chart.xAxis.axisLabel
              )
                xAxis = scope.chartOpt.chart.xAxis.axisLabel;

              var yAxis = undefined;
              if (
                scope.chartOpt.chart &&
                scope.chartOpt.chart.yAxis &&
                scope.chartOpt.chart.yAxis.axisLabel
              )
                yAxis = scope.chartOpt.chart.yAxis.axisLabel;

              scope.chartOpt = {};
              scope.chartOpt = chartConfig.options;
              if (title !== undefined) scope.chartOpt.title = title;
              if (xAxis !== undefined)
                scope.chartOpt.chart.xAxis.axisLabel = xAxis;
              if (yAxis !== undefined)
                scope.chartOpt.chart.yAxis.axisLabel = yAxis;

              scope.modifOpt = false;

              var configdefault = chartFactory.getOptionsByType(
                scope.chartOpt.chart.type,
                dateattributes,
                scope.attrChoices.choice.x.name
              );
              scope.chartOpt.chart.tooltip = configdefault.chart.tooltip;
              scope.chartOpt.affichage = resulttype;
              scope.chartOpt.showColonneNumber = showColonneNumber;
              scope.chartOpt.showColonnePercentage = showColonnePercentage;
              resdata = response.data;
              scope.wait = false;
              try {
                scope.chartdata = resdata.data;
                //$('#' + scope.graphid).children().empty();
                // if ( chartConfig.options.chart.type == "discreteBarChart" ) {
                //     //console.log("type discreteBarChart", scope.chartdata[0]);
                //     // scope.chartdata[0].values.length < 15 ? scope.chartOpt.chart.staggerLabels = false : scope.chartOpt.chart.staggerLabels = true ;
                //     // scope.chartdata[0].values.length < 30 ? scope.chartOpt.chart.showXAxis = true : scope.chartOpt.chart.showXAxis = false ;
                //     //scope.api.refresh();
                //     //scope.api.refresh();
                // }
                scope.tableParamsResults.reload();
              } catch (e) {
                e.stack;
                $('#' + scope.graphid)
                  .children()
                  .empty();
              }
            });
        };

        String.prototype.sansAccent = function() {
          var accent = [
            /[\300-\306]/g,
            /[\340-\346]/g, // A, a
            /[\310-\313]/g,
            /[\350-\353]/g, // E, e
            /[\314-\317]/g,
            /[\354-\357]/g, // I, i
            /[\322-\330]/g,
            /[\362-\370]/g, // O, o
            /[\331-\334]/g,
            /[\371-\374]/g, // U, u
            /[\321]/g,
            /[\361]/g, // N, n
            /[\307]/g,
            /[\347]/g, // C, c
          ];
          var noaccent = [
            'A',
            'a',
            'E',
            'e',
            'I',
            'i',
            'O',
            'o',
            'U',
            'u',
            'N',
            'n',
            'C',
            'c',
          ];

          var str = this;
          for (var i = 0; i < accent.length; i++) {
            str = str.replace(accent[i], noaccent[i]);
          }

          return str;
        };

        /*
         * extraction du svg présentant le chart
         * convertir en image canvas
         * téléchargement de l'image en png
         */
        scope.downloadPNG = function() {
          /*scope.chartOpt.chart.interactive = false;
                    scope.api.updateWithOptions(options);*/

          if (chartConfig.options.chart.type != 'stackedAreaChart') {
            d3.selectAll('path.nv-line').style('fill', 'none');
          }
          d3.selectAll('.nv-point-paths').remove();
          //d3.selectAll('.nv-series').remove();
          d3.selectAll('g.tick line').style('stroke', '#e5e5e5');
          d3.selectAll('g.tick line').style('fill', 'none');
          d3.selectAll('g.tick line').style('shape-rendering', 'cripEdges');
          d3.selectAll('path.domain').style('stroke', '#000');
          d3.selectAll('path.domain').style('stroke-opacity', '1');
          d3.selectAll('path.domain').style('shape-rendering', 'cripEdges');
          d3.selectAll('path.domain').style('fill', 'none');

          var gcsvg = document.getElementById(scope.graphid);
          var title = gcsvg.getElementsByClassName('title')[0];

          var svg = gcsvg.getElementsByTagName('svg')[0];

          var xml = new XMLSerializer().serializeToString(svg).sansAccent();
          var img = new Image();
          img.onload = function() {
            var canvas = document.createElement('canvas');
            document.body.appendChild(canvas);
            try {
              if (angular.isDefined(title)) {
                canvas.width = svg.width.baseVal.value + title.offsetLeft || 0;
                canvas.height =
                  svg.height.baseVal.value +
                    title.clientHeight +
                    title.offsetTop || 0;
                var context = canvas.getContext('2d');
                context.fillStyle = '#FFFFFF';
                context.fillRect(0, 0, canvas.width, canvas.height);
                context.drawImage(
                  img,
                  0,
                  title.clientHeight + title.offsetTop || 0,
                  svg.width.baseVal.value,
                  svg.height.baseVal.value
                );
                context.font = "18px 'opensans', sans-serif";
                context.textAlign = 'center';
                context.fillStyle = '#000000';
                context.fillText(
                  title.innerHTML,
                  canvas.width / 2 - title.innerHTML.length / 2,
                  (title.clientHeight + title.offsetTop || 0) / 2 + 18
                );
              } else {
                canvas.width = svg.width.baseVal.value;
                canvas.height = svg.height.baseVal.value;
                var context = canvas.getContext('2d');
                context.fillStyle = '#FFFFFF';
                context.fillRect(0, 0, canvas.width, canvas.height);
                context.drawImage(img, 0, 0, canvas.width, canvas.height);
              }

              var download = document.createElement('a');
              document.body.appendChild(download);
              download.href = canvas.toDataURL('image/png');
              download.download = 'chart.png';
              download.click();
            } catch (e) {
              console.error(e.message);
            }
            canvas.parentNode.removeChild(canvas);
            download.parentNode.removeChild(download);
            //scope.chartOpt.chart.interactive = true;
          };
          img.src = 'data:image/svg+xml;base64,' + window.btoa(xml);
        };

        scope.$watch('chartOpt.chart.axisType', function(newval) {
          if (newval) {
            scope.chartOpt.chart.y =
              scope.typesAndcounts[scope.configChart.choice.type][newval];
          }
        });

        scope.$watch('configChart.choice.type', function(newval, oldval) {
          scope.configChart.changed = false;
          if (newval == 'pieChart' || newval == 'discreteBarChart') {
            scope.modifOpt = scope.attrChoices.res !== undefined ? true : false;
          } else if (
            newval == 'lineChart' ||
            newval == 'stackedAreaChart' ||
            newval == 'scatterChart'
          ) {
            scope.modifOpt =
              scope.attrChoices.res !== undefined &&
              scope.attrChoices.choice.y.length !== 0
                ? true
                : false;
          } else if (newval == 'multiBarChart') {
            scope.modifOpt =
              scope.attrChoices.res !== undefined &&
              scope.attrChoices.res2 !== undefined
                ? true
                : false;
          }
        });

        scope.$watch('attrChoices.total', function(newval, oldval) {
          scope.configChart.changed = false;
          if (
            scope.configChart.choice.type == 'pieChart' ||
            scope.configChart.choice.type == 'discreteBarChart'
          ) {
            scope.modifOpt = scope.attrChoices.res !== undefined ? true : false;
          } else if (
            scope.configChart.choice.type == 'lineChart' ||
            scope.configChart.choice.type == 'stackedAreaChart' ||
            scope.configChart.choice.type == 'scatterChart'
          ) {
            scope.modifOpt =
              scope.attrChoices.res !== undefined &&
              scope.attrChoices.choice.y.length !== 0
                ? true
                : false;
          } else if (scope.configChart.choice.type == 'multiBarChart') {
            scope.modifOpt =
              scope.attrChoices.res !== undefined &&
              scope.attrChoices.res2 !== undefined
                ? true
                : false;
          }
        });

        scope.$watch('attrChoices.res', function(newval, oldval) {
          if (!firstLoad1) {
            if (newval) {
              scope.configChart.changed = false;
              if (
                scope.configChart.choice.type == 'pieChart' ||
                scope.configChart.choice.type == 'discreteBarChart'
              ) {
                scope.modifOpt =
                  scope.attrChoices.res !== undefined ? true : false;
              } else if (
                scope.configChart.choice.type == 'lineChart' ||
                scope.configChart.choice.type == 'stackedAreaChart' ||
                scope.configChart.choice.type == 'scatterChart'
              ) {
                scope.modifOpt =
                  scope.attrChoices.res !== undefined &&
                  scope.attrChoices.choice.y.length !== 0
                    ? true
                    : false;
              } else if (scope.configChart.choice.type == 'multiBarChart') {
                scope.modifOpt =
                  scope.attrChoices.res !== undefined &&
                  scope.attrChoices.res2 !== undefined
                    ? true
                    : false;
              }
              if (scope.canShowErrorConfig) {
                scope.canShowErrorConfig = false;
                // scope.canShowErrorConfigFilterRemoved = false;
              }
            }
          } else {
            firstLoad1 = false;
            scope.modifOpt = false;
          }
        });

        scope.$watch('attrChoices.res2', function(newval, oldval) {
          if (!firstLoad2) {
            if (newval) {
              scope.configChart.changed = false;
              if (
                scope.configChart.choice.type == 'lineChart' ||
                scope.configChart.choice.type == 'stackedAreaChart' ||
                scope.configChart.choice.type == 'scatterChart' ||
                scope.configChart.choice.type == 'multiBarChart'
              ) {
                scope.modifOpt =
                  scope.attrChoices.res !== undefined &&
                  scope.attrChoices.res2 !== undefined
                    ? true
                    : false;
              } else {
                scope.modifOpt = false;
              }
            }
          } else {
            firstLoad2 = false;
            scope.modifOpt = false;
          }
        });

        scope.$watch('attrChoices.choice.y', function(newval, oldval) {
          if (newval) {
            scope.configChart.changed = false;
            if (
              scope.configChart.choice.type == 'lineChart' ||
              scope.configChart.choice.type == 'stackedAreaChart' ||
              scope.configChart.choice.type == 'scatterChart'
            ) {
              if (scope.attrChoices.choice.y.length !== 0) {
                scope.attrChoices.choice.y.map(function(x) {
                  var index = arrtibutesNameswithoutsort.indexOf(
                    x.nametosearch
                  );
                  x.name = sortAttributeswithoutsort[index];
                });
              }
              scope.modifOpt =
                scope.attrChoices.res !== undefined &&
                scope.attrChoices.choice.y.length !== 0
                  ? true
                  : false;
            } else {
              scope.modifOpt = false;
            }
          }
        });

        scope.DecimalFilter = function(x) {
          if (x) return d3.format('.2f')(x) + '%';
          else return '0%';
        };

        scope.integerFilter = function(x) {
          if (x) return d3.format('.i')(x);
          else return '0';
        };

        scope.canShowErrorConfig = false;
        // scope.canShowErrorConfigFilterRemoved = false;

        if (
          scope.attrChoices &&
          scope.attrChoices.res &&
          scope.attrChoices.res.name &&
          scope.fti
        ) {
          var attributesNames = attributes.map(function(x) {
            return x.name;
          });
          if (attributesNames.indexOf(scope.attrChoices.res.name) === -1) {
            $timeout(function() {
              scope.canShowErrorConfig = true;
            }, 600);
            // if ( scope.where && scope.where.indexOf(scope.attrChoices.res.name) !== -1 ){
            //   scope.where = "";
            //   scope.canShowErrorConfigFilterRemoved = true;
            // }
            // if ( angular.isDefined(chartConfig) && chartConfig.cql_filter &&
            //   chartConfig.cql_filter.where && chartConfig.cql_filter.where.indexOf(scope.attrChoices.res.name) !== -1 ){
            //     chartConfig.cql_filter.where = "";
            //     scope.canShowErrorConfigFilterRemoved = true;
            //   }
          } else {
            if (getdata && scope.runcalc) scope.chartBuild();
          }
        } else {
          if (getdata && scope.runcalc) scope.chartBuild();
        }
      },
    };
  };

  element.$inject = [
    'ConfigFactory',
    'gcPopup',
    '$http',
    '$translate',
    'chartFactory',
    '$filter',
    'gaBrowserSniffer',
    'ngTableParams',
    '$timeout',
  ];
  return element;
});
