'use strict';
define(function() {
  var element = function(
    ConfigFactory,
    gcPopup,
    $http,
    $translate,
    chartFactoryBuilder,
    $filter,
    gaBrowserSniffer,
    ngTableParams,
    $rootScope,
    RightsFactory
  ) {
    return {
      templateUrl: 'js/XG/widgets/utilities/chart/views/chartBuilder.html',
      restrict: 'A',
      scope: {
        fti: '=fti',
        where: '=where',
        features: '=features',
        fromSelected: '=selected',
      },

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

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

        scope.chartOpt = {
          chart: {
            type: 'discreteBarChart',
            height: 450,
            margin: {
              top: 20,
              right: 20,
              bottom: 50,
              left: 55,
            },
            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 = [
          {
            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 = 'graph';
        scope.chartOpt.showColonneNumber = true;
        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 w = 650;
        var h = 450;

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

        var dateattributes = scope.fti.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 = scope.fti.attributes
          .map(function(x) {
            if (['java.lang.String'].indexOf(x.type) !== -1) return x.name;
          })
          .filter(function(x) {
            if (x !== undefined) return x;
          });

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

        /*
         * Récupération des attributs et triés pour l'axe des ordonnées
         */
        scope.attrChoices = {
          attributes: [],
          choice: {
            x: {},
            y: [],
          },
          visible: false,
          total: true,
        };
        var sortAttributes = new Array();
        var arrtibutesNames = new Array();
        let authorizedAttributes = [];
        if($rootScope.xgos){
          scope.isAdmin = $rootScope.xgos.isroot || $rootScope.xgos.isadmin;
          authorizedAttributes = RightsFactory.getUserWriteOrReadRightsAttributes($rootScope.xgos.user, scope.fti, scope.isAdmin, true);
        }
        authorizedAttributes.forEach(function(elem) {
          sortAttributes.push(elem.name);
          arrtibutesNames.push(elem.alias);
        });
        var arrtibutesNameswithoutsort = angular.copy(arrtibutesNames);
        var sortAttributeswithoutsort = angular.copy(sortAttributes);
        //arrtibutesNames.sort();

        sortAttributes.forEach(function(elem, i) {
          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;
        scope.setChartType = function(str) {
          scope.chartOpt.affichage = 'graph';
          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 = chartFactoryBuilder.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 = chartFactoryBuilder.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 = chartFactoryBuilder.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 = chartFactoryBuilder.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 = chartFactoryBuilder.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 = chartFactoryBuilder.getscatterChartOption(
              w,
              h,
              dateattributes,
              scope.attrChoices.choice.x.name
            );
            scope.attrChoices.visible = true;
            scope.attrChoices.visibleSingle = false;
          }

          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;
          }
        };

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

        scope.$watch('res2', function(newval, oldval) {
          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.res !== undefined && scope.res2 !== undefined
                ? true
                : false;
          }
        });

        scope.$watch('attrChoices.choice.y', function(newval, oldval) {
          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.res !== undefined && scope.attrChoices.choice.y.length !== 0
                ? true
                : false;
          }
        });

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

        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 (
                    $filter('translate')(
                      'features.' +
                        scope.fti.name +
                        '.domaine.' +
                        scope.res.name +
                        '.' +
                        d.label
                    ).indexOf('features.') === -1
                  )
                    return $filter('translate')(
                      'features.' +
                        scope.fti.name +
                        '.domaine.' +
                        scope.res.name +
                        '.' +
                        d.label
                    );
                  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 {
                  if (
                    $filter('translate')(
                      'features.' +
                        scope.fti.name +
                        '.domaine.' +
                        scope.res.name +
                        '.' +
                        d.x
                    ).indexOf('features.') === -1
                  )
                    return $filter('translate')(
                      'features.' +
                        scope.fti.name +
                        '.domaine.' +
                        scope.res.name +
                        '.' +
                        d.x
                    );
                  try {
                    return d.x.toFixed(2);
                  } catch (e) {
                    return d.x;
                  }
                }
              }
            },
            y: function(d) {
              if (d && ((d.x && d.y) || d.x === 0 || d.y === 0)) {
                try {
                  return d.y.toFixed(2);
                } catch (e) {
                  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 (
                    $filter('translate')(
                      'features.' +
                        scope.fti.name +
                        '.domaine.' +
                        scope.res.name +
                        '.' +
                        d.x
                    ).indexOf('features.') === -1
                  )
                    return $filter('translate')(
                      'features.' +
                        scope.fti.name +
                        '.domaine.' +
                        scope.res.name +
                        '.' +
                        d.x
                    );
                  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 (
                    $filter('translate')(
                      'features.' +
                        scope.fti.name +
                        '.domaine.' +
                        scope.res.name +
                        '.' +
                        d.label
                    ).indexOf('features.') === -1
                  )
                    return $filter('translate')(
                      'features.' +
                        scope.fti.name +
                        '.domaine.' +
                        scope.res.name +
                        '.' +
                        d.label
                    );
                  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 (
                    $filter('translate')(
                      'features.' +
                        scope.fti.name +
                        '.domaine.' +
                        scope.res.name +
                        '.' +
                        d.x
                    ).indexOf('features.') === -1
                  )
                    return $filter('translate')(
                      'features.' +
                        scope.fti.name +
                        '.domaine.' +
                        scope.res.name +
                        '.' +
                        d.x
                    );
                  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 (
                    $filter('translate')(
                      'features.' +
                        scope.fti.name +
                        '.domaine.' +
                        scope.res.name +
                        '.' +
                        d.x
                    ).indexOf('features.') === -1
                  )
                    return $filter('translate')(
                      'features.' +
                        scope.fti.name +
                        '.domaine.' +
                        scope.res.name +
                        '.' +
                        d.x
                    );
                  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,
          };
        });

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

        // 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) {
            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('discreteBarChart');

        /*
         * 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.res)) {
            scope.attrChoices.choice.x = { name: scope.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.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;
          $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 = chartFactoryBuilder.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);
          };
          img.src = 'data:image/svg+xml;base64,' + window.btoa(xml);
        };

        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';
        };
      },
    };
  };

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