labelAll = document.querySelectorAll('.g2-label-customize')
,但移入的当前的柱图的下标是所有数据中的某一个,这样就会有冲突(比如:移入的当前的柱图,下标是3,但在当前label下可能是0)import React from 'react';
import G2 from '@antv/g2';
import Slider from '@antv/g2-plugin-slider';
import DataSet from '@antv/data-set';
class Silder extends React.Component {
constructor(props) {
super(props)
this.state = {
}
}
componentDidMount() {
this.fun()
}
fun() {
let mIndex;//当前移入的下标
let startIndex = 0;//起始下标
let endIndex = 4;//终止下标
const data = [
{
index: 0, type: 'a', type1: 'b', type2: 'c', country: '巴西', value: 18203, value1: 1820 },
{
index: 1, type: 'a', type1: 'b', type2: 'c', country: '印尼', value: 23489, value1: 2349 },
{
index: 2, type: 'a', type1: 'b', type2: 'c', country: '美国', value: 29034, value1: 2934 },
{
index: 3, type: 'a', type1: 'b', type2: 'c', country: '印度', value: 104970, value1: 14970 },
{
index: 4, type: 'a', type1: 'b', type2: 'c', country: '中国', value: 131744, value1: 31744 },
{
index: 5, type: 'a', type1: 'b', type2: 'c', country: '加拿大', value: 11203, value1: 1320 },
{
index: 6, type: 'a', type1: 'b', type2: 'c', country: '塞尔维亚', value: 143489, value1: 12349 },
{
index: 7, type: 'a', type1: 'b', type2: 'c', country: '伦敦', value: 20034, value1: 21934 },
{
index: 8, type: 'a', type1: 'b', type2: 'c', country: '泰国', value: 14970, value1: 1470 },
{
index: 9, type: 'a', type1: 'b', type2: 'c', country: '巴基斯坦', value: 0, value1: 21744 },
];
let nums = []//value的所有值
data.forEach(item => {
nums.push(item.value)
})
let maxNum = 0;//最大值
maxNum = Math.max(...nums) + 1
data.forEach(item => {
item.value2 = maxNum
})
const ds = new DataSet({
state: {
from: data[0].index,
to: data[4].index
}
})
const dv = ds.createView();
dv.source(data)
.transform({
type: 'filter',//过滤条件,与滑块联动进行chart展示
callback: obj => {
// console.log(obj);
return obj.index >= ds.state.from && obj.index <= ds.state.to
}
});
const chart = new G2.Chart({
container: 'container',
forceFit: true,
height: 320,
padding: [40, 60, 70, 90]
})
const view1 = chart.view()
view1.source(dv)
view1.scale('value', {
min: Math.min(...nums),
max: Math.max(...nums) + 1
})
view1.interval().position('country*value').color('type').tooltip('country*value*value1*value2', function (country, value, value1, value2) {
// console.log(country, value, value1, 'ccc');
return {
value: !value ? '--' : value,
value1: !value1 ? '--' : value1,
value2: !value2 ? '--' : value2
}
}).label('country*value', function (country, value) {
return {
useHtml: true,
htmlTemplate: function htmlTemplate(text, item) {
return (
`` +
value +
" "
);
},
// offset: 10,
}
})
const view2 = chart.view()
view2.source(dv)
//triangle 三角形
view2.point().position('country*value1').color('type1', 'orange').shape('triangle').size(7).style({
lineWidth: 0
})
view2.axis('value1', {
position: 'right',
grid: null
})
view2.tooltip(false)
const view3 = chart.view()
view3.source(dv)
view3.scale('value2', {
min: Math.min(...nums),
max: Math.max(...nums) + 1
})
view3.interval().position('country*value2').color('transparent')
view3.axis('value2', false)
view3.tooltip(false)
chart.on('interval:mouseenter', ev => {
mIndex = dv.origin.slice(startIndex, endIndex + 1).findIndex(item => item.country === ev.data._origin.country
)
let labelAll = document.querySelectorAll('.g2-label-customize');
labelAll[mIndex].style.color = 'red';
})
chart.on('interval:mouseleave', ev => {
let labelAll = document.querySelectorAll('.g2-label-customize');
labelAll[mIndex].style.color = '#b3f';
})
//使用辅助文本来设置坐标上方的单位
chart.guide().text({
top: true,
position: ['start', 'end'],
content: '(万m²)',
style: {
fill: '#000',
fontSize: '12'
},
offsetX: -40,
offsetY: -20
})
chart.guide().text({
top: true,
position: ['end', 'end'],
content: '(月)',
style: {
fill: '#000',
fontSize: '12'
},
offsetX: 15,
offsetY: -20
})
//设置tooltip
chart.tooltip({
// title: 'year',
containerTpl: '' + '' + '
' + '', // tooltip的外层模板
itemTpl:
`
a(万m²){value}
b(月){value1}
`,
offset: 50,
'g2-tooltip': {
position: 'absolute',
width: '160px',
backgroundColor: '#fff',
color: '#000',
padding: '5px 15px',
fontSize: '12px',
'transition': 'top 200ms,left 200ms'
}
});
chart.render()
//滑块
const slider = new Slider({
container: 'silder',
padding: [60],
height: 15,
start: data[0].country,//声明滑动条起始滑块的位置对应的数据值
end: data[4].country,//声明滑动条结束滑块的位置对应的数据值
data,//原始数据data不是转换后的数据dv
xAxis: 'country',//x轴对应的字段
yAxis: 'value1',//y轴对应的字段
fillerStyle: {
//选中区域的样式配置,默认配置如下:
fill: 'red',
fillOpacity: 0.4
},
backgroundChart: {
//slider 整体背景样式。
type: 'line',
color: 'rgba(0, 0, 0, 0.3)',
fill: 'yellow'
},
textStyle: {
//slider 辅助文本字体样式配置。
fill: 'orange'
},
backgroundStyle: {
fill: 'blue'
},
onChange: ({
startText, endText }) => {
//当滑动条滑块发生变化时,触发该回调函数,主要用于更新 ds 的状态量。该回调函数会提供一个参数,该参数是一个对象,包含如下属性:const { startValue, endValue, startText, endText } = obj;
console.log(startText, endText);
//过滤的时候判断条件是数值类型即下标,但为了在滑块两端展示文字,需要将'start','end'那边改成对应的起始终止文字,但又会出现新的问题,就是在onChange里面打印的startText和endText也为相应的文字而不是下标,考虑着在变化的时候需要将变化的下标赋值给ds里面的from和to,不然chart图表不再展示,就需要进行遍历判断一下,找到文字下对应的下标,然后赋值给from和to
//dv.rows的数据是实时变化的,所以不能拿dv.rows数据做判断条件,拿原始的数据dv.origin或者data做判断
let startRows = dv.origin.filter(item => item.country === startText)
let endRows = dv.origin.filter(item => item.country === endText)
startIndex = startRows[0].index
endIndex = endRows[0].index
// !!! 更新状态量
ds.setState('from', startIndex);
ds.setState('to', endIndex);
}
});
slider.render();
}
render() {
return (
<div>
<div id='container'></div>
<div id='silder'></div>
</div >
)
}
}
export default Silder