0

我在 GitHub ( https://github.com/RallyCommunity/TagCloud ) 上找到了一些代码,用于在 Rally 中显示 TagCloud。从概念上讲,它看起来很棒,但我似乎无法让它工作,并想知道是否有任何 Rally JavaScript 专家可以快速浏览一下。

我稍微修改了它,因为分析的 URL 不正确(根据文档)并且 API 被硬编码为折旧版本,所以我更新了这些。

我不是 JavaScript 专家。当我运行它时,它没有找到任何针对故事的标签。

当我在 Chrome 调试模式下运行它时,我可以获取 URL 并在我的浏览器中执行它,但它也不会返回任何标签。它带有来自 Analytics 的完整结果响应,但没有标签,而且我知道所选项目中有针对故事的标签。

任何人的任何想法?

<!DOCTYPE html>
<html>
<head>
<title>TagCloud</title>

<script type="text/javascript" src="/apps/2.0p/sdk.js"></script>
<script type="text/javascript">
Rally.onReady(function() {
   Ext.define('CustomApp', {
       extend: 'Rally.app.App',
       componentCls: 'app',
       layout: 'border',
       items: [
    {
        title: 'Tag Cloud',
        xtype: 'panel',
        itemId: 'cloud',
        region: 'west',
        width: '30%',
        collapsible: true,
        bodyStyle: 'padding:15px',
        listeners: { 'afterRender': function(el) { setTimeout(function() { el.setLoading(); }, 500);}} // needs a little delay
    },
    {
        title: '<<< Select a tag from the Tag Cloud',
        xtype: 'panel',
        itemId: 'grid',
        region: 'center',
        width: '70%',
        collapsible: false
    }
       ],

       tagMap : [],
       maxFont : 24, // largest desired font size
       minFont : 8,  // and smallest

       _renderTag : function renderHandler(tagLabel) {
    tagLabel.getEl().on('click',this._tagSelected, this);
       },

       // does the actual building of the cloud from 'tagMap'
       _buildCloud: function(app, response) {

        //title: '<<< Select a tag from the Tag Cloud - Building',
        var i, tag;
    for (i=0;i<response.Results.length;i++) {
        tag = response.Results[i];

        if(typeof app.tagMap[tag.ObjectID] !== "undefined") {
        app.tagMap[tag.ObjectID].Name = tag._refObjectName;
        }
    }
    if(response.StartIndex+response.PageSize < response.TotalResultCount) {
        app._queryForTagNames(response.StartIndex+response.PageSize, app, app._buildCloud);
    } else {
        if(app.tagMap.length === 0) {
        tag = new Ext.form.Label({
            id: 'tagNone',
            text: '  No tagged Stories found  '
            });
            app.down('#cloud').add(tag);
        } else {
        var minFrequency = Number.MAX_VALUE;
        var maxFrequency = Number.MIN_VALUE;
        var tuples = [];
        for (var x in app.tagMap) {
            if (app.tagMap.hasOwnProperty(x)) {
            tuples.push([x, app.tagMap[x]]);
            if(app.tagMap[x].count > maxFrequency) {
                maxFrequency = app.tagMap[x].count;
            }
            if(app.tagMap[x].count < minFrequency) {
                minFrequency = app.tagMap[x].count;
            }
            }
        }

        tuples.sort(function(a,b) { a = a[1]; b = b[1]; return a.Name > b.Name ? 1 : a.Name < b.Name ? -1 : 0 ;});

        for (i = 0; i < tuples.length; i++) {
            var ftsize = ((tuples[i][1].count-minFrequency)*(app.maxFont-app.minFont) / (maxFrequency-minFrequency)) + app.minFont;
            tag = new Ext.form.Label({
            id: 'tag'+tuples[i][0],
            text: '  ' + tuples[i][1].Name + '  ',
            overCls: 'link',
            style:"font-size: "+ftsize+"pt;",
            listeners: { scope: app, render: app._renderTag }
            });
            app.down('#cloud').add(tag);
        }
        }
        app.getComponent('cloud').setLoading(false);
    }
       },

       // collects the _queryForTags responses and calls _queryForTagNames when it has them all
       _buildTagMap: function(app, response)  {
    for (var i=0;i<response.Results.length;i++) {
        var ent = response.Results[i];
        for (var j=0; j < ent.Tags.length; j++) {
        var tag = ent.Tags[j];
        var mapent = app.tagMap[tag];
        if(typeof mapent === "undefined") {
            mapent = { count: 1 };
        } else {
            mapent.count++;
        }
        app.tagMap[tag] = mapent;
        }
    }
    if(response.StartIndex+response.PageSize < response.TotalResultCount) {
        app._queryForTags(response.StartIndex+response.PageSize, app, app._buildTagMap);
    } else {
        app._queryForTagNames(0, app, app._buildCloud);
    }
       },

       // get a list of the tags from the Lookback API, iterating if necessary (see _buildTagMap)
       _queryForTags: function(start, app, callback) {
    var params = {
        find: "{'Tags':{'$exists':true}, '__At':'current', '_Type':'HierarchicalRequirement', '_ProjectHierarchy':"+ this.getContext().getProject().ObjectID +" }",
        fields: "['Tags']",
        pagesize: 20000,
        start: start
    };
    Ext.Ajax.request({
        url: 'https://rally1.rallydev.com/analytics/v2.0/service/rally/workspace/'+ this.context.getWorkspace().ObjectID + '/artifact/snapshot/query.js',
        method: 'GET',
        params: params,
        withCredentials: true,
        success: function(response){
        var text = response.responseText;
        var json = Ext.JSON.decode(text);
        callback(app, json);
        }
    });
       },

       // once all the tags have been collected, get a list of the tag names from the WSAPI, iterating if necessary (see _buildCloud)
       _queryForTagNames: function(start, app, callback) {
    Ext.Ajax.request({
        url: 'https://rally1.rallydev.com/slm/webservice/1.41/tag.js',
        method: 'GET',
        params: { fetch: "ObjectID", pagesize: 200, "start": start},
        withCredentials: true,
        success: function(response){
        callback(app, Ext.JSON.decode(response.responseText).QueryResult);
        }
    });
       },

       _queryForStories: function(tagOid) {
    Ext.create('Rally.data.WsapiDataStore', {
        model: 'UserStory',
        autoLoad: true,
        fetch: ['Rank', 'FormattedID', 'Name', 'ScheduleState'],
        filters: [{ 
        property:'Tags',
        operator: '=',
        value: "tag/" + tagOid
        }],
        sorters: [{
        property: 'Rank',
        direction: 'ASC'
        }],
        listeners: {
        load: this._onDataLoaded,
        scope: this
        }
    });
       },

       _tagSelected: function(app, elem) {
    this.getComponent('grid').setLoading();
    this._queryForStories(elem.id.substring(3)); // cheesy, id is "tag"+tagOid, we need the oid
    this.tagName = elem.innerText;
       },

       _onDataLoaded: function(store, data) {
    var records = [], rankIndex = 1;
    Ext.Array.each(data, function(record) {
        records.push({
        Ranking: rankIndex,
        FormattedID: record.get('FormattedID'),
        Name: record.get('Name'),
        State: record.get('ScheduleState')
        });
        rankIndex++;
    });

    var customStore = Ext.create('Rally.data.custom.Store', {
        data: records,
        pageSize: 25
    });

    if(!this.grid) {
        this.grid = this.down('#grid').add({
        xtype: 'rallygrid',
        store: customStore,
        columnCfgs: [
            { text: 'Ranking', dataIndex: 'Ranking' },
            { text: 'ID', dataIndex: 'FormattedID' },
            { text: 'Name', dataIndex: 'Name', flex: 1 },
            { text: 'State', dataIndex: 'State' }
        ]
        });
    } else {
        this.grid.reconfigure(customStore);
    }
    this.getComponent('grid').setTitle('Stories tagged: ' + this.tagName);
    this.getComponent('grid').setLoading(false);
       },

       launch: function() {
    this._queryForTags(0, this, this._buildTagMap);
       }
   });

Rally.launchApp('CustomApp', {
name: 'TagCloud'
});
 });
</script>

<style type="text/css">
  .app {

  }

  .link {
    color: #066792;
    cursor: pointer;
  } </style>
</head>
<body></body>
</html>
4

1 回答 1

2

对于最近的 LBAPI 更改,该代码已经过时 - 特别是 _Type 与 _TypeHierarchy 的使用,当然还有 url,正如您已经发现的那样。请拿起更改并试一试。

于 2013-03-20T19:10:12.530 回答