【问题标题】:Can I specify a different font size for each row of text in Chart Title?我可以为图表标题中的每一行文本指定不同的字体大小吗?
【发布时间】:2019-09-06 18:31:40
【问题描述】:

我使用的是 Chart.js 版本:2.7.3

我的图表标题有三行。我想让第一行字体大小为 16,然后第二个 14 和第三个 12。我不确定这是否可能并且还没有找到方法。

这是我的代码的一部分,它定义了我的图表的选项...

options: {
    title: {
        display: true,
        // Supply the title as an array and each array index prints on a separate line in the title section
        text: ['My Chart','Last Month', 'Local Time'],
        fontSize: 16,
        callbacks: {
            drawTitle: function(pt, vm, ctx, opacity) {
                    console.log("title.length: " + title.length);
                    var title = vm.title;

                    if (title.length) {
                        ctx.textAlign = vm._titleAlign;
                        ctx.textBaseline = 'top';

                        var titleFontSize = vm.titleFontSize;
                        var titleSpacing = vm.titleSpacing;

                        ctx.fillStyle = mergeOpacity(vm.titleFontColor, opacity);
                        ctx.font = helpers.fontString(titleFontSize, vm._titleFontStyle, vm._titleFontFamily);

                        var i, len;
                        for (i = 0, len = title.length; i < len; ++i) {
                            ctx.fillText(title[i], pt.x, pt.y);
                            pt.y += titleFontSize + titleSpacing; // Line Height and spacing

                            if (i + 1 === title.length) {
                                pt.y += vm.titleMarginBottom - titleSpacing; // If Last, add margin, remove spacing
                            }
                        }
                    }
                }
            }
        },

我知道您可以指定“fontSize”,但这适用于图表标题中的所有文本。我想为每一行文本使用不同的字体大小。我尝试指定回调,但在签入 Chrome F12 开发工具时没有看到 console.log() 消息。

Chart.js 中有没有办法为图表标题中的每一行指定不同的字体大小?

谢谢!

解决方案更新

我接受了 Edi Carlos 的回答,因为它提供了有关如何将格式化文本附加到画布元素的有用建议,并且这可以在 Chart.js 动画回调中完成。

我的图表是启用了工具提示的散点图。使用公认的解决方案,将鼠标悬停在绘图点上时,fillText 可能会消失或更改屏幕上的位置。我发现如果我使用 F12 Chrome 开发工具,文本也会消失。在接受的答案中的 jsfiddle 中也会发生同样的情况...如果您启用工具提示...尝试将鼠标悬停在条形图上或按 F12。

要在将鼠标悬停在 ToolTip 上时阻止 fillText 移动位置,我发现我必须指定:

ctx.textBaseline = 'top';
ctx.textAlign = 'center';

为了阻止 fillText 在按下 F12 时消失,我发现我必须使用绝对位置设置画布元素的 CSS 样式。

#canvas{
    position:absolute;
}

这是我的 Chart.js 选项中的一段代码,显示了如何为 Chart.js 图表标题中的每一行文本指定不同的字体大小和样式:

options: {
    animation: {
        onProgress: function(animation) {
            ctx.textBaseline = 'top';
            ctx.textAlign = 'center';

            // Set the font size and text position for the 2nd row in the Chart title
            ctx.font = "bold 14px 'Helvetica Neue', Helvetica, Arial, sans-serif";
            ctx.fillStyle = "#666";
            ctx.fillText("Last 24 Hours", 610, 32);

            // Set the font size and text position for the 3rd row in the Chart title
            ctx.font = "bold 12px 'Helvetica Neue', Helvetica, Arial, sans-serif";
            ctx.fillStyle = "#666";
            ctx.fillText("Local Time | Limit=None", 610, 53);
        }
    },      
    title: {
        display: true,
        text: ['Sensor Chart','             ', '                         '],
        fontSize: 16
        }
    }

Chart.js 允许您提供一个字符串数组作为标题。然后每个数组索引打印在单独的行上。我在文本中留了空格:[] 数组索引 1 和 2,所以图表标题中会有空格来定位 ctx.fillText()。

建议添加到 Chart.js

总的来说,这仍然是一种略显老套的方式。我认为 Chart.js 应该有一个更集成的解决方案。就像您可以指定多个 y 轴一样,每个 y 轴都有自己的属性:

yAxes: [
        {
            id: 'A',
            ..
            ..
        },
        {
            id: 'B',
            ..
            ..
        }
    ]

如果您可以为图表标题中的多行指定样式,那就太好了:

title: {
    display: true,
    titleRows: [
            {
                id: 'A',
                text: 'Row1',
                fontSize: 16,
                ..
            },
            {
                id: 'B',
                text: 'Row2',
                fontSize: 14,
                ..
            },
            {
                id: 'C',
                text: 'Row3',
                fontSize: 12,
                ..
            }
        ]
    }

【问题讨论】:

    标签: javascript chart.js


    【解决方案1】:

    您可以使用 fillText() 方法 使用 Chart.js 版本:2.7.3

    使用 fillText() 在画布上写入 "Network!""Stackoverflow"(带有渐变):

    var c = document.getElementById("myCanvas");
    var ctx = c.getContext("2d");
    
    ctx.font = "20px Georgia";
    ctx.fillText("Network", 10, 50);
    
    ctx.font = "30px Verdana";
    // Create gradient
    var gradient = ctx.createLinearGradient(0, 0, c.width, 0);
    gradient.addColorStop("0"," magenta");
    gradient.addColorStop("0.5", "blue");
    gradient.addColorStop("1.0", "red");
    // Fill with gradient
    ctx.fillStyle = gradient;
    ctx.fillText("Stackoverflow", 10, 90);
    

    fillText() 方法在画布上绘制填充文本。文本的默认颜色是黑色。 使用 font 属性指定字体和字体大小,并使用 fillStyle 属性以另一种颜色/渐变呈现文本。

    我的Fiddle 示例

    更新 ->您可以使用动画回调(onProgress 或 onComplete)来执行此操作,例如:

    options: {
            animation: {
                onProgress: function(animation) {
                    // code above
                }
            }
        }
    

    更新 2 -> 完整代码

    var ctx = document.getElementById('myChart').getContext('2d');
    var myChart = new Chart(ctx, {
        type: 'bar',
        data: {
            labels: ['Red', 'Blue', 'Yellow', 'Green', 'Purple', 'Orange'],
            datasets: [{
                data: [2, 2, 3, 5, 2, 3],
                backgroundColor: [
                    'rgba(255, 99, 132, 0.2)',
                    'rgba(54, 162, 235, 0.2)',
                    'rgba(255, 206, 86, 0.2)',
                    'rgba(75, 192, 192, 0.2)',
                    'rgba(153, 102, 255, 0.2)',
                    'rgba(255, 159, 64, 0.2)'
                ],
                borderColor: [
                    'rgba(255, 99, 132, 1)',
                    'rgba(54, 162, 235, 1)',
                    'rgba(255, 206, 86, 1)',
                    'rgba(75, 192, 192, 1)',
                    'rgba(153, 102, 255, 1)',
                    'rgba(255, 159, 64, 1)'
                ],
                borderWidth: 1
            }]
        },
        options: {
        tooltips: {
             enabled: false
        },
          legend: {
              display: false
          },
            scales: {
                yAxes: [{
                    ticks: {
                        beginAtZero: true
                    }
                }]
            },
            animation: {
                onProgress: function(animation) {
                    var c = document.getElementById("myChart");
                    var ctx = c.getContext("2d");
    
                    ctx.font = "20px Georgia";
                    ctx.fillText("1 - Network", 45, 30);                
    
                    ctx.font = "30px Verdana";
                    // Create gradient
                    var gradient = ctx.createLinearGradient(0, 0, c.width, 0);
                    gradient.addColorStop("0", "magenta");
                    gradient.addColorStop("0.5", "blue");
                    gradient.addColorStop("1.0", "red");
                    // Fill with gradient
                    ctx.fillStyle = gradient;
                    ctx.fillText("2 - Stackoverflow", 45, 70);                
                }
            }
        }
    });
    

    完整的Fiddle

    希望对你有帮助!

    【讨论】:

    • 谢谢你。好吧,它没有回答我的问题,但它很有用。但是它对我不起作用。我可以将我的文本放置在图表画布上,并使用 fillText 和 fillStyle 为我的文本设置颜色,但是 ctx.font 没有任何效果。例如:ctx.font = "bold 26px";什么也没做。实际上字体大小采用 Chart.js 选项中指定的大小... title{fontSize:16}。你能帮我吗?如果不是,也许我会使用 CSS 并在标题区域放置一个跨度!
    • 您可以使用动画回调(onProgress 或 onComplete)。我更新了我的答案,您可以使用您的代码并进行测试!更改回调类型!在我的回答中,fontSize 适用于几行!您可以在标签位置添加边距和填充
    • 感谢您的帮助,Edi。我接受了您的解决方案并更新了我的问题,展示了我如何使用您的信息来解决我的问题。
    【解决方案2】:

    使用 ChartJS 字幕选项:

    var ctx = document.getElementById('chart').getContext('2d');
    var cfg = {
      type: 'bar',
      data: {
        labels: [1,2,3,4,5],
        datasets: [{label:'Frequency',data:[36,23,72,43,27]}]
      },
      options: {
        responsive: true,
        plugins: {
          title: {
            display: true,
            text: 'Chart Title',
            padding: {
              top: 10,
              bottom: 5
            },
            font: {
              size: 16
            }
          },
          subtitle: {
            display: true,
            text: 'Chart Subtitle',
            padding: {
              top: 0,
              bottom: 30
            },
            font: {
              size: 10,
              weight: 'bold'
            }
          }
        }
      }
    };
    var chart = new Chart(ctx, cfg);
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.5.1/chart.min.js"></script>
    
    <canvas id="chart"></canvas>

    【讨论】:

      猜你喜欢
      • 2010-12-14
      • 1970-01-01
      • 2014-09-15
      • 2012-06-16
      • 1970-01-01
      • 1970-01-01
      • 2012-11-14
      • 2017-02-11
      • 1970-01-01
      相关资源
      最近更新 更多