amcharts / amcharts4

The most advanced amCharts charting library for JavaScript and TypeScript apps.
https://www.amcharts.com/
1.16k stars 322 forks source link

With the Fill Adapter, the active state doesn't work. #4408

Closed kindunq closed 4 months ago

kindunq commented 4 months ago

Question

 const series = chart.seriesTemplates.create("1");
  if (series.tooltip) {
    series.tooltip.disabled = true;
  }

  series.columns.template.column.adapter.add("fill", function (fill, target) {
    if (target.dataItem) {
      return am4core.color("#b8180d");
    }
    return fill;
  });

const template = series.columns.template;

const activeState = template.states.create("active");

activeState.properties.fill = am4core.color("#000");

template.events.on("hit", function (ev) {
        const target = ev.target;
        if (target.dataItem) {
          target.isActive = !target.isActive;
        }
      });

This should not be done, and

 const series = chart.seriesTemplates.create("1");
  if (series.tooltip) {
    series.tooltip.disabled = true;
  }

const template = series.columns.template;

const activeState = template.states.create("active");

activeState.properties.fill = am4core.color("#000");

template.events.on("hit", function (ev) {
        const target = ev.target;
        if (target.dataItem) {
          target.isActive = !target.isActive;
        }
      });

This will work

How do I fix it? T_T

please help me..

Environment (if applicable)

Additional context

martynasma commented 4 months ago

Adapter will always take precedence over anything else, including states.

You may need to update your adapter code to check if target element is active before overriding the fill color.

  series.columns.template.column.adapter.add("fill", function (fill, target) {
    if (target.dataItem && !target.isActive) {
      return am4core.color("#b8180d");
    }
    return fill;
  });
kindunq commented 4 months ago

Adapter will always take precedence over anything else, including states.

You may need to update your adapter code to check if target element is active before overriding the fill color.

  series.columns.template.column.adapter.add("fill", function (fill, target) {
    if (target.dataItem && !target.isActive) {
      return am4core.color("#b8180d");
    }
    return fill;
  });

omg....

still not working..

just one look as my code

https://codepen.io/kin-dunq/pen/yLWmrpP

The code you recommended is line 96 ~ 101

martynasma commented 4 months ago

OK, so the issue is because you set adapter on series.columns.template.column whereas adapters (and everything else on series.columns.template. This is why the target.isActive does not take proper value in the adapter.

kindunq commented 4 months ago

OK, so the issue is because you set adapter on series.columns.template.column whereas adapters (and everything else on series.columns.template. This is why the target.isActive does not take proper value in the adapter. Ah, I see.

But if you install the fill adapter on series.columns.template

it doesn't work if I install the fill adapter on series.columns.template.

So I installed it in series.columns.template.column.

Sorry I still don't understand

kindunq commented 4 months ago

OK, so the issue is because you set adapter on series.columns.template.column whereas adapters (and everything else on series.columns.template. This is why the target.isActive does not take proper value in the adapter.

Instead, I did something else

template.events.on("ready", function (ev) { ....})

https://codepen.io/kin-dunq/pen/yLWmrpP

applied to line 134 in the link

thank you always

And it's too hard to use & customize amchart

@martynasma