[axis] allow skipping x values
This commit is contained in:
parent
51ece1bb63
commit
59ad41427f
195
dist/frappe-charts.esm.js
vendored
195
dist/frappe-charts.esm.js
vendored
@ -273,27 +273,6 @@ function equilizeNoOfElements(array1, array2,
|
|||||||
return [array1, array2];
|
return [array1, array2];
|
||||||
}
|
}
|
||||||
|
|
||||||
// let char_width = 8;
|
|
||||||
// let allowed_space = avgUnitWidth * 1.5;
|
|
||||||
// let allowed_letters = allowed_space / 8;
|
|
||||||
|
|
||||||
// return values.map((value, i) => {
|
|
||||||
// let space_taken = getStringWidth(value, char_width) + 2;
|
|
||||||
// if(space_taken > allowed_space) {
|
|
||||||
// if(isSeries) {
|
|
||||||
// // Skip some axis lines if X axis is a series
|
|
||||||
// let skips = 1;
|
|
||||||
// while((space_taken/skips)*2 > allowed_space) {
|
|
||||||
// skips++;
|
|
||||||
// }
|
|
||||||
// if(i % skips !== 0) {
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
// } else {
|
|
||||||
// value = value.slice(0, allowed_letters-3) + " ...";
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
const UNIT_ANIM_DUR = 350;
|
const UNIT_ANIM_DUR = 350;
|
||||||
const PATH_ANIM_DUR = 350;
|
const PATH_ANIM_DUR = 350;
|
||||||
const MARKER_LINE_ANIM_DUR = UNIT_ANIM_DUR;
|
const MARKER_LINE_ANIM_DUR = UNIT_ANIM_DUR;
|
||||||
@ -411,6 +390,8 @@ 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 = 8;
|
||||||
|
|
||||||
const AXIS_TICK_LENGTH = 6;
|
const AXIS_TICK_LENGTH = 6;
|
||||||
const LABEL_MARGIN = 4;
|
const LABEL_MARGIN = 4;
|
||||||
const FONT_SIZE = 10;
|
const FONT_SIZE = 10;
|
||||||
@ -2283,24 +2264,57 @@ function zeroDataPrep(realData) {
|
|||||||
chartType: d.chartType
|
chartType: d.chartType
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
yRegions: [
|
};
|
||||||
|
|
||||||
|
if(realData.yMarkers) {
|
||||||
|
zeroData.yMarkers = [
|
||||||
|
{
|
||||||
|
value: 0,
|
||||||
|
label: ''
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
if(realData.yRegions) {
|
||||||
|
zeroData.yRegions = [
|
||||||
{
|
{
|
||||||
start: 0,
|
start: 0,
|
||||||
end: 0,
|
end: 0,
|
||||||
label: ''
|
label: ''
|
||||||
}
|
}
|
||||||
],
|
];
|
||||||
yMarkers: [
|
}
|
||||||
{
|
|
||||||
value: 0,
|
|
||||||
label: ''
|
|
||||||
}
|
|
||||||
]
|
|
||||||
};
|
|
||||||
|
|
||||||
return zeroData;
|
return zeroData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getShortenedLabels(chartWidth, labels=[], isSeries=true) {
|
||||||
|
let allowedSpace = chartWidth / labels.length;
|
||||||
|
let allowedLetters = allowedSpace / DEFAULT_CHAR_WIDTH;
|
||||||
|
|
||||||
|
let calcLabels = labels.map((label, i) => {
|
||||||
|
label += "";
|
||||||
|
if(label.length > allowedLetters) {
|
||||||
|
|
||||||
|
if(!isSeries) {
|
||||||
|
if(allowedLetters-3 > 0) {
|
||||||
|
label = label.slice(0, allowedLetters-3) + " ...";
|
||||||
|
} else {
|
||||||
|
label = label.slice(0, allowedLetters) + '..';
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
let multiple = Math.ceil(label.length/allowedLetters);
|
||||||
|
if(i % multiple !== 0) {
|
||||||
|
label = "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return label;
|
||||||
|
});
|
||||||
|
|
||||||
|
return calcLabels;
|
||||||
|
}
|
||||||
|
|
||||||
class ChartComponent {
|
class ChartComponent {
|
||||||
constructor({
|
constructor({
|
||||||
layerClass = '',
|
layerClass = '',
|
||||||
@ -2396,23 +2410,23 @@ let componentConfigs = {
|
|||||||
layerClass: 'x axis',
|
layerClass: 'x axis',
|
||||||
makeElements(data) {
|
makeElements(data) {
|
||||||
return data.positions.map((position, i) =>
|
return data.positions.map((position, i) =>
|
||||||
xLine(position, data.labels[i], this.constants.height,
|
xLine(position, data.calcLabels[i], this.constants.height,
|
||||||
{mode: this.constants.mode, pos: this.constants.pos})
|
{mode: this.constants.mode, pos: this.constants.pos})
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
||||||
animateElements(newData) {
|
animateElements(newData) {
|
||||||
let newPos = newData.positions;
|
let newPos = newData.positions;
|
||||||
let newLabels = newData.labels;
|
let newLabels = newData.calcLabels;
|
||||||
let oldPos = this.oldData.positions;
|
let oldPos = this.oldData.positions;
|
||||||
let oldLabels = this.oldData.labels;
|
let oldLabels = this.oldData.calcLabels;
|
||||||
|
|
||||||
[oldPos, newPos] = equilizeNoOfElements(oldPos, newPos);
|
[oldPos, newPos] = equilizeNoOfElements(oldPos, newPos);
|
||||||
[oldLabels, newLabels] = equilizeNoOfElements(oldLabels, newLabels);
|
[oldLabels, newLabels] = equilizeNoOfElements(oldLabels, newLabels);
|
||||||
|
|
||||||
this.render({
|
this.render({
|
||||||
positions: oldPos,
|
positions: oldPos,
|
||||||
labels: newLabels
|
calcLabels: newLabels
|
||||||
});
|
});
|
||||||
|
|
||||||
return this.store.map((line, i) => {
|
return this.store.map((line, i) => {
|
||||||
@ -2564,23 +2578,24 @@ let componentConfigs = {
|
|||||||
makeElements(data) {
|
makeElements(data) {
|
||||||
let c = this.constants;
|
let c = this.constants;
|
||||||
this.unitType = 'dot';
|
this.unitType = 'dot';
|
||||||
|
this.paths = {};
|
||||||
this.paths = getPaths(
|
if(!c.hideLine) {
|
||||||
data.xPositions,
|
this.paths = getPaths(
|
||||||
data.yPositions,
|
data.xPositions,
|
||||||
c.color,
|
data.yPositions,
|
||||||
{
|
c.color,
|
||||||
heatline: c.heatline,
|
{
|
||||||
regionFill: c.regionFill
|
heatline: c.heatline,
|
||||||
},
|
regionFill: c.regionFill
|
||||||
{
|
},
|
||||||
svgDefs: c.svgDefs,
|
{
|
||||||
zeroLine: data.zeroLine
|
svgDefs: c.svgDefs,
|
||||||
}
|
zeroLine: data.zeroLine
|
||||||
);
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
this.units = [];
|
this.units = [];
|
||||||
|
|
||||||
if(!c.hideDots) {
|
if(!c.hideDots) {
|
||||||
this.units = data.yPositions.map((y, j) => {
|
this.units = data.yPositions.map((y, j) => {
|
||||||
return datasetDot(
|
return datasetDot(
|
||||||
@ -2621,8 +2636,10 @@ let componentConfigs = {
|
|||||||
|
|
||||||
let animateElements = [];
|
let animateElements = [];
|
||||||
|
|
||||||
animateElements = animateElements.concat(animatePath(
|
if(Object.keys(this.paths).length) {
|
||||||
this.paths, newXPos, newYPos, newData.zeroLine));
|
animateElements = animateElements.concat(animatePath(
|
||||||
|
this.paths, newXPos, newYPos, newData.zeroLine));
|
||||||
|
}
|
||||||
|
|
||||||
if(this.units.length) {
|
if(this.units.length) {
|
||||||
this.units.map((dot, i) => {
|
this.units.map((dot, i) => {
|
||||||
@ -2649,24 +2666,29 @@ function getComponent(name, constants, getData) {
|
|||||||
class AxisChart extends BaseChart {
|
class AxisChart extends BaseChart {
|
||||||
constructor(parent, args) {
|
constructor(parent, args) {
|
||||||
super(parent, args);
|
super(parent, args);
|
||||||
this.isSeries = args.isSeries;
|
|
||||||
this.valuesOverPoints = args.valuesOverPoints;
|
|
||||||
this.formatTooltipY = args.formatTooltipY;
|
|
||||||
this.formatTooltipX = args.formatTooltipX;
|
|
||||||
this.barOptions = args.barOptions || {};
|
this.barOptions = args.barOptions || {};
|
||||||
this.lineOptions = args.lineOptions || {};
|
this.lineOptions = args.lineOptions || {};
|
||||||
this.type = args.type || 'line';
|
|
||||||
|
|
||||||
this.xAxisMode = args.xAxisMode || 'span';
|
this.type = args.type || 'line';
|
||||||
this.yAxisMode = args.yAxisMode || 'span';
|
|
||||||
|
|
||||||
this.setup();
|
this.setup();
|
||||||
}
|
}
|
||||||
|
|
||||||
configure(args) {3;
|
configure(args) {
|
||||||
super.configure();
|
super.configure();
|
||||||
this.config.xAxisMode = args.xAxisMode;
|
|
||||||
this.config.yAxisMode = args.yAxisMode;
|
args.axisOptions = args.axisOptions || {};
|
||||||
|
args.tooltipOptions = args.tooltipOptions || {};
|
||||||
|
|
||||||
|
this.config.xAxisMode = args.axisOptions.xAxisMode || 'span';
|
||||||
|
this.config.yAxisMode = args.axisOptions.yAxisMode || 'span';
|
||||||
|
this.config.xIsSeries = args.axisOptions.xIsSeries || 1;
|
||||||
|
|
||||||
|
this.config.formatTooltipX = args.tooltipOptions.formatTooltipX;
|
||||||
|
this.config.formatTooltipY = args.tooltipOptions.formatTooltipY;
|
||||||
|
|
||||||
|
this.config.valuesOverPoints = args.valuesOverPoints;
|
||||||
}
|
}
|
||||||
|
|
||||||
setMargins() {
|
setMargins() {
|
||||||
@ -2770,7 +2792,7 @@ class AxisChart extends BaseChart {
|
|||||||
if(this.data.yMarkers) {
|
if(this.data.yMarkers) {
|
||||||
this.state.yMarkers = this.data.yMarkers.map(d => {
|
this.state.yMarkers = this.data.yMarkers.map(d => {
|
||||||
d.position = scale(d.value, s.yAxis);
|
d.position = scale(d.value, s.yAxis);
|
||||||
if(!d.label) {
|
if(!d.label.includes(':')) {
|
||||||
d.label += ': ' + d.value;
|
d.label += ': ' + d.value;
|
||||||
}
|
}
|
||||||
return d;
|
return d;
|
||||||
@ -2806,19 +2828,29 @@ class AxisChart extends BaseChart {
|
|||||||
[
|
[
|
||||||
'yAxis',
|
'yAxis',
|
||||||
{
|
{
|
||||||
mode: this.yAxisMode,
|
mode: this.config.yAxisMode,
|
||||||
width: this.width,
|
width: this.width,
|
||||||
// pos: 'right'
|
// pos: 'right'
|
||||||
}
|
},
|
||||||
|
function() {
|
||||||
|
return this.state.yAxis;
|
||||||
|
}.bind(this)
|
||||||
],
|
],
|
||||||
|
|
||||||
[
|
[
|
||||||
'xAxis',
|
'xAxis',
|
||||||
{
|
{
|
||||||
mode: this.xAxisMode,
|
mode: this.config.xAxisMode,
|
||||||
height: this.height,
|
height: this.height,
|
||||||
// pos: 'right'
|
// pos: 'right'
|
||||||
}
|
},
|
||||||
|
function() {
|
||||||
|
let s = this.state;
|
||||||
|
s.xAxis.calcLabels = getShortenedLabels(this.width,
|
||||||
|
s.xAxis.labels, this.config.xIsSeries);
|
||||||
|
|
||||||
|
return s.xAxis;
|
||||||
|
}.bind(this)
|
||||||
],
|
],
|
||||||
|
|
||||||
[
|
[
|
||||||
@ -2826,18 +2858,13 @@ class AxisChart extends BaseChart {
|
|||||||
{
|
{
|
||||||
width: this.width,
|
width: this.width,
|
||||||
pos: 'right'
|
pos: 'right'
|
||||||
}
|
},
|
||||||
|
function() {
|
||||||
|
return this.state.yRegions;
|
||||||
|
}.bind(this)
|
||||||
],
|
],
|
||||||
];
|
];
|
||||||
|
|
||||||
componentConfigs.map(args => {
|
|
||||||
args.push(
|
|
||||||
function() {
|
|
||||||
return this.state[args[0]];
|
|
||||||
}.bind(this)
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
let barDatasets = this.state.datasets.filter(d => d.chartType === 'bar');
|
let barDatasets = this.state.datasets.filter(d => d.chartType === 'bar');
|
||||||
let lineDatasets = this.state.datasets.filter(d => d.chartType === 'line');
|
let lineDatasets = this.state.datasets.filter(d => d.chartType === 'line');
|
||||||
|
|
||||||
@ -2853,7 +2880,7 @@ class AxisChart extends BaseChart {
|
|||||||
stacked: this.barOptions.stacked,
|
stacked: this.barOptions.stacked,
|
||||||
|
|
||||||
// same for all datasets
|
// same for all datasets
|
||||||
valuesOverPoints: this.valuesOverPoints,
|
valuesOverPoints: this.config.valuesOverPoints,
|
||||||
minHeight: this.height * MIN_BAR_PERCENT_HEIGHT,
|
minHeight: this.height * MIN_BAR_PERCENT_HEIGHT,
|
||||||
},
|
},
|
||||||
function() {
|
function() {
|
||||||
@ -2910,9 +2937,10 @@ class AxisChart extends BaseChart {
|
|||||||
heatline: this.lineOptions.heatline,
|
heatline: this.lineOptions.heatline,
|
||||||
regionFill: this.lineOptions.regionFill,
|
regionFill: this.lineOptions.regionFill,
|
||||||
hideDots: this.lineOptions.hideDots,
|
hideDots: this.lineOptions.hideDots,
|
||||||
|
hideLine: this.lineOptions.hideLine,
|
||||||
|
|
||||||
// same for all datasets
|
// same for all datasets
|
||||||
valuesOverPoints: this.valuesOverPoints,
|
valuesOverPoints: this.config.valuesOverPoints,
|
||||||
},
|
},
|
||||||
function() {
|
function() {
|
||||||
let s = this.state;
|
let s = this.state;
|
||||||
@ -2937,18 +2965,13 @@ class AxisChart extends BaseChart {
|
|||||||
{
|
{
|
||||||
width: this.width,
|
width: this.width,
|
||||||
pos: 'right'
|
pos: 'right'
|
||||||
}
|
},
|
||||||
|
function() {
|
||||||
|
return this.state.yMarkers;
|
||||||
|
}.bind(this)
|
||||||
]
|
]
|
||||||
];
|
];
|
||||||
|
|
||||||
markerConfigs.map(args => {
|
|
||||||
args.push(
|
|
||||||
function() {
|
|
||||||
return this.state[args[0]];
|
|
||||||
}.bind(this)
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
componentConfigs = componentConfigs.concat(barsConfigs, lineConfigs, markerConfigs);
|
componentConfigs = componentConfigs.concat(barsConfigs, lineConfigs, markerConfigs);
|
||||||
|
|
||||||
let optionals = ['yMarkers', 'yRegions'];
|
let optionals = ['yMarkers', 'yRegions'];
|
||||||
|
|||||||
2
dist/frappe-charts.min.cjs.js
vendored
2
dist/frappe-charts.min.cjs.js
vendored
File diff suppressed because one or more lines are too long
2
dist/frappe-charts.min.esm.js
vendored
2
dist/frappe-charts.min.esm.js
vendored
File diff suppressed because one or more lines are too long
2
dist/frappe-charts.min.iife.js
vendored
2
dist/frappe-charts.min.iife.js
vendored
File diff suppressed because one or more lines are too long
2
dist/frappe-charts.min.iife.js.map
vendored
2
dist/frappe-charts.min.iife.js.map
vendored
File diff suppressed because one or more lines are too long
2
docs/assets/js/frappe-charts.min.js
vendored
2
docs/assets/js/frappe-charts.min.js
vendored
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -63,7 +63,7 @@ let c1 = document.querySelector("#chart-composite-1");
|
|||||||
let c2 = document.querySelector("#chart-composite-2");
|
let c2 = document.querySelector("#chart-composite-2");
|
||||||
|
|
||||||
let bar_composite_chart = new Chart (c1, {
|
let bar_composite_chart = new Chart (c1, {
|
||||||
title: "Fireball/Bolide Events - Yearly (more than 5 reports)",
|
title: "Fireball/Bolide Events - Yearly (reported)",
|
||||||
data: bar_composite_data,
|
data: bar_composite_data,
|
||||||
type: 'line',
|
type: 'line',
|
||||||
height: 180,
|
height: 180,
|
||||||
@ -179,9 +179,11 @@ let type_chart = new Chart("#chart-types", {
|
|||||||
isNavigable: 1,
|
isNavigable: 1,
|
||||||
barOptions: {
|
barOptions: {
|
||||||
stacked: 1
|
stacked: 1
|
||||||
|
},
|
||||||
|
tooltipOptions: {
|
||||||
|
formatTooltipX: d => (d + '').toUpperCase(),
|
||||||
|
formatTooltipY: d => d + ' pts'
|
||||||
}
|
}
|
||||||
// formatTooltipX: d => (d + '').toUpperCase(),
|
|
||||||
// formatTooltipY: d => d + ' pts'
|
|
||||||
});
|
});
|
||||||
|
|
||||||
Array.prototype.slice.call(
|
Array.prototype.slice.call(
|
||||||
@ -222,7 +224,7 @@ let trends_data = {
|
|||||||
]
|
]
|
||||||
};
|
};
|
||||||
|
|
||||||
let plot_chart_args = {
|
let plotChartArgs = {
|
||||||
title: "Mean Total Sunspot Count - Yearly",
|
title: "Mean Total Sunspot Count - Yearly",
|
||||||
data: trends_data,
|
data: trends_data,
|
||||||
type: 'line',
|
type: 'line',
|
||||||
@ -233,11 +235,14 @@ let plot_chart_args = {
|
|||||||
hideDots: 1,
|
hideDots: 1,
|
||||||
heatline: 1,
|
heatline: 1,
|
||||||
},
|
},
|
||||||
xAxisMode: 'tick',
|
axisOptions: {
|
||||||
yAxisMode: 'span'
|
xAxisMode: 'tick',
|
||||||
|
yAxisMode: 'span',
|
||||||
|
xIsSeries: 1
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
new Chart("#chart-trends", plot_chart_args);
|
new Chart("#chart-trends", plotChartArgs);
|
||||||
|
|
||||||
Array.prototype.slice.call(
|
Array.prototype.slice.call(
|
||||||
document.querySelectorAll('.chart-plot-buttons button')
|
document.querySelectorAll('.chart-plot-buttons button')
|
||||||
@ -245,23 +250,17 @@ Array.prototype.slice.call(
|
|||||||
el.addEventListener('click', (e) => {
|
el.addEventListener('click', (e) => {
|
||||||
let btn = e.target;
|
let btn = e.target;
|
||||||
let type = btn.getAttribute('data-type');
|
let type = btn.getAttribute('data-type');
|
||||||
let config = [];
|
let config = {};
|
||||||
|
config[type] = 1;
|
||||||
|
|
||||||
if(type === 'line') {
|
if(['regionFill', 'heatline'].includes(type)) {
|
||||||
config = [0, 0, 0];
|
config.hideDots = 1;
|
||||||
} else if(type === 'region') {
|
|
||||||
config = [0, 0, 1];
|
|
||||||
} else {
|
|
||||||
config = [0, 1, 0];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
plot_chart_args.hideDots = config[0];
|
// plotChartArgs.init = false;
|
||||||
plot_chart_args.heatline = config[1];
|
plotChartArgs.lineOptions = config;
|
||||||
plot_chart_args.regionFill = config[2];
|
|
||||||
|
|
||||||
plot_chart_args.init = false;
|
new Chart("#chart-trends", plotChartArgs);
|
||||||
|
|
||||||
new Chart("#chart-trends", plot_chart_args);
|
|
||||||
|
|
||||||
Array.prototype.slice.call(
|
Array.prototype.slice.call(
|
||||||
btn.parentNode.querySelectorAll('button')).map(el => {
|
btn.parentNode.querySelectorAll('button')).map(el => {
|
||||||
@ -308,6 +307,7 @@ let update_chart = new Chart("#chart-update", {
|
|||||||
colors: ['red'],
|
colors: ['red'],
|
||||||
isSeries: 1,
|
isSeries: 1,
|
||||||
lineOptions: {
|
lineOptions: {
|
||||||
|
// hideLine: 1,
|
||||||
regionFill: 1
|
regionFill: 1
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
@ -398,48 +398,7 @@ events_chart.parent.addEventListener('data-select', (e) => {
|
|||||||
|
|
||||||
// Aggregation chart
|
// Aggregation chart
|
||||||
// ================================================================================
|
// ================================================================================
|
||||||
let aggr_data = {
|
|
||||||
labels: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"],
|
|
||||||
datasets: [
|
|
||||||
{
|
|
||||||
"values": [25, 40, 30, 35, 8, 52, 17]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"values": [25, 50, 10, 15, 18, 32, 27],
|
|
||||||
}
|
|
||||||
]
|
|
||||||
};
|
|
||||||
|
|
||||||
let aggr_chart = new Chart("#chart-aggr", {
|
|
||||||
data: aggr_data,
|
|
||||||
type: 'bar',
|
|
||||||
height: 250,
|
|
||||||
colors: ['light-green', 'blue'],
|
|
||||||
valuesOverPoints: 1,
|
|
||||||
barOptions: {
|
|
||||||
stacked: 1
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
document.querySelector('[data-aggregation="sums"]').addEventListener("click", (e) => {
|
|
||||||
if(e.target.innerHTML === "Show Sums") {
|
|
||||||
aggr_chart.show_sums();
|
|
||||||
e.target.innerHTML = "Hide Sums";
|
|
||||||
} else {
|
|
||||||
aggr_chart.hide_sums();
|
|
||||||
e.target.innerHTML = "Show Sums";
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
document.querySelector('[data-aggregation="average"]').addEventListener("click", (e) => {
|
|
||||||
if(e.target.innerHTML === "Show Averages") {
|
|
||||||
aggr_chart.show_averages();
|
|
||||||
e.target.innerHTML = "Hide Averages";
|
|
||||||
} else {
|
|
||||||
aggr_chart.hide_averages();
|
|
||||||
e.target.innerHTML = "Show Averages";
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Heatmap
|
// Heatmap
|
||||||
// ================================================================================
|
// ================================================================================
|
||||||
|
|||||||
@ -165,10 +165,10 @@
|
|||||||
...</code></pre>
|
...</code></pre>
|
||||||
<div id="chart-trends" class="border"></div>
|
<div id="chart-trends" class="border"></div>
|
||||||
<div class="btn-group chart-plot-buttons mt-1 mx-auto" role="group">
|
<div class="btn-group chart-plot-buttons mt-1 mx-auto" role="group">
|
||||||
<button type="button" class="btn btn-sm btn-secondary" data-type="line">Line</button>
|
<button type="button" class="btn btn-sm btn-secondary" data-type="hideDots">Line</button>
|
||||||
<button type="button" class="btn btn-sm btn-secondary" data-type="dots">Dots</button>
|
<button type="button" class="btn btn-sm btn-secondary" data-type="hideLine">Dots</button>
|
||||||
<button type="button" class="btn btn-sm btn-secondary active" data-type="heatline">HeatLine</button>
|
<button type="button" class="btn btn-sm btn-secondary active" data-type="heatline">HeatLine</button>
|
||||||
<button type="button" class="btn btn-sm btn-secondary" data-type="region">Region</button>
|
<button type="button" class="btn btn-sm btn-secondary" data-type="regionFill">Region</button>
|
||||||
</div>
|
</div>
|
||||||
<pre><code class="hljs javascript margin-vertical-px"> ...
|
<pre><code class="hljs javascript margin-vertical-px"> ...
|
||||||
type: 'line', // Line Chart specific properties:
|
type: 'line', // Line Chart specific properties:
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import BaseChart from './BaseChart';
|
import BaseChart from './BaseChart';
|
||||||
import { dataPrep, zeroDataPrep } from './axis-chart-utils';
|
import { dataPrep, zeroDataPrep, getShortenedLabels } from '../utils/axis-chart-utils';
|
||||||
import { Y_AXIS_MARGIN } from '../utils/constants';
|
import { Y_AXIS_MARGIN } from '../utils/constants';
|
||||||
import { getComponent } from '../objects/ChartComponents';
|
import { getComponent } from '../objects/ChartComponents';
|
||||||
import { getOffset, fire } from '../utils/dom';
|
import { getOffset, fire } from '../utils/dom';
|
||||||
@ -11,24 +11,29 @@ import { MIN_BAR_PERCENT_HEIGHT, DEFAULT_AXIS_CHART_TYPE, BAR_CHART_SPACE_RATIO,
|
|||||||
export default class AxisChart extends BaseChart {
|
export default class AxisChart extends BaseChart {
|
||||||
constructor(parent, args) {
|
constructor(parent, args) {
|
||||||
super(parent, args);
|
super(parent, args);
|
||||||
this.isSeries = args.isSeries;
|
|
||||||
this.valuesOverPoints = args.valuesOverPoints;
|
|
||||||
this.formatTooltipY = args.formatTooltipY;
|
|
||||||
this.formatTooltipX = args.formatTooltipX;
|
|
||||||
this.barOptions = args.barOptions || {};
|
this.barOptions = args.barOptions || {};
|
||||||
this.lineOptions = args.lineOptions || {};
|
this.lineOptions = args.lineOptions || {};
|
||||||
this.type = args.type || 'line';
|
|
||||||
|
|
||||||
this.xAxisMode = args.xAxisMode || 'span';
|
this.type = args.type || 'line';
|
||||||
this.yAxisMode = args.yAxisMode || 'span';
|
|
||||||
|
|
||||||
this.setup();
|
this.setup();
|
||||||
}
|
}
|
||||||
|
|
||||||
configure(args) {3
|
configure(args) {
|
||||||
super.configure();
|
super.configure();
|
||||||
this.config.xAxisMode = args.xAxisMode;
|
|
||||||
this.config.yAxisMode = args.yAxisMode;
|
args.axisOptions = args.axisOptions || {};
|
||||||
|
args.tooltipOptions = args.tooltipOptions || {};
|
||||||
|
|
||||||
|
this.config.xAxisMode = args.axisOptions.xAxisMode || 'span';
|
||||||
|
this.config.yAxisMode = args.axisOptions.yAxisMode || 'span';
|
||||||
|
this.config.xIsSeries = args.axisOptions.xIsSeries || 1;
|
||||||
|
|
||||||
|
this.config.formatTooltipX = args.tooltipOptions.formatTooltipX;
|
||||||
|
this.config.formatTooltipY = args.tooltipOptions.formatTooltipY;
|
||||||
|
|
||||||
|
this.config.valuesOverPoints = args.valuesOverPoints;
|
||||||
}
|
}
|
||||||
|
|
||||||
setMargins() {
|
setMargins() {
|
||||||
@ -132,7 +137,7 @@ export default class AxisChart extends BaseChart {
|
|||||||
if(this.data.yMarkers) {
|
if(this.data.yMarkers) {
|
||||||
this.state.yMarkers = this.data.yMarkers.map(d => {
|
this.state.yMarkers = this.data.yMarkers.map(d => {
|
||||||
d.position = scale(d.value, s.yAxis);
|
d.position = scale(d.value, s.yAxis);
|
||||||
if(!d.label) {
|
if(!d.label.includes(':')) {
|
||||||
d.label += ': ' + d.value;
|
d.label += ': ' + d.value;
|
||||||
}
|
}
|
||||||
return d;
|
return d;
|
||||||
@ -169,19 +174,29 @@ export default class AxisChart extends BaseChart {
|
|||||||
[
|
[
|
||||||
'yAxis',
|
'yAxis',
|
||||||
{
|
{
|
||||||
mode: this.yAxisMode,
|
mode: this.config.yAxisMode,
|
||||||
width: this.width,
|
width: this.width,
|
||||||
// pos: 'right'
|
// pos: 'right'
|
||||||
}
|
},
|
||||||
|
function() {
|
||||||
|
return this.state.yAxis;
|
||||||
|
}.bind(this)
|
||||||
],
|
],
|
||||||
|
|
||||||
[
|
[
|
||||||
'xAxis',
|
'xAxis',
|
||||||
{
|
{
|
||||||
mode: this.xAxisMode,
|
mode: this.config.xAxisMode,
|
||||||
height: this.height,
|
height: this.height,
|
||||||
// pos: 'right'
|
// pos: 'right'
|
||||||
}
|
},
|
||||||
|
function() {
|
||||||
|
let s = this.state;
|
||||||
|
s.xAxis.calcLabels = getShortenedLabels(this.width,
|
||||||
|
s.xAxis.labels, this.config.xIsSeries);
|
||||||
|
|
||||||
|
return s.xAxis;
|
||||||
|
}.bind(this)
|
||||||
],
|
],
|
||||||
|
|
||||||
[
|
[
|
||||||
@ -189,18 +204,13 @@ export default class AxisChart extends BaseChart {
|
|||||||
{
|
{
|
||||||
width: this.width,
|
width: this.width,
|
||||||
pos: 'right'
|
pos: 'right'
|
||||||
}
|
},
|
||||||
|
function() {
|
||||||
|
return this.state.yRegions;
|
||||||
|
}.bind(this)
|
||||||
],
|
],
|
||||||
];
|
];
|
||||||
|
|
||||||
componentConfigs.map(args => {
|
|
||||||
args.push(
|
|
||||||
function() {
|
|
||||||
return this.state[args[0]];
|
|
||||||
}.bind(this)
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
let barDatasets = this.state.datasets.filter(d => d.chartType === 'bar');
|
let barDatasets = this.state.datasets.filter(d => d.chartType === 'bar');
|
||||||
let lineDatasets = this.state.datasets.filter(d => d.chartType === 'line');
|
let lineDatasets = this.state.datasets.filter(d => d.chartType === 'line');
|
||||||
|
|
||||||
@ -216,7 +226,7 @@ export default class AxisChart extends BaseChart {
|
|||||||
stacked: this.barOptions.stacked,
|
stacked: this.barOptions.stacked,
|
||||||
|
|
||||||
// same for all datasets
|
// same for all datasets
|
||||||
valuesOverPoints: this.valuesOverPoints,
|
valuesOverPoints: this.config.valuesOverPoints,
|
||||||
minHeight: this.height * MIN_BAR_PERCENT_HEIGHT,
|
minHeight: this.height * MIN_BAR_PERCENT_HEIGHT,
|
||||||
},
|
},
|
||||||
function() {
|
function() {
|
||||||
@ -273,9 +283,10 @@ export default class AxisChart extends BaseChart {
|
|||||||
heatline: this.lineOptions.heatline,
|
heatline: this.lineOptions.heatline,
|
||||||
regionFill: this.lineOptions.regionFill,
|
regionFill: this.lineOptions.regionFill,
|
||||||
hideDots: this.lineOptions.hideDots,
|
hideDots: this.lineOptions.hideDots,
|
||||||
|
hideLine: this.lineOptions.hideLine,
|
||||||
|
|
||||||
// same for all datasets
|
// same for all datasets
|
||||||
valuesOverPoints: this.valuesOverPoints,
|
valuesOverPoints: this.config.valuesOverPoints,
|
||||||
},
|
},
|
||||||
function() {
|
function() {
|
||||||
let s = this.state;
|
let s = this.state;
|
||||||
@ -300,18 +311,13 @@ export default class AxisChart extends BaseChart {
|
|||||||
{
|
{
|
||||||
width: this.width,
|
width: this.width,
|
||||||
pos: 'right'
|
pos: 'right'
|
||||||
}
|
},
|
||||||
|
function() {
|
||||||
|
return this.state.yMarkers;
|
||||||
|
}.bind(this)
|
||||||
]
|
]
|
||||||
];
|
];
|
||||||
|
|
||||||
markerConfigs.map(args => {
|
|
||||||
args.push(
|
|
||||||
function() {
|
|
||||||
return this.state[args[0]];
|
|
||||||
}.bind(this)
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
componentConfigs = componentConfigs.concat(barsConfigs, lineConfigs, markerConfigs);
|
componentConfigs = componentConfigs.concat(barsConfigs, lineConfigs, markerConfigs);
|
||||||
|
|
||||||
let optionals = ['yMarkers', 'yRegions'];
|
let optionals = ['yMarkers', 'yRegions'];
|
||||||
|
|||||||
@ -98,23 +98,23 @@ let componentConfigs = {
|
|||||||
layerClass: 'x axis',
|
layerClass: 'x axis',
|
||||||
makeElements(data) {
|
makeElements(data) {
|
||||||
return data.positions.map((position, i) =>
|
return data.positions.map((position, i) =>
|
||||||
xLine(position, data.labels[i], this.constants.height,
|
xLine(position, data.calcLabels[i], this.constants.height,
|
||||||
{mode: this.constants.mode, pos: this.constants.pos})
|
{mode: this.constants.mode, pos: this.constants.pos})
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
||||||
animateElements(newData) {
|
animateElements(newData) {
|
||||||
let newPos = newData.positions;
|
let newPos = newData.positions;
|
||||||
let newLabels = newData.labels;
|
let newLabels = newData.calcLabels;
|
||||||
let oldPos = this.oldData.positions;
|
let oldPos = this.oldData.positions;
|
||||||
let oldLabels = this.oldData.labels;
|
let oldLabels = this.oldData.calcLabels;
|
||||||
|
|
||||||
[oldPos, newPos] = equilizeNoOfElements(oldPos, newPos);
|
[oldPos, newPos] = equilizeNoOfElements(oldPos, newPos);
|
||||||
[oldLabels, newLabels] = equilizeNoOfElements(oldLabels, newLabels);
|
[oldLabels, newLabels] = equilizeNoOfElements(oldLabels, newLabels);
|
||||||
|
|
||||||
this.render({
|
this.render({
|
||||||
positions: oldPos,
|
positions: oldPos,
|
||||||
labels: newLabels
|
calcLabels: newLabels
|
||||||
});
|
});
|
||||||
|
|
||||||
return this.store.map((line, i) => {
|
return this.store.map((line, i) => {
|
||||||
@ -266,23 +266,24 @@ let componentConfigs = {
|
|||||||
makeElements(data) {
|
makeElements(data) {
|
||||||
let c = this.constants;
|
let c = this.constants;
|
||||||
this.unitType = 'dot';
|
this.unitType = 'dot';
|
||||||
|
this.paths = {};
|
||||||
this.paths = getPaths(
|
if(!c.hideLine) {
|
||||||
data.xPositions,
|
this.paths = getPaths(
|
||||||
data.yPositions,
|
data.xPositions,
|
||||||
c.color,
|
data.yPositions,
|
||||||
{
|
c.color,
|
||||||
heatline: c.heatline,
|
{
|
||||||
regionFill: c.regionFill
|
heatline: c.heatline,
|
||||||
},
|
regionFill: c.regionFill
|
||||||
{
|
},
|
||||||
svgDefs: c.svgDefs,
|
{
|
||||||
zeroLine: data.zeroLine
|
svgDefs: c.svgDefs,
|
||||||
}
|
zeroLine: data.zeroLine
|
||||||
)
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
this.units = []
|
this.units = []
|
||||||
|
|
||||||
if(!c.hideDots) {
|
if(!c.hideDots) {
|
||||||
this.units = data.yPositions.map((y, j) => {
|
this.units = data.yPositions.map((y, j) => {
|
||||||
return datasetDot(
|
return datasetDot(
|
||||||
@ -325,8 +326,10 @@ let componentConfigs = {
|
|||||||
|
|
||||||
let animateElements = [];
|
let animateElements = [];
|
||||||
|
|
||||||
animateElements = animateElements.concat(animatePath(
|
if(Object.keys(this.paths).length) {
|
||||||
this.paths, newXPos, newYPos, newData.zeroLine));
|
animateElements = animateElements.concat(animatePath(
|
||||||
|
this.paths, newXPos, newYPos, newData.zeroLine));
|
||||||
|
}
|
||||||
|
|
||||||
if(this.units.length) {
|
if(this.units.length) {
|
||||||
this.units.map((dot, i) => {
|
this.units.map((dot, i) => {
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import { floatTwo, fillArray } from '../utils/helpers';
|
import { floatTwo, fillArray } from '../utils/helpers';
|
||||||
import { DEFAULT_AXIS_CHART_TYPE, AXIS_DATASET_CHART_TYPES } from '../utils/constants';
|
import { DEFAULT_AXIS_CHART_TYPE, AXIS_DATASET_CHART_TYPES, DEFAULT_CHAR_WIDTH } from '../utils/constants';
|
||||||
|
|
||||||
export function dataPrep(data, type) {
|
export function dataPrep(data, type) {
|
||||||
data.labels = data.labels || [];
|
data.labels = data.labels || [];
|
||||||
@ -72,20 +72,53 @@ export function zeroDataPrep(realData) {
|
|||||||
chartType: d.chartType
|
chartType: d.chartType
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
yRegions: [
|
};
|
||||||
|
|
||||||
|
if(realData.yMarkers) {
|
||||||
|
zeroData.yMarkers = [
|
||||||
|
{
|
||||||
|
value: 0,
|
||||||
|
label: ''
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
if(realData.yRegions) {
|
||||||
|
zeroData.yRegions = [
|
||||||
{
|
{
|
||||||
start: 0,
|
start: 0,
|
||||||
end: 0,
|
end: 0,
|
||||||
label: ''
|
label: ''
|
||||||
}
|
}
|
||||||
],
|
];
|
||||||
yMarkers: [
|
}
|
||||||
{
|
|
||||||
value: 0,
|
|
||||||
label: ''
|
|
||||||
}
|
|
||||||
]
|
|
||||||
};
|
|
||||||
|
|
||||||
return zeroData;
|
return zeroData;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getShortenedLabels(chartWidth, labels=[], isSeries=true) {
|
||||||
|
let allowedSpace = chartWidth / labels.length;
|
||||||
|
let allowedLetters = allowedSpace / DEFAULT_CHAR_WIDTH;
|
||||||
|
|
||||||
|
let calcLabels = labels.map((label, i) => {
|
||||||
|
label += "";
|
||||||
|
if(label.length > allowedLetters) {
|
||||||
|
|
||||||
|
if(!isSeries) {
|
||||||
|
if(allowedLetters-3 > 0) {
|
||||||
|
label = label.slice(0, allowedLetters-3) + " ...";
|
||||||
|
} else {
|
||||||
|
label = label.slice(0, allowedLetters) + '..';
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
let multiple = Math.ceil(label.length/allowedLetters);
|
||||||
|
if(i % multiple !== 0) {
|
||||||
|
label = "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return label;
|
||||||
|
});
|
||||||
|
|
||||||
|
return calcLabels;
|
||||||
}
|
}
|
||||||
@ -14,4 +14,6 @@ export const BAR_CHART_SPACE_RATIO = 0.5;
|
|||||||
export const MIN_BAR_PERCENT_HEIGHT = 0.01;
|
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 = 8;
|
||||||
@ -24,24 +24,3 @@ export function equilizeNoOfElements(array1, array2,
|
|||||||
}
|
}
|
||||||
return [array1, array2];
|
return [array1, array2];
|
||||||
}
|
}
|
||||||
|
|
||||||
// let char_width = 8;
|
|
||||||
// let allowed_space = avgUnitWidth * 1.5;
|
|
||||||
// let allowed_letters = allowed_space / 8;
|
|
||||||
|
|
||||||
// return values.map((value, i) => {
|
|
||||||
// let space_taken = getStringWidth(value, char_width) + 2;
|
|
||||||
// if(space_taken > allowed_space) {
|
|
||||||
// if(isSeries) {
|
|
||||||
// // Skip some axis lines if X axis is a series
|
|
||||||
// let skips = 1;
|
|
||||||
// while((space_taken/skips)*2 > allowed_space) {
|
|
||||||
// skips++;
|
|
||||||
// }
|
|
||||||
// if(i % skips !== 0) {
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
// } else {
|
|
||||||
// value = value.slice(0, allowed_letters-3) + " ...";
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user