@@ -247,11 +247,7 @@ const MIN_BAR_PERCENT_HEIGHT = 0.01; | |||||
const LINE_CHART_DOT_SIZE = 4; | const LINE_CHART_DOT_SIZE = 4; | ||||
const DOT_OVERLAY_SIZE_INCR = 4; | const DOT_OVERLAY_SIZE_INCR = 4; | ||||
const DEFAULT_CHAR_WIDTH = 7; | |||||
// Universal constants | |||||
const ANGLE_RATIO = Math.PI / 180; | |||||
const FULL_ANGLE = 360; | |||||
const PERCENTAGE_BAR_DEFAULT_HEIGHT = 20; | |||||
// Fixed 5-color theme, | // Fixed 5-color theme, | ||||
// More colors are difficult to parse visually | // More colors are difficult to parse visually | ||||
@@ -260,6 +256,8 @@ const HEATMAP_DISTRIBUTION_SIZE = 5; | |||||
const HEATMAP_SQUARE_SIZE = 10; | const HEATMAP_SQUARE_SIZE = 10; | ||||
const HEATMAP_GUTTER_SIZE = 2; | const HEATMAP_GUTTER_SIZE = 2; | ||||
const DEFAULT_CHAR_WIDTH = 7; | |||||
const HEATMAP_COLORS = ['#ebedf0', '#c6e48b', '#7bc96f', '#239a3b', '#196127']; | const HEATMAP_COLORS = ['#ebedf0', '#c6e48b', '#7bc96f', '#239a3b', '#196127']; | ||||
const DEFAULT_CHART_COLORS = ['light-blue', 'blue', 'violet', 'red', 'orange', | const DEFAULT_CHART_COLORS = ['light-blue', 'blue', 'violet', 'red', 'orange', | ||||
'yellow', 'green', 'light-green', 'purple', 'magenta', 'light-grey', 'dark-grey']; | 'yellow', 'green', 'light-green', 'purple', 'magenta', 'light-grey', 'dark-grey']; | ||||
@@ -272,6 +270,10 @@ const DEFAULT_COLORS = { | |||||
heatmap: HEATMAP_COLORS | heatmap: HEATMAP_COLORS | ||||
}; | }; | ||||
// Universal constants | |||||
const ANGLE_RATIO = Math.PI / 180; | |||||
const FULL_ANGLE = 360; | |||||
function floatTwo(d) { | function floatTwo(d) { | ||||
return parseFloat(d.toFixed(2)); | return parseFloat(d.toFixed(2)); | ||||
} | } | ||||
@@ -472,6 +474,19 @@ function makeGradient(svgDefElem, color, lighter = false) { | |||||
return gradientId; | return gradientId; | ||||
} | } | ||||
function percentageBar(x, y, width, height, fill='none') { | |||||
let args = { | |||||
className: 'percentage-bar', | |||||
x: x, | |||||
y: y, | |||||
width: width, | |||||
height: height, | |||||
fill: fill | |||||
}; | |||||
return createSVG("rect", args); | |||||
} | |||||
function heatSquare(className, x, y, size, fill='none', data={}) { | function heatSquare(className, x, y, size, fill='none', data={}) { | ||||
let args = { | let args = { | ||||
className: className, | className: className, | ||||
@@ -1555,6 +1570,8 @@ class AggregationChart extends BaseChart { | |||||
s.sliceTotals.push(d[0]); | s.sliceTotals.push(d[0]); | ||||
s.labels.push(d[1]); | s.labels.push(d[1]); | ||||
}); | }); | ||||
s.grandTotal = s.sliceTotals.reduce((a, b) => a + b, 0); | |||||
} | } | ||||
renderLegend() { | renderLegend() { | ||||
@@ -1578,79 +1595,8 @@ class AggregationChart extends BaseChart { | |||||
// </span>`; | // </span>`; | ||||
// } | // } | ||||
// }); | // }); | ||||
} | |||||
} | |||||
class PercentageChart extends AggregationChart { | |||||
constructor(parent, args) { | |||||
super(parent, args); | |||||
this.type = 'percentage'; | |||||
this.setup(); | |||||
} | |||||
makeChartArea() { | |||||
this.container.className += ' ' + 'graph-focus-margin'; | |||||
this.container.style.marginTop = '45px'; | |||||
// this.statsWrapper.className += ' ' + 'graph-focus-margin'; | |||||
// this.statsWrapper.style.marginBottom = '30px'; | |||||
// this.statsWrapper.style.paddingTop = '0px'; | |||||
this.svg = $.create('div', { | |||||
className: 'div', | |||||
inside: this.container | |||||
}); | |||||
this.chart = $.create('div', { | |||||
className: 'progress-chart', | |||||
inside: this.svg | |||||
}); | |||||
this.percentageBar = $.create('div', { | |||||
className: 'progress', | |||||
inside: this.chart | |||||
}); | |||||
} | |||||
render() { | |||||
let s = this.state; | |||||
this.grandTotal = s.sliceTotals.reduce((a, b) => a + b, 0); | |||||
s.slices = []; | |||||
s.sliceTotals.map((total, i) => { | |||||
let slice = $.create('div', { | |||||
className: `progress-bar`, | |||||
'data-index': i, | |||||
inside: this.percentageBar, | |||||
styles: { | |||||
background: this.colors[i], | |||||
width: total*100/this.grandTotal + "%" | |||||
} | |||||
}); | |||||
s.slices.push(slice); | |||||
}); | |||||
} | |||||
bindTooltip() { | |||||
let s = this.state; | |||||
this.container.addEventListener('mousemove', (e) => { | |||||
let slice = e.target; | |||||
if(slice.classList.contains('progress-bar')) { | |||||
let i = slice.getAttribute('data-index'); | |||||
let gOff = getOffset(this.container), pOff = getOffset(slice); | |||||
let x = pOff.left - gOff.left + slice.offsetWidth/2; | |||||
let y = pOff.top - gOff.top - 6; | |||||
let title = (this.formattedLabels && this.formattedLabels.length>0 | |||||
? this.formattedLabels[i] : this.state.labels[i]) + ': '; | |||||
let percent = (s.sliceTotals[i]*100/this.grandTotal).toFixed(1); | |||||
this.tip.setValues(x, y, {name: title, value: percent + "%"}); | |||||
this.tip.showTip(); | |||||
} | |||||
}); | |||||
// | |||||
} | } | ||||
} | } | ||||
@@ -1707,7 +1653,7 @@ class ChartComponent { | |||||
this.refresh(); | this.refresh(); | ||||
let animateElements = []; | let animateElements = []; | ||||
if(animate) { | if(animate) { | ||||
animateElements = this.animateElements(this.data); | |||||
animateElements = this.animateElements(this.data) || []; | |||||
} | } | ||||
return animateElements; | return animateElements; | ||||
} | } | ||||
@@ -1733,18 +1679,15 @@ let componentConfigs = { | |||||
percentageBars: { | percentageBars: { | ||||
layerClass: 'percentage-bars', | layerClass: 'percentage-bars', | ||||
makeElements(data) { | makeElements(data) { | ||||
// return data.sliceStrings.map((s, i) =>{ | |||||
// let slice = makePath(s, 'pie-path', 'none', data.colors[i]); | |||||
// slice.style.transition = 'transform .3s;'; | |||||
// return slice; | |||||
// }); | |||||
return data.xPositions.map((x, i) =>{ | |||||
let y = 0; | |||||
let bar = percentageBar(x, y, data.widths[i], | |||||
this.constants.barHeight, data.colors[i]); | |||||
return bar; | |||||
}); | |||||
}, | }, | ||||
animateElements(newData) { | |||||
// return this.store.map((slice, i) => | |||||
// animatePathStr(slice, newData.sliceStrings[i]) | |||||
// ); | |||||
} | |||||
animateElements(newData) { } | |||||
}, | }, | ||||
yAxis: { | yAxis: { | ||||
layerClass: 'y axis', | layerClass: 'y axis', | ||||
@@ -1905,11 +1848,7 @@ let componentConfigs = { | |||||
return this.serializedSubDomains; | return this.serializedSubDomains; | ||||
}, | }, | ||||
animateElements(newData) { | |||||
// return this.store.map((slice, i) => | |||||
// animatePathStr(slice, newData.sliceStrings[i]) | |||||
// ); | |||||
} | |||||
animateElements(newData) { } | |||||
}, | }, | ||||
barGraph: { | barGraph: { | ||||
@@ -2064,6 +2003,83 @@ function getComponent(name, constants, getData) { | |||||
return new ChartComponent(config); | return new ChartComponent(config); | ||||
} | } | ||||
class PercentageChart extends AggregationChart { | |||||
constructor(parent, args) { | |||||
super(parent, args); | |||||
this.type = 'percentage'; | |||||
this.barOptions = args.barOptions || {}; | |||||
this.barOptions.height = this.barOptions.height | |||||
|| PERCENTAGE_BAR_DEFAULT_HEIGHT; | |||||
this.setup(); | |||||
} | |||||
setupComponents() { | |||||
let s = this.state; | |||||
let componentConfigs = [ | |||||
[ | |||||
'percentageBars', | |||||
{ | |||||
barHeight: this.barOptions.height | |||||
}, | |||||
function() { | |||||
return { | |||||
xPositions: s.xPositions, | |||||
widths: s.widths, | |||||
colors: this.colors | |||||
}; | |||||
}.bind(this) | |||||
] | |||||
]; | |||||
this.components = new Map(componentConfigs | |||||
.map(args => { | |||||
let component = getComponent(...args); | |||||
return [args[0], component]; | |||||
})); | |||||
} | |||||
calc() { | |||||
super.calc(); | |||||
let s = this.state; | |||||
s.xPositions = []; | |||||
s.widths = []; | |||||
let xPos = 0; | |||||
s.sliceTotals.map((value, i) => { | |||||
let width = this.width * value / s.grandTotal; | |||||
s.widths.push(width); | |||||
s.xPositions.push(xPos); | |||||
xPos += width; | |||||
}); | |||||
} | |||||
bindTooltip() { | |||||
let s = this.state; | |||||
this.container.addEventListener('mousemove', (e) => { | |||||
let slice = e.target; | |||||
if(slice.classList.contains('progress-bar')) { | |||||
let i = slice.getAttribute('data-index'); | |||||
let gOff = getOffset(this.container), pOff = getOffset(slice); | |||||
let x = pOff.left - gOff.left + slice.offsetWidth/2; | |||||
let y = pOff.top - gOff.top - 6; | |||||
let title = (this.formattedLabels && this.formattedLabels.length>0 | |||||
? this.formattedLabels[i] : this.state.labels[i]) + ': '; | |||||
let percent = (s.sliceTotals[i]*100/this.grandTotal).toFixed(1); | |||||
this.tip.setValues(x, y, {name: title, value: percent + "%"}); | |||||
this.tip.showTip(); | |||||
} | |||||
}); | |||||
} | |||||
} | |||||
class PieChart extends AggregationChart { | class PieChart extends AggregationChart { | ||||
constructor(parent, args) { | constructor(parent, args) { | ||||
super(parent, args); | super(parent, args); | ||||
@@ -2087,16 +2103,12 @@ class PieChart extends AggregationChart { | |||||
calc() { | calc() { | ||||
super.calc(); | super.calc(); | ||||
let s = this.state; | |||||
this.center = { | this.center = { | ||||
x: this.width / 2, | x: this.width / 2, | ||||
y: this.height / 2 | y: this.height / 2 | ||||
}; | }; | ||||
this.radius = (this.height > this.width ? this.center.x : this.center.y); | this.radius = (this.height > this.width ? this.center.x : this.center.y); | ||||
s.grandTotal = s.sliceTotals.reduce((a, b) => a + b, 0); | |||||
this.calcSlices(); | this.calcSlices(); | ||||
} | } | ||||
@@ -1 +1 @@ | |||||
.chart-container{font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,Fira Sans,Droid Sans,Helvetica Neue,sans-serif}.chart-container .axis,.chart-container .chart-label{fill:#555b51}.chart-container .axis line,.chart-container .chart-label line{stroke:#dadada}.chart-container .dataset-units circle{stroke:#fff;stroke-width:2}.chart-container .dataset-units path{fill:none;stroke-opacity:1;stroke-width:2px}.chart-container .dataset-path{stroke-width:2px}.chart-container .path-group path{fill:none;stroke-opacity:1;stroke-width:2px}.chart-container line.dashed{stroke-dasharray:5,3}.chart-container .axis-line .specific-value{text-anchor:start}.chart-container .axis-line .y-line{text-anchor:end}.chart-container .axis-line .x-line{text-anchor:middle}.chart-container .progress{height:20px;margin-bottom:20px;overflow:hidden;background-color:#f5f5f5;border-radius:4px;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,.1);box-shadow:inset 0 1px 2px rgba(0,0,0,.1)}.chart-container .progress-bar{float:left;width:0;height:100%;font-size:12px;line-height:20px;color:#fff;text-align:center;background-color:#36414c;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,.15);box-shadow:inset 0 -1px 0 rgba(0,0,0,.15);-webkit-transition:width .6s ease;transition:width .6s ease}.chart-container .graph-svg-tip{position:absolute;z-index:1;padding:10px;font-size:12px;color:#959da5;text-align:center;background:rgba(0,0,0,.8);border-radius:3px}.chart-container .graph-svg-tip ol,.chart-container .graph-svg-tip ul{padding-left:0;display:-webkit-box;display:-ms-flexbox;display:flex}.chart-container .graph-svg-tip ul.data-point-list li{min-width:90px;-webkit-box-flex:1;-ms-flex:1;flex:1;font-weight:600}.chart-container .graph-svg-tip strong{color:#dfe2e5;font-weight:600}.chart-container .graph-svg-tip .svg-pointer{position:absolute;height:5px;margin:0 0 0 -5px;content:" ";border:5px solid transparent;border-top-color:rgba(0,0,0,.8)}.chart-container .graph-svg-tip.comparison{padding:0;text-align:left;pointer-events:none}.chart-container .graph-svg-tip.comparison .title{display:block;padding:10px;margin:0;font-weight:600;line-height:1;pointer-events:none}.chart-container .graph-svg-tip.comparison ul{margin:0;white-space:nowrap;list-style:none}.chart-container .graph-svg-tip.comparison li{display:inline-block;padding:5px 10px} | |||||
.chart-container{font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,Fira Sans,Droid Sans,Helvetica Neue,sans-serif}.chart-container .axis,.chart-container .chart-label{fill:#555b51}.chart-container .axis line,.chart-container .chart-label line{stroke:#dadada}.chart-container .dataset-units circle{stroke:#fff;stroke-width:2}.chart-container .dataset-units path{fill:none;stroke-opacity:1;stroke-width:2px}.chart-container .dataset-path{stroke-width:2px}.chart-container .path-group path{fill:none;stroke-opacity:1;stroke-width:2px}.chart-container line.dashed{stroke-dasharray:5,3}.chart-container .axis-line .specific-value{text-anchor:start}.chart-container .axis-line .y-line{text-anchor:end}.chart-container .axis-line .x-line{text-anchor:middle}.chart-container .graph-svg-tip{position:absolute;z-index:1;padding:10px;font-size:12px;color:#959da5;text-align:center;background:rgba(0,0,0,.8);border-radius:3px}.chart-container .graph-svg-tip ol,.chart-container .graph-svg-tip ul{padding-left:0;display:-webkit-box;display:-ms-flexbox;display:flex}.chart-container .graph-svg-tip ul.data-point-list li{min-width:90px;-webkit-box-flex:1;-ms-flex:1;flex:1;font-weight:600}.chart-container .graph-svg-tip strong{color:#dfe2e5;font-weight:600}.chart-container .graph-svg-tip .svg-pointer{position:absolute;height:5px;margin:0 0 0 -5px;content:" ";border:5px solid transparent;border-top-color:rgba(0,0,0,.8)}.chart-container .graph-svg-tip.comparison{padding:0;text-align:left;pointer-events:none}.chart-container .graph-svg-tip.comparison .title{display:block;padding:10px;margin:0;font-weight:600;line-height:1;pointer-events:none}.chart-container .graph-svg-tip.comparison ul{margin:0;white-space:nowrap;list-style:none}.chart-container .graph-svg-tip.comparison li{display:inline-block;padding:5px 10px} |
@@ -28,12 +28,18 @@ function __$styleInject(css, ref) { | |||||
} | } | ||||
} | } | ||||
// Universal constants | |||||
// Fixed 5-color theme, | |||||
// More colors are difficult to parse visually | |||||
// Fixed 5-color theme, | |||||
// More colors are difficult to parse visually | |||||
// Universal constants | |||||
/** | /** | ||||
* Returns whether or not two given arrays are equal. | * Returns whether or not two given arrays are equal. | ||||
@@ -44,6 +44,8 @@ export default class AggregationChart extends BaseChart { | |||||
s.sliceTotals.push(d[0]); | s.sliceTotals.push(d[0]); | ||||
s.labels.push(d[1]); | s.labels.push(d[1]); | ||||
}); | }); | ||||
s.grandTotal = s.sliceTotals.reduce((a, b) => a + b, 0); | |||||
} | } | ||||
renderLegend() { | renderLegend() { | ||||
@@ -67,5 +69,7 @@ export default class AggregationChart extends BaseChart { | |||||
// </span>`; | // </span>`; | ||||
// } | // } | ||||
// }); | // }); | ||||
// | |||||
} | } | ||||
} | } |
@@ -1,53 +1,59 @@ | |||||
import AggregationChart from './AggregationChart'; | import AggregationChart from './AggregationChart'; | ||||
import { $, getOffset } from '../utils/dom'; | import { $, getOffset } from '../utils/dom'; | ||||
import { getComponent } from '../objects/ChartComponents'; | |||||
import { PERCENTAGE_BAR_DEFAULT_HEIGHT } from '../utils/constants'; | |||||
export default class PercentageChart extends AggregationChart { | export default class PercentageChart extends AggregationChart { | ||||
constructor(parent, args) { | constructor(parent, args) { | ||||
super(parent, args); | super(parent, args); | ||||
this.type = 'percentage'; | this.type = 'percentage'; | ||||
this.barOptions = args.barOptions || {}; | |||||
this.barOptions.height = this.barOptions.height | |||||
|| PERCENTAGE_BAR_DEFAULT_HEIGHT; | |||||
this.setup(); | this.setup(); | ||||
} | } | ||||
makeChartArea() { | |||||
this.container.className += ' ' + 'graph-focus-margin'; | |||||
this.container.style.marginTop = '45px'; | |||||
setupComponents() { | |||||
let s = this.state; | |||||
// this.statsWrapper.className += ' ' + 'graph-focus-margin'; | |||||
// this.statsWrapper.style.marginBottom = '30px'; | |||||
// this.statsWrapper.style.paddingTop = '0px'; | |||||
let componentConfigs = [ | |||||
[ | |||||
'percentageBars', | |||||
{ | |||||
barHeight: this.barOptions.height | |||||
}, | |||||
function() { | |||||
return { | |||||
xPositions: s.xPositions, | |||||
widths: s.widths, | |||||
colors: this.colors | |||||
}; | |||||
}.bind(this) | |||||
] | |||||
]; | |||||
this.svg = $.create('div', { | |||||
className: 'div', | |||||
inside: this.container | |||||
}); | |||||
this.chart = $.create('div', { | |||||
className: 'progress-chart', | |||||
inside: this.svg | |||||
}); | |||||
this.percentageBar = $.create('div', { | |||||
className: 'progress', | |||||
inside: this.chart | |||||
}); | |||||
this.components = new Map(componentConfigs | |||||
.map(args => { | |||||
let component = getComponent(...args); | |||||
return [args[0], component]; | |||||
})); | |||||
} | } | ||||
render() { | |||||
calc() { | |||||
super.calc(); | |||||
let s = this.state; | let s = this.state; | ||||
this.grandTotal = s.sliceTotals.reduce((a, b) => a + b, 0); | |||||
s.slices = []; | |||||
s.sliceTotals.map((total, i) => { | |||||
let slice = $.create('div', { | |||||
className: `progress-bar`, | |||||
'data-index': i, | |||||
inside: this.percentageBar, | |||||
styles: { | |||||
background: this.colors[i], | |||||
width: total*100/this.grandTotal + "%" | |||||
} | |||||
}); | |||||
s.slices.push(slice); | |||||
s.xPositions = []; | |||||
s.widths = []; | |||||
let xPos = 0; | |||||
s.sliceTotals.map((value, i) => { | |||||
let width = this.width * value / s.grandTotal; | |||||
s.widths.push(width); | |||||
s.xPositions.push(xPos); | |||||
xPos += width; | |||||
}); | }); | ||||
} | } | ||||
@@ -38,8 +38,6 @@ export default class PieChart extends AggregationChart { | |||||
}; | }; | ||||
this.radius = (this.height > this.width ? this.center.x : this.center.y); | this.radius = (this.height > this.width ? this.center.x : this.center.y); | ||||
s.grandTotal = s.sliceTotals.reduce((a, b) => a + b, 0); | |||||
this.calcSlices(); | this.calcSlices(); | ||||
} | } | ||||
@@ -1,5 +1,5 @@ | |||||
import { makeSVGGroup } from '../utils/draw'; | import { makeSVGGroup } from '../utils/draw'; | ||||
import { makePath, xLine, yLine, yMarker, yRegion, datasetBar, datasetDot, getPaths, heatSquare } from '../utils/draw'; | |||||
import { makePath, xLine, yLine, yMarker, yRegion, datasetBar, datasetDot, percentageBar, getPaths, heatSquare } from '../utils/draw'; | |||||
import { equilizeNoOfElements } from '../utils/draw-utils'; | import { equilizeNoOfElements } from '../utils/draw-utils'; | ||||
import { translateHoriLine, translateVertLine, animateRegion, animateBar, | import { translateHoriLine, translateVertLine, animateRegion, animateBar, | ||||
animateDot, animatePath, animatePathStr } from '../utils/animate'; | animateDot, animatePath, animatePathStr } from '../utils/animate'; | ||||
@@ -57,7 +57,7 @@ class ChartComponent { | |||||
this.refresh(); | this.refresh(); | ||||
let animateElements = []; | let animateElements = []; | ||||
if(animate) { | if(animate) { | ||||
animateElements = this.animateElements(this.data); | |||||
animateElements = this.animateElements(this.data) || []; | |||||
} | } | ||||
return animateElements; | return animateElements; | ||||
} | } | ||||
@@ -83,18 +83,15 @@ let componentConfigs = { | |||||
percentageBars: { | percentageBars: { | ||||
layerClass: 'percentage-bars', | layerClass: 'percentage-bars', | ||||
makeElements(data) { | makeElements(data) { | ||||
// return data.sliceStrings.map((s, i) =>{ | |||||
// let slice = makePath(s, 'pie-path', 'none', data.colors[i]); | |||||
// slice.style.transition = 'transform .3s;'; | |||||
// return slice; | |||||
// }); | |||||
return data.xPositions.map((x, i) =>{ | |||||
let y = 0; | |||||
let bar = percentageBar(x, y, data.widths[i], | |||||
this.constants.barHeight, data.colors[i]); | |||||
return bar; | |||||
}); | |||||
}, | }, | ||||
animateElements(newData) { | |||||
// return this.store.map((slice, i) => | |||||
// animatePathStr(slice, newData.sliceStrings[i]) | |||||
// ); | |||||
} | |||||
animateElements(newData) { } | |||||
}, | }, | ||||
yAxis: { | yAxis: { | ||||
layerClass: 'y axis', | layerClass: 'y axis', | ||||
@@ -255,11 +252,7 @@ let componentConfigs = { | |||||
return this.serializedSubDomains; | return this.serializedSubDomains; | ||||
}, | }, | ||||
animateElements(newData) { | |||||
// return this.store.map((slice, i) => | |||||
// animatePathStr(slice, newData.sliceStrings[i]) | |||||
// ); | |||||
} | |||||
animateElements(newData) { } | |||||
}, | }, | ||||
barGraph: { | barGraph: { | ||||
@@ -37,11 +37,7 @@ export const MIN_BAR_PERCENT_HEIGHT = 0.01; | |||||
export const LINE_CHART_DOT_SIZE = 4; | export const LINE_CHART_DOT_SIZE = 4; | ||||
export const DOT_OVERLAY_SIZE_INCR = 4; | export const DOT_OVERLAY_SIZE_INCR = 4; | ||||
export const DEFAULT_CHAR_WIDTH = 7; | |||||
// Universal constants | |||||
export const ANGLE_RATIO = Math.PI / 180; | |||||
export const FULL_ANGLE = 360; | |||||
export const PERCENTAGE_BAR_DEFAULT_HEIGHT = 20; | |||||
// Fixed 5-color theme, | // Fixed 5-color theme, | ||||
// More colors are difficult to parse visually | // More colors are difficult to parse visually | ||||
@@ -50,6 +46,8 @@ export const HEATMAP_DISTRIBUTION_SIZE = 5; | |||||
export const HEATMAP_SQUARE_SIZE = 10; | export const HEATMAP_SQUARE_SIZE = 10; | ||||
export const HEATMAP_GUTTER_SIZE = 2; | export const HEATMAP_GUTTER_SIZE = 2; | ||||
export const DEFAULT_CHAR_WIDTH = 7; | |||||
const HEATMAP_COLORS = ['#ebedf0', '#c6e48b', '#7bc96f', '#239a3b', '#196127']; | const HEATMAP_COLORS = ['#ebedf0', '#c6e48b', '#7bc96f', '#239a3b', '#196127']; | ||||
const DEFAULT_CHART_COLORS = ['light-blue', 'blue', 'violet', 'red', 'orange', | const DEFAULT_CHART_COLORS = ['light-blue', 'blue', 'violet', 'red', 'orange', | ||||
'yellow', 'green', 'light-green', 'purple', 'magenta', 'light-grey', 'dark-grey']; | 'yellow', 'green', 'light-green', 'purple', 'magenta', 'light-grey', 'dark-grey']; | ||||
@@ -60,4 +58,8 @@ export const DEFAULT_COLORS = { | |||||
pie: DEFAULT_CHART_COLORS, | pie: DEFAULT_CHART_COLORS, | ||||
percentage: DEFAULT_CHART_COLORS, | percentage: DEFAULT_CHART_COLORS, | ||||
heatmap: HEATMAP_COLORS | heatmap: HEATMAP_COLORS | ||||
}; | |||||
}; | |||||
// Universal constants | |||||
export const ANGLE_RATIO = Math.PI / 180; | |||||
export const FULL_ANGLE = 360; |
@@ -132,6 +132,19 @@ export function makeGradient(svgDefElem, color, lighter = false) { | |||||
return gradientId; | return gradientId; | ||||
} | } | ||||
export function percentageBar(x, y, width, height, fill='none') { | |||||
let args = { | |||||
className: 'percentage-bar', | |||||
x: x, | |||||
y: y, | |||||
width: width, | |||||
height: height, | |||||
fill: fill | |||||
}; | |||||
return createSVG("rect", args); | |||||
} | |||||
export function heatSquare(className, x, y, size, fill='none', data={}) { | export function heatSquare(className, x, y, size, fill='none', data={}) { | ||||
let args = { | let args = { | ||||
className: className, | className: className, | ||||
@@ -51,30 +51,6 @@ | |||||
text-anchor: middle; | text-anchor: middle; | ||||
} | } | ||||
} | } | ||||
.progress { | |||||
height: 20px; | |||||
margin-bottom: 20px; | |||||
overflow: hidden; | |||||
background-color: #f5f5f5; | |||||
border-radius: 4px; | |||||
-webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, .1); | |||||
box-shadow: inset 0 1px 2px rgba(0, 0, 0, .1); | |||||
} | |||||
.progress-bar { | |||||
float: left; | |||||
width: 0; | |||||
height: 100%; | |||||
font-size: 12px; | |||||
line-height: 20px; | |||||
color: #fff; | |||||
text-align: center; | |||||
background-color: #36414c; | |||||
-webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, .15); | |||||
box-shadow: inset 0 -1px 0 rgba(0, 0, 0, .15); | |||||
-webkit-transition: width .6s ease; | |||||
-o-transition: width .6s ease; | |||||
transition: width .6s ease; | |||||
} | |||||
.graph-svg-tip { | .graph-svg-tip { | ||||
position: absolute; | position: absolute; | ||||