forked from grafana/grafana
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge remote-tracking branch 'grafana/master' into show-all-columns
* grafana/master: (56 commits) another change that didn't come with earlier commit change that didn't come with in last commit reversed dashboard-padding Update CloudWatch metrics/dimension list (grafana#16102) brought back dashboard-padding and panel-padding variables, made dashboard-padding more specific fix(prometheus): Change aligment of range queries (grafana#16110) Minor refactoring of testdata query order PR grafana#16122 cleaner version maintain query order Update PLUGIN_DEV.md Merge with master, and updated logo and name more fixes to snapshot more fixes to snapshot removed empty space in snapshot fixed snapshot for test removed dashboard variables, removed headings-font-family variable, created theme variables for links and z-index, removed unused class in _panel_editor and _dashboard Tooltip: show percent instead of value Right tooltip position Add "No data points" message Improve tooltip look ...
- Loading branch information
Showing
33 changed files
with
994 additions
and
233 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
42 changes: 42 additions & 0 deletions
42
packages/grafana-ui/src/components/PieChart/PieChart.story.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
import { storiesOf } from '@storybook/react'; | ||
import { number, text, object } from '@storybook/addon-knobs'; | ||
import { PieChart, PieChartType } from './PieChart'; | ||
import { withCenteredStory } from '../../utils/storybook/withCenteredStory'; | ||
import { renderComponentWithTheme } from '../../utils/storybook/withTheme'; | ||
|
||
const getKnobs = () => { | ||
return { | ||
datapoints: object('datapoints', [ | ||
{ | ||
value: 100, | ||
name: '100', | ||
color: '#7EB26D', | ||
}, | ||
{ | ||
value: 200, | ||
name: '200', | ||
color: '#6ED0E0', | ||
}, | ||
]), | ||
pieType: text('pieType', PieChartType.PIE), | ||
strokeWidth: number('strokeWidth', 1), | ||
unit: text('unit', 'ms'), | ||
}; | ||
}; | ||
|
||
const PieChartStories = storiesOf('UI/PieChart/PieChart', module); | ||
|
||
PieChartStories.addDecorator(withCenteredStory); | ||
|
||
PieChartStories.add('Pie type: pie', () => { | ||
const { datapoints, pieType, strokeWidth, unit } = getKnobs(); | ||
|
||
return renderComponentWithTheme(PieChart, { | ||
width: 200, | ||
height: 400, | ||
datapoints, | ||
pieType, | ||
strokeWidth, | ||
unit, | ||
}); | ||
}); |
147 changes: 147 additions & 0 deletions
147
packages/grafana-ui/src/components/PieChart/PieChart.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,147 @@ | ||
import React, { PureComponent } from 'react'; | ||
import { select, pie, arc, event } from 'd3'; | ||
import { sum } from 'lodash'; | ||
|
||
import { GrafanaThemeType } from '../../types'; | ||
import { Themeable } from '../../index'; | ||
|
||
export enum PieChartType { | ||
PIE = 'pie', | ||
DONUT = 'donut', | ||
} | ||
|
||
export interface PieChartDataPoint { | ||
value: number; | ||
name: string; | ||
color: string; | ||
} | ||
|
||
export interface Props extends Themeable { | ||
height: number; | ||
width: number; | ||
datapoints: PieChartDataPoint[]; | ||
|
||
unit: string; | ||
pieType: PieChartType; | ||
strokeWidth: number; | ||
} | ||
|
||
export class PieChart extends PureComponent<Props> { | ||
containerElement: any; | ||
svgElement: any; | ||
tooltipElement: any; | ||
tooltipValueElement: any; | ||
|
||
static defaultProps = { | ||
pieType: 'pie', | ||
format: 'short', | ||
stat: 'current', | ||
strokeWidth: 1, | ||
theme: GrafanaThemeType.Dark, | ||
}; | ||
|
||
componentDidMount() { | ||
this.draw(); | ||
} | ||
|
||
componentDidUpdate() { | ||
this.draw(); | ||
} | ||
|
||
draw() { | ||
const { datapoints, pieType, strokeWidth } = this.props; | ||
|
||
if (datapoints.length === 0) { | ||
return; | ||
} | ||
|
||
const data = datapoints.map(datapoint => datapoint.value); | ||
const names = datapoints.map(datapoint => datapoint.name); | ||
const colors = datapoints.map(datapoint => datapoint.color); | ||
|
||
const total = sum(data) || 1; | ||
const percents = data.map((item: number) => (item / total) * 100); | ||
|
||
const width = this.containerElement.offsetWidth; | ||
const height = this.containerElement.offsetHeight; | ||
const radius = Math.min(width, height) / 2; | ||
|
||
const outerRadius = radius - radius / 10; | ||
const innerRadius = pieType === PieChartType.PIE ? 0 : radius - radius / 3; | ||
|
||
const svg = select(this.svgElement) | ||
.html('') | ||
.attr('width', width) | ||
.attr('height', height) | ||
.append('g') | ||
.attr('transform', `translate(${width / 2},${height / 2})`); | ||
|
||
const pieChart = pie(); | ||
|
||
const customArc = arc() | ||
.outerRadius(outerRadius) | ||
.innerRadius(innerRadius) | ||
.padAngle(0); | ||
|
||
svg | ||
.selectAll('path') | ||
.data(pieChart(data)) | ||
.enter() | ||
.append('path') | ||
.attr('d', customArc as any) | ||
.attr('fill', (d: any, idx: number) => colors[idx]) | ||
.style('fill-opacity', 0.15) | ||
.style('stroke', (d: any, idx: number) => colors[idx]) | ||
.style('stroke-width', `${strokeWidth}px`) | ||
.on('mouseover', (d: any, idx: any) => { | ||
select(this.tooltipElement).style('opacity', 1); | ||
select(this.tooltipValueElement).text(`${names[idx]} (${percents[idx].toFixed(2)}%)`); | ||
}) | ||
.on('mousemove', () => { | ||
select(this.tooltipElement) | ||
.style('top', `${event.pageY - height / 2}px`) | ||
.style('left', `${event.pageX}px`); | ||
}) | ||
.on('mouseout', () => { | ||
select(this.tooltipElement).style('opacity', 0); | ||
}); | ||
} | ||
|
||
render() { | ||
const { height, width, datapoints } = this.props; | ||
|
||
if (datapoints.length > 0) { | ||
return ( | ||
<div className="piechart-panel"> | ||
<div | ||
ref={element => (this.containerElement = element)} | ||
className="piechart-container" | ||
style={{ | ||
height: `${height * 0.9}px`, | ||
width: `${Math.min(width, height * 1.3)}px`, | ||
}} | ||
> | ||
<svg ref={element => (this.svgElement = element)} /> | ||
</div> | ||
<div className="piechart-tooltip" ref={element => (this.tooltipElement = element)}> | ||
<div className="piechart-tooltip-time"> | ||
<div | ||
id="tooltip-value" | ||
className="piechart-tooltip-value" | ||
ref={element => (this.tooltipValueElement = element)} | ||
/> | ||
</div> | ||
</div> | ||
</div> | ||
); | ||
} else { | ||
return ( | ||
<div className="piechart-panel"> | ||
<div className="datapoints-warning"> | ||
<span className="small">No data points</span> | ||
</div> | ||
</div> | ||
); | ||
} | ||
} | ||
} |
Oops, something went wrong.