C3js: Как перемещать и вращать текст линии сетки?

На диаграмму C3js можно добавить линии сетки, как показано на следующих страницах:

Добавить x линий сетки

Стиль линий сетки x

Вторая ссылка выше показывает, как стилизовать линии сетки.

Как бы с помощью CSS или другого метода:

(а) переместить текст линии сетки на другую сторону линии сетки?

(б) повернуть текст по часовой стрелке на 90 градусов и сдвинуть его влево, вправо и т. д.?

ОБНОВЛЕНИЕ: я использую React-c3js, поэтому я не могу просто выбрать элемент SVG, преобразовать и повернуть его (отсюда и предложение использовать CSS).

Я не эксперт, но быстрый поиск в источнике c3 / grid.js строки «rotat» показывает ссылки только на переменную с именем «axis_rotated». Из этого я предполагаю, что весь код, ссылающийся на этот атрибут, сфокусирован на вращении оси, а не на вращении текста отдельных текстовых элементов линии сетки.

Vanquished Wombat 26.10.2018 14:46

@VanquishedWombat. Да, мне тоже не удалось найти варианты перемещения текста. Моя единственная надежда, если таковая имеется, - через CSS. К этому тексту применяется селектор .c3-xgrid-line text.

Shafique Jamal 26.10.2018 17:05

хорошо - я думаю, вы готовы принять решение JS. Небольшое исследование заставляет меня думать, что нам нужно обрабатывать вращение (легко), но также обрабатывать точку вращения. Хотя должно быть выполнимо.

Vanquished Wombat 29.10.2018 14:24

У response-c3.js нет события onrendered ()? Это срабатывает после первой визуализации диаграммы. Причина, по которой я прошу, заключается в том, что для повторного поворота текста вам нужно будет вычислить и преобразовать начало вращения, а затем применить поворот. Я не думаю, что необходимые вычисления хорошо поддерживаются или даже возможны в фиксированном CSS. Опция onrendered () позволит использовать манипуляции с DOM в процедурном JS, что имеет гораздо больше шансов на успех и кроссбраузерность.

Vanquished Wombat 31.10.2018 08:02

Я бы проголосовал за этот вопрос еще раз, если бы мог, спасибо за вопрос.

Blair Connolly 06.06.2019 17:18
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Введение в CSS
Введение в CSS
CSS является неотъемлемой частью трех основных составляющих front-end веб-разработки.
Как выровнять Div по центру?
Как выровнять Div по центру?
Чтобы выровнять элемент <div>по горизонтали и вертикали с помощью CSS, можно использовать комбинацию свойств и значений CSS. Вот несколько методов,...
Навигация по приложениям React: Исчерпывающее руководство по React Router
Навигация по приложениям React: Исчерпывающее руководство по React Router
React Router стала незаменимой библиотекой для создания одностраничных приложений с навигацией в React. В этой статье блога мы подробно рассмотрим...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
CSS: FlexBox
CSS: FlexBox
Ранее разработчики использовали макеты с помощью Position и Float. После появления flexbox сценарий полностью изменился.
1
5
880
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вот возможный подход. Событие onrendered () диаграммы используется для запуска некоторого JS, который использует d3.js (уже присутствующий, поскольку вы используете c3.js) для нацеливания на текст линии сетки и манипулирования им по мере необходимости. См. Красный текст «Метка 2» и «МЕТКА 4».

Я провел разумное исследование решения CSS, но я пришел к выводу, что подход CSS будет проблематичным, поскольку интерфейс между атрибутами CSS и SVG несовместим на момент написания. Решение JS кажется жизнеспособным.

const { Component } = React;
const columns = [
  ['My Numbers', 30, 200, 100, 400, 150, 250],
  ['Your Numbers', 50, 20, 10, 40, 15, 25]
];

class Chart extends Component {
  componentDidMount() {
    this._updateChart();
  }
  componentDidUpdate() {
    this._updateChart();
  }
  _updateChart() {
    const chart = c3.generate({
      bindto: '#chart',
      size: { width: 400, height: 200},
      data: {
        columns: this.props.columns,
        type: this.props.chartType
      },
          grid: {
        x: {
            lines: [{value: 2, text: 'Label 2'}, {value: 4, text: 'LABEL 4'}]
        },
        y: {
            lines: [{value: 300, text: 'LABEL 300'}]
        }
    },
      onrendered:  function() {

        // for each svg element with the class 'c3-xgrid-line'
        d3.selectAll('.c3-xgrid-line').each(function(d, i){

          // cache the group node
          var groupNode = d3.select(this).node();         

          // for each 'text' element within the group 
          d3.select(this).select('text').each(function(d, i){
                        
            // hide the text to get size of group box otherwise text affects size.
            d3.select(this).attr("hidden",true); 

            // use svg getBBox() func to get the group size without the text - want the position
            var groupBx = groupNode.getBBox();

            d3.select(this)
              .attr('transform', null) // remove text rotation
              .attr('x', groupBx.x)   // x-offset from left of chart
              .attr('y', 0)          // y-offset of the text from the top of the chart 
              .attr('dx', 20)         // small x-adjust to clear the line
              .attr('dy', 15)         // small y-adjust to get onto the chart
              .attr("hidden", null)   // better make the text visible again
              .attr("text-anchor", null)  // anchor to left by default
              .style('fill', 'red');    // color it red for fun
            })
        })   
      }
    });
  }
  render() {
 
    
    return <div id = "chart">hi</div>;  
    
  }

}

class App extends Component {
  constructor(props) {
    super(props);
    this._setBarChart = this._setBarChart.bind(this);
    this._setLineChart = this._setLineChart.bind(this);
    this.state = {
      chartType: 'line'
    };
  }
  _setBarChart() {
    this.setState({ chartType: 'bar' });
  }
  _setLineChart() {
    this.setState({ chartType: 'line' });
  }
	render() {
		return (
      <div className = "app-wrap">
        <Chart 
          columns = {columns}
          chartType = {this.state.chartType} />
        <p>
          Chart Type
          <button onClick = {this._setBarChart}>bar</button> 
          <button onClick = {this._setLineChart}>Line</button>
        </p>
      </div>
    );
  }
}

ReactDOM.render(
	<App />,
    document.getElementById('app')
);
* {
  box-sizing: border-box;
}
body {
  background: #eee;
}
p {
  text-align: center;
}
button {
  margin-left: 1em;
  background: #159fff;
  border: none;
  padding: 0.5em 2em;
  color: white;
  text-transform: uppercase;

}

#chart {
  background: #fff;
}
<script src = "https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src = "https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<link href = "https://cdnjs.cloudflare.com/ajax/libs/c3/0.6.7/c3.min.css" rel = "stylesheet"/>
<script src = "https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<script src = "https://cdnjs.cloudflare.com/ajax/libs/c3/0.6.7/c3.min.js"></script>



<div class='chart-wrapper'>
<div id = "app"></div>
</div>

Я бы проголосовал за этот ответ еще раз, если бы мог, спасибо за ответ.

Blair Connolly 06.06.2019 17:18

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