@axdspub/axiom-charts 0.0.18 → 0.0.20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/library/Libraries/axiom/index.js +256 -19
- package/library/Libraries/axiom/index.js.map +1 -1
- package/library/axiom-charts.d.ts +15 -2
- package/library/browser.js.map +1 -1
- package/library/cjs.js.map +1 -1
- package/library/index.js.map +1 -1
- package/package.json +5 -3
- package/tailwind.config.js +12 -0
|
@@ -757,10 +757,225 @@ class AxiomScatter extends AxiomPlotRoot {
|
|
|
757
757
|
}
|
|
758
758
|
}
|
|
759
759
|
|
|
760
|
+
class AxiomBar extends AxiomPlotRoot {
|
|
761
|
+
constructor(props) {
|
|
762
|
+
super(props);
|
|
763
|
+
this.legendHeight = 12;
|
|
764
|
+
this.legendPaddingTop = 8;
|
|
765
|
+
const chart = this.chart;
|
|
766
|
+
const chartElements = chart.getChartElements();
|
|
767
|
+
if ((chartElements === null || chartElements === void 0 ? void 0 : chartElements.svg) !== undefined) {
|
|
768
|
+
chartElements.svg.style('z-index', 20);
|
|
769
|
+
// TODO find better way ^. Doing this so that svg can get events.
|
|
770
|
+
}
|
|
771
|
+
}
|
|
772
|
+
draw() {
|
|
773
|
+
var _a, _b, _c, _d, _e;
|
|
774
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
775
|
+
const dataResponse = yield this.getData();
|
|
776
|
+
const parsedData = (_a = dataResponse === null || dataResponse === void 0 ? void 0 : dataResponse.parsed) === null || _a === void 0 ? void 0 : _a.data;
|
|
777
|
+
if (parsedData === undefined)
|
|
778
|
+
return;
|
|
779
|
+
const xAccessor = this.getAccessorAtAxis('x');
|
|
780
|
+
const yAccessor = (_b = dataResponse.parsed) === null || _b === void 0 ? void 0 : _b.accessors.y;
|
|
781
|
+
if (xAccessor === undefined || yAccessor === undefined)
|
|
782
|
+
return;
|
|
783
|
+
const y2Accessor = (_c = dataResponse.parsed) === null || _c === void 0 ? void 0 : _c.accessors.y2;
|
|
784
|
+
const yGroups = this.dimensions;
|
|
785
|
+
const yKey = yGroups.y.property;
|
|
786
|
+
const yLabel = yGroups.y.label;
|
|
787
|
+
const y2Key = this.dimensions.y2.property;
|
|
788
|
+
const y2Label = this.dimensions.y2.label;
|
|
789
|
+
const chart = this.chart;
|
|
790
|
+
const chartElements = chart.getChartElements();
|
|
791
|
+
if (chartElements === undefined || chartElements.svg === null || yKey === undefined || yLabel === undefined)
|
|
792
|
+
return undefined;
|
|
793
|
+
if (chartElements.svg.select('g') !== undefined)
|
|
794
|
+
chartElements.svg.select('g').remove();
|
|
795
|
+
let { width, height } = chart.settings;
|
|
796
|
+
width = Number(width);
|
|
797
|
+
height = Number(height);
|
|
798
|
+
const oneOrZero = y2Key === undefined ? 0 : 1; // Used to add in space for y2 if exists.
|
|
799
|
+
const xAxisHeight = 48; // HOW TO GET DYNAMICALLY?
|
|
800
|
+
const yAxisWidth = 36; // HOW TO GET DYNAMICALLY?
|
|
801
|
+
const y2AxisWidth = yAxisWidth * oneOrZero;
|
|
802
|
+
const chartPaddingTop = 4;
|
|
803
|
+
const yLabelWidth = 24;
|
|
804
|
+
const y1TotalWidth = yAxisWidth + yLabelWidth;
|
|
805
|
+
const y2LabelWidth = yLabelWidth * oneOrZero;
|
|
806
|
+
const y2TotalWidth = y2AxisWidth * oneOrZero + y2LabelWidth;
|
|
807
|
+
const plotHeight = height - xAxisHeight - this.legendHeight - this.legendPaddingTop - chartPaddingTop;
|
|
808
|
+
const plotWidth = width - yAxisWidth - yLabelWidth - y2TotalWidth;
|
|
809
|
+
const plotXStart = width - plotWidth - y2TotalWidth;
|
|
810
|
+
const plotXEnd = width - y2TotalWidth;
|
|
811
|
+
const groups = parsedData.map(d => xAccessor(d));
|
|
812
|
+
const subgroups = [yKey];
|
|
813
|
+
if (y2Key !== undefined && y2Accessor !== undefined)
|
|
814
|
+
subgroups.push(y2Key);
|
|
815
|
+
// Colors
|
|
816
|
+
const fillColors = (_e = (_d = this.style) === null || _d === void 0 ? void 0 : _d.colors) !== null && _e !== void 0 ? _e : d3.schemeTableau10;
|
|
817
|
+
const color = d3.scaleOrdinal(fillColors).domain(subgroups);
|
|
818
|
+
// TODO use real data
|
|
819
|
+
// @ts-expect-error just for testing
|
|
820
|
+
this.emitDataLoad(parsedData, color);
|
|
821
|
+
const svg = chartElements.svg;
|
|
822
|
+
const g = svg.insert('g');
|
|
823
|
+
const x = this.getXScale(plotXStart, plotXEnd, groups);
|
|
824
|
+
const y = this.getYScale(plotHeight, chartPaddingTop, parsedData, yAccessor);
|
|
825
|
+
const y2 = this.getY2Scale(plotHeight, chartPaddingTop, parsedData, y2Accessor);
|
|
826
|
+
const subgroupScales = this.getSubgroupScales(yKey, y, y2Key, y2);
|
|
827
|
+
const xSubgroup = d3.scaleBand()
|
|
828
|
+
.domain(subgroups)
|
|
829
|
+
.range([0, x.bandwidth()])
|
|
830
|
+
.padding(0.05);
|
|
831
|
+
const onMouseEnterOrMove = (event, data) => {
|
|
832
|
+
if (this.chart.onScrub === undefined)
|
|
833
|
+
return;
|
|
834
|
+
const scrubPositions = {
|
|
835
|
+
[this.id]: {
|
|
836
|
+
xPosition: event.offsetX,
|
|
837
|
+
xValue: null,
|
|
838
|
+
yPosition: event.offsetY,
|
|
839
|
+
yValue: data.value
|
|
840
|
+
}
|
|
841
|
+
};
|
|
842
|
+
this.chart.onScrub(scrubPositions);
|
|
843
|
+
};
|
|
844
|
+
const onMouseLeave = () => {
|
|
845
|
+
if (this.chart.onScrubEnd === undefined)
|
|
846
|
+
return;
|
|
847
|
+
this.chart.onScrubEnd();
|
|
848
|
+
};
|
|
849
|
+
// Make Bar Groups
|
|
850
|
+
g.append('g')
|
|
851
|
+
.attr('width', plotWidth)
|
|
852
|
+
.attr('height', plotHeight)
|
|
853
|
+
.selectAll('g')
|
|
854
|
+
.data(parsedData)
|
|
855
|
+
.enter()
|
|
856
|
+
.append('g')
|
|
857
|
+
.attr('transform', d => `translate(${Number(x(xAccessor(d)))}, 0)`)
|
|
858
|
+
.selectAll('rect')
|
|
859
|
+
.data(d => Object.keys(this.dimensions).filter(key => key !== 'x').map((key) => {
|
|
860
|
+
var _a, _b, _c;
|
|
861
|
+
return {
|
|
862
|
+
label: (_a = this.dimensions[key].label) !== null && _a !== void 0 ? _a : key,
|
|
863
|
+
key: (_b = this.dimensions[key].property) !== null && _b !== void 0 ? _b : '',
|
|
864
|
+
value: d[(_c = this.dimensions[key].property) !== null && _c !== void 0 ? _c : '']
|
|
865
|
+
};
|
|
866
|
+
}))
|
|
867
|
+
.enter()
|
|
868
|
+
.append('rect')
|
|
869
|
+
.attr('x', d => Number(xSubgroup(d.key)))
|
|
870
|
+
.attr('y', d => Number(subgroupScales[d.key](d.value)))
|
|
871
|
+
.attr('width', xSubgroup.bandwidth())
|
|
872
|
+
.attr('height', d => plotHeight - Number(subgroupScales[d.key](d.value)))
|
|
873
|
+
.attr('fill', d => color(d.key))
|
|
874
|
+
.classed('bar', true)
|
|
875
|
+
.on('mouseover', onMouseEnterOrMove)
|
|
876
|
+
.on('mousemove', onMouseEnterOrMove)
|
|
877
|
+
.on('mouseleave', onMouseLeave);
|
|
878
|
+
// X Axis
|
|
879
|
+
const xAxis = g.append('g')
|
|
880
|
+
.attr('transform', `translate(0, ${plotHeight})`)
|
|
881
|
+
.call(d3.axisBottom(x));
|
|
882
|
+
// X Labels
|
|
883
|
+
xAxis.selectAll('text')
|
|
884
|
+
.attr('text-anchor', 'end')
|
|
885
|
+
.attr('transform', 'rotate(-45)translate(-10, 0)');
|
|
886
|
+
// Y Axis
|
|
887
|
+
g.append('g')
|
|
888
|
+
.call(d3.axisLeft(y))
|
|
889
|
+
.attr('transform', `translate(${y1TotalWidth}, 0)`);
|
|
890
|
+
if (y2 !== undefined) {
|
|
891
|
+
// Y2 Axis
|
|
892
|
+
g.append('g')
|
|
893
|
+
.call(d3.axisRight(y2))
|
|
894
|
+
.attr('transform', `translate(${width - y2TotalWidth}, 0)`);
|
|
895
|
+
}
|
|
896
|
+
// Y Label
|
|
897
|
+
g.append('text')
|
|
898
|
+
.attr('text-anchor', 'middle')
|
|
899
|
+
.attr('transform', 'rotate(-90)')
|
|
900
|
+
.attr('x', -1 * plotHeight / 2)
|
|
901
|
+
.attr('y', yLabelWidth)
|
|
902
|
+
.attr('font-weight', 800)
|
|
903
|
+
.text(yLabel);
|
|
904
|
+
if (y2Label !== undefined) {
|
|
905
|
+
// Y2 Label
|
|
906
|
+
g.append('text')
|
|
907
|
+
.attr('text-anchor', 'middle')
|
|
908
|
+
.attr('transform', 'rotate(90)')
|
|
909
|
+
.attr('x', 1 * plotHeight / 2)
|
|
910
|
+
.attr('y', -1 * (width - y2LabelWidth))
|
|
911
|
+
.attr('font-weight', 800)
|
|
912
|
+
.text(y2Label);
|
|
913
|
+
}
|
|
914
|
+
});
|
|
915
|
+
}
|
|
916
|
+
getXScale(plotXStart, plotXEnd, groups) {
|
|
917
|
+
return d3.scaleBand()
|
|
918
|
+
.domain(groups)
|
|
919
|
+
.range([plotXStart, plotXEnd])
|
|
920
|
+
.padding(0.25);
|
|
921
|
+
}
|
|
922
|
+
getYScale(plotHeight, chartPaddingTop, data, yAccessor) {
|
|
923
|
+
return d3.scaleLinear()
|
|
924
|
+
.domain([
|
|
925
|
+
0,
|
|
926
|
+
Number(d3.max(data, d => yAccessor(d)))
|
|
927
|
+
])
|
|
928
|
+
.range([plotHeight, chartPaddingTop]);
|
|
929
|
+
}
|
|
930
|
+
getY2Scale(plotHeight, chartPaddingTop, data, y2Accessor) {
|
|
931
|
+
if (y2Accessor === undefined)
|
|
932
|
+
return undefined;
|
|
933
|
+
return this.getYScale(plotHeight, chartPaddingTop, data, y2Accessor);
|
|
934
|
+
}
|
|
935
|
+
/**
|
|
936
|
+
*
|
|
937
|
+
* Returns a map from Y key to Y scale. E.g.
|
|
938
|
+
* {
|
|
939
|
+
* "frequency": Y,
|
|
940
|
+
* "proportion": Y2
|
|
941
|
+
* }
|
|
942
|
+
*/
|
|
943
|
+
getSubgroupScales(yKey, y, y2Key, y2) {
|
|
944
|
+
const subgroupScales = {
|
|
945
|
+
[yKey]: y
|
|
946
|
+
};
|
|
947
|
+
if (y2Key !== undefined && y2 !== undefined) {
|
|
948
|
+
subgroupScales[y2Key] = y2;
|
|
949
|
+
}
|
|
950
|
+
return subgroupScales;
|
|
951
|
+
}
|
|
952
|
+
getScrubPosition(mouseX) { return undefined; }
|
|
953
|
+
drawScrubbing(mouseX) { }
|
|
954
|
+
emitDataLoad(data, color) {
|
|
955
|
+
if (this.onDataLoad !== undefined) {
|
|
956
|
+
const legend = Object.keys(this.dimensions).filter(key => key !== 'x').map(key => {
|
|
957
|
+
var _a, _b;
|
|
958
|
+
return ({
|
|
959
|
+
key,
|
|
960
|
+
label: (_a = this.dimensions[key].label) !== null && _a !== void 0 ? _a : key,
|
|
961
|
+
color: color((_b = this.dimensions[key].property) !== null && _b !== void 0 ? _b : '')
|
|
962
|
+
});
|
|
963
|
+
});
|
|
964
|
+
const barPlotLoadEvent = {
|
|
965
|
+
plotId: this.id,
|
|
966
|
+
data,
|
|
967
|
+
properties: { legend }
|
|
968
|
+
};
|
|
969
|
+
this.onDataLoad(barPlotLoadEvent);
|
|
970
|
+
}
|
|
971
|
+
}
|
|
972
|
+
}
|
|
973
|
+
|
|
760
974
|
const chartTypes = {
|
|
761
975
|
Line: AxiomLine,
|
|
762
976
|
Area: AxiomArea,
|
|
763
|
-
Scatter: AxiomScatter
|
|
977
|
+
Scatter: AxiomScatter,
|
|
978
|
+
Bar: AxiomBar
|
|
764
979
|
};
|
|
765
980
|
|
|
766
981
|
function styleInject(css, ref) {
|
|
@@ -1029,6 +1244,9 @@ class AxiomChart extends ChartRoot {
|
|
|
1029
1244
|
else if (plot.type === EPlotTypes.scatter) {
|
|
1030
1245
|
return new chartTypes.Scatter(props);
|
|
1031
1246
|
}
|
|
1247
|
+
else if (plot.type === EPlotTypes.bar) {
|
|
1248
|
+
return new chartTypes.Bar(props);
|
|
1249
|
+
}
|
|
1032
1250
|
return new PlotRoot(props);
|
|
1033
1251
|
}
|
|
1034
1252
|
clearCanvas() {
|
|
@@ -1762,14 +1980,20 @@ function calculateWindRoseProportions(data) {
|
|
|
1762
1980
|
|
|
1763
1981
|
/* eslint-disable @typescript-eslint/ban-ts-comment */
|
|
1764
1982
|
class AxiomWindrose extends AxiomPlotRoot {
|
|
1765
|
-
constructor() {
|
|
1766
|
-
super(
|
|
1983
|
+
constructor(props) {
|
|
1984
|
+
super(props);
|
|
1767
1985
|
this.Y_DOMAIN_TYPE = 'frequency';
|
|
1768
1986
|
this.raw = {
|
|
1769
1987
|
direction: [],
|
|
1770
1988
|
speed: []
|
|
1771
1989
|
};
|
|
1772
1990
|
this.columns = DEFAULT_COLUMNS;
|
|
1991
|
+
const chart = this.chart;
|
|
1992
|
+
const chartElements = chart.getChartElements();
|
|
1993
|
+
if ((chartElements === null || chartElements === void 0 ? void 0 : chartElements.svg) !== undefined) {
|
|
1994
|
+
chartElements.svg.style('z-index', 20);
|
|
1995
|
+
// TODO find better way ^. Doing this so that svg can get events.
|
|
1996
|
+
}
|
|
1773
1997
|
}
|
|
1774
1998
|
initializeData() {
|
|
1775
1999
|
if (this.Y_DOMAIN_TYPE === 'frequency') {
|
|
@@ -1780,7 +2004,7 @@ class AxiomWindrose extends AxiomPlotRoot {
|
|
|
1780
2004
|
}
|
|
1781
2005
|
}
|
|
1782
2006
|
draw() {
|
|
1783
|
-
var _a, _b, _c;
|
|
2007
|
+
var _a, _b, _c, _d, _e;
|
|
1784
2008
|
return __awaiter(this, void 0, void 0, function* () {
|
|
1785
2009
|
const chart = this.chart;
|
|
1786
2010
|
const chartElements = chart.getChartElements();
|
|
@@ -1822,25 +2046,16 @@ class AxiomWindrose extends AxiomPlotRoot {
|
|
|
1822
2046
|
const y = d3
|
|
1823
2047
|
.scaleLinear() // you can try scaleRadial but it scales differently
|
|
1824
2048
|
.range([innerRadius, outerRadius]);
|
|
2049
|
+
const fillColors = (_b = (_a = this.style) === null || _a === void 0 ? void 0 : _a.colors) !== null && _b !== void 0 ? _b : d3.schemeTableau10;
|
|
1825
2050
|
const z = d3
|
|
1826
2051
|
.scaleOrdinal()
|
|
1827
|
-
.range(
|
|
1828
|
-
'#8e44ad',
|
|
1829
|
-
'#4242f4',
|
|
1830
|
-
'#42c5f4',
|
|
1831
|
-
'#42f4ce',
|
|
1832
|
-
'#42f456',
|
|
1833
|
-
'#adf442',
|
|
1834
|
-
'#f4e242',
|
|
1835
|
-
'#f4a142',
|
|
1836
|
-
'#f44242'
|
|
1837
|
-
]);
|
|
2052
|
+
.range(fillColors);
|
|
1838
2053
|
x.domain(data.map((d) => String(d.angle)));
|
|
1839
2054
|
if (this.Y_DOMAIN_TYPE === 'frequency') {
|
|
1840
2055
|
y.domain([
|
|
1841
2056
|
0,
|
|
1842
|
-
((
|
|
1843
|
-
? (
|
|
2057
|
+
((_c = d3.max(data, (d) => d.total)) !== null && _c !== void 0 ? _c : 0) > 1
|
|
2058
|
+
? (_d = d3.max(data, (d) => d.total)) !== null && _d !== void 0 ? _d : 0
|
|
1844
2059
|
: 1
|
|
1845
2060
|
]);
|
|
1846
2061
|
}
|
|
@@ -1849,7 +2064,7 @@ class AxiomWindrose extends AxiomPlotRoot {
|
|
|
1849
2064
|
}
|
|
1850
2065
|
z.domain(this.columns.slice(1));
|
|
1851
2066
|
// Extend the domain slightly to match the range of [0, 2π].
|
|
1852
|
-
angle.domain([0, (
|
|
2067
|
+
angle.domain([0, (_e = d3.max(data, (_, i) => i + 1)) !== null && _e !== void 0 ? _e : 0]);
|
|
1853
2068
|
// radius.domain([0, d3.max(data, (): number => 0) || 0])
|
|
1854
2069
|
radius.domain([0, 0]);
|
|
1855
2070
|
// radius.domain([innerRadius, outerRadius]);
|
|
@@ -1891,7 +2106,10 @@ class AxiomWindrose extends AxiomPlotRoot {
|
|
|
1891
2106
|
arc
|
|
1892
2107
|
// @ts-expect-error
|
|
1893
2108
|
.attr('d', arcVal)
|
|
1894
|
-
.attr('transform', `rotate(${angleOffset})`)
|
|
2109
|
+
.attr('transform', `rotate(${angleOffset})`)
|
|
2110
|
+
.on('mouseover', (event, data) => { this.onMouseEnterOrMove(event, data); })
|
|
2111
|
+
.on('mousemove', (event, data) => { this.onMouseEnterOrMove(event, data); })
|
|
2112
|
+
.on('mouseleave', () => { this.onMouseLeave(); });
|
|
1895
2113
|
const label = g
|
|
1896
2114
|
.append('g')
|
|
1897
2115
|
.selectAll('g')
|
|
@@ -1974,6 +2192,25 @@ class AxiomWindrose extends AxiomPlotRoot {
|
|
|
1974
2192
|
}
|
|
1975
2193
|
drawScrubbing(mouseX) {
|
|
1976
2194
|
}
|
|
2195
|
+
onMouseEnterOrMove(event, data) {
|
|
2196
|
+
if (this.chart.onScrub === undefined)
|
|
2197
|
+
return;
|
|
2198
|
+
const scrubPositions = {
|
|
2199
|
+
[this.id]: {
|
|
2200
|
+
xPosition: event.offsetX,
|
|
2201
|
+
xValue: data.data.angle,
|
|
2202
|
+
yPosition: event.offsetY,
|
|
2203
|
+
yValue: data[1] - data[0],
|
|
2204
|
+
properties: Object.assign({}, data)
|
|
2205
|
+
}
|
|
2206
|
+
};
|
|
2207
|
+
this.chart.onScrub(scrubPositions);
|
|
2208
|
+
}
|
|
2209
|
+
onMouseLeave() {
|
|
2210
|
+
if (this.chart.onScrubEnd === undefined)
|
|
2211
|
+
return;
|
|
2212
|
+
this.chart.onScrubEnd();
|
|
2213
|
+
}
|
|
1977
2214
|
}
|
|
1978
2215
|
|
|
1979
2216
|
class AxiomWindroseChart extends AxiomChart {
|