diff --git a/examples/case/advanced/demo/associate-filter.ts b/examples/case/advanced/demo/associate-filter.ts new file mode 100644 index 0000000000..ba7d4e0829 --- /dev/null +++ b/examples/case/advanced/demo/associate-filter.ts @@ -0,0 +1,100 @@ +import { Column, Pie } from '@antv/g2plot'; +import { each, groupBy } from '@antv/util'; +import insertCss from 'insert-css'; + +// We use 'insert-css' to insert custom styles +// It is recommended to add the style to your own style sheet files +// If you want to copy the code directly, please remember to install the npm package 'insert-css +insertCss(` +#container { + display: flex; + flex-direction: column !important; + padding: 8px; +} +#container1, #container2 { + flex: 1; +} +`); + +fetch('https://gw.alipayobjects.com/os/antfincdn/PC3daFYjNw/column-data.json') + .then((data) => data.json()) + .then((data) => { + const pieData = ((originData) => { + const groupData = groupBy(originData, 'type'); + const result = []; + each(groupData, (values, k) => { + result.push({ type: k, value: values.reduce((a, b) => a + b.value, 0) }); + }); + return result; + })(data); + + const pie = new Pie('container1', { + data: pieData, + colorField: 'type', + angleField: 'value', + label: { type: 'inner' }, + tooltip: false, + state: { + // 设置【active】激活状态样式 - 无描边 + active: { + style: { + lineWidth: 0, + }, + }, + }, + interactions: [ + { + type: 'element-highlight', + cfg: { + showEnable: [{ trigger: 'element:mouseenter', action: 'cursor:pointer' }], + end: [ + { trigger: 'element:mouseleave', action: 'cursor:default' }, + { trigger: 'element:mouseleave', action: 'element-highlight:reset' }, + ], + }, + }, + ], + }); + + const column = new Column('container2', { + data, + xField: 'city', + yField: 'value', + seriesField: 'type', + isGroup: 'true', + legend: false, + columnStyle: { + radius: [4, 4, 0, 0], + }, + }); + + pie.render(); + column.render(); + + pie.on('element:mouseover', (evt) => { + const eventData = evt.data; + if (eventData?.data) { + const type = eventData.data.type; + column.setState('selected', (datum) => datum.type === type); + column.setState('selected', (datum) => datum.type !== type, false); + } + }); + pie.on('element:mouseleave', () => { + // 取消 selected 选中状态 + column.setState('selected', () => true, false); + }); + + pie.on('element:click', (evt) => { + const eventData = evt.data; + if (eventData?.data) { + const type = eventData.data.type; + pie.chart.changeData(pieData.filter((datum) => datum.type === type)); + column.chart.changeData(data.filter((datum) => datum.type === type)); + } + }); + // 双击,还原数据 + pie.on('element:dblclick', () => { + pie.chart.changeData(pieData); + column.chart.changeData(data); + }); + }); diff --git a/examples/case/advanced/demo/associate-pie-tooltip.ts b/examples/case/advanced/demo/associate-pie-tooltip.ts new file mode 100644 index 0000000000..e9154b2056 --- /dev/null +++ b/examples/case/advanced/demo/associate-pie-tooltip.ts @@ -0,0 +1,144 @@ +import { Pie, G2 } from '@antv/g2plot'; +import insertCss from 'insert-css'; + +// We use 'insert-css' to insert custom styles +// It is recommended to add the style to your own style sheet files +// If you want to copy the code directly, please remember to install the npm package 'insert-css +insertCss(` +#container { + display: flex; + flex-direction: row !important; + padding: 8px; +} +#container1, #container2 { + flex: 1; +} +`); + +const { Util } = G2; + +const plot1 = new Pie('container1', { + data: [ + { type: '一线城市', value: 0.19 }, + { type: '二线城市', value: 0.21 }, + { type: '三线城市', value: 0.27 }, + { type: '四线及以下', value: 0.33 }, + ], + meta: { + value: { + formatter: (v) => `${(v * 100).toFixed(0)}%`, + }, + }, + angleField: 'value', + colorField: 'type', + radius: 0.8, + legend: false, + label: { type: 'inner' }, +}); + +const plot2 = new Pie('container2', { + data: [ + { type: '一线城市', value: 0.19 }, + { type: '二线城市', value: 0.31 }, + { type: '三线城市', value: 0.27 }, + { type: '四线及以下', value: 0.12 }, + ], + meta: { + value: { + formatter: (v) => `${(v * 100).toFixed(0)}%`, + }, + }, + angleField: 'value', + colorField: 'type', + radius: 0.8, + innerRadius: 0.5, + legend: false, + label: { type: 'inner' }, + + statistic: { + title: false, + content: { + customHtml: (container, view, datum, data) => { + container.style.overflow = 'visible'; + const text = datum + ? `${(datum.value * 100).toFixed(0)}%` + : `${(data.reduce((r, d) => r + d.value, 0) * 100).toFixed(0)}%`; + return text; + }, + }, + }, + // Because interactions of 'statistic' will cause tooltip interaction not to work, so enable tooltip interaction explicitly. + interactions: [{ type: 'tooltip', enable: true }], +}); + +plot1.render(); +plot2.render(); + +/** + * 根据指定 切片数据 获取切片元素 element 的中心坐标点 + * @param view G2.View + * @param xField string + * @param activeValue string + * @returns Point | null + */ +function getPoint(view, xField, activeValue) { + const { elements, coordinate } = view.geometries[0]; + const element = elements.find((ele) => ele.getModel().data[xField] === activeValue); + if (element) { + const { radius, innerRadius, polarRadius } = coordinate; + const center = coordinate.getCenter(); + const { startAngle, endAngle } = Util.getAngle(element.getModel(), coordinate); + const middleAngle = (startAngle + endAngle) / 2; + const r = (polarRadius * (radius + innerRadius)) / 2; + const x = r * Math.cos(middleAngle); + const y = r * Math.sin(middleAngle); + + return { + x: center.x + x, + y: center.y + y, + }; + } + return null; +} + +// 监听事件,进行 Tooltip 联动 +let inAction = null; +plot1.on('tooltip:change', (e) => { + if (inAction !== 'plot2') { + const { data: eventData } = e; + const point = getPoint(plot2.chart, 'type', eventData.items?.[0]?.data?.type); + if (point) { + inAction = 'plot1'; + plot2.chart.showTooltip(point); + } else { + plot2.chart.hideTooltip(); + } + } +}); + +plot1.on('tooltip:hide', (e) => { + if (inAction) { + inAction = null; + plot2.chart.hideTooltip(); + } +}); + +plot2.on('tooltip:change', (e) => { + if (inAction !== 'plot1') { + const { data: eventData } = e; + inAction = 'plot2'; + const point = getPoint(plot1.chart, 'type', eventData.items?.[0]?.data?.type); + if (point) { + plot1.chart.showTooltip(point); + } else { + plot1.chart.hideTooltip(); + } + } +}); + +plot2.on('tooltip:hide', (e) => { + if (inAction) { + inAction = null; + plot1.chart.hideTooltip(); + } +}); diff --git a/examples/case/advanced/demo/meta.json b/examples/case/advanced/demo/meta.json new file mode 100644 index 0000000000..3a6d7ddd42 --- /dev/null +++ b/examples/case/advanced/demo/meta.json @@ -0,0 +1,24 @@ +{ + "title": { + "zh": "中文分类", + "en": "Category" + }, + "demos": [ + { + "filename": "associate-pie-tooltip.ts", + "title": { + "zh": "联动 Tooltip (饼图)", + "en": "Associate Tooltip for Pie plot" + }, + "screenshot": "https://gw.alipayobjects.com/zos/antfincdn/VoiPvFL%26U5/pie-tooltip.gif" + }, + { + "filename": "associate-filter.ts", + "title": { + "zh": "联动筛选", + "en": "Associate Filter" + }, + "screenshot": "https://gw.alipayobjects.com/zos/antfincdn/tHF3bgalmB/association-filter.gif" + } + ] +} \ No newline at end of file diff --git a/examples/case/advanced/index.en.md b/examples/case/advanced/index.en.md new file mode 100644 index 0000000000..638a32ff5a --- /dev/null +++ b/examples/case/advanced/index.en.md @@ -0,0 +1,4 @@ +--- +title: Advanced usages +order: 1 +--- diff --git a/examples/case/advanced/index.zh.md b/examples/case/advanced/index.zh.md new file mode 100644 index 0000000000..3ebfe1f0b8 --- /dev/null +++ b/examples/case/advanced/index.zh.md @@ -0,0 +1,4 @@ +--- +title: 高级用法 +order: 1 +--- diff --git a/examples/dynamic-plots/brush/demo/advanced-brush1.ts b/examples/dynamic-plots/brush/demo/advanced-brush1.ts index bc62fc44d6..4e99f40074 100644 --- a/examples/dynamic-plots/brush/demo/advanced-brush1.ts +++ b/examples/dynamic-plots/brush/demo/advanced-brush1.ts @@ -1,16 +1,6 @@ import { Column, G2 } from '@antv/g2plot'; -import { each, groupBy } from '@antv/util'; import insertCss from 'insert-css'; -const div1 = document.createElement('div'); -div1.id = 'container1'; -const div2 = document.createElement('div'); -div2.id = 'container2'; - -const container = document.querySelector('#container'); -container.appendChild(div1); -container.appendChild(div2); - insertCss(` #container { display: flex; @@ -21,7 +11,7 @@ insertCss(` flex: 1; } #container2 { - padding-top: 12px; + padding-top: 12px; height: 120px; } `); diff --git a/examples/dynamic-plots/brush/demo/advanced-brush2.ts b/examples/dynamic-plots/brush/demo/advanced-brush2.ts index 66533c0398..4c7a726ac7 100644 --- a/examples/dynamic-plots/brush/demo/advanced-brush2.ts +++ b/examples/dynamic-plots/brush/demo/advanced-brush2.ts @@ -2,15 +2,6 @@ import { Column, G2 } from '@antv/g2plot'; import { each, groupBy } from '@antv/util'; import insertCss from 'insert-css'; -const div1 = document.createElement('div'); -div1.id = 'container1'; -const div2 = document.createElement('div'); -div2.id = 'container2'; - -const container = document.querySelector('#container'); -container.appendChild(div1); -container.appendChild(div2); - insertCss(` #container { display: flex; @@ -21,7 +12,7 @@ insertCss(` flex: 1; } #container2 { - padding-top: 12px; + padding-top: 12px; height: 120px; } `); diff --git a/gatsby-config.js b/gatsby-config.js index c541b857e3..e2f3386577 100644 --- a/gatsby-config.js +++ b/gatsby-config.js @@ -28,6 +28,8 @@ module.exports = { showAPIDoc: true, // 是否在demo页展示API文档 themeSwitcher: 'g2plot', playground: { + extraLib: '', + container: '
', // 定义演示的渲染节点,默认
devDependencies: { typescript: 'latest', },