diff --git a/site/examples/general/cell/demo/cell-calendar-horizontal.ts b/site/examples/general/cell/demo/cell-calendar-horizontal.ts new file mode 100644 index 00000000000..a5c37330443 --- /dev/null +++ b/site/examples/general/cell/demo/cell-calendar-horizontal.ts @@ -0,0 +1,82 @@ +import { Chart } from '@antv/g2'; + +fetch('https://gw.alipayobjects.com/os/antvdemo/assets/data/github-commit.json') + .then((res) => res.json()) + .then((data) => { + const chart = new Chart({ + container: 'container', + autoFit: true, + height: 500, + paddingTop: 150, + paddingRight: 30, + paddingBottom: 150, + paddingLeft: 70, + }); + + chart + .scale('x', { type: 'band' }) + .scale('y', { type: 'band' }) + .scale('color', { + domain: [0, 10, 20], + range: ['#BAE7FF', '#1890FF', '#0050B3'], + }); + + chart.axis('x', { + title: false, + tick: false, + line: false, + label: true, + labelFontSize: 12, + labelFill: '#666', + labelFormatter: (val: string) => { + if (val === '2') return 'MAY'; + if (val === '6') return 'JUN'; + if (val === '10') return 'JUL'; + if (val === '15') return 'AUG'; + if (val === '19') return 'SEP'; + if (val === '24') return 'OCT'; + return ''; + }, + }); + + chart.axis('y', { + title: false, + label: true, + tick: false, + grid: false, + labelFormatter: (val: string) => { + const days = ['周日', '周一', '周二', '周三', '周四', '周五', '周六']; + return days[parseInt(val)]; + }, + }); + + chart.legend(false); + + chart.interaction('tooltip', { + title: 'date', + showMarkers: false, + }); + + chart + .cell() + .data(data) + .encode('x', 'week') + .encode('y', 'day') + .encode('color', 'commits') + .style('inset', 0.5) + .style('stroke', (d: any) => { + if (d.lastWeek && d.lastDay) return '#404040'; + if (d.lastWeek) return '#404040'; + return '#fff'; + }) + .style('lineWidth', (d: any) => { + if (d.lastWeek || d.lastDay) return 2; + return 1; + }) + .state('active', { stroke: '#000', lineWidth: 2 }) + .state('inactive', { opacity: 0.6 }); + + chart.interaction('elementHighlight', true); + + chart.render(); + }); diff --git a/site/examples/general/cell/demo/cell-calendar.ts b/site/examples/general/cell/demo/cell-calendar.ts new file mode 100644 index 00000000000..ecb698bb897 --- /dev/null +++ b/site/examples/general/cell/demo/cell-calendar.ts @@ -0,0 +1,123 @@ +import { Chart } from '@antv/g2'; + +// 定义月份名称及分类 +const MONTHS = [ + 'January', + 'February', + 'March', + 'April', + 'May', + 'June', + 'July', + 'August', + 'September', + 'October', + 'November', + 'December', +]; + +// 预计算月份位置 (1-12月分4行3列排列) +const MONTH_POSITIONS = Array.from({ length: 12 }, (_, month) => { + const monthNum = month + 1; + const row = Math.ceil(monthNum / 3); + const col = ((monthNum - 1) % 3) + 1; + return { + row: String(row), + col: String(col), + }; +}); + +fetch( + 'https://gw.alipayobjects.com/os/antvdemo/assets/data/stock-calendar.json', +) + .then((res) => res.json()) + .then((data) => { + // 优化数据处理: 减少Date对象创建和计算 + const processedData = data.map((obj) => { + const date = new Date(obj['日期']); + const month = date.getMonth(); + const dayOfMonth = date.getDate(); + + // 计算当前月的第一天是星期几(只计算一次) + const firstDayWeek = new Date(date.getFullYear(), month, 1).getDay(); + const monthPosition = MONTH_POSITIONS[month]; + + return { + ...obj, + date, + month: MONTHS[month], + monthXCategory: monthPosition.col, + monthYCategory: monthPosition.row, + position: `${month + 1}月`, + day: date.getDay(), + week: Math.floor((dayOfMonth + firstDayWeek - 1) / 7), + }; + }); + + const chart = new Chart({ + container: 'container', + autoFit: true, + height: 800, + paddingTop: 100, + paddingRight: 40, + paddingBottom: 100, + paddingLeft: 80, + }); + + chart.scale('涨跌幅', { + domain: [-10, -5, -2, -1, 0, 1, 2, 5, 10], + range: [ + '#F51D27', + '#FA541C', + '#FFBE15', + '#FFF2D1', + '#FFFFFF', + '#E3F6FF', + '#85C6FF', + '#0086FA', + '#0A61D7', + ], + }); + + const facetRect = chart + .facetRect() + .data(processedData) + .scale('x', { type: 'band', compare: (a, b) => Number(a) - Number(b) }) + .scale('y', { type: 'band', compare: (a, b) => Number(a) - Number(b) }) + .encode('x', 'monthXCategory') + .encode('y', 'monthYCategory') + .axis('x', { title: false, label: false, tick: false }) + .axis('y', { title: false, label: false, tick: false }); + + facetRect + .cell() + .scale('x', { + type: 'band', + compare: (a: number, b: number) => a - b, + }) + .scale('y', { + type: 'band', + compare: (a: number, b: number) => a - b, + }) + .encode('x', 'day') + .axis('x', { + title: false, + label: false, + tick: false, + grid: false, + }) + .encode('y', 'week') + .axis('y', { + title: false, + label: false, + tick: false, + grid: false, + }) + .transform({ type: 'sortY', by: 'x' }) + .attr('frame', false) + .encode('color', '涨跌幅'); + + chart.interaction('elementHighlight', true); + + chart.render(); + }); diff --git a/site/examples/general/cell/demo/meta.json b/site/examples/general/cell/demo/meta.json index 4d725574aa5..125f2ca4fb4 100644 --- a/site/examples/general/cell/demo/meta.json +++ b/site/examples/general/cell/demo/meta.json @@ -12,6 +12,22 @@ }, "screenshot": "https://mdn.alipayobjects.com/huamei_qa8qxu/afts/img/A*F8DLSYJAyKQAAAAAAAAAAAAADmJ7AQ/original" }, + { + "filename": "cell-calendar.ts", + "title": { + "zh": "日历色块图", + "en": "Calendar heatmap" + }, + "screenshot": "https://gw.alipayobjects.com/mdn/rms_f5c722/afts/img/A*-2ggQ6U5_dIAAAAAAAAAAABkARQnAQ" + }, + { + "filename": "cell-calendar-horizontal.ts", + "title": { + "zh": "水平日历色块图", + "en": "Calendar heatmap" + }, + "screenshot": "https://gw.alipayobjects.com/mdn/rms_2274c3/afts/img/A*_GtkQo1vCHcAAAAAAAAAAABkARQnAQ" + }, { "filename": "cell-heatmap.ts", "title": {