Maintainer: Danijel Beljan
Q Table is one tool of the Q toolbox to create tables. Test it in the demo.
git clone git@github.com:nzzdev/Q-table.git
cd ./Q-table
nvm use
npm install
npm run build
Start the Q dev server:
npx @nzz/q-cli server
Run the Q tool (DEV Mode):
npm run start
The testing framework used in this repository is Code.
Run the tests:
npm run test
When changing or implementing...
- A
route
, it needs to be tested in thee2e-tests.js
file - Something on the frontend, it needs to be tested in the
dom-tests.js
file
We provide automatically built docker images. There are three options for deployment:
- Use the provided images
- Build your own docker images
- Deploy the service using another technology
- Deploy
nzzonline/q-table
to a docker environment
The tool structure follows the general structure of each Q tool. Further information can be found in Q server documentation - Developing tools.
Footnotes are a feature to display annotations in the table and the sources in the footer of the table. It uses the metaData
feature of Q-Editor. Footnotes with the same text will be merged together.
- The function
getFootnotes()
will filter and sort all footnotes fromitem.data.metaData
. Additional the data will be transitioned, that there will be listed only unique footnotes, with an array of coordinates, where the footnote will be placed. The function will always return an object, when not used the object will be empty. - Those footnotes will then be passed to the function
getTableData()
- Once the
tableData
is adjusted ingetTableData()
, there's a check if footnotes are set - If there are footnotes, they will be passed to the function
appendFootnoteAnnotationsToTableData()
along withtableData
andoptions
- In
appendFootnoteAnnotationsToTableData()
thefootnoteClass
will be calculated and determined if extra spacing is used or not - Before appending the footnotes to the
tableData
, the footnotes array will be flattened and prepared to ease to complexity. - This is the matrix how we apply spacing classes to the cell
- Because the title in the Card-Layout is already set by the
::before
pseudo element, it's not possible to apply the annotation with this selector as well. Therefore we have to add the unicode to the datasetdata-label
when the Card-Layout is set so we map the footnote annoation value to theunicode
. Important: The mapping of the value is from 1 to 9. - After applying the annotations to the
tableData
, the functionappendFootnoteAnnotationsToTableData()
should return an object like this:
[
[
{
type: "numeric",
value: "Rank",
classes: [],
footnote: {
value: 1,
unicode: "¹",
class: null,
},
},
],
[
{
type: "numeric",
value: "3",
classes: ["q-table-footnote-col-cardlayout-single"],
footnote: {
value: 2,
unicode: "²",
class: null,
},
},
],
];
This options allows to hide the header of each column. By default it's false
- If the options is used, the table-header won't be rendered
This option allows to show or hide the table search feature. The option is only available, when there are more than 16 rows in the table. Default value is false
.
Card-Layout is an option to display large tables well-arranged on mobile. There are 2 options to use it:
- Only show the Card-Layout in the mobile view
- Show the Card-Layout in every view
- The Card-Layout renderingInfoScript contains an
EventListener
on the eventresize
which calculates the current size of the graphic - When the graphic is smaller than
400px
, the renderingInfoScriptapplyCardLayoutClassFunction
adds the classq-table--card-layout
to thedataObject
and replaces all its styles - The column headers will then be hidden and each cell will display the
::before
:pseudo element containing its column header (e.g.Header1
)
- The
option-availability
route will check if there are at least 3 columns and check if at least one if them isnumeric
- Once the option will be shown, the
dynamic-schema
route will read allnumeric
columns and display them in the option - Important: The function
getMinibarContext()
will always return an object, when minibars aren't used the object is empty - The function
getMinibarContext()
uses a copy ofitem.data
since the data will be altered - If minibars will be used, the function
getMinibarData()
with the parametersdata
andminibarOptions
will be called - The function then calls
getMinibarNumbersWithType()
will set the type of the minibar and prepare the data to be calculated - The table can have 3 types:
positive
when there positive numbers only,negative
when there are negative numbers only ormixed
when the numbers are positive and negative numbers in the column - The cell can have 3 types:
positive
, when the cell contains a positive number,negative
when the cell contains a negative number orempty
when there's no content in the cell - The function
getMinibarValue()
then calculates the length of the minibar based on thetype
of the table and max-value of the selected column - Then the color of the minibars will be adjusted. By default the sophie-colors
s-viz-color-diverging-2-2
forpositive
ands-viz-color-diverging-2-1
fornegative
colors will be used. If the user has the rolepoweruser
, he can set the colors by himself. One way by theclassName
of the sophie-colors or thecolorCode
which are simple hex codes of colors - In the end the
getMinibarContext()
function will return an object like this:
{
values: [
{type:"empty", value:0},
{type:"negative", value:7.142857142857143},
{type:"positive", value:14.285714285714286},
],
type:"mixed",
barColor: {
positive:{className:"s-viz-color-diverging-2-2", colorCode:""},
negative:{className:"s-viz-color-diverging-2-1", colorCode:""}
}
}
- There are 3 different files for displaying minibars:
minibar-positive.html
,minibar-negative.html
andminibar-mixed.html
- Positive will display the
value
first and then theminibar
. Both as atd
-element - Negative will display the
minibar
first and then thevalue
. Both as atd
-element - Mixed will display the
value
and theminibar
inside thetd
as adiv
-element but in the same order as listed above - When resizing the graphic, the
EventLister
on the eventresize
implemented in thegetCardLayoutScript()
will be triggered - When the graphic is smaller than
400px
, the renderingInfoScriptrenderMinibarsFunction()
will be called inside theEventListener
listed above - The function
renderMinibarsFunction()
then loads the elements of the columnselectedColumn
andminibarColumn
which then will passed to the functionhandleMinibarsMinWidthFunctionName()
- The function
handleMinibarsMinWidthFunctionName()
then either removes or addsq-table-minibar-cell-mobile
orq-table-minibar--mixed-mobile
to the cell according to thetype
of the table which can be read out on the datasetdata-minibar
on each cell
This feature allows to select a column and colorize it. There are two types:
numerical
categorical
When selecting the numerical option, the numbers inside the column will be split in buckets. Depending on the bucketType
, the buckets will be calculated differently.
This option will be displayed with columns containing numerical values only, otherwise an error will be displayed.
The label allows to select between three options:
noLabel
(default)average
median
This value will then be displayed on the legend.
There are four different buckets and each of it comes with it's own properties:
- Ckmeans,
numberBuckets
- Quantile,
numberBuckets
- Equal,
numberBuckets
- Custom, ,
numberBuckets
andcustomBuckets
The scale can be chosen from between two types:
sequential
diverging
When having the expert-role added, the user is able to adjust the colors of the buckets.
When selecting the diverging
-option, the options from which border it will be spilt are dynamically listed too.
When selecting the categorical option, the values of the column will be mapped to categories. The categories will then be colored according to the color-scale.
The way the legend will be displayed is depending on the colorColumnType
. When using numerical-option, the range of the values will be calculated by buckets, which can be changed on the options. The lowest and highest value will be displayed on the left and right end of the legend.
Depending on the selected bucketing method, the legend will be displayed differently. The array passed to render the legend looks as following:
buckets = [
{
from, // lowest bucket border value
to, // highest bucket border value
color, // color depending on the selected color schema
},
]
If there's the case that one of the bucket has just a single value in it, the single bucket will be displayed below with a seperate icon. If there is an entry without a value, there will be an extra icon too, for displaying 'no data'.
The categorical legend will simply map the values to their colors.
- Just like the feature minibars, the
option-availability
route will check if there are at least 3 columns to display this option\ - If the option is selected, through the
dynamic-schema
route, depending on whichcolorColumnType
is selected, will display specific options - Important: The function
getColorColumnContext()
will always return an object, when minibars aren't used the object is empty - The function
getColorColumnContext()
uses three parameters:colorColumn
(option),data
(data from table) andwidth
(content-width) - If the option is selected, the function
getColorColumnContext()
will always return this object
{
categoricalOptions, // object
colorColumnType, // string
colors, // array
legendData, // object
numericalOptions, // object
selectedColumn, // number
}
- Depending on the selected
colorColumnType
, eithernumerical
orcategorical
, some of the properties will be added - Important: The properties
categoricalOptions
andnumericalOptions
will always be an object, even if not selected - If selecting the
colorColumnType
numerical
, the following properties will be added
{
methodBox, // object
formattedValue, // array
}
- Either
numerical
orcategorical
, both table-cells will be colored with the reference to thecolors
array - The legend will be displayed 100% on
desktop
andmobile
, onfullwidth
it will be displayed640px
(size of the text in article) - When resizing the graphic, the
EventLister
on the eventresize
implemented in therenderColorColumnNumericalLegend()
will be triggered - The legend will then be resized according to the
width
Display options can be set before embedding the graphic in the article.
Allows to hide the title
Copyright (c) Neue Zürcher Zeitung. All rights reserved.
This software is published under the MIT license.