diff --git a/.size-limit.json b/.size-limit.json
index 5261dc91..b9e90c47 100644
--- a/.size-limit.json
+++ b/.size-limit.json
@@ -1,7 +1,7 @@
[
{
"path": "dist/index.js",
- "limit": "1.7 KB",
+ "limit": "1.9 KB",
"webpack": false,
"running": false
},
diff --git a/sandboxes/events/index.html b/sandboxes/events/index.html
new file mode 100644
index 00000000..087b841f
--- /dev/null
+++ b/sandboxes/events/index.html
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/sandboxes/events/index.ts b/sandboxes/events/index.ts
new file mode 100644
index 00000000..52c7b68b
--- /dev/null
+++ b/sandboxes/events/index.ts
@@ -0,0 +1,4 @@
+import { createApp } from 'vue'
+import App from './src/App.vue'
+
+createApp(App).mount('#app')
diff --git a/sandboxes/events/package.json b/sandboxes/events/package.json
new file mode 100644
index 00000000..df369262
--- /dev/null
+++ b/sandboxes/events/package.json
@@ -0,0 +1,16 @@
+{
+ "type": "module",
+ "scripts": {
+ "start": "vite"
+ },
+ "dependencies": {
+ "chart.js": "^4.0.0",
+ "vue": "^3.2.31",
+ "vue-chartjs": "^5.0.0"
+ },
+ "devDependencies": {
+ "@vitejs/plugin-vue": "^3.0.1",
+ "typescript": "^4.9.3",
+ "vite": "^3.2.4"
+ }
+}
diff --git a/sandboxes/events/src/App.vue b/sandboxes/events/src/App.vue
new file mode 100644
index 00000000..11e991ce
--- /dev/null
+++ b/sandboxes/events/src/App.vue
@@ -0,0 +1,89 @@
+
+
+
+
+
diff --git a/sandboxes/events/src/chartConfig.ts b/sandboxes/events/src/chartConfig.ts
new file mode 100644
index 00000000..514c046d
--- /dev/null
+++ b/sandboxes/events/src/chartConfig.ts
@@ -0,0 +1,28 @@
+export const data = {
+ labels: [
+ 'January',
+ 'February',
+ 'March',
+ 'April',
+ 'May',
+ 'June',
+ 'July',
+ 'August',
+ 'September',
+ 'October',
+ 'November',
+ 'December'
+ ],
+ datasets: [
+ {
+ label: 'Data One',
+ backgroundColor: '#f87979',
+ data: [40, 20, 12, 39, 10, 40, 39, 80, 40, 20, 12, 11]
+ }
+ ]
+}
+
+export const options = {
+ responsive: true,
+ maintainAspectRatio: false
+}
diff --git a/sandboxes/events/vite.config.js b/sandboxes/events/vite.config.js
new file mode 100644
index 00000000..2e3d2576
--- /dev/null
+++ b/sandboxes/events/vite.config.js
@@ -0,0 +1,6 @@
+import { defineConfig } from 'vite'
+import vue from '@vitejs/plugin-vue'
+
+export default defineConfig({
+ plugins: [vue()]
+})
diff --git a/src/index.ts b/src/index.ts
index 26f802d1..7d85bfff 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -12,6 +12,11 @@ import {
} from './typedCharts.js'
export type { ChartProps, ChartComponentRef } from './types.js'
+export {
+ getDatasetAtEvent,
+ getElementAtEvent,
+ getElementsAtEvent
+} from './utils.js'
export {
Chart,
createTypedChart,
diff --git a/src/utils.ts b/src/utils.ts
index 49f1c7fb..50728a5c 100644
--- a/src/utils.ts
+++ b/src/utils.ts
@@ -91,3 +91,48 @@ export function cloneData<
return nextData
}
+
+/**
+ * Get dataset from mouse click event
+ * @param chart - Chart.js instance
+ * @param event - Mouse click event
+ * @returns Dataset
+ */
+export function getDatasetAtEvent(chart: Chart, event: MouseEvent) {
+ return chart.getElementsAtEventForMode(
+ event,
+ 'dataset',
+ { intersect: true },
+ false
+ )
+}
+
+/**
+ * Get single dataset element from mouse click event
+ * @param chart - Chart.js instance
+ * @param event - Mouse click event
+ * @returns Dataset
+ */
+export function getElementAtEvent(chart: Chart, event: MouseEvent) {
+ return chart.getElementsAtEventForMode(
+ event,
+ 'nearest',
+ { intersect: true },
+ false
+ )
+}
+
+/**
+ * Get all dataset elements from mouse click event
+ * @param chart - Chart.js instance
+ * @param event - Mouse click event
+ * @returns Dataset
+ */
+export function getElementsAtEvent(chart: Chart, event: MouseEvent) {
+ return chart.getElementsAtEventForMode(
+ event,
+ 'index',
+ { intersect: true },
+ false
+ )
+}
diff --git a/stories/chart.stories.ts b/stories/chart.stories.ts
new file mode 100644
index 00000000..df91040a
--- /dev/null
+++ b/stories/chart.stories.ts
@@ -0,0 +1,101 @@
+import 'chart.js/auto'
+import type { InteractionItem } from 'chart.js'
+import { ref } from 'vue'
+import {
+ ChartComponentRef,
+ Chart,
+ getDatasetAtEvent,
+ getElementAtEvent,
+ getElementsAtEvent
+} from '../src/index.js'
+import * as barChartConfig from '../sandboxes/bar/src/chartConfig.js'
+
+export default {
+ title: 'Chart',
+ component: Chart,
+ parameters: {
+ layout: 'centered'
+ }
+}
+
+export function Default(args) {
+ return {
+ components: { Chart },
+ template: '',
+ setup() {
+ return { args }
+ }
+ }
+}
+
+Default.args = {
+ id: 'bar-chart',
+ type: 'bar',
+ width: 400,
+ height: 400,
+ ...barChartConfig
+}
+
+export function Events(args) {
+ return {
+ components: { Chart },
+ template: '',
+ setup() {
+ const datasetAtEvent = (dataset: InteractionItem[]) => {
+ if (!dataset.length) return
+
+ const datasetIndex = dataset[0].datasetIndex
+
+ console.log('dataset', barChartConfig.data.datasets[datasetIndex].label)
+ }
+
+ const elementAtEvent = (element: InteractionItem[]) => {
+ if (!element.length) return
+
+ const { datasetIndex, index } = element[0]
+
+ console.log(
+ 'element',
+ barChartConfig.data.labels[index],
+ barChartConfig.data.datasets[datasetIndex].data[index]
+ )
+ }
+
+ const elementsAtEvent = (elements: InteractionItem[]) => {
+ if (!elements.length) return
+
+ console.log('elements', elements)
+ }
+
+ const chartRef = ref(null)
+
+ const onClick = (event: MouseEvent) => {
+ const {
+ value: { chart }
+ } = chartRef
+
+ if (!chart) {
+ return
+ }
+
+ datasetAtEvent(getDatasetAtEvent(chart, event))
+ elementAtEvent(getElementAtEvent(chart, event))
+ elementsAtEvent(getElementsAtEvent(chart, event))
+ }
+
+ return {
+ chartRef,
+ args,
+ onClick
+ }
+ }
+ }
+}
+
+Events.args = {
+ id: 'bar-chart',
+ type: 'bar',
+ width: 400,
+ height: 400,
+ ...barChartConfig
+}