diff --git a/demo/index.html b/demo/index.html
index e4eb1d2..47fc91d 100644
--- a/demo/index.html
+++ b/demo/index.html
@@ -28,16 +28,21 @@
pre-selected range with 1000ms debounce delay
@@ -98,7 +103,7 @@
"
minDate="05 May 1972"
maxDate="21 Dec 1980"
- bins="[ 85, 25, 200, 0, 0, 34, 0, 2, 5, 10, 0, 56, 10, 45, 100, 70, 50 ]"
+ bins="[85, 25, 200, 34, 10, 56, 10, 45 ,11]"
>
@@ -107,10 +112,10 @@
@@ -137,8 +142,8 @@
);
histogram.minDate = '1950';
histogram.maxDate = '2000';
- // generate array of [0, 1, 2, ... 49]
- histogram.bins = [...Array(50).keys()];
+ // generate array of [0, 1, 2, ... 46]
+ histogram.bins = [...Array(51).keys()];
});
diff --git a/src/histogram-date-range.ts b/src/histogram-date-range.ts
index 4cf99ec..a497588 100644
--- a/src/histogram-date-range.ts
+++ b/src/histogram-date-range.ts
@@ -107,6 +107,7 @@ export class HistogramDateRange extends LitElement {
private _histData: HistogramItem[] = [];
private _emitUpdatedEventTimer?: ReturnType;
private _previousDateRange = '';
+ private _dateFormatYear = true;
/* eslint-enable lines-between-class-members */
@@ -141,6 +142,7 @@ export class HistogramDateRange extends LitElement {
if (!this.hasBinData) {
return;
}
+ this._dateFormatYear = this.dateFormat === 'YYYY' ? true : false;
this._histWidth = this.width - this.sliderWidth * 2;
this._minDateMS = this.getMSFromString(this.minDate);
this._maxDateMS = this.getMSFromString(this.maxDate);
@@ -255,16 +257,36 @@ export class HistogramDateRange extends LitElement {
/** horizontal position of min date slider */
get minSliderX(): number {
- const x = this.translateDateToPosition(this.minSelectedDate);
+ const x = this._dateFormatYear
+ ? this.translateDateToPositionForMin(this.minSelectedDate)
+ : this.translateDateToPosition(this.minSelectedDate);
return this.validMinSliderX(x);
}
/** horizontal position of max date slider */
get maxSliderX(): number {
- const x = this.translateDateToPosition(this.maxSelectedDate);
+ const x = this._dateFormatYear
+ ? this.translateDateToPositionForMax(this.maxSelectedDate)
+ : this.translateDateToPosition(this.maxSelectedDate);
return this.validMaxSliderX(x);
}
+ /**
+ * number of slider movement
+ */
+ private get noSliderMove(): number {
+ let maxDate = Number(this.maxDate);
+ const dateRange = maxDate - Number(this.minDate);
+
+ // check difference value is odd or even
+ // if diff is even increment mindate by ones
+ if (this._numBins !== dateRange) {
+ maxDate = maxDate + 1;
+ }
+ const maxDateCus = this.getMSFromString(maxDate);
+ return maxDateCus - this._minDateMS;
+ }
+
private get dateRangeMS(): number {
return this._maxDateMS - this._minDateMS;
}
@@ -335,6 +357,10 @@ export class HistogramDateRange extends LitElement {
this.maxSelectedDate = this.translatePositionToDate(
this.validMaxSliderX(newX)
);
+ this.maxSelectedDate =
+ this.maxSelectedDate <= this.maxDate
+ ? this.maxSelectedDate
+ : this.maxDate;
}
};
@@ -350,7 +376,9 @@ export class HistogramDateRange extends LitElement {
// allow the left slider to go right only to the right slider, even if the
// max selected date is out of range
const rightLimit = Math.min(
- this.translateDateToPosition(this.maxSelectedDate),
+ this._dateFormatYear
+ ? this.translateDateToPositionForMin(this.maxSelectedDate)
+ : this.translateDateToPosition(this.maxSelectedDate),
this.histogramRightEdgeX
);
newX = this.clamp(newX, this.histogramLeftEdgeX, rightLimit);
@@ -371,8 +399,10 @@ export class HistogramDateRange extends LitElement {
// allow the right slider to go left only to the left slider, even if the
// min selected date is out of range
const leftLimit = Math.max(
- this.histogramLeftEdgeX,
- this.translateDateToPosition(this.minSelectedDate)
+ this.histogramLeftEdgeX - this._binWidth,
+ this._dateFormatYear
+ ? this.translateDateToPositionForMin(this.minSelectedDate)
+ : this.translateDateToPosition(this.minSelectedDate)
);
newX = this.clamp(newX, leftLimit, this.histogramRightEdgeX);
const isInvalid =
@@ -408,7 +438,10 @@ export class HistogramDateRange extends LitElement {
const options = {
detail: {
minDate: this.minSelectedDate,
- maxDate: this.maxSelectedDate,
+ maxDate:
+ this.maxSelectedDate <= this.maxDate
+ ? this.maxSelectedDate
+ : this.maxDate,
},
bubbles: true,
composed: true,
@@ -446,13 +479,15 @@ export class HistogramDateRange extends LitElement {
// use Math.ceil to round up to fix case where input like 1/1/2010 would get
// translated to 12/31/2009
const milliseconds = Math.ceil(
- ((x - this.sliderWidth) * this.dateRangeMS) / this._histWidth
+ ((x - this.sliderWidth) *
+ (this._dateFormatYear ? this.noSliderMove : this.dateRangeMS)) /
+ this._histWidth
);
return this.formatDate(this._minDateMS + milliseconds);
}
/**
- * Returns slider x-position corresponding to given date
+ * Returns both slider x-position corresponding to given date
*
* @param date
* @returns x-position of slider
@@ -465,6 +500,41 @@ export class HistogramDateRange extends LitElement {
);
}
+ /**
+ * Returns min slider x-position corresponding to given date
+ *
+ * @param date
+ * @returns x-position of slider
+ */
+ private translateDateToPositionForMin(date: string): number {
+ const milliseconds = this.getMSFromString(date);
+ return (
+ this.sliderWidth +
+ ((milliseconds - this._minDateMS) * this._histWidth) /
+ (this._dateFormatYear ? this.noSliderMove : this.dateRangeMS)
+ );
+ }
+
+ /**
+ * Returns max slider x-position corresponding to given date
+ *
+ * @param date
+ * @returns x-position of slider
+ */
+ private translateDateToPositionForMax(date: string): number {
+ const setCustomDate = Number(date) == Number(this.maxDate);
+ const milliseconds = this.getMSFromString(
+ setCustomDate ? String(Number(date) + 1) : date
+ );
+
+ return (
+ this.sliderWidth +
+ this._binWidth +
+ ((milliseconds - this._minDateMS) * this._histWidth) /
+ (this._dateFormatYear ? this.noSliderMove : this.dateRangeMS)
+ );
+ }
+
/** ensure that the returned value is between minValue and maxValue */
private clamp(x: number, minValue: number, maxValue: number): number {
return Math.min(Math.max(x, minValue), maxValue);
@@ -539,14 +609,21 @@ export class HistogramDateRange extends LitElement {
this.getMSFromString(dataset.binEnd)) /
2;
const distanceFromMinSlider = Math.abs(
- clickPosition - this.getMSFromString(this.minSelectedDate)
+ clickPosition -
+ this.getMSFromString(
+ this._dateFormatYear
+ ? Number(this.minSelectedDate) - 1
+ : this.minSelectedDate
+ )
);
const distanceFromMaxSlider = Math.abs(
clickPosition - this.getMSFromString(this.maxSelectedDate)
);
// update the selected range by moving the nearer slider
if (distanceFromMinSlider < distanceFromMaxSlider) {
- this.minSelectedDate = dataset.binStart;
+ this.minSelectedDate = this._dateFormatYear
+ ? dataset.binEnd
+ : dataset.binStart;
} else {
this.maxSelectedDate = dataset.binEnd;
}
@@ -637,7 +714,7 @@ export class HistogramDateRange extends LitElement {
get histogramTemplate(): SVGTemplateResult[] {
const xScale = this._histWidth / this._numBins;
const barWidth = xScale - 1;
- let x = this.sliderWidth; // start at the left edge of the histogram
+ let x = this.sliderWidth + 0.5; // start at the left edge of the histogram
// the stroke-dasharray style below creates a transparent border around the
// right edge of the bar, which prevents user from encountering a gap
@@ -799,7 +876,7 @@ export class HistogramDateRange extends LitElement {
bars */
stroke: rgba(0, 0, 0, 0);
/* ensure transparent stroke wide enough to cover gap between bars */
- stroke-width: 2px;
+ stroke-width: 1px;
}
.bar:hover {
/* highlight currently hovered bar */