Skip to content

Commit

Permalink
Version 5.9.0
Browse files Browse the repository at this point in the history
  • Loading branch information
martynasma committed Apr 9, 2024
1 parent 75575aa commit fe09b74
Show file tree
Hide file tree
Showing 56 changed files with 2,315 additions and 981 deletions.
2 changes: 1 addition & 1 deletion package.json
@@ -1,7 +1,7 @@
{
"private": true,
"name": "@amcharts/amcharts5",
"version": "5.8.7",
"version": "5.9.0",
"author": "amCharts <contact@amcharts.com> (https://www.amcharts.com/)",
"description": "amCharts 5",
"homepage": "https://www.amcharts.com/",
Expand Down
33 changes: 33 additions & 0 deletions packages/shared/CHANGELOG.md
Expand Up @@ -5,6 +5,39 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/).
Please note, that this project, while following numbering syntax, it DOES NOT
adhere to [Semantic Versioning](http://semver.org/spec/v2.0.0.html) rules.

## [5.9.0] - 2024-04-09

### Added
- `zoomToDataItems(dataItems, rotate)` method added to `MapPolygonSeries`.
- Bigger hit circle added to Stock charts drawings bullets, which becomes visible when hovered.
- A public method `markDirtyKey()` added. Could be used to trigger an adapter.
- A "Reset to default" link added to `StockChart`'s settings modal.
- New `StockChart`/`DrawingSeries` methods added related to drawing selection: `selectDrawing(id, keepSelection)`, `unselectDrawing(id)`, `unselectDrawings()`.
- New `StockChart`/`DrawingSeries` methods added related to drawing deletion: `deleteDrawing(id)`, `deleteSelectedDrawings()`.
- New `StockChart` events: `drawingadded`, `drawingremoved`, `drawingselected`, `drawingunselected`.
- New `DropdownListControl` methods: `getItemById(id)` and `setItemById(id)`.
- New `IconControl` methods: `getIconByPath(path)` and `setIconByPath(path)`.
- New drawing tools added to `StockChart`: "Triangle" and "Polyfill".

### Changed
- Improved handling of moving lines of an `XYCursor`. It will now move by one cell automatically, or by 5 cells if pressed together with `CTRL`.
- Improved styling of a color picker control in `StockChart`'s toolbar and settings modals.
- Drawing functionality was completely revamped: all drawings are now selectable, editable, movable, and can be deleted by selecting them and pressing `DEL`.
- Accessibility: Pressing SPACE when element with `role="checkbox"` set is focused, will now toggle it just like pressing ENTER.
- `pdfmake` updated to `0.2.10`.

### Fixed
- `Sprite` was not marking its bounds dirty when margins changed. It was causing layouts with margins not to be redrawn after margins changed.
- When drawing mode was enabled in a `StockChart` while in the percent scale, it used to reset scale to regular.
- `Tooltip` no longer overwrites user-provided `background`.
- `Treemap` was not redrawing when layout algorithm was changed dynamically.
- `Tooltip` position was not being updated when bounds of a `Sprite` changed.
- Moving line of an `XYCursor` with a keyboard press could result in an axis line to be out of sync with series tooltips.
- `tabindexOrder` was not working properly in some cases.
- Font family and font size controls were showing unnecessary "+" icon.
- In some rare cases setting value on an object / data item was not working.


## [5.8.7] - 2024-03-25

### Fixed
Expand Down
11 changes: 7 additions & 4 deletions src/.internal/charts/hierarchy/Treemap.ts
Expand Up @@ -163,9 +163,12 @@ export class Treemap extends Hierarchy {
}
if (algorithm) {
this._treemapLayout = d3hierarchy.treemap().tile(algorithm);
}
if (this._rootNode) {
this._updateNodes(this._rootNode);
this._updateVisuals();

const selectedDataItem = this.get("selectedDataItem") as DataItem<this["_dataItemSettings"]>;
if(selectedDataItem){
this._zoom(selectedDataItem);
}
}
}

Expand All @@ -179,7 +182,7 @@ export class Treemap extends Hierarchy {
if (this._rootNode) {
this._updateNodesScale(this._rootNode);
}
}
}
}

protected _updateVisuals() {
Expand Down
11 changes: 10 additions & 1 deletion src/.internal/charts/map/ClusteredPointSeries.ts
Expand Up @@ -21,6 +21,11 @@ export interface IClusteredDataItem extends IComponentDataItem {
* Bullet of clustered data item
*/
bullet?: Bullet;

/**
* An ID of a group.
*/
groupId?: string
}

export interface IClusteredPointSeriesDataItem extends IMapPointSeriesDataItem {
Expand Down Expand Up @@ -78,7 +83,7 @@ export interface IClusteredPointSeriesSettings extends IMapPointSeriesSettings {
*
* @see {@link https://www.amcharts.com/docs/v5/charts/map-chart/clustered-point-series/#Group_bullet} for more info
*/
clusteredBullet?: (root: Root, series: ClusteredPointSeries, dataItem: DataItem<IClusteredPointSeriesDataItem>) => Bullet | undefined;
clusteredBullet?: (root: Root, series: ClusteredPointSeries, dataItem: DataItem<IClusteredDataItem>) => Bullet | undefined;

/**
* If bullets are closer to each other than `scatterDistance`, they will be
Expand Down Expand Up @@ -266,6 +271,8 @@ export class ClusteredPointSeries extends MapPointSeries {
this.clusteredDataItems.push(clusteredDataItem)
}

let groupId;

$array.each(cluster, (dataItem) => {
dataItem.setRaw("cluster", clusteredDataItem);

Expand All @@ -284,12 +291,14 @@ export class ClusteredPointSeries extends MapPointSeries {
}
})
}
groupId = dataItem.get("groupId");
})

let averageX = sumX / len;
let averageY = sumY / len;

clusteredDataItem.setRaw("children" as any, cluster);
clusteredDataItem.setRaw("groupId", groupId);

const prevLen = clusteredDataItem.get("value" as any);
clusteredDataItem.setRaw("value" as any, len);
Expand Down
2 changes: 1 addition & 1 deletion src/.internal/charts/map/MapPointSeries.ts
Expand Up @@ -444,7 +444,7 @@ export class MapPointSeries extends MapSeries {
* @return Animation
* @since 5.5.6
*/
zoomToDataItems(dataItems: Array<DataItem<IMapPointSeriesDataItem>>, rotate?: boolean): Animation<any> | undefined {
public zoomToDataItems(dataItems: Array<DataItem<IMapPointSeriesDataItem>>, rotate?: boolean): Animation<any> | undefined {

let left: number | null = null;
let right: number | null = null;
Expand Down
63 changes: 62 additions & 1 deletion src/.internal/charts/map/MapPolygonSeries.ts
@@ -1,4 +1,5 @@
import type { DataItem } from "../../core/render/Component";
import type { Animation } from "../../core/util/Entity";

import { MapSeries, IMapSeriesSettings, IMapSeriesDataItem, IMapSeriesPrivate } from "./MapSeries";
import { MapPolygon } from "./MapPolygon";
Expand All @@ -7,7 +8,8 @@ import { ListTemplate } from "../../core/util/List";

import * as $array from "../../core/util/Array";
import * as $mapUtils from "./MapUtils";
import type { Animation } from "../../core/util/Entity";



export interface IMapPolygonSeriesPrivate extends IMapSeriesPrivate {
}
Expand Down Expand Up @@ -234,4 +236,63 @@ export class MapPolygonSeries extends MapSeries {
}
}
}

/**
* Zooms the map in so that all polygons in the array are visible.
*
* @param dataItems An array of data items to zoom to
* @param rotate Rotate the map so it is centered on the selected items
* @return Animation
* @since 5.9.0
*/
public zoomToDataItems(dataItems: Array<DataItem<IMapPolygonSeriesDataItem>>, rotate?: boolean): Animation<any> | undefined {
let left!: number;
let right!: number;
let top!: number;
let bottom!: number;

$array.each(dataItems, (dataItem) => {

const polygon = dataItem.get("mapPolygon");
if (polygon) {
const geometry = polygon.get("geometry");
if (geometry) {
let bounds = $mapUtils.getGeoBounds(geometry);

if (left == null) {
left = bounds.left;
}
if (right == null) {
right = bounds.right;
}
if (top == null) {
top = bounds.top;
}
if (bottom == null) {
bottom = bounds.bottom;
}

left = Math.min(bounds.left, left);
right = Math.max(bounds.right, right);
top = Math.max(bounds.top, top);
bottom = Math.min(bounds.bottom, bottom);
}
}
})

if (left != null && right != null && top != null && bottom != null) {
const chart = this.chart;
if (chart) {
if (rotate) {
const rx = left + (right - left) / 2;
const ry = bottom + (top - bottom) / 2;

chart.rotate(-rx, -ry);
return chart.zoomToGeoBounds({ left, right, top, bottom }, undefined, -rx, -ry);
}

return chart.zoomToGeoBounds({ left, right, top, bottom });
}
}
}
}
2 changes: 1 addition & 1 deletion src/.internal/charts/stock/PanelControls.ts
Expand Up @@ -104,7 +104,7 @@ export class PanelControls extends Container {
this.closeButton.events.on("click", () => {
const stockPanel = this.get("stockPanel");
stockPanel.close();
});
});

this.expandButton.events.on("click", () => {
const stockPanel = this.get("stockPanel");
Expand Down
58 changes: 55 additions & 3 deletions src/.internal/charts/stock/SettingsModal.ts
Expand Up @@ -20,6 +20,14 @@ export interface ISettingsModalSettings extends IModalSettings {
*/
stockChart: StockChart;

/**
* Show the "Reset to default" link?
*
* @default true
* @since 5.9.0
*/
showResetLink?: boolean;

}

export interface ISettingsModalPrivate extends IModalPrivate {
Expand Down Expand Up @@ -221,7 +229,22 @@ export class SettingsModal extends Modal {
table.className = "am5-modal-table";
content.appendChild(table);

// Log defaults
let populateDefaults = false;
let defaults: any = {};
if (!target.get("userData")) {
target.set("userData", {});
}
if (!target.get("userData")["__defaults"]) {
target.get("userData")["__defaults"] = defaults;
populateDefaults = true;
}
else {
defaults = target.get("userData")["__defaults"];
}

const settingInputs: { [index: string]: HTMLInputElement | HTMLSelectElement } = {};
const controls: { [index: string]: ColorControl } = {};
const settingsWithTarget: { [index: string]: any } = {};
let prevName = "";
let prevLine: HTMLDivElement;
Expand All @@ -230,6 +253,10 @@ export class SettingsModal extends Modal {
const keyTarget = setting.target || target;
const currentValue = setting.currentValue || keyTarget.get(setting.key);

if (populateDefaults) {
defaults[key] = currentValue;
}

if (setting.target) {
settingsWithTarget[key] = setting;
}
Expand Down Expand Up @@ -265,7 +292,9 @@ export class SettingsModal extends Modal {
}
break;
case "color":
element = this.getColor(setting, currentValue);
const control = this.getColor(setting, currentValue);
element = control.getPrivate("button")!;
controls[key] = control;
break;
case "checkbox":
element = this.getCheckbox(setting, currentValue);
Expand Down Expand Up @@ -303,6 +332,29 @@ export class SettingsModal extends Modal {
}
});

// Reset
if (this.get("showResetLink", true)) {
const resetLink = document.createElement("a");
resetLink.className = "am5-modal-link am5-modal-table-cell am5-modal-link-reset";
resetLink.innerHTML = this._root.language.translateAny("Reset to default");
table.appendChild(resetLink);

this._disposers.push($utils.addEventListener(resetLink, "click", () => {
const defaults = target.get("userData")["__defaults"];
$object.each(settingInputs, (key, element) => {
if (element.type === "checkbox") {
(element as HTMLInputElement).checked = defaults[key];
}
else {
element.value = defaults[key];
}
});
$object.each(controls, (key, control) => {
control.setColor(defaults[key]);
});
}));
}

// Buttons
const saveButton = document.createElement("input");
saveButton.type = "button";
Expand Down Expand Up @@ -427,7 +479,7 @@ export class SettingsModal extends Modal {
return element;
}

private getColor(setting: any, currentValue: any): HTMLDivElement {
private getColor(setting: any, currentValue: any): ColorControl {
const control = ColorControl.new(this.root, {
stockChart: this.get("stockChart"),
useOpacity: false
Expand All @@ -440,7 +492,7 @@ export class SettingsModal extends Modal {
};
});
this._disposers.push(control);
return control.getPrivate("button")!;
return control;
}

/**
Expand Down

0 comments on commit fe09b74

Please sign in to comment.