【问题标题】:C3js: How to move and rotate grid line text?C3js:如何移动和旋转网格线文本?
【发布时间】:2018-10-26 01:04:20
【问题描述】:

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

Add x grid lines

Style x grid lines

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

如何使用 CSS 或其他方法:

(a) 将网格线文本移动到网格线的另一侧?

(b) 将文本顺时针旋转 90 度,然后向左、向右等移动?

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

【问题讨论】:

  • 我不是专家,但通过 c3/grid.js 的源代码快速搜索字符串 'rotat' 显示仅对名为 'axis_rotated' 的变量的引用。我由此假设引用此属性的所有代码都集中在轴旋转上,而不是单个网格线文本元素的文本旋转。
  • @VanquiishedWombat。是的,我也找不到移动文本的选项。如果有的话,我唯一的希望是通过 CSS。选择器 .c3-xgrid-line text 应用于此文本。
  • 好的 - 所以你准备好接受我猜的 JS 解决方案。一点点调查让我认为我们需要处理旋转(简单)但也要处理旋转点。不过应该是可行的。
  • react-c3.js 没有 onrendered() 事件吗?在第一次渲染图表后触发。我问的原因是要重新旋转文本,您需要计算和转换旋转原点,然后应用旋转。我认为所需的计算在固定 css 中没有得到很好的支持,甚至是不可能的。 onrendered() 选项将允许在程序 JS 中使用 DOM 操作,这将有更好的成功机会和跨浏览器操作。
  • 如果可以的话,我会多次支持这个问题,谢谢你的提问。

标签: css c3.js


【解决方案1】:

这是一种可能的方法。图表的 onrendered() 事件用于运行一些使用 d3.js(在使用 c3.js 时已经存在)的 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>

【讨论】:

  • 如果可以的话,我会多次支持这个答案,谢谢你的回答。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-12-26
  • 1970-01-01
  • 1970-01-01
  • 2021-10-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多