0

谁能告诉我如何在 extjs 的饼图中为标签和图例提供不同的字段?我有一个商店,有两个字段,名称,值。我想在图例中显示名称字段,在标签中显示值字段。现在我为 labe1 和 legend 获得了相同的值。

谢谢

4

4 回答 4

2

像这样配置label饼系列的属性:

label: {
    // name of the model field to use as legend
    field: 'name'
    ,renderer: function(value, label, storeItem) {
        // storeItem is your model, so return the value you want as label
        return storeItem.get('value');
    }
}

编辑:

前面的代码只适用于 Ext 4.2 以后。要将它与 4.1 一起使用,您必须重写Ext.chart.series.Pie#onPlaceLabel()方法来替换行:

    label.setAttributes({
        text: format(storeItem.get(field[index]))
    }, true);

有了这些,来自 Ext4.2 代码:

    label.setAttributes({
        text: format(storeItem.get(field), label, storeItem, item, i, display, animate, index)
    }, true);

编辑 2:如何覆盖 Ext 4.1

在 Ext 4 中覆盖类的语法与扩展类的语法相同,只是您使用override代替extend. 覆盖类被命名,就像任何其他类一样。为了加载覆盖,您必须像普通类一样需要它(如果您不使用 Ext Loader,则必须将文件包含在脚本标记中。

现在,这里的代码将使值渲染器以与 Ext4.2 相同的方式工作:

// Again, you're free to chose the class name, just ensure the Loader can find the file
// (and don't forget to require it!)
Ext.define('MyApp.Ext.char.series.Pie', {
    override: 'Ext.chart.series.Pie'

    ,onPlaceLabel: function(label, storeItem, item, i, display, animate, index) {
        var me = this,
            chart = me.chart,
            resizing = chart.resizing,
            config = me.label,
            format = config.renderer,
            field = [].concat(config.field),
            centerX = me.centerX,
            centerY = me.centerY,
            middle = item.middle,
            opt = {
                x: middle.x,
                y: middle.y
            },
            x = middle.x - centerX,
            y = middle.y - centerY,
            from = {},
            rho = 1,
            theta = Math.atan2(y, x || 1),
            dg = theta * 180 / Math.PI,
            prevDg;

        opt.hidden = false;

        if (this.__excludes && this.__excludes[i]) {
            opt.hidden = true;
        }

        function fixAngle(a) {
            if (a < 0) {
                a += 360;
            }
            return a % 360;
        }

        label.setAttributes({
            // Removed:
            // text: format(storeItem.get(field[index]))
            // Added:
            text: format(storeItem.get(config.field), label, storeItem, item, i, display, animate, index)
        }, true);

        switch (display) {
            case 'outside':
                rho = Math.sqrt(x * x + y * y) * 2;
                //update positions
                opt.x = rho * Math.cos(theta) + centerX;
                opt.y = rho * Math.sin(theta) + centerY;
                break;

            case 'rotate':
                dg = fixAngle(dg);
                dg = (dg > 90 && dg < 270) ? dg + 180: dg;

                prevDg = label.attr.rotation.degrees;
                if (prevDg != null && Math.abs(prevDg - dg) > 180 * 0.5) {
                    if (dg > prevDg) {
                        dg -= 360;
                    } else {
                        dg += 360;
                    }
                    dg = dg % 360;
                } else {
                    dg = fixAngle(dg);
                }
                //update rotation angle
                opt.rotate = {
                    degrees: dg,
                    x: opt.x,
                    y: opt.y
                };
                break;

            default:
                break;
        }
        //ensure the object has zero translation
        opt.translate = {
            x: 0, y: 0
        };
        if (animate && !resizing && (display != 'rotate' || prevDg != null)) {
            me.onAnimate(label, {
                to: opt
            });
        } else {
            label.setAttributes(opt, true);
        }
        label._from = from;
    }
});

如您所见,我不得不复制粘贴整个方法代码。我不喜欢这样,因为这使我们在很大程度上暴露于未来版本中的任何代码更改,但是没有其他可能的方法来更改我所针对的代码位。

在现实生活中,为了防范这种风险,我会添加版本检查并在 Ext 版本大于 4.1 时发出警告:

// Using a function instead of a raw object, in order to run some code at the time of class definition
Ext.define('MyApp.Ext.char.series.Pie', function() {
    if (Ext.getVersion().isGreaterThanOrEqual('4.2')) {
        Ext.Logger.warn('This override is rendered useless since Ext4.2');
        return {};
    } else {
        return {
            override: 'Ext.chart.series.Pie'

            ,onPlaceLabel: function(label, storeItem, item, i, display, animate, index) {
                var me = this,
                    chart = me.chart,
                    resizing = chart.resizing,
                    config = me.label,
                    format = config.renderer,
                    field = [].concat(config.field),
                    centerX = me.centerX,
                    centerY = me.centerY,
                    middle = item.middle,
                    opt = {
                        x: middle.x,
                        y: middle.y
                    },
                    x = middle.x - centerX,
                    y = middle.y - centerY,
                    from = {},
                    rho = 1,
                    theta = Math.atan2(y, x || 1),
                    dg = theta * 180 / Math.PI,
                    prevDg;

                opt.hidden = false;

                if (this.__excludes && this.__excludes[i]) {
                    opt.hidden = true;
                }

                function fixAngle(a) {
                    if (a < 0) {
                        a += 360;
                    }
                    return a % 360;
                }

                label.setAttributes({
                    // Removed:
                    // text: format(storeItem.get(field[index]))
                    // Added:
                    text: format(storeItem.get(config.field), label, storeItem, item, i, display, animate, index)
                }, true);

                switch (display) {
                    case 'outside':
                        rho = Math.sqrt(x * x + y * y) * 2;
                        //update positions
                        opt.x = rho * Math.cos(theta) + centerX;
                        opt.y = rho * Math.sin(theta) + centerY;
                        break;

                    case 'rotate':
                        dg = fixAngle(dg);
                        dg = (dg > 90 && dg < 270) ? dg + 180: dg;

                        prevDg = label.attr.rotation.degrees;
                        if (prevDg != null && Math.abs(prevDg - dg) > 180 * 0.5) {
                            if (dg > prevDg) {
                                dg -= 360;
                            } else {
                                dg += 360;
                            }
                            dg = dg % 360;
                        } else {
                            dg = fixAngle(dg);
                        }
                        //update rotation angle
                        opt.rotate = {
                            degrees: dg,
                            x: opt.x,
                            y: opt.y
                        };
                        break;

                    default:
                        break;
                }
                //ensure the object has zero translation
                opt.translate = {
                    x: 0, y: 0
                };
                if (animate && !resizing && (display != 'rotate' || prevDg != null)) {
                    me.onAnimate(label, {
                        to: opt
                    });
                } else {
                    label.setAttributes(opt, true);
                }
                label._from = from;
            }
        };
    }
}()); // the define function must be executed manually with overrides (this is documented in the API)
于 2013-05-30T15:28:51.693 回答
1

这应该适用于 Ext 4.0

new Ext.chart.Chart({
  store: store, 
  series: [{
    type: 'pie',
    field: 'value',
    label: {
        field: 'name',
        renderer: function(value){
            Ext.each(store.data.items, function(item){
                if(item.data.name == value) {
                    value = item.data.value;
                }
            });
            return value;
        }
    }
  }],
  ... 

存储数据如下所示:

[{"name":"series1","value":5},{"name":"series2","value":7}]
于 2014-12-18T16:25:02.137 回答
1
I don't know whether it is against the copyright law or not 

我对你所做的任何事情概不负责。但它会起作用

step 1 

open  touch/src/chart/series/pie.js file 

step 2
 add one property to this file  (like legendLabel:null,)
step 3 
 Edit method  provideLegendInfo: function (target) . and change 
 labelField = this.getLabelField(), to
 labelField = this.getLegendLabel()
step 4<br>
Add new property to series you create in your file to show pie chart


    series: [
                    {
                        type: 'pie',
                        legendLabel :'name',
                        xField: 'value',                        
                        labelField: 'value',

}]


promote  this answer if you find this is helpful 
thank u
于 2013-08-02T07:29:59.960 回答
0

我有一种方法可以使用 rendererFn (精灵)分别在图例和 PIE 上显示两个不同的标签。在这里您不需要编辑 JS 文件。

在“系列”部分的“标签”类别下,使用“字段”显示 LEGEND 文本,并在渲染器函数中使用值作为输出以将值返回到饼图上。

系列:[{类型:'pie',字段:'value',甜甜圈:25,
showInLegend:true,

        label: {
            field: 'name',
            renderer: {rendererFn},
            display: 'inside'
        }
        ,renderer: function(sprite, config, rendererData, index) {
            return { text: {rendererFn}(window.dataJSON[index]['value']) };
        }
}]

这就足够了。

于 2014-01-30T10:28:05.420 回答