@truedat/dd 4.44.5 → 4.45.0

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/CHANGELOG.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  ## [4.44.4] 2022-05-19
4
4
 
5
- ## Added
5
+ ### Added
6
6
 
7
7
  - [TD-4660] Support for reference datasets
8
8
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@truedat/dd",
3
- "version": "4.44.5",
3
+ "version": "4.45.0",
4
4
  "description": "Truedat Web Data Dictionary",
5
5
  "sideEffects": false,
6
6
  "jsnext:main": "src/index.js",
@@ -34,7 +34,7 @@
34
34
  "@testing-library/jest-dom": "^5.16.4",
35
35
  "@testing-library/react": "^12.0.0",
36
36
  "@testing-library/user-event": "^13.2.1",
37
- "@truedat/test": "4.44.5",
37
+ "@truedat/test": "4.45.0",
38
38
  "babel-jest": "^28.1.0",
39
39
  "babel-plugin-dynamic-import-node": "^2.3.3",
40
40
  "babel-plugin-lodash": "^3.3.4",
@@ -88,9 +88,9 @@
88
88
  },
89
89
  "dependencies": {
90
90
  "@apollo/client": "^3.6.4",
91
- "@truedat/auth": "4.44.5",
92
- "@truedat/core": "4.44.5",
93
- "@truedat/df": "4.44.5",
91
+ "@truedat/auth": "4.45.0",
92
+ "@truedat/core": "4.45.0",
93
+ "@truedat/df": "4.45.0",
94
94
  "lodash": "^4.17.21",
95
95
  "path-to-regexp": "^1.7.0",
96
96
  "prop-types": "^15.8.1",
@@ -99,7 +99,6 @@
99
99
  "react-moment": "^1.1.2",
100
100
  "react-redux": "^7.2.4",
101
101
  "react-router-dom": "^5.2.0",
102
- "react-vis": "^1.11.7",
103
102
  "redux": "^4.1.1",
104
103
  "redux-saga": "^1.1.3",
105
104
  "redux-saga-routines": "^3.2.3",
@@ -107,9 +106,10 @@
107
106
  "svg-pan-zoom": "^3.6.1"
108
107
  },
109
108
  "peerDependencies": {
109
+ "@truedat/profile": ">= 4.45.0",
110
110
  "react": ">= 16.8.6 < 17",
111
111
  "react-dom": ">= 16.8.6 < 17",
112
112
  "semantic-ui-react": ">= 0.88.2 < 2.1"
113
113
  },
114
- "gitHead": "5a339468198c803592b285eddd0dd0c0b0eced93"
114
+ "gitHead": "b8a49c6bae0bbde203dfb4763a5657fc398e3b7a"
115
115
  }
@@ -18,7 +18,6 @@ import StructureLineage from "./StructureLineage";
18
18
  import StructureNotes from "./StructureNotes";
19
19
  import StructureNotesEdit from "./StructureNotesEdit";
20
20
  import StructureParentRelations from "./StructureParentRelations";
21
- import StructureProfiling from "./StructureProfiling";
22
21
  import StructureVersions from "./StructureVersions";
23
22
  import StructureMetadata from "./StructureMetadata";
24
23
  import StructureNotesLoader from "./StructureNotesLoader";
@@ -26,6 +25,9 @@ import StructureNotesLoader from "./StructureNotesLoader";
26
25
  const StructureLinks = React.lazy(() =>
27
26
  import("@truedat/lm/components/StructureLinks")
28
27
  );
28
+
29
+ const StructureProfile = React.lazy(() => import("@truedat/profile"));
30
+
29
31
  const StructureRelationForm = React.lazy(() =>
30
32
  import("@truedat/lm/components/StructureRelationForm")
31
33
  );
@@ -59,7 +61,7 @@ export const StructureTabPane = ({ activeTab, tabVisibility }) => (
59
61
  <Route render={() => <StructureLinks />} />
60
62
  </Switch>
61
63
  )}
62
- {activeTab === "profile" && tabVisibility.profile && <StructureProfiling />}
64
+ {activeTab === "profile" && tabVisibility.profile && <StructureProfile />}
63
65
  {activeTab === "parents" && <StructureParentRelations />}
64
66
  {activeTab === "children" && <StructureChildrenRelations />}
65
67
  {activeTab === "versions" && <StructureVersions />}
@@ -55,7 +55,7 @@ exports[`<StructureTabPane /> matches the latest snapshot: notes 1`] = `
55
55
 
56
56
  exports[`<StructureTabPane /> matches the latest snapshot: profile 1`] = `
57
57
  <ErrorBoundary>
58
- <Connect(StructureProfiling) />
58
+ <lazy />
59
59
  </ErrorBoundary>
60
60
  `;
61
61
 
@@ -8,8 +8,6 @@ import LineageDownloadButton from "./LineageDownloadButton";
8
8
  import LineageGroup from "./LineageGroup";
9
9
  import LineageLink from "./LineageLink";
10
10
  import LineageRoutes from "./LineageRoutes";
11
- import ProfilingGraph from "./ProfilingGraph";
12
- import ProfilingPatterns from "./ProfilingPatterns";
13
11
  import StructureCrumbs from "./StructureCrumbs";
14
12
  import StructureEvents from "./StructureEvents";
15
13
  import StructureFieldRow from "./StructureFieldRow";
@@ -23,7 +21,6 @@ import StructureLoader from "./StructureLoader";
23
21
  import StructureNav from "./StructureNav";
24
22
  import StructureNotes from "./StructureNotes";
25
23
  import StructureNotesEdit from "./StructureNotesEdit";
26
- import StructureProfiling from "./StructureProfiling";
27
24
  import StructureProperties from "./StructureProperties";
28
25
  import StructureRow from "./StructureRow";
29
26
  import StructureSelectedFilters from "./StructureSelectedFilters";
@@ -64,8 +61,6 @@ export {
64
61
  LineageGroup,
65
62
  LineageLink,
66
63
  LineageRoutes,
67
- ProfilingGraph,
68
- ProfilingPatterns,
69
64
  StructureCrumbs,
70
65
  StructureEvents,
71
66
  StructureFieldRow,
@@ -79,7 +74,6 @@ export {
79
74
  StructureNav,
80
75
  StructureNotes,
81
76
  StructureNotesEdit,
82
- StructureProfiling,
83
77
  StructureProperties,
84
78
  StructureMetadata,
85
79
  StructureRow,
@@ -1,89 +0,0 @@
1
- import _ from "lodash/fp";
2
- import React, { useState } from "react";
3
- import PropTypes from "prop-types";
4
- import { connect } from "react-redux";
5
- import { Button, Icon, Grid } from "semantic-ui-react";
6
- import { FormattedMessage } from "react-intl";
7
- import ProfilingGraph from "./ProfilingGraph";
8
- import ProfilingPatterns from "./ProfilingPatterns";
9
-
10
- export const ProfilingElements = ({ profile }) => {
11
- const { most_frequent, patterns } = profile || {};
12
- const [elementActive, setElementActive] = useState("graph");
13
- const titleElement =
14
- elementActive === "graph"
15
- ? "structure.field.graph.title"
16
- : "structure.field.patterns.title";
17
- return (
18
- <>
19
- {!_.isEmpty(most_frequent) && !_.isEmpty(patterns) && (
20
- <>
21
- <Grid>
22
- <Grid.Column width={8}>
23
- <p>
24
- <FormattedMessage id={titleElement} />:
25
- </p>
26
- </Grid.Column>
27
- <Grid.Column width={8} textAlign="right">
28
- <Button.Group floated="right">
29
- <Button
30
- active={elementActive === "graph"}
31
- icon
32
- onClick={() => setElementActive("graph")}
33
- >
34
- <Icon name="chart line" />
35
- </Button>
36
- <Button
37
- active={elementActive === "patterns"}
38
- icon
39
- onClick={() => setElementActive("patterns")}
40
- >
41
- <Icon name="list ul" />
42
- </Button>
43
- </Button.Group>
44
- </Grid.Column>
45
- </Grid>
46
-
47
- {elementActive === "graph" && <ProfilingGraph />}
48
- {elementActive === "patterns" && <ProfilingPatterns />}
49
- </>
50
- )}
51
-
52
- {!_.isEmpty(most_frequent) && _.isEmpty(patterns) && (
53
- <>
54
- <Grid>
55
- <Grid.Column width={16}>
56
- <p>
57
- <FormattedMessage id="structure.field.graph.title" />:
58
- </p>
59
- </Grid.Column>
60
- </Grid>
61
-
62
- <ProfilingGraph />
63
- </>
64
- )}
65
-
66
- {_.isEmpty(most_frequent) && !_.isEmpty(patterns) && (
67
- <>
68
- <Grid>
69
- <Grid.Column width={16}>
70
- <p>
71
- <FormattedMessage id="structure.field.patterns.title" />
72
- </p>
73
- </Grid.Column>
74
- </Grid>
75
-
76
- <ProfilingPatterns />
77
- </>
78
- )}
79
- </>
80
- );
81
- };
82
-
83
- ProfilingElements.propTypes = {
84
- profile: PropTypes.object,
85
- };
86
-
87
- const mapStateToProps = ({ structureProfile: profile }) => ({ profile });
88
-
89
- export default connect(mapStateToProps)(ProfilingElements);
@@ -1,89 +0,0 @@
1
- import _ from "lodash/fp";
2
- import React, { useState } from "react";
3
- import PropTypes from "prop-types";
4
- import { connect } from "react-redux";
5
- import { Label } from "semantic-ui-react";
6
- import { FormattedMessage } from "react-intl";
7
- import { XYPlot, XAxis, YAxis, HorizontalBarSeries, Hint } from "react-vis";
8
-
9
- const getDistribution = _.flow(
10
- _.pathOr("[]", "most_frequent"),
11
- _.map(({ k, v }) => ({ x: v, y: k })),
12
- _.orderBy("x", "desc"),
13
- _.take(30),
14
- _.reverse
15
- );
16
-
17
- const getMinMax = _.flow(
18
- _.map("x"),
19
- (d) => [_.min(d) - 1, _.max(d)],
20
- _.defaultTo([-Infinity, Infinity])
21
- );
22
-
23
- const formatNumber = (num) =>
24
- num.toString().replace(/(\d)(?=(\d{3})+(?!\d))/g, "$1,");
25
-
26
- export const ProfilingGraph = ({ count, distribution }) => {
27
- const [hintValue, setHintValue] = useState(null);
28
- const data = _.map((d) => ({ color: d.y == hintValue?.y ? 0 : 1, ...d }))(
29
- distribution
30
- );
31
- return (
32
- <XYPlot
33
- yType="ordinal"
34
- xType="linear"
35
- width={800}
36
- height={400}
37
- margin={{ left: 180 }}
38
- xDomain={getMinMax(data)}
39
- colorRange={["#ed5c17", "#002057"]}
40
- >
41
- <YAxis
42
- tickFormat={_.truncate({ length: 30 })}
43
- style={{ fontSize: "12px", width: "100px" }}
44
- />
45
- <XAxis style={{ fontSize: "12px" }} />
46
- <HorizontalBarSeries
47
- onValueMouseOver={setHintValue}
48
- onValueMouseOut={() => setHintValue(null)}
49
- data={data}
50
- />
51
- {hintValue ? (
52
- <Hint
53
- style={{ width: "500px", bottom: "190px" }}
54
- align={{ horizontal: "right", vertical: "top" }}
55
- value={hintValue}
56
- >
57
- <Label pointing="left" className="graph">
58
- <div>
59
- <div>
60
- <FormattedMessage id="structure.field.graph.value" />
61
- {hintValue.y}
62
- </div>
63
- <div>
64
- <FormattedMessage id="structure.field.graph.count" />
65
- {formatNumber(hintValue.x)}
66
- </div>
67
- <div>
68
- <FormattedMessage id="structure.field.graph.percentage" />
69
- {Math.floor((hintValue.x / count) * 100) + "%"}
70
- </div>
71
- </div>
72
- </Label>
73
- </Hint>
74
- ) : null}
75
- </XYPlot>
76
- );
77
- };
78
-
79
- ProfilingGraph.propTypes = {
80
- count: PropTypes.number,
81
- distribution: PropTypes.arrayOf(PropTypes.object),
82
- };
83
-
84
- const mapStateToProps = ({ structureProfile }) => ({
85
- count: structureProfile?.total_count,
86
- distribution: getDistribution(structureProfile),
87
- });
88
-
89
- export default connect(mapStateToProps)(ProfilingGraph);
@@ -1,57 +0,0 @@
1
- import _ from "lodash/fp";
2
- import React from "react";
3
- import PropTypes from "prop-types";
4
- import { connect } from "react-redux";
5
- import { Table } from "semantic-ui-react";
6
- import { useIntl } from "react-intl";
7
-
8
- export const ProfilingPatterns = ({ patterns, totalCount }) => {
9
- const { formatNumber, formatMessage } = useIntl();
10
- const dataPatterns = _.flow(
11
- _.orderBy("v", "desc"),
12
- _.map(({ k, v }) => ({
13
- frecuency: k,
14
- count: formatNumber(v),
15
- percentage: parseFloat(((v / totalCount) * 100).toFixed(2)),
16
- }))
17
- )(patterns);
18
-
19
- return !_.isEmpty(dataPatterns) ? (
20
- <Table>
21
- <Table.Header>
22
- <Table.Row>
23
- <Table.HeaderCell>
24
- {formatMessage({ id: "structure.field.patterns.frecuency" })}
25
- </Table.HeaderCell>
26
- <Table.HeaderCell>
27
- {formatMessage({ id: "structure.field.patterns.count" })}
28
- </Table.HeaderCell>
29
- <Table.HeaderCell>
30
- {formatMessage({ id: "structure.field.patterns.percentage" })}
31
- </Table.HeaderCell>
32
- </Table.Row>
33
- </Table.Header>
34
- <Table.Body>
35
- {dataPatterns.map((pattern, i) => (
36
- <Table.Row key={i}>
37
- <Table.Cell>{pattern.frecuency}</Table.Cell>
38
- <Table.Cell>{pattern.count}</Table.Cell>
39
- <Table.Cell>{`${pattern.percentage} %`}</Table.Cell>
40
- </Table.Row>
41
- ))}
42
- </Table.Body>
43
- </Table>
44
- ) : null;
45
- };
46
-
47
- ProfilingPatterns.propTypes = {
48
- patterns: PropTypes.array,
49
- totalCount: PropTypes.number,
50
- };
51
-
52
- const mapStateToProps = ({ structureProfile }) => ({
53
- patterns: structureProfile?.patterns,
54
- totalCount: structureProfile?.total_count,
55
- });
56
-
57
- export default connect(mapStateToProps)(ProfilingPatterns);
@@ -1,124 +0,0 @@
1
- import _ from "lodash/fp";
2
- import React from "react";
3
- import PropTypes from "prop-types";
4
- import { connect } from "react-redux";
5
- import { Table } from "semantic-ui-react";
6
- import { useIntl } from "react-intl";
7
- import { Link } from "react-router-dom";
8
- import { linkTo } from "@truedat/core/routes";
9
- import { getSortedFields } from "../selectors";
10
- import ProfilingElements from "./ProfilingElements";
11
-
12
- const calculatePercent = (value_count, total_count) =>
13
- ((parseFloat(value_count) / parseFloat(total_count)) * 100).toFixed(2) + "%";
14
-
15
- const calculateUniquePercent = ({ unique_count, total_count }) =>
16
- calculatePercent(unique_count, total_count);
17
- const calculateNullPercent = ({ null_count, total_count }) =>
18
- calculatePercent(null_count, total_count);
19
-
20
- const calculateMode = (distribution) =>
21
- _.isEmpty(distribution)
22
- ? "-"
23
- : _.flow(_.orderBy("v", "desc"), _.head, _.prop("k"))(distribution);
24
-
25
- export const FieldProfileRow = ({ profile, data_structure_id, name }) => {
26
- const { unique_count, null_count, total_count, min, max, most_frequent } =
27
- profile;
28
- const uniquePercent =
29
- !_.isNil(unique_count) && !_.isNil(total_count) && total_count > 0
30
- ? calculateUniquePercent(profile)
31
- : "-";
32
- const nullPercent =
33
- !_.isNil(null_count) && !_.isNil(total_count)
34
- ? calculateNullPercent(profile)
35
- : "-";
36
-
37
- const maxLength = 50;
38
- const truncFn = _.truncate({ length: maxLength });
39
- const minValue = _.isNil(min) ? "-" : truncFn(min);
40
- const maxValue = _.isNil(max) ? "-" : truncFn(max);
41
- const minTitle = !_.isNil(min) && min.length > maxLength ? min : "";
42
- const maxTitle = !_.isNil(max) && max.length > maxLength ? max : "";
43
- const modeValue = _.isNil(most_frequent) ? "-" : calculateMode(most_frequent);
44
-
45
- return (
46
- <Table.Row>
47
- <Table.Cell>
48
- <Link
49
- to={
50
- _.isNil(most_frequent)
51
- ? linkTo.STRUCTURE({ id: data_structure_id })
52
- : linkTo.STRUCTURE_PROFILE({ id: data_structure_id })
53
- }
54
- >
55
- {name}
56
- </Link>
57
- </Table.Cell>
58
- <Table.Cell className="text-right" content={uniquePercent} />
59
- <Table.Cell className="text-right" content={nullPercent} />
60
- <Table.Cell>
61
- <span title={minTitle}> {minValue} </span>
62
- </Table.Cell>
63
- <Table.Cell>
64
- <span title={maxTitle}> {maxValue} </span>
65
- </Table.Cell>
66
- <Table.Cell content={modeValue} />
67
- </Table.Row>
68
- );
69
- };
70
-
71
- FieldProfileRow.propTypes = {
72
- data_structure_id: PropTypes.number,
73
- name: PropTypes.string,
74
- profile: PropTypes.object,
75
- };
76
-
77
- export const StructureProfiling = ({ fields }) => {
78
- const { formatMessage } = useIntl();
79
- return _.isEmpty(fields) ? (
80
- <ProfilingElements />
81
- ) : (
82
- <Table>
83
- <Table.Header>
84
- <Table.Row>
85
- <Table.HeaderCell
86
- content={formatMessage({ id: "profiling.field.name" })}
87
- />
88
- <Table.HeaderCell
89
- className="text-right"
90
- content={formatMessage({ id: "profiling.field.unique" })}
91
- />
92
- <Table.HeaderCell
93
- className="text-right"
94
- content={formatMessage({ id: "profiling.field.null" })}
95
- />
96
- <Table.HeaderCell
97
- content={formatMessage({ id: "profiling.field.min" })}
98
- />
99
- <Table.HeaderCell
100
- content={formatMessage({ id: "profiling.field.max" })}
101
- />
102
- <Table.HeaderCell
103
- content={formatMessage({ id: "profiling.field.mode" })}
104
- />
105
- </Table.Row>
106
- </Table.Header>
107
- <Table.Body>
108
- {fields.map((field, i) => (
109
- <FieldProfileRow key={i} {...field} />
110
- ))}
111
- </Table.Body>
112
- </Table>
113
- );
114
- };
115
-
116
- StructureProfiling.propTypes = {
117
- fields: PropTypes.array,
118
- };
119
-
120
- const mapStateToProps = (state) => ({
121
- fields: _.filter(_.has("profile"))(getSortedFields(state)),
122
- });
123
-
124
- export default connect(mapStateToProps)(StructureProfiling);
@@ -1,45 +0,0 @@
1
- import React from "react";
2
- import { render } from "@truedat/test/render";
3
- import StructureProfiling from "../StructureProfiling";
4
-
5
- const profile = {
6
- unique_count: 5,
7
- null_count: 2,
8
- total_count: 10,
9
- min: "33",
10
- max: "40",
11
- most_frequent: [
12
- { k: "foo", v: 10 },
13
- { k: "bar", v: 42 },
14
- ],
15
- };
16
-
17
- const messages = {
18
- en: {
19
- "profiling.field.max": "max",
20
- "profiling.field.min": "min",
21
- "profiling.field.mode": "mode",
22
- "profiling.field.name": "name",
23
- "profiling.field.null": "null",
24
- "profiling.field.unique": "unique",
25
- "structure.field.graph.title": "Frequency chart",
26
- },
27
- };
28
-
29
- describe("<StructureProfiling />", () => {
30
- it("matches the latest snapshot (fields)", () => {
31
- const structureFields = [
32
- { data_structure_id: 123, name: "field1", profile },
33
- { data_structure_id: 122, name: "field2", profile },
34
- ];
35
- const state = { structureFields };
36
- const { container } = render(<StructureProfiling />, { messages, state });
37
- expect(container).toMatchSnapshot();
38
- });
39
-
40
- it("matches the latest snapshot (profile)", () => {
41
- const state = { structureProfile: profile };
42
- const { container } = render(<StructureProfiling />, { messages, state });
43
- expect(container).toMatchSnapshot();
44
- });
45
- });
@@ -1,444 +0,0 @@
1
- // Jest Snapshot v1, https://goo.gl/fbAQLP
2
-
3
- exports[`<StructureProfiling /> matches the latest snapshot (fields) 1`] = `
4
- <div>
5
- <table
6
- class="ui table"
7
- >
8
- <thead
9
- class=""
10
- >
11
- <tr
12
- class=""
13
- >
14
- <th
15
- class=""
16
- >
17
- name
18
- </th>
19
- <th
20
- class="text-right"
21
- >
22
- unique
23
- </th>
24
- <th
25
- class="text-right"
26
- >
27
- null
28
- </th>
29
- <th
30
- class=""
31
- >
32
- min
33
- </th>
34
- <th
35
- class=""
36
- >
37
- max
38
- </th>
39
- <th
40
- class=""
41
- >
42
- mode
43
- </th>
44
- </tr>
45
- </thead>
46
- <tbody
47
- class=""
48
- >
49
- <tr
50
- class=""
51
- >
52
- <td
53
- class=""
54
- >
55
- <a
56
- href="/structures/123/profile"
57
- >
58
- field1
59
- </a>
60
- </td>
61
- <td
62
- class="text-right"
63
- >
64
- 50.00%
65
- </td>
66
- <td
67
- class="text-right"
68
- >
69
- 20.00%
70
- </td>
71
- <td
72
- class=""
73
- >
74
- <span
75
- title=""
76
- >
77
-
78
- 33
79
-
80
- </span>
81
- </td>
82
- <td
83
- class=""
84
- >
85
- <span
86
- title=""
87
- >
88
-
89
- 40
90
-
91
- </span>
92
- </td>
93
- <td
94
- class=""
95
- >
96
- bar
97
- </td>
98
- </tr>
99
- <tr
100
- class=""
101
- >
102
- <td
103
- class=""
104
- >
105
- <a
106
- href="/structures/122/profile"
107
- >
108
- field2
109
- </a>
110
- </td>
111
- <td
112
- class="text-right"
113
- >
114
- 50.00%
115
- </td>
116
- <td
117
- class="text-right"
118
- >
119
- 20.00%
120
- </td>
121
- <td
122
- class=""
123
- >
124
- <span
125
- title=""
126
- >
127
-
128
- 33
129
-
130
- </span>
131
- </td>
132
- <td
133
- class=""
134
- >
135
- <span
136
- title=""
137
- >
138
-
139
- 40
140
-
141
- </span>
142
- </td>
143
- <td
144
- class=""
145
- >
146
- bar
147
- </td>
148
- </tr>
149
- </tbody>
150
- </table>
151
- </div>
152
- `;
153
-
154
- exports[`<StructureProfiling /> matches the latest snapshot (profile) 1`] = `
155
- <div>
156
- <div
157
- class="ui grid"
158
- >
159
- <div
160
- class="sixteen wide column"
161
- >
162
- <p>
163
- Frequency chart
164
- :
165
- </p>
166
- </div>
167
- </div>
168
- <div
169
- class="rv-xy-plot "
170
- style="width: 800px; height: 400px;"
171
- >
172
- <svg
173
- class="rv-xy-plot__inner"
174
- height="400"
175
- width="800"
176
- >
177
- <g
178
- class="rv-xy-plot__axis rv-xy-plot__axis--vertical "
179
- style="font-size: 12px; width: 100px;"
180
- transform="translate(0,10)"
181
- >
182
- <line
183
- class="rv-xy-plot__axis__line"
184
- style="font-size: 12px; width: 100px;"
185
- x1="180"
186
- x2="180"
187
- y1="0"
188
- y2="350"
189
- />
190
- <g
191
- class="rv-xy-plot__axis__ticks"
192
- transform="translate(180, 0)"
193
- >
194
- <g
195
- class="rv-xy-plot__axis__tick"
196
- style="font-size: 12px; width: 100px;"
197
- transform="translate(0, 262.5)"
198
- >
199
- <line
200
- class="rv-xy-plot__axis__tick__line"
201
- style="font-size: 12px; width: 100px;"
202
- x1="6"
203
- x2="-6"
204
- y1="0"
205
- y2="0"
206
- />
207
- <text
208
- class="rv-xy-plot__axis__tick__text"
209
- dy="0.32em"
210
- style="font-size: 12px; width: 100px;"
211
- text-anchor="end"
212
- transform="translate(-14, 0)"
213
- >
214
- foo
215
- </text>
216
- </g>
217
- <g
218
- class="rv-xy-plot__axis__tick"
219
- style="font-size: 12px; width: 100px;"
220
- transform="translate(0, 87.5)"
221
- >
222
- <line
223
- class="rv-xy-plot__axis__tick__line"
224
- style="font-size: 12px; width: 100px;"
225
- x1="6"
226
- x2="-6"
227
- y1="0"
228
- y2="0"
229
- />
230
- <text
231
- class="rv-xy-plot__axis__tick__text"
232
- dy="0.32em"
233
- style="font-size: 12px; width: 100px;"
234
- text-anchor="end"
235
- transform="translate(-14, 0)"
236
- >
237
- bar
238
- </text>
239
- </g>
240
- </g>
241
- </g>
242
- <g
243
- class="rv-xy-plot__axis rv-xy-plot__axis--horizontal "
244
- style="font-size: 12px;"
245
- transform="translate(180,360)"
246
- >
247
- <line
248
- class="rv-xy-plot__axis__line"
249
- style="font-size: 12px;"
250
- x1="0"
251
- x2="610"
252
- y1="0"
253
- y2="0"
254
- />
255
- <g
256
- class="rv-xy-plot__axis__ticks"
257
- transform="translate(0, 0)"
258
- >
259
- <g
260
- class="rv-xy-plot__axis__tick"
261
- style="font-size: 12px;"
262
- transform="translate(18.484848484848484, 0)"
263
- >
264
- <line
265
- class="rv-xy-plot__axis__tick__line"
266
- style="font-size: 12px;"
267
- x1="0"
268
- x2="0"
269
- y1="-6"
270
- y2="6"
271
- />
272
- <text
273
- class="rv-xy-plot__axis__tick__text"
274
- dy="0.72em"
275
- style="font-size: 12px;"
276
- text-anchor="middle"
277
- transform="translate(0, 14)"
278
- >
279
- 10
280
- </text>
281
- </g>
282
- <g
283
- class="rv-xy-plot__axis__tick"
284
- style="font-size: 12px;"
285
- transform="translate(110.9090909090909, 0)"
286
- >
287
- <line
288
- class="rv-xy-plot__axis__tick__line"
289
- style="font-size: 12px;"
290
- x1="0"
291
- x2="0"
292
- y1="-6"
293
- y2="6"
294
- />
295
- <text
296
- class="rv-xy-plot__axis__tick__text"
297
- dy="0.72em"
298
- style="font-size: 12px;"
299
- text-anchor="middle"
300
- transform="translate(0, 14)"
301
- >
302
- 15
303
- </text>
304
- </g>
305
- <g
306
- class="rv-xy-plot__axis__tick"
307
- style="font-size: 12px;"
308
- transform="translate(203.33333333333331, 0)"
309
- >
310
- <line
311
- class="rv-xy-plot__axis__tick__line"
312
- style="font-size: 12px;"
313
- x1="0"
314
- x2="0"
315
- y1="-6"
316
- y2="6"
317
- />
318
- <text
319
- class="rv-xy-plot__axis__tick__text"
320
- dy="0.72em"
321
- style="font-size: 12px;"
322
- text-anchor="middle"
323
- transform="translate(0, 14)"
324
- >
325
- 20
326
- </text>
327
- </g>
328
- <g
329
- class="rv-xy-plot__axis__tick"
330
- style="font-size: 12px;"
331
- transform="translate(295.75757575757575, 0)"
332
- >
333
- <line
334
- class="rv-xy-plot__axis__tick__line"
335
- style="font-size: 12px;"
336
- x1="0"
337
- x2="0"
338
- y1="-6"
339
- y2="6"
340
- />
341
- <text
342
- class="rv-xy-plot__axis__tick__text"
343
- dy="0.72em"
344
- style="font-size: 12px;"
345
- text-anchor="middle"
346
- transform="translate(0, 14)"
347
- >
348
- 25
349
- </text>
350
- </g>
351
- <g
352
- class="rv-xy-plot__axis__tick"
353
- style="font-size: 12px;"
354
- transform="translate(388.1818181818182, 0)"
355
- >
356
- <line
357
- class="rv-xy-plot__axis__tick__line"
358
- style="font-size: 12px;"
359
- x1="0"
360
- x2="0"
361
- y1="-6"
362
- y2="6"
363
- />
364
- <text
365
- class="rv-xy-plot__axis__tick__text"
366
- dy="0.72em"
367
- style="font-size: 12px;"
368
- text-anchor="middle"
369
- transform="translate(0, 14)"
370
- >
371
- 30
372
- </text>
373
- </g>
374
- <g
375
- class="rv-xy-plot__axis__tick"
376
- style="font-size: 12px;"
377
- transform="translate(480.60606060606057, 0)"
378
- >
379
- <line
380
- class="rv-xy-plot__axis__tick__line"
381
- style="font-size: 12px;"
382
- x1="0"
383
- x2="0"
384
- y1="-6"
385
- y2="6"
386
- />
387
- <text
388
- class="rv-xy-plot__axis__tick__text"
389
- dy="0.72em"
390
- style="font-size: 12px;"
391
- text-anchor="middle"
392
- transform="translate(0, 14)"
393
- >
394
- 35
395
- </text>
396
- </g>
397
- <g
398
- class="rv-xy-plot__axis__tick"
399
- style="font-size: 12px;"
400
- transform="translate(573.0303030303031, 0)"
401
- >
402
- <line
403
- class="rv-xy-plot__axis__tick__line"
404
- style="font-size: 12px;"
405
- x1="0"
406
- x2="0"
407
- y1="-6"
408
- y2="6"
409
- />
410
- <text
411
- class="rv-xy-plot__axis__tick__text"
412
- dy="0.72em"
413
- style="font-size: 12px;"
414
- text-anchor="middle"
415
- transform="translate(0, 14)"
416
- >
417
- 40
418
- </text>
419
- </g>
420
- </g>
421
- </g>
422
- <g
423
- class="rv-xy-plot__series rv-xy-plot__series--bar "
424
- transform="translate(180,10)"
425
- >
426
- <rect
427
- height="148.75"
428
- style="opacity: 1; stroke: rgb(0, 32, 87); fill: rgb(0, 32, 87);"
429
- width="18.484848484848484"
430
- x="0"
431
- y="188.125"
432
- />
433
- <rect
434
- height="148.75"
435
- style="opacity: 1; stroke: rgb(0, 32, 87); fill: rgb(0, 32, 87);"
436
- width="610"
437
- x="0"
438
- y="13.125"
439
- />
440
- </g>
441
- </svg>
442
- </div>
443
- </div>
444
- `;