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

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

问题描述

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

<小时>

脚本

//圆角Chart.pluginService.register({afterUpdate:函数(图表){if (chart.config.options.elements.arc.roundedCornersFor !== undefined) {var arc = chart.getDatasetMeta(0).data[chart.config.options.elements.arc.roundedCornersFor];圆弧 = {x: (chart.chartArea.left + chart.chartArea.right)/2,y: (chart.chartArea.top + chart.chartArea.bottom)/2,半径:(chart.outerRadius + chart.innerRadius)/2,厚度:(chart.outerRadius - chart.innerRadius)/2 - 1,背景颜色:arc._model.backgroundColor}}},afterDraw:函数(图表){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);控制台日志(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:函数(图表){如果(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);如果(centerConfig.fontSize)var fontSize = centerConfig.fontSize;//找出最佳字体大小,如果没有指定别的 {ctx.save();var fontSize = helpers.getValueOrDefault(centerConfig.minFontSize, 1);var maxFontSize = helpers.getValueOrDefault(centerConfig.maxFontSize, 256);var maxText = helpers.getValueOrDefault(centerConfig.maxText, centerConfig.text);做 {ctx.font = helpers.fontString(fontSize, fontStyle, fontFamily);var textWidth = ctx.measureText(maxText).width;//检查它是否合适,是否在配置的限制范围内,并且我们不是简单地来回切换if (textWidth < chart.innerRadius * 2 && fontSize < maxFontSize)字体大小 += 1;别的 {//反转最后一步字体大小 -= 1;休息;}} 而(真)ctx.restore();}//保存属性图表中心 = {字体:helpers.fontString(fontSize, fontStyle, fontFamily),填充样式:helpers.getValueOrDefault(centerConfig.fontColor, globalConfig.defaultFontColor)};}},afterDraw:函数(图表){如果(图表中心){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 = '中心';ctx.textBaseline = '中间';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();}},})

然后

<代码> ...选项: {元素:{弧:{圆角为:0},中央: {//可能出现在中心的最长文本maxText: '100%',文字:'67%',fontColor: '#FF6684',fontFamily: "'Helvetica Neue', 'Helvetica', 'Arial', sans-serif",fontStyle: '正常',//字体大小:12,//如果未指定 fontSize,我们将缩放(在以下限制内)maxText 以占据中心的最大空间//如果这些都没有指定,我们默认为 1 和 256最小字体大小:1,最大字体大小: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天全站免登陆