From 8d9bd00e89d7284f7143053e7a4a9d403487e635 Mon Sep 17 00:00:00 2001 From: jinhee park Date: Mon, 15 Jan 2024 17:40:06 +0900 Subject: [PATCH] =?UTF-8?q?[#1579]=20Chart=20>=20Tooltip=20>=20label=20fon?= =?UTF-8?q?t=20color,=20series=20color=20shape=20=EC=98=B5=EC=85=98=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80=20#####=20-=20font=20color=20=EC=98=B5?= =?UTF-8?q?=EC=85=98=20=EC=B6=94=EA=B0=80=20-=20padding=20=EA=B0=92=20?= =?UTF-8?q?=EC=9D=BC=EB=B6=80=20=EC=A1=B0=EC=A0=95=20-=20=EC=A4=84=20?= =?UTF-8?q?=EB=86=92=EC=9D=B4=20=ED=99=95=EB=8C=80=20-=20series=20color=20?= =?UTF-8?q?shape=20=EB=A5=BC=20=EB=B3=80=EA=B2=BD=ED=95=A0=20=EC=88=98=20?= =?UTF-8?q?=EC=9E=88=EB=8A=94=20=EC=98=B5=EC=85=98=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/views/barChart/api/barChart.md | 2 + docs/views/lineChart/api/lineChart.md | 2 + docs/views/lineChart/example/Tooltip.vue | 63 +++++++++++++++++-- docs/views/pieChart/api/pieChart.md | 2 + docs/views/scatterChart/api/scatterChart.md | 38 +++++------ .../chart/plugins/plugins.tooltip.js | 42 +++++++++---- src/components/chart/style/chart.scss | 2 +- src/components/chart/uses.js | 1 + 8 files changed, 116 insertions(+), 36 deletions(-) diff --git a/docs/views/barChart/api/barChart.md b/docs/views/barChart/api/barChart.md index d48e7d4c8..d1d4dd1b9 100644 --- a/docs/views/barChart/api/barChart.md +++ b/docs/views/barChart/api/barChart.md @@ -298,6 +298,8 @@ const chartData = { | maxWidth | Number | | 툴팁의 최대 너비 | | | textOverflow | String | 'wrap' | 툴팁에 표시될 텍스트가 maxWidth 값을 넘길 경우 의 처리 | 'wrap', 'ellipsis | | fontFamily | String | 'Roboto' | 툴팁에 표시될 폰트 | 'Roboto', 'serif | +| fontColor | Hex code (string), Object | '#000000' | 툴팁에 표시될 폰트 컬러 | '#FFFFFF', { label: '#FFFFFF', value: '#FFFFFF', 'title: #FFFFFF' } | +| colorShape | String | 'rect' | 툴팁에 표시될 series color의 모양 | 'rect', 'circle' | | showAllValueInRange | Boolean | false | 동일한 axes값을 가진 전체 series를 Tooltip에 표시 | | formatter | function / Object | null | 데이터가 표시되기 전에 데이터의 형식을 지정하는 데 사용 | (아래 코드 참고) | ``` diff --git a/docs/views/lineChart/api/lineChart.md b/docs/views/lineChart/api/lineChart.md index 99eb2aca5..8fc86c613 100644 --- a/docs/views/lineChart/api/lineChart.md +++ b/docs/views/lineChart/api/lineChart.md @@ -252,6 +252,8 @@ const chartData = | maxWidth | Number | | 툴팁의 최대 너비 | | | textOverflow | String | 'wrap' | 툴팁에 표시될 텍스트가 maxWidth 값을 넘길 경우 의 처리 | 'wrap', 'ellipsis | | fontFamily | String | 'Roboto' | 툴팁에 표시될 폰트 | 'Roboto', 'serif | +| fontColor | Hex code (string), Object | '#000000' | 툴팁에 표시될 폰트 컬러 | '#FFFFFF', { label: '#FFFFFF', value: '#FFFFFF', 'title: #FFFFFF' } | +| colorShape | String | 'rect' | 툴팁에 표시될 series color의 모양 | 'rect', 'circle' | | showAllValueInRange | Boolean | false | 동일한 axes값을 가진 전체 series를 Tooltip에 표시 | | formatter | function / Object | null | 데이터가 표시되기 전에 데이터의 형식을 지정하는 데 사용 | (아래 코드 참고) | ``` diff --git a/docs/views/lineChart/example/Tooltip.vue b/docs/views/lineChart/example/Tooltip.vue index 5e9828963..9f04ca196 100644 --- a/docs/views/lineChart/example/Tooltip.vue +++ b/docs/views/lineChart/example/Tooltip.vue @@ -87,15 +87,45 @@
- 글자 색상 + 배경 색상 - +
- 배경 색상 + series color 모양 - + +
+
+ +
+

Font Color

+
+ +
+
+ + Title + + +
+ +
+ + Label + + +
+ +
+ + Value + +
@@ -115,8 +145,19 @@ const useShadow = ref(false); const shadowOpacity = ref(0.25); const fontColor = ref('#000000'); - const backgroundColor = ref('rgb(210, 234, 227, 0.7)'); + const backgroundColor = ref('rgb(210, 234, 227, 1)'); const textOverflow = ref('wrap'); + const colorShape = ref('rect'); + const colorShapeList = [{ + name: 'rect (Default)', + value: 'rect', + }, { + name: 'circle', + value: 'circle', + }]; + const titleFontColor = ref('#005CB5'); + const labelFontColor = ref('#FF8C40'); + const valueFontColor = ref('#FF00FF'); const chartData = reactive({ series: { @@ -195,7 +236,6 @@ use: true, sortByValue, backgroundColor, - fontColor, shadowOpacity, useShadow, useScrollbar, @@ -206,6 +246,12 @@ title: ({ x }) => dayjs(x).format('YYYY-MM-DD HH:mm:ss'), value: ({ y }) => `${y.toFixed(2)}`, }, + colorShape, + fontColor: { + title: titleFontColor, + label: labelFontColor, + value: valueFontColor, + }, }, }); @@ -237,6 +283,11 @@ fontColor, backgroundColor, textOverflow, + colorShape, + colorShapeList, + titleFontColor, + labelFontColor, + valueFontColor, }; }, }; diff --git a/docs/views/pieChart/api/pieChart.md b/docs/views/pieChart/api/pieChart.md index fa18dfad4..db0042f7d 100644 --- a/docs/views/pieChart/api/pieChart.md +++ b/docs/views/pieChart/api/pieChart.md @@ -126,6 +126,8 @@ const chartData = | maxWidth | Number | | 툴팁의 최대 너비 | | | textOverflow | String | 'wrap' | 툴팁에 표시될 텍스트가 maxWidth 값을 넘길 경우 의 처리 | 'wrap', 'ellipsis | | fontFamily | String | 'Roboto' | 툴팁에 표시될 폰트 | 'Roboto', 'serif | +| fontColor | Hex code (string), Object | '#000000' | 툴팁에 표시될 폰트 컬러 | '#FFFFFF', { label: '#FFFFFF', value: '#FFFFFF', 'title: #FFFFFF' } | +| colorShape | String | 'rect' | 툴팁에 표시될 series color의 모양 | 'rect', 'circle' | | showAllValueInRange | Boolean | false | 동일한 axes값을 가진 전체 series를 Tooltip에 표시 | | formatter | function / Object | null | 데이터가 표시되기 전에 데이터의 형식을 지정하는 데 사용 | (아래 코드 참고) | ``` diff --git a/docs/views/scatterChart/api/scatterChart.md b/docs/views/scatterChart/api/scatterChart.md index 2040f18dc..4137a423a 100644 --- a/docs/views/scatterChart/api/scatterChart.md +++ b/docs/views/scatterChart/api/scatterChart.md @@ -199,23 +199,25 @@ const chartData = * PC버전에서는 drag, Mobile에서는 touch로 선택 영역을 지정할 수 있습니다. #### tooltip -| 이름 | 타입 | 디폴트 | 설명 | 종류(예시) | -| --- | ---- | ----- | --- | ----------| -| use | Boolean | false | tooltip 표시 여부 | true /false | -| backgroundColor | Hex, RGB, RGBA Code(String) | '#4C4C4C' | tooltip 배경 색상 | | -| borderColor | Hex, RGB, RGBA Code(String) | '#666666' | tooltip 테두리 색상 | | -| useShadow | Boolean | false | 그림자 사용 여부 | | -| shadowOpacity | Number | 0.25 | 그림자 투명도 | | -| throttledMove | Boolean | false | 데이터 조회 Throttling 처리 유무 | | -| debouncedHide | Boolean | false | 좌표 이동 시 tooltip hide 여부 | | -| sortByValue | Boolean | true | 값을 기준으로 정렬할지의 여부 | | -| useScrollbar | Boolean | false | 스크롤바 사용 여부 | | -| maxHeight | Number | | 툴팁의 최대 높이 | | -| maxWidth | Number | | 툴팁의 최대 너비 | | -| textOverflow | String | 'wrap' | 툴팁에 표시될 텍스트가 maxWidth 값을 넘길 경우 의 처리 | 'wrap', 'ellipsis | -| fontFamily | String | 'Roboto' | 툴팁에 표시될 폰트 | 'Roboto', 'serif | -| showAllValueInRange | Boolean | false | 동일한 axes값을 가진 전체 series를 Tooltip에 표시 | -| formatter | function / Object | null | 데이터가 표시되기 전에 데이터의 형식을 지정하는 데 사용 | (아래 코드 참고) | +| 이름 | 타입 | 디폴트 | 설명 | 종류(예시) | +|---------------------|-----------------------------|-----------|--------------------------------------|---------------------------------------------------------------------| +| use | Boolean | false | tooltip 표시 여부 | true /false | +| backgroundColor | Hex, RGB, RGBA Code(String) | '#4C4C4C' | tooltip 배경 색상 | | +| borderColor | Hex, RGB, RGBA Code(String) | '#666666' | tooltip 테두리 색상 | | +| useShadow | Boolean | false | 그림자 사용 여부 | | +| shadowOpacity | Number | 0.25 | 그림자 투명도 | | +| throttledMove | Boolean | false | 데이터 조회 Throttling 처리 유무 | | +| debouncedHide | Boolean | false | 좌표 이동 시 tooltip hide 여부 | | +| sortByValue | Boolean | true | 값을 기준으로 정렬할지의 여부 | | +| useScrollbar | Boolean | false | 스크롤바 사용 여부 | | +| maxHeight | Number | | 툴팁의 최대 높이 | | +| maxWidth | Number | | 툴팁의 최대 너비 | | +| textOverflow | String | 'wrap' | 툴팁에 표시될 텍스트가 maxWidth 값을 넘길 경우 의 처리 | 'wrap', 'ellipsis' | +| fontFamily | String | 'Roboto' | 툴팁에 표시될 폰트 | 'Roboto', 'serif' | +| fontColor | Hex code (string), Object | '#000000' | 툴팁에 표시될 폰트 컬러 | '#FFFFFF', { label: '#FFFFFF', value: '#FFFFFF', 'title: #FFFFFF' } | +| colorShape | String | 'rect' | 툴팁에 표시될 series color의 모양 | 'rect', 'circle' | +| showAllValueInRange | Boolean | false | 동일한 axes값을 가진 전체 series를 Tooltip에 표시 | +| formatter | function / Object | null | 데이터가 표시되기 전에 데이터의 형식을 지정하는 데 사용 | (아래 코드 참고) | ``` const chartOptions = { tooltip: { @@ -294,4 +296,4 @@ const chartOptions = { ### 6. v-model:realTimeScatterReset - realTimeScatter 옵션을 사용할 때, 내부 데이터를 모두 초기화하고 싶을 때 사용. -- realTimeScatterReset이 true가 되면 데이터를 모두 초기화하고 자동으로 false로 바뀜. 초기화하고 싶을 때마다 true로 바꿔주면 됩니다. \ No newline at end of file +- realTimeScatterReset이 true가 되면 데이터를 모두 초기화하고 자동으로 false로 바뀜. 초기화하고 싶을 때마다 true로 바꿔주면 됩니다. diff --git a/src/components/chart/plugins/plugins.tooltip.js b/src/components/chart/plugins/plugins.tooltip.js index cf0266e9a..5959097b5 100644 --- a/src/components/chart/plugins/plugins.tooltip.js +++ b/src/components/chart/plugins/plugins.tooltip.js @@ -3,8 +3,8 @@ import debounce from '@/common/utils.debounce'; import Canvas from '../helpers/helpers.canvas'; import Util from '../helpers/helpers.util'; -const TITLE_HEIGHT = 30; -const TEXT_HEIGHT = 14; +const TITLE_HEIGHT = 35; +const TEXT_HEIGHT = 20; const LINE_SPACING = 8; const COLOR_MARGIN = 16; const VALUE_MARGIN = 50; @@ -77,7 +77,7 @@ const modules = { const [maxSeries, maxValue] = hitInfo.maxTip; const seriesKeys = Object.keys(items); const seriesLen = seriesKeys.length; - const boxPadding = { t: 8, b: 8, r: 20, l: 16 }; + const boxPadding = { t: 10, b: 4, r: 20, l: 16 }; const opt = this.options.tooltip; @@ -279,10 +279,16 @@ const modules = { } // 1. Draw series color - ctx.fillRect(itemX - 4, itemY - 12, 12, 12); - ctx.fillStyle = opt.fontColor; + if (opt.colorShape === 'circle') { + ctx.beginPath(); + ctx.arc(itemX - 2, itemY - 4, 6, 0, 2 * Math.PI); + ctx.fill(); + } else { + ctx.fillRect(itemX - 4, itemY - 12, 12, 12); + } // 2. Draw series name + ctx.fillStyle = opt.fontColor?.label ?? opt.fontColor; ctx.textBaseline = 'Bottom'; const seriesNameSpaceWidth = opt.maxWidth - Math.round(ctx.measureText(maxValue).width) - boxPadding.l - boxPadding.r - COLOR_MARGIN - VALUE_MARGIN; @@ -317,6 +323,7 @@ const modules = { ctx.save(); // 3. Draw value + ctx.fillStyle = opt.fontColor?.value ?? opt.fontColor; ctx.textAlign = 'right'; ctx.fillText(valueText, this.tooltipDOM.offsetWidth - boxPadding.r, itemY); ctx.restore(); @@ -414,8 +421,14 @@ const modules = { } // 1. Draw value color - ctx.fillRect(itemX - 4, itemY - 12, 12, 12); - ctx.fillStyle = opt.fontColor; + if (opt.colorShape === 'circle') { + ctx.beginPath(); + ctx.arc(itemX - 2, itemY - 4, 6, 0, 2 * Math.PI); + ctx.fill(); + } else { + ctx.fillRect(itemX - 4, itemY - 12, 12, 12); + } + ctx.fillStyle = opt.fontColor?.label ?? opt.fontColor; // 2. Draw value y names ctx.textBaseline = 'Bottom'; @@ -514,8 +527,15 @@ const modules = { } // 1. Draw series color - ctx.fillRect(itemX - 4, itemY - 12, 12, 12); - ctx.fillStyle = opt.fontColor; + if (opt.colorShape === 'circle') { + ctx.beginPath(); + ctx.arc(itemX - 2, itemY - 4, 6, 0, 2 * Math.PI); + ctx.fill(); + } else { + ctx.fillRect(itemX - 4, itemY - 12, 12, 12); + } + + ctx.fillStyle = opt.fontColor?.label ?? opt.fontColor; // 2. Draw series name ctx.textBaseline = 'Bottom'; @@ -626,7 +646,7 @@ const modules = { this.tooltipDOM.style.overflowY = 'hidden'; this.tooltipDOM.style.backgroundColor = opt.backgroundColor; this.tooltipDOM.style.border = `1px solid ${opt.borderColor}`; - this.tooltipDOM.style.color = opt.fontColor; + this.tooltipDOM.style.color = opt.fontColor?.title ?? opt.fontColor; } }, @@ -638,7 +658,7 @@ const modules = { this.tooltipDOM.style.overflowY = 'hidden'; this.tooltipDOM.style.backgroundColor = tooltipOptions.backgroundColor; this.tooltipDOM.style.border = `1px solid ${tooltipOptions.borderColor}`; - this.tooltipDOM.style.color = tooltipOptions.fontColor; + this.tooltipDOM.style.color = tooltipOptions.fontColor?.title ?? tooltipOptions.fontColor; if (tooltipOptions.useShadow) { const shadowColor = `rgba(0, 0, 0, ${tooltipOptions.shadowOpacity})`; diff --git a/src/components/chart/style/chart.scss b/src/components/chart/style/chart.scss index ffa4c031e..b571c182b 100644 --- a/src/components/chart/style/chart.scss +++ b/src/components/chart/style/chart.scss @@ -304,7 +304,7 @@ border-radius: 8px; .ev-chart-tooltip-header { - padding: 8px 16px 0 16px; + padding: 16px 16px 0 16px; overflow: hidden; font-size: 16px; diff --git a/src/components/chart/uses.js b/src/components/chart/uses.js index 2600a3f27..d980cce5c 100644 --- a/src/components/chart/uses.js +++ b/src/components/chart/uses.js @@ -100,6 +100,7 @@ const DEFAULT_OPTIONS = { useScrollbar: false, textOverflow: 'wrap', fontFamily: 'Roboto', + colorShape: 'rect', }, indicator: { use: true,