Amélioration visuelle de la compréhension des calculs
Faire un YAML amélioré, pas plus (pour ne pas avoir un code source et une représentation totalement différente) Ce qui est inline reste inline. Factorisation du JSX dans traverse-common-jsxpull/6/head
parent
45dd66f009
commit
b223334028
|
@ -67,65 +67,128 @@
|
|||
}
|
||||
|
||||
#rule-rules section {
|
||||
margin: 1em 3em
|
||||
margin: 1em 3em;
|
||||
font-weight: 500;
|
||||
font-size: 90%;
|
||||
color: #444
|
||||
}
|
||||
#rule-rules section h2 {
|
||||
font-size: 130%;
|
||||
}
|
||||
.node {
|
||||
margin-top: 1em;
|
||||
padding-left: 1em;
|
||||
}
|
||||
.ruleProp > div > .name {
|
||||
padding: 0 1em;
|
||||
border: 1px solid black;
|
||||
background: #df5320
|
||||
}
|
||||
.mecanism {
|
||||
}
|
||||
.mecanism > div > .name {
|
||||
padding: 0 1em;
|
||||
border: 1px solid black;
|
||||
background: #d5911a
|
||||
color: #4B4B66
|
||||
}
|
||||
|
||||
.nodeHead {
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
|
||||
.mecanism > .nodeHead .name {
|
||||
padding: .05em 1em;
|
||||
background: #d5911a;
|
||||
color: white;
|
||||
font-weight: 600;
|
||||
border-radius: .4em;
|
||||
}
|
||||
.ruleProp > .nodeHead .name {
|
||||
background: #df5320
|
||||
}
|
||||
.mecanism li {
|
||||
}
|
||||
.mecanism ul {
|
||||
margin-top: 0;
|
||||
padding-left: 1em;
|
||||
list-style-type: none;
|
||||
border-left: 1px dashed #ccc;
|
||||
}
|
||||
.mecanism ul .key {
|
||||
color: #d5911a;
|
||||
font-weight: 600;
|
||||
display: inline-block;
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
|
||||
.multiplication li .key {
|
||||
margin-right: .6em;
|
||||
}
|
||||
|
||||
.mecanism.list > ul {
|
||||
list-style-type: disc;
|
||||
}
|
||||
.mecanism.list > ul > li {
|
||||
margin-left: .8em;
|
||||
padding-left: .3em;
|
||||
}
|
||||
|
||||
#rule-rules .situationValue {
|
||||
padding-left: 1em;
|
||||
font-weight: 600;
|
||||
color: #333350;
|
||||
}
|
||||
|
||||
.maximum .description {
|
||||
font-style: italic;
|
||||
font-weight: 600;
|
||||
margin-bottom: .4em;
|
||||
margin-left: 1em;
|
||||
}
|
||||
|
||||
.situationValue {
|
||||
opacity: .6
|
||||
}
|
||||
|
||||
.condition {
|
||||
margin-bottom: .6em;
|
||||
}
|
||||
|
||||
|
||||
#rule-rules .value {
|
||||
padding-left: 1em;
|
||||
font-weight: bold;
|
||||
.node.inlineExpression {
|
||||
padding-left: 0;
|
||||
display: inline;
|
||||
}
|
||||
.inlineExpression .nodeContent {
|
||||
/*border-bottom: 1px solid rgba(51, 51, 80, 0.25);*/
|
||||
/*border-right: 1px solid rgba(51, 51, 80, 0.25);*/
|
||||
/*padding: .5em .6em;*/
|
||||
/*border-radius: .3em;*/
|
||||
}
|
||||
.nodeHead {
|
||||
display: inline-block;
|
||||
}
|
||||
.leaf .situationValue {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
#rule-rules .value.oui {
|
||||
#rule-rules .situationValue.oui {
|
||||
color: #5ab738;
|
||||
}
|
||||
#rule-rules .value.non {
|
||||
#rule-rules .situationValue.non {
|
||||
color: #f22c40;
|
||||
}
|
||||
|
||||
.variable .name {
|
||||
padding: 0 1em;
|
||||
border: 1px solid black;
|
||||
background: #6666ea;
|
||||
color: #5B5B73;
|
||||
text-align: center;
|
||||
margin-top: 1em;
|
||||
padding: .05em 1em;
|
||||
line-height: 1.8em;
|
||||
border-radius: .4em;
|
||||
font-weight: 600;
|
||||
font-size: 90%;
|
||||
border: 1px solid rgba(51, 51, 80, 0.25);
|
||||
}
|
||||
|
||||
.comparison .name {
|
||||
padding: 0 1em;
|
||||
border: 1px solid black;
|
||||
background: #407ee7;
|
||||
}
|
||||
|
||||
.rate .name {
|
||||
padding: 0 1em;
|
||||
border: 1px solid black;
|
||||
background: #407ee7;
|
||||
.percentage .name {
|
||||
font-size: 110%;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.operator {
|
||||
margin: .1em .6em;
|
||||
font-size: 150%;
|
||||
vertical-align: sub;
|
||||
display: block;
|
||||
font-weight: 600;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.json {
|
||||
|
|
|
@ -99,92 +99,6 @@ export default class Rule extends Component {
|
|||
}
|
||||
}
|
||||
|
||||
let RuleProp = ({nodeValue, explanation, name}) =>
|
||||
<div className="ruleProp node" >
|
||||
<div>
|
||||
<span className="name">{name}</span>
|
||||
<NodeValue data={nodeValue}/>
|
||||
</div>
|
||||
{
|
||||
explanation.category == 'mecanism' && <Mecanism {...explanation}/>
|
||||
}
|
||||
</div>
|
||||
|
||||
let Mecanism = ({nodeValue, name, explanation}) =>
|
||||
<div className="mecanism node" >
|
||||
<div>
|
||||
<span className="name">{name}</span>
|
||||
<NodeValue data={nodeValue}/>
|
||||
</div>
|
||||
{R.contains(name)(["l'une de ces conditions", 'toutes ces conditions']) &&
|
||||
<ul>
|
||||
{explanation.map(item => <li key={item.variableName + item.name}>
|
||||
{item.category == 'variable' ?
|
||||
<Variable {...item} />
|
||||
: item.category == 'comparison' ?
|
||||
<Comparison {...item} />
|
||||
: <Mecanism {...item} />
|
||||
}
|
||||
</li>)}
|
||||
</ul>
|
||||
}
|
||||
{name == 'multiplication' &&
|
||||
<Multiplication {...explanation}/>
|
||||
}
|
||||
{name == 'le maximum de' &&
|
||||
<JSONView o={{nodeValue, name, explanation}} />
|
||||
}
|
||||
</div>
|
||||
|
||||
let Multiplication = ({base, rate}) =>
|
||||
<div className="multiplication node" >
|
||||
<Variable {...base}/>
|
||||
<span className="multiplicationSign">×</span>
|
||||
{
|
||||
rate.explanation ?
|
||||
<JSONView o={rate} />
|
||||
: <Percentage {...rate}/>
|
||||
}
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
let Variable = (yo) => do {
|
||||
let {nodeValue, variableName} = yo
|
||||
;<span className="variable" >
|
||||
<span className="name">{variableName}</span>
|
||||
<NodeValue data={nodeValue}/>
|
||||
</span>
|
||||
}
|
||||
|
||||
|
||||
let Comparison = ({nodeValue, text}) =>
|
||||
<span className="comparison" >
|
||||
<span className="name">{text}</span>
|
||||
<NodeValue data={nodeValue}/>
|
||||
</span>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
let Percentage = ({percentage}) =>
|
||||
<span className="rate" >
|
||||
<span className="name">{percentage}</span>
|
||||
</span>
|
||||
|
||||
|
||||
|
||||
// let Formula = ({explanation, nodeValue}) => do {
|
||||
// <div className="form node" >
|
||||
// <div>
|
||||
// <span className="name">{expression}</span>
|
||||
// <NodeValue data={nodeValue}/>
|
||||
// </div>
|
||||
// </div>
|
||||
// }
|
||||
|
||||
let JSONView = ({o, rootKey}) => (
|
||||
<div className="json">
|
||||
<JSONTree
|
||||
|
|
|
@ -1,15 +1,41 @@
|
|||
import React from 'react'
|
||||
import R from 'ramda'
|
||||
import classNames from 'classnames'
|
||||
|
||||
export let NodeValue = ({data}) => do {
|
||||
let valeur = data == null ?
|
||||
'?'
|
||||
: ( R.is(Number)(data) ?
|
||||
Math.round(data)
|
||||
: ( data ? 'oui' : 'non')
|
||||
)
|
||||
let treatValue = data => data == null ?
|
||||
'?'
|
||||
: ( R.is(Number)(data) ?
|
||||
Math.round(data)
|
||||
: ( data ? 'oui' : 'non')
|
||||
)
|
||||
|
||||
;<span className={"value " + valeur}>←
|
||||
{valeur}
|
||||
let NodeValue = ({data}) =>
|
||||
<span className={"situationValue " + treatValue(data)}>←
|
||||
{treatValue(data)}
|
||||
</span>
|
||||
}
|
||||
|
||||
|
||||
// Un élément du graphe de calcul qui a une valeur interprétée (à afficher)
|
||||
export let Node = ({classes, name, value, child}) =>
|
||||
<div className={classNames(classes, 'node')}>
|
||||
{name &&
|
||||
<span className="nodeHead">
|
||||
<span className="name">{name}</span>
|
||||
<NodeValue data={value}/>
|
||||
</span>
|
||||
}
|
||||
{child}
|
||||
{!name && <NodeValue data={value}/>}
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
// Un élément du graphe de calcul qui a une valeur interprétée (à afficher)
|
||||
export let Leaf = ({classes, name, value}) =>
|
||||
<span className={classNames(classes, 'leaf')}>
|
||||
{name &&
|
||||
<span className="nodeHead">
|
||||
<span className="name">{name}<NodeValue data={value}/></span>
|
||||
</span>
|
||||
}
|
||||
</span>
|
||||
|
|
|
@ -6,7 +6,7 @@ import knownMecanisms from './known-mecanisms.yaml'
|
|||
import { Parser } from 'nearley'
|
||||
import Grammar from './grammar.ne'
|
||||
import variablesInDevelopment from './variablesInDevelopment.yaml'
|
||||
import {NodeValue} from './traverse-common-jsx'
|
||||
import {Node, Leaf} from './traverse-common-jsx'
|
||||
|
||||
|
||||
|
||||
|
@ -76,11 +76,11 @@ let fillVariableNode = (rule, situationGate) => (parseResult) => {
|
|||
type: 'boolean | numeric',
|
||||
explanation: null,
|
||||
missingVariables: known ? [] : [variableName],
|
||||
jsx:
|
||||
<span className="variable" >
|
||||
<span className="name">{variableName}</span>
|
||||
<NodeValue data={nodeValue}/>
|
||||
</span>
|
||||
jsx: <Leaf
|
||||
classes="variable"
|
||||
name={variableName}
|
||||
value={nodeValue}
|
||||
/>
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -135,16 +135,17 @@ let treat = (situationGate, rule) => rawNode => {
|
|||
category: 'calcExpression',
|
||||
type: 'numeric',
|
||||
explanation: filledExplanation,
|
||||
jsx:
|
||||
<div className="mecanism node" >
|
||||
<div>
|
||||
<span className="name">Éxpression de calcul</span>
|
||||
<NodeValue data={nodeValue}/>
|
||||
</div>
|
||||
{filledExplanation[0].jsx}
|
||||
<span className="operator">{parseResult.operator}</span>
|
||||
{filledExplanation[1].jsx}
|
||||
</div>
|
||||
jsx: <Node
|
||||
classes="inlineExpression calcExpression"
|
||||
value={nodeValue}
|
||||
child={
|
||||
<span className="nodeContent">
|
||||
{filledExplanation[0].jsx}
|
||||
<span className="operator">{parseResult.operator}</span>
|
||||
{filledExplanation[1].jsx}
|
||||
</span>
|
||||
}
|
||||
/>
|
||||
}
|
||||
}
|
||||
if (parseResult.category == 'comparison') {
|
||||
|
@ -179,12 +180,17 @@ let treat = (situationGate, rule) => rawNode => {
|
|||
category: 'comparison',
|
||||
type: 'boolean',
|
||||
explanation: filledExplanation,
|
||||
jsx:
|
||||
<div className="comparison node" >
|
||||
{filledExplanation[0].jsx}
|
||||
<span className="operator">{parseResult.operator}</span>
|
||||
{filledExplanation[1].jsx}
|
||||
</div>
|
||||
jsx: <Node
|
||||
classes="inlineExpression comparison"
|
||||
value={nodeValue}
|
||||
child={
|
||||
<span className="nodeContent">
|
||||
{filledExplanation[0].jsx}
|
||||
<span className="operator">{parseResult.operator}</span>
|
||||
{filledExplanation[1].jsx}
|
||||
</span>
|
||||
}
|
||||
/>
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -236,16 +242,16 @@ let treat = (situationGate, rule) => rawNode => {
|
|||
}) // Reduce but don't use R.reduced to set the nodeValue : we need to treat all the nodes
|
||||
)(v)
|
||||
return {...result,
|
||||
jsx:
|
||||
<div className="mecanism node" >
|
||||
<div>
|
||||
<span className="name">{result.name}</span>
|
||||
<NodeValue data={result.nodeValue}/>
|
||||
</div>
|
||||
jsx: <Node
|
||||
classes="mecanism list"
|
||||
name={result.name}
|
||||
value={result.nodeValue}
|
||||
child={
|
||||
<ul>
|
||||
{result.explanation.map(item => <li>{item.jsx}</li>)}
|
||||
</ul>
|
||||
</div>
|
||||
{result.explanation.map(item => <li>{item.jsx}</li>)}
|
||||
</ul>
|
||||
}
|
||||
/>
|
||||
}
|
||||
}
|
||||
if (k === 'toutes ces conditions') {
|
||||
|
@ -281,7 +287,7 @@ let treat = (situationGate, rule) => rawNode => {
|
|||
percentage: rate,
|
||||
explanation: null,
|
||||
jsx:
|
||||
<span className="rate" >
|
||||
<span className="percentage" >
|
||||
<span className="name">{rate}</span>
|
||||
</span>
|
||||
}),
|
||||
|
@ -320,12 +326,12 @@ let treat = (situationGate, rule) => rawNode => {
|
|||
conditionValue: conditionNode.nodeValue,
|
||||
type: 'boolean',
|
||||
explanation: childNumericalLogic,
|
||||
jsx: <span className="condition">
|
||||
jsx: <div className="condition">
|
||||
{conditionNode.jsx}
|
||||
<span>
|
||||
---> {childNumericalLogic.jsx}
|
||||
</span>
|
||||
</span>
|
||||
<div>
|
||||
{childNumericalLogic.jsx}
|
||||
</div>
|
||||
</div>
|
||||
}],
|
||||
}
|
||||
}, {
|
||||
|
@ -336,16 +342,16 @@ let treat = (situationGate, rule) => rawNode => {
|
|||
explanation: []
|
||||
}),
|
||||
node => ({...node,
|
||||
jsx:
|
||||
<div className="mecanism node" >
|
||||
<div>
|
||||
<span className="name">logique numérique</span>
|
||||
<NodeValue data={node.nodeValue}/>
|
||||
</div>
|
||||
jsx: <Node
|
||||
classes="mecanism numericalLogic list"
|
||||
name="logique numérique"
|
||||
value={node.nodeValue}
|
||||
child={
|
||||
<ul>
|
||||
{node.explanation.map(item => <li>{item.jsx}</li>)}
|
||||
</ul>
|
||||
</div>
|
||||
{node.explanation.map(item => <li>{item.jsx}</li>)}
|
||||
</ul>
|
||||
}
|
||||
/>
|
||||
})
|
||||
))
|
||||
|
||||
|
@ -363,7 +369,7 @@ let treat = (situationGate, rule) => rawNode => {
|
|||
nodeValue: transformPercentage(v),
|
||||
explanation: null,
|
||||
jsx:
|
||||
<span className="rate" >
|
||||
<span className="percentage" >
|
||||
<span className="name">{v}</span>
|
||||
</span>
|
||||
}
|
||||
|
@ -386,14 +392,16 @@ let treat = (situationGate, rule) => rawNode => {
|
|||
val = node => node.nodeValue,
|
||||
base = reTreat(v['assiette']),
|
||||
rate = v['taux'] ? reTreat({taux: v['taux']}) : {nodeValue: 1}, //TODO parser le taux dans le parser ?
|
||||
facteur = v['facteur'] ? reTreat(v['facteur']) : {nodeValue: 1}
|
||||
|
||||
return {
|
||||
nodeValue: (val(rate) === 0 || val(rate) === false || val(base) === 0 || val(facteur) === 0) ?
|
||||
facteur = v['facteur'] ? reTreat(v['facteur']) : {nodeValue: 1},
|
||||
// OUCH :-o !
|
||||
nodeValue = (val(rate) === 0 || val(rate) === false || val(base) === 0 || val(facteur) === 0) ?
|
||||
0
|
||||
: (val(rate) == null || val(base) == null || val(facteur) == null) ?
|
||||
null
|
||||
: val(base) * val(rate) * val(facteur),
|
||||
: val(base) * val(rate) * val(facteur)
|
||||
|
||||
return {
|
||||
nodeValue,
|
||||
category: 'mecanism',
|
||||
name: 'multiplication',
|
||||
type: 'numeric',
|
||||
|
@ -404,13 +412,29 @@ let treat = (situationGate, rule) => rawNode => {
|
|||
//TODO limit: 'plafond'
|
||||
//TODO introduire 'prorata' ou 'multiplicateur', pour sémantiser les opérandes ?
|
||||
},
|
||||
jsx:
|
||||
<div className="multiplication node" >
|
||||
{base.jsx}
|
||||
<span className="multiplicationSign">×</span>
|
||||
{rate && rate.jsx}
|
||||
{facteur && facteur.jsx}
|
||||
</div>
|
||||
jsx: <Node
|
||||
classes="mecanism multiplication"
|
||||
name="multiplication"
|
||||
value={nodeValue}
|
||||
child={
|
||||
<ul>
|
||||
<li>
|
||||
<span className="key">assiette: </span>
|
||||
<span className="value">{base.jsx}</span>
|
||||
</li>
|
||||
{rate.nodeValue != 1 &&
|
||||
<li>
|
||||
<span className="key">taux: </span>
|
||||
<span className="value">{rate.jsx}</span>
|
||||
</li>}
|
||||
{facteur.nodeValue != 1 &&
|
||||
<li>
|
||||
<span className="key">facteur: </span>
|
||||
<span className="value">{facteur.jsx}</span>
|
||||
</li>}
|
||||
</ul>
|
||||
}
|
||||
/>
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -427,16 +451,21 @@ let treat = (situationGate, rule) => rawNode => {
|
|||
name: 'le maximum de',
|
||||
nodeValue,
|
||||
explanation: contenders,
|
||||
jsx:
|
||||
<div className="mecanism node" >
|
||||
<div>
|
||||
<span className="name">le maximum de</span>
|
||||
<NodeValue data={nodeValue}/>
|
||||
</div>
|
||||
jsx: <Node
|
||||
classes="mecanism list maximum"
|
||||
name="le maximum de"
|
||||
value={nodeValue}
|
||||
child={
|
||||
<ul>
|
||||
{contenders.map(item => <li>{item.jsx}</li>)}
|
||||
</ul>
|
||||
</div>
|
||||
{contenders.map((item, i) =>
|
||||
<li>
|
||||
<div className="description">{v[i].description}</div>
|
||||
{item.jsx}
|
||||
</li>
|
||||
)}
|
||||
</ul>
|
||||
}
|
||||
/>
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -460,14 +489,14 @@ let treatRuleRoot = (situationGate, rule) => R.evolve({ // -> Voilà les attribu
|
|||
type: 'boolean',
|
||||
nodeValue: child.nodeValue,
|
||||
explanation: child,
|
||||
jsx:
|
||||
<div className="ruleProp node" >
|
||||
<div>
|
||||
<span className="name">non applicable si</span>
|
||||
<NodeValue data={nodeValue}/>
|
||||
</div>
|
||||
{ child.jsx }
|
||||
</div>
|
||||
jsx: <Node
|
||||
classes="ruleProp mecanism cond"
|
||||
name="non applicable si"
|
||||
value={nodeValue}
|
||||
child={
|
||||
child.jsx
|
||||
}
|
||||
/>
|
||||
}
|
||||
}
|
||||
,
|
||||
|
@ -488,14 +517,14 @@ let treatRuleRoot = (situationGate, rule) => R.evolve({ // -> Voilà les attribu
|
|||
nodeValue: nodeValue,
|
||||
explanation: child,
|
||||
shortCircuit: R.pathEq(['non applicable si', 'nodeValue'], true),
|
||||
jsx:
|
||||
<div className="ruleProp node" >
|
||||
<div>
|
||||
<span className="name">formula</span>
|
||||
<NodeValue data={nodeValue}/>
|
||||
</div>
|
||||
{ child.jsx }
|
||||
</div>
|
||||
jsx: <Node
|
||||
classes="ruleProp mecanism formula"
|
||||
name="formule"
|
||||
value={nodeValue}
|
||||
child={
|
||||
child.jsx
|
||||
}
|
||||
/>
|
||||
}
|
||||
}
|
||||
,
|
||||
|
|
Loading…
Reference in New Issue