Добавьте текст внутри кольцевой диаграммы в поле React-Chartjs-2, чтобы отреагировать

Я создал кольцевую диаграмму, которая работает правильно, но теперь мне нужно, например, показать число 45 в центре.

Где мне указать отображаемый текст и координаты? В опциях графика?

Я использую компонент React

class DoughnutChart extends React.Component {

  render() {
    const data = {
      datasets: [{
      data: [],
      backgroundColor: [
        '#999',
        '#eee'
      ]
    }],
     text: '45'
  };
    return (
       <Doughnut data = {data} />
    );
  }
};

export default DoughnutChart;

РЕДАКТИРОВАТЬ

Я нашел этот плагин, но не могу найти, как он применяется к компоненту реакции.

//Plugin for center text
Chart.pluginService.register({
  beforeDraw: function(chart) {
    var width = chart.chart.width,
    height = chart.chart.height,
    ctx = chart.chart.ctx;
    ctx.restore();
    var fontSize = (height / 160).toFixed(2);
    ctx.font = fontSize + "em sans-serif";
    ctx.textBaseline = "top";
    var text = "Foo-bar",
    textX = Math.round((width - ctx.measureText(text).width) / 2),
    textY = height / 2;
    ctx.fillText(text, textX, textY);
    ctx.save();
  }
});

Спасибо за вашу помощь.

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
3
0
7 627
5

Ответы 5

Из того, что я видел из реагировать-диаграмма js-2, он имеет только следующие свойства:

data: (PropTypes.object | PropTypes.func).isRequired,
width: PropTypes.number,
height: PropTypes.number,
id: PropTypes.string,
legend: PropTypes.object,
options: PropTypes.object,
redraw: PropTypes.bool,
getDatasetAtEvent: PropTypes.func,
getElementAtEvent: PropTypes.func,
getElementsAtEvent: PropTypes.func
onElementsClick: PropTypes.func, // alias for getElementsAtEvent (backward compatibility)

Ни один из них не похож на текст, который вы можете передать, чтобы показать свой номер посередине. Возможно, вы можете использовать опору легенды и манипулировать объектом, созданным для легенды, чтобы переместить его с помощью css, или иметь другой div внутри вашего рендера, который отображает число, а затем стилизует его так, чтобы он находился внутри диаграммы.

Другой способ сделать это - обернуть компонент Donut в div с другим дочерним элементом внутри этого div, содержащего текст, например:

    return( 
    <div className='wrapper'> 
        <div className='chart-number'>{this.state.text}</div>
        <Doughnut data = {data} />
    </div>)

в вашем css вам нужно будет выяснить, как разместить div с номером диаграммы в середине div-оболочки, которая будет содержать диаграмму.

Если вы только начинаете использовать эту библиотеку, возможно, поищите другую, которая соответствует вашим потребностям, чтобы вам не пришлось ее кодировать!

Надеюсь это поможет :)

РЕДАКТИРОВАТЬ 1:

Из того, что я вижу, вам, вероятно, нужно каким-то образом связать код Chart.pluginService.register с вашим графическим объектом, который является компонентом <Doughnut />, тогда он выполнит расчет перед перерисовкой.

Спасибо за ответ, может быть полезно. Я нашел плагин, который может это сделать. Я только что отредактировал свой вопрос. Не могли бы вы посмотреть его еще раз?

NelbeDG 31.10.2018 10:15

Я не верю, что в React Chart JS есть такая возможность. Однако существуют специальные плагины, которые позволяют вставлять пользовательские метки данных в кольцевые диаграммы. Пожалуйста, обратитесь к этой документации, чтобы узнать, как это сделать.

Таблицы данных плагина ChartJS

Большое спасибо, но я читал об этой библиотеке и думаю, что это тоже невозможно. Потому что мне нужно значение внутри диаграммы.

NelbeDG 31.10.2018 10:06

Я нашел плагин, который может это сделать. Я только что отредактировал свой вопрос. Не могли бы вы посмотреть его еще раз?

NelbeDG 31.10.2018 10:16

Вот простое решение:

Шаг 01:добавьте эти параметры в свои параметры

options: {
        centerText: {
            display: true,
            text: `90%`
        }
      .....
      .....

Шаг 02:Создайте новый метод drawInnerText

drawInnerText = (chart) => {

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

    ctx.restore();
    var fontSize = (height / 114).toFixed(2);
    ctx.font = fontSize + "em sans-serif";
    ctx.textBaseline = "middle";

    var text = chart.config.options.centerText.text,
        textX = Math.round((width - ctx.measureText(text).width) / 2),
        textY = height / 2;

    ctx.fillText(text, textX, textY);
    ctx.save();
}

Шаг 03: вызов drawInnerText

componentWillMount() {
        Chart.Chart.pluginService.register({
            beforeDraw: function (chart) {                    
                if (chart.config.options.centerText.display !== null &&
                    typeof chart.config.options.centerText.display !== 'undefined' &&
                    chart.config.options.centerText.display) {
                    this.drawInnerText(chart);
                }
            },
        });
    }

Я пробовал это, и это сработало

import { Doughnut } from "react-chartjs-2";

function DoughnutChart() {

 const data = {...}

 const options = {...}

 const plugins = [{
     beforeDraw: function(chart) {
      var width = chart.width,
          height = chart.height,
          ctx = chart.ctx;
          ctx.restore();
          var fontSize = (height / 160).toFixed(2);
          ctx.font = fontSize + "em sans-serif";
          ctx.textBaseline = "top";
          var text = "Foo-bar",
          textX = Math.round((width - ctx.measureText(text).width) / 2),
          textY = height / 2;
          ctx.fillText(text, textX, textY);
          ctx.save();
     } 
   }]



  return (
   
        <Doughnut 
          type = "doughnut" 
          data = {data} 
          options{options} 
          plugins = {plugins} 
         />
  );
}

export default DoughnutChart;

Не знаю почему, но в вашем ответе исправлена ​​проблема с пикселизацией текста.

Kundan 10.08.2021 18:09
function DoughnutChart({ data = {} }) {
 return (
   <Doughnut
     data = {format(dataObj)}
     plugins = {[
      {
        beforeDraw(chart) {
         const { width } = chart;
         const { height } = chart;
         const { ctx } = chart;
         ctx.restore();
         const fontSize = (height / 160).toFixed(2);
         ctx.font = `${fontSize}em sans-serif`;
         ctx.textBaseline = 'top';
         const { text } = "23";
         const textX = Math.round((width - ctx.measureText(text).width) / 2);
         const textY = height / 2;
         ctx.fillText(text, textX, textY);
         ctx.save();
       },
     },
   ]}
 />);

}

Другие вопросы по теме