antvis/G2

数据绑定chart和子标记的数据会互相干扰 #4710

Stephenzcc posted onGitHub

官方例子的https://g2.antv.antgroup.com/zh/examples/general/dual#line-bar 如果把其中的interval标记的data更改为下面这种形式,按照官方的定义,line会使用chart的数据,而interval会使用自己的数据 image chart .interval() .data([ { time: '10:10', call: 4, waiting: 2, people: 2 }, { time: '10:15', call: 2, waiting: 6, people: 3 }, { time: '10:30', call: 5, waiting: 2, people: 3 }, ]) .encode('x', 'time') .encode('y', 'waiting') .axis('y', { titleFill: '#5B8FF9', title: 'Waiting' }); 但实际情况是他们会互相干扰 image


这个可以理解为interval的x轴和line的x轴总长度一样导致的错误吗 还有这个例子https://g2.antv.antgroup.com/examples/annotation/annotation/#line-range 把其中的point改成interval也会出问题 image

posted by Stephenzcc about 2 years ago

第一个问题是,interval 和 line 默认推断的 x 比例尺 domain 不符合预期。有两种解决办法可以达到以下的效果:

image

第一种显示指定 x 比例尺的 domain。

import { Chart } from '@antv/g2';

const data = [
  { time: '10:10', call: 4, waiting: 2, people: 2 },
  { time: '10:15', call: 2, waiting: 6, people: 3 },
  { time: '10:20', call: 13, waiting: 2, people: 5 },
  { time: '10:25', call: 9, waiting: 9, people: 1 },
  { time: '10:30', call: 5, waiting: 2, people: 3 },
  { time: '10:35', call: 8, waiting: 2, people: 1 },
  { time: '10:40', call: 13, waiting: 1, people: 2 },
];

const chart = new Chart({
  container: 'container',
  autoFit: true,
});

// 显示指定 x 比例尺的定义域
chart.data(data).scale('x', { domain: data.map((d) => d.time) });

chart
  .interval()
  .data([
    { time: '10:10', call: 4, waiting: 2, people: 2 },
    { time: '10:15', call: 2, waiting: 6, people: 3 },
    { time: '10:30', call: 5, waiting: 2, people: 3 },
  ])
  .encode('x', 'time')
  .encode('y', 'waiting')
  .axis('y', { titleFill: '#5B8FF9', title: 'Waiting' });

chart
  .line()
  .encode('x', 'time')
  .encode('y', 'people')
  .encode('shape', 'smooth')
  .style('stroke', '#fdae6b')
  .style('lineWidth', 2)
  .scale('y', { independent: true })
  .axis('y', {
    position: 'right',
    grid: null,
    title: 'People',
    titleFill: '#fdae6b',
  });

chart.render();

第二种,指定 x 比例尺的排序方法。因为 x 通道的数据是离散数据,离散数据没有默认的排序方法,所以需要显式指定。

import { Chart } from '@antv/g2';

const data = [
  { time: '10:10', call: 4, waiting: 2, people: 2 },
  { time: '10:15', call: 2, waiting: 6, people: 3 },
  { time: '10:20', call: 13, waiting: 2, people: 5 },
  { time: '10:25', call: 9, waiting: 9, people: 1 },
  { time: '10:30', call: 5, waiting: 2, people: 3 },
  { time: '10:35', call: 8, waiting: 2, people: 1 },
  { time: '10:40', call: 13, waiting: 1, people: 2 },
];

const chart = new Chart({
  container: 'container',
  autoFit: true,
});

// 显示指定 x 的排序规则
const minute = (d) => +d.split(':').pop();
chart.data(data).scale('x', { compare: (a, b) => minute(a) - minute(b) });

chart
  .interval()
  .data([
    { time: '10:10', call: 4, waiting: 2, people: 2 },
    { time: '10:15', call: 2, waiting: 6, people: 3 },
    { time: '10:30', call: 5, waiting: 2, people: 3 },
  ])
  .encode('x', 'time')
  .encode('y', 'waiting')
  .axis('y', { titleFill: '#5B8FF9', title: 'Waiting' });

chart
  .line()
  .encode('x', 'time')
  .encode('y', 'people')
  .encode('shape', 'smooth')
  .style('stroke', '#fdae6b')
  .style('lineWidth', 2)
  .scale('y', { independent: true })
  .axis('y', {
    position: 'right',
    grid: null,
    title: 'People',
    titleFill: '#fdae6b',
  });

chart.render();
posted by pearmini about 2 years ago

第二个问题是因为 interval 只于离散数据(Point 是离散和连续数据都适用),但是 Date 对象不是离散数据。所以解决办法是不转换成 Date 对象,并且指定排序方法。

image

import { Chart } from '@antv/g2';

const chart = new Chart({
  container: 'container',
  height: 360,
  paddingLeft: 60,
});

chart.data({
  type: 'fetch',
  value: 'https://assets.antv.antgroup.com/g2/year-population.json',
});

// 排序
chart.scale('x', { compare: (a, b) => +a - +b });

chart
  .rangeX()
  .data([
    { year: ['1933', '1945'], event: 'Nazi Rule' },
    { year: ['1948', '1989'], event: 'GDR (East Germany)' },
  ])
  .encode('x', 'year')
  .encode('color', 'event')
  .scale('color', { independent: true, range: ['#FAAD14', '#30BF78'] })
  .style('fillOpacity', 0.75);

chart
  .line()
  .encode('x', 'year')
  .encode('y', 'population')
  .encode('color', '#333');

chart
  .interval()
  .encode('x', 'year')
  .encode('y', 'population')
  .encode('color', '#333')
  .style('lineWidth', 1.5);

chart.render();
posted by pearmini about 2 years ago

哦哦明白了,感谢

posted by Stephenzcc about 2 years ago

Fund this Issue

$0.00
Funded

Pull requests