@@ -311,10 +311,6 @@ class SvgTip { | |||
} | |||
} | |||
/** | |||
* Returns the value of a number upto 2 decimal places. | |||
* @param {Number} d Any number | |||
*/ | |||
function floatTwo(d) { | |||
return parseFloat(d.toFixed(2)); | |||
} | |||
@@ -3694,7 +3690,6 @@ class AxisChart extends BaseChart { | |||
// removeDataPoint(index = 0) {} | |||
} | |||
// import MultiAxisChart from './charts/MultiAxisChart'; | |||
const chartTypes = { | |||
bar: AxisChart, | |||
line: AxisChart, | |||
@@ -3706,7 +3701,7 @@ const chartTypes = { | |||
function getChartByType(chartType = 'line', parent, options) { | |||
if (chartType === 'axis-mixed') { | |||
options.type = 'line'; | |||
// options.type = 'line'; | |||
return new AxisChart(parent, options); | |||
} | |||
@@ -470,10 +470,6 @@ var SvgTip = function () { | |||
return SvgTip; | |||
}(); | |||
/** | |||
* Returns the value of a number upto 2 decimal places. | |||
* @param {Number} d Any number | |||
*/ | |||
function floatTwo(d) { | |||
return parseFloat(d.toFixed(2)); | |||
} | |||
@@ -4294,7 +4290,6 @@ var AxisChart = function (_BaseChart) { | |||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } | |||
// import MultiAxisChart from './charts/MultiAxisChart'; | |||
var chartTypes = { | |||
bar: AxisChart, | |||
line: AxisChart, | |||
@@ -4310,7 +4305,7 @@ function getChartByType() { | |||
var options = arguments[2]; | |||
if (chartType === 'axis-mixed') { | |||
options.type = 'line'; | |||
// options.type = 'line'; | |||
return new AxisChart(parent, options); | |||
} | |||
@@ -466,10 +466,6 @@ var SvgTip = function () { | |||
return SvgTip; | |||
}(); | |||
/** | |||
* Returns the value of a number upto 2 decimal places. | |||
* @param {Number} d Any number | |||
*/ | |||
function floatTwo(d) { | |||
return parseFloat(d.toFixed(2)); | |||
} | |||
@@ -4290,7 +4286,6 @@ var AxisChart = function (_BaseChart) { | |||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } | |||
// import MultiAxisChart from './charts/MultiAxisChart'; | |||
var chartTypes = { | |||
bar: AxisChart, | |||
line: AxisChart, | |||
@@ -4306,7 +4301,7 @@ function getChartByType() { | |||
var options = arguments[2]; | |||
if (chartType === 'axis-mixed') { | |||
options.type = 'line'; | |||
// options.type = 'line'; | |||
return new AxisChart(parent, options); | |||
} | |||
@@ -4,7 +4,7 @@ | |||
* Axis charts | |||
* [A basic chart](basic/basic_chart.md) | |||
* [Area and Trends Charts](basic/trends_regions.md) | |||
* [Annotations and Tooltip format](basic/annotations.md) | |||
* [Tooltips and Annotations](basic/annotations.md) | |||
* [Stacked and Mixed Charts](basic/stacked_and_mixed.md) | |||
* Aggregation Charts | |||
@@ -1,8 +1,9 @@ | |||
Annotations are for special values (like range points). They are defined within the `data` property itself. | |||
## Annotations | |||
Special values (like range points) on a chart can be annotated for quick comparisions. As they are among the components of a graph that can be updated, they are defined within the `data` property itself. There are two kinds of annotations that can be used to mark the vertical axis values: **markers** and **regions**. | |||
## Markers | |||
#### Markers | |||
To highlight certain values on the Y axis, `yMarkers` can be set. They will shown ad dotted lines on the graph. | |||
To highlight certain values on the Y axis, `yMarkers` can be set. They will shown as dashed lines on the graph. | |||
```js | |||
data = { | |||
@@ -10,35 +11,98 @@ data = { | |||
// datasets: [], | |||
yMarkers: [ | |||
{ | |||
label: "Marker", | |||
value: 43, | |||
options: { labelPos: 'right' } | |||
label: "Threshold", | |||
value: 650, | |||
options: { labelPos: 'left' } // default: 'right' | |||
} | |||
] | |||
} | |||
``` | |||
<chart-demo data="ymarkers" | |||
v-bind:config="{ | |||
type: 'line', | |||
height: 180, | |||
colors: ['violet'], | |||
axisOptions: { | |||
yAxisMode: 'tick' | |||
}, | |||
}"> | |||
</chart-demo> | |||
[demo only marker] | |||
## Regions | |||
#### Regions | |||
2D counterparts to markers, they have a `start` and `end` instead of value: | |||
```js | |||
yRegions: [ | |||
{ | |||
label: "Region", | |||
start: -10, | |||
end: 50, | |||
options: { labelPos: 'left' } | |||
}, | |||
label: "Optimum Value", | |||
start: 100, | |||
end: 600, | |||
options: { labelPos: 'right' } | |||
} | |||
], | |||
``` | |||
Shown as a a greyed out area between the extremes. | |||
[demo only region] | |||
Shown as a greyed-out area between the extremes. | |||
<chart-demo data="yregions" | |||
v-bind:config="{ | |||
type: 'line', | |||
height: 180, | |||
colors: ['violet'], | |||
axisOptions: { | |||
yAxisMode: 'tick' | |||
}, | |||
}"> | |||
</chart-demo> | |||
## Tooltips | |||
Tooltips are by default | |||
[demo format] | |||
Frappe Charts are known for their [awesome tooltips](https://twitter.com/Elijah_Meeks/status/934338534143488000). What's more, they are also customizable for the format of the label and value displayed on them. | |||
```js | |||
tooltipOptions: { | |||
formatTooltipX: d => (d + '').toUpperCase(), | |||
formatTooltipY: d => d + ' pts', | |||
} | |||
``` | |||
<chart-demo data="0" | |||
v-bind:config="{ | |||
type: 'line', | |||
height: 150, | |||
colors: ['violet'], | |||
axisOptions: { | |||
yAxisMode: 'tick' | |||
}, | |||
tooltipOptions: { | |||
formatTooltipX: d => (d + '').toUpperCase(), | |||
formatTooltipY: d => d + ' pts', | |||
} | |||
}"> | |||
</chart-demo> | |||
For a non-web or static interface, where tooltips are absent, `valuesOverPoints` is a useful tweak to show value information at a glance. | |||
```js | |||
{ | |||
valuesOverPoints: 1 // default: 0 | |||
} | |||
``` | |||
<chart-demo data="1" v-bind:config="{ | |||
type: 'line', | |||
height: 200, | |||
colors:['violet', 'magenta'], | |||
valuesOverPoints: 1 | |||
}" | |||
v-bind:options="[ | |||
{ | |||
name: 'type', | |||
path: ['type'], | |||
type: 'string', | |||
states: { 'Bar': 'bar', 'Line': 'line' }, | |||
activeState: 'Bar' | |||
} | |||
]"> | |||
</chart-demo> | |||
Next up we'll look at perhaps one the more exciting parts in axis charts: **Mixed Charts**. |
@@ -61,7 +61,7 @@ Notice that this case demonstrates why the `colors` option is an array. We'll se | |||
name: 'type', | |||
path: ['type'], | |||
type: 'string', | |||
states: { 'Line': 'line', 'Bar': 'bar', }, | |||
states: { 'Line': 'line', 'Bar': 'bar' }, | |||
activeState: 'Mixed' | |||
} | |||
]"> | |||
@@ -1,47 +1,95 @@ | |||
## Adding more datasets | |||
#### Mixed Bar/Line Chart | |||
As we have seen, chart can have [multiple datasets](). In an axis chart, every dataset is represented individually. | |||
As we have seen, chart can have [multiple datasets](/basic/basic_chart?id=adding-more-datasets). Each dataset can also have a different `chartType`, which if specified, should accompany the `type` property set to `axis-mixed`. | |||
```js | |||
data: { | |||
labels: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"], | |||
datasets: [ | |||
{ name: "Dataset 1", values: [18, 40, 30, 35, 8, 52, 17, -4] }, | |||
{ name: "Dataset 2", values: [30, 50, -10, 15, 18, 32, 27, 14] } | |||
{ | |||
name: "Dataset 1", | |||
values: [18, 40, 30, 35, 8, 52, 17, -4], | |||
chartType: 'bar' | |||
}, | |||
{ | |||
name: "Dataset 2", | |||
values: [30, 50, -10, 15, 18, 32, 27, 14], | |||
chartType: 'line' | |||
} | |||
] | |||
} | |||
``` | |||
<div class="demo" id="multi-dataset-line-bar"></div> | |||
}, | |||
## Stacked Bar Chart | |||
type: 'axis-mixed' | |||
``` | |||
This allows for creation of mixed axis chart. It is recommended to list the bar datasets before the line ones to avoid overlapping. | |||
<chart-demo data="mixed-1" v-bind:config="{ | |||
type: 'axis-mixed', | |||
height: 200, | |||
colors:['light-green', 'green'] | |||
}"> | |||
</chart-demo> | |||
Bars have two ways to show multiple data point values. The property [`stacked`]() in `barOptions` renders a stacked bar chart instead of the default adjacent bars: | |||
All the `lineOptions` and `barOptions` apply to mix and match datasets as well. | |||
```js | |||
barOptions: { | |||
stacked: 1 // default 0 | |||
} | |||
``` | |||
<chart-demo data="mixed-2" v-bind:config="{ | |||
type: 'axis-mixed', | |||
height: 240, | |||
colors:['light-green', 'green', 'blue'], | |||
lineOptions: { | |||
dotSize: 4 | |||
}, | |||
barOptions: { | |||
spaceRatio: 0.4 | |||
}, | |||
}" | |||
v-bind:options="[ | |||
{ | |||
name: 'barOptions', | |||
path: ['barOptions', 'spaceRatio'], | |||
type: 'number', | |||
numberOptions: { min: 0.1, max: 1.9, step: 0.1 }, | |||
activeState: 0.4 | |||
}, | |||
{ | |||
name: 'lineOptions', | |||
path: ['lineOptions', 'dotSize'], | |||
type: 'number', | |||
numberOptions: { min: 3, max: 10, step: 1 }, | |||
activeState: 4 | |||
} | |||
]"> | |||
</chart-demo> | |||
[stacked/adjacent] | |||
Infact, one of the bar options is actually dependent on multiple datasets. | |||
#### Stacked Bar Chart | |||
## Mixed Bar/Line Chart | |||
Each dataset can also have a different `chartType`, which if specified, will take precedence over the `type` property. | |||
Unlike lines, bars have two ways to show multiple data point values: adjacent or stacked bars. Stacked bar charts are similar to area charts, being useful for comparisions of similar trends. The property [`stacked`]() in `barOptions` renders a stacked bar chart instead of the default adjacent bars: | |||
```js | |||
data: { | |||
labels: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"], | |||
datasets: [ | |||
{ name: "Dataset 1", values: [18, 40, 30, 35, 8, 52, 17, -4] }, | |||
{ name: "Dataset 2", values: [30, 50, -10, 15, 18, 32, 27, 14] } | |||
] | |||
barOptions: { | |||
stacked: 1 // default 0, i.e. adjacent | |||
} | |||
``` | |||
<chart-demo data="bar-composite-data" v-bind:config="{ | |||
type: 'bar', | |||
height: 240, | |||
colors:['blue', 'green', 'light-green'], | |||
barOptions: { | |||
spaceRatio: 0.4, | |||
stacked: 1 | |||
}, | |||
}" | |||
v-bind:options="[ | |||
{ | |||
name: 'barOptions', | |||
path: ['barOptions', 'stacked'], | |||
type: 'boolean', | |||
states: { 'Stacked': 1, 'Adjacent': 0 }, | |||
activeState: 1 | |||
} | |||
]"> | |||
</chart-demo> | |||
All the `lineOptions` and `barOptions` apply to mix and match datasets as well. | |||
[mix and match demo, no buttons] | |||
In [Aggregation Charts]() however, instead of being rendered individually, each data point in aggregated accross every dataset. We'll cover those next. |
@@ -1,3 +1,63 @@ | |||
const fireball_5_25 = [ | |||
[4, 0, 3, 1, 1, 2, 1, 1, 1, 0, 1, 1], | |||
[2, 3, 3, 2, 1, 3, 0, 1, 2, 7, 10, 4], | |||
[5, 6, 2, 4, 0, 1, 4, 3, 0, 2, 0, 1], | |||
[0, 2, 6, 2, 1, 1, 2, 3, 6, 3, 7, 8], | |||
[6, 8, 7, 7, 4, 5, 6, 5, 22, 12, 10, 11], | |||
[7, 10, 11, 7, 3, 2, 7, 7, 11, 15, 22, 20], | |||
[13, 16, 21, 18, 19, 17, 12, 17, 31, 28, 25, 29], | |||
[24, 14, 21, 14, 11, 15, 19, 21, 41, 22, 32, 18], | |||
[31, 20, 30, 22, 14, 17, 21, 35, 27, 50, 117, 24], | |||
[32, 24, 21, 27, 11, 27, 43, 37, 44, 40, 48, 32], | |||
[31, 38, 36, 26, 23, 23, 25, 29, 26, 47, 61, 50], | |||
]; | |||
const fireball_2_5 = [ | |||
[22, 6, 6, 9, 7, 8, 6, 14, 19, 10, 8, 20], | |||
[11, 13, 12, 8, 9, 11, 9, 13, 10, 22, 40, 24], | |||
[20, 13, 13, 19, 13, 10, 14, 13, 20, 18, 5, 9], | |||
[7, 13, 16, 19, 12, 11, 21, 27, 27, 24, 33, 33], | |||
[38, 25, 28, 22, 31, 21, 35, 42, 37, 32, 46, 53], | |||
[50, 33, 36, 34, 35, 28, 27, 52, 58, 59, 75, 69], | |||
[54, 67, 67, 45, 66, 51, 38, 64, 90, 113, 116, 87], | |||
[84, 52, 56, 51, 55, 46, 50, 87, 114, 83, 152, 93], | |||
[73, 58, 59, 63, 56, 51, 83, 140, 103, 115, 265, 89], | |||
[106, 95, 94, 71, 77, 75, 99, 136, 129, 154, 168, 156], | |||
[81, 102, 95, 72, 58, 91, 89, 122, 124, 135, 183, 171], | |||
]; | |||
const fireballOver25 = [ | |||
// [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], | |||
[0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0], | |||
[0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0], | |||
[1, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0], | |||
[0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 2], | |||
[3, 2, 1, 3, 2, 0, 2, 2, 2, 3, 0, 1], | |||
[2, 3, 5, 2, 1, 3, 0, 2, 3, 5, 1, 4], | |||
[7, 4, 6, 1, 9, 2, 2, 2, 20, 9, 4, 9], | |||
[5, 6, 1, 2, 5, 4, 5, 5, 16, 9, 14, 9], | |||
[5, 4, 7, 5, 1, 5, 3, 3, 5, 7, 22, 2], | |||
[5, 13, 11, 6, 1, 7, 9, 8, 14, 17, 16, 3], | |||
[8, 9, 8, 6, 4, 8, 5, 6, 14, 11, 21, 12] | |||
]; | |||
const barCompositeData = { | |||
labels: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", | |||
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"], | |||
datasets: [ | |||
{ | |||
name: "Over 25 reports", | |||
values: fireballOver25[9], | |||
}, | |||
{ | |||
name: "5 to 25 reports", | |||
values: fireball_5_25[9], | |||
}, | |||
{ | |||
name: "2 to 5 reports", | |||
values: fireball_2_5[9] | |||
} | |||
] | |||
}; | |||
const sampleData = { | |||
"0": { | |||
labels: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"], | |||
@@ -41,5 +101,78 @@ const sampleData = { | |||
12.6, 4.2, 4.8, 24.9, 80.8, 84.5, 94.0, 113.3, 69.8, 39.8] | |||
} | |||
] | |||
} | |||
}, | |||
"ymarkers": { | |||
labels: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun", "Mon"], | |||
datasets: [ | |||
{ values: [300, 250, 720, 560, 370, 610, 690, 410, | |||
370, 480, 620, 260, 170, 510, 630, 710] } | |||
], | |||
yMarkers: [ | |||
{ | |||
label: "Threshold", | |||
value: 650, | |||
options: { labelPos: 'left' } | |||
} | |||
] | |||
}, | |||
"yregions": { | |||
labels: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun", "Mon"], | |||
datasets: [ | |||
{ values: [300, 250, 720, 560, -370, 610, 690, 410, | |||
370, 480, 620, -260, 170, 430, 630, 210] } | |||
], | |||
yRegions: [ | |||
{ | |||
label: "Optimum Value", | |||
start: 100, | |||
end: 600, | |||
options: { labelPos: 'right' } | |||
} | |||
] | |||
}, | |||
"mixed-1": { | |||
labels: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"], | |||
datasets: [ | |||
{ | |||
name: "Dataset 1", | |||
values: [18, 40, 30, 35, 8, 52, 17, -4], | |||
chartType: 'bar' | |||
}, | |||
{ | |||
name: "Dataset 2", | |||
values: [30, 50, -10, 15, 18, 32, 27, 14], | |||
chartType: 'line' | |||
} | |||
] | |||
}, | |||
"mixed-2": { | |||
labels: ["12am-3am", "3am-6am", "6am-9am", "9am-12pm", | |||
"12pm-3pm", "3pm-6pm", "6pm-9pm", "9pm-12am"], | |||
datasets: [ | |||
{ | |||
name: "Some Data", | |||
values: [18, 40, 30, 35, 8, 52, 17, -4], | |||
axisPosition: 'right', | |||
chartType: 'bar' | |||
}, | |||
{ | |||
name: "Another Set", | |||
values: [30, 50, -10, 15, 18, 32, 27, 14], | |||
axisPosition: 'right', | |||
chartType: 'bar' | |||
}, | |||
{ | |||
name: "Yet Another", | |||
values: [15, 20, -3, -15, 58, 12, -17, 37], | |||
chartType: 'line' | |||
} | |||
] | |||
}, | |||
"bar-composite-data": barCompositeData | |||
} |
@@ -45,6 +45,7 @@ function toTitleCase(str) { | |||
return str.replace(/\w*/g, function(txt){return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase();}); | |||
} | |||
// export class demoBuilder { | |||
class demoBuilder { | |||
constructor(LIB_OBJ) { | |||
this.LIB_OBJ = LIB_OBJ; | |||
@@ -171,7 +172,7 @@ class docSection { | |||
} | |||
}); | |||
} else if(["map", "string"].includes(o.type)) { | |||
} else if(["map", "string", "boolean"].includes(o.type)) { | |||
args[o.path[0]] = {}; | |||
Object.keys(o.states).forEach(key => { | |||
@@ -115,7 +115,7 @@ | |||
name: 'frappe-charts', | |||
// repo: 'https://github.com/frappe/charts', | |||
loadSidebar: true, | |||
subMaxLevel: 2, | |||
subMaxLevel: 5, | |||
executeScript: true, | |||
search: { | |||
placeholder: 'Search Docs ...', | |||
@@ -195,12 +195,6 @@ var HEATMAP_COLORS_YELLOW = ['#ebedf0', '#fdf436', '#ffc700', '#ff9100', '#06001 | |||
// Universal constants | |||
/** | |||
* Returns the value of a number upto 2 decimal places. | |||
* @param {Number} d Any number | |||
*/ | |||
/** | |||
* Returns whether or not two given arrays are equal. | |||
* @param {Array} arr1 First array | |||
@@ -953,10 +947,6 @@ var SvgTip = function () { | |||
return SvgTip; | |||
}(); | |||
/** | |||
* Returns the value of a number upto 2 decimal places. | |||
* @param {Number} d Any number | |||
*/ | |||
function floatTwo$1(d) { | |||
return parseFloat(d.toFixed(2)); | |||
} | |||
@@ -5102,7 +5092,6 @@ function _classCallCheck$1$1(instance, Constructor) { | |||
} | |||
} | |||
// import MultiAxisChart from './charts/MultiAxisChart'; | |||
var chartTypes = { | |||
bar: AxisChart, | |||
line: AxisChart, | |||
@@ -5118,7 +5107,7 @@ function getChartByType() { | |||
var options = arguments[2]; | |||
if (chartType === 'axis-mixed') { | |||
options.type = 'line'; | |||
// options.type = 'line'; | |||
return new AxisChart(parent, options); | |||
} | |||
@@ -5150,6 +5139,7 @@ var MONTH_NAMES_SHORT = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", | |||
// https://stackoverflow.com/a/11252167/6495043 | |||
function clone$1(date) { | |||
@@ -5190,8 +5180,6 @@ function addDays$1(date, numberOfDays) { | |||
date.setDate(date.getDate() + numberOfDays); | |||
} | |||
// Composite Chart | |||
// ================================================================================ | |||
var reportCountList = [152, 222, 199, 287, 534, 709, 1179, 1256, 1632, 1856, 1850]; | |||
var lineCompositeData = { | |||
@@ -5540,7 +5528,7 @@ var demoSections = [{ | |||
"Line": [0, 1, 0, 0], | |||
"Dots": [1, 0, 0, 0], | |||
"HeatLine": [0, 1, 1, 0], | |||
"Region": [0, 1, 0, 1] | |||
"Area": [0, 1, 0, 1] | |||
}, | |||
activeState: "HeatLine" | |||
}], | |||
@@ -17,7 +17,7 @@ const chartTypes = { | |||
function getChartByType(chartType = 'line', parent, options) { | |||
if (chartType === 'axis-mixed') { | |||
options.type = 'line'; | |||
// options.type = 'line'; | |||
return new AxisChart(parent, options); | |||
} | |||