mirror of
https://github.com/apache/superset.git
synced 2024-09-17 11:09:47 -04:00
[SIP-5] Refactor and update heatmap (#5704)
* Extract slice and formData * Define data shape * update style * organize imports * fix heatmap axis labels * add new line * adjust indent
This commit is contained in:
parent
4ae08c2c64
commit
fcf2c756c0
@ -6,20 +6,24 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.heatmap .axis text {
|
.heatmap .axis text {
|
||||||
font: 10px sans-serif;
|
font: 12px sans-serif;
|
||||||
text-rendering: optimizeLegibility;
|
text-rendering: optimizeLegibility;
|
||||||
|
fill: #555;
|
||||||
|
}
|
||||||
|
|
||||||
|
.heatmap .background-rect {
|
||||||
|
stroke: #ddd;
|
||||||
|
fill-opacity: 0;
|
||||||
|
pointer-events: all;
|
||||||
}
|
}
|
||||||
|
|
||||||
.heatmap .axis path,
|
.heatmap .axis path,
|
||||||
.heatmap .axis line {
|
.heatmap .axis line {
|
||||||
fill: none;
|
fill: none;
|
||||||
stroke: #000;
|
stroke: #ddd;
|
||||||
shape-rendering: crispEdges;
|
shape-rendering: crispEdges;
|
||||||
}
|
}
|
||||||
|
|
||||||
.heatmap svg {
|
|
||||||
}
|
|
||||||
|
|
||||||
.heatmap canvas, .heatmap img {
|
.heatmap canvas, .heatmap img {
|
||||||
image-rendering: optimizeSpeed; /* Older versions of FF */
|
image-rendering: optimizeSpeed; /* Older versions of FF */
|
||||||
image-rendering: -moz-crisp-edges; /* FF 6.0+ */
|
image-rendering: -moz-crisp-edges; /* FF 6.0+ */
|
||||||
@ -41,3 +45,8 @@
|
|||||||
.heatmap .legendCells .cell:last-child text {
|
.heatmap .legendCells .cell:last-child text {
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.dashboard .heatmap .axis text {
|
||||||
|
font-size: 10px;
|
||||||
|
opacity: .75;
|
||||||
|
}
|
||||||
|
@ -1,21 +1,85 @@
|
|||||||
import d3 from 'd3';
|
import d3 from 'd3';
|
||||||
// eslint-disable-next-line no-unused-vars
|
import PropTypes from 'prop-types';
|
||||||
import d3legend from 'd3-svg-legend';
|
import 'd3-svg-legend';
|
||||||
import d3tip from 'd3-tip';
|
import d3tip from 'd3-tip';
|
||||||
|
|
||||||
import { colorScalerFactory } from '../modules/colors';
|
import { colorScalerFactory } from '../modules/colors';
|
||||||
import '../../stylesheets/d3tip.css';
|
import '../../stylesheets/d3tip.css';
|
||||||
import './heatmap.css';
|
import './heatmap.css';
|
||||||
|
|
||||||
|
const propTypes = {
|
||||||
|
data: PropTypes.shape({
|
||||||
|
records: PropTypes.arrayOf(PropTypes.shape({
|
||||||
|
x: PropTypes.string,
|
||||||
|
y: PropTypes.string,
|
||||||
|
v: PropTypes.number,
|
||||||
|
perc: PropTypes.number,
|
||||||
|
rank: PropTypes.number,
|
||||||
|
})),
|
||||||
|
extents: PropTypes.arrayOf(PropTypes.number),
|
||||||
|
}),
|
||||||
|
width: PropTypes.number,
|
||||||
|
height: PropTypes.number,
|
||||||
|
bottomMargin: PropTypes.oneOfType([
|
||||||
|
PropTypes.string,
|
||||||
|
PropTypes.number,
|
||||||
|
]),
|
||||||
|
colorScheme: PropTypes.string,
|
||||||
|
columnX: PropTypes.string,
|
||||||
|
columnY: PropTypes.string,
|
||||||
|
leftMargin: PropTypes.oneOfType([
|
||||||
|
PropTypes.string,
|
||||||
|
PropTypes.number,
|
||||||
|
]),
|
||||||
|
metric: PropTypes.oneOfType([
|
||||||
|
PropTypes.string,
|
||||||
|
PropTypes.object,
|
||||||
|
]),
|
||||||
|
normalized: PropTypes.bool,
|
||||||
|
numberFormat: PropTypes.string,
|
||||||
|
showLegend: PropTypes.bool,
|
||||||
|
showPercentage: PropTypes.bool,
|
||||||
|
showValues: PropTypes.bool,
|
||||||
|
sortXAxis: PropTypes.string,
|
||||||
|
sortYAxis: PropTypes.string,
|
||||||
|
xScaleInterval: PropTypes.number,
|
||||||
|
yScaleInterval: PropTypes.number,
|
||||||
|
yAxisBounds: PropTypes.arrayOf(PropTypes.number),
|
||||||
|
};
|
||||||
|
|
||||||
function cmp(a, b) {
|
function cmp(a, b) {
|
||||||
return a > b ? 1 : -1;
|
return a > b ? 1 : -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Inspired from http://bl.ocks.org/mbostock/3074470
|
// Inspired from http://bl.ocks.org/mbostock/3074470
|
||||||
// https://jsfiddle.net/cyril123/h0reyumq/
|
// https://jsfiddle.net/cyril123/h0reyumq/
|
||||||
function heatmapVis(slice, payload) {
|
function Heatmap(element, props) {
|
||||||
const data = payload.data.records;
|
PropTypes.checkPropTypes(propTypes, props, 'prop', 'Heatmap');
|
||||||
const fd = slice.formData;
|
|
||||||
|
const {
|
||||||
|
data,
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
bottomMargin,
|
||||||
|
canvasImageRendering,
|
||||||
|
colorScheme,
|
||||||
|
columnX,
|
||||||
|
columnY,
|
||||||
|
leftMargin,
|
||||||
|
metric,
|
||||||
|
normalized,
|
||||||
|
numberFormat,
|
||||||
|
showLegend,
|
||||||
|
showPercentage,
|
||||||
|
showValues,
|
||||||
|
sortXAxis,
|
||||||
|
sortYAxis,
|
||||||
|
xScaleInterval,
|
||||||
|
yScaleInterval,
|
||||||
|
yAxisBounds,
|
||||||
|
} = props;
|
||||||
|
|
||||||
|
const { records, extents } = data;
|
||||||
|
|
||||||
const margin = {
|
const margin = {
|
||||||
top: 10,
|
top: 10,
|
||||||
@ -23,7 +87,7 @@ function heatmapVis(slice, payload) {
|
|||||||
bottom: 35,
|
bottom: 35,
|
||||||
left: 35,
|
left: 35,
|
||||||
};
|
};
|
||||||
const valueFormatter = d3.format(fd.y_axis_format);
|
const valueFormatter = d3.format(numberFormat);
|
||||||
|
|
||||||
// Dynamically adjusts based on max x / y category lengths
|
// Dynamically adjusts based on max x / y category lengths
|
||||||
function adjustMargins() {
|
function adjustMargins() {
|
||||||
@ -31,33 +95,32 @@ function heatmapVis(slice, payload) {
|
|||||||
const pixelsPerCharY = 6; // approx, depends on font size
|
const pixelsPerCharY = 6; // approx, depends on font size
|
||||||
let longestX = 1;
|
let longestX = 1;
|
||||||
let longestY = 1;
|
let longestY = 1;
|
||||||
let datum;
|
|
||||||
|
|
||||||
for (let i = 0; i < data.length; i++) {
|
for (let i = 0; i < records.length; i++) {
|
||||||
datum = data[i];
|
const datum = records[i];
|
||||||
longestX = Math.max(longestX, datum.x.toString().length || 1);
|
longestX = Math.max(longestX, datum.x.toString().length || 1);
|
||||||
longestY = Math.max(longestY, datum.y.toString().length || 1);
|
longestY = Math.max(longestY, datum.y.toString().length || 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fd.left_margin === 'auto') {
|
if (leftMargin === 'auto') {
|
||||||
margin.left = Math.ceil(Math.max(margin.left, pixelsPerCharY * longestY));
|
margin.left = Math.ceil(Math.max(margin.left, pixelsPerCharY * longestY));
|
||||||
if (fd.show_legend) {
|
|
||||||
margin.left += 40;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
margin.left = fd.left_margin;
|
margin.left = leftMargin;
|
||||||
}
|
}
|
||||||
if (fd.bottom_margin === 'auto') {
|
|
||||||
margin.bottom = Math.ceil(Math.max(margin.bottom, pixelsPerCharX * longestX));
|
if (showLegend) {
|
||||||
} else {
|
margin.right += 40;
|
||||||
margin.bottom = fd.bottom_margin;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
margin.bottom = (bottomMargin === 'auto')
|
||||||
|
? Math.ceil(Math.max(margin.bottom, pixelsPerCharX * longestX))
|
||||||
|
: bottomMargin;
|
||||||
}
|
}
|
||||||
|
|
||||||
function ordScale(k, rangeBands, sortMethod) {
|
function ordScale(k, rangeBands, sortMethod) {
|
||||||
let domain = {};
|
let domain = {};
|
||||||
const actualKeys = {}; // hack to preserve type of keys when number
|
const actualKeys = {}; // hack to preserve type of keys when number
|
||||||
data.forEach((d) => {
|
records.forEach((d) => {
|
||||||
domain[d[k]] = (domain[d[k]] || 0) + d.v;
|
domain[d[k]] = (domain[d[k]] || 0) + d.v;
|
||||||
actualKeys[d[k]] = d[k];
|
actualKeys[d[k]] = d[k];
|
||||||
});
|
});
|
||||||
@ -83,28 +146,27 @@ function heatmapVis(slice, payload) {
|
|||||||
return d3.scale.ordinal().domain(domain).range(d3.range(domain.length));
|
return d3.scale.ordinal().domain(domain).range(d3.range(domain.length));
|
||||||
}
|
}
|
||||||
|
|
||||||
slice.container.html('');
|
// eslint-disable-next-line no-param-reassign
|
||||||
|
element.innerHTML = '';
|
||||||
const matrix = {};
|
const matrix = {};
|
||||||
|
|
||||||
adjustMargins();
|
adjustMargins();
|
||||||
|
|
||||||
const width = slice.width();
|
|
||||||
const height = slice.height();
|
|
||||||
const hmWidth = width - (margin.left + margin.right);
|
const hmWidth = width - (margin.left + margin.right);
|
||||||
const hmHeight = height - (margin.bottom + margin.top);
|
const hmHeight = height - (margin.bottom + margin.top);
|
||||||
const fp = d3.format('.2%');
|
const fp = d3.format('.2%');
|
||||||
|
|
||||||
const xScale = ordScale('x', null, fd.sort_x_axis);
|
const xScale = ordScale('x', null, sortXAxis);
|
||||||
const yScale = ordScale('y', null, fd.sort_y_axis);
|
const yScale = ordScale('y', null, sortYAxis);
|
||||||
const xRbScale = ordScale('x', [0, hmWidth], fd.sort_x_axis);
|
const xRbScale = ordScale('x', [0, hmWidth], sortXAxis);
|
||||||
const yRbScale = ordScale('y', [hmHeight, 0], fd.sort_y_axis);
|
const yRbScale = ordScale('y', [hmHeight, 0], sortYAxis);
|
||||||
const X = 0;
|
const X = 0;
|
||||||
const Y = 1;
|
const Y = 1;
|
||||||
const heatmapDim = [xRbScale.domain().length, yRbScale.domain().length];
|
const heatmapDim = [xRbScale.domain().length, yRbScale.domain().length];
|
||||||
|
|
||||||
const minBound = fd.y_axis_bounds[0] || 0;
|
const minBound = yAxisBounds[0] || 0;
|
||||||
const maxBound = fd.y_axis_bounds[1] || 1;
|
const maxBound = yAxisBounds[1] || 1;
|
||||||
const colorScaler = colorScalerFactory(fd.linear_color_scheme, null, null, [minBound, maxBound]);
|
const colorScaler = colorScalerFactory(colorScheme, null, null, [minBound, maxBound]);
|
||||||
|
|
||||||
const scale = [
|
const scale = [
|
||||||
d3.scale.linear()
|
d3.scale.linear()
|
||||||
@ -115,14 +177,14 @@ function heatmapVis(slice, payload) {
|
|||||||
.range([0, hmHeight]),
|
.range([0, hmHeight]),
|
||||||
];
|
];
|
||||||
|
|
||||||
const container = d3.select(slice.selector);
|
const container = d3.select(element);
|
||||||
|
|
||||||
const canvas = container.append('canvas')
|
const canvas = container.append('canvas')
|
||||||
.attr('width', heatmapDim[X])
|
.attr('width', heatmapDim[X])
|
||||||
.attr('height', heatmapDim[Y])
|
.attr('height', heatmapDim[Y])
|
||||||
.style('width', hmWidth + 'px')
|
.style('width', hmWidth + 'px')
|
||||||
.style('height', hmHeight + 'px')
|
.style('height', hmHeight + 'px')
|
||||||
.style('image-rendering', fd.canvas_image_rendering)
|
.style('image-rendering', canvasImageRendering)
|
||||||
.style('left', margin.left + 'px')
|
.style('left', margin.left + 'px')
|
||||||
.style('top', margin.top + 'px')
|
.style('top', margin.top + 'px')
|
||||||
.style('position', 'absolute');
|
.style('position', 'absolute');
|
||||||
@ -132,9 +194,9 @@ function heatmapVis(slice, payload) {
|
|||||||
.attr('height', height)
|
.attr('height', height)
|
||||||
.style('position', 'relative');
|
.style('position', 'relative');
|
||||||
|
|
||||||
if (fd.show_values) {
|
if (showValues) {
|
||||||
const cells = svg.selectAll('rect')
|
const cells = svg.selectAll('rect')
|
||||||
.data(data)
|
.data(records)
|
||||||
.enter()
|
.enter()
|
||||||
.append('g')
|
.append('g')
|
||||||
.attr('transform', `translate(${margin.left}, ${margin.top})`);
|
.attr('transform', `translate(${margin.left}, ${margin.top})`);
|
||||||
@ -147,21 +209,21 @@ function heatmapVis(slice, payload) {
|
|||||||
.attr('dy', '.35em')
|
.attr('dy', '.35em')
|
||||||
.text(d => valueFormatter(d.v))
|
.text(d => valueFormatter(d.v))
|
||||||
.attr('font-size', Math.min(yRbScale.rangeBand(), xRbScale.rangeBand()) / 3 + 'px')
|
.attr('font-size', Math.min(yRbScale.rangeBand(), xRbScale.rangeBand()) / 3 + 'px')
|
||||||
.attr('fill', d => d.v >= payload.data.extents[1] / 2 ? 'white' : 'black');
|
.attr('fill', d => d.v >= extents[1] / 2 ? 'white' : 'black');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fd.show_legend) {
|
if (showLegend) {
|
||||||
const colorLegend = d3.legend.color()
|
const colorLegend = d3.legend.color()
|
||||||
.labelFormat(valueFormatter)
|
.labelFormat(valueFormatter)
|
||||||
.scale(colorScaler)
|
.scale(colorScaler)
|
||||||
.shapePadding(0)
|
.shapePadding(0)
|
||||||
.cells(50)
|
.cells(10)
|
||||||
.shapeWidth(10)
|
.shapeWidth(10)
|
||||||
.shapeHeight(3)
|
.shapeHeight(10)
|
||||||
.labelOffset(2);
|
.labelOffset(3);
|
||||||
|
|
||||||
svg.append('g')
|
svg.append('g')
|
||||||
.attr('transform', 'translate(10, 5)')
|
.attr('transform', `translate(${width - 40}, ${margin.top})`)
|
||||||
.call(colorLegend);
|
.call(colorLegend);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -177,14 +239,14 @@ function heatmapVis(slice, payload) {
|
|||||||
const k = d3.mouse(this);
|
const k = d3.mouse(this);
|
||||||
const m = Math.floor(scale[0].invert(k[0]));
|
const m = Math.floor(scale[0].invert(k[0]));
|
||||||
const n = Math.floor(scale[1].invert(k[1]));
|
const n = Math.floor(scale[1].invert(k[1]));
|
||||||
const metric = typeof fd.metric === 'object' ? fd.metric.label : fd.metric;
|
const metricLabel = typeof metric === 'object' ? metric.label : metric;
|
||||||
if (m in matrix && n in matrix[m]) {
|
if (m in matrix && n in matrix[m]) {
|
||||||
const obj = matrix[m][n];
|
const obj = matrix[m][n];
|
||||||
s += '<div><b>' + fd.all_columns_x + ': </b>' + obj.x + '<div>';
|
s += '<div><b>' + columnX + ': </b>' + obj.x + '<div>';
|
||||||
s += '<div><b>' + fd.all_columns_y + ': </b>' + obj.y + '<div>';
|
s += '<div><b>' + columnY + ': </b>' + obj.y + '<div>';
|
||||||
s += '<div><b>' + metric + ': </b>' + valueFormatter(obj.v) + '<div>';
|
s += '<div><b>' + metricLabel + ': </b>' + valueFormatter(obj.v) + '<div>';
|
||||||
if (fd.show_perc) {
|
if (showPercentage) {
|
||||||
s += '<div><b>%: </b>' + fp(fd.normalized ? obj.rank : obj.perc) + '<div>';
|
s += '<div><b>%: </b>' + fp(normalized ? obj.rank : obj.perc) + '<div>';
|
||||||
}
|
}
|
||||||
tip.style('display', null);
|
tip.style('display', null);
|
||||||
} else {
|
} else {
|
||||||
@ -198,11 +260,9 @@ function heatmapVis(slice, payload) {
|
|||||||
const rect = svg.append('g')
|
const rect = svg.append('g')
|
||||||
.attr('transform', `translate(${margin.left}, ${margin.top})`)
|
.attr('transform', `translate(${margin.left}, ${margin.top})`)
|
||||||
.append('rect')
|
.append('rect')
|
||||||
.attr('pointer-events', 'all')
|
.classed('background-rect', true)
|
||||||
.on('mousemove', tip.show)
|
.on('mousemove', tip.show)
|
||||||
.on('mouseout', tip.hide)
|
.on('mouseout', tip.hide)
|
||||||
.style('fill-opacity', 0)
|
|
||||||
.attr('stroke', 'black')
|
|
||||||
.attr('width', hmWidth)
|
.attr('width', hmWidth)
|
||||||
.attr('height', hmHeight);
|
.attr('height', hmHeight);
|
||||||
|
|
||||||
@ -210,17 +270,19 @@ function heatmapVis(slice, payload) {
|
|||||||
|
|
||||||
const xAxis = d3.svg.axis()
|
const xAxis = d3.svg.axis()
|
||||||
.scale(xRbScale)
|
.scale(xRbScale)
|
||||||
|
.outerTickSize(0)
|
||||||
.tickValues(xRbScale.domain().filter(
|
.tickValues(xRbScale.domain().filter(
|
||||||
function (d, i) {
|
function (d, i) {
|
||||||
return !(i % (parseInt(fd.xscale_interval, 10)));
|
return !(i % (xScaleInterval));
|
||||||
}))
|
}))
|
||||||
.orient('bottom');
|
.orient('bottom');
|
||||||
|
|
||||||
const yAxis = d3.svg.axis()
|
const yAxis = d3.svg.axis()
|
||||||
.scale(yRbScale)
|
.scale(yRbScale)
|
||||||
|
.outerTickSize(0)
|
||||||
.tickValues(yRbScale.domain().filter(
|
.tickValues(yRbScale.domain().filter(
|
||||||
function (d, i) {
|
function (d, i) {
|
||||||
return !(i % (parseInt(fd.yscale_interval, 10)));
|
return !(i % (yScaleInterval));
|
||||||
}))
|
}))
|
||||||
.orient('left');
|
.orient('left');
|
||||||
|
|
||||||
@ -229,6 +291,9 @@ function heatmapVis(slice, payload) {
|
|||||||
.attr('transform', 'translate(' + margin.left + ',' + (margin.top + hmHeight) + ')')
|
.attr('transform', 'translate(' + margin.left + ',' + (margin.top + hmHeight) + ')')
|
||||||
.call(xAxis)
|
.call(xAxis)
|
||||||
.selectAll('text')
|
.selectAll('text')
|
||||||
|
.attr('x', -4)
|
||||||
|
.attr('y', 10)
|
||||||
|
.attr('dy', '0.3em')
|
||||||
.style('text-anchor', 'end')
|
.style('text-anchor', 'end')
|
||||||
.attr('transform', 'rotate(-45)');
|
.attr('transform', 'rotate(-45)');
|
||||||
|
|
||||||
@ -237,7 +302,6 @@ function heatmapVis(slice, payload) {
|
|||||||
.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')')
|
.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')')
|
||||||
.call(yAxis);
|
.call(yAxis);
|
||||||
|
|
||||||
|
|
||||||
const context = canvas.node().getContext('2d');
|
const context = canvas.node().getContext('2d');
|
||||||
context.imageSmoothingEnabled = false;
|
context.imageSmoothingEnabled = false;
|
||||||
|
|
||||||
@ -246,8 +310,8 @@ function heatmapVis(slice, payload) {
|
|||||||
const imageObj = new Image();
|
const imageObj = new Image();
|
||||||
const image = context.createImageData(heatmapDim[0], heatmapDim[1]);
|
const image = context.createImageData(heatmapDim[0], heatmapDim[1]);
|
||||||
const pixs = {};
|
const pixs = {};
|
||||||
data.forEach((d) => {
|
records.forEach((d) => {
|
||||||
const c = d3.rgb(colorScaler(fd.normalized ? d.rank : d.perc));
|
const c = d3.rgb(colorScaler(normalized ? d.rank : d.perc));
|
||||||
const x = xScale(d.x);
|
const x = xScale(d.x);
|
||||||
const y = yScale(d.y);
|
const y = yScale(d.y);
|
||||||
pixs[x + (y * xScale.domain().length)] = c;
|
pixs[x + (y * xScale.domain().length)] = c;
|
||||||
@ -278,4 +342,53 @@ function heatmapVis(slice, payload) {
|
|||||||
createImageObj();
|
createImageObj();
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = heatmapVis;
|
Heatmap.propTypes = propTypes;
|
||||||
|
|
||||||
|
function adaptor(slice, payload) {
|
||||||
|
const { selector, formData } = slice;
|
||||||
|
const {
|
||||||
|
bottom_margin: bottomMargin,
|
||||||
|
canvas_image_rendering: canvasImageRendering,
|
||||||
|
all_columns_x: columnX,
|
||||||
|
all_columns_y: columnY,
|
||||||
|
linear_color_scheme: colorScheme,
|
||||||
|
left_margin: leftMargin,
|
||||||
|
metric,
|
||||||
|
normalized,
|
||||||
|
show_legend: showLegend,
|
||||||
|
show_perc: showPercentage,
|
||||||
|
show_values: showValues,
|
||||||
|
sort_x_axis: sortXAxis,
|
||||||
|
sort_y_axis: sortYAxis,
|
||||||
|
xscale_interval: xScaleInterval,
|
||||||
|
yscale_interval: yScaleInterval,
|
||||||
|
y_axis_bounds: yAxisBounds,
|
||||||
|
y_axis_format: numberFormat,
|
||||||
|
} = formData;
|
||||||
|
const element = document.querySelector(selector);
|
||||||
|
|
||||||
|
return Heatmap(element, {
|
||||||
|
data: payload.data,
|
||||||
|
width: slice.width(),
|
||||||
|
height: slice.height(),
|
||||||
|
bottomMargin,
|
||||||
|
canvasImageRendering,
|
||||||
|
colorScheme,
|
||||||
|
columnX,
|
||||||
|
columnY,
|
||||||
|
leftMargin,
|
||||||
|
metric,
|
||||||
|
normalized,
|
||||||
|
numberFormat,
|
||||||
|
showLegend,
|
||||||
|
showPercentage,
|
||||||
|
showValues,
|
||||||
|
sortXAxis,
|
||||||
|
sortYAxis,
|
||||||
|
xScaleInterval: parseInt(xScaleInterval, 10),
|
||||||
|
yScaleInterval: parseInt(yScaleInterval, 10),
|
||||||
|
yAxisBounds,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export default adaptor;
|
||||||
|
Loading…
Reference in New Issue
Block a user