diff --git a/packages/osd-charts/src/chart_types/goal_chart/renderer/canvas/connected_component.tsx b/packages/osd-charts/src/chart_types/goal_chart/renderer/canvas/connected_component.tsx index 88849ea4c735..92a803adb704 100644 --- a/packages/osd-charts/src/chart_types/goal_chart/renderer/canvas/connected_component.tsx +++ b/packages/osd-charts/src/chart_types/goal_chart/renderer/canvas/connected_component.tsx @@ -17,7 +17,7 @@ * under the License. */ -import React, { MouseEvent } from 'react'; +import React, { MouseEvent, RefObject } from 'react'; import { connect } from 'react-redux'; import { bindActionCreators, Dispatch } from 'redux'; @@ -39,18 +39,20 @@ interface ReactiveChartDispatchProps { onChartRendered: typeof onChartRendered; } -type Props = ReactiveChartStateProps & ReactiveChartDispatchProps; +interface ReactiveChartOwnProps { + forwardStageRef: RefObject; +} + +type Props = ReactiveChartStateProps & ReactiveChartDispatchProps & ReactiveChartOwnProps; class Component extends React.Component { static displayName = 'Goal'; // firstRender = true; // this'll be useful for stable resizing of treemaps - private readonly canvasRef: React.RefObject; private ctx: CanvasRenderingContext2D | null; // see example https://developer.mozilla.org/en-US/docs/Web/API/Window/devicePixelRatio#Example private readonly devicePixelRatio: number; // fixme this be no constant: multi-monitor window drag may necessitate modifying the `` dimensions constructor(props: Readonly) { super(props); - this.canvasRef = React.createRef(); this.ctx = null; this.devicePixelRatio = window.devicePixelRatio; } @@ -78,7 +80,7 @@ class Component extends React.Component { } private tryCanvasContext() { - const canvas = this.canvasRef.current; + const canvas = this.props.forwardStageRef.current; this.ctx = canvas && canvas.getContext('2d'); } @@ -96,13 +98,15 @@ class Component extends React.Component { const { initialized, chartContainerDimensions: { width, height }, + forwardStageRef, + geometries, } = this.props; - if (!this.canvasRef.current || !this.ctx || !initialized || width === 0 || height === 0) { + if (!forwardStageRef.current || !this.ctx || !initialized || width === 0 || height === 0) { return; } - const picker = this.props.geometries.pickQuads; - const box = this.canvasRef.current.getBoundingClientRect(); - const { chartCenter } = this.props.geometries; + const picker = geometries.pickQuads; + const box = forwardStageRef.current.getBoundingClientRect(); + const { chartCenter } = geometries; const x = e.clientX - box.left - chartCenter.x; const y = e.clientY - box.top - chartCenter.y; const pickedShapes: Array = picker(x, y); @@ -113,6 +117,7 @@ class Component extends React.Component { const { initialized, chartContainerDimensions: { width, height }, + forwardStageRef, } = this.props; if (!initialized || width === 0 || height === 0) { return null; @@ -120,7 +125,7 @@ class Component extends React.Component { return ( ) { return ( <> - + ); } diff --git a/packages/osd-charts/src/chart_types/partition_chart/renderer/canvas/partition.tsx b/packages/osd-charts/src/chart_types/partition_chart/renderer/canvas/partition.tsx index 8283695e2c47..b427a0352d63 100644 --- a/packages/osd-charts/src/chart_types/partition_chart/renderer/canvas/partition.tsx +++ b/packages/osd-charts/src/chart_types/partition_chart/renderer/canvas/partition.tsx @@ -17,7 +17,7 @@ * under the License. */ -import React, { MouseEvent } from 'react'; +import React, { MouseEvent, RefObject } from 'react'; import { connect } from 'react-redux'; import { bindActionCreators, Dispatch } from 'redux'; @@ -40,20 +40,21 @@ interface ReactiveChartStateProps { interface ReactiveChartDispatchProps { onChartRendered: typeof onChartRendered; } +interface ReactiveChartOwnProps { + forwardStageRef: RefObject; +} -type PartitionProps = ReactiveChartStateProps & ReactiveChartDispatchProps; +type PartitionProps = ReactiveChartStateProps & ReactiveChartDispatchProps & ReactiveChartOwnProps; class PartitionComponent extends React.Component { static displayName = 'Partition'; // firstRender = true; // this'll be useful for stable resizing of treemaps - private readonly canvasRef: React.RefObject; private ctx: CanvasRenderingContext2D | null; // see example https://developer.mozilla.org/en-US/docs/Web/API/Window/devicePixelRatio#Example private readonly devicePixelRatio: number; // fixme this be no constant: multi-monitor window drag may necessitate modifying the `` dimensions constructor(props: Readonly) { super(props); - this.canvasRef = React.createRef(); this.ctx = null; this.devicePixelRatio = window.devicePixelRatio; } @@ -91,7 +92,7 @@ class PartitionComponent extends React.Component { } private tryCanvasContext() { - const canvas = this.canvasRef.current; + const canvas = this.props.forwardStageRef.current; this.ctx = canvas && canvas.getContext('2d'); } @@ -99,12 +100,13 @@ class PartitionComponent extends React.Component { const { initialized, chartContainerDimensions: { width, height }, + forwardStageRef, } = this.props; - if (!this.canvasRef.current || !this.ctx || !initialized || width === 0 || height === 0) { + if (!forwardStageRef.current || !this.ctx || !initialized || width === 0 || height === 0) { return; } const picker = this.props.geometries.pickQuads; - const box = this.canvasRef.current.getBoundingClientRect(); + const box = forwardStageRef.current.getBoundingClientRect(); const { diskCenter } = this.props.geometries; const x = e.clientX - box.left - diskCenter.x; const y = e.clientY - box.top - diskCenter.y; @@ -129,6 +131,7 @@ class PartitionComponent extends React.Component { render() { const { + forwardStageRef, initialized, chartContainerDimensions: { width, height }, } = this.props; @@ -138,7 +141,7 @@ class PartitionComponent extends React.Component { return ( ) { return ( <> - + diff --git a/packages/osd-charts/stories/interactions/17_png_export.tsx b/packages/osd-charts/stories/interactions/17_png_export.tsx index 7c7d587107ee..b8626d592ac6 100644 --- a/packages/osd-charts/stories/interactions/17_png_export.tsx +++ b/packages/osd-charts/stories/interactions/17_png_export.tsx @@ -17,19 +17,34 @@ * under the License. */ -import { button } from '@storybook/addon-knobs'; -import React from 'react'; +import { button, select } from '@storybook/addon-knobs'; +import React, { RefObject } from 'react'; -import { Axis, BarSeries, Chart, niceTimeFormatter, Position, ScaleType, Settings } from '../../src'; +import { + Axis, + BarSeries, + Chart, + niceTimeFormatter, + Position, + ScaleType, + Settings, + Partition, + Datum, + Goal, + ChartTypes, +} from '../../src'; +import { GOAL_SUBTYPES, BandFillColorAccessorInput } from '../../src/chart_types/goal_chart/specs'; +import { config } from '../../src/chart_types/partition_chart/layout/config/config'; +import { mocks } from '../../src/mocks/hierarchical'; +import { Color } from '../../src/utils/commons'; import { KIBANA_METRICS } from '../../src/utils/data_samples/test_dataset_kibana'; import { SB_KNOBS_PANEL } from '../utils/storybook'; +import { productLookup, indexInterpolatedFillColor, interpolatorCET2s } from '../utils/utils'; export const Example = () => { /** * The handler section of this story demonstrates the PNG export functionality */ - const data = KIBANA_METRICS.metrics.kibana_os_load[0].data.slice(0, 100); - const label = 'Export PNG'; const chartRef: React.RefObject = React.createRef(); const handler = () => { if (!chartRef.current) { @@ -57,8 +72,49 @@ export const Example = () => { document.body.removeChild(link); } }; - const groupId = ''; - button(label, handler, groupId); + button('Export PNG', handler); + const selectedChart = select( + 'chart type', + [ChartTypes.XYAxis, ChartTypes.Partition, ChartTypes.Goal], + ChartTypes.XYAxis, + ); + + switch (selectedChart) { + case ChartTypes.Partition: + return renderPartitionChart(chartRef); + case ChartTypes.Goal: + return renderGoalchart(chartRef); + case ChartTypes.XYAxis: + default: + return renderXYAxisChart(chartRef); + } +}; + +function renderPartitionChart(chartRef: RefObject) { + return ( + + d.exportVal as number} + valueFormatter={(d: number) => `$${config.fillLabel.valueFormatter(Math.round(d / 1000000000))}\u00A0Bn`} + layers={[ + { + groupByRollup: (d: Datum) => d.sitc1, + nodeLabel: (d: Datum) => productLookup[d].name, + fillLabel: { textInvertible: true }, + shape: { + fillColor: indexInterpolatedFillColor(interpolatorCET2s), + }, + }, + ]} + /> + + ); +} + +function renderXYAxisChart(chartRef: RefObject) { + const data = KIBANA_METRICS.metrics.kibana_os_load[0].data.slice(0, 100); return ( @@ -80,7 +136,43 @@ export const Example = () => { /> ); -}; +} + +function renderGoalchart(chartRef: RefObject) { + const subtype = GOAL_SUBTYPES[0]; + + const colorMap: { [k: number]: Color } = { + 200: '#fc8d62', + 250: 'lightgrey', + 300: '#66c2a5', + }; + + const bandFillColor = (x: number): Color => colorMap[x]; + + return ( + + String(value)} + bandFillColor={({ value }: BandFillColorAccessorInput) => bandFillColor(value)} + labelMajor="" + labelMinor="" + centralMajor="280 MB/s" + centralMinor="" + config={{ + angleStart: Math.PI + (Math.PI - (2 * Math.PI) / 3) / 2, + angleEnd: -(Math.PI - (2 * Math.PI) / 3) / 2, + }} + /> + + ); +} // storybook configuration Example.story = {