@mozaic-ds/chart 0.1.0-beta.3 → 0.1.0-beta.5

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.
@@ -1,85 +1,126 @@
1
- import { ref } from 'vue';
2
- import type { Ref } from 'vue';
3
- import {
4
- getHtmlLegendPlugin
5
- } from '../services/ChartsCommonLegend';
6
- import { formatWithThousandsSeprators } from '../services/FormatUtilities';
1
+ import { ref } from "vue";
2
+ import type { Ref } from "vue";
3
+ import { getHtmlLegendPlugin } from "../services/ChartsCommonLegend";
4
+ import { formatWithThousandsSeprators } from "../services/FormatUtilities";
7
5
 
8
- import ChartDesign from './patterns/ChartDesign';
9
- import {addAlpha} from './ColorFunctions';
6
+ import ChartDesign from "./patterns/ChartDesign";
7
+ import { addAlpha } from "./ColorFunctions";
10
8
 
11
9
  export default function () {
12
10
  const doughnutRef: Ref = ref(null);
13
11
  const onHoverIndex: Ref<number | null> = ref(null);
14
12
  const backgroundColor: Ref<CanvasPattern[] | null> = ref(null);
15
13
 
16
- function privateGetHtmlLegendPlugin(legendContainer: Ref, selectMode: Ref<boolean>, disableAccessibility: Ref<boolean>, patternsColors: Ref<string[]>, patternsList: Ref<((hover: boolean, color: string, disableAccessibility: boolean) => CanvasPattern)[]>, maxValueToDisplay: number, doughnutData: any) {
17
- return getHtmlLegendPlugin(legendContainer, selectMode, onHoverIndex, disableAccessibility, patternsColors, patternsList, maxValueToDisplay, doughnutData);
14
+ function privateGetHtmlLegendPlugin(
15
+ legendContainer: Ref,
16
+ selectMode: Ref<boolean>,
17
+ disableAccessibility: Ref<boolean>,
18
+ patternsColors: Ref<string[]>,
19
+ patternsList: Ref<
20
+ ((
21
+ hover: boolean,
22
+ color: string,
23
+ disableAccessibility: boolean
24
+ ) => CanvasPattern)[]
25
+ >,
26
+ maxValueToDisplay: number,
27
+ doughnutData: any
28
+ ) {
29
+ return getHtmlLegendPlugin(
30
+ legendContainer,
31
+ selectMode,
32
+ onHoverIndex,
33
+ disableAccessibility,
34
+ patternsColors,
35
+ patternsList,
36
+ maxValueToDisplay,
37
+ doughnutData
38
+ );
18
39
  }
19
40
 
20
-
21
- function getBackgroundColor(patternsColors: string[], patternsList: ((hover: boolean, color: string, disableAccessibility: boolean) => CanvasPattern)[], disableAccessibility: boolean) {
41
+ function getBackgroundColor(
42
+ patternsColors: string[],
43
+ patternsList: ((
44
+ hover: boolean,
45
+ color: string,
46
+ disableAccessibility: boolean
47
+ ) => CanvasPattern)[],
48
+ disableAccessibility: boolean
49
+ ) {
22
50
  if (onHoverIndex.value !== null) {
23
- return patternsList
24
- .map((pattern, index) => onHoverIndex.value === index ? pattern(false, patternsColors[index], disableAccessibility) : pattern(true, patternsColors[index], disableAccessibility));
51
+ return patternsList.map((pattern, index) =>
52
+ onHoverIndex.value === index
53
+ ? pattern(false, patternsColors[index], disableAccessibility)
54
+ : pattern(true, patternsColors[index], disableAccessibility)
55
+ );
25
56
  } else {
26
- return patternsList
27
- .map((pattern, index) => pattern(false, patternsColors[index], disableAccessibility),);
57
+ return patternsList.map((pattern, index) =>
58
+ pattern(false, patternsColors[index], disableAccessibility)
59
+ );
28
60
  }
29
61
  }
30
62
 
31
63
  function getBorderColor(patternsColors: string[]): string[] {
32
64
  if (onHoverIndex.value !== null) {
33
- return patternsColors.map((color, index) => onHoverIndex.value === index ? color : addAlpha(color, 0.2));
65
+ return patternsColors.map((color, index) =>
66
+ onHoverIndex.value === index ? color : addAlpha(color, 0.2)
67
+ );
34
68
  } else {
35
69
  return patternsColors;
36
70
  }
37
71
  }
38
72
 
73
+ function getOnHoverOptions() {
74
+ return (_ignore: unknown, activeElements: Array<any>): void => {
75
+ if (activeElements[0] !== undefined) {
76
+ onHoverIndex.value = activeElements[0].element.$context.index;
77
+ } else {
78
+ onHoverIndex.value = null;
79
+ }
80
+ };
81
+ }
39
82
 
40
- function getOnHoverOptions () {
41
- return (_ignore: unknown, activeElements: Array<any>): void => {
42
- if (activeElements[0] !== undefined) {
43
- onHoverIndex.value = activeElements[0].element.$context.index;
44
- } else {
45
- onHoverIndex.value = null;
46
- }
83
+ const getFormatedText = (str: string) => {
84
+ return str.charAt(0).toUpperCase() + str.slice(1).toLowerCase();
47
85
  };
48
- }
49
-
50
- const getFormatedText = (str: string) => {
51
- return str.charAt(0).toUpperCase() + str.slice(1).toLowerCase();
52
- };
53
86
 
54
- function getDoughnutLabels(labels: string[], data: any[], maxValues: number) {
55
- let truncatedLabels = labels.slice(0);
56
- let truncatedData = data.slice(0);
57
- if (labels.length > maxValues){
58
- truncatedData = groupDataAfterNthValue(data, maxValues);
59
- truncatedLabels = truncatedLabels.slice(0, maxValues - 1);
60
- truncatedLabels.push('others');
87
+ function getDoughnutLabels(labels: string[], data: any[], maxValues: number) {
88
+ let truncatedLabels = labels.slice(0);
89
+ let truncatedData = data.slice(0);
90
+ if (labels.length > maxValues) {
91
+ truncatedData = groupDataAfterNthValue(data, maxValues);
92
+ truncatedLabels = truncatedLabels.slice(0, maxValues - 1);
93
+ truncatedLabels.push("others");
94
+ }
95
+ return truncatedLabels.map(
96
+ (label: string, index: number) =>
97
+ `${getFormatedText(label)} (${formatWithThousandsSeprators(
98
+ truncatedData[index].rate as number
99
+ )} %)`
100
+ );
61
101
  }
62
- return truncatedLabels.map((label: string, index: number) => `${getFormatedText(label)} (${formatWithThousandsSeprators(truncatedData[index].rate as number)} %)`);
63
- }
64
102
 
65
- function groupDataAfterNthValue (data: any, maxValues: number): any[] {
66
- if (maxValues < 1) {
67
- return data;
68
- }
69
- let truncatedData = data.slice(0);
70
- if (data.length > maxValues) {
71
- truncatedData = truncatedData.slice(0, maxValues);
72
- truncatedData[maxValues - 1] = data.slice(maxValues).reduce((result: any, current: any) => {
73
- result.rate += current.rate;
74
- result.value += current.value;
75
- return result;
76
- }, {
77
- rate: data[maxValues - 1].rate,
78
- value: data[maxValues - 1].value
79
- });
103
+ function groupDataAfterNthValue(data: any, maxValues: number): any[] {
104
+ if (maxValues < 1) {
105
+ return data;
106
+ }
107
+ let truncatedData = data.slice(0);
108
+ if (data.length > maxValues) {
109
+ truncatedData = truncatedData.slice(0, maxValues);
110
+ truncatedData[maxValues - 1] = data.slice(maxValues).reduce(
111
+ (result: any, current: any) => {
112
+ result.rate += current.rate;
113
+ result.value += current.value;
114
+ return result;
115
+ },
116
+ {
117
+ rate: data[maxValues - 1].rate,
118
+ value: data[maxValues - 1].value,
119
+ }
120
+ );
121
+ }
122
+ return truncatedData;
80
123
  }
81
- return truncatedData;
82
- }
83
124
 
84
125
  return {
85
126
  onHoverIndex,
@@ -91,6 +132,6 @@ function groupDataAfterNthValue (data: any, maxValues: number): any[] {
91
132
  getFormatedText,
92
133
  getBorderColor,
93
134
  backgroundColor,
94
- doughnutRef
135
+ doughnutRef,
95
136
  };
96
137
  }
@@ -1,6 +1,6 @@
1
1
  import type { Chart, RadialLinearScale } from 'chart.js';
2
2
 
3
- export function drawLabels (chart: Chart, props: any) {
3
+ export function drawLabels(chart: Chart, props: any) {
4
4
  const ctx = chart.ctx;
5
5
  const scale = chart.scales.r as RadialLinearScale;
6
6
  const labels = chart.data.labels as string[][];
@@ -14,37 +14,39 @@ export function drawLabels (chart: Chart, props: any) {
14
14
  const angle = (scale.getIndexAngle(index) - Math.PI / 2) % (2 * Math.PI);
15
15
  const position = scale.getPointPositionForValue(index, scale.max);
16
16
 
17
- ctx.textAlign = angle <= Math.PI / 2 || angle > 3 * Math.PI / 2 ? 'left' : 'right';
18
- let xOffset = angle <= Math.PI / 2 || angle > 3 * Math.PI / 2 ? 15 : -15;
17
+ ctx.textAlign =
18
+ angle <= Math.PI / 2 || angle > (3 * Math.PI) / 2 ? 'left' : 'right';
19
+ let xOffset = angle <= Math.PI / 2 || angle > (3 * Math.PI) / 2 ? 15 : -15;
19
20
 
20
21
  let yOffset;
21
22
  //top or bottom labels
22
- if ( angle < 0 || angle > Math.PI) {
23
+ if (angle < 0 || angle > Math.PI) {
23
24
  yOffset = -15;
24
25
  } else {
25
26
  yOffset = 15;
26
27
  }
27
28
 
28
29
  //bottom labels
29
- if ( angle > Math.PI / 4 && angle < 3 * Math.PI / 4) {
30
+ if (angle > Math.PI / 4 && angle < (3 * Math.PI) / 4) {
30
31
  yOffset *= 3;
31
32
  }
32
33
 
33
34
  //top labels left and right
34
- if ( angle < -Math.PI / 4 || angle > 5 * Math.PI / 4) {
35
+ if (angle < -Math.PI / 4 || angle > (5 * Math.PI) / 4) {
35
36
  yOffset *= 3;
36
37
  xOffset = 0;
37
38
  }
38
39
 
39
40
  // full top label
40
- if ( angle > 11 * Math.PI / 8 || angle < -3 * Math.PI / 8){
41
+ if (angle > (11 * Math.PI) / 8 || angle < (-3 * Math.PI) / 8) {
41
42
  ctx.textAlign = 'center';
42
43
  }
43
- const yPos = position.y + yOffset * (label.length - 1) / 2;
44
+ const yPos = position.y + (yOffset * (label.length - 1)) / 2;
44
45
  ctx.font = '15px Arial';
45
46
 
46
47
  label.forEach((text, i) => {
47
- const color = i === label.length - 1 ? buildColorArray(props)[index] : '#000000';
48
+ const color =
49
+ i === label.length - 1 ? buildColorArray(props)[index] : '#000000';
48
50
  ctx.fillStyle = color;
49
51
 
50
52
  const x = position.x + xOffset;
@@ -56,8 +58,8 @@ export function drawLabels (chart: Chart, props: any) {
56
58
  ctx.restore();
57
59
  }
58
60
 
59
- const buildColorArray = (props: any): string[]=> {
60
- return props.areas[0].areaData.map((x: { color: string }) => {
61
+ const buildColorArray = (props: any): string[] => {
62
+ return props.datasets[0].areaData.map((x: { color: string }) => {
61
63
  switch (x.color) {
62
64
  case 'red':
63
65
  return '#C61112';
@@ -0,0 +1,6 @@
1
+ import { Meta, Markdown } from "@storybook/blocks";
2
+ import Changelog from "../../CHANGELOG.md?raw";
3
+
4
+ <Meta title="Changelog" />
5
+
6
+ <Markdown>{Changelog}</Markdown>
@@ -0,0 +1,101 @@
1
+ import { Meta } from "@storybook/blocks";
2
+ import { Mermaid } from "mdx-mermaid/Mermaid";
3
+
4
+ <Meta title="Contributing" />
5
+
6
+ # Be part of something bigger!
7
+
8
+ **Mozaic-Chart** is made possible by an incredible community that finds issues and creates pull requests.<br/>
9
+ It is our job to enable you to create amazing applications.
10
+
11
+ Most of the time, you find something that can be made better. You could find a bug, or you have an idea for additional functionality.<br/>
12
+ That's great! It's as easy as cloning the [mozaic-chart repository](https://github.com/adeo/mozaic-chart) to get started working in the development environment.
13
+
14
+ Hopefully this document makes the process for contributing clear and answers some questions that you may have.<br/>
15
+ If you have any questions, please reach out to us on our [slack channel](https://adeo-tech-community.slack.com/archives/CN4K3A99R).
16
+
17
+ ## Contribution model
18
+
19
+ The contribution process can be summarized as follows:
20
+
21
+ <Mermaid
22
+ chart={`flowchart TD;
23
+ A((I have a need <br/>fix or new feature));
24
+ A --> B{An issue already exists?};
25
+ B --> |YES| I;
26
+ I([The issue corresponds to my needs <br/>or I complete it]);
27
+ I --> D;
28
+ B --> |NO| C;
29
+ C([I create an issue <br/>]);
30
+ C --> D;
31
+ D{I can contribute?};
32
+ D --> |YES| E;
33
+ D --> |NO| J;
34
+ E([I clone the repo <br/>& create a PR associated to the issue]);
35
+ E --> F;
36
+ F([The PR is ready <br/>and I assign it to reviewers]);
37
+ F --> G;
38
+ G{The proofreading is OK <br/>and the PR is validated?};
39
+ G --> |YES| H;
40
+ G --> |NO| K;
41
+ H([The PR is merged and will be released soon]);
42
+ H;
43
+ J([In this case, I wait for the issue <br/>to be traited and delivered.]);
44
+ K([I make the requested changes]);
45
+ K --> F;
46
+ click B "https://github.com/adeo/mozaic-chart/issues" _blank;
47
+ click C "https://github.com/adeo/mozaic-chart/issues/new/choose" _blank;
48
+ `}
49
+ />
50
+
51
+ You can now discover the details of each of these steps below.
52
+
53
+ ## Reporting issues
54
+
55
+ ### Where to find known issues
56
+
57
+ We are using [GitHub Issues](https://github.com/adeo/mozaic-chart/issues) for our bugs.<br/>
58
+ We keep a close eye on this and try to make it clear when we have an internal fix in progress.<br/>
59
+
60
+ **Before filing a new task, try to make sure your problem doesn't already exist.**
61
+
62
+ ### Reporting new issue
63
+
64
+ The best way to get your bug fixed is to provide a reduced test case.
65
+
66
+ Once you've gathered all information, please fill out an issue [here](https://github.com/adeo/mozaic-chart/issues/new/choose).
67
+
68
+ ## Proposing a change
69
+
70
+ If you intend to add a new component, or make any non-trivial changes, we recommend filing an issue.
71
+
72
+ This will lets us prepare an agreement on your proposal before you put significant effort into it.
73
+
74
+ If you’re only fixing a bug, it should be fine to submit a pull request but we still recommend to submit an issue detailing what you’re looking to fix.
75
+
76
+ ## Setup Dev Environment
77
+
78
+ ### Project setup
79
+
80
+ ```bash
81
+ // Clone mozaic-chart repo
82
+ git clone git@github.com:adeo/mozaic-chart.git
83
+
84
+ // Go to the cloned directory
85
+ cd mozaic-chart
86
+
87
+ // Checkout the branch you are working on
88
+ git checkout <branch name>
89
+
90
+ // Install dependencies
91
+ npm install
92
+ ```
93
+
94
+ ## Submitting Changes/ Pull Requests
95
+
96
+ Working on your first Pull Request?<br/>
97
+ You can learn how from this video series:
98
+ [How to contribute to an open source project on Github](https://egghead.io/courses/how-to-contribute-to-an-open-source-project-on-github).
99
+
100
+ Mozaic's team is keeping an eye on pull requests.<br/>
101
+ We will check your pull request, either merge it, request changes or close it with explanation.
@@ -0,0 +1,92 @@
1
+ import { Meta } from "@storybook/blocks";
2
+ import { Badge, OutlineCTA, Link } from "@storybook/design-system";
3
+ import pkg from "../../package.json";
4
+
5
+ <Meta title="Getting Started" />
6
+
7
+ <style>
8
+ {`
9
+ .outlineCTA {
10
+ margin: 16px auto;
11
+ display: flex;
12
+ align-items: center;
13
+ gap: 4px;
14
+ }
15
+ .outlineCTA span {
16
+ font-size: 14px;
17
+ }
18
+ .outlineCTA p {
19
+ margin: 0;
20
+ }
21
+ `}
22
+ </style>
23
+
24
+ # Getting Started
25
+
26
+ **Mozaic-Chart** is the [Chart.js](https://vuejs.org/) implementation for [Vue.js](https://vuejs.org/) of [Mozaic Design System Dataviz](https://mozaic.adeo.cloud/)
27
+
28
+ <OutlineCTA
29
+ className="outlineCTA"
30
+ badge={<Badge status="positive">Vue.js 3</Badge>}
31
+ >
32
+ Note that this package is built to be used only with <strong>Vue.js 3</strong>
33
+ </OutlineCTA>
34
+
35
+ ## Installation
36
+
37
+ > **PREREQUISITES:**<br/>
38
+ > To allow you to include and use our package, we assume that you are using a module bundlers like [Webpack](https://webpack.js.org/), [Parcel](https://parceljs.org/) or [rollup.js](https://rollupjs.org/guide/en/), or that your project has been initiated with [Vue CLI >= 5](https://cli.vuejs.org/) or [Vite](https://vitejs.dev/guide/). Otherwise, the package might not work.<br/>
39
+ > Minimum Vue.js version required: **{pkg.dependencies.vue.slice(1)}**
40
+
41
+ In order to use **Mozaic-Chart** in your **Vue.js** project, you must first install the [npm package](https://www.npmjs.com/package/@mozaic-ds/chart):
42
+
43
+ ```bash
44
+ npm install @mozaic-ds/chart --save --save-exact
45
+ ```
46
+
47
+ Or with **Yarn**:
48
+
49
+ ```bash
50
+ yarn add @mozaic-ds/chart -E
51
+ ```
52
+
53
+ ## Set up
54
+
55
+ After installing **Mozaic-Chart**, you need to set up the library.
56
+
57
+ The easiest way to do this is to import all components and make them globally available in your application.
58
+
59
+ In your entry point file, insert the following code:
60
+
61
+ ```javascript
62
+ // In the entry point file of your application - usually src/main.js
63
+
64
+ import MozaicChart from "@mozaic-ds/chart";
65
+ import "@mozaic-ds/chart/dist/style.css";
66
+
67
+ Vue.use(MozaicChart);
68
+ ```
69
+
70
+ <br />
71
+
72
+ ### Global/local component registration
73
+
74
+ As indicated in [its documentation](https://vuejs.org/guide/components/registration.html), **Vue.js** proposes to register/import the components in a global or local way:
75
+
76
+ - The global import allows you to make your components accessible throughout your application
77
+ - The local import, on the other hand, makes a component accessible only in the part of the application that uses it
78
+
79
+ > Learn more about the notion of global/local registration on [the associated Vue.js documentation](https://vuejs.org/guide/components/registration.html).
80
+
81
+ {/* > Learn more about how to import globally or locally the components of **Mozaic-Chart** into your project, by visiting [the dedicated documentation](?path=/docs/importing-components--docs). */}
82
+
83
+ ## Usage
84
+
85
+ That's it! You’re all set! ✅ <br/>
86
+ You are now able to use the **Mozaic-Chart** components in your **Vue.js** project.
87
+
88
+ Simply call the component as follows:
89
+
90
+ ```vue-html
91
+ <BarChart :labels="labels" :datasets="datasets" />
92
+ ```
@@ -0,0 +1,44 @@
1
+ import { Meta } from "@storybook/blocks";
2
+ import { Button } from "@storybook/design-system";
3
+
4
+ <Meta
5
+ title="Support & Onboarding"
6
+ parameters={{
7
+ layout: "fullscreen",
8
+ viewMode: "docs",
9
+ previewTabs: {
10
+ canvas: { hidden: true },
11
+ },
12
+ }}
13
+ />
14
+
15
+ # Need help?
16
+
17
+ ## Support
18
+
19
+ Any feedback, ideas or questions?
20
+
21
+ The **Mozaic Design System team** would welcome any feedback, ideas, or requirements that you have.<br/>
22
+ Our goal is to make your lives easier.
23
+
24
+ If you want to get more detailed information on the components or any other topic related to **Mozaic-Vue**, you can contact us through the channels below:
25
+
26
+ - Join the [#ads-charts](https://app.slack.com/client/T4R6RCZFA/C04DE3DN8LD) channel on **Slack**
27
+ - Join the [#mozaic-support](https://app.slack.com/client/T4R6RCZFA/CKQJZL7C4/) channel on **Slack**
28
+
29
+ ## Onboarding Sessions
30
+
31
+ Are you new to using a design system, and in particular Mozaic?<br/>
32
+ Do you want to know more about how **Mozaic** works, and more specifically how to use **Mozaic-Vue**?<br/>
33
+ You need a personalized support to install or configure your project?
34
+
35
+ The **Mozaic Design System team** is at your disposal for that.
36
+
37
+ Do not hesitate to book a slot for **an onboarding session**, by going to this url:
38
+
39
+ <Button
40
+ appearance="secondary"
41
+ isLink
42
+ href="https://calendar.app.google/Tk9JkMdKTzM2DeX36"
43
+ target="_blank"
44
+ >{`I book an Onboarding Session`}</Button>
package/src/App.vue DELETED
@@ -1,80 +0,0 @@
1
- <template>
2
- <div>
3
- <h1>Ouais Ouais Ouais !</h1>
4
- <BarChart v-bind="barProps" />
5
- </div>
6
- </template>
7
-
8
- <script setup lang="ts">
9
- import { reactive } from "vue";
10
- // import { BarChart } from "./components";
11
-
12
- const barProps = reactive({
13
- width: "500px",
14
- height: "400px",
15
- rawTitle: "Bar title",
16
- firstTooltip: "content",
17
- secondTooltip: "content2",
18
- disableAccessibility: false,
19
- newPatternsOrder: [0, 4, 1, 2, 3, 5],
20
- labels: ["Data One", "Data Two", "Data Three"],
21
- colourSet: 0,
22
- datasets: [
23
- {
24
- label: "Data One",
25
- data: [
26
- {
27
- amount: 163790.23,
28
- rate: 1.719528,
29
- amountUnit: "€",
30
- },
31
- {
32
- amount: 217064,
33
- rate: 2.278815,
34
- amountUnit: "€",
35
- },
36
- {
37
- amount: 9144447.23,
38
- rate: 96.0016569,
39
- amountUnit: "€",
40
- },
41
- ],
42
- },
43
- {
44
- label: "Data Two",
45
- data: [
46
- {
47
- amount: 103144.22,
48
- rate: 1.1232806,
49
- amountUnit: "€",
50
- },
51
- {
52
- amount: 297474.14,
53
- rate: 3.2396087,
54
- amountUnit: "€",
55
- },
56
- {
57
- amount: 8781791.1,
58
- rate: 95.6371107,
59
- amountUnit: "€",
60
- },
61
- ],
62
- },
63
- ],
64
- unit: "%",
65
- });
66
- </script>
67
-
68
- <style scoped>
69
- .logo {
70
- height: 6em;
71
- padding: 1.5em;
72
- will-change: filter;
73
- }
74
- .logo:hover {
75
- filter: drop-shadow(0 0 2em #646cffaa);
76
- }
77
- .logo.vue:hover {
78
- filter: drop-shadow(0 0 2em #42b883aa);
79
- }
80
- </style>