const chartData = { measureFieldName: "totalCases", seriesName: "City", category: ["2020-04-1 23:59:59", "2020-04-2 23:59:59", "2020-04-3 23:59:59", "2020-04-4 23:59:59", "2020-04-5 23:59:59", "2020-04-6 23:59:59", "2020-04-7 23:59:59", "2020-04-8 23:59:59", "2020-04-9 23:59:59", "2020-04-10 23:59:59", "2020-04-11 23:59:59", "2020-04-12 23:59:59"], data: { Delhi: [{ totalCases: 10 }, { totalCases: 14 }, { totalCases: 18 }, { totalCases: 15 }, { totalCases: 26 }, { totalCases: 18 }, { totalCases: 34 }, { totalCases: 20 }, { totalCases: 42 }, { totalCases: 28 }, { totalCases: 52 }, { totalCases: 35 }], Mumbai: [{ totalCases: 115 }, { totalCases: 130 }, { totalCases: 152 }, { totalCases: 160 }, { totalCases: 150 }, { totalCases: 190 }, { totalCases: 155 }, { totalCases: 220 }, { totalCases: 130 }, { totalCases: 250 }, { totalCases: 148 }, { totalCases: 220 }], Ahmedabad: [{ totalCases: 80 }, { totalCases: 90 }, { totalCases: 55 }, { totalCases: 110 }, { totalCases: 65 }, { totalCases: 130 }, { totalCases: 45 }, { totalCases: 150 }, { totalCases: 105 }, { totalCases: 172 }, { totalCases: 165 }, { totalCases: 160 }] } }; function getTicksCalculation(minDate, maxDate, typeOfTicks, startPoint, ticksFormat) { const distinctTicks = []; let startPointDate = d3.timeFormat("%Y-%m-%d 00:00:00")(new Date(startPoint)); let startPointIndex = 0; if (minDate != null && maxDate != null && typeOfTicks != null) { let startDate = new Date(minDate); let endDate = new Date(maxDate); switch (typeOfTicks) { case "month": { startDate = new Date(startDate.getFullYear(), startDate.getMonth(), 1, 23, 59, 59); endDate = new Date(endDate.getFullYear(), endDate.getMonth() + 1, 0); let startTime = startDate.getTime(); while (startTime <= endDate.getTime()) { const month = d3.timeFormat("%b")(new Date(startTime)); if (new Date(startTime).getMonth() == 0) { const displayName = ticksFormat != null && typeof ticksFormat == "function" ? ticksFormat({ startPoint: d3.timeFormat("%Y-%m-%d 23:59:59")(new Date(startTime)), endPoint: d3.timeFormat("%Y-%m-%d 23:59:59")(new Date(startTime)) }) : [`${month}`, `${new Date(startTime).getFullYear()}`]; distinctTicks.push({ title: `${d3.timeFormat("%d %b,%Y")(new Date(startTime))}`, data: `${d3.timeFormat("%Y-%m-%d 00:00:00")(new Date(startTime))}`, displayName: displayName }); } else { const displayName = ticksFormat != null && typeof ticksFormat == "function" ? ticksFormat({ startPoint: d3.timeFormat("%Y-%m-%d 23:59:59")(new Date(startTime)), endPoint: d3.timeFormat("%Y-%m-%d 23:59:59")(new Date(startTime)) }) : `${month}`; distinctTicks.push({ title: `${d3.timeFormat("%d %b,%Y")(new Date(startTime))}`, data: `${d3.timeFormat("%Y-%m-%d 00:00:00")(new Date(startTime))}`, displayName: displayName }); } startTime = new Date(startTime); startTime = new Date(startTime.setMonth(startTime.getMonth() + 1)).getTime(); } startPointDate = d3.timeFormat("%Y-%m-01 00:00:00")(new Date(startPoint)); break; } case "day": { let startTime = startDate.getTime(); while (startTime <= endDate.getTime()) { const date = d3.timeFormat("%d")(new Date(startTime)); const month = d3.timeFormat("%b")(new Date(startTime)); const monthYear = d3.timeFormat("%b-%Y")(new Date(startTime)); if (new Date(startTime).getDate() == 1 && new Date(startTime).getMonth() == 0) { const displayName = ticksFormat != null && typeof ticksFormat == "function" ? ticksFormat({ startPoint: d3.timeFormat("%Y-%m-%d 23:59:59")(new Date(startTime)), endPoint: d3.timeFormat("%Y-%m-%d 23:59:59")(new Date(startTime)) }) : [`${date}`, `${monthYear}`]; distinctTicks.push({ title: `${d3.timeFormat("%d %b,%Y")(new Date(startTime))}`, data: `${d3.timeFormat("%Y-%m-%d 00:00:00")(new Date(startTime))}`, displayName: displayName }); } else if (new Date(startTime).getDate() == 1) { const displayName = ticksFormat != null && typeof ticksFormat == "function" ? ticksFormat({ startPoint: d3.timeFormat("%Y-%m-%d 23:59:59")(new Date(startTime)), endPoint: d3.timeFormat("%Y-%m-%d 23:59:59")(new Date(startTime)) }) : [`${date}`, `${month}`]; distinctTicks.push({ title: `${d3.timeFormat("%d %b,%Y")(new Date(startTime))}`, data: `${d3.timeFormat("%Y-%m-%d 00:00:00")(new Date(startTime))}`, displayName: displayName }); } else { const displayName = ticksFormat != null && typeof ticksFormat == "function" ? ticksFormat({ startPoint: d3.timeFormat("%Y-%m-%d 23:59:59")(new Date(startTime)), endPoint: d3.timeFormat("%Y-%m-%d 23:59:59")(new Date(startTime)) }) : `${date}`; distinctTicks.push({ title: `${d3.timeFormat("%d %b,%Y")(new Date(startTime))}`, data: `${d3.timeFormat("%Y-%m-%d 00:00:00")(new Date(startTime))}`, displayName: displayName }); } startTime = new Date(startTime); startTime = new Date(startTime.setDate(startTime.getDate() + 1)).getTime(); } startPointDate = d3.timeFormat("%Y-%m-%d 00:00:00")(new Date(startPoint)); break; } case "week-sunday": { let startTime = startDate.getTime(); while (startTime <= endDate.getTime()) { const date = d3.timeFormat("%d")(new Date(startTime)); const month = d3.timeFormat("%b")(new Date(startTime)); startTime = new Date(startTime); const weekNumber = Math.abs(d3.timeFormat("%U")(new Date(startTime))) % 4; const dataValueForStartDate = d3.timeFormat("%Y-%m-%d 00:00:00")(new Date(startTime)); const nextDayCount = 7; const currentDayNumber = Math.abs(d3.timeFormat("%w")(startTime)); const weekEndDay = new Date(startTime.setDate(startTime.getDate() + (nextDayCount - 1 - currentDayNumber))).getTime(); const weekEndDate = d3.timeFormat("%d %b")(new Date(weekEndDay)); if (weekNumber == 0) { const displayName = ticksFormat != null && typeof ticksFormat == "function" ? ticksFormat({ startPoint: d3.timeFormat("%Y-%m-%d 23:59:59")(new Date(dataValueForStartDate)), endPoint: d3.timeFormat("%Y-%m-%d 23:59:59")(new Date(weekEndDay)) }) : [`${date}-${weekEndDate}`, `${startTime.getFullYear()}`]; distinctTicks.push({ title: `${d3.timeFormat("%d %b,%Y")(new Date(dataValueForStartDate))}`, data: `${dataValueForStartDate}`, displayName: displayName }); } else { const displayName = ticksFormat != null && typeof ticksFormat == "function" ? ticksFormat({ startPoint: d3.timeFormat("%Y-%m-%d 23:59:59")(new Date(dataValueForStartDate)), endPoint: d3.timeFormat("%Y-%m-%d 23:59:59")(new Date(weekEndDay)) }) : `${date}-${weekEndDate}`; distinctTicks.push({ title: `${d3.timeFormat("%d %b,%Y")(new Date(dataValueForStartDate))}`, data: `${dataValueForStartDate}`, displayName: displayName }); } startTime = new Date(startTime.setDate(startTime.getDate() + 1)).getTime(); } //CBT:for calculate start Point index startPointDate = new Date(startPointDate); const weekOfTheDay = startPointDate.getDay(); startPointDate = d3.timeFormat("%Y-%m-%d 00:00:00")(new Date(startPointDate.setDate(startPointDate.getDate() - weekOfTheDay))); break; } case "week-monday": { let startTime = startDate.getTime(); while (startTime <= endDate.getTime()) { const date = d3.timeFormat("%d")(new Date(startTime)); const month = d3.timeFormat("%b")(new Date(startTime)); startTime = new Date(startTime); const dataValueForStartDate = d3.timeFormat("%Y-%m-%d 00:00:00")(new Date(startTime)); const nextDayCount = 7; const currentDayNumber = Math.abs(d3.timeFormat("%u")(startTime)); const weekEndDay = new Date(startTime.setDate(startTime.getDate() + (nextDayCount - currentDayNumber))).getTime(); const WeekEndDateNumber = Math.abs(d3.timeFormat("%V")(new Date(weekEndDay))) % 4; const weekEndDate = d3.timeFormat("%d %b")(new Date(weekEndDay)); if (WeekEndDateNumber == 1) { const displayName = ticksFormat != null && typeof ticksFormat == "function" ? ticksFormat({ startPoint: d3.timeFormat("%Y-%m-%d 23:59:59")(new Date(dataValueForStartDate)), endPoint: d3.timeFormat("%Y-%m-%d 23:59:59")(new Date(weekEndDay)) }) : [`${date}-${weekEndDate}`, `${startTime.getFullYear()}`]; distinctTicks.push({ title: `${d3.timeFormat("%d %b,%Y")(new Date(dataValueForStartDate))}`, data: `${dataValueForStartDate}`, displayName: displayName }); } else { const displayName = ticksFormat != null && typeof ticksFormat == "function" ? ticksFormat({ startPoint: d3.timeFormat("%Y-%m-%d 23:59:59")(new Date(dataValueForStartDate)), endPoint: d3.timeFormat("%Y-%m-%d 23:59:59")(new Date(weekEndDay)) }) : `${date}-${weekEndDate}`; distinctTicks.push({ title: `${d3.timeFormat("%d %b,%Y")(new Date(dataValueForStartDate))}`, data: `${dataValueForStartDate}`, displayName: displayName }); } startTime = new Date(startTime.setDate(startTime.getDate() + 1)).getTime(); } //CBT:for calculate start Point index startPointDate = new Date(startPointDate); const weekOfTheDay = startPointDate.getDay(); const diffInDate = startPointDate.getDate() - weekOfTheDay + (weekOfTheDay == 0 ? -6 : 1); startPointDate = d3.timeFormat("%Y-%m-%d 00:00:00")(new Date(startPointDate.setDate(diffInDate))); break; } case "yearly-january": { let startYear = Math.abs(d3.timeFormat("%Y")(new Date(startDate))); const endYear = Math.abs(d3.timeFormat("%Y")(new Date(endDate))); while (startYear <= endYear) { const startTime = new Date(startYear, 0, 1, 0, 0, 0, 0); const displayName = ticksFormat != null && typeof ticksFormat == "function" ? ticksFormat({ startPoint: d3.timeFormat("%Y-01-01 23:59:59")(startTime), endPoint: d3.timeFormat("%Y-12-31 23:59:59")(startTime) }) : `${startYear}`; distinctTicks.push({ title: `${d3.timeFormat("%d %b,%Y")(new Date(startTime))}`, data: `${d3.timeFormat("%Y-%m-%d 00:00:00")(new Date(startTime))}`, displayName: displayName }); startYear = startYear + 1; } startPointDate = d3.timeFormat("%Y-01-01 00:00:00")(new Date(startPoint)); break; } case "yearly-march": { let startYear = Math.abs(d3.timeFormat("%Y")(new Date(startDate))); if (startDate.getMonth() < 3) { startYear = startYear - 1; } let endYear = Math.abs(d3.timeFormat("%Y")(new Date(endDate))); if (endDate.getMonth() >= 3) { endYear = endYear + 1; } while (startYear < endYear) { const startTime = new Date(startYear, 3, 1, 0, 0, 0, 0); const endTime = new Date(startYear + 1, 2, 31, 23, 59, 59, 100); const displayName = ticksFormat != null && typeof ticksFormat == "function" ? ticksFormat({ startPoint: d3.timeFormat("%Y-%m-%d 23:59:59")(startTime), endPoint: d3.timeFormat("%Y-%m-%d 23:59:59")(endTime) }) : [`${startYear}-`, `${startYear + 1}`]; distinctTicks.push({ title: `${d3.timeFormat("%d %b,%Y")(new Date(startTime))}`, data: `${d3.timeFormat("%Y-%m-%d 00:00:00")(new Date(startTime))}`, displayName: displayName }); startYear = startYear + 1; } //CBT:for calculate start Point index startPointDate = new Date(startPointDate); if (startPointDate.getMonth() < 3) { startPointDate = new Date(startPointDate.setFullYear(startPointDate.getFullYear() - 1)); startPointDate = d3.timeFormat("%Y-04-01 00:00:00")(new Date(startPointDate)); } else { startPointDate = d3.timeFormat("%Y-04-01 00:00:00")(new Date(startPointDate)); } break; } } } startPointIndex = distinctTicks .map(d => { return d.data; }) .indexOf(startPointDate); startPointIndex = startPointIndex == -1 ? 0 : startPointIndex; return { distinctTicks: distinctTicks, startPointIndex: startPointIndex }; } function getPrepareChartData(chartData, category, measureFieldName) { const preparedData = {}; const allPercentageValues = []; category.map((categoryPoint, baseIndex) => { preparedData[categoryPoint] = {}; Object.keys(chartData).forEach(lineDimension => { preparedData[categoryPoint][lineDimension] = []; const basePoint = chartData[lineDimension][baseIndex][measureFieldName]; chartData[lineDimension].forEach(data => { const value = basePoint == 0 || basePoint == null || data[measureFieldName] == null ? 0 : +parseFloat((data[measureFieldName] - basePoint) / basePoint * 100).toFixed(2); preparedData[categoryPoint][lineDimension].push(value); allPercentageValues.push(value); }); }); }); return { resultData: preparedData, minMax: d3.extent(allPercentageValues) }; } const granularityToLabelMapping = { daily: { labelForTableHeader: "day", granularityLabelForSlider: "day" }, monthly: { labelForTableHeader: "month", granularityLabelForSlider: "month" }, "weekly-sunday": { labelForTableHeader: "week", granularityLabelForSlider: "week-sunday" }, "weekly-monday": { labelForTableHeader: "week", granularityLabelForSlider: "week-monday" }, "yearly-january": { labelForTableHeader: "year", granularityLabelForSlider: "yearly-january" }, "yearly-march": { labelForTableHeader: "year", granularityLabelForSlider: "yearly-march" } }; const getNextDivisible = (maxNumber, binSize) => { if (maxNumber % binSize === 0) return maxNumber; return maxNumber + binSize - maxNumber % binSize; }; const getPrevDivisible = (minNumber, binSize) => { return minNumber - minNumber % binSize; }; const getSmootherBinSize = num => { if (num > 1) { var pow = 0; while (num / Math.pow(10, pow) > 9) pow += 1; return getNextDivisible(num, Math.pow(10, pow)); } else { var pow = 0; while (num / Math.pow(10, pow) <= 0.09) { pow -= 1; } return Math.round(getNextDivisible(num, Math.pow(10, pow)) * Math.pow(10, -pow)) / Math.pow(10, -pow); } }; const calculateMinMaxValue = (minValue, maxValue, zeroBase, ticks) => { if (minValue == maxValue && minValue == 0) { maxValue = 10; } if (minValue == maxValue && minValue > 0) { minValue = minValue - minValue * 0.25; maxValue = maxValue + maxValue * 0.25; } if (minValue > 0 && zeroBase === true) { minValue = 0; } var num = (maxValue - minValue) / ((ticks || 10) - 1); var binSize = getSmootherBinSize(num); if (zeroBase == false && minValue < 0) { minValue = -1 * getNextDivisible(minValue * -1, binSize); } else if (zeroBase == false && minValue > 0) { minValue = getPrevDivisible(minValue, binSize); } maxValue = getNextDivisible(maxValue, binSize); if (ticks != null) { const missingTicks = ticks - ((maxValue - minValue) / binSize + 1); if (missingTicks > 0) { minValue -= Math.floor(missingTicks / 2) * binSize; maxValue += (Math.floor(missingTicks / 2) + missingTicks % 2) * binSize; } } return { minValue: minValue, maxValue: maxValue }; };