diff --git a/packages/web/src/charts/ChartEditor.js b/packages/web/src/charts/ChartEditor.js index 4507f273c..ca67a482e 100644 --- a/packages/web/src/charts/ChartEditor.js +++ b/packages/web/src/charts/ChartEditor.js @@ -71,7 +71,7 @@ export default function ChartEditor({ data, config, setConfig, sql, conid, datab if (config.labelColumn && sql && conid && database) { handleLoadData(); } - }, [config, sql, conid, database]); + }, [config, sql, conid, database, availableColumnNames]); return ( @@ -90,12 +90,17 @@ export default function ChartEditor({ data, config, setConfig, sql, conid, datab */} - + + + + + + diff --git a/packages/web/src/charts/DataChart.js b/packages/web/src/charts/DataChart.js index 4ee551088..217fe75fb 100644 --- a/packages/web/src/charts/DataChart.js +++ b/packages/web/src/charts/DataChart.js @@ -1,9 +1,11 @@ import React from 'react'; +import _ from 'lodash'; import Chart from 'react-chartjs-2'; import randomcolor from 'randomcolor'; import styled from 'styled-components'; import useDimensions from '../utility/useDimensions'; import { useForm } from '../utility/FormProvider'; +import { saturateByTenth } from '../theme/colorUtil'; const ChartWrapper = styled.div` flex: 1; @@ -13,18 +15,29 @@ const ChartWrapper = styled.div` function createChartData(freeData, labelColumn, dataColumns, colorSeed, chartType) { if (!freeData || !labelColumn || !dataColumns || dataColumns.length == 0) return {}; const colors = randomcolor({ - count: freeData.rows.length, + count: _.max([freeData.rows.length, dataColumns.length, 1]), seed: colorSeed, }); + let backgroundColor = null; + let borderColor = null; const res = { labels: freeData.rows.map((x) => x[labelColumn]), - datasets: dataColumns.map((dataColumn) => ({ - label: dataColumn, - data: freeData.rows.map((row) => row[dataColumn]), - backgroundColor: chartType != 'line' ? colors : null, - borderColor: chartType == 'line' ? colors : null, - borderWidth: 1, - })), + datasets: dataColumns.map((dataColumn, columnIndex) => { + if (chartType == 'line' || chartType == 'bar') { + backgroundColor = colors[columnIndex]; + borderColor = saturateByTenth(backgroundColor); + } else { + backgroundColor = colors; + } + + return { + label: dataColumn, + data: freeData.rows.map((row) => row[dataColumn]), + backgroundColor, + borderColor, + borderWidth: 1, + }; + }), }; return res; diff --git a/packages/web/src/charts/chartDataLoader.ts b/packages/web/src/charts/chartDataLoader.ts index 07b8a351f..997f3d4f7 100644 --- a/packages/web/src/charts/chartDataLoader.ts +++ b/packages/web/src/charts/chartDataLoader.ts @@ -1,6 +1,7 @@ import { dumpSqlSelect, Select } from 'dbgate-sqltree'; import { EngineDriver } from 'dbgate-types'; import axios from '../utility/axios'; +import _ from 'lodash'; import { extractDataColumns } from './DataChart'; export async function loadChartStructure(driver: EngineDriver, conid, database, sql) { @@ -22,24 +23,11 @@ export async function loadChartStructure(driver: EngineDriver, conid, database, export async function loadChartData(driver: EngineDriver, conid, database, sql, config) { const dataColumns = extractDataColumns(config); - const { labelColumn } = config; + const { labelColumn, truncateFrom, truncateLimit } = config; if (!labelColumn || !dataColumns || dataColumns.length == 0) return null; const select: Select = { commandType: 'select', - // columns:[ - // { - // exprType:'call', - // func:'SUM', - // args: [ - // { - // exprType: 'column', - // columnName, - // source: { alias: 'subq' }, - // } - // ] - // } - // ], columns: [ { @@ -62,7 +50,7 @@ export async function loadChartData(driver: EngineDriver, conid, database, sql, alias: columnName, })), ], - topRecords: 500, + topRecords: truncateLimit || 100, from: { subQueryString: sql, alias: 'subq', @@ -74,10 +62,24 @@ export async function loadChartData(driver: EngineDriver, conid, database, sql, columnName: labelColumn, }, ], + orderBy: [ + { + exprType: 'column', + source: { alias: 'subq' }, + columnName: labelColumn, + direction: truncateFrom == 'end' ? 'DESC' : 'ASC', + }, + ], }; const dmp = driver.createDumper(); dumpSqlSelect(dmp, select); const resp = await axios.post('database-connections/query-data', { conid, database, sql: dmp.s }); + if (truncateFrom == 'end' && resp.data.rows) { + return { + ...resp.data, + rows: _.reverse([...resp.data.rows]), + }; + } return resp.data; }