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

Axis Range support for JSON config #1155

Open
davidjb opened this issue Oct 30, 2023 · 4 comments
Open

Axis Range support for JSON config #1155

davidjb opened this issue Oct 30, 2023 · 4 comments
Labels
enhancement Feature request

Comments

@davidjb
Copy link

davidjb commented Oct 30, 2023

Looking at https://www.amcharts.com/docs/v5/concepts/serializing/ and the source code, it appears that defining Axis Ranges in JSON isn't currently supported. Having this ability would be very useful in declaratively defining charts, in the same way the parser currently does for other aspects of charts.

For note, I'm in the process of arranging a paid licence, just raising this here to ascertain if it's on the roadmap or if I've missed anything.

@martynasma martynasma added the enhancement Feature request label Oct 30, 2023
@martynasma
Copy link
Collaborator

What type of axis range are you trying to implement?

Is it simple guides/bands, or related to series?

@davidjb
Copy link
Author

davidjb commented Oct 31, 2023

There's three different types of axis ranges I'm looking at, each for different use cases:

  1. Guides (either a single value or with endValue), with a label
  2. Series axis range (for adjusting appearance in 1 dimension)
  3. Multi-axes range (for adjusting appearance on 2 dimensions - e.g. points in a certain region or quadrant of an XY scatter)

I understand the latter isn't supported by axis ranges since they're relative to a single axis or series. The data-based Bullet configuration (https://www.amcharts.com/docs/v5/concepts/common-elements/bullets/#selectively-displaying-bullets) looks sufficient from a JavaScript perspective, but I'll have to look at adding something like an expression language to be able to parse logic out of a JSON chart configuration.

@martynasma
Copy link
Collaborator

Thanks.

None of those are available or can be easily implemented right now.

Axis ranges require special series/axis methods to be created, so it would need special handling in JSON parser.

I'm marking as a feature request, but can't provide any ETA or even promise that this will be implemented.

JSON parser in amCharts 5 was never meant as a 100% replacement for procedural code.

@davidjb
Copy link
Author

davidjb commented Nov 1, 2023

Thanks @martynasma - very much understand and I appreciate your consideration. 👍

I've implemented a workaround for use cases 1 and 2 with the following, noting that it's very much not feature-complete for everything axes ranges can do, only does basic color parsing of specific properties, and is specifically written for config where properties xAxes and yAxes values are set as #refs. Still, it might be useful for someone:

//chart.json
...
"xAxis": {
  "type": "ValueAxis",
  "settings": {
    "min": 0,
    "max": 100,
    "renderer": {
      "type": "AxisRendererX"
    }
  },
  "axisRanges": [
    {
      "range": {
        "value": 75,
        "endValue": 100
      },
      "elements": {
        "grid": {
          "stroke": "#000",
          "strokeOpacity": 0.5,
          "strokeWidth": 3
        },
        "axisFill": {
          "fill": "#00f"
        },
        "label": {
          "fill": "#060",
          "text": "75",
          "fontWeight": 500,
          "location": 0
        }
      }
    }
  ]
}
...
// chart.js
const config = JSON.parse(cfg);
const chart = await parser.parse(, { parent: root.container });

function resolveRef(ref) {
  const refId = ref.split('#')[1];
  return config.refs.findLast(obj => !!obj[refId])[refId];
}

['xAxes', 'yAxes'].forEach(axesId => {
  chart[axesId].each((axis, i) => {
    const axisData = resolveRef(config.properties[axesId][i]);
    axisData?.axisRanges.forEach(ar => {
      const rangeDataItem = axis.makeDataItem(ar.range);
      axis.createAxisRange(rangeDataItem);
      if (ar?.elements?.grid) {
        if (ar?.elements?.grid?.stroke) {
          ar.elements.grid.stroke = am5.color(ar.elements.grid.stroke);
        }
        rangeDataItem.get('grid').setAll(ar?.elements?.grid);
      }
      if (ar?.elements?.axisFill) {
        if (ar?.elements?.axisFill?.fill) {
          ar.elements.axisFill.fill = am5.color(ar.elements.axisFill.fill);
        }
        rangeDataItem.get('axisFill').setAll({ ...ar?.elements?.axisFill, visible: true });
      }
      if (ar?.elements?.label) {
        if (ar?.elements?.label?.fill) {
          ar.elements.label.fill = am5.color(ar.elements.label.fill);
        }
        rangeDataItem.get('label').setAll(ar.elements.label);
      }
    });
  });

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

No branches or pull requests

2 participants