diff --git a/package-lock.json b/package-lock.json index 32f04eded..d1ccb90a1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "apexcharts", - "version": "3.35.5", + "version": "3.36.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "apexcharts", - "version": "3.35.5", + "version": "3.36.0", "license": "MIT", "dependencies": { "svg.draggable.js": "^2.2.2", diff --git a/package.json b/package.json index 422815236..e5e876e3d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "apexcharts", - "version": "3.35.5", + "version": "3.36.0", "description": "A JavaScript Chart Library", "repository": { "type": "git", diff --git a/samples/react/rangeArea/basic-range-area.html b/samples/react/rangeArea/basic-range-area.html new file mode 100644 index 000000000..7eaf7d02c --- /dev/null +++ b/samples/react/rangeArea/basic-range-area.html @@ -0,0 +1,181 @@ + + + + + + + Basic Range Area Chart + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ <div id="chart"> + <ReactApexChart options={this.state.options} series={this.state.series} type="rangeArea" height={350} /> +</div> +
+ + + + + + diff --git a/samples/react/rangeArea/range-area-line-combo.html b/samples/react/rangeArea/range-area-line-combo.html new file mode 100644 index 000000000..3ce47cde8 --- /dev/null +++ b/samples/react/rangeArea/range-area-line-combo.html @@ -0,0 +1,308 @@ + + + + + + + Range Area - Line (Combo) + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ <div id="chart"> + <ReactApexChart options={this.state.options} series={this.state.series} type="rangeArea" height={350} /> +</div> +
+ + + + + + diff --git a/samples/source/rangeArea/basic-range-area.xml b/samples/source/rangeArea/basic-range-area.xml new file mode 100644 index 000000000..ab70e09d1 --- /dev/null +++ b/samples/source/rangeArea/basic-range-area.xml @@ -0,0 +1,89 @@ +Basic Range Area Chart + + + +chart: { + height: 350, + type: 'rangeArea' +}, +stroke: { + curve: 'straight' +}, +title: { + text: 'New York Temperature (all year round)' +}, +markers: { + hover: { + sizeOffset: 5 + } +}, +dataLabels: { + enabled: false +}, +yaxis: { + labels: { + formatter: (val) => { + return val + '°C' + } + } +} + + + +[ + { + name: 'New York Temperature', + data: [ + { + x: 'Jan', + y: [-2, 4] + }, + { + x: 'Feb', + y: [-1, 6] + }, + { + x: 'Mar', + y: [3, 10] + }, + { + x: 'Apr', + y: [8, 16] + }, + { + x: 'May', + y: [13, 22] + }, + { + x: 'Jun', + y: [18, 26] + }, + { + x: 'Jul', + y: [21, 29] + }, + { + x: 'Aug', + y: [21, 28] + }, + { + x: 'Sep', + y: [17, 24] + }, + { + x: 'Oct', + y: [11, 18] + }, + { + x: 'Nov', + y: [6, 12] + }, + { + x: 'Dec', + y: [1, 7] + } + ] + } +] + + \ No newline at end of file diff --git a/samples/source/rangeArea/range-area-line-combo.xml b/samples/source/rangeArea/range-area-line-combo.xml new file mode 100644 index 000000000..75898002e --- /dev/null +++ b/samples/source/rangeArea/range-area-line-combo.xml @@ -0,0 +1,217 @@ +Range Area - Line (Combo) + + + + +chart: { + height: 350, + type: 'rangeArea', + animations: { + speed: 500 + } +}, +colors: ['#d4526e', '#33b2df', '#d4526e', '#33b2df'], +dataLabels: { + enabled: false +}, +fill: { + opacity: [0.24, 0.24, 1, 1] +}, +forecastDataPoints: { + count: 2 +}, +stroke: { + curve: 'straight', + width: [0, 0, 2, 2] +}, +legend: { + show: true, + customLegendItems: ['Team B', 'Team A'], + inverseOrder: true +}, +title: { + text: 'Range Area with Forecast Line (Combo)' +}, +markers: { + hover: { + sizeOffset: 5 + } +} + + + +[ + { + type: 'rangeArea', + name: 'Team B Range', + + data: [ + { + x: 'Jan', + y: [1100, 1900] + }, + { + x: 'Feb', + y: [1200, 1800] + }, + { + x: 'Mar', + y: [900, 2900] + }, + { + x: 'Apr', + y: [1400, 2700] + }, + { + x: 'May', + y: [2600, 3900] + }, + { + x: 'Jun', + y: [500, 1700] + }, + { + x: 'Jul', + y: [1900, 2300] + }, + { + x: 'Aug', + y: [1000, 1500] + } + ] + }, + + { + type: 'rangeArea', + name: 'Team A Range', + data: [ + { + x: 'Jan', + y: [3100, 3400] + }, + { + x: 'Feb', + y: [4200, 5200] + }, + { + x: 'Mar', + y: [3900, 4900] + }, + { + x: 'Apr', + y: [3400, 3900] + }, + { + x: 'May', + y: [5100, 5900] + }, + { + x: 'Jun', + y: [5400, 6700] + }, + { + x: 'Jul', + y: [4300, 4600] + }, + { + x: 'Aug', + y: [2100, 2900] + } + ] + }, + + { + type: 'line', + name: 'Team B Median', + data: [ + { + x: 'Jan', + y: 1500 + }, + { + x: 'Feb', + y: 1700 + }, + { + x: 'Mar', + y: 1900 + }, + { + x: 'Apr', + y: 2200 + }, + { + x: 'May', + y: 3000 + }, + { + x: 'Jun', + y: 1000 + }, + { + x: 'Jul', + y: 2100 + }, + { + x: 'Aug', + y: 1200 + }, + { + x: 'Sep', + y: 1800 + }, + { + x: 'Oct', + y: 2000 + } + ] + }, + { + type: 'line', + name: 'Team A Median', + data: [ + { + x: 'Jan', + y: 3300 + }, + { + x: 'Feb', + y: 4900 + }, + { + x: 'Mar', + y: 4300 + }, + { + x: 'Apr', + y: 3700 + }, + { + x: 'May', + y: 5500 + }, + { + x: 'Jun', + y: 5900 + }, + { + x: 'Jul', + y: 4500 + }, + { + x: 'Aug', + y: 2400 + }, + { + x: 'Sep', + y: 2100 + }, + { + x: 'Oct', + y: 1500 + } + ] + } +] + + \ No newline at end of file diff --git a/samples/vanilla-js/rangeArea/basic-range-area.html b/samples/vanilla-js/rangeArea/basic-range-area.html new file mode 100644 index 000000000..ffa8b82ed --- /dev/null +++ b/samples/vanilla-js/rangeArea/basic-range-area.html @@ -0,0 +1,148 @@ + + + + + + + Basic Range Area Chart + + + + + + + + + + + + + + + + + +
+ + + + + + diff --git a/samples/vanilla-js/rangeArea/range-area-line-combo.html b/samples/vanilla-js/rangeArea/range-area-line-combo.html new file mode 100644 index 000000000..9c8885241 --- /dev/null +++ b/samples/vanilla-js/rangeArea/range-area-line-combo.html @@ -0,0 +1,275 @@ + + + + + + + Range Area - Line (Combo) + + + + + + + + + + + + + + + + + +
+ + + + + + diff --git a/samples/vue/rangeArea/basic-range-area.html b/samples/vue/rangeArea/basic-range-area.html new file mode 100644 index 000000000..9760c5366 --- /dev/null +++ b/samples/vue/rangeArea/basic-range-area.html @@ -0,0 +1,167 @@ + + + + + + + Basic Range Area Chart + + + + + + + + + + + + + + + + + + + + +
+
+ +
+
+ + +
+ <div id="chart"> + <apexchart type="rangeArea" height="350" :options="chartOptions" :series="series"></apexchart> + </div> +
+ + + + + diff --git a/samples/vue/rangeArea/range-area-line-combo.html b/samples/vue/rangeArea/range-area-line-combo.html new file mode 100644 index 000000000..89a350fd8 --- /dev/null +++ b/samples/vue/rangeArea/range-area-line-combo.html @@ -0,0 +1,294 @@ + + + + + + + Range Area - Line (Combo) + + + + + + + + + + + + + + + + + + + + +
+
+ +
+
+ + +
+ <div id="chart"> + <apexchart type="rangeArea" height="350" :options="chartOptions" :series="series"></apexchart> + </div> +
+ + + + + diff --git a/src/assets/apexcharts.css b/src/assets/apexcharts.css index 15b766e74..47619fcae 100644 --- a/src/assets/apexcharts.css +++ b/src/assets/apexcharts.css @@ -1,39 +1,51 @@ +@keyframes opaque { + 0% { + opacity: 0 + } + + to { + opacity: 1 + } +} + +@keyframes resizeanim { + 0%,to { + opacity: 0 + } +} + .apexcharts-canvas { position: relative; - user-select: none; - /* cannot give overflow: hidden as it will crop tooltips which overflow outside chart area */ + user-select: none } - -/* scrollbar is not visible by default for legend, hence forcing the visibility */ .apexcharts-canvas ::-webkit-scrollbar { -webkit-appearance: none; - width: 6px; + width: 6px } .apexcharts-canvas ::-webkit-scrollbar-thumb { border-radius: 4px; - background-color: rgba(0, 0, 0, .5); - box-shadow: 0 0 1px rgba(255, 255, 255, .5); - -webkit-box-shadow: 0 0 1px rgba(255, 255, 255, .5); + background-color: rgba(0,0,0,.5); + box-shadow: 0 0 1px rgba(255,255,255,.5); + -webkit-box-shadow: 0 0 1px rgba(255,255,255,.5) } - .apexcharts-inner { - position: relative; + position: relative } .apexcharts-text tspan { - font-family: inherit; + font-family: inherit } .legend-mouseover-inactive { - transition: 0.15s ease all; - opacity: 0.20; + transition: .15s ease all; + opacity: .2 } .apexcharts-series-collapsed { - opacity: 0; + opacity: 0 } .apexcharts-tooltip { @@ -51,90 +63,73 @@ overflow: hidden; white-space: nowrap; z-index: 12; - transition: 0.15s ease all; + transition: .15s ease all } .apexcharts-tooltip.apexcharts-active { opacity: 1; - transition: 0.15s ease all; + transition: .15s ease all } .apexcharts-tooltip.apexcharts-theme-light { border: 1px solid #e3e3e3; - background: rgba(255, 255, 255, 0.96); + background: rgba(255,255,255,.96) } .apexcharts-tooltip.apexcharts-theme-dark { color: #fff; - background: rgba(30, 30, 30, 0.8); + background: rgba(30,30,30,.8) } .apexcharts-tooltip * { - font-family: inherit; + font-family: inherit } - .apexcharts-tooltip-title { padding: 6px; font-size: 15px; - margin-bottom: 4px; + margin-bottom: 4px } .apexcharts-tooltip.apexcharts-theme-light .apexcharts-tooltip-title { - background: #ECEFF1; - border-bottom: 1px solid #ddd; + background: #eceff1; + border-bottom: 1px solid #ddd } .apexcharts-tooltip.apexcharts-theme-dark .apexcharts-tooltip-title { - background: rgba(0, 0, 0, 0.7); - border-bottom: 1px solid #333; + background: rgba(0,0,0,.7); + border-bottom: 1px solid #333 } -.apexcharts-tooltip-text-y-value, -.apexcharts-tooltip-text-goals-value, -.apexcharts-tooltip-text-z-value { +.apexcharts-tooltip-text-goals-value,.apexcharts-tooltip-text-y-value,.apexcharts-tooltip-text-z-value { display: inline-block; - font-weight: 600; margin-left: 5px; + font-weight: 600 } -.apexcharts-tooltip-title:empty, -.apexcharts-tooltip-text-y-label:empty, -.apexcharts-tooltip-text-y-value:empty, -.apexcharts-tooltip-text-goals-label:empty, -.apexcharts-tooltip-text-goals-value:empty, -.apexcharts-tooltip-text-z-value:empty { - display: none; +.apexcharts-tooltip-text-goals-label:empty,.apexcharts-tooltip-text-goals-value:empty,.apexcharts-tooltip-text-y-label:empty,.apexcharts-tooltip-text-y-value:empty,.apexcharts-tooltip-text-z-value:empty,.apexcharts-tooltip-title:empty { + display: none } -.apexcharts-tooltip-text-y-value, -.apexcharts-tooltip-text-goals-value, -.apexcharts-tooltip-text-z-value { - font-weight: 600; +.apexcharts-tooltip-text-goals-label,.apexcharts-tooltip-text-goals-value { + padding: 6px 0 5px } -.apexcharts-tooltip-text-goals-label, -.apexcharts-tooltip-text-goals-value { - padding: 6px 0 5px; +.apexcharts-tooltip-goals-group,.apexcharts-tooltip-text-goals-label,.apexcharts-tooltip-text-goals-value { + display: flex } -.apexcharts-tooltip-goals-group, -.apexcharts-tooltip-text-goals-label, -.apexcharts-tooltip-text-goals-value { - display: flex; -} -.apexcharts-tooltip-text-goals-label:not(:empty), -.apexcharts-tooltip-text-goals-value:not(:empty) { - margin-top: -6px; +.apexcharts-tooltip-text-goals-label:not(:empty),.apexcharts-tooltip-text-goals-value:not(:empty) { + margin-top: -6px } .apexcharts-tooltip-marker { width: 12px; height: 12px; position: relative; - top: 0px; + top: 0; margin-right: 10px; - border-radius: 50%; + border-radius: 50% } .apexcharts-tooltip-series-group { @@ -142,64 +137,62 @@ display: none; text-align: left; justify-content: left; - align-items: center; + align-items: center } .apexcharts-tooltip-series-group.apexcharts-active .apexcharts-tooltip-marker { - opacity: 1; + opacity: 1 } -.apexcharts-tooltip-series-group.apexcharts-active, -.apexcharts-tooltip-series-group:last-child { - padding-bottom: 4px; +.apexcharts-tooltip-series-group.apexcharts-active,.apexcharts-tooltip-series-group:last-child { + padding-bottom: 4px } .apexcharts-tooltip-series-group-hidden { opacity: 0; height: 0; line-height: 0; - padding: 0 !important; + padding: 0!important } .apexcharts-tooltip-y-group { - padding: 6px 0 5px; + padding: 6px 0 5px } -.apexcharts-tooltip-box, .apexcharts-custom-tooltip { - padding: 4px 8px; +.apexcharts-custom-tooltip,.apexcharts-tooltip-box { + padding: 4px 8px } .apexcharts-tooltip-boxPlot { display: flex; - flex-direction: column-reverse; + flex-direction: column-reverse } .apexcharts-tooltip-box>div { - margin: 4px 0; + margin: 4px 0 } .apexcharts-tooltip-box span.value { - font-weight: bold; + font-weight: 700 } .apexcharts-tooltip-rangebar { - padding: 5px 8px; + padding: 5px 8px } .apexcharts-tooltip-rangebar .category { font-weight: 600; - color: #777; + color: #777 } .apexcharts-tooltip-rangebar .series-name { - font-weight: bold; + font-weight: 700; display: block; - margin-bottom: 5px; + margin-bottom: 5px } -.apexcharts-xaxistooltip { +.apexcharts-xaxistooltip,.apexcharts-yaxistooltip { opacity: 0; - padding: 9px 10px; pointer-events: none; color: #373d3f; font-size: 13px; @@ -207,223 +200,192 @@ border-radius: 2px; position: absolute; z-index: 10; - background: #ECEFF1; - border: 1px solid #90A4AE; - transition: 0.15s ease all; + background: #eceff1; + border: 1px solid #90a4ae +} + +.apexcharts-xaxistooltip { + padding: 9px 10px; + transition: .15s ease all } .apexcharts-xaxistooltip.apexcharts-theme-dark { - background: rgba(0, 0, 0, 0.7); - border: 1px solid rgba(0, 0, 0, 0.5); - color: #fff; + background: rgba(0,0,0,.7); + border: 1px solid rgba(0,0,0,.5); + color: #fff } -.apexcharts-xaxistooltip:after, -.apexcharts-xaxistooltip:before { +.apexcharts-xaxistooltip:after,.apexcharts-xaxistooltip:before { left: 50%; border: solid transparent; content: " "; height: 0; width: 0; position: absolute; - pointer-events: none; + pointer-events: none } .apexcharts-xaxistooltip:after { - border-color: rgba(236, 239, 241, 0); + border-color: transparent; border-width: 6px; - margin-left: -6px; + margin-left: -6px } .apexcharts-xaxistooltip:before { - border-color: rgba(144, 164, 174, 0); + border-color: transparent; border-width: 7px; - margin-left: -7px; + margin-left: -7px } -.apexcharts-xaxistooltip-bottom:after, -.apexcharts-xaxistooltip-bottom:before { - bottom: 100%; +.apexcharts-xaxistooltip-bottom:after,.apexcharts-xaxistooltip-bottom:before { + bottom: 100% } -.apexcharts-xaxistooltip-top:after, -.apexcharts-xaxistooltip-top:before { - top: 100%; +.apexcharts-xaxistooltip-top:after,.apexcharts-xaxistooltip-top:before { + top: 100% } .apexcharts-xaxistooltip-bottom:after { - border-bottom-color: #ECEFF1; + border-bottom-color: #eceff1 } .apexcharts-xaxistooltip-bottom:before { - border-bottom-color: #90A4AE; -} - -.apexcharts-xaxistooltip-bottom.apexcharts-theme-dark:after { - border-bottom-color: rgba(0, 0, 0, 0.5); + border-bottom-color: #90a4ae } -.apexcharts-xaxistooltip-bottom.apexcharts-theme-dark:before { - border-bottom-color: rgba(0, 0, 0, 0.5); +.apexcharts-xaxistooltip-bottom.apexcharts-theme-dark:after,.apexcharts-xaxistooltip-bottom.apexcharts-theme-dark:before { + border-bottom-color: rgba(0,0,0,.5) } .apexcharts-xaxistooltip-top:after { - border-top-color: #ECEFF1 + border-top-color: #eceff1 } .apexcharts-xaxistooltip-top:before { - border-top-color: #90A4AE; + border-top-color: #90a4ae } -.apexcharts-xaxistooltip-top.apexcharts-theme-dark:after { - border-top-color: rgba(0, 0, 0, 0.5); -} - -.apexcharts-xaxistooltip-top.apexcharts-theme-dark:before { - border-top-color: rgba(0, 0, 0, 0.5); +.apexcharts-xaxistooltip-top.apexcharts-theme-dark:after,.apexcharts-xaxistooltip-top.apexcharts-theme-dark:before { + border-top-color: rgba(0,0,0,.5) } .apexcharts-xaxistooltip.apexcharts-active { opacity: 1; - transition: 0.15s ease all; + transition: .15s ease all } .apexcharts-yaxistooltip { - opacity: 0; - padding: 4px 10px; - pointer-events: none; - color: #373d3f; - font-size: 13px; - text-align: center; - border-radius: 2px; - position: absolute; - z-index: 10; - background: #ECEFF1; - border: 1px solid #90A4AE; + padding: 4px 10px } .apexcharts-yaxistooltip.apexcharts-theme-dark { - background: rgba(0, 0, 0, 0.7); - border: 1px solid rgba(0, 0, 0, 0.5); - color: #fff; + background: rgba(0,0,0,.7); + border: 1px solid rgba(0,0,0,.5); + color: #fff } -.apexcharts-yaxistooltip:after, -.apexcharts-yaxistooltip:before { +.apexcharts-yaxistooltip:after,.apexcharts-yaxistooltip:before { top: 50%; border: solid transparent; content: " "; height: 0; width: 0; position: absolute; - pointer-events: none; + pointer-events: none } .apexcharts-yaxistooltip:after { - border-color: rgba(236, 239, 241, 0); + border-color: transparent; border-width: 6px; - margin-top: -6px; + margin-top: -6px } .apexcharts-yaxistooltip:before { - border-color: rgba(144, 164, 174, 0); + border-color: transparent; border-width: 7px; - margin-top: -7px; + margin-top: -7px } -.apexcharts-yaxistooltip-left:after, -.apexcharts-yaxistooltip-left:before { - left: 100%; +.apexcharts-yaxistooltip-left:after,.apexcharts-yaxistooltip-left:before { + left: 100% } -.apexcharts-yaxistooltip-right:after, -.apexcharts-yaxistooltip-right:before { - right: 100%; +.apexcharts-yaxistooltip-right:after,.apexcharts-yaxistooltip-right:before { + right: 100% } .apexcharts-yaxistooltip-left:after { - border-left-color: #ECEFF1; + border-left-color: #eceff1 } .apexcharts-yaxistooltip-left:before { - border-left-color: #90A4AE; + border-left-color: #90a4ae } -.apexcharts-yaxistooltip-left.apexcharts-theme-dark:after { - border-left-color: rgba(0, 0, 0, 0.5); -} - -.apexcharts-yaxistooltip-left.apexcharts-theme-dark:before { - border-left-color: rgba(0, 0, 0, 0.5); +.apexcharts-yaxistooltip-left.apexcharts-theme-dark:after,.apexcharts-yaxistooltip-left.apexcharts-theme-dark:before { + border-left-color: rgba(0,0,0,.5) } .apexcharts-yaxistooltip-right:after { - border-right-color: #ECEFF1; + border-right-color: #eceff1 } .apexcharts-yaxistooltip-right:before { - border-right-color: #90A4AE; -} - -.apexcharts-yaxistooltip-right.apexcharts-theme-dark:after { - border-right-color: rgba(0, 0, 0, 0.5); + border-right-color: #90a4ae } -.apexcharts-yaxistooltip-right.apexcharts-theme-dark:before { - border-right-color: rgba(0, 0, 0, 0.5); +.apexcharts-yaxistooltip-right.apexcharts-theme-dark:after,.apexcharts-yaxistooltip-right.apexcharts-theme-dark:before { + border-right-color: rgba(0,0,0,.5) } .apexcharts-yaxistooltip.apexcharts-active { - opacity: 1; + opacity: 1 } .apexcharts-yaxistooltip-hidden { - display: none; + display: none } -.apexcharts-xcrosshairs, -.apexcharts-ycrosshairs { +.apexcharts-xcrosshairs,.apexcharts-ycrosshairs { pointer-events: none; opacity: 0; - transition: 0.15s ease all; + transition: .15s ease all } -.apexcharts-xcrosshairs.apexcharts-active, -.apexcharts-ycrosshairs.apexcharts-active { +.apexcharts-xcrosshairs.apexcharts-active,.apexcharts-ycrosshairs.apexcharts-active { opacity: 1; - transition: 0.15s ease all; + transition: .15s ease all } .apexcharts-ycrosshairs-hidden { - opacity: 0; + opacity: 0 } .apexcharts-selection-rect { - cursor: move; + cursor: move } -.svg_select_boundingRect, .svg_select_points_rot { +.svg_select_boundingRect,.svg_select_points_rot { pointer-events: none; opacity: 0; - visibility: hidden; + visibility: hidden } -.apexcharts-selection-rect + g .svg_select_boundingRect, -.apexcharts-selection-rect + g .svg_select_points_rot { + +.apexcharts-selection-rect+g .svg_select_boundingRect,.apexcharts-selection-rect+g .svg_select_points_rot { opacity: 0; - visibility: hidden; + visibility: hidden } -.apexcharts-selection-rect + g .svg_select_points_l, -.apexcharts-selection-rect + g .svg_select_points_r { +.apexcharts-selection-rect+g .svg_select_points_l,.apexcharts-selection-rect+g .svg_select_points_r { cursor: ew-resize; opacity: 1; - visibility: visible; + visibility: visible } .svg_select_points { fill: #efefef; stroke: #333; - rx: 2; + rx: 2 } .apexcharts-svg.apexcharts-zoomable.hovering-zoom { @@ -434,104 +396,75 @@ cursor: move } -.apexcharts-zoom-icon, -.apexcharts-zoomin-icon, -.apexcharts-zoomout-icon, -.apexcharts-reset-icon, -.apexcharts-pan-icon, -.apexcharts-selection-icon, -.apexcharts-menu-icon, -.apexcharts-toolbar-custom-icon { +.apexcharts-menu-icon,.apexcharts-pan-icon,.apexcharts-reset-icon,.apexcharts-selection-icon,.apexcharts-toolbar-custom-icon,.apexcharts-zoom-icon,.apexcharts-zoomin-icon,.apexcharts-zoomout-icon { cursor: pointer; width: 20px; height: 20px; line-height: 24px; - color: #6E8192; - text-align: center; + color: #6e8192; + text-align: center } -.apexcharts-zoom-icon svg, -.apexcharts-zoomin-icon svg, -.apexcharts-zoomout-icon svg, -.apexcharts-reset-icon svg, -.apexcharts-menu-icon svg { - fill: #6E8192; +.apexcharts-menu-icon svg,.apexcharts-reset-icon svg,.apexcharts-zoom-icon svg,.apexcharts-zoomin-icon svg,.apexcharts-zoomout-icon svg { + fill: #6e8192 } .apexcharts-selection-icon svg { fill: #444; - transform: scale(0.76) + transform: scale(.76) } -.apexcharts-theme-dark .apexcharts-zoom-icon svg, -.apexcharts-theme-dark .apexcharts-zoomin-icon svg, -.apexcharts-theme-dark .apexcharts-zoomout-icon svg, -.apexcharts-theme-dark .apexcharts-reset-icon svg, -.apexcharts-theme-dark .apexcharts-pan-icon svg, -.apexcharts-theme-dark .apexcharts-selection-icon svg, -.apexcharts-theme-dark .apexcharts-menu-icon svg, -.apexcharts-theme-dark .apexcharts-toolbar-custom-icon svg { - fill: #f3f4f5; +.apexcharts-theme-dark .apexcharts-menu-icon svg,.apexcharts-theme-dark .apexcharts-pan-icon svg,.apexcharts-theme-dark .apexcharts-reset-icon svg,.apexcharts-theme-dark .apexcharts-selection-icon svg,.apexcharts-theme-dark .apexcharts-toolbar-custom-icon svg,.apexcharts-theme-dark .apexcharts-zoom-icon svg,.apexcharts-theme-dark .apexcharts-zoomin-icon svg,.apexcharts-theme-dark .apexcharts-zoomout-icon svg { + fill: #f3f4f5 } -.apexcharts-canvas .apexcharts-zoom-icon.apexcharts-selected svg, -.apexcharts-canvas .apexcharts-selection-icon.apexcharts-selected svg, -.apexcharts-canvas .apexcharts-reset-zoom-icon.apexcharts-selected svg { - fill: #008FFB; +.apexcharts-canvas .apexcharts-reset-zoom-icon.apexcharts-selected svg,.apexcharts-canvas .apexcharts-selection-icon.apexcharts-selected svg,.apexcharts-canvas .apexcharts-zoom-icon.apexcharts-selected svg { + fill: #008ffb } -.apexcharts-theme-light .apexcharts-selection-icon:not(.apexcharts-selected):hover svg, -.apexcharts-theme-light .apexcharts-zoom-icon:not(.apexcharts-selected):hover svg, -.apexcharts-theme-light .apexcharts-zoomin-icon:hover svg, -.apexcharts-theme-light .apexcharts-zoomout-icon:hover svg, -.apexcharts-theme-light .apexcharts-reset-icon:hover svg, -.apexcharts-theme-light .apexcharts-menu-icon:hover svg { - fill: #333; +.apexcharts-theme-light .apexcharts-menu-icon:hover svg,.apexcharts-theme-light .apexcharts-reset-icon:hover svg,.apexcharts-theme-light .apexcharts-selection-icon:not(.apexcharts-selected):hover svg,.apexcharts-theme-light .apexcharts-zoom-icon:not(.apexcharts-selected):hover svg,.apexcharts-theme-light .apexcharts-zoomin-icon:hover svg,.apexcharts-theme-light .apexcharts-zoomout-icon:hover svg { + fill: #333 } -.apexcharts-selection-icon, -.apexcharts-menu-icon { - position: relative; +.apexcharts-menu-icon,.apexcharts-selection-icon { + position: relative } .apexcharts-reset-icon { - margin-left: 5px; + margin-left: 5px } -.apexcharts-zoom-icon, -.apexcharts-reset-icon, -.apexcharts-menu-icon { - transform: scale(0.85); +.apexcharts-menu-icon,.apexcharts-reset-icon,.apexcharts-zoom-icon { + transform: scale(.85) } -.apexcharts-zoomin-icon, -.apexcharts-zoomout-icon { - transform: scale(0.7) +.apexcharts-zoomin-icon,.apexcharts-zoomout-icon { + transform: scale(.7) } .apexcharts-zoomout-icon { - margin-right: 3px; + margin-right: 3px } .apexcharts-pan-icon { - transform: scale(0.62); + transform: scale(.62); position: relative; left: 1px; - top: 0px; + top: 0 } .apexcharts-pan-icon svg { fill: #fff; - stroke: #6E8192; - stroke-width: 2; + stroke: #6e8192; + stroke-width: 2 } .apexcharts-pan-icon.apexcharts-selected svg { - stroke: #008FFB; + stroke: #008ffb } .apexcharts-pan-icon:not(.apexcharts-selected):hover svg { - stroke: #333; + stroke: #333 } .apexcharts-toolbar { @@ -540,10 +473,10 @@ max-width: 176px; text-align: right; border-radius: 3px; - padding: 0px 6px 2px 6px; + padding: 0 6px 2px; display: flex; justify-content: space-between; - align-items: center; + align-items: center } .apexcharts-menu { @@ -556,136 +489,88 @@ right: 10px; opacity: 0; min-width: 110px; - transition: 0.15s ease all; - pointer-events: none; + transition: .15s ease all; + pointer-events: none } .apexcharts-menu.apexcharts-menu-open { opacity: 1; pointer-events: all; - transition: 0.15s ease all; + transition: .15s ease all } .apexcharts-menu-item { padding: 6px 7px; font-size: 12px; - cursor: pointer; + cursor: pointer } .apexcharts-theme-light .apexcharts-menu-item:hover { - background: #eee; + background: #eee } .apexcharts-theme-dark .apexcharts-menu { - background: rgba(0, 0, 0, 0.7); - color: #fff; + background: rgba(0,0,0,.7); + color: #fff } -@media screen and (min-width: 768px) { +@media screen and (min-width:768px) { .apexcharts-canvas:hover .apexcharts-toolbar { - opacity: 1; + opacity: 1 } } -.apexcharts-datalabel.apexcharts-element-hidden { - opacity: 0; +.apexcharts-canvas .apexcharts-element-hidden,.apexcharts-datalabel.apexcharts-element-hidden,.apexcharts-hide .apexcharts-series-points { + opacity: 0 } -.apexcharts-pie-label, -.apexcharts-datalabels, -.apexcharts-datalabel, -.apexcharts-datalabel-label, -.apexcharts-datalabel-value { +.apexcharts-datalabel,.apexcharts-datalabel-label,.apexcharts-datalabel-value,.apexcharts-datalabels,.apexcharts-pie-label { cursor: default; - pointer-events: none; + pointer-events: none } .apexcharts-pie-label-delay { opacity: 0; animation-name: opaque; - animation-duration: 0.3s; + animation-duration: .3s; animation-fill-mode: forwards; - animation-timing-function: ease; + animation-timing-function: ease } -.apexcharts-canvas .apexcharts-element-hidden { - opacity: 0; -} - -.apexcharts-hide .apexcharts-series-points { - opacity: 0; +.apexcharts-annotation-rect,.apexcharts-area-series .apexcharts-area,.apexcharts-area-series .apexcharts-series-markers .apexcharts-marker.no-pointer-events,.apexcharts-gridline,.apexcharts-line,.apexcharts-line-series .apexcharts-series-markers .apexcharts-marker.no-pointer-events,.apexcharts-point-annotation-label,.apexcharts-radar-series path,.apexcharts-radar-series polygon,.apexcharts-toolbar svg,.apexcharts-tooltip .apexcharts-marker,.apexcharts-xaxis-annotation-label,.apexcharts-yaxis-annotation-label,.apexcharts-zoom-rect { + pointer-events: none } -.apexcharts-gridline, -.apexcharts-annotation-rect, -.apexcharts-xaxis-annotation-label, -.apexcharts-yaxis-annotation-label, -.apexcharts-point-annotation-label, -.apexcharts-tooltip .apexcharts-marker, -.apexcharts-area-series .apexcharts-area, -.apexcharts-line, -.apexcharts-zoom-rect, -.apexcharts-toolbar svg, -.apexcharts-area-series .apexcharts-series-markers .apexcharts-marker.no-pointer-events, -.apexcharts-line-series .apexcharts-series-markers .apexcharts-marker.no-pointer-events, -.apexcharts-radar-series path, -.apexcharts-radar-series polygon { - pointer-events: none; -} - - -/* markers */ - .apexcharts-marker { - transition: 0.15s ease all; -} - -@keyframes opaque { - 0% { - opacity: 0; - } - 100% { - opacity: 1; - } -} - - -/* Resize generated styles */ - -@keyframes resizeanim { - from { - opacity: 0; - } - to { - opacity: 0; - } + transition: .15s ease all } .resize-triggers { animation: 1ms resizeanim; visibility: hidden; opacity: 0; + height: 100%; + width: 100%; + overflow: hidden } -.resize-triggers, -.resize-triggers>div, -.contract-trigger:before { +.contract-trigger:before,.resize-triggers,.resize-triggers>div { content: " "; display: block; position: absolute; top: 0; - left: 0; - height: 100%; - width: 100%; - overflow: hidden; + left: 0 } .resize-triggers>div { + height: 100%; + width: 100%; background: #eee; - overflow: auto; + overflow: auto } .contract-trigger:before { + overflow: hidden; width: 200%; - height: 200%; + height: 200% } \ No newline at end of file diff --git a/src/charts/Bar.js b/src/charts/Bar.js index 48a3cd850..d435a0d92 100644 --- a/src/charts/Bar.js +++ b/src/charts/Bar.js @@ -23,7 +23,7 @@ class Bar { this.strokeWidth = w.config.stroke.width this.isNullValue = false - this.isRangeBar = w.globals.seriesRangeBar.length && this.isHorizontal + this.isRangeBar = w.globals.seriesRange.length && this.isHorizontal this.xyRatios = xyRatios diff --git a/src/charts/Line.js b/src/charts/Line.js index 4b8e0e2ae..1a3f4818d 100644 --- a/src/charts/Line.js +++ b/src/charts/Line.js @@ -8,7 +8,7 @@ import Utils from '../utils/Utils' import Helpers from './common/line/Helpers' /** - * ApexCharts Line Class responsible for drawing Line / Area Charts. + * ApexCharts Line Class responsible for drawing Line / Area / RangeArea Charts. * This class is also responsible for generating values for Bubble/Scatter charts, so need to rename it to Axis Charts to avoid confusions * @module Line **/ @@ -38,10 +38,10 @@ class Line { this.yaxisIndex = 0 } - draw(series, ptype, seriesIndex) { + draw(series, ctype, seriesIndex, seriesRangeEnd) { let w = this.w let graphics = new Graphics(this.ctx) - let type = w.globals.comboCharts ? ptype : w.config.chart.type + let type = w.globals.comboCharts ? ctype : w.config.chart.type let ret = graphics.group({ class: `apexcharts-${type}-series apexcharts-plot-series` }) @@ -84,8 +84,10 @@ class Line { let pX = x let pY + let pY2 let prevX = pX let prevY = this.zeroY + let prevY2 = this.zeroY let lineYPosition = 0 // the first value in the current series is not null or undefined @@ -96,19 +98,35 @@ class Line { lineYPosition }) prevY = firstPrevY.prevY - yArrj.push(prevY) pY = prevY + // y2 are needed for range-area charts + let firstPrevY2 + + if (type === 'rangeArea') { + firstPrevY2 = this.lineHelpers.determineFirstPrevY({ + i, + series: seriesRangeEnd, + prevY: prevY2, + lineYPosition + }) + prevY2 = firstPrevY2.prevY + pY2 = prevY2 + } + let pathsFrom = this._calculatePathsFrom({ + type, series, i, realIndex, prevX, - prevY + prevY, + prevY2 }) - let paths = this._iterateOverDataPoints({ + const iteratingOpts = { + type, series, realIndex, i, @@ -122,9 +140,37 @@ class Line { seriesIndex, lineYPosition, xArrj, - yArrj + yArrj, + seriesRangeEnd + } + + let paths = this._iterateOverDataPoints({ + ...iteratingOpts, + iterations: type === 'rangeArea' ? series[i].length - 1 : undefined, + isRangeStart: true }) + if (type === 'rangeArea') { + let pathsFrom2 = this._calculatePathsFrom({ + series: seriesRangeEnd, + i, + realIndex, + prevX, + prevY: prevY2 + }) + let rangePaths = this._iterateOverDataPoints({ + ...iteratingOpts, + series: seriesRangeEnd, + pY: pY2, + pathsFrom: pathsFrom2, + iterations: seriesRangeEnd[i].length - 1, + isRangeStart: false + }) + + paths.linePaths[0] = rangePaths.linePath + paths.linePath + paths.pathFromLine = rangePaths.pathFromLine + paths.pathFromLine + } + this._handlePaths({ type, realIndex, i, paths }) this.elSeries.add(this.elPointsMain) @@ -212,7 +258,7 @@ class Line { this.appendPathFrom = true } - _calculatePathsFrom({ series, i, realIndex, prevX, prevY }) { + _calculatePathsFrom({ type, series, i, realIndex, prevX, prevY, prevY2 }) { const w = this.w const graphics = new Graphics(this.ctx) let linePath, areaPath, pathFromLine, pathFromArea @@ -230,6 +276,10 @@ class Line { } } else { linePath = graphics.move(prevX, prevY) + + if (type === 'rangeArea') { + linePath = graphics.move(prevX, prevY2) + graphics.line(prevX, prevY) + } areaPath = graphics.move(prevX, this.areaBottomY) + graphics.line(prevX, prevY) } @@ -270,7 +320,7 @@ class Line { w.globals.seriesYvalues[realIndex] = paths.yArrj const forecast = w.config.forecastDataPoints - if (forecast.count > 0) { + if (forecast.count > 0 && type !== 'rangeArea') { const forecastCutoff = w.globals.seriesXvalues[realIndex][ w.globals.seriesXvalues[realIndex].length - forecast.count - 1 @@ -353,7 +403,14 @@ class Line { } } + // range-area paths are drawn using linePaths for (let p = 0; p < paths.linePaths.length; p++) { + let pathFill = lineFill + if (type === 'rangeArea') { + pathFill = fill.fillPath({ + seriesNumber: realIndex + }) + } const linePathCommonOpts = { ...defaultRenderedPathOptions, pathFrom: paths.pathFromLine, @@ -361,12 +418,13 @@ class Line { stroke: lineFill, strokeWidth: this.strokeWidth, strokeLineCap: w.config.stroke.lineCap, - fill: 'none' + fill: type === 'rangeArea' ? pathFill : 'none' } let renderedPath = graphics.renderPaths(linePathCommonOpts) this.elSeries.add(renderedPath) + renderedPath.attr('fill-rule', `evenodd`) - if (forecast.count > 0) { + if (forecast.count > 0 && type !== 'rangeArea') { let renderedForecastPath = graphics.renderPaths(linePathCommonOpts) renderedForecastPath.node.setAttribute( @@ -396,7 +454,9 @@ class Line { } _iterateOverDataPoints({ + type, series, + iterations, realIndex, i, x, @@ -409,7 +469,9 @@ class Line { seriesIndex, lineYPosition, xArrj, - yArrj + yArrj, + isRangeStart, + seriesRangeEnd }) { const w = this.w let graphics = new Graphics(this.ctx) @@ -420,9 +482,14 @@ class Line { ? w.globals.minYArr[realIndex] : w.globals.minY - const iterations = - w.globals.dataPoints > 1 ? w.globals.dataPoints - 1 : w.globals.dataPoints + if (!iterations) { + iterations = + w.globals.dataPoints > 1 + ? w.globals.dataPoints - 1 + : w.globals.dataPoints + } + let y2 = y for (let j = 0; j < iterations; j++) { const isNull = typeof series[i][j + 1] === 'undefined' || series[i][j + 1] === null @@ -474,6 +541,16 @@ class Line { lineYPosition - series[i][j + 1] / yRatio[this.yaxisIndex] + (this.isReversed ? series[i][j + 1] / yRatio[this.yaxisIndex] : 0) * 2 + + if (type === 'rangeArea') { + y2 = + lineYPosition - + seriesRangeEnd[i][j + 1] / yRatio[this.yaxisIndex] + + (this.isReversed + ? seriesRangeEnd[i][j + 1] / yRatio[this.yaxisIndex] + : 0) * + 2 + } } // push current X @@ -493,19 +570,22 @@ class Line { }) let calculatedPaths = this._createPaths({ + type, series, i, realIndex, j, x, y, + y2, pX, pY, linePath, areaPath, linePaths, areaPaths, - seriesIndex + seriesIndex, + isRangeStart }) areaPaths = calculatedPaths.areaPaths @@ -523,14 +603,12 @@ class Line { this.handleNullDataPoints(series, pointsPos, i, j, realIndex) this._handleMarkersAndLabels({ + type, pointsPos, - series, - x, - y, - prevY, i, j, - realIndex + realIndex, + isRangeStart }) } @@ -540,11 +618,13 @@ class Line { pathFromArea, areaPaths, pathFromLine, - linePaths + linePaths, + linePath, + areaPath } } - _handleMarkersAndLabels({ pointsPos, series, x, y, prevY, i, j, realIndex }) { + _handleMarkersAndLabels({ type, pointsPos, isRangeStart, i, j, realIndex }) { const w = this.w let dataLabels = new DataLabels(this.ctx) @@ -571,31 +651,35 @@ class Line { }) } - let drawnLabels = dataLabels.drawDataLabel( - pointsPos, - realIndex, - j + 1, - null - ) + let drawnLabels = dataLabels.drawDataLabel({ + type, + isRangeStart, + pos: pointsPos, + i: realIndex, + j: j + 1 + }) if (drawnLabels !== null) { this.elDataLabelsWrap.add(drawnLabels) } } _createPaths({ + type, series, i, realIndex, j, x, y, + y2, pX, pY, linePath, areaPath, linePaths, areaPaths, - seriesIndex + seriesIndex, + isRangeStart }) { let w = this.w let graphics = new Graphics(this.ctx) @@ -652,9 +736,18 @@ class Line { graphics.curve(pX, pY, x, y, x, areaBottomY) + graphics.move(x, y) + 'z' - if (!w.globals.hasNullValues) { - linePaths.push(linePath) - areaPaths.push(areaPath) + + if (type === 'rangeArea' && isRangeStart) { + linePath = + linePath + + graphics.curve(pX, pY, x, y, x, y2) + + graphics.move(x, y2) + + 'z' + } else { + if (!w.globals.hasNullValues) { + linePaths.push(linePath) + areaPaths.push(areaPath) + } } } } else { @@ -689,8 +782,14 @@ class Line { // last loop, close path areaPath = areaPath + graphics.line(x, areaBottomY) + graphics.move(x, y) + 'z' - linePaths.push(linePath) - areaPaths.push(areaPath) + + if (type === 'rangeArea' && isRangeStart) { + linePath = + linePath + graphics.line(x, y2) + graphics.move(x, y2) + 'z' + } else { + linePaths.push(linePath) + areaPaths.push(areaPath) + } } } diff --git a/src/charts/RangeBar.js b/src/charts/RangeBar.js index cdfb6bcd3..03d96c64f 100644 --- a/src/charts/RangeBar.js +++ b/src/charts/RangeBar.js @@ -212,7 +212,7 @@ class RangeBar extends Bar { const labelX = w.config.series[i].data[j].x const rowIndex = w.globals.labels.indexOf(labelX) - const overlappedIndex = w.globals.seriesRangeBar[i].findIndex( + const overlappedIndex = w.globals.seriesRange[i].findIndex( (tx) => tx.x === labelX && tx.overlaps.length > 0 ) @@ -223,7 +223,7 @@ class RangeBar extends Bar { } if (overlappedIndex > -1 && !w.config.plotOptions.bar.rangeBarOverlap) { - overlaps = w.globals.seriesRangeBar[i][overlappedIndex].overlaps + overlaps = w.globals.seriesRange[i][overlappedIndex].overlaps if (overlaps.indexOf(rangeName) > -1) { barHeight = initPositions.barHeight / overlaps.length @@ -368,87 +368,6 @@ class RangeBar extends Bar { end: w.globals.seriesRangeEnd[i][j] } } - - getTooltipValues({ ctx, seriesIndex, dataPointIndex, y1, y2, w }) { - let start = w.globals.seriesRangeStart[seriesIndex][dataPointIndex] - let end = w.globals.seriesRangeEnd[seriesIndex][dataPointIndex] - let ylabel = w.globals.labels[dataPointIndex] - let seriesName = w.config.series[seriesIndex].name - ? w.config.series[seriesIndex].name - : '' - const yLbFormatter = w.config.tooltip.y.formatter - const yLbTitleFormatter = w.config.tooltip.y.title.formatter - - const opts = { - w, - seriesIndex, - dataPointIndex, - start, - end - } - - if (typeof yLbTitleFormatter === 'function') { - seriesName = yLbTitleFormatter(seriesName, opts) - } - - if (Number.isFinite(y1) && Number.isFinite(y2)) { - start = y1 - end = y2 - - if (w.config.series[seriesIndex].data[dataPointIndex].x) { - ylabel = w.config.series[seriesIndex].data[dataPointIndex].x + ':' - } - - if (typeof yLbFormatter === 'function') { - ylabel = yLbFormatter(ylabel, opts) - } - } - - let startVal = '' - let endVal = '' - - const color = w.globals.colors[seriesIndex] - if (w.config.tooltip.x.formatter === undefined) { - if (w.config.xaxis.type === 'datetime') { - let datetimeObj = new DateTime(ctx) - startVal = datetimeObj.formatDate( - datetimeObj.getDate(start), - w.config.tooltip.x.format - ) - endVal = datetimeObj.formatDate( - datetimeObj.getDate(end), - w.config.tooltip.x.format - ) - } else { - startVal = start - endVal = end - } - } else { - startVal = w.config.tooltip.x.formatter(start) - endVal = w.config.tooltip.x.formatter(end) - } - - return { start, end, startVal, endVal, ylabel, color, seriesName } - } - - buildCustomTooltipHTML({ color, seriesName, ylabel, start, end }) { - return ( - '
' + - '
' + - (seriesName ? seriesName : '') + - '
' + - '
' + - ylabel + - ' ' + - start + - ' - ' + - end + - '
' + - '
' - ) - } } export default RangeBar diff --git a/src/charts/common/bar/Helpers.js b/src/charts/common/bar/Helpers.js index 9a56bab0c..430b3ad29 100644 --- a/src/charts/common/bar/Helpers.js +++ b/src/charts/common/bar/Helpers.js @@ -170,9 +170,9 @@ export default class Helpers { dataPointIndex: j, color: fillColor, value: series[i][j], - fillConfig: w.config.series[i].data[j].fill, - fillType: w.config.series[i].data[j].fill?.type - ? w.config.series[i].data[j].fill.type + fillConfig: w.config.series[i].data[j]?.fill, + fillType: w.config.series[i].data[j]?.fill?.type + ? w.config.series[i].data[j]?.fill.type : w.config.fill.type }) diff --git a/src/charts/common/line/Helpers.js b/src/charts/common/line/Helpers.js index 4aec0afe3..9016918f7 100644 --- a/src/charts/common/line/Helpers.js +++ b/src/charts/common/line/Helpers.js @@ -11,12 +11,12 @@ export default class Helpers { const w = this.w if ( - w.config.chart.type === 'line' && - (w.config.fill.type === 'gradient' || - w.config.fill.type[i] === 'gradient') + w.config.fill.type === 'gradient' || + w.config.fill.type[i] === 'gradient' ) { const coreUtils = new CoreUtils(this.lineCtx.ctx, w) + // applied only to LINE chart // a small adjustment to allow gradient line to draw correctly for all same values /* #fix https://github.com/apexcharts/apexcharts.js/issues/358 */ if (coreUtils.seriesHaveSameValues(i)) { @@ -104,7 +104,7 @@ export default class Helpers { determineFirstPrevY({ i, series, prevY, lineYPosition }) { let w = this.w - if (typeof series[i][0] !== 'undefined') { + if (typeof series[i]?.[0] !== 'undefined') { if (w.config.chart.stacked) { if (i > 0) { // 1st y value of previous series diff --git a/src/modules/Core.js b/src/modules/Core.js index 08457396c..525f8e4d9 100644 --- a/src/modules/Core.js +++ b/src/modules/Core.js @@ -45,6 +45,7 @@ export default class Core { 'area', 'bar', 'rangeBar', + 'rangeArea', 'candlestick', 'boxPlot', 'scatter', @@ -59,6 +60,7 @@ export default class Core { 'area', 'bar', 'rangeBar', + 'rangeArea', 'candlestick', 'boxPlot', 'scatter', @@ -152,7 +154,18 @@ export default class Core { i: [] } - gl.series.map((series, st) => { + let rangeBarSeries = { + series: [], + i: [] + } + + let rangeAreaSeries = { + series: [], + seriesRangeEnd: [], + i: [] + } + + gl.series.map((serie, st) => { let comboCount = 0 // if user has specified a particular type for particular series if (typeof ser[st].type !== 'undefined') { @@ -163,33 +176,42 @@ export default class Core { 'Horizontal bars are not supported in a mixed/combo chart. Please turn off `plotOptions.bar.horizontal`' ) } - columnSeries.series.push(series) + columnSeries.series.push(serie) columnSeries.i.push(st) comboCount++ w.globals.columnSeries = columnSeries.series } else if (ser[st].type === 'area') { - areaSeries.series.push(series) + areaSeries.series.push(serie) areaSeries.i.push(st) comboCount++ } else if (ser[st].type === 'line') { - lineSeries.series.push(series) + lineSeries.series.push(serie) lineSeries.i.push(st) comboCount++ } else if (ser[st].type === 'scatter') { - scatterSeries.series.push(series) + scatterSeries.series.push(serie) scatterSeries.i.push(st) } else if (ser[st].type === 'bubble') { - bubbleSeries.series.push(series) + bubbleSeries.series.push(serie) bubbleSeries.i.push(st) comboCount++ } else if (ser[st].type === 'candlestick') { - candlestickSeries.series.push(series) + candlestickSeries.series.push(serie) candlestickSeries.i.push(st) comboCount++ } else if (ser[st].type === 'boxPlot') { - boxplotSeries.series.push(series) + boxplotSeries.series.push(serie) boxplotSeries.i.push(st) comboCount++ + } else if (ser[st].type === 'rangeBar') { + rangeBarSeries.series.push(serie) + rangeBarSeries.i.push(st) + comboCount++ + } else if (ser[st].type === 'rangeArea') { + rangeAreaSeries.series.push(gl.seriesRangeStart[st]) + rangeAreaSeries.seriesRangeEnd.push(gl.seriesRangeEnd[st]) + rangeAreaSeries.i.push(st) + comboCount++ } else { // user has specified type, but it is not valid (other than line/area/column) console.warn( @@ -200,7 +222,7 @@ export default class Core { gl.comboCharts = true } } else { - lineSeries.series.push(series) + lineSeries.series.push(serie) lineSeries.i.push(st) } }) @@ -226,6 +248,16 @@ export default class Core { elGraph.push(this.ctx.bar.draw(columnSeries.series, columnSeries.i)) } } + if (rangeAreaSeries.series.length > 0) { + elGraph.push( + line.draw( + rangeAreaSeries.series, + 'rangeArea', + rangeAreaSeries.i, + rangeAreaSeries.seriesRangeEnd + ) + ) + } if (lineSeries.series.length > 0) { elGraph.push(line.draw(lineSeries.series, 'line', lineSeries.i)) } @@ -237,6 +269,12 @@ export default class Core { if (boxplotSeries.series.length > 0) { elGraph.push(boxCandlestick.draw(boxplotSeries.series, boxplotSeries.i)) } + if (rangeBarSeries.series.length > 0) { + elGraph.push( + this.ctx.rangeBar.draw(rangeBarSeries.series, rangeBarSeries.i) + ) + } + if (scatterSeries.series.length > 0) { const scatterLine = new Line(this.ctx, xyRatios, true) elGraph.push( @@ -277,6 +315,14 @@ export default class Core { case 'rangeBar': elGraph = this.ctx.rangeBar.draw(gl.series) break + case 'rangeArea': + elGraph = line.draw( + gl.seriesRangeStart, + 'rangeArea', + undefined, + gl.seriesRangeEnd + ) + break case 'heatmap': let heatmap = new HeatMap(this.ctx, xyRatios) elGraph = heatmap.draw(gl.series) diff --git a/src/modules/Data.js b/src/modules/Data.js index 1dad4c854..51829b562 100644 --- a/src/modules/Data.js +++ b/src/modules/Data.js @@ -202,10 +202,10 @@ export default class Data { gl.seriesRangeStart.push(range.start) gl.seriesRangeEnd.push(range.end) - gl.seriesRangeBar.push(range.rangeUniques) + gl.seriesRange.push(range.rangeUniques) // check for overlaps to avoid clashes in a timeline chart - gl.seriesRangeBar.forEach((sr, si) => { + gl.seriesRange.forEach((sr, si) => { if (sr) { sr.forEach((sarr, sarri) => { sarr.y.forEach((arr, arri) => { @@ -268,29 +268,24 @@ export default class Data { } }) - const err = - 'Please provide [Start, End] values in valid format. Read more https://apexcharts.com/docs/series/#rangecharts' - - const serObj = new Series(this.ctx) - const activeIndex = serObj.getActiveConfigSeriesIndex() if (format === 'array') { - if (ser[activeIndex].data[0][1].length !== 2) { - throw new Error(err) - } for (let j = 0; j < ser[i].data.length; j++) { - rangeStart.push(ser[i].data[j][1][0]) - rangeEnd.push(ser[i].data[j][1][1]) + if (Array.isArray(ser[i].data[j])) { + rangeStart.push(ser[i].data[j][1][0]) + rangeEnd.push(ser[i].data[j][1][1]) + } else { + rangeStart.push(ser[i].data[j]) + rangeEnd.push(ser[i].data[j]) + } } } else if (format === 'xy') { - if (ser[activeIndex].data[0].y.length !== 2) { - throw new Error(err) - } for (let j = 0; j < ser[i].data.length; j++) { + let isDataPoint2D = Array.isArray(ser[i].data[j].y) const id = Utils.randomId() const x = ser[i].data[j].x const y = { - y1: ser[i].data[j].y[0], - y2: ser[i].data[j].y[1], + y1: isDataPoint2D ? ser[i].data[j].y[0] : ser[i].data[j].y, + y2: isDataPoint2D ? ser[i].data[j].y[1] : ser[i].data[j].y, rangeName: id } @@ -439,7 +434,16 @@ export default class Data { ser[i].type === 'rangeArea' ) { gl.isRangeData = true - this.handleRangeData(ser, i) + if (gl.isComboCharts) { + if (ser[i].type === 'rangeBar' || ser[i].type === 'rangeArea') { + this.handleRangeData(ser, i) + } + } else if ( + cnf.chart.type === 'rangeBar' || + cnf.chart.type === 'rangeArea' + ) { + this.handleRangeData(ser, i) + } } if (this.isMultiFormat()) { @@ -542,8 +546,8 @@ export default class Data { // user provided labels in x prop in [{ x: 3, y: 55 }] data, and those labels are already stored in gl.labels[0], so just re-arrange the gl.labels array gl.labels = gl.labels[0] - if (gl.seriesRangeBar.length) { - gl.seriesRangeBar.map((srt) => { + if (gl.seriesRange.length) { + gl.seriesRange.map((srt) => { srt.forEach((sr) => { if (gl.labels.indexOf(sr.x) < 0 && sr.x) { gl.labels.push(sr.x) @@ -649,13 +653,12 @@ export default class Data { if (gl.axisCharts) { // axisCharts includes line / area / column / scatter this.parseDataAxisCharts(ser) + this.coreUtils.getLargestSeries() } else { // non-axis charts are pie / donut this.parseDataNonAxisCharts(ser) } - this.coreUtils.getLargestSeries() - // set Null values to 0 in all series when user hides/shows some series if (cnf.chart.type === 'bar' && cnf.chart.stacked) { const series = new Series(this.ctx) diff --git a/src/modules/DataLabels.js b/src/modules/DataLabels.js index c0f140fdf..8027fa434 100644 --- a/src/modules/DataLabels.js +++ b/src/modules/DataLabels.js @@ -76,7 +76,7 @@ class DataLabels { } } - drawDataLabel(pos, i, j, z = null, strokeWidth = 2) { + drawDataLabel({ type, pos, i, j, isRangeStart, strokeWidth = 2 }) { // this method handles line, area, bubble, scatter charts as those charts contains markers/points which have pre-defined x/y positions // all other charts like radar / bars / heatmaps will define their own drawDataLabel routine let w = this.w @@ -110,6 +110,14 @@ class DataLabels { let val = w.globals.series[i][dataPointIndex] + if (type === 'rangeArea') { + if (isRangeStart) { + val = w.globals.seriesRangeStart[i][dataPointIndex] + } else { + val = w.globals.seriesRangeEnd[i][dataPointIndex] + } + } + let text = '' const getText = (v) => { diff --git a/src/modules/Range.js b/src/modules/Range.js index f0a0b971c..45a9d3fa4 100644 --- a/src/modules/Range.js +++ b/src/modules/Range.js @@ -73,23 +73,32 @@ class Range { if ( this.w.config.chart.type === 'candlestick' || - this.w.config.chart.type === 'boxPlot' + this.w.config.chart.type === 'boxPlot' || + this.w.config.chart.type !== 'rangeArea' || + this.w.config.chart.type !== 'rangeBar' ) { - if (typeof gl.seriesCandleC[i][j] !== 'undefined') { - maxY = Math.max(maxY, gl.seriesCandleO[i][j]) - maxY = Math.max(maxY, gl.seriesCandleH[i][j]) - maxY = Math.max(maxY, gl.seriesCandleL[i][j]) - maxY = Math.max(maxY, gl.seriesCandleC[i][j]) - if (this.w.config.chart.type === 'boxPlot') { - maxY = Math.max(maxY, gl.seriesCandleM[i][j]) + if ( + this.w.config.chart.type === 'candlestick' || + this.w.config.chart.type === 'boxPlot' + ) { + if (typeof gl.seriesCandleC[i][j] !== 'undefined') { + maxY = Math.max(maxY, gl.seriesCandleO[i][j]) + maxY = Math.max(maxY, gl.seriesCandleH[i][j]) + maxY = Math.max(maxY, gl.seriesCandleL[i][j]) + maxY = Math.max(maxY, gl.seriesCandleC[i][j]) + if (this.w.config.chart.type === 'boxPlot') { + maxY = Math.max(maxY, gl.seriesCandleM[i][j]) + } } } - // there is a combo chart and the specified series in not either candlestick or boxplot, find the max there + // there is a combo chart and the specified series in not either candlestick, boxplot, or rangeArea/rangeBar; find the max there if ( cnf.series[i].type && (cnf.series[i].type !== 'candlestick' || - cnf.series[i].type !== 'boxPlot') + cnf.series[i].type !== 'boxPlot' || + cnf.series[i].type !== 'rangeArea' || + cnf.series[i].type !== 'rangeBar') ) { maxY = Math.max(maxY, gl.series[i][j]) lowestY = Math.min(lowestY, gl.series[i][j]) diff --git a/src/modules/Series.js b/src/modules/Series.js index 3fd65e25e..29d0a26d7 100644 --- a/src/modules/Series.js +++ b/src/modules/Series.js @@ -303,6 +303,7 @@ export default class Series { 'area', 'bar', 'rangebar', + 'rangeArea', 'candlestick', 'radar' ] diff --git a/src/modules/axes/Grid.js b/src/modules/axes/Grid.js index 1711405ad..883479a1f 100644 --- a/src/modules/axes/Grid.js +++ b/src/modules/axes/Grid.js @@ -18,7 +18,7 @@ class Grid { this.xaxisLabels = w.globals.labels.slice() this.axesUtils = new AxesUtils(ctx) - this.isRangeBar = w.globals.seriesRangeBar.length + this.isRangeBar = w.globals.seriesRange.length if (w.globals.timescaleLabels.length > 0) { // timescaleLabels labels are there diff --git a/src/modules/helpers/InitCtxVariables.js b/src/modules/helpers/InitCtxVariables.js index 596dfb354..e4bbf6c4c 100644 --- a/src/modules/helpers/InitCtxVariables.js +++ b/src/modules/helpers/InitCtxVariables.js @@ -97,6 +97,7 @@ export default class InitCtxVariables { this.ctx.titleSubtitle = new TitleSubtitle(this.ctx) this.ctx.legend = new Legend(this.ctx) this.ctx.toolbar = new Toolbar(this.ctx) + this.ctx.tooltip = new Tooltip(this.ctx) this.ctx.dimensions = new Dimensions(this.ctx) this.ctx.updateHelpers = new UpdateHelpers(this.ctx) this.ctx.zoomPanSelection = new ZoomPanSelection(this.ctx) diff --git a/src/modules/settings/Config.js b/src/modules/settings/Config.js index 5fc677fe8..c815bac92 100644 --- a/src/modules/settings/Config.js +++ b/src/modules/settings/Config.js @@ -48,6 +48,7 @@ export default class Config { 'candlestick', 'boxPlot', 'rangeBar', + 'rangeArea', 'histogram', 'bubble', 'scatter', diff --git a/src/modules/settings/Defaults.js b/src/modules/settings/Defaults.js index 5858a0edd..db3ef3e00 100644 --- a/src/modules/settings/Defaults.js +++ b/src/modules/settings/Defaults.js @@ -1,5 +1,5 @@ import Utils from '../../utils/Utils' -import RangeBar from '../../charts/RangeBar' +import DateTime from '../../utils/DateTime' /** * ApexCharts Default Class for setting default options for all chart types. @@ -7,6 +7,119 @@ import RangeBar from '../../charts/RangeBar' * @module Defaults **/ +const getRangeValues = ({ ctx, seriesIndex, dataPointIndex, y1, y2, w }) => { + let start = w.globals.seriesRangeStart[seriesIndex][dataPointIndex] + let end = w.globals.seriesRangeEnd[seriesIndex][dataPointIndex] + let ylabel = w.globals.labels[dataPointIndex] + let seriesName = w.config.series[seriesIndex].name + ? w.config.series[seriesIndex].name + : '' + const yLbFormatter = w.config.tooltip.y.formatter + const yLbTitleFormatter = w.config.tooltip.y.title.formatter + + const opts = { + w, + seriesIndex, + dataPointIndex, + start, + end + } + + if (typeof yLbTitleFormatter === 'function') { + seriesName = yLbTitleFormatter(seriesName, opts) + } + if (w.config.series[seriesIndex].data[dataPointIndex]?.x) { + ylabel = w.config.series[seriesIndex].data[dataPointIndex].x + ':' + } + + if (typeof yLbFormatter === 'function') { + ylabel = yLbFormatter(ylabel, opts) + } + if (Number.isFinite(y1) && Number.isFinite(y2)) { + start = y1 + end = y2 + } + + let startVal = '' + let endVal = '' + + const color = w.globals.colors[seriesIndex] + if (w.config.tooltip.x.formatter === undefined) { + if (w.config.xaxis.type === 'datetime') { + let datetimeObj = new DateTime(ctx) + startVal = datetimeObj.formatDate( + datetimeObj.getDate(start), + w.config.tooltip.x.format + ) + endVal = datetimeObj.formatDate( + datetimeObj.getDate(end), + w.config.tooltip.x.format + ) + } else { + startVal = start + endVal = end + } + } else { + startVal = w.config.tooltip.x.formatter(start) + endVal = w.config.tooltip.x.formatter(end) + } + + return { start, end, startVal, endVal, ylabel, color, seriesName } +} +const buildRangeTooltipHTML = (opts) => { + let { + color, + seriesName, + ylabel, + start, + end, + seriesIndex, + dataPointIndex + } = opts + + const formatter = opts.ctx.tooltip.tooltipLabels.getFormatters(seriesIndex) + + start = formatter.yLbFormatter(start) + end = formatter.yLbFormatter(end) + const val = formatter.yLbFormatter( + opts.w.globals.series[seriesIndex][dataPointIndex] + ) + + let valueHTML = '' + const rangeValues = ` + ${start} + - + ${end} + ` + + if (opts.w.globals.comboCharts) { + if ( + opts.w.config.series[seriesIndex].type === 'rangeArea' || + opts.w.config.series[seriesIndex].type === 'rangeBar' + ) { + valueHTML = rangeValues + } else { + valueHTML = `${val}` + } + } else { + valueHTML = rangeValues + } + return ( + '
' + + '
' + + (seriesName ? seriesName : '') + + '
' + + '
' + + ylabel + + ' ' + + valueHTML + + '
' + + '
' + ) +} + export default class Defaults { constructor(opts) { this.opts = opts @@ -235,16 +348,10 @@ export default class Defaults { rangeBar() { const handleTimelineTooltip = (opts) => { - const rangeCtx = new RangeBar(opts.ctx, null) - - const { - color, - seriesName, - ylabel, - startVal, - endVal - } = rangeCtx.getTooltipValues(opts) - return rangeCtx.buildCustomTooltipHTML({ + const { color, seriesName, ylabel, startVal, endVal } = getRangeValues( + opts + ) + return buildRangeTooltipHTML({ color, seriesName, ylabel, @@ -254,16 +361,8 @@ export default class Defaults { } const handleRangeColumnTooltip = (opts) => { - const rangeCtx = new RangeBar(opts.ctx, null) - - const { - color, - seriesName, - ylabel, - start, - end - } = rangeCtx.getTooltipValues(opts) - return rangeCtx.buildCustomTooltipHTML({ + const { color, seriesName, ylabel, start, end } = getRangeValues(opts) + return buildRangeTooltipHTML({ color, seriesName, ylabel, @@ -287,9 +386,24 @@ export default class Defaults { dataLabels: { enabled: false, formatter(val, { ctx, seriesIndex, dataPointIndex, w }) { - const start = w.globals.seriesRangeStart[seriesIndex][dataPointIndex] - const end = w.globals.seriesRangeEnd[seriesIndex][dataPointIndex] - return end - start + const getVal = () => { + const start = + w.globals.seriesRangeStart[seriesIndex][dataPointIndex] + const end = w.globals.seriesRangeEnd[seriesIndex][dataPointIndex] + return end - start + } + if (w.globals.comboCharts) { + if ( + w.config.series[seriesIndex].type === 'rangeBar' || + w.config.series[seriesIndex].type === 'rangeArea' + ) { + return getVal() + } else { + return val + } + } else { + return getVal() + } }, background: { enabled: false @@ -366,6 +480,53 @@ export default class Defaults { } } + rangeArea() { + const handleRangeAreaTooltip = (opts) => { + const { color, seriesName, ylabel, start, end } = getRangeValues(opts) + return buildRangeTooltipHTML({ + ...opts, + color, + seriesName, + ylabel, + start, + end + }) + } + return { + stroke: { + curve: 'straight', + width: 0 + }, + fill: { + type: 'solid', + opacity: 0.6 + }, + markers: { + size: 0 + }, + states: { + hover: { + filter: { + type: 'none' + } + }, + active: { + filter: { + type: 'none' + } + } + }, + tooltip: { + intersect: false, + shared: true, + followCursor: true, + custom(opts) { + return handleRangeAreaTooltip(opts) + } + } + } + } + brush(defaults) { const ret = { chart: { diff --git a/src/modules/settings/Globals.js b/src/modules/settings/Globals.js index 9e161e1d5..22da50081 100644 --- a/src/modules/settings/Globals.js +++ b/src/modules/settings/Globals.js @@ -10,7 +10,7 @@ export default class Globals { gl.seriesCandleC = [] gl.seriesRangeStart = [] gl.seriesRangeEnd = [] - gl.seriesRangeBar = [] + gl.seriesRange = [] gl.seriesPercent = [] gl.seriesGoals = [] gl.seriesX = [] diff --git a/src/modules/tooltip/Position.js b/src/modules/tooltip/Position.js index 7d5f338e6..6a90306a9 100644 --- a/src/modules/tooltip/Position.js +++ b/src/modules/tooltip/Position.js @@ -324,8 +324,16 @@ export default class Position { } if (pointArr && pointArr.length) { let pcy = pointsArr[p][j][1] + let pcy2 points[p].setAttribute('cx', cx) + if (w.config.chart.type === 'rangeArea' && !w.globals.comboCharts) { + const rangeStartIndex = j + w.globals.series[p].length + pcy2 = pointsArr[p][rangeStartIndex][1] + const pcyDiff = Math.abs(pcy - pcy2) / 2 + + pcy = pcy - pcyDiff + } if ( pcy !== null && !isNaN(pcy) && diff --git a/tests/e2e/snapshots/area/area-datetime.png b/tests/e2e/snapshots/area/area-datetime.png index 3058c5129..8760e197a 100644 Binary files a/tests/e2e/snapshots/area/area-datetime.png and b/tests/e2e/snapshots/area/area-datetime.png differ diff --git a/tests/e2e/snapshots/area/area-spline.png b/tests/e2e/snapshots/area/area-spline.png index 1b6b02f71..3cb015b4d 100644 Binary files a/tests/e2e/snapshots/area/area-spline.png and b/tests/e2e/snapshots/area/area-spline.png differ diff --git a/tests/e2e/snapshots/area/area-with-missing-data.png b/tests/e2e/snapshots/area/area-with-missing-data.png index 1772c7d5f..ad001b330 100644 Binary files a/tests/e2e/snapshots/area/area-with-missing-data.png and b/tests/e2e/snapshots/area/area-with-missing-data.png differ diff --git a/tests/e2e/snapshots/area/area-with-negative.png b/tests/e2e/snapshots/area/area-with-negative.png index a8e929662..332ce8c05 100644 Binary files a/tests/e2e/snapshots/area/area-with-negative.png and b/tests/e2e/snapshots/area/area-with-negative.png differ diff --git a/tests/e2e/snapshots/area/basic-area.png b/tests/e2e/snapshots/area/basic-area.png index 2c041ccd9..34305a897 100644 Binary files a/tests/e2e/snapshots/area/basic-area.png and b/tests/e2e/snapshots/area/basic-area.png differ diff --git a/tests/e2e/snapshots/area/stacked-area.png b/tests/e2e/snapshots/area/stacked-area.png index f0f7beaf1..feab382bd 100644 Binary files a/tests/e2e/snapshots/area/stacked-area.png and b/tests/e2e/snapshots/area/stacked-area.png differ diff --git a/tests/e2e/snapshots/area/timeseries-with-irregular-data.png b/tests/e2e/snapshots/area/timeseries-with-irregular-data.png index 73f327cc8..46fe74c75 100644 Binary files a/tests/e2e/snapshots/area/timeseries-with-irregular-data.png and b/tests/e2e/snapshots/area/timeseries-with-irregular-data.png differ diff --git a/tests/e2e/snapshots/bar/stacked-bar.png b/tests/e2e/snapshots/bar/stacked-bar.png index de266de4a..e4c8d2413 100644 Binary files a/tests/e2e/snapshots/bar/stacked-bar.png and b/tests/e2e/snapshots/bar/stacked-bar.png differ diff --git a/tests/e2e/snapshots/column/column-with-rotated-labels.png b/tests/e2e/snapshots/column/column-with-rotated-labels.png index 1d6c7b601..201a14c20 100644 Binary files a/tests/e2e/snapshots/column/column-with-rotated-labels.png and b/tests/e2e/snapshots/column/column-with-rotated-labels.png differ diff --git a/tests/e2e/snapshots/column/distributed-columns.png b/tests/e2e/snapshots/column/distributed-columns.png index 846ca9403..0e99bc684 100644 Binary files a/tests/e2e/snapshots/column/distributed-columns.png and b/tests/e2e/snapshots/column/distributed-columns.png differ diff --git a/tests/e2e/snapshots/column/stacked-column.png b/tests/e2e/snapshots/column/stacked-column.png index df6c7a4e7..bd6442227 100644 Binary files a/tests/e2e/snapshots/column/stacked-column.png and b/tests/e2e/snapshots/column/stacked-column.png differ diff --git a/tests/e2e/snapshots/heatmap/rounded.png b/tests/e2e/snapshots/heatmap/rounded.png index 1ab6227ba..380b1029e 100644 Binary files a/tests/e2e/snapshots/heatmap/rounded.png and b/tests/e2e/snapshots/heatmap/rounded.png differ diff --git a/tests/e2e/snapshots/line/brush-charts.png b/tests/e2e/snapshots/line/brush-charts.png index a28eab0b3..332acbc92 100644 Binary files a/tests/e2e/snapshots/line/brush-charts.png and b/tests/e2e/snapshots/line/brush-charts.png differ diff --git a/tests/e2e/snapshots/line/line-with-missing-data.png b/tests/e2e/snapshots/line/line-with-missing-data.png index 5435766ba..9eba621b2 100644 Binary files a/tests/e2e/snapshots/line/line-with-missing-data.png and b/tests/e2e/snapshots/line/line-with-missing-data.png differ diff --git a/tests/e2e/snapshots/line/realtime.png b/tests/e2e/snapshots/line/realtime.png index f78abb196..bab74fd5a 100644 Binary files a/tests/e2e/snapshots/line/realtime.png and b/tests/e2e/snapshots/line/realtime.png differ diff --git a/tests/e2e/snapshots/line/syncing-charts.png b/tests/e2e/snapshots/line/syncing-charts.png index 5b6d73861..937afad49 100644 Binary files a/tests/e2e/snapshots/line/syncing-charts.png and b/tests/e2e/snapshots/line/syncing-charts.png differ diff --git a/tests/e2e/snapshots/line/zoomable-timeseries.png b/tests/e2e/snapshots/line/zoomable-timeseries.png index 7a48b4e2a..6a1183e6e 100644 Binary files a/tests/e2e/snapshots/line/zoomable-timeseries.png and b/tests/e2e/snapshots/line/zoomable-timeseries.png differ diff --git a/tests/e2e/snapshots/misc/annotations-example.png b/tests/e2e/snapshots/misc/annotations-example.png index 882c51772..01cf85cd5 100644 Binary files a/tests/e2e/snapshots/misc/annotations-example.png and b/tests/e2e/snapshots/misc/annotations-example.png differ diff --git a/tests/e2e/snapshots/misc/custom-legend.png b/tests/e2e/snapshots/misc/custom-legend.png index 71ccafbe6..a79e064bb 100644 Binary files a/tests/e2e/snapshots/misc/custom-legend.png and b/tests/e2e/snapshots/misc/custom-legend.png differ diff --git a/tests/e2e/snapshots/misc/minMaxPoints.png b/tests/e2e/snapshots/misc/minMaxPoints.png index 7a9c5a435..bfd0c148d 100644 Binary files a/tests/e2e/snapshots/misc/minMaxPoints.png and b/tests/e2e/snapshots/misc/minMaxPoints.png differ diff --git a/tests/e2e/snapshots/mixed/line-area.png b/tests/e2e/snapshots/mixed/line-area.png index a5a1a674c..fab0df24f 100644 Binary files a/tests/e2e/snapshots/mixed/line-area.png and b/tests/e2e/snapshots/mixed/line-area.png differ diff --git a/tests/e2e/snapshots/mixed/line-column-area.png b/tests/e2e/snapshots/mixed/line-column-area.png index a31ee8b1f..8bc91c44f 100644 Binary files a/tests/e2e/snapshots/mixed/line-column-area.png and b/tests/e2e/snapshots/mixed/line-column-area.png differ diff --git a/tests/e2e/snapshots/pie/monochrome-pie.png b/tests/e2e/snapshots/pie/monochrome-pie.png index ffb04b49a..e9bb109bb 100644 Binary files a/tests/e2e/snapshots/pie/monochrome-pie.png and b/tests/e2e/snapshots/pie/monochrome-pie.png differ diff --git a/tests/e2e/snapshots/radar/radar-with-polygon-fill.png b/tests/e2e/snapshots/radar/radar-with-polygon-fill.png index 0a2b29128..5e4fb9f00 100644 Binary files a/tests/e2e/snapshots/radar/radar-with-polygon-fill.png and b/tests/e2e/snapshots/radar/radar-with-polygon-fill.png differ diff --git a/tests/e2e/snapshots/radialBar/circle-gradient.png b/tests/e2e/snapshots/radialBar/circle-gradient.png index 7dc5207c5..a72e8ffe8 100644 Binary files a/tests/e2e/snapshots/radialBar/circle-gradient.png and b/tests/e2e/snapshots/radialBar/circle-gradient.png differ diff --git a/tests/e2e/snapshots/rangeArea/basic-range-area.png b/tests/e2e/snapshots/rangeArea/basic-range-area.png new file mode 100644 index 000000000..d12686443 Binary files /dev/null and b/tests/e2e/snapshots/rangeArea/basic-range-area.png differ diff --git a/tests/e2e/snapshots/rangeArea/range-area-line-combo.png b/tests/e2e/snapshots/rangeArea/range-area-line-combo.png new file mode 100644 index 000000000..6f2fc0c9c Binary files /dev/null and b/tests/e2e/snapshots/rangeArea/range-area-line-combo.png differ diff --git a/tests/e2e/snapshots/sparklines/sparklines.png b/tests/e2e/snapshots/sparklines/sparklines.png index ebc123697..d9eb70069 100644 Binary files a/tests/e2e/snapshots/sparklines/sparklines.png and b/tests/e2e/snapshots/sparklines/sparklines.png differ diff --git a/tests/e2e/snapshots/treemap/color-scale.png b/tests/e2e/snapshots/treemap/color-scale.png index 6165e27f7..6e20aac6b 100644 Binary files a/tests/e2e/snapshots/treemap/color-scale.png and b/tests/e2e/snapshots/treemap/color-scale.png differ diff --git a/types/apexcharts.d.ts b/types/apexcharts.d.ts index 54c3a0b22..164ecc341 100644 --- a/types/apexcharts.d.ts +++ b/types/apexcharts.d.ts @@ -115,6 +115,7 @@ type ApexChart = { | 'radar' | 'polarArea' | 'rangeBar' + | 'rangeArea' | 'treemap' foreColor?: string fontFamily?: string