C3js:如何移动和旋转网格线文本?
C3js: How to move and rotate grid line text?
可以向 C3js 图表添加网格线,如下页所示:
上面的第二个 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>
可以向 C3js 图表添加网格线,如下页所示:
上面的第二个 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>