0

我已将 Sankey JS 作为 Qlik sense 的外部插件包含在内。我在图表中总共添加了 5 个维度和 1 个度量。但是当我查看图表时,我只能看到 4 个维度,并且最后一个维度替换了之前的维度。例如:

Dim1、Dim2、Dim3、Dim4 - 当我只包含 4 个维度时,它看起来很好。

Dim1、Dim2、Dim3、Dim5 - 如果我在图表中添加第 5 个维度。

问题是当我查看 QDataPages[0] 大小对象时,我只能看到 qMatrix 对象下的 4 个维度的值。如何增加尺寸或查看更多尺寸。非常感谢您的帮助。

requirejs.config({
  shim : {
    "extensions/SenseSankey/sankeymore" : {
      "deps" : ["extensions/SenseSankey/d3.min"]
    }
  }
});
//define(["jquery", "text!./style.css","extensions/SenseSankey/sankeymore"], function($, cssContent) {
define(["jquery", "text!./style.css","core.utils/theme","extensions/SenseSankey/md5.min","extensions/SenseSankey/sankeymore"], function($, cssContent, Theme, md5) {
    'use strict';
    $( "<style>" ).html( cssContent ).appendTo( "head" );
    return {
        initialProperties: {
            version: 1.3,
            qHyperCubeDef: {
                qDimensions: [],
                qMeasures: [],
                qInitialDataFetch: [{
                    qWidth: 5,
                    qHeight: 2000
                }]
            },
            selectionMode: "QUICK"
        },
        definition: {
            type: "items",
            component: "accordion",
            items: {
                dimensions: {
                    uses: "dimensions",
                    min: 2,
                    max: 7
                },
                measures: {
                    uses: "measures",
                    min: 1,
                    max: 1
                },
                //sorting: {
                //  uses: "sorting"
                //},
                settings: {
                    uses: "settings",
                    type: "items",
                    items : {
                            SankeyGroup:{
                            label : "Sankey Settings",
                            type:"items",
                            items : {
                            flowMax:{
                                type: "integer",
                                label: "Flow max (10 to 2000)",
                                ref: "flowMax (max is 2000)",
                                defaultValue: 500,
                                min : 10,
                                max : 2000
                                },
                            flowChoice:{
                                ref:"flowChoice",
                                type:"integer",
                                component:"dropdown",
                                label:"Color Flow",
                                options:
                                [
                                    {
                                    value:1,
                                    label:"Qlik Color"
                                    },
                                    {
                                    value:2,
                                    label:"Custom Color"
                                    }
                                ],
                                defaultValue: 1

                            },
                            flowColor:{
                                type: "string",
                                component: "color-picker",
                                //component: "ColorsPickerComponent",
                                expression: "optional",
                                label: "Color Flow if no Hex Color",
                                ref: "flowColor",
                                defaultValue: 2,
                                show: function(layout) { return layout.flowChoice == 1 }
                                },

                            flowColorCustom:{
                                type: "string",
                                label: "Custom Hex Color for Flow",
                                ref: "flowColorCustom",
                                defaultValue: "#999999",
                                show: function(layout) { return layout.flowChoice == 2 }
                                },

                            Separateur:{
                                ref: "displaySeparateur",
                                type: "string",
                                component: "dropdown",
                                label: "Pop-up Separator",
                                options:
                                [
                                    {
                                    value:" - ",
                                    label:"-"
                                    },
                                    {
                                    value:" <-> ",
                                    label:"<->"
                                    },
                                    {
                                    value: " → ",
                                    label: " → "
                                    },
                                ],
                                defaultValue: " - "
                            },
                            Format:{
                                ref: "displayFormat",
                                type: "string",
                                component: "dropdown",
                                label: "Pop-up Format",
                                options: 
                                [ 
                                    {
                                    value: "Number2",
                                    label: "1000.12"
                                    },
                                    {
                                    value: "Number1",
                                    label: "1000.1"
                                    },
                                    {
                                    value: "Number",
                                    label: "1000"
                                    },
                                    {
                                    value: "Money2",
                                    label: "1000.12 €"
                                    },
                                    {
                                    value: "Money1",
                                    label: "1000.1 €"
                                    },
                                    {
                                    value: "Money",
                                    label: "1000 €"
                                    },
                                ],
                                    defaultValue: "Number"
                                    },

                            Palette:{
                                ref:"displayPalette",
                                type:"string",
                                component: "dropdown",
                                label : "Palette",
                                options:
                                [
                                    {
                                    value: "D3-20",
                                    label: "Ordinal Palette 20 colors"
                                    },
                                    {
                                    value: "D3-20c",
                                    label: "Blue-Grey Palette 20 colors"
                                    },
                                    {
                                    value: "D3-20b",
                                    label: "Blue-Purple Palette 20 colors"
                                    },
                                    {
                                    value: "20",
                                    label: "Palette 20 colors"
                                    },
                                    {
                                    value: "20a",
                                    label: "Other Palette 20 colors"
                                    },
                                    {
                                    value: "20b",
                                    label: "Spectral 14 color Palette"    // Added by Anand.V.N for Spectral Color Palette
                                    },
                                ],
                                    defaultValue: "D3-20"
                                    },
                                colorPersistence:{
                                    ref: "colorPersistence",
                                    component: "switch",
                                    type: "boolean",
                                    translation: "Persistence",
                                    defaultValue: false,
                                    trueOption: {
                                      value: true,
                                      translation: "properties.on"
                                    },
                                    falseOption: {
                                      value: false,
                                      translation: "properties.off"
                                    },
                                    show: true
                                }
                            }
                        }

                    }
                }
            }
        },
        snapshot: {
            canTakeSnapshot: true
        },

        paint: function ( $element, layout ) {

        // Fonction format pop-up       
        function formatMoney(n, c, d, t, m, l){
            var c = isNaN(c = Math.abs(c)) ? 2 : c, 
                d = d == undefined ? "." : d, 
                t = t == undefined ? "," : t, 
                s = n < 0 ? "-" : "", 
                i = parseInt(n = Math.abs(+n || 0).toFixed(c)) + "", 
                j = (j = i.length) > 3 ? j % 3 : 0;
               return l + ' \n ' + s + (j ? i.substr(0, j) + t : "") + i.substr(j).replace(/(\d{3})(?=\d)/g, "$1" + t) + (c ? d + Math.abs(n - i).toFixed(c).slice(2) : "")+ m;
             };

        // Persistent color function
        var hashScale = d3.scale.linear().domain([1, 4294967295]).range([ 0, 19.9999 ]);


        function hashL(str) {
          var hashL = 5381,
              i    = str.length
          while(i)
            hashL = (hashL * 33) ^ str.charCodeAt(--i) 
            //hash = md5(str)
          return hashL >>> 0;
        }

        function getColorForNode(strValue) {
            if (colorPersistence===true) {
                return colours[parseInt(Math.floor(hashScale(hashL(md5(strValue)))))];
            } else 
            {
                return colours[Math.floor(Math.random() * (19))];
            }
            }

          var _this = this;
          var maxHeight         = layout.flowMax;
          var displayFormat     = layout.displayFormat;
          var displaySeparateur = layout.displaySeparateur;
          var displayPalette    = layout.displayPalette;
          var colorPersistence  = layout.colorPersistence;

         if (displayPalette === "D3-20") {
            var colours = ['#1f77b4','#aec7e8','#ff7f0e','#ffbb78','#2ca02c','#98df8a','#d62728','#ff9896','#9467bd','#c5b0d5','#8c564b',
                            '#c49c94','#e377c2','#f7b6d2','#7f7f7f','#c7c7c7','#bcbd22','#dbdb8d','#17becf','#9edae5' ];
        }
        else if (displayPalette === "D3-20b") {
            var colours = ['#393b79','#5254a3','#6b6ecf','#9c9ede','#637939','#8ca252','#b5cf6b','#cedb9c','#8c6d31','#bd9e39',
            '#e7ba52','#e7cb94','#843c39','#ad494a','#d6616b','#e7969c','#7b4173','#a55194','#ce6dbd','#de9ed6'];
        }
        else if (displayPalette === "D3-20c") {
            var colours = ['#3182bd','#6baed6', '#9ecae1','#c6dbef','#e6550d','#fd8d3c','#fdae6b','#fdd0a2','#31a354',
                '#74c476','#a1d99b','#c7e9c0','#756bb1','#9e9ac8','#bcbddc','#dadaeb','#636363','#969696','#bdbdbd','#d9d9d9' ];
        }
        else if (displayPalette === "20") {
            var colours = [ '#1abc9c','#7f8c8d','#2ecc71','#bdc3c7','#3498db','#c0392b','#9b59b6','#d35400','#34495e','#f39c12',
                '#16a085','#95a5a6','#27ae60','#ecf0f1','#2980b9','#e74c3c','#8e44ad','#e67e22','#2c3e50','#f1c40f' ];
        }
        else if (displayPalette === "20a") {
            var colours = [ '#023FA5','#7D87B9','#BEC1D4','#D6BCC0','#BB7784','#FFFFFF','#4A6FE3','#8595E1','#B5BBE3','#E6AFB9',
            '#E07B91','#D33F6A','#11C638','#8DD593','#C6DEC7','#EAD3C6','#F0B98D','#EF9708','#0FCFC0','#9CDED6'];
        }
        else if (displayPalette === "20b") {  // Added by Anand.V.N for Spectral Color Palette
            var colours = [ '#F46D43','#E78162','#FDAE61','#F0B880','#FEE08B','#F1CA5F','#E6F598','#D4E86D','#ABDDA4','#85D07B',
            '#66C2A5','#44B591','#3288BD','#5E4FA2','#D9D9D9','#BFBFBF','#A6A6A6','#7F7F7F','#595959','#9CDED6'];
        }


        var flowColor = (layout.flowChoice == 2) ? layout.flowColorCustom : Theme.palette[layout.flowColor];

        var qData = layout.qHyperCube.qDataPages[0];
          // create a new array that contains the dimension labels
        var qDim  = layout.qHyperCube.qDimensionInfo.map(function(d) {
                return d.qFallbackTitle;
            });

          console.log(layout.qHyperCube);
        var divName = layout.qInfo.qId;
        var qMatrix = qData.qMatrix.sort();
        var source = qMatrix.map(function(d) {

        var path = ""; 
        var sep = ""; 
        for (var i = 0; i < d.length - 1; i++) {
            path += sep + (d[i].qText.replace('|', ' ')) + '|' + (d[i].qElemNumber); 
            sep = ",";
        }

        return {
              //"Path":d[0].qText,
              "Path": path,
              "Frequency": d[d.length - 1].qNum
            }
           });
          var id = "sk_"+ layout.qInfo.qId;

          if (document.getElementById(id)) {
             $("#" + id).empty();
           }
           else {
            $element.append($('<div />').attr("id", id));        
           }
          $("#" + id).width($element.width()).height($element.height());
          var sLinks = [];
          var endArr = [];
          var catArray = [];

          //********Creates Duplicate IDs*************
          //        $element.attr("id",id)
          //******************************************
          //var td = _this.Data;
          var sNodes = [];
          var jNodes = [];
          var rev = 0; //permet de pivoter les dimensions


          source=source.slice(0,maxHeight);
          //source foreach
        source.forEach(function(d) {
          //var row = d;
          var path = d.Path;
          var val = parseFloat(d.Frequency);
          if(val > 0) {
            var tArr = path.split(",",4);  
            //tArr.sort();
            if (rev == "1") {
                tArr.reverse();
            }       
            if (tArr.length > 1) {
                $.each(tArr, function(i) {

                if(tArr.length === (i + 1)){
                    tArr[i] = this.toString().trim() + "~end";
                }else{
                    tArr[i] = this.toString().trim() + "~" + i; 
                }
            });
            $.each(tArr, function(i) {
                if ($.inArray(this.toString().trim(), sNodes) === -1) {
                    sNodes.push(this.toString().trim());
                }
            });
            }
            }
            });

           sNodes.forEach(function(d) {
                    jNodes.push({
                        name: d.toString()
                    })
            });

          //source foreach
        source.forEach(function(d) {
          //var row = d;
          var path = d.Path
          var val = parseFloat(d.Frequency);
          if(val > 0) {
          var tArr = path.split(",");  

          if (rev == "1") {
            tArr.reverse();
          }         
          if (tArr.length > 1) {
            $.each(tArr, function(i) {

                    if(tArr.length === (i + 1)){
                        tArr[i] = this.toString().trim() + "~end";
                    }else{
                        tArr[i] = this.toString().trim() + "~" + i; 
                    }
                });

            $.each(tArr, function(i) {
                    var tFlag = "no";
                    if ((i + 1) != tArr.length) {
                        var cS = $.inArray(this.toString().trim(), sNodes);
                        var cT = $.inArray(tArr[i + 1].toString().trim(), sNodes);

                        $.each(sLinks, function(i, v) {
                            if ((v.source === cS) && (v.target === cT)) {
                                tFlag = "yes";
                                v.value = v.value + val;

                            }
                        });
                        if (tFlag == "no") {
                            sLinks.push({
                                "source" : cS,
                                "target" : cT,
                                "value" : val
                            });
                        }

                    }
                });
            }
        }
        });


      var margin = {
          top : 1,
          right : 1,
          bottom : 0,
          left : 1
        }, width = $element.width(), height = $element.height();

            // Added svgHeader class for Scrollbars by Anand.V.N

        var svg = d3.select("#sk_" + divName).attr("class","svgHeader").append("svg").attr("width", width + margin.left +  margin.right).attr("height", height + margin.top + margin.bottom).append("g").attr("transform", "translate(" + margin.left + "," + margin.top + ")");

        var sankey = d3.sankey().nodeWidth(15).nodePadding(10).size([width -10 , height-10]);
        var path = sankey.link();


        sankey.nodes(jNodes).links(sLinks).layout(32);
        var link = svg.append("g").selectAll(".link").data(sLinks).enter().append("path").attr("class", "link").attr("d", path).style("stroke-width",function(d) {
          return Math.max(1, d.dy);
        }).sort(function(a, b) {
          return b.dy - a.dy;
        });

        //Color of Flow 
        link.style('stroke', flowColor);

        // affiche la valeur sur le flux en popup
            link.append("title").text(function(d) {
            //Je supprime les tildes et les pipes
            var start = d.source.name.split('|')[0];
            //var start = d.source.name.substr(0, d.source.name.length - 2).split('|')[0];
            var end = d.target.name.split('|')[0];

          if (displayFormat === "Number"){
          return formatMoney(d.value, 0, '.', ' ','' , start + displaySeparateur + end);
          }
          if (displayFormat === "Number1"){
          return formatMoney(d.value, 1, '.', ' ','' , start + displaySeparateur + end);
          }
          if (displayFormat === "Number2"){
          return formatMoney(d.value, 2, '.', ' ','' , start + displaySeparateur + end);
          }
          if (displayFormat === "Money"){
          return formatMoney(d.value, 0, '.', ' ',' €' , start + displaySeparateur + end);
          }
          if (displayFormat === "Money1"){
          return formatMoney(d.value, 1, '.', ' ',' €' , start + displaySeparateur + end);
          }
          if (displayFormat === "Money2"){
          return formatMoney(d.value, 2, '.', ' ',' €' , start + displaySeparateur + end);
          }
        });

        var node = svg
        .append("g").selectAll(".node").data(jNodes).enter().append("g").attr("class", "node").attr("transform", function(d) {
          return "translate(" + d.x + "," + d.y + ")";
        })

        node.on("click",function(d, i) {
            //on passe a la fonction l'identifiant qElement precedemment stocké dans le nom et le nom de la dimension sous forme d'un tableau

            _this.backendApi.selectValues(
                parseInt(d.name.split('~')[1].replace('end', qDim.length - 1)),
                [ parseInt(d.name.split('~')[0].split('|')[1]) ],
                true
            );
        })

        // Start of Node and Path/Link Color. Declared variables for the arrays to store unique colors for specific nodes  Added by Anand.V.N 

        var nodeLinkColor='';
        var nodeName='';
        var colorArray= new Array();
        var objColor={};
        var tempArr=new Array();

        // End of Node and Path/Link Color  Added by Anand.V.N

        // AVEC POPUP sur le carré de couleur
        node.append("rect").attr("height", function(d) {
          return d.dy;
        }).attr("width", sankey.nodeWidth()).style("fill", function(d) {


        // Implemented Logic for the arrays to store unique colors for specific nodes  Added by Anand.V.N 

        nodeName= d.name.split('|')[0];
        if (!tempArr.contains(nodeName)) {
                    d.color = getColorForNode(d.name);
                    nodeLinkColor=d.color;
                    objColor[nodeName]=nodeLinkColor
                    colorArray.push(objColor);
                }
        else
                {
                     colorArray.forEach(function(i){
                     d.color=i[nodeName];
                    });
                }

        tempArr.push(nodeName); 

        // End of Node and Path/Link Color  Added by Anand.V.N

        return d.color;

        }).style("stroke", function(d) {
          return d3.rgb(d.color).darker(2);
        }).append("title").text(function(d) {

        var level = d.name.substr(d.name.indexOf("~")+1,1);

        if (level === "e" ){level = qDim.length -1;}
        var entete = qDim[level] + ' : ' + d.name.split('|')[0];

          if (displayFormat === "Number"){
          return formatMoney(d.value, 0, '.', ' ','', entete);
          }
          if (displayFormat === "Number1"){
          return formatMoney(d.value, 1, '.', ' ','',entete);
          }
          if (displayFormat === "Number2"){
          return formatMoney(d.value, 2, '.', ' ','',entete);
          }
          if (displayFormat === "Money"){
          return formatMoney(d.value, 0, '.', ' ',' €',entete);
          }
          if (displayFormat === "Money1"){
          return formatMoney(d.value, 1, '.', ' ',' €',entete);
          }
          if (displayFormat === "Money2"){
          return formatMoney(d.value, 2, '.', ' ',' €',entete);
          }
        });


            var link = svg.append("g").selectAll(".link").data(sLinks).enter().append("path").attr("class", "link").attr("d", path).style("stroke-width",function(d) {
          return Math.max(1, d.dy);
        }).sort(function(a, b) {
          return b.dy - a.dy;
        });

        link.style('stroke', function(d) {

            // Implemented Logic to compare node arrays for specific colors and assign to the link/path.  Added by Anand.V.N 

            var start = d.source.name.split('|')[0];
            var end = d.target.name.split('|')[0];
           colorArray.forEach(function(i){
                    // console.log(i);
                    if(colorArray.indexOf(start)==-1)
                        d.color=i[start];
            });

            // End of Node and Path/Link Color  Added by Anand.V.N

            return d.color; 

        });

        link.append("title").text(function(d) {
        var start = d.source.name.split('|')[0];
        //var start = d.source.name.substr(0, d.source.name.length - 2).split('|')[0];
        var end = d.target.name.split('|')[0];


          if (displayFormat === "Number"){
          return formatMoney(d.value, 0, '.', ' ','' , start + displaySeparateur + end);
          }
          if (displayFormat === "Number1"){
          return formatMoney(d.value, 1, '.', ' ','' , start + displaySeparateur + end);
          }
          if (displayFormat === "Number2"){
          return formatMoney(d.value, 2, '.', ' ','' , start + displaySeparateur + end);
          }
          if (displayFormat === "Money"){
          return formatMoney(d.value, 0, '.', ' ',' €' , start + displaySeparateur + end);
          }
          if (displayFormat === "Money1"){
          return formatMoney(d.value, 1, '.', ' ',' €' , start + displaySeparateur + end);
          }
          if (displayFormat === "Money2"){
          return formatMoney(d.value, 2, '.', ' ',' €' , start + displaySeparateur + end);
          }
        });

            // Changes the 'x' attribute size for the <text> to include text within <rect> nodes. Also have updated <text> tag by appending it next to <rect> tag. Added by Anand.V.N 

            node.append("text").attr("class", "nodeTitle").attr("x", 5).attr("y", function(d) {
              return d.dy / 2;
        }).attr("dy", ".35em").attr("text-anchor", "middle").attr("alignment-baseline", "middle").attr("transform", null).text(function(d) {
          var str = d.name.substring(0, d.name.indexOf("~")).split('|')[0];
          return str 
        }).filter(function(d) {
          return d.x < width / 2;
       }).attr("text-anchor", "start"); 

            // End of <text> tag. Added by Anand.V.N

        /*
         function dragmove(d) {
          d3.select(this).attr("transform", "translate(" + d.x + "," + (d.y = Math.max(0, Math.min(height - d.dy, d3.event.y))) + ")");
          sankey.relayout();
          link.attr("d", path);
        }
        */
        }        
    };

} );

问候,

4

2 回答 2

0

只是一个假设:您是否将此代码从 qWidth=4 更改为 qWidth=5?

qInitialDataFetch: [{
                    qWidth: 5,
                    qHeight: 2000
                }

如果是这种情况,请从工作表中删除扩展名,刷新浏览器并再次重新添加扩展名!

于 2017-06-07T14:33:28.397 回答
0

我认为您只需要重新创建应用程序,qwidth 和最大/最小尺寸已正确设置。只需重新创建应用程序或重新添加扩展程序。我遇到了同样的问题,重新创建应用程序后,问题已解决。

于 2019-12-14T12:11:28.433 回答