Skip to content

Commit b1ca53f

Browse files
committed
Added range
1 parent 987f252 commit b1ca53f

File tree

5 files changed

+161
-58
lines changed

5 files changed

+161
-58
lines changed

.gitignore

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
lib/*
2-
node_modules/*
1+
node_modules
2+
lib

README.md

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -15,20 +15,27 @@ Enable it in the settings of a chart
1515
type: "bar",
1616
options: {
1717
plugins: {
18-
selectdrag: {
19-
enabled: true,
20-
onSelectComplete: (event) => {
21-
// Show selected
22-
document.getElementById('results').innerHTML = event.range;
18+
selectdrag: {
19+
enabled: true,
20+
output: 'value', // Can be 'value' or 'label'
21+
highlight: false, // Highlight the selected data on the chart?
22+
colors: {
23+
selection: "#e8eff6", // Background color of selection box
24+
selected: "#1f77b4", // Color of selected data
25+
unselected: "#cccccc" // Color of unselected data
26+
},
27+
onSelectComplete: (event) => {
28+
// Show selected
29+
document.getElementById('results').innerHTML = event.range;
2330
24-
// Get selected range
25-
console.log(event.range);
26-
27-
// Get selection coordinates
28-
console.log(event.boundingBox);
29-
}
30-
}
31-
},
31+
// Get selected range
32+
console.log(event.range);
33+
34+
// Get selection coordinates
35+
console.log(event.boundingBox);
36+
}
37+
}
38+
},
3239
},
3340
data: {
3441
labels: [],

package-lock.json

Lines changed: 21 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@01coder/chartjs-plugin-selectdrag",
3-
"version": "1.0.3",
3+
"version": "1.0.4",
44
"description": "Chartjs plugin which allows you to select a range of data by dragging over a chart",
55
"main": "lib/index.js",
66
"types": "lib/index.d.ts",
@@ -15,6 +15,7 @@
1515
"author": "Luke Tinnion",
1616
"license": "ISC",
1717
"devDependencies": {
18+
"chart.js": "^4.4.8",
1819
"typescript": "^4.8.2"
1920
},
2021
"keywords": [
@@ -33,6 +34,5 @@
3334
"homepage": "https://github.com/01CodeLT/chartjs-plugin-selectdrag#readme",
3435
"directories": {
3536
"lib": "lib"
36-
},
37-
"dependencies": {}
37+
}
3838
}

src/index.ts

Lines changed: 115 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,21 @@ const getState = (chart) => {
66
}
77
const setState = (chart, updatedState) => {
88
const originalState = getState(chart);
9-
states.set(chart, Object.assign({}, originalState, updatedState));
9+
states.set(
10+
chart,
11+
updatedState == null ? null : Object.assign({}, originalState, updatedState)
12+
);
1013
return updatedState;
1114
}
1215

1316
// Store options
1417
const pluginOptions = {
18+
output: 'label',
19+
highlight: true,
1520
colors: {
16-
selection: "#e8eff6", selectedElements: "#1f77b4", unselectedElements: "#cccccc"
21+
selection: "#e8eff6",
22+
selected: "#1f77b4", // Unused if backgroundColorDefault set on dataset
23+
unselected: "#cccccc"
1724
}
1825
};
1926

@@ -36,18 +43,31 @@ export default {
3643
const axisElements = chart.getElementsAtEventForMode(e, "index", { intersect: false });
3744
if(axisElements.length === 0) { return; }
3845

39-
// Get axis value
40-
const axisIndex = chart.getElementsAtEventForMode(e, "index", { intersect: false })[0].index;
41-
const axisValue = chart.data.labels[axisIndex];
42-
43-
// Set selection origin
44-
setState(chart, {
46+
// Create state
47+
const state = {
4548
selectionXY: {
4649
drawing: true,
47-
start: { axisValue, axisIndex, x: e.offsetX, y: e.offsetY },
50+
start: { axisValue: null, axisIndex: null, x: e.offsetX, y: e.offsetY },
4851
end: {}
4952
}
50-
});
53+
};
54+
55+
// Get axis value
56+
const output = chart?.config?.options?.plugins?.selectdrag?.output || pluginOptions.output;
57+
({
58+
'label': () => {
59+
const axisIndex = chart.getElementsAtEventForMode(e, "index", { intersect: false })[0].index;
60+
state.selectionXY.start.axisIndex = axisIndex;
61+
state.selectionXY.start.axisValue = chart.data.labels[axisIndex];
62+
},
63+
'value': () => {
64+
// Get value by scale
65+
state.selectionXY.start.axisValue = chart.scales.x.getValueForPixel(e.offsetX);
66+
},
67+
})[output]();
68+
69+
// Set selection origin
70+
setState(chart, state);
5171
});
5272

5373
// Draw end
@@ -59,19 +79,39 @@ export default {
5979
}
6080

6181
// Get axis value
62-
const axisElements = chart.getElementsAtEventForMode(e, "index", { intersect: false });
63-
const axisIndex = axisElements.length > 0 ? axisElements[0].index : chart.data.labels.length - 1;
64-
const axisValue = chart.data.labels[axisIndex];
65-
66-
// Check values & set end origin
67-
if(state.selectionXY.start.axisIndex > axisIndex) {
68-
// Switch values - user has selected opposite way
69-
state.selectionXY.end = JSON.parse(JSON.stringify(state.selectionXY.start));
70-
state.selectionXY.start = { axisValue, axisIndex, x: e.offsetX, y: e.offsetY }
71-
} else {
72-
// Set end origin
73-
state.selectionXY.end = { axisValue, axisIndex, x: e.offsetX, y: e.offsetY };
74-
}
82+
const output = chart?.config?.options?.plugins?.selectdrag?.output || pluginOptions.output;
83+
({
84+
'label': () => {
85+
// Get value by label
86+
const axisElements = chart.getElementsAtEventForMode(e, "index", { intersect: false });
87+
const axisIndex = axisElements.length > 0 ? axisElements[0].index : chart.data.labels.length - 1;
88+
const axisValue = chart.data.labels[axisIndex];
89+
90+
// Check values & set end origin
91+
if(state.selectionXY.start.axisIndex > axisIndex) {
92+
// Switch values - user has selected opposite way
93+
state.selectionXY.end = JSON.parse(JSON.stringify(state.selectionXY.start));
94+
state.selectionXY.start = { axisValue, axisIndex, x: e.offsetX, y: e.offsetY }
95+
} else {
96+
// Set end origin
97+
state.selectionXY.end = { axisValue, axisIndex, x: e.offsetX, y: e.offsetY };
98+
}
99+
},
100+
'value': () => {
101+
// Get value by scale
102+
const axisValue = chart.scales.x.getValueForPixel(e.offsetX);
103+
104+
// Check values & set end origin
105+
if(state.selectionXY.start.axisValue > axisValue) {
106+
// Switch values - user has selected opposite way
107+
state.selectionXY.end = JSON.parse(JSON.stringify(state.selectionXY.start));
108+
state.selectionXY.start = { axisValue, axisIndex: null, x: e.offsetX, y: e.offsetY }
109+
} else {
110+
// Set end origin
111+
state.selectionXY.end = { axisValue, axisIndex: null, x: e.offsetX, y: e.offsetY };
112+
}
113+
},
114+
})[output]();
75115

76116
// End drawing
77117
state.selectionXY.drawing = false;
@@ -125,22 +165,47 @@ export default {
125165
return;
126166
}
127167

168+
// Check if enabled
169+
const highlight = chart?.config?.options?.plugins?.selectdrag?.highlight;
170+
if(highlight !== undefined && highlight == false) { return; }
171+
128172
// Check drawing status
129173
const state = getState(chart);
130174

175+
// Color based on output
176+
const output = chart?.config?.options?.plugins?.selectdrag?.output || pluginOptions.output;
177+
const colors = chart?.config?.options?.plugins?.selectdrag?.colors || pluginOptions.colors;
178+
const backgroundColorCallback = {
179+
'label': (value, index, defaultColor) => {
180+
// Show selected/unselected
181+
if(index >= state.selectionXY.start?.axisIndex && index <= state.selectionXY.end?.axisIndex) {
182+
return defaultColor;
183+
} else {
184+
return colors.unselected;
185+
}
186+
},
187+
'value': (value, index, defaultColor) => {
188+
// Show selected/unselected
189+
const v = value.x || value;
190+
if(v >= state.selectionXY.start?.axisValue && v <= state.selectionXY.end?.axisValue) {
191+
return defaultColor;
192+
} else {
193+
return colors.unselected;
194+
}
195+
}
196+
}[output];
197+
131198
// Set highlighted
132199
chart.data.datasets = chart.data.datasets.map((dataset) => {
133-
dataset.backgroundColor = chart.data.labels.map((value, index) => {
200+
dataset.backgroundColor = (
201+
output == 'value' ? dataset.data : chart.data.labels
202+
).map((value, index) => {
134203
if(!state || !state?.selectionXY?.start?.x || !state?.selectionXY?.end?.x) {
135204
// Show default
136-
return pluginOptions.colors.selectedElements;
205+
return dataset.backgroundColorDefault || colors.selected;
137206
} else {
138207
// Show selected/unselected
139-
if(index >= state.selectionXY.start?.axisIndex && index <= state.selectionXY.end?.axisIndex) {
140-
return pluginOptions.colors.selectedElements;
141-
} else {
142-
return pluginOptions.colors.unselectedElements;
143-
}
208+
return backgroundColorCallback(value, index, dataset.backgroundColorDefault || colors.selected);
144209
}
145210
});
146211
return dataset;
@@ -195,21 +260,33 @@ export default {
195260
}
196261
};
197262

263+
// Get output type
264+
const output = chart?.config?.options?.plugins?.selectdrag?.output || pluginOptions.output;
265+
const getValue = {
266+
'label': (v) => {
267+
const axisIndex = chart.data.labels.findIndex((item) => item === v);
268+
return { i: axisIndex, v: chart.data.labels[axisIndex] };
269+
},
270+
'value': (v) => {
271+
return { i: null, v: v.x || v };
272+
}
273+
}[output];
274+
198275
// Set start axis
199-
const startAxisIndex = chart.data.labels.findIndex((item) => item === range[0]);
276+
const startValue = getValue(range[0]);
200277
state.selectionXY.start = {
201-
axisValue: range[0],
202-
axisIndex: startAxisIndex,
203-
x: chart.scales.x.getPixelForValue(chart.data.labels[startAxisIndex]),
278+
axisValue: startValue.v,
279+
axisIndex: startValue.i,
280+
x: chart.scales.x.getPixelForValue(startValue.v),
204281
y: 0
205282
}
206283

207284
// Set end axis
208-
const endAxisIndex = chart.data.labels.findIndex((item) => item === range[1]);
285+
const endValue = getValue(range[1]);
209286
state.selectionXY.end = {
210-
axisValue: range[0],
211-
axisIndex: endAxisIndex,
212-
x: chart.scales.x.getPixelForValue(chart.data.labels[endAxisIndex]),
287+
axisValue: endValue.v,
288+
axisIndex: endValue.i,
289+
x: chart.scales.x.getPixelForValue(endValue.v),
213290
y: chart.chartArea.height
214291
}
215292

0 commit comments

Comments
 (0)