Рассчитать отступы для горизонтальных гистограмм C3 js - PullRequest
0 голосов
/ 21 апреля 2020

Основано на моей старой проблеме: C3 js обрезаны метки горизонтальной гистограммы и проблема с размером Сейчас я пытаюсь вычислить необходимое заполнение для оси y на основе ширины текста, используя текстовую ширину контекста холста .

const colors = ['#0065A3', '#767670', '#D73648', '#7FB2CE', '#00345B'];


const data= [
['veryveryveryveryverylongdatalabel01', 439034],
['veryveryveryveryverylongdatalabel02', 413664],
['veryveryveryveryverylongdatalabel03', 351376],
['veryveryveryveryverylongdatalabel04', 349932],
['veryveryveryveryverylongdatalabel05', 316490],
['veryveryveryveryverylongdatalabel06', 315039],
['veryveryveryveryverylongdatalabel07', 285908],
['veryveryveryveryverylongdatalabel08', 285681],
['veryveryveryveryverylongdatalabel09', 285215],
['veryveryveryveryverylongdatalabel10', 203248],
['veryveryveryveryverylongdatalabel11', 200508],
['veryveryveryveryverylongdatalabel12', 195508],
['veryveryveryveryverylongdatalabel13', 195058],
['veryveryveryveryverylongdatalabel14', 193508],
['veryveryveryveryverylongdatalabel15', 185508],
['veryveryveryveryverylongdatalabel16', 180508],
['veryveryveryveryverylongdatalabel17', 177508]
];

let totalDataValue = 0
data.forEach(function(d){
	totalDataValue+=d[1];
});
let maxLabelWidth = 0;
/**
* Measures the rendered width of arbitrary text given the font size and font face
* @param {string} text The text to measure
* @param {number} fontSize The font size in pixels
* @param {string} fontFace The font face ("Arial", "Helvetica", etc.)
* @returns {number} The width of the text
		     **/
function getWidth(text, font) {
  const canvas = document.createElement('canvas'),
        context = canvas.getContext('2d');
  context.font = font;
  return context.measureText(text).width;
}

//TODO get font fpr c3-text from CSS 
const font = '10px sans-serif'
data.forEach(function(d){
	//formatted string
  const label = d[0] + ": " + d3.format(",.0f")(d[1]) + " ["+d3.format(".2%")(d[1]/totalDataValue)+"]"; 
	maxLabelWidth = Math.max(maxLabelWidth, getWidth(label, font));
});
var C3Styles = null;

const chart1 = c3.generate({
  bindto: d3.select('#chart1'),
  data: {
    columns: data,
    type: 'bar',
    labels: {format : function(v, id) {return id + ": " + d3.format(",.0f")(v) + " ["+d3.format(".2%")(v/totalDataValue)+"]"; }}
  },
  bar: {
  	width: { ratio: 1}
  },
  legend: {
    show: false,
  },
  tooltip: {
    show: true,
    format: {
      value: function(value) {
        return d3.format(",.0f")(value);
      }
    }
  },
  zoom: {
    enabled: true
  },
  axis: {
    x: {
      show:false,
      type:'category',
      categories: ['value1']
    },
    y: {
      show:false,
        padding : {
            top: Math.ceil(maxLabelWidth)
        }
    },
    rotated: true
  }
  });
#chart1 {
  width: 600px;
  height: 400px;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/c3/0.7.15/c3.min.css" rel="stylesheet" />
<script src="https://d3js.org/d3.v5.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/c3/0.7.15/c3.min.js"></script>
<div id="chart1" class "c3">

</div>

Осталось две проблемы: во-первых, расчетная ширина текста немного меньше ширины текстового элемента SVG, хотя нет интервал, отступы и др. c. Как получить ширину SVG-элемента на основе длины текста?

Во-вторых, даже если значение будет рассчитано правильно, рассчитанная ширина текста кажется слишком низкой для использования для оси. значение y.padding.top. Чего мне не хватает?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...