Et voíla. Bar charts.
parent
796a0b495b
commit
a4e6195b6e
|
@ -63,6 +63,7 @@ const VisView = ({
|
|||
activeQueryIndex={activeQueryIndex}
|
||||
isInDataExplorer={isInDataExplorer}
|
||||
showSingleStat={cellType === 'line-plus-single-stat'}
|
||||
isBarChart={cellType === 'bar'}
|
||||
displayOptions={displayOptions}
|
||||
editQueryStatus={editQueryStatus}
|
||||
/>
|
||||
|
|
|
@ -23,6 +23,71 @@ const LINE_COLORS = [
|
|||
'#a0725b',
|
||||
]
|
||||
|
||||
const darkenColor = colorStr => {
|
||||
// Defined in dygraph-utils.js
|
||||
const color = Dygraphs.toRGB_(colorStr)
|
||||
color.r = Math.floor((255 + color.r) / 2)
|
||||
color.g = Math.floor((255 + color.g) / 2)
|
||||
color.b = Math.floor((255 + color.b) / 2)
|
||||
return `rgb(${color.r},${color.g},${color.b})`
|
||||
}
|
||||
|
||||
const multiColumnBarPlotter = e => {
|
||||
// We need to handle all the series simultaneously.
|
||||
if (e.seriesIndex !== 0) {
|
||||
return
|
||||
}
|
||||
|
||||
const g = e.dygraph
|
||||
const ctx = e.drawingContext
|
||||
const sets = e.allSeriesPoints
|
||||
const yBottom = e.dygraph.toDomYCoord(0)
|
||||
|
||||
// Find the minimum separation between x-values.
|
||||
// This determines the bar width.
|
||||
let minSep = Infinity
|
||||
for (let j = 0; j < sets.length; j++) {
|
||||
const points = sets[j]
|
||||
for (let i = 1; i < points.length; i++) {
|
||||
const sep = points[i].canvasx - points[i - 1].canvasx
|
||||
if (sep < minSep) {
|
||||
minSep = sep
|
||||
}
|
||||
}
|
||||
}
|
||||
const barWidth = Math.floor(2.0 / 3 * minSep)
|
||||
|
||||
const fillColors = []
|
||||
const strokeColors = g.getColors()
|
||||
for (let i = 0; i < strokeColors.length; i++) {
|
||||
fillColors.push(darkenColor(strokeColors[i]))
|
||||
}
|
||||
|
||||
for (let j = 0; j < sets.length; j++) {
|
||||
ctx.fillStyle = fillColors[j]
|
||||
ctx.strokeStyle = strokeColors[j]
|
||||
for (let i = 0; i < sets[j].length; i++) {
|
||||
const p = sets[j][i]
|
||||
const centerX = p.canvasx
|
||||
const xLeft = centerX - barWidth / 2 * (1 - j / (sets.length - 1))
|
||||
|
||||
ctx.fillRect(
|
||||
xLeft,
|
||||
p.canvasy,
|
||||
barWidth / sets.length,
|
||||
yBottom - p.canvasy
|
||||
)
|
||||
|
||||
ctx.strokeRect(
|
||||
xLeft,
|
||||
p.canvasy,
|
||||
barWidth / sets.length,
|
||||
yBottom - p.canvasy
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default class Dygraph extends Component {
|
||||
constructor(props) {
|
||||
super(props)
|
||||
|
@ -61,6 +126,7 @@ export default class Dygraph extends Component {
|
|||
ruleValues,
|
||||
overrideLineColors,
|
||||
isGraphFilled,
|
||||
isBarChart,
|
||||
options,
|
||||
} = this.props
|
||||
|
||||
|
@ -155,6 +221,10 @@ export default class Dygraph extends Component {
|
|||
},
|
||||
}
|
||||
|
||||
if (isBarChart) {
|
||||
defaultOptions.plotter = multiColumnBarPlotter
|
||||
}
|
||||
|
||||
this.dygraph = new Dygraphs(graphContainerNode, timeSeries, {
|
||||
...defaultOptions,
|
||||
...options,
|
||||
|
@ -189,7 +259,14 @@ export default class Dygraph extends Component {
|
|||
}
|
||||
|
||||
componentDidUpdate() {
|
||||
const {labels, ranges, options, dygraphSeries, ruleValues} = this.props
|
||||
const {
|
||||
labels,
|
||||
ranges,
|
||||
options,
|
||||
dygraphSeries,
|
||||
ruleValues,
|
||||
isBarChart,
|
||||
} = this.props
|
||||
const dygraph = this.dygraph
|
||||
if (!dygraph) {
|
||||
throw new Error(
|
||||
|
@ -217,6 +294,7 @@ export default class Dygraph extends Component {
|
|||
stackedGraph: options.stackedGraph,
|
||||
underlayCallback: options.underlayCallback,
|
||||
series: dygraphSeries,
|
||||
plotter: isBarChart ? multiColumnBarPlotter : null,
|
||||
})
|
||||
// part of optional workaround for preventing updateOptions from breaking legend
|
||||
// if (this.lastMouseMoveEvent) {
|
||||
|
@ -265,6 +343,7 @@ Dygraph.propTypes = {
|
|||
options: shape({}),
|
||||
containerStyle: shape({}),
|
||||
isGraphFilled: bool,
|
||||
isBarChart: bool,
|
||||
overrideLineColors: array,
|
||||
dygraphSeries: shape({}).isRequired,
|
||||
ruleValues: shape({
|
||||
|
|
|
@ -110,6 +110,7 @@ export const LayoutRenderer = React.createClass({
|
|||
timeRange={timeRange}
|
||||
autoRefresh={autoRefresh}
|
||||
showSingleStat={type === 'line-plus-single-stat'}
|
||||
isBarChart={type === 'bar'}
|
||||
displayOptions={displayOptions}
|
||||
synchronizer={synchronizer}
|
||||
/>
|
||||
|
|
|
@ -22,6 +22,7 @@ export default React.createClass({
|
|||
isRefreshing: bool,
|
||||
underlayCallback: func,
|
||||
isGraphFilled: bool,
|
||||
isBarChart: bool,
|
||||
overrideLineColors: array,
|
||||
queries: arrayOf(shape({}).isRequired).isRequired,
|
||||
showSingleStat: bool,
|
||||
|
@ -80,6 +81,7 @@ export default React.createClass({
|
|||
isFetchingInitially,
|
||||
isRefreshing,
|
||||
isGraphFilled,
|
||||
isBarChart,
|
||||
overrideLineColors,
|
||||
title,
|
||||
underlayCallback,
|
||||
|
@ -101,25 +103,22 @@ export default React.createClass({
|
|||
)
|
||||
}
|
||||
|
||||
const options = Object.assign(
|
||||
{},
|
||||
{
|
||||
labels,
|
||||
connectSeparatedPoints: true,
|
||||
labelsKMB: true,
|
||||
axisLineColor: '#383846',
|
||||
gridLineColor: '#383846',
|
||||
title,
|
||||
rightGap: 0,
|
||||
yRangePad: 10,
|
||||
axisLabelWidth: 38,
|
||||
drawAxesAtZero: true,
|
||||
underlayCallback,
|
||||
ylabel: _.get(queries, ['0', 'label'], ''),
|
||||
y2label: _.get(queries, ['1', 'label'], ''),
|
||||
},
|
||||
displayOptions
|
||||
)
|
||||
const options = {
|
||||
labels,
|
||||
connectSeparatedPoints: true,
|
||||
labelsKMB: true,
|
||||
axisLineColor: '#383846',
|
||||
gridLineColor: '#383846',
|
||||
title,
|
||||
rightGap: 0,
|
||||
yRangePad: 10,
|
||||
axisLabelWidth: 38,
|
||||
drawAxesAtZero: true,
|
||||
underlayCallback,
|
||||
ylabel: _.get(queries, ['0', 'label'], ''),
|
||||
y2label: _.get(queries, ['1', 'label'], ''),
|
||||
...displayOptions,
|
||||
}
|
||||
|
||||
let roundedValue
|
||||
if (showSingleStat) {
|
||||
|
@ -141,6 +140,7 @@ export default React.createClass({
|
|||
containerStyle={{width: '100%', height: '100%'}}
|
||||
overrideLineColors={overrideLineColors}
|
||||
isGraphFilled={isGraphFilled}
|
||||
isBarChart={isBarChart}
|
||||
timeSeries={timeSeries}
|
||||
labels={labels}
|
||||
options={options}
|
||||
|
|
|
@ -4,4 +4,5 @@
|
|||
{type: "line-stepplot", menuOption: "Step-Plot"},
|
||||
{type: "single-stat", menuOption: "SingleStat"},
|
||||
{type: "line-plus-single-stat", menuOption: "Line + Stat"},
|
||||
{type: "bar", menuOption: "Bar"},
|
||||
]
|
||||
|
|
Loading…
Reference in New Issue