C3js:如何移动和旋转网格线文本?

C3js: How to move and rotate grid line text?

可以向 C3js 图表添加网格线,如下页所示:

Add x grid lines

Style x grid lines

上面的第二个 link 显示了如何设置网格线的样式。

如何使用 CSS 或其他方法:

(a)将网格线文字移动到网格线的另一边?

(b) 将文字顺时针旋转90度,左右移动等?

更新:我正在使用 React-c3js,所以我不能简单地 select 一个 SVG 元素并对其进行变换和旋转(因此建议使用 CSS)。

这是一个可能的方法。图表的 onrendered() 事件用于 运行 某些使用 d3.js 的 JS(在您使用 c3.js 时已经存在)来定位网格线文本并根据需要对其进行操作.见红色文字 'Label 2' 和 'LABEL4'.

我对 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>