Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: chart bg colors and title styles from properties and theme #1183

Merged
merged 13 commits into from
Mar 28, 2023
19 changes: 14 additions & 5 deletions apis/nucleus/src/components/Cell.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import useLayout, { useAppLayout } from '../hooks/useLayout';
import InstanceContext from '../contexts/InstanceContext';
import useObjectSelections from '../hooks/useObjectSelections';
import eventmixin from '../selections/event-mixin';
import { resolveBgColor, resolveBgImage } from '../utils/background-props';
import { resolveBgColor, resolveBgImage, resolveTextStyle } from '../utils/background-props';

/**
* @interface
Expand Down Expand Up @@ -303,6 +303,7 @@ const Cell = forwardRef(
const hoveringDebouncer = useRef({ enter: null, leave: null });
const [bgColor, setBgColor] = useState(undefined);
const [bgImage, setBgImage] = useState(undefined); // {url: "", size: "", pos: ""}
const [titleStyles, setTitleStyles] = useState(undefined);

const focusHandler = useRef({
focusToolbarButton(last) {
Expand All @@ -316,9 +317,16 @@ const Cell = forwardRef(
}, []);

useEffect(() => {
const bgComp = layout?.components ? layout.components.find((comp) => comp.key === 'general') : null;
setBgColor(resolveBgColor(bgComp, halo.public.theme));
setBgImage(resolveBgImage(bgComp, halo.app));
if (layout && halo.public.theme) {
const bgComp = layout.components ? layout.components.find((comp) => comp.key === 'general') : null;
setTitleStyles({
main: resolveTextStyle(bgComp, 'main', halo.public.theme, layout.visualization),
footer: resolveTextStyle(bgComp, 'footer', halo.public.theme, layout.visualization),
subTitle: resolveTextStyle(bgComp, 'subTitle', halo.public.theme, layout.visualization),
});
setBgColor(resolveBgColor(bgComp, halo.public.theme, layout.visualization));
setBgImage(resolveBgImage(bgComp, halo.app));
}
}, [layout, halo.public.theme, halo.app, themeName]);

focusHandler.current.blurCallback = (resetFocus) => {
Expand Down Expand Up @@ -527,6 +535,7 @@ const Cell = forwardRef(
anchorEl={cellNode}
hovering={hovering}
focusHandler={focusHandler.current}
titleStyles={titleStyles}
>
 
</Header>
Expand All @@ -543,7 +552,7 @@ const Cell = forwardRef(
>
{Content}
</Grid>
<Footer layout={layout} />
<Footer layout={layout} titleStyles={titleStyles} />
</Grid>
{state.longRunningQuery && <LongRunningQuery canCancel={canCancel} canRetry={canRetry} api={longrunning} />}
</Paper>
Expand Down
4 changes: 2 additions & 2 deletions apis/nucleus/src/components/Footer.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,11 @@ const CellFooter = {
className: 'njs-cell-footer',
};

function Footer({ layout }) {
function Footer({ layout, titleStyles = {} }) {
return layout && layout.showTitles && layout.footnote ? (
<StyledGrid container>
<Grid item className={classes.itemStyle}>
<Typography noWrap variant="body2" className={CellFooter.className}>
<Typography noWrap variant="body2" className={CellFooter.className} style={titleStyles.footer}>
{layout.footnote}
</Typography>
</Grid>
Expand Down
6 changes: 3 additions & 3 deletions apis/nucleus/src/components/Header.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ const CellSubTitle = {
className: 'njs-cell-sub-title',
};

function Header({ layout, sn, anchorEl, hovering, focusHandler }) {
function Header({ layout, sn, anchorEl, hovering, focusHandler, titleStyles = {} }) {
const showTitle = layout.showTitles && !!layout.title;
const showSubtitle = layout.showTitles && !!layout.subtitle;
const showInSelectionActions = layout.qSelectionInfo && layout.qSelectionInfo.qInSelections;
Expand Down Expand Up @@ -97,12 +97,12 @@ function Header({ layout, sn, anchorEl, hovering, focusHandler }) {
<Grid item zeroMinWidth xs>
<Grid container wrap="nowrap" direction="column">
{showTitle && (
<Typography variant="h6" noWrap className={CellTitle.className}>
<Typography variant="h6" noWrap className={CellTitle.className} style={titleStyles.main}>
{layout.title}
</Typography>
)}
{showSubtitle && (
<Typography variant="body2" noWrap className={CellSubTitle.className}>
<Typography variant="body2" noWrap className={CellSubTitle.className} style={titleStyles.subTitle}>
{layout.subtitle}
</Typography>
)}
Expand Down
79 changes: 78 additions & 1 deletion apis/nucleus/src/utils/__tests__/background-props.test.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import theme from '@nebula.js/theme';
import { resolveBgColor, resolveBgImage } from '../background-props';
import { resolveBgColor, resolveBgImage, resolveTextStyle } from '../background-props';

describe('Background property resolver', () => {
let bgCompLayout;
Expand Down Expand Up @@ -35,6 +35,10 @@ describe('Background property resolver', () => {
};
});

test('should resolve background color to empty', () => {
const color = resolveBgColor({});
expect(color).toBeUndefined();
});
test('should resolve background color by expression', () => {
const color = resolveBgColor(bgCompLayout, t);
expect(color).toBe('rgb(255, 0, 0)');
Expand All @@ -55,4 +59,77 @@ describe('Background property resolver', () => {
expect(url).toBe('http://example.com/media/Tulips.jpg');
expect(size).toBe('contain');
});
test('should resolve background color by theme', () => {
const color = resolveBgColor({}, t, 'peoplechart');
expect(color).toBe('transparent');
});

test('should resolve background color by custom theme', () => {
const color = resolveBgColor(
{},
{
getStyle: (obj, path, attr) => {
if (obj === 'object.gantt' && path === '' && attr === 'backgroundColor') {
return '#ff00ff';
}
return undefined;
},
},
'gantt'
);
expect(color).toBe('#ff00ff');
});

test('should resolve text style by props', () => {
const prop = {
title: {
main: {
color: { color: 'red' },
fontFamily: 'familiiii',
fontStyle: ['underline', 'italic'],
},
},
};
const style = resolveTextStyle(prop, 'main', t, 'peoplechart');
expect(style).toEqual({
color: 'red',
fontFamily: 'familiiii',
fontWeight: 'normal',
fontStyle: 'italic',
textDecoration: 'underline',
});
});

test('should resolve text style by theme', () => {
const prop = {
title: {
footer: {
color: { color: 'red' },
fontStyle: '',
},
},
};
const style = resolveTextStyle(
prop,
'footer',
{
getStyle: (obj, path, attr) => {
if (obj === 'object.peoplechart' && path === 'title.footer' && attr === 'fontFamily') {
return 'a font';
}
return 'wrong';
},
getColorPickerColor: (color) => color.color,
},
'peoplechart'
);

expect(style).toEqual({
color: 'red',
fontFamily: 'a font',
fontWeight: 'normal',
fontStyle: 'normal',
textDecoration: 'initial',
});
});
});
36 changes: 32 additions & 4 deletions apis/nucleus/src/utils/background-props.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ function resolveImageUrl(app, relativeUrl) {
return relativeUrl ? getSenseServerUrl(app) + relativeUrl : undefined;
}

export const resolveBgImage = (bgComp, app) => {
export function resolveBgImage(bgComp, app) {
const bgImageDef = bgComp?.bgImage;

if (bgImageDef) {
Expand All @@ -77,15 +77,43 @@ export const resolveBgImage = (bgComp, app) => {
return url ? { url, pos, size } : undefined;
}
return undefined;
};
}

export const resolveBgColor = (bgComp, theme) => {
export function resolveBgColor(bgComp, theme, objectType) {
const bgColor = bgComp?.bgColor;
if (bgColor && theme) {
if (bgColor.useExpression) {
return theme.validateColor(bgColor.colorExpression);
}
return bgColor.color && bgColor.color.color !== 'none' ? theme.getColorPickerColor(bgColor.color, true) : undefined;
}
if (theme && objectType) {
return theme.getStyle(`object.${objectType}`, '', 'backgroundColor');
}
if (theme) {
return theme.getStyle('', '', 'backgroundColor');
}
return undefined;
};
}
function unfurlFontStyle(fontStyle, target) {
if (fontStyle && Array.isArray(fontStyle)) {
return fontStyle;
}
return target === 'main' ? ['bold'] : [];
}

export function resolveTextStyle(textComp, target, theme, objectType) {
const textProps = textComp?.title?.[target] || {};
const fontStyle = unfurlFontStyle(textProps.fontStyle, target);

return {
fontFamily: textProps.fontFamily || theme.getStyle(`object.${objectType}`, `title.${target}`, 'fontFamily'),
color:
textProps.color && textProps.color.color !== 'none'
? theme.getColorPickerColor(textProps.color, true)
: theme.getStyle(`object.${objectType}`, target, 'color'),
fontWeight: fontStyle.includes('bold') ? 'bold' : 'normal',
fontStyle: fontStyle.includes('italic') ? 'italic' : 'normal',
textDecoration: fontStyle.includes('underline') ? 'underline' : 'initial',
};
}
26 changes: 21 additions & 5 deletions test/rendering/sheet/configured.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ const pie = {
component: {
mounted(el) {
// eslint-disable-next-line
el.innerHTML = '<div id="pie" style="background: aliceblue; height:100%; width:100%;">Hello pie</div>';
el.innerHTML = '<div id="pie" style="height:100%; width:100%;">Hello pie</div>';
},
},
};
Expand All @@ -18,10 +18,9 @@ const bar = function (env) {
component: {
mounted(el) {
// eslint-disable-next-line
el.innerHTML = `<div id="bar" style="font-size: 64px; background: tan; height:100%; width:100%;">${env.translator.get(
'hello',
['bar']
)}</div>`;
el.innerHTML = `<div id="bar" style="font-size: 64px; height:100%; width:100%;">${env.translator.get('hello', [
'bar',
])}</div>`;
},
},
};
Expand All @@ -31,7 +30,24 @@ const bar = function (env) {
const configured = stardust.embed.createConfiguration({
context: {
language: 'sv-SE',
theme: 'bla',
},
themes: [
{
id: 'bla',
load: () =>
Promise.resolve({
_inherit: false,
color: '#fff',
object: {
backgroundColor: '#ff00ff',
},
backgroundColor: '#eeeeee',
fontSize: '20px',
fontFamily: 'Arial',
}),
},
],
types: [
{
name: 'piechart',
Expand Down
26 changes: 26 additions & 0 deletions test/rendering/sheet/sheet-data.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,32 @@ window.getFuncs = function getFuncs() {
qId: 'bar',
},
visualization: 'barchart',
title: 'This is the title of the barchart',
subtitle: 'here is the subtitle',
footnote: 'and here is a footnote',
showTitles: true,
components: [
{
key: 'general',
title: {
main: {
color: { color: 'green' },
fontFamily: 'Verdana',
},
subTitle: {
color: { color: 'blue' },
fontStyle: ['bold', 'italic', 'underline'],
},
footer: {
color: { color: 'red' },
fontFamily: 'Lucida Console, monospace',
},
},
bgColor: {
color: { color: '#00ff00' },
},
},
],
};
},
getPieLayout: () => {
Expand Down
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.