Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

自定义图例失效 #5364

Closed
daykalif opened this issue Aug 2, 2023 · 1 comment
Closed

自定义图例失效 #5364

daykalif opened this issue Aug 2, 2023 · 1 comment
Assignees

Comments

@daykalif
Copy link

daykalif commented Aug 2, 2023

image
解开任意part1或者part2部分,都会使自定义legend失效。(其中part1是用于增加x,y轴的中心线;part2是用于增加象限图背景区域划分)

复现代码:

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

const chart = new Chart({
  theme: 'classic',
  container: 'container',
});

const data = [
  { genre: 'Sports', sold: 275 },
  { genre: 'Strategy', sold: 115 },
  { genre: 'Action', sold: 120 },
  { genre: 'Shooter', sold: 350 },
  { genre: 'Other', sold: 150 },
];

const colorField = 'genre';

chart
  .interval()
  .data(data)
  .encode('x', 'genre')
  .encode('y', 'sold')
  .encode('color', colorField)
  .legend(false); // Hide built-in legends.

// part1注释
// chart.lineX().data([0]);
// chart.lineY().data([0]);



// part2注释
// chart
//   .range()
//   .data([
//     { x: [-25, 0], y: [-30, 0], region: '1' },
//     { x: [-25, 0], y: [0, 20], region: '2' },
//     { x: [0, 5], y: [-30, 0], region: '2' },
//     { x: [0, 5], y: [0, 20], region: '1' },
//   ])
//   .encode('x', 'x')
//   .encode('y', 'y')
//   .encode('color', 'region')
//   .scale('color', {
//     range: ['#d8d0c0', '#a3dda1'],
//     independent: true,
//     guide: null,
//   })
//   .style('fillOpacity', 0.2);

chart.render().then(renderCustomLegend);

function renderCustomLegend(chart) {
  // Get color scale.
  const scale = chart.getScaleByChannel('color');
  const { domain, range } = scale.getOptions();
  const excludedValues = [];

  // Create items from scale domain.
  const items = domain.map((text, i) => {
    const span = document.createElement('span');
    const color = range[i];

    // Items' style.
    span.innerText = text;
    span.style.display = 'inline-block';
    span.style.padding = '0.5em';
    span.style.color = color;
    span.style.cursor = 'pointer';

    span.onclick = () => {
      const index = excludedValues.findIndex((d) => d === text);
      if (index === -1) {
        excludedValues.push(text);
        span.style.color = '#aaa';
      } else {
        excludedValues.splice(index, 1);
        span.style.color = color;
      }
      onChange(excludedValues);
    };

    return span;
  });

  // Mount legend items.
  const container = document.getElementById('container');
  const canvas = container.getElementsByTagName('canvas')[0];
  const legend = document.createElement('legend');
  container.insertBefore(legend, canvas);
  for (const item of items) legend.append(item);

  // Emit legendFilter event.
  function onChange(values) {
    const selectedValues = domain.filter((d) => !values.includes(d));
    const selectedData = data.filter((d) =>
      selectedValues.includes(d[colorField]),
    );
    chart.changeData(selectedData);
  }
}
@ai-qing-hai
Copy link
Collaborator

ai-qing-hai commented Aug 2, 2023

@daykalif chart.changeData 会改变所有 chart 下 view 的 data, 而你改变的数据 唯一适用的是 第一个 interval, 尝试 changeData 的时候,不适用 chart 而是 对应的 mask 看看。

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

const chart = new Chart({
theme: 'classic',
container: 'container',
});

const data = [
{ genre: 'Sports', sold: 275 },
{ genre: 'Strategy', sold: 115 },
{ genre: 'Action', sold: 120 },
{ genre: 'Shooter', sold: 350 },
{ genre: 'Other', sold: 150 },
];

const colorField = 'genre';

const demo = chart
.interval()
.data(data)
.encode('x', 'genre')
.encode('y', 'sold')
.encode('color', colorField)
.legend(false); // Hide built-in legends.

// part1注释
chart.lineX().data([0]);
// chart.lineY().data([0]);

// part2注释
// chart
// .range()
// .data([
// { x: [-25, 0], y: [-30, 0], region: '1' },
// { x: [-25, 0], y: [0, 20], region: '2' },
// { x: [0, 5], y: [-30, 0], region: '2' },
// { x: [0, 5], y: [0, 20], region: '1' },
// ])
// .encode('x', 'x')
// .encode('y', 'y')
// .encode('color', 'region')
// .scale('color', {
// range: ['#d8d0c0', '#a3dda1'],
// independent: true,
// guide: null,
// })
// .style('fillOpacity', 0.2);

chart.render().then(renderCustomLegend);

function renderCustomLegend(chart) {
// Get color scale.
const scale = chart.getScaleByChannel('color');
const { domain, range } = scale.getOptions();
const excludedValues = [];
console.log(domain, 'doma1in');
// Create items from scale domain.
const items = domain.map((text, i) => {
const span = document.createElement('span');
const color = range[i];

// Items' style.
span.innerText = text;
span.style.display = 'inline-block';
span.style.padding = '0.5em';
span.style.color = color;
span.style.cursor = 'pointer';

span.onclick = () => {
  const index = excludedValues.findIndex((d) => d === text);
  if (index === -1) {
    excludedValues.push(text);
    span.style.color = '#aaa';
  } else {
    excludedValues.splice(index, 1);
    span.style.color = color;
  }
  console.log(excludedValues);
  onChange(excludedValues);
};

return span;

});

// Mount legend items.
const container = document.getElementById('container');
const canvas = container.getElementsByTagName('canvas')[0];
const legend = document.createElement('legend');
container.insertBefore(legend, canvas);
for (const item of items) legend.append(item);

// Emit legendFilter event.
function onChange(values) {
const selectedValues = domain.filter((d) => !values.includes(d));
const selectedData = data.filter((d) =>
selectedValues.includes(d[colorField]),
);
demo.changeData(selectedData);
}
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants