Chart.js甜甜圈圆边和文本居中 [英] Chart.js Doughnut with rounded edges and text centered

查看:659
本文介绍了Chart.js甜甜圈圆边和文本居中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试实现类似于本文






脚本

  //圆角
Chart.pluginService.register({
afterUpdate:function (chart){
if(chart.config.options.elements.arc.roundedCornersFor!== undefined){
var arc = chart.getDatasetMeta(0).data [chart.config.options.elements .arc.roundedCornersFor];
arc.round = {
x:(chart.chartArea.left + chart.chartArea.right)/ 2,
y:(chart.chartArea.top + chart。 chartArea.bottom)/ 2,
radius:(chart.outerRadius + chart.innerRadius)/ 2,
th ickness:(chart.outerRadius - chart.innerRadius)/ 2 - 1,
backgroundColor:arc._model.backgroundColor
}
}
},

afterDraw:function(chart){
if(chart.config.options.elements.arc.roundedCornersFor!== undefined){
var ctx = chart.chart.ctx;
var arc = chart.getDatasetMeta(0).data [chart.config.options.elements.arc.roundedCornersFor];
var startAngle = Math.PI / 2 - arc._view.startAngle;
var endAngle = Math.PI / 2 - arc._view.endAngle;

ctx.save();
ctx.translate(arc.round.x,arc.round.y);
console.log(arc.round.startAngle)
ctx.fillStyle = arc.round.backgroundColor;
ctx.beginPath();
ctx.arc(arc.round.radius * Math.sin(startAngle),arc.round.radius * Math.cos(startAngle),arc.round.thickness,0,2 * Math.PI);
ctx.arc(arc.round.radius * Math.sin(endAngle),arc.round.radius * Math.cos(endAngle),arc.round.thickness,0,2 * Math.PI);
ctx.closePath();
ctx.fill();
ctx.restore();
}
},
});

//写入文本插件
Chart.pluginService.register({
afterUpdate:function(chart){
if(chart.config.options.elements.center ){
var helpers = Chart.helpers;
var centerConfig = chart.config.options.elements.center;
var globalConfig = Chart.defaults.global;
var ctx = chart.chart.ctx;

var fontStyle = helpers.getValueOrDefault(centerConfig.fontStyle,globalConfig.defaultFontStyle);
var fontFamily = helpers.getValueOrDefault(centerConfig.fontFamily,globalConfig.defaultFontFamily);

if(centerConfig.fontSize)
var fontSize = centerConfig.fontSize;
//找出最佳字体大小(如果没有指定)
else {
ctx.save();
var fontSize = helpers.getValueOrDefault(centerConfig.minFontSize,1);
var maxFontSiz e = helpers.getValueOrDefault(centerConfig.maxFontSize,256);
var maxText = helpers.getValueOrDefault(centerConfig.maxText,centerConfig.text);

do {
ctx.font = helpers.fontString(fontSize,fontStyle,fontFamily);
var textWidth = ctx.measureText(maxText).width;

//检查它是否合适,是否在配置的限制内,并且我们不是简单地来回切换
if(textWidth< chart.innerRadius * 2&& fontSize< maxFontSize)
fontSize + = 1;
else {
//倒退上一步
fontSize - = 1;
休息;

} while(true)
ctx.restore();

$ b $ //保存属性
chart.center = {
字体:helpers.fontString(fontSize,fontStyle,fontFamily),
fillStyle:helpers .getValueOrDefault(centerConfig.fontColor,globalConfig.defaultFontColor)
};


afterDraw:function(chart){
if(chart.center){
var centerConfig = chart.config.options.elements.center;
var ctx = chart.chart.ctx;

ctx.save();
ctx.font = chart.center.font;
ctx.fillStyle = chart.center.fillStyle;
ctx.textAlign ='center';
ctx.textBaseline ='middle';
var centerX =(chart.chartArea.left + chart.chartArea.right)/ 2;
var centerY =(chart.chartArea.top + chart.chartArea.bottom)/ 2;
ctx.fillText(centerConfig.text,centerX,centerY);
ctx.restore();
}
},
})

然后 p>

  ... 
选项:{
元素:{
arc:{
roundedCornersFor:0
},
center:{
//可以出现在中心的最长文字
maxText:'100%',
text:'67 %',
fontColor:'#FF6684',
fontFamily:''Helvetica Neue','Helvetica','Arial',sans-serif,
fontStyle:'normal',
// fontSize:12,
//如果未指定fontSize,我们将缩放(在下限内)maxText占据中心的最大空间
//如果它们是未指定,我们默认为1和256
minFontSize:1,
maxFontSize:256,
}
}
}
};

如果你不希望它是通用的,你可以去掉一些代码。如果你修正了fontSize,如果你修复了索引等等)




小提琴 - http://jsfiddle.net/cd3fdoy9/


I am trying to achieve rounded corners similar to this article here, but combined with text in the centre, so far i have the code below, but i am not sure how to combine both ideas

Any help would be appreciated!

the image looks like below, donut with text image:

and my code is as follows to produce the text inside the donut.

Chart.types.Doughnut.extend({
   name: "DoughnutTextInside",
   showTooltip: function() {
       this.chart.ctx.save();
       Chart.types.Doughnut.prototype.showTooltip.apply(this, arguments);
       this.chart.ctx.restore();
},
draw: function() {
    Chart.types.Doughnut.prototype.draw.apply(this, arguments);

    var width = this.chart.width,
        height = this.chart.height;

    var fontSize = (height / 114).toFixed(2);
    this.chart.ctx.font = fontSize + "em Lato";
    this.chart.ctx.textBaseline = "middle";

    var text = "40%",
        textX = Math.round((width - this.chart.ctx.measureText(text).width) / 2),
        textY = height / 2;

    this.chart.ctx.fillText(text, textX, textY);
   }
});

var data = [{
   label: "Wins %",
   value: 120,
   color: "#2ecc71"
}, {
   label: "Losses %",
   value: 240,
   color: "#dddddd"
}, {
   value: 0,
   color: "#888888"
}];

var DoughnutTextInsideChart = new Chart($('#myChart')  [0].getContext('2d')).DoughnutTextInside(data, {
   responsive: true,
   segmentShowStroke: false,
   animationEasing: "easeInOutQuint",
});

解决方案

With v2.1.3, you can use the pluginService to do this


Preview


Script

// round corners
Chart.pluginService.register({
    afterUpdate: function (chart) {
        if (chart.config.options.elements.arc.roundedCornersFor !== undefined) {
            var arc = chart.getDatasetMeta(0).data[chart.config.options.elements.arc.roundedCornersFor];
            arc.round = {
                x: (chart.chartArea.left + chart.chartArea.right) / 2,
                y: (chart.chartArea.top + chart.chartArea.bottom) / 2,
                radius: (chart.outerRadius + chart.innerRadius) / 2,
                thickness: (chart.outerRadius - chart.innerRadius) / 2 - 1,
                backgroundColor: arc._model.backgroundColor
            }
        }
    },

    afterDraw: function (chart) {
        if (chart.config.options.elements.arc.roundedCornersFor !== undefined) {
            var ctx = chart.chart.ctx;
            var arc = chart.getDatasetMeta(0).data[chart.config.options.elements.arc.roundedCornersFor];
            var startAngle = Math.PI / 2 - arc._view.startAngle;
            var endAngle = Math.PI / 2 - arc._view.endAngle;

            ctx.save();
            ctx.translate(arc.round.x, arc.round.y);
            console.log(arc.round.startAngle)
            ctx.fillStyle = arc.round.backgroundColor;
            ctx.beginPath();
            ctx.arc(arc.round.radius * Math.sin(startAngle), arc.round.radius * Math.cos(startAngle), arc.round.thickness, 0, 2 * Math.PI);
            ctx.arc(arc.round.radius * Math.sin(endAngle), arc.round.radius * Math.cos(endAngle), arc.round.thickness, 0, 2 * Math.PI);
            ctx.closePath();
            ctx.fill();
            ctx.restore();
        }
    },
});

// write text plugin
Chart.pluginService.register({
    afterUpdate: function (chart) {
        if (chart.config.options.elements.center) {
            var helpers = Chart.helpers;
            var centerConfig = chart.config.options.elements.center;
            var globalConfig = Chart.defaults.global;
            var ctx = chart.chart.ctx;

            var fontStyle = helpers.getValueOrDefault(centerConfig.fontStyle, globalConfig.defaultFontStyle);
            var fontFamily = helpers.getValueOrDefault(centerConfig.fontFamily, globalConfig.defaultFontFamily);

            if (centerConfig.fontSize)
                var fontSize = centerConfig.fontSize;
                // figure out the best font size, if one is not specified
            else {
                ctx.save();
                var fontSize = helpers.getValueOrDefault(centerConfig.minFontSize, 1);
                var maxFontSize = helpers.getValueOrDefault(centerConfig.maxFontSize, 256);
                var maxText = helpers.getValueOrDefault(centerConfig.maxText, centerConfig.text);

                do {
                    ctx.font = helpers.fontString(fontSize, fontStyle, fontFamily);
                    var textWidth = ctx.measureText(maxText).width;

                    // check if it fits, is within configured limits and that we are not simply toggling back and forth
                    if (textWidth < chart.innerRadius * 2 && fontSize < maxFontSize)
                        fontSize += 1;
                    else {
                        // reverse last step
                        fontSize -= 1;
                        break;
                    }
                } while (true)
                ctx.restore();
            }

            // save properties
            chart.center = {
                font: helpers.fontString(fontSize, fontStyle, fontFamily),
                fillStyle: helpers.getValueOrDefault(centerConfig.fontColor, globalConfig.defaultFontColor)
            };
        }
    },
    afterDraw: function (chart) {
        if (chart.center) {
            var centerConfig = chart.config.options.elements.center;
            var ctx = chart.chart.ctx;

            ctx.save();
            ctx.font = chart.center.font;
            ctx.fillStyle = chart.center.fillStyle;
            ctx.textAlign = 'center';
            ctx.textBaseline = 'middle';
            var centerX = (chart.chartArea.left + chart.chartArea.right) / 2;
            var centerY = (chart.chartArea.top + chart.chartArea.bottom) / 2;
            ctx.fillText(centerConfig.text, centerX, centerY);
            ctx.restore();
        }
    },
})

and then

    ...
    options: {
        elements: {
            arc: {
                roundedCornersFor: 0
            },
            center: {
                // the longest text that could appear in the center
                maxText: '100%',
                text: '67%',
                fontColor: '#FF6684',
                fontFamily: "'Helvetica Neue', 'Helvetica', 'Arial', sans-serif",
                fontStyle: 'normal',
                // fontSize: 12,
                // if a fontSize is NOT specified, we will scale (within the below limits) maxText to take up the maximum space in the center
                // if these are not specified either, we default to 1 and 256
                minFontSize: 1,
                maxFontSize: 256,
            }
        }
    }
};

You can get rid of a bit of code if you don't want it to be generic (eg. if you fix the fontSize, if you fix the index to round, etc.)


Fiddle - http://jsfiddle.net/cd3fdoy9/

这篇关于Chart.js甜甜圈圆边和文本居中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆