d3#min TypeScript Examples
The following examples show how to use
d3#min.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: BaseChart.ts From anichart.js with MIT License | 6 votes |
setup(stage: Stage) {
super.setup(stage);
this.setData();
this.setMeta();
this.setDefaultAniTime(stage);
this.setDataScales();
this.setAlphaScale();
// 初始化整体最值
this.totallyMax = max(this.data, (d) => d[this.valueField]);
this.totallyMin = min(this.data, (d) => d[this.valueField]);
// 初始化历史最值
this.historyMax = this.totallyMin;
this.historyMin = this.totallyMin;
// 用于计算坐标
this.currentMax = this.historyMin;
this.currentMin = this.historyMax;
if (!this.shape) {
this.shape = {
width: stage.canvas.width,
height: stage.canvas.height,
};
}
}
Example #2
Source File: SleepChart.tsx From nyxo-website with MIT License | 6 votes |
getNightAsDays = (nights: Night[]) => {
const firstDate = min([...nights.map((night) => new Date(night.startDate))])
const lastDate = max([...nights.map((night) => new Date(night.endDate))])
const days = eachDayOfInterval({
start: subDays(new Date(), 30),
end: new Date(), // lastDate
})
return days.map((day) => ({
date: day.toISOString(),
night: nights
.filter((night) => matchDayAndNight(night.startDate, day.toISOString()))
.map((night) => {
const startDifference = differenceInMilliseconds(
new Date(night.startDate),
startOfDay(new Date(day))
)
const newStartDate = addMilliseconds(
startOfDay(new Date()),
startDifference
)
const newEndDate = addMinutes(newStartDate, night.totalDuration)
return {
...night,
startDate: newStartDate.valueOf(),
endDate: newEndDate.valueOf(),
}
}),
}))
}
Example #3
Source File: SleepChart.tsx From nyxo-app with GNU General Public License v3.0 | 5 votes |
SleepTimeChart: FC = () => {
const data = useAppSelector(getNightsAsDays)
const daysToShow = data.length
const chartWidth = (barWidth + 10) * daysToShow + paddingLeft + paddingRight
const xDomain: Date[] = extent(data, (date) => new Date(date.date)) as Date[]
const yDomain: number[] = [
min(data, (date) =>
min(date.night, (night) =>
subHours(new Date(night.startDate), 1).valueOf()
)
) as number,
max(data, (date) =>
max(date.night, (night) => addHours(new Date(night.endDate), 1).valueOf())
) as number
]
const scaleX = scaleTime()
.domain(xDomain)
.range([paddingLeft, chartWidth - paddingRight])
const scaleY = scaleTime()
.domain(yDomain)
.nice()
.range([10, chartHeight - 80])
const yTicks = scaleY.ticks(5)
const xTicks = scaleX.ticks(daysToShow)
return (
<Card>
<Title>STAT.TREND</Title>
<ScrollContainer>
<YTicksContainer
pointerEvents="auto"
width={chartWidth}
height={chartHeight}>
<YTicks scaleY={scaleY} chartWidth={chartWidth} ticks={yTicks} />
</YTicksContainer>
<ScrollView
style={{ transform: [{ scaleX: -1 }] }}
horizontal
showsHorizontalScrollIndicator={false}>
<View style={{ transform: [{ scaleX: -1 }] }}>
<Svg width={chartWidth} height={chartHeight}>
{/* <TargetBars
start={bedtimeWindow}
onPress={select}
barWidth={barWidth}
scaleX={scaleX}
scaleY={scaleY}
data={normalizedSleepData}
/> */}
<SleepBars
onPress={() => undefined}
barWidth={barWidth}
scaleX={scaleX}
scaleY={scaleY}
data={data}
/>
<XTicks
chartHeight={chartHeight}
scaleX={scaleX}
barWidth={barWidth}
ticks={xTicks}
/>
</Svg>
</View>
</ScrollView>
</ScrollContainer>
</Card>
)
}
Example #4
Source File: nights.ts From nyxo-app with GNU General Public License v3.0 | 5 votes |
getShortestBedTime = createSelector(getBedTimeNights, (days) =>
min(days, (item) => item.inBedDuration)
)
Example #5
Source File: nights.ts From nyxo-app with GNU General Public License v3.0 | 5 votes |
getShortestSleepTime = createSelector(getAsleepNights, (days) =>
min(days, (item) => item.asleepDuration)
)
Example #6
Source File: SleepChart.tsx From nyxo-website with MIT License | 5 votes |
SleepChart: FC<ChartProps> = ({ data }) => {
const ref = useRef<HTMLDivElement>(null)
useLayoutEffect(() => {
ref.current?.scrollBy({ left: ref.current.offsetWidth })
}, [])
const { normalizedData } = useMemo(
() => ({
normalizedData: getNightAsDays(data),
}),
[data]
)
const daysToShow = normalizedData.length
const chartWidth = (barWidth + 10) * daysToShow + paddingLeft + paddingRight
const xDomain: Date[] = extent(
normalizedData,
(date) => new Date(date.date)
) as Date[]
const yDomain: number[] = [
min(normalizedData, (date) =>
min(date.night, (night) =>
subHours(new Date(night.startDate), 1).valueOf()
)
) as number,
max(normalizedData, (date) =>
max(date.night, (night) => addHours(new Date(night.endDate), 1).valueOf())
) as number,
]
const scaleX = scaleTime()
.domain(xDomain)
.range([paddingLeft, chartWidth - paddingRight])
const scaleY = scaleTime()
.domain(yDomain)
.nice()
.range([10, chartHeight - 80])
const yTicks = scaleY.ticks(10)
const xTicks = scaleX.ticks(daysToShow)
return (
<Container ref={ref}>
<svg width={chartWidth} height={chartHeight}>
<XTicks
chartHeight={chartHeight}
scaleX={scaleX}
barWidth={barWidth}
ticks={xTicks}
/>
<SleepBars
barWidth={barWidth}
scaleX={scaleX}
scaleY={scaleY}
data={normalizedData}
/>
<YTicks scaleY={scaleY} chartWidth={chartWidth} ticks={yTicks} />
</svg>
</Container>
)
}
Example #7
Source File: render.ts From fe-v5 with Apache License 2.0 | 4 votes |
function renderHoneyComb(svgGroup, data, { width, height, fontAutoScale = true, fontSize = 12 }) {
const t = transition().duration(750);
const { columns: mapColumns, rows: mapRows } = getMapColumnsAndRows(width, height, data.length);
const hexRadius = Math.floor(min([width / ((mapColumns + 0.5) * Math.sqrt(3)), height / ((mapRows + 1 / 3) * 1.5), width / 7]));
const hexbinWidth = Math.sin((60 * Math.PI) / 180) * hexRadius * 2;
const points = getPlaceHolderElems(mapRows, mapColumns, data.length, hexRadius);
let adjustedOffSetX = (width - hexbinWidth * mapColumns) / 2 + hexbinWidth / 2;
if (points.length >= mapColumns * 2) {
adjustedOffSetX = (width - hexbinWidth * mapColumns - hexbinWidth / 2) / 2 + hexbinWidth / 2;
}
const offSetY = hexRadius;
const hexbin = d3Hexbin().radius(hexRadius);
const translateX = adjustedOffSetX;
const translateY = offSetY;
const hexbinPoints = hexbin(points);
const textAreaHeight = hexRadius;
const textAreaWidth = hexbinWidth * 0.9;
let activeLabelFontSize = fontSize;
let activeValueFontSize = fontSize;
let isShowEllipses = false;
let numOfChars = 0;
if (fontAutoScale) {
let maxLabel = '';
let maxValue = '';
for (let i = 0; i < data.length; i++) {
if (data[i].name.length > maxLabel.length) {
maxLabel = data[i].name;
}
if (_.toString(data[i].value).length > maxValue.length) {
maxValue = _.toString(data[i].value);
}
}
activeLabelFontSize = computeTextFontSize(maxLabel, 2, textAreaWidth, textAreaHeight);
activeValueFontSize = computeTextFontSize(maxValue, 2, textAreaWidth, textAreaHeight);
if (activeLabelFontSize < minFont) {
isShowEllipses = true;
numOfChars = 18;
maxLabel = maxLabel.substring(0, numOfChars + 2);
activeLabelFontSize = computeTextFontSize(maxLabel, 2, textAreaWidth, textAreaHeight);
if (activeLabelFontSize < minFont) {
numOfChars = 10;
maxLabel = maxLabel.substring(0, numOfChars + 2);
activeLabelFontSize = computeTextFontSize(maxLabel, 2, textAreaWidth, textAreaHeight);
if (activeLabelFontSize < minFont) {
numOfChars = 6;
maxLabel = maxLabel.substring(0, numOfChars + 2);
activeLabelFontSize = computeTextFontSize(maxLabel, 2, textAreaWidth, textAreaHeight);
}
}
}
if (activeValueFontSize > activeLabelFontSize) {
activeValueFontSize = activeLabelFontSize;
}
}
const valueWithLabelTextAlignment = textAreaHeight / 2 / 2 + activeValueFontSize / 2;
const labelWithValueTextAlignment = -(textAreaHeight / 2 / 2) + activeLabelFontSize / 2;
svgGroup.attr('width', width).attr('height', height).attr('transform', `translate(${translateX},${translateY})`);
const hexagons = svgGroup.selectAll('.hexagon').data(hexbinPoints);
const removeSelection = hexagons.exit().remove();
hexagons
.enter()
.append(function () {
const nodeToAdd = document.createElementNS(xmlns, 'path');
return nodeToAdd;
})
.attr('class', 'hexagon')
// TODO: 进入动画暂时关闭
// .attr("d", function(d) {
// return "M" + d.x + "," + d.y + zeroHexBin.hexagon();
// })
.on('mousemove', function (_d, i) {
const metricObj = data[i]?.metric;
const metricName = metricObj?.__name__ || 'value';
const metricNameRow = `<div><strong>${metricName}: ${data[i]?.value}</strong></div>`;
const labelsRows = _.map(_.omit(metricObj, '__name__'), (val, key) => {
return `<div>${key}: ${val}</div>`;
});
const content = `${metricNameRow}${labelsRows.join('')}`;
div.style('opacity', 0.9);
div
.html(content)
.style('left', event.pageX + 10 + 'px')
.style('top', event.pageY - 28 + 'px');
})
.on('mouseout', function () {
div.style('opacity', 0);
})
.attr('stroke', 'white')
.attr('stroke-width', '1px')
.style('fill', (_d, i) => {
return data[i]?.color;
})
.style('fill-opacity', 1)
.transition(t)
.attr('d', function (d) {
return 'M' + d.x + ',' + d.y + hexbin.hexagon();
});
hexagons
.enter()
.append('text')
.attr('x', function (d) {
return d.x;
})
.attr('y', function (d) {
return d.y + labelWithValueTextAlignment;
})
.text(function (_d, i) {
let name = data[i]?.name;
if (isShowEllipses) {
name = name.substring(0, numOfChars) + '...';
return name;
}
return name;
})
.attr('text-anchor', 'middle')
.attr('alignment-baseline', 'central')
.style('pointer-events', 'none')
.style('font-size', activeLabelFontSize + 'px')
.style('fill', 'white')
.each(function (this, d) {
d.bbox = this.getBBox();
});
if (activeLabelFontSize) {
hexagons
.enter()
.insert('rect', 'text')
.attr('x', function (d) {
return d.bbox.x - 4;
})
.attr('y', function (d) {
return d.bbox.y - 4;
})
.attr('rx', 2)
.attr('ry', 2)
.attr('width', function (d) {
return d.bbox.width + 8;
})
.attr('height', function (d) {
return d.bbox.height + 8;
})
.attr('fill-opacity', '0.2')
.style('fill', '#000')
.style('pointer-events', 'none');
}
hexagons
.enter()
.append('text')
.attr('x', function (d) {
return d.x;
})
.attr('y', function (d) {
return d.y + valueWithLabelTextAlignment;
})
.text(function (_d, i) {
const value = data[i]?.value;
return value;
})
.attr('text-anchor', 'middle')
.attr('alignment-baseline', 'central')
.style('font-size', activeValueFontSize + 'px')
.style('fill', 'white')
.style('pointer-events', 'none')
.each(function (this, d) {
d.bbox = this.getBBox();
});
if (activeValueFontSize) {
hexagons
.enter()
.insert('rect', 'text')
.attr('x', function (d) {
return d.bbox.x - 4;
})
.attr('y', function (d) {
return d.bbox.y - 4;
})
.attr('rx', 2)
.attr('ry', 2)
.attr('width', function (d) {
return d.bbox.width + 8;
})
.attr('height', function (d) {
return d.bbox.height + 8;
})
.attr('fill-opacity', '0.2')
.style('fill', '#000')
.style('pointer-events', 'none');
}
return [...removeSelection.nodes()];
}