timeline chart
This commit is contained in:
+9
-1
@@ -110,6 +110,12 @@
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Drawing" />
|
||||
<Reference Include="System.Security.Claims, Version=4.0.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\System.Security.Claims.4.0.1\lib\net46\System.Security.Claims.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Security.Principal.Windows, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\System.Security.Principal.Windows.4.0.0\lib\net46\System.Security.Principal.Windows.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Web.Cors, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Microsoft.AspNet.Cors.5.2.3\lib\net45\System.Web.Cors.dll</HintPath>
|
||||
</Reference>
|
||||
@@ -197,7 +203,9 @@
|
||||
<Compile Include="WebApiUnhandledExceptionHandler.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="App.config" />
|
||||
<Content Include="App.config">
|
||||
<SubType>Designer</SubType>
|
||||
</Content>
|
||||
<Content Include="App.Debug.config">
|
||||
<DependentUpon>App.config</DependentUpon>
|
||||
</Content>
|
||||
|
||||
@@ -31,5 +31,7 @@
|
||||
<package id="Owin" version="1.0" targetFramework="net462" />
|
||||
<package id="Swashbuckle" version="5.6.0" targetFramework="net462" />
|
||||
<package id="Swashbuckle.Core" version="5.6.0" targetFramework="net462" />
|
||||
<package id="System.Security.Claims" version="4.0.1" targetFramework="net462" />
|
||||
<package id="System.Security.Principal.Windows" version="4.0.0" targetFramework="net462" />
|
||||
<package id="WebActivatorEx" version="2.2.0" targetFramework="net462" />
|
||||
</packages>
|
||||
+5043
-4150
File diff suppressed because it is too large
Load Diff
@@ -34,6 +34,7 @@
|
||||
@import "job-editor.less";
|
||||
@import "scada.less";
|
||||
@import "report.less";
|
||||
@import "tooltip.less";
|
||||
|
||||
@background-color: rgb(216, 216, 216);
|
||||
@handle-width: 48px;
|
||||
@@ -209,7 +210,7 @@ body {
|
||||
width: @spinner-loading-height;
|
||||
height: @spinner-loading-width;
|
||||
top: calc(~'50%' - @spinner-loading-height /2);
|
||||
left: calc(~'50%' - @spinner-loading-width /2);
|
||||
left: calc(~'50%' - @spinner-loading-width /2);
|
||||
text-align: center;
|
||||
line-height: @spinner-loading-height;
|
||||
font-size: @spinner-loading-height/2;
|
||||
|
||||
@@ -0,0 +1,116 @@
|
||||
// out: false, sourceMap: false, main: ../style.less
|
||||
@import "colors.less";
|
||||
|
||||
.tooltip {
|
||||
display: block !important;
|
||||
z-index: 10000;
|
||||
|
||||
.tooltip-inner {
|
||||
min-width: 288px;
|
||||
min-height: 220px;
|
||||
border-radius: 2px;
|
||||
border: solid 2px @color-clear-blue;
|
||||
background: white;
|
||||
color: @color-greyish-brown;
|
||||
border-radius: 16px;
|
||||
padding: 5px 10px 4px;
|
||||
}
|
||||
|
||||
.tooltip-arrow {
|
||||
width: 0;
|
||||
height: 0;
|
||||
border-style: solid;
|
||||
position: absolute;
|
||||
margin: 5px;
|
||||
background: transparent;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
&[x-placement^="top"] {
|
||||
margin-bottom: 5px;
|
||||
|
||||
.tooltip-arrow {
|
||||
border-width: 5px 5px 0 5px;
|
||||
border-left-color: transparent !important;
|
||||
border-right-color: transparent !important;
|
||||
border-bottom-color: transparent !important;
|
||||
bottom: -5px;
|
||||
left: calc(50% - 5px);
|
||||
margin-top: 0;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
&[x-placement^="bottom"] {
|
||||
margin-top: 5px;
|
||||
|
||||
.tooltip-arrow {
|
||||
border-width: 0 5px 5px 5px;
|
||||
border-left-color: transparent !important;
|
||||
border-right-color: transparent !important;
|
||||
border-top-color: transparent !important;
|
||||
top: -5px;
|
||||
left: calc(50% - 5px);
|
||||
margin-top: 0;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
&[x-placement^="right"] {
|
||||
margin-left: 5px;
|
||||
|
||||
.tooltip-arrow {
|
||||
border-width: 5px 5px 5px 0;
|
||||
border-left-color: transparent !important;
|
||||
border-top-color: transparent !important;
|
||||
border-bottom-color: transparent !important;
|
||||
left: -5px;
|
||||
top: calc(50% - 5px);
|
||||
margin-left: 0;
|
||||
margin-right: 0;
|
||||
}
|
||||
}
|
||||
|
||||
&[x-placement^="left"] {
|
||||
margin-right: 5px;
|
||||
|
||||
.tooltip-arrow {
|
||||
border-width: 5px 0 5px 5px;
|
||||
border-top-color: transparent !important;
|
||||
border-right-color: transparent !important;
|
||||
border-bottom-color: transparent !important;
|
||||
right: -5px;
|
||||
top: calc(50% - 5px);
|
||||
margin-left: 0;
|
||||
margin-right: 0;
|
||||
}
|
||||
}
|
||||
|
||||
&.popover {
|
||||
color: #f9f9f9;
|
||||
|
||||
.popover-inner {
|
||||
background: $color;
|
||||
color: @color-greyish-brown;
|
||||
padding: 24px;
|
||||
border-radius: 5px;
|
||||
box-shadow: 0 5px 30px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.popover-arrow {
|
||||
border: solid 2px @color-clear-blue;
|
||||
}
|
||||
}
|
||||
|
||||
&[aria-hidden='true'] {
|
||||
visibility: hidden;
|
||||
opacity: 0;
|
||||
transition: opacity .15s, visibility .15s;
|
||||
}
|
||||
|
||||
&[aria-hidden='false'] {
|
||||
visibility: visible;
|
||||
opacity: 1;
|
||||
transition: opacity .15s;
|
||||
}
|
||||
}
|
||||
@@ -8640,6 +8640,10 @@ footer .container button.big:before {
|
||||
line-height: 1.11;
|
||||
color: #4b4b4b;
|
||||
}
|
||||
.card-report-production .reports-box-body-left .body-left-center .body-left-center-container .body-left-center-left div .accordion-dropdown {
|
||||
position: relative;
|
||||
margin-top: 2px;
|
||||
}
|
||||
.card-report-production .reports-box-body-left .body-left-center .body-left-center-container .body-left-center-left div .accordion-dropdown header {
|
||||
height: 64px;
|
||||
width: 312px;
|
||||
@@ -9229,6 +9233,10 @@ footer .container button.big:before {
|
||||
line-height: 1.11;
|
||||
color: #4b4b4b;
|
||||
}
|
||||
.card-report-events .reports-box-body-left .body-left-center .body-left-center-container .body-left-center-left div .accordion-dropdown {
|
||||
position: relative;
|
||||
margin-top: 2px;
|
||||
}
|
||||
.card-report-events .reports-box-body-left .body-left-center .body-left-center-container .body-left-center-left div .accordion-dropdown header {
|
||||
height: 64px;
|
||||
width: 312px;
|
||||
@@ -9869,6 +9877,10 @@ footer .container button.big:before {
|
||||
line-height: 1.11;
|
||||
color: #4b4b4b;
|
||||
}
|
||||
.card-report-alarms .reports-box-body-left .body-left-center .body-left-center-container .body-left-center-left div .accordion-dropdown {
|
||||
position: relative;
|
||||
margin-top: 2px;
|
||||
}
|
||||
.card-report-alarms .reports-box-body-left .body-left-center .body-left-center-container .body-left-center-left div .accordion-dropdown header {
|
||||
height: 64px;
|
||||
width: 312px;
|
||||
@@ -10412,7 +10424,6 @@ footer .container button.big:before {
|
||||
.card-report-timeline .reports-box-body-left .body-left-header-machinestatus > div {
|
||||
display: flex;
|
||||
flex-flow: column;
|
||||
height: 70px;
|
||||
margin-right: 24px;
|
||||
}
|
||||
.card-report-timeline .reports-box-body-left .body-left-header > div label,
|
||||
@@ -10467,40 +10478,78 @@ footer .container button.big:before {
|
||||
padding-left: 16px;
|
||||
border: none;
|
||||
}
|
||||
.card-report-timeline .reports-box-body-left .body-left-header .zoom-control,
|
||||
.card-report-timeline .reports-box-body-left .body-left-header-machinestatus .zoom-control {
|
||||
display: block;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 120px;
|
||||
float: right;
|
||||
margin: 0px;
|
||||
position: absolute;
|
||||
right: 0px;
|
||||
top: 11px;
|
||||
}
|
||||
.card-report-timeline .reports-box-body-left .body-left-header .zoom-control button,
|
||||
.card-report-timeline .reports-box-body-left .body-left-header-machinestatus .zoom-control button {
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
border-radius: 2px;
|
||||
box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.4);
|
||||
background-image: linear-gradient(to bottom, #f1f1f1, #bbbcbc);
|
||||
border: none;
|
||||
}
|
||||
.card-report-timeline .reports-box-body-left .body-left-header .zoom-control button:first-child,
|
||||
.card-report-timeline .reports-box-body-left .body-left-header-machinestatus .zoom-control button:first-child {
|
||||
margin-right: 16px;
|
||||
}
|
||||
.card-report-timeline .reports-box-body-left .body-left-header .zoom-control button:active,
|
||||
.card-report-timeline .reports-box-body-left .body-left-header-machinestatus .zoom-control button:active {
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
border-radius: 2px;
|
||||
box-shadow: inset 0 1px 3px 0 rgba(0, 0, 0, 0.4);
|
||||
background-image: linear-gradient(to bottom, #bbbcbc, #f1f1f1);
|
||||
border: none;
|
||||
}
|
||||
.card-report-timeline .reports-box-body-left .body-left-center {
|
||||
width: 1448px;
|
||||
max-height: 681px;
|
||||
display: flex;
|
||||
flex-flow: column;
|
||||
border: solid 1px #dddddd;
|
||||
}
|
||||
.card-report-timeline .reports-box-body-left .body-left-center .body-left-center-container {
|
||||
.card-report-timeline .reports-box-body-left .body-left-center .body-left-center-header {
|
||||
width: 100%;
|
||||
height: 104px;
|
||||
display: flex;
|
||||
flex-flow: row;
|
||||
flex: 1 1 auto;
|
||||
}
|
||||
.card-report-timeline .reports-box-body-left .body-left-center .body-left-center-container .body-left-center-left {
|
||||
.card-report-timeline .reports-box-body-left .body-left-center .body-left-center-header .body-left-center-left {
|
||||
width: 360px;
|
||||
height: 616px;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-flow: column;
|
||||
align-items: center;
|
||||
border: solid 1px #dddddd;
|
||||
overflow-y: auto;
|
||||
border-right: solid 1px #dddddd;
|
||||
}
|
||||
.card-report-timeline .reports-box-body-left .body-left-center .body-left-center-container .body-left-center-left .multiselect {
|
||||
.card-report-timeline .reports-box-body-left .body-left-center .body-left-center-header .body-left-center-left .multiselect {
|
||||
z-index: 100;
|
||||
margin-bottom: 24px;
|
||||
margin-top: 16px;
|
||||
}
|
||||
.card-report-timeline .reports-box-body-left .body-left-center .body-left-center-container .body-left-center-left .multiselect label {
|
||||
.card-report-timeline .reports-box-body-left .body-left-center .body-left-center-header .body-left-center-left .multiselect label {
|
||||
font-size: 14px;
|
||||
line-height: 1.29;
|
||||
color: #878787;
|
||||
}
|
||||
.card-report-timeline .reports-box-body-left .body-left-center .body-left-center-container .body-left-center-left .selectBox {
|
||||
.card-report-timeline .reports-box-body-left .body-left-center .body-left-center-header .body-left-center-left .selectBox {
|
||||
position: relative;
|
||||
width: 328px;
|
||||
height: 64px;
|
||||
}
|
||||
.card-report-timeline .reports-box-body-left .body-left-center .body-left-center-container .body-left-center-left .selectBox select {
|
||||
.card-report-timeline .reports-box-body-left .body-left-center .body-left-center-header .body-left-center-left .selectBox select {
|
||||
width: 100%;
|
||||
padding: 8px;
|
||||
cursor: pointer;
|
||||
@@ -10511,37 +10560,38 @@ footer .container button.big:before {
|
||||
margin-bottom: 0;
|
||||
margin-top: 0;
|
||||
}
|
||||
.card-report-timeline .reports-box-body-left .body-left-center .body-left-center-container .body-left-center-left .selectBox select option {
|
||||
.card-report-timeline .reports-box-body-left .body-left-center .body-left-center-header .body-left-center-left .selectBox select option {
|
||||
display: none;
|
||||
}
|
||||
.card-report-timeline .reports-box-body-left .body-left-center .body-left-center-container .body-left-center-left .overSelect {
|
||||
.card-report-timeline .reports-box-body-left .body-left-center .body-left-center-header .body-left-center-left .overSelect {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
}
|
||||
.card-report-timeline .reports-box-body-left .body-left-center .body-left-center-container .body-left-center-left .checkboxes {
|
||||
.card-report-timeline .reports-box-body-left .body-left-center .body-left-center-header .body-left-center-left .checkboxes {
|
||||
display: none;
|
||||
}
|
||||
.card-report-timeline .reports-box-body-left .body-left-center .body-left-center-container .body-left-center-left .checkboxesView {
|
||||
width: calc(100% - 8px);
|
||||
.card-report-timeline .reports-box-body-left .body-left-center .body-left-center-header .body-left-center-left .checkboxesView {
|
||||
position: absolute;
|
||||
width: 320px;
|
||||
background-color: #fff;
|
||||
display: block;
|
||||
z-index: 100;
|
||||
padding: 6px 4px;
|
||||
box-shadow: 0 3px 5px 0 rgba(0, 0, 0, 0.4);
|
||||
}
|
||||
.card-report-timeline .reports-box-body-left .body-left-center .body-left-center-container .body-left-center-left .checkboxesView label {
|
||||
.card-report-timeline .reports-box-body-left .body-left-center .body-left-center-header .body-left-center-left .checkboxesView label {
|
||||
font-size: 18px;
|
||||
margin: 2px;
|
||||
display: flex;
|
||||
flex-flow: row;
|
||||
}
|
||||
.card-report-timeline .reports-box-body-left .body-left-center .body-left-center-container .body-left-center-left .checkboxesView .label-state {
|
||||
.card-report-timeline .reports-box-body-left .body-left-center .body-left-center-header .body-left-center-left .checkboxesView .label-state {
|
||||
margin-left: 12px;
|
||||
}
|
||||
.card-report-timeline .reports-box-body-left .body-left-center .body-left-center-container .body-left-center-left div select {
|
||||
.card-report-timeline .reports-box-body-left .body-left-center .body-left-center-header .body-left-center-left div select {
|
||||
width: 328px;
|
||||
height: 48px;
|
||||
border-radius: 2px;
|
||||
@@ -10553,7 +10603,124 @@ footer .container button.big:before {
|
||||
line-height: 1.11;
|
||||
color: #4b4b4b;
|
||||
}
|
||||
.card-report-timeline .reports-box-body-left .body-left-center .body-left-center-container .body-left-center-left div .accordion-dropdown header {
|
||||
.card-report-timeline .reports-box-body-left .body-left-center .body-left-center-header .body-left-center-right {
|
||||
width: 1088px;
|
||||
height: 100%;
|
||||
display: block;
|
||||
position: relative;
|
||||
}
|
||||
.card-report-timeline .reports-box-body-left .body-left-center .body-left-center-header .body-left-center-right .timeline-chart-header {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
position: relative;
|
||||
}
|
||||
.card-report-timeline .reports-box-body-left .body-left-center .body-left-center-header .body-left-center-right .timeline-chart-header .timeline-chart-header-title {
|
||||
width: 100%;
|
||||
height: 20px;
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
font-style: normal;
|
||||
font-stretch: normal;
|
||||
line-height: 1.11;
|
||||
letter-spacing: normal;
|
||||
text-align: center;
|
||||
color: #4b4b4b;
|
||||
position: absolute;
|
||||
top: 24px;
|
||||
}
|
||||
.card-report-timeline .reports-box-body-left .body-left-center .body-left-center-header .body-left-center-right .timeline-chart-header .timeline-chart-header-items {
|
||||
display: flex;
|
||||
flex-flow: row;
|
||||
flex-wrap: nowrap;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
text-align: center;
|
||||
vertical-align: bottom;
|
||||
}
|
||||
.card-report-timeline .reports-box-body-left .body-left-center .body-left-center-header .body-left-center-right .timeline-chart-header .timeline-chart-header-items .timeline-chart-header-item {
|
||||
flex: 1 1 auto;
|
||||
font-size: 12px;
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
font-stretch: normal;
|
||||
line-height: 1.43;
|
||||
letter-spacing: normal;
|
||||
text-align: center;
|
||||
color: #4b4b4b;
|
||||
overflow: hidden;
|
||||
}
|
||||
.card-report-timeline .reports-box-body-left .body-left-center .body-left-center-header .body-left-center-right .timeline-chart-header .timeline-chart-header-items .timeline-chart-header-item:first-child {
|
||||
border-right: solid 1px #dddddd;
|
||||
}
|
||||
.card-report-timeline .reports-box-body-left .body-left-center .body-left-center-header .body-left-center-right .timeline-chart-header .timeline-chart-header-items .timeline-chart-header-item:last-child {
|
||||
border-left: solid 1px #dddddd;
|
||||
}
|
||||
.card-report-timeline .reports-box-body-left .body-left-center .body-left-center-header .body-left-center-right .timeline-chart-header .timeline-chart-header-items .timeline-chart-header-item label {
|
||||
position: relative;
|
||||
line-height: 164px;
|
||||
display: block;
|
||||
}
|
||||
.card-report-timeline .reports-box-body-left .body-left-center .body-left-center-header .body-left-center-right .timeline-chart-header .timeline-chart-header-items .timeline-chart-header-item label.rotate {
|
||||
-webkit-transform: rotate(-78deg);
|
||||
-moz-transform: rotate(-78deg);
|
||||
-ms-transform: rotate(-78deg);
|
||||
-o-transform: rotate(-78deg);
|
||||
filter: progid:DXImageTransform.Microsoft.BasicImage(rotation=3);
|
||||
}
|
||||
.card-report-timeline .reports-box-body-left .body-left-center .body-left-center-header .body-left-center-right .timeline-chart-header .cursone-gantt {
|
||||
width: 30px;
|
||||
height: 618px;
|
||||
position: absolute;
|
||||
top: 52px;
|
||||
margin-left: -15px;
|
||||
z-index: 100;
|
||||
}
|
||||
.card-report-timeline .reports-box-body-left .body-left-center .body-left-center-header .body-left-center-right .timeline-chart-header .cursone-gantt .oval {
|
||||
width: 30px;
|
||||
border-radius: 2px;
|
||||
color: #002680;
|
||||
cursor: e-resize;
|
||||
}
|
||||
.card-report-timeline .reports-box-body-left .body-left-center .body-left-center-header .body-left-center-right .timeline-chart-header .cursone-gantt .oval svg {
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
fill: #002680;
|
||||
}
|
||||
.card-report-timeline .reports-box-body-left .body-left-center .body-left-center-header .body-left-center-right .timeline-chart-header .cursone-gantt .line {
|
||||
width: 2px;
|
||||
height: 576px;
|
||||
border-left: solid 4px #002680;
|
||||
margin-bottom: 4px;
|
||||
margin-left: 13px;
|
||||
cursor: e-resize;
|
||||
}
|
||||
.card-report-timeline .reports-box-body-left .body-left-center .body-left-center-header .body-left-center-right .timeline-chart-header .cursone-gantt.active .oval {
|
||||
background-color: #004990;
|
||||
}
|
||||
.card-report-timeline .reports-box-body-left .body-left-center .body-left-center-header .body-left-center-right .timeline-chart-header .cursone-gantt.active .line {
|
||||
border-color: #004990;
|
||||
}
|
||||
.card-report-timeline .reports-box-body-left .body-left-center .body-left-center-container {
|
||||
width: 100%;
|
||||
height: 508px;
|
||||
display: flex;
|
||||
flex-flow: row;
|
||||
overflow-x: hidden;
|
||||
flex: 1 1 auto;
|
||||
}
|
||||
.card-report-timeline .reports-box-body-left .body-left-center .body-left-center-container .body-left-center-left {
|
||||
width: 360px;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-flow: column;
|
||||
align-items: center;
|
||||
border-right: solid 1px #dddddd;
|
||||
}
|
||||
.card-report-timeline .reports-box-body-left .body-left-center .body-left-center-container .body-left-center-left .accordion-dropdown {
|
||||
position: relative;
|
||||
margin-top: 2px;
|
||||
}
|
||||
.card-report-timeline .reports-box-body-left .body-left-center .body-left-center-container .body-left-center-left .accordion-dropdown header {
|
||||
height: 64px;
|
||||
width: 312px;
|
||||
border-radius: 2px;
|
||||
@@ -10567,60 +10734,114 @@ footer .container button.big:before {
|
||||
padding-left: 16px;
|
||||
cursor: pointer;
|
||||
}
|
||||
.card-report-timeline .reports-box-body-left .body-left-center .body-left-center-container .body-left-center-left div .accordion-dropdown header span {
|
||||
.card-report-timeline .reports-box-body-left .body-left-center .body-left-center-container .body-left-center-left .accordion-dropdown header span {
|
||||
width: 100%;
|
||||
}
|
||||
.card-report-timeline .reports-box-body-left .body-left-center .body-left-center-container .body-left-center-left div .accordion-dropdown header .expander {
|
||||
.card-report-timeline .reports-box-body-left .body-left-center .body-left-center-container .body-left-center-left .accordion-dropdown header .expander {
|
||||
margin: 0 12px;
|
||||
line-height: 28px;
|
||||
height: 28px;
|
||||
width: 28px;
|
||||
font-size: 28px;
|
||||
}
|
||||
.card-report-timeline .reports-box-body-left .body-left-center .body-left-center-container .body-left-center-left div .accordion-dropdown section {
|
||||
.card-report-timeline .reports-box-body-left .body-left-center .body-left-center-container .body-left-center-left .accordion-dropdown header .row-chart {
|
||||
position: absolute;
|
||||
top: 0px;
|
||||
left: 345px;
|
||||
width: 1087px;
|
||||
}
|
||||
.card-report-timeline .reports-box-body-left .body-left-center .body-left-center-container .body-left-center-left .accordion-dropdown header .row-chart .timeline-chart-row {
|
||||
width: 100%;
|
||||
height: 64px;
|
||||
background-color: #ddd;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
.card-report-timeline .reports-box-body-left .body-left-center .body-left-center-container .body-left-center-left .accordion-dropdown header .row-chart .timeline-chart-row .timeline-chart-row-item {
|
||||
background-color: #76baf7;
|
||||
position: absolute;
|
||||
top: 8px;
|
||||
bottom: 8px;
|
||||
left: 10%;
|
||||
right: 50%;
|
||||
border-radius: 2px;
|
||||
height: 48px;
|
||||
}
|
||||
.card-report-timeline .reports-box-body-left .body-left-center .body-left-center-container .body-left-center-left .accordion-dropdown section {
|
||||
width: 328px;
|
||||
min-height: 0;
|
||||
max-height: 0;
|
||||
transition: max-height 100ms ease-in-out, min-height 200ms ease-in-out;
|
||||
overflow: hidden;
|
||||
}
|
||||
.card-report-timeline .reports-box-body-left .body-left-center .body-left-center-container .body-left-center-left div .accordion-dropdown section.expanded {
|
||||
.card-report-timeline .reports-box-body-left .body-left-center .body-left-center-container .body-left-center-left .accordion-dropdown section.expanded {
|
||||
min-height: 64px;
|
||||
background-color: rgba(255, 255, 255, 0.1);
|
||||
max-height: 1000px;
|
||||
overflow: visible;
|
||||
}
|
||||
.card-report-timeline .reports-box-body-left .body-left-center .body-left-center-container .body-left-center-left div .accordion-dropdown section .item {
|
||||
.card-report-timeline .reports-box-body-left .body-left-center .body-left-center-container .body-left-center-left .accordion-dropdown section .item {
|
||||
height: 64px;
|
||||
width: 100%;
|
||||
line-height: 64px;
|
||||
background-color: #f1f1f1;
|
||||
position: relative;
|
||||
}
|
||||
.card-report-timeline .reports-box-body-left .body-left-center .body-left-center-container .body-left-center-left div .accordion-dropdown section .dropdown {
|
||||
.card-report-timeline .reports-box-body-left .body-left-center .body-left-center-container .body-left-center-left .accordion-dropdown section .dropdown {
|
||||
height: 100%;
|
||||
margin-top: 2px;
|
||||
}
|
||||
.card-report-timeline .reports-box-body-left .body-left-center .body-left-center-container .body-left-center-left div .accordion-dropdown section .dropdown .filename {
|
||||
.card-report-timeline .reports-box-body-left .body-left-center .body-left-center-container .body-left-center-left .accordion-dropdown section .dropdown .filename {
|
||||
display: flex;
|
||||
height: 64px;
|
||||
align-items: center;
|
||||
cursor: pointer;
|
||||
}
|
||||
.card-report-timeline .reports-box-body-left .body-left-center .body-left-center-container .body-left-center-left div .accordion-dropdown section .dropdown .filename i {
|
||||
.card-report-timeline .reports-box-body-left .body-left-center .body-left-center-container .body-left-center-left .accordion-dropdown section .dropdown .filename i {
|
||||
color: #002e6e;
|
||||
margin: 0 20px 0 20px;
|
||||
}
|
||||
.card-report-timeline .reports-box-body-left .body-left-center .body-left-center-container .body-left-center-left div .accordion-dropdown section .dropdown .filename span {
|
||||
.card-report-timeline .reports-box-body-left .body-left-center .body-left-center-container .body-left-center-left .accordion-dropdown section .dropdown .filename span {
|
||||
width: 100%;
|
||||
font-size: 18px;
|
||||
line-height: 1;
|
||||
color: #002680;
|
||||
}
|
||||
.card-report-timeline .reports-box-body-left .body-left-center .body-left-center-container .body-left-center-left div .accordion-dropdown section .dropdown .filename.selected span,
|
||||
.card-report-timeline .reports-box-body-left .body-left-center .body-left-center-container .body-left-center-left div .accordion-dropdown section .dropdown .filename.selected i {
|
||||
.card-report-timeline .reports-box-body-left .body-left-center .body-left-center-container .body-left-center-left .accordion-dropdown section .dropdown .filename.selected {
|
||||
background-color: rgba(255, 255, 255, 0.8);
|
||||
}
|
||||
.card-report-timeline .reports-box-body-left .body-left-center .body-left-center-container .body-left-center-left .accordion-dropdown section .dropdown .filename.selected span,
|
||||
.card-report-timeline .reports-box-body-left .body-left-center .body-left-center-container .body-left-center-left .accordion-dropdown section .dropdown .filename.selected i {
|
||||
color: #4b4b4b;
|
||||
}
|
||||
.card-report-timeline .reports-box-body-left .body-left-center .body-left-center-container .body-left-center-left div .accordion-dropdown section .dropdown .filename.selected {
|
||||
background-color: rgba(255, 255, 255, 0.8);
|
||||
.card-report-timeline .reports-box-body-left .body-left-center .body-left-center-container .body-left-center-left .accordion-dropdown section .dropdown .row-chart {
|
||||
position: absolute;
|
||||
top: 0px;
|
||||
left: 345px;
|
||||
width: 1087px;
|
||||
}
|
||||
.card-report-timeline .reports-box-body-left .body-left-center .body-left-center-container .body-left-center-left .accordion-dropdown section .dropdown .row-chart .timeline-chart-row {
|
||||
width: 100%;
|
||||
height: 64px;
|
||||
background-color: #ddd;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
.card-report-timeline .reports-box-body-left .body-left-center .body-left-center-container .body-left-center-left .accordion-dropdown section .dropdown .row-chart .timeline-chart-row .timeline-chart-row-item {
|
||||
background-color: #76baf7;
|
||||
position: absolute;
|
||||
top: 8px;
|
||||
bottom: 8px;
|
||||
left: 10%;
|
||||
right: 50%;
|
||||
border-radius: 2px;
|
||||
height: 48px;
|
||||
}
|
||||
.card-report-timeline .reports-box-body-left .body-left-center .body-left-center-container .body-left-center-right {
|
||||
width: 1088px;
|
||||
height: 100%;
|
||||
display: block;
|
||||
position: relative;
|
||||
}
|
||||
.card-report-timeline .reports-box-body-left .body-left-center .body-left-center-footer {
|
||||
height: 64px;
|
||||
@@ -11112,6 +11333,8 @@ footer .container button.big:before {
|
||||
color: @color-greyish-brown;
|
||||
}
|
||||
.accordion-dropdown{
|
||||
position: relative;
|
||||
margin-top: 2px;
|
||||
header {
|
||||
height: 64px;
|
||||
width: 312px;
|
||||
@@ -18422,6 +18645,104 @@ footer .container button.big:before {
|
||||
display: flex;
|
||||
flex-flow: row;
|
||||
}
|
||||
.tooltip {
|
||||
display: block !important;
|
||||
z-index: 10000;
|
||||
}
|
||||
.tooltip .tooltip-inner {
|
||||
min-width: 288px;
|
||||
min-height: 220px;
|
||||
border-radius: 2px;
|
||||
border: solid 2px #1791ff;
|
||||
background: white;
|
||||
color: #4b4b4b;
|
||||
border-radius: 16px;
|
||||
padding: 5px 10px 4px;
|
||||
}
|
||||
.tooltip .tooltip-arrow {
|
||||
width: 0;
|
||||
height: 0;
|
||||
border-style: solid;
|
||||
position: absolute;
|
||||
margin: 5px;
|
||||
background: transparent;
|
||||
z-index: 1;
|
||||
}
|
||||
.tooltip[x-placement^="top"] {
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
.tooltip[x-placement^="top"] .tooltip-arrow {
|
||||
border-width: 5px 5px 0 5px;
|
||||
border-left-color: transparent !important;
|
||||
border-right-color: transparent !important;
|
||||
border-bottom-color: transparent !important;
|
||||
bottom: -5px;
|
||||
left: calc(45%);
|
||||
margin-top: 0;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
.tooltip[x-placement^="bottom"] {
|
||||
margin-top: 5px;
|
||||
}
|
||||
.tooltip[x-placement^="bottom"] .tooltip-arrow {
|
||||
border-width: 0 5px 5px 5px;
|
||||
border-left-color: transparent !important;
|
||||
border-right-color: transparent !important;
|
||||
border-top-color: transparent !important;
|
||||
top: -5px;
|
||||
left: calc(45%);
|
||||
margin-top: 0;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
.tooltip[x-placement^="right"] {
|
||||
margin-left: 5px;
|
||||
}
|
||||
.tooltip[x-placement^="right"] .tooltip-arrow {
|
||||
border-width: 5px 5px 5px 0;
|
||||
border-left-color: transparent !important;
|
||||
border-top-color: transparent !important;
|
||||
border-bottom-color: transparent !important;
|
||||
left: -5px;
|
||||
top: calc(45%);
|
||||
margin-left: 0;
|
||||
margin-right: 0;
|
||||
}
|
||||
.tooltip[x-placement^="left"] {
|
||||
margin-right: 5px;
|
||||
}
|
||||
.tooltip[x-placement^="left"] .tooltip-arrow {
|
||||
border-width: 5px 0 5px 5px;
|
||||
border-top-color: transparent !important;
|
||||
border-right-color: transparent !important;
|
||||
border-bottom-color: transparent !important;
|
||||
right: -5px;
|
||||
top: calc(45%);
|
||||
margin-left: 0;
|
||||
margin-right: 0;
|
||||
}
|
||||
.tooltip.popover {
|
||||
color: #f9f9f9;
|
||||
}
|
||||
.tooltip.popover .popover-inner {
|
||||
background: $color;
|
||||
color: #4b4b4b;
|
||||
padding: 24px;
|
||||
border-radius: 5px;
|
||||
box-shadow: 0 5px 30px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
.tooltip.popover .popover-arrow {
|
||||
border: solid 2px #1791ff;
|
||||
}
|
||||
.tooltip[aria-hidden='true'] {
|
||||
visibility: hidden;
|
||||
opacity: 0;
|
||||
transition: opacity .15s, visibility .15s;
|
||||
}
|
||||
.tooltip[aria-hidden='false'] {
|
||||
visibility: visible;
|
||||
opacity: 1;
|
||||
transition: opacity .15s;
|
||||
}
|
||||
a,
|
||||
a:visited,
|
||||
a:hover,
|
||||
|
||||
+63
-62
@@ -1,64 +1,65 @@
|
||||
{
|
||||
"name": "step",
|
||||
"version": "1.0.0",
|
||||
"description": "step",
|
||||
"author": "Paolo Possanzini <paolo@teamdev.it>",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"build": "webpack",
|
||||
"dev": "webpack --watch"
|
||||
},
|
||||
"dependencies": {
|
||||
"axios": "0.17.1",
|
||||
"brace": "0.11.1",
|
||||
"chart.js": "^2.7.3",
|
||||
"izitoast": "1.2.0",
|
||||
"justgage": "^1.2.2",
|
||||
"moment": "2.20.1",
|
||||
"raphael": "^2.2.7",
|
||||
"sprintf-js": "1.1.1",
|
||||
"vee-validate": "2.0.3",
|
||||
"vue": "^2.5.2",
|
||||
"vue-chartjs": "^3.4.0",
|
||||
"vue-class-component": "6.1.0",
|
||||
"vue-drag-drop": "1.1.0",
|
||||
"vue-property-decorator": "6.0.0",
|
||||
"vue-router": "^3.0.1",
|
||||
"vue-smooth-dnd": "0.2.1",
|
||||
"vue2-ace-editor": "0.0.11",
|
||||
"vue2-datepicker": "2.6.2",
|
||||
"vuex": "3.0.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"autoprefixer": "^7.1.2",
|
||||
"babel-core": "^6.0.0",
|
||||
"babel-loader": "7.1.1",
|
||||
"babel-plugin-transform-decorators-legacy": "^1.3.4",
|
||||
"babel-plugin-transform-runtime": "^6.0.0",
|
||||
"babel-polyfill": "^6.23.0",
|
||||
"babel-preset-es2015": "^6.0.0",
|
||||
"babel-preset-stage-2": "^6.0.0",
|
||||
"babel-runtime": "^6.0.0",
|
||||
"babelify": "^7.2.0",
|
||||
"chalk": "^2.0.1",
|
||||
"copy-webpack-plugin": "^4.0.1",
|
||||
"css-loader": "^0.28.0",
|
||||
"eventsource-polyfill": "^0.9.6",
|
||||
"file-loader": "^1.1.4",
|
||||
"url-loader": "^0.5.8",
|
||||
"ts-loader": "3.1.1",
|
||||
"typescript": "2.6.1",
|
||||
"vue-loader": "^13.3.0",
|
||||
"vue-template-compiler": "^2.5.2",
|
||||
"webpack": "^3.6.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 4.0.0",
|
||||
"npm": ">= 3.0.0"
|
||||
},
|
||||
"browserslist": [
|
||||
"> 1%",
|
||||
"last 2 versions",
|
||||
"not ie <= 8"
|
||||
]
|
||||
"name": "step",
|
||||
"version": "1.0.0",
|
||||
"description": "step",
|
||||
"author": "Paolo Possanzini <paolo@teamdev.it>",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"build": "webpack",
|
||||
"dev": "webpack --watch"
|
||||
},
|
||||
"dependencies": {
|
||||
"axios": "0.17.1",
|
||||
"brace": "0.11.1",
|
||||
"chart.js": "^2.7.3",
|
||||
"izitoast": "1.2.0",
|
||||
"justgage": "^1.2.2",
|
||||
"moment": "2.20.1",
|
||||
"raphael": "^2.2.7",
|
||||
"sprintf-js": "1.1.1",
|
||||
"v-tooltip": "^2.0.0-rc.33",
|
||||
"vee-validate": "2.0.3",
|
||||
"vue": "^2.5.2",
|
||||
"vue-chartjs": "^3.4.0",
|
||||
"vue-class-component": "6.1.0",
|
||||
"vue-drag-drop": "1.1.0",
|
||||
"vue-property-decorator": "6.0.0",
|
||||
"vue-router": "^3.0.1",
|
||||
"vue-smooth-dnd": "0.2.1",
|
||||
"vue2-ace-editor": "0.0.11",
|
||||
"vue2-datepicker": "2.6.2",
|
||||
"vuex": "3.0.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"autoprefixer": "^7.1.2",
|
||||
"babel-core": "^6.0.0",
|
||||
"babel-loader": "7.1.1",
|
||||
"babel-plugin-transform-decorators-legacy": "^1.3.4",
|
||||
"babel-plugin-transform-runtime": "^6.0.0",
|
||||
"babel-polyfill": "^6.23.0",
|
||||
"babel-preset-es2015": "^6.0.0",
|
||||
"babel-preset-stage-2": "^6.0.0",
|
||||
"babel-runtime": "^6.0.0",
|
||||
"babelify": "^7.2.0",
|
||||
"chalk": "^2.0.1",
|
||||
"copy-webpack-plugin": "^4.0.1",
|
||||
"css-loader": "^0.28.0",
|
||||
"eventsource-polyfill": "^0.9.6",
|
||||
"file-loader": "^1.1.4",
|
||||
"url-loader": "^0.5.8",
|
||||
"ts-loader": "3.1.1",
|
||||
"typescript": "2.6.1",
|
||||
"vue-loader": "^13.3.0",
|
||||
"vue-template-compiler": "^2.5.2",
|
||||
"webpack": "^3.6.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 4.0.0",
|
||||
"npm": ">= 3.0.0"
|
||||
},
|
||||
"browserslist": [
|
||||
"> 1%",
|
||||
"last 2 versions",
|
||||
"not ie <= 8"
|
||||
]
|
||||
}
|
||||
|
||||
+53
-22
@@ -1,26 +1,57 @@
|
||||
declare module server {
|
||||
export interface reportData {
|
||||
absoluteValue: number;
|
||||
productedPieces: number;
|
||||
discardedPieces: number;
|
||||
}
|
||||
|
||||
export interface reportData {
|
||||
absoluteValue: number,
|
||||
productedPieces: number,
|
||||
discardedPieces: number
|
||||
}
|
||||
export interface pieChartData {
|
||||
stop: number;
|
||||
run: number;
|
||||
idle: number;
|
||||
}
|
||||
|
||||
export interface pieChartData {
|
||||
stop: number,
|
||||
run: number,
|
||||
idle: number
|
||||
}
|
||||
export interface programTableData {
|
||||
progName: string;
|
||||
quantity: number;
|
||||
startDate: Date;
|
||||
endDate: Date;
|
||||
actualT: string;
|
||||
averageT: string;
|
||||
theoricT: string;
|
||||
deviation: string;
|
||||
frequency: number;
|
||||
}
|
||||
|
||||
export interface programTableData {
|
||||
progName: string,
|
||||
quantity: number,
|
||||
startDate: Date,
|
||||
endDate: Date,
|
||||
actualT: string,
|
||||
averageT: string,
|
||||
theoricT: string,
|
||||
deviation: string,
|
||||
frequency: number
|
||||
}
|
||||
}
|
||||
export interface timeLineChartData {
|
||||
partPrgs: timeLineChartProduzione[];
|
||||
statusData: timeLineChartStatoMacchina;
|
||||
}
|
||||
|
||||
export interface timeLineChartProduzione {
|
||||
name: string;
|
||||
executed: string;
|
||||
frequency: string;
|
||||
occurrences: timeLineChartTask[];
|
||||
}
|
||||
|
||||
export interface timeLineChartStatoMacchina {
|
||||
run: timeLineChartTask[];
|
||||
idle: timeLineChartTask[];
|
||||
stop: timeLineChartTask[];
|
||||
}
|
||||
|
||||
export interface timeLineChartTask {
|
||||
from: string;
|
||||
to: string;
|
||||
}
|
||||
|
||||
export interface timeLineChartItem {
|
||||
name: string;
|
||||
executed: string;
|
||||
frequency: string;
|
||||
color: string
|
||||
from: string,
|
||||
to: string
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,53 +1,150 @@
|
||||
import Vue from "vue";
|
||||
import Component from "vue-class-component";
|
||||
import { cardReport } from "../../../modules/base-components/cards/index";
|
||||
import accordionDropdown from "../../../modules/base-components/accordion-dropdown.vue";
|
||||
import modalReportSelectColumn from "../../../modules/base-components/modal-report-select-column.vue";
|
||||
import { Accordion } from "src/modules/base-components";
|
||||
import { loginService } from "src/services";
|
||||
import { Component, Watch } from "vue-property-decorator";
|
||||
import { cardReport } from "src/modules/base-components/cards/index";
|
||||
import accordionDropdown from "src/modules/base-components/accordion-dropdown.vue";
|
||||
import DatePicker from "vue2-datepicker";
|
||||
import moment from "moment";
|
||||
import { ModalHelper } from "src/components/modals";
|
||||
import { ReportGetters } from "../../../store/report.store";
|
||||
import { Watch } from "vue-property-decorator";
|
||||
import { ReportGetters } from "src/store/report.store";
|
||||
import { reportService } from "src/services/reportService";
|
||||
import { TimeLineChartHeader, TimeLineChartRow } from "src/components/timeline-chart";
|
||||
|
||||
declare let $: any;
|
||||
declare var JustGage: any;
|
||||
@Component({ components: { datePicker: DatePicker, cardReport: cardReport, accordionDropdown: accordionDropdown } })
|
||||
|
||||
@Component({
|
||||
components: {
|
||||
datePicker: DatePicker,
|
||||
cardReport: cardReport,
|
||||
accordionDropdown: accordionDropdown,
|
||||
"timeline-chart-row": TimeLineChartRow,
|
||||
"timeline-chart-header": TimeLineChartHeader
|
||||
}
|
||||
})
|
||||
export default class CardReportTimeline extends Vue {
|
||||
|
||||
lang = {
|
||||
days: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'],
|
||||
months: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
|
||||
pickers: ['next 7 days', 'next 30 days', 'previous 7 days', 'previous 30 days'],
|
||||
days: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"],
|
||||
months: [
|
||||
"Jan",
|
||||
"Feb",
|
||||
"Mar",
|
||||
"Apr",
|
||||
"May",
|
||||
"Jun",
|
||||
"Jul",
|
||||
"Aug",
|
||||
"Sep",
|
||||
"Oct",
|
||||
"Nov",
|
||||
"Dec"
|
||||
],
|
||||
pickers: [
|
||||
"next 7 days",
|
||||
"next 30 days",
|
||||
"previous 7 days",
|
||||
"previous 30 days"
|
||||
],
|
||||
placeholder: {
|
||||
date: 'Select Date',
|
||||
dateRange: 'Select Date Range'
|
||||
date: "Select Date",
|
||||
dateRange: "Select Date Range"
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
get dataPieces() : server.reportData{
|
||||
return (this.$store.getters as ReportGetters).getReportData();
|
||||
}
|
||||
occurrences: any = {
|
||||
machine_status: {
|
||||
total: [] as server.timeLineChartItem[],
|
||||
run: [] as server.timeLineChartItem[],
|
||||
idle: [] as server.timeLineChartItem[],
|
||||
stop: [] as server.timeLineChartItem[]
|
||||
},
|
||||
programs: {
|
||||
total: [] as server.timeLineChartItem[],
|
||||
items: [] as server.timeLineChartItem[]
|
||||
}
|
||||
};
|
||||
|
||||
private defaultStartDate: Date = new Date(2019, 0, 1); //new Date(new Date().setDate(new Date().getDate() - 6));
|
||||
private defaultEndDate: Date = new Date(2019, 0, 31); //new Date(new Date().setDate(new Date().getDate() + 1));
|
||||
|
||||
filter: {
|
||||
interval?: Date[],
|
||||
timelineMacro: Array<string>,
|
||||
interval?: Date[];
|
||||
timelineMacro: Array<string>;
|
||||
currentTime: Date;
|
||||
} = {
|
||||
timelineMacro: ["Allarmi", "Stato macchina", "Programmi"],
|
||||
interval: [new Date(new Date().setDate(new Date().getDate() - 6)), new Date(new Date().setDate(new Date().getDate() + 1))]
|
||||
timelineMacro: ["Stato macchina", "Programmi"],
|
||||
interval: [],
|
||||
currentTime: null
|
||||
};
|
||||
|
||||
interval: {
|
||||
date?: Date[];
|
||||
startTime: Date;
|
||||
endTime: Date;
|
||||
} = {
|
||||
date: [new Date(2019, 0, 1), new Date(2019, 0, 31)],
|
||||
startTime: null,
|
||||
endTime: null,
|
||||
};
|
||||
|
||||
filterName: string = "";
|
||||
public searchText: string = "";
|
||||
|
||||
async mounted() {
|
||||
this.filterIntervalChange(this.interval.date, null);
|
||||
this.buildGage();
|
||||
await this.getData();
|
||||
}
|
||||
|
||||
|
||||
@Watch("searchText")
|
||||
public applyFilter(n) {
|
||||
this.filterName = n.toLowerCase();
|
||||
}
|
||||
|
||||
mounted() {
|
||||
this.buildGage();
|
||||
@Watch("interval.date", { immediate: true })
|
||||
public filterIntervalChange(n: Date[], o: Date[]) {
|
||||
if(!n || (n && n.length < 0))
|
||||
{
|
||||
this.interval.date = [this.defaultStartDate, this.defaultEndDate]
|
||||
return;
|
||||
}
|
||||
if(n && n.length > 0 && n !== o)
|
||||
{
|
||||
// let startDate = n[0];
|
||||
// let endDate = new Date(n[1].setHours(23, 59, 59));
|
||||
|
||||
// this.filter.interval = [startDate, endDate];
|
||||
this.filter.interval = this.interval.date;
|
||||
this.filter.currentTime = new Date((this.filter.interval[1].getTime() + this.filter.interval[0].getTime()) / 2);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
get dataPieces(): server.reportData {
|
||||
return (this.$store.getters as ReportGetters).getReportData();
|
||||
}
|
||||
|
||||
oneDay: number = 24 * 60 * 60 * 1000;
|
||||
get diffDays(): number {
|
||||
return Math.round(Math.abs((this.interval.date[1].getTime() - this.interval.date[0].getTime()) / this.oneDay)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
handleZoomIn(){
|
||||
let interval = (this.interval.date[1].getTime() - this.interval.date[0].getTime()) / 2;
|
||||
this.setZoom(interval)
|
||||
}
|
||||
|
||||
handleZoomOut(){
|
||||
let interval = (this.interval.date[1].getTime() - this.interval.date[0].getTime()) * 2;
|
||||
this.setZoom(interval);
|
||||
}
|
||||
|
||||
private setZoom(interval){
|
||||
let middle = (interval / 2);
|
||||
let start = new Date(this.filter.currentTime.getTime() - middle);
|
||||
let end = new Date(this.filter.currentTime.getTime() + middle);
|
||||
this.interval.date = [start, end];
|
||||
}
|
||||
|
||||
buildGage() {
|
||||
@@ -59,15 +156,93 @@ export default class CardReportTimeline extends Vue {
|
||||
});
|
||||
}
|
||||
|
||||
isVisible(value){
|
||||
async getData() {
|
||||
let occurrences = await reportService.TimeLine(this.filter.interval.map(x => x.toString()));
|
||||
this.occurrences = {
|
||||
machine_status: {
|
||||
total: [] as server.timeLineChartItem[],
|
||||
run: [] as server.timeLineChartItem[],
|
||||
idle: [] as server.timeLineChartItem[],
|
||||
stop: [] as server.timeLineChartItem[]
|
||||
},
|
||||
programs: {
|
||||
total: [] as server.timeLineChartItem[],
|
||||
items: [] as server.timeLineChartItem[]
|
||||
}
|
||||
};
|
||||
|
||||
(
|
||||
(occurrences.statusData || ({} as server.timeLineChartStatoMacchina))
|
||||
.run || ([] as server.timeLineChartTask[])
|
||||
).forEach(m => {
|
||||
let elem = {
|
||||
from: m.from,
|
||||
to: m.to,
|
||||
name: "run",
|
||||
color: "#7ed321"
|
||||
} as server.timeLineChartItem;
|
||||
this.occurrences.machine_status.run.push(elem);
|
||||
this.occurrences.machine_status.total.push(elem);
|
||||
});
|
||||
|
||||
(
|
||||
(occurrences.statusData || ({} as server.timeLineChartStatoMacchina))
|
||||
.idle || ([] as server.timeLineChartTask[])
|
||||
).forEach(m => {
|
||||
let elem = {
|
||||
from: m.from,
|
||||
to: m.to,
|
||||
name: "idle",
|
||||
color: "#e3d300"
|
||||
} as server.timeLineChartItem;
|
||||
this.occurrences.machine_status.idle.push(elem);
|
||||
this.occurrences.machine_status.total.push(elem);
|
||||
});
|
||||
|
||||
(
|
||||
(occurrences.statusData || ({} as server.timeLineChartStatoMacchina))
|
||||
.stop || ([] as server.timeLineChartTask[])
|
||||
).forEach(m => {
|
||||
let elem = {
|
||||
from: m.from,
|
||||
to: m.to,
|
||||
name: "stop",
|
||||
color: "#ff4a60"
|
||||
} as server.timeLineChartItem;
|
||||
this.occurrences.machine_status.stop.push(elem);
|
||||
this.occurrences.machine_status.total.push(elem);
|
||||
});
|
||||
|
||||
(occurrences.partPrgs || ([] as server.timeLineChartProduzione[])).forEach(
|
||||
item => {
|
||||
let elem = {
|
||||
name: item.name,
|
||||
occurrences: [] as server.timeLineChartItem[]
|
||||
};
|
||||
item.occurrences.forEach(m => {
|
||||
let oc = {
|
||||
from: m.from,
|
||||
to: m.to,
|
||||
name: item.name,
|
||||
frequency: item.frequency,
|
||||
executed: item.executed,
|
||||
color: "#76baf7"
|
||||
} as server.timeLineChartItem;
|
||||
elem.occurrences.push(oc);
|
||||
this.occurrences.programs.total.push(oc);
|
||||
});
|
||||
this.occurrences.programs.items.push(elem);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
isVisible(value) {
|
||||
return this.filter.timelineMacro.some(c => c == value);
|
||||
}
|
||||
|
||||
public openSelectState() {
|
||||
if (!$('.checkboxes').hasClass('checkboxesView'))
|
||||
$('.checkboxes').addClass('checkboxesView');
|
||||
else
|
||||
$('.checkboxes').removeClass('checkboxesView');
|
||||
if (!$(".checkboxes").hasClass("checkboxesView"))
|
||||
$(".checkboxes").addClass("checkboxesView");
|
||||
else $(".checkboxes").removeClass("checkboxesView");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,153 +1,191 @@
|
||||
<template>
|
||||
<div class="card-report-timeline">
|
||||
<div class="reports-box-body-left">
|
||||
<div class="body-left-header">
|
||||
<div>
|
||||
<label class="intervaldate">{{'reports_body_header_date_range' | localize("Intervallo date")}}</label>
|
||||
<date-picker v-model="filter.interval" range type="daterange" :lang="lang"></date-picker>
|
||||
<div class="reports-box-body-left">
|
||||
<div class="body-left-header">
|
||||
<div>
|
||||
<label class="intervaldate">{{'reports_body_header_date_range' | localize("Intervallo date")}}</label>
|
||||
<date-picker v-model="interval.date" range type="daterange" :lang="lang"></date-picker>
|
||||
</div>
|
||||
<div>
|
||||
<label>{{'reports_body_header_label_hour' | localize("Intervallo orario")}}</label>
|
||||
<div class="interval-time">
|
||||
<input type="time" v-model="interval.startTime" />
|
||||
<input type="time" v-model="interval.endTime"/>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<label>{{'reports_body_header_label_program' | localize("Programma")}}</label>
|
||||
<input type="text" class="program" v-model="searchText" :placeholder="'reports_body_header_placeholder_program' | localize('Nome del programma')" />
|
||||
</div>
|
||||
<div class="zoom-control">
|
||||
<button @click="handleZoomOut()"
|
||||
:disabled="((interval.date[1].getFullYear() - interval.date[0].getFullYear()) >= 2)">
|
||||
<i class="fa fa-search-minus fa-2x"></i></button>
|
||||
<button @click="handleZoomIn()"
|
||||
:disabled="((interval.date[1].getTime() - interval.date[0].getTime()) <= oneDay && diffDays == 0)">
|
||||
<i class="fa fa-search-plus fa-2x"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="body-left-center">
|
||||
<div class="body-left-center-header">
|
||||
<div class="body-left-center-left">
|
||||
<div class="multiselect">
|
||||
<div class="selectBox" @click="openSelectState()">
|
||||
<select id="selectListCheckboxes">
|
||||
<option>
|
||||
<span v-for="(item, index) in filter.timelineMacro" :key="item" >
|
||||
{{'report_state_'+item | localize(item)}}{{(index==filter.timelineMacro.length-1)?'':', '}}
|
||||
</span>
|
||||
</option>
|
||||
<div class="overSelect"></div>
|
||||
</select>
|
||||
</div>
|
||||
<!-- <div>
|
||||
<label>{{'reports_body_header_label_hour' | localize("Intervallo orario")}}</label>
|
||||
<div class="interval-time">
|
||||
<input type="time"/>
|
||||
<input type="time"/>
|
||||
<div class="checkboxes">
|
||||
<div>
|
||||
<label for="Stato macchina">
|
||||
<div class="custom-checkbox">
|
||||
<input type="checkbox" v-model="filter.timelineMacro" value="Stato macchina" id="Stato macchina" />
|
||||
<label for="Stato macchina"></label>
|
||||
</div>
|
||||
<label class="label-state">{{'report_timeline_filter_machine_status' | localize("Stato macchina")}}</label>
|
||||
</label>
|
||||
</div>
|
||||
<div>
|
||||
<label for="Programmi">
|
||||
<div class="custom-checkbox">
|
||||
<input type="checkbox" v-model="filter.timelineMacro" value="Programmi" id="Programmi" />
|
||||
<label for="Programmi"></label>
|
||||
</div>
|
||||
<label class="label-state">{{'report_timeline_filter_programs' | localize("Programmi")}}</label>
|
||||
</label>
|
||||
</div>
|
||||
</div> -->
|
||||
<div>
|
||||
<label>{{'reports_body_header_label_program' | localize("Programma")}}</label>
|
||||
<input type="text" class="program" v-model="searchText" :placeholder="'reports_body_header_placeholder_program' | localize('Nome del programma')" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="body-left-center">
|
||||
<div class="body-left-center-container">
|
||||
<div class="body-left-center-left">
|
||||
<div class="multiselect">
|
||||
<div class="selectBox" @click="openSelectState()">
|
||||
<select id="selectListCheckboxes">
|
||||
<option><span v-for="(item, index) in filter.timelineMacro" :key="item" >{{'report_state_'+item | localize(item)}}{{(index==filter.timelineMacro.length-1)?'':', '}}</span></option>
|
||||
<div class="overSelect"></div>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="checkboxes">
|
||||
<!-- <div>
|
||||
<label for="Eventi">
|
||||
<div class="custom-checkbox">
|
||||
<input type="checkbox" v-model="filter.timelineMacro" value="Eventi" id="Eventi" />
|
||||
<label for="Eventi"></label>
|
||||
</div>
|
||||
<label class="label-state">{{'report_timeline_filter_events' | localize("Eventi")}}</label>
|
||||
</label>
|
||||
</div> -->
|
||||
<div>
|
||||
<label for="Allarmi">
|
||||
<div class="custom-checkbox">
|
||||
<input type="checkbox" v-model="filter.timelineMacro" value="Allarmi" id="Allarmi" />
|
||||
<label for="Allarmi"></label>
|
||||
</div>
|
||||
<label class="label-state">{{'report_timeline_filter_alarms' | localize("Allarmi")}}</label>
|
||||
</label>
|
||||
</div>
|
||||
<div>
|
||||
<label for="Stato macchina">
|
||||
<div class="custom-checkbox">
|
||||
<input type="checkbox" v-model="filter.timelineMacro" value="Stato macchina" id="Stato macchina" />
|
||||
<label for="Stato macchina"></label>
|
||||
</div>
|
||||
<label class="label-state">{{'report_timeline_filter_machine_status' | localize("Stato macchina")}}</label>
|
||||
</label>
|
||||
</div>
|
||||
<div>
|
||||
<label for="Programmi">
|
||||
<div class="custom-checkbox">
|
||||
<input type="checkbox" v-model="filter.timelineMacro" value="Programmi" id="Programmi" />
|
||||
<label for="Programmi"></label>
|
||||
</div>
|
||||
<label class="label-state">{{'report_timeline_filter_programs' | localize("Programmi")}}</label>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="isVisible('Eventi')">
|
||||
<accordion-dropdown :title="'reports_body_left_center_left_dropdown_title_events' | localize('Eventi')">
|
||||
<div class="dropdown">
|
||||
<div class="item">
|
||||
<div class="filename"><i class="fa fa-file"></i><span>Test</span></div>
|
||||
</div>
|
||||
</div>
|
||||
</accordion-dropdown>
|
||||
</div>
|
||||
<div v-if="isVisible('Allarmi')">
|
||||
<accordion-dropdown :title="'reports_body_left_center_left_dropdown_title_alarms' | localize('Allarmi')">
|
||||
<div class="dropdown">
|
||||
<div class="item">
|
||||
<div class="filename"><i class="fa fa-file"></i><span>Test</span></div>
|
||||
</div>
|
||||
</div>
|
||||
</accordion-dropdown>
|
||||
</div>
|
||||
<div v-if="isVisible('Stato macchina')">
|
||||
<accordion-dropdown :title="'reports_body_left_center_left_dropdown_title_machine_status' | localize('Stato macchina')">
|
||||
<div class="dropdown">
|
||||
<div class="item">
|
||||
<div class="filename"><i class="fa fa-file"></i><span>Test</span></div>
|
||||
</div>
|
||||
</div>
|
||||
</accordion-dropdown>
|
||||
</div>
|
||||
<div v-if="isVisible('Programmi')">
|
||||
<accordion-dropdown :title="'reports_body_left_center_left_dropdown_title_programs' | localize('Programmi')">
|
||||
<div class="dropdown">
|
||||
<div class="item">
|
||||
<div class="filename"><i class="fa fa-file"></i><span>Test</span></div>
|
||||
</div>
|
||||
</div>
|
||||
</accordion-dropdown>
|
||||
</div>
|
||||
</div>
|
||||
<div class="body-left-center-right">
|
||||
</div>
|
||||
</div>
|
||||
<div class="body-left-center-footer">
|
||||
<div class="header-title">
|
||||
<div class="title">
|
||||
{{'reports_body_left_center_footer_title_time_slider' | localize('Cursore temporale')}}
|
||||
</div>
|
||||
<div class="data-temporal">
|
||||
09 Aprile 2017 - 23:14
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="body-left-center-right">
|
||||
<timeline-chart-header v-if="filter.interval.length == 2" v-model="filter.currentTime"
|
||||
:start="filter.interval[0]"
|
||||
:end="filter.interval[1]"
|
||||
:interval="40"
|
||||
show-cursor></timeline-chart-header>
|
||||
</div>
|
||||
</div>
|
||||
<div class="body-left-center-container">
|
||||
<div class="body-left-center-left">
|
||||
<div v-if="isVisible('Stato macchina')">
|
||||
<accordion-dropdown>
|
||||
<template slot="header">
|
||||
<span>{{'reports_body_left_center_left_dropdown_title_machine_status' | localize('Stato macchina')}}</span>
|
||||
<div class="row-chart">
|
||||
<timeline-chart-row v-if="filter.interval.length == 2 && occurrences.machine_status.total.length > 0"
|
||||
:start="filter.interval[0]"
|
||||
:end="filter.interval[1]"
|
||||
:occurrences="occurrences.machine_status.total"></timeline-chart-row>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<div class="dropdown">
|
||||
<div class="item">
|
||||
<div class="filename"><i class="fa fa-file"></i><span>run</span></div>
|
||||
<div class="row-chart">
|
||||
<timeline-chart-row v-if="filter.interval.length == 2 && occurrences.machine_status.run.length > 0"
|
||||
:start="filter.interval[0]"
|
||||
:end="filter.interval[1]"
|
||||
:occurrences="occurrences.machine_status.run"
|
||||
:color="'#7ed321'"></timeline-chart-row>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="dropdown">
|
||||
<div class="item">
|
||||
<div class="filename"><i class="fa fa-file"></i><span>idle</span></div>
|
||||
<div class="row-chart">
|
||||
<timeline-chart-row v-if="filter.interval.length == 2 && occurrences.machine_status.idle.length > 0"
|
||||
:start="filter.interval[0]"
|
||||
:end="filter.interval[1]"
|
||||
:occurrences="occurrences.machine_status.idle"
|
||||
:color="'#e3d300'"></timeline-chart-row>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="dropdown">
|
||||
<div class="item">
|
||||
<div class="filename"><i class="fa fa-file"></i><span>stop</span></div>
|
||||
<div class="row-chart">
|
||||
<timeline-chart-row v-if="filter.interval.length == 2 && occurrences.machine_status.stop.length > 0"
|
||||
:start="filter.interval[0]"
|
||||
:end="filter.interval[1]"
|
||||
:occurrences="occurrences.machine_status.stop"
|
||||
:color="'#ff4a60'"></timeline-chart-row>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</accordion-dropdown>
|
||||
</div>
|
||||
<div v-if="isVisible('Programmi')">
|
||||
<accordion-dropdown>
|
||||
<template slot="header">
|
||||
<span>{{'reports_body_left_center_left_dropdown_title_programs' | localize('Programmi')}}</span>
|
||||
<div class="row-chart">
|
||||
<timeline-chart-row v-if="filter.interval.length == 2 && occurrences.programs.total.length > 0"
|
||||
:start="filter.interval[0]"
|
||||
:end="filter.interval[1]"
|
||||
:occurrences="occurrences.programs.total"></timeline-chart-row>
|
||||
</div>
|
||||
</template>
|
||||
<div class="dropdown" v-for="(item, index) in occurrences.programs.items" :key="index">
|
||||
<div class="item">
|
||||
<div class="filename"><i class="fa fa-file"></i><span>{{item.name}}</span></div>
|
||||
<div class="row-chart">
|
||||
<timeline-chart-row v-if="filter.interval.length == 2 && item.occurrences && item.occurrences.length > 0"
|
||||
:start="filter.interval[0]"
|
||||
:end="filter.interval[1]"
|
||||
:occurrences="item.occurrences"></timeline-chart-row>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</accordion-dropdown>
|
||||
</div>
|
||||
</div>
|
||||
<!-- <div class="body-left-center-right"></div> -->
|
||||
</div>
|
||||
<div class="body-left-center-footer">
|
||||
<div class="header-title">
|
||||
<div class="title">
|
||||
{{'reports_body_left_center_footer_title_time_slider' | localize('Cursore temporale')}}
|
||||
</div>
|
||||
<div class="data-temporal">
|
||||
{{filter.currentTime | date("DD MMMM YYYY - HH:mm")}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="reports-box-body-right">
|
||||
<div class="body-right-header">
|
||||
<div class="body-right-header-right">
|
||||
<button><i class="fa fa-print fa-2x"></i></button>
|
||||
<button><i class="fa fa-upload fa-2x"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="body-right-card">
|
||||
<card-report :title="'Valore assoluto (%)'">
|
||||
<div id="gauge" class="gauge"></div>
|
||||
</card-report>
|
||||
<card-report :title="'Valore assoluto'">
|
||||
<div class="rectangle_gray">
|
||||
<label>{{'reports_body_rectangle_label_pieces produced' | localize("Pezzi prodotti")}}</label>
|
||||
<!-- <span>10.000</span> -->
|
||||
<span>{{dataPieces.productedPieces}}</span>
|
||||
</div>
|
||||
</card-report>
|
||||
<card-report :title="'Valore assoluto'">
|
||||
<div class="rectangle_gray">
|
||||
<label>{{'reports_body_rectangle_label_discarded_pieces' | localize("Pezzi scartati")}}</label>
|
||||
<span>{{dataPieces.discardedPieces}}</span>
|
||||
</div>
|
||||
</card-report>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="reports-box-body-right">
|
||||
<div class="body-right-header">
|
||||
<div class="body-right-header-right">
|
||||
<button><i class="fa fa-print fa-2x"></i></button>
|
||||
<button><i class="fa fa-upload fa-2x"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="body-right-card">
|
||||
<card-report :title="'Valore assoluto (%)'">
|
||||
<div id="gauge" class="gauge"></div>
|
||||
</card-report>
|
||||
<card-report :title="'Valore assoluto'">
|
||||
<div class="rectangle_gray">
|
||||
<label>{{'reports_body_rectangle_label_pieces produced' | localize("Pezzi prodotti")}}</label>
|
||||
<span>{{dataPieces.productedPieces}}</span>
|
||||
</div>
|
||||
</card-report>
|
||||
<card-report :title="'Valore assoluto'">
|
||||
<div class="rectangle_gray">
|
||||
<label>{{'reports_body_rectangle_label_discarded_pieces' | localize("Pezzi scartati")}}</label>
|
||||
<span>{{dataPieces.discardedPieces}}</span>
|
||||
</div>
|
||||
</card-report>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</template>
|
||||
|
||||
<script src="./card-report-timeline.ts" lang="ts"></script>
|
||||
<script src="./card-report-timeline.ts" lang="ts"></script>
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
import TimeLineChartRow from "./timeline-chart-row.vue";
|
||||
import TimeLineChartHeader from "./timeline-chart-header.vue";
|
||||
|
||||
export {
|
||||
TimeLineChartRow,
|
||||
TimeLineChartHeader
|
||||
}
|
||||
@@ -0,0 +1,228 @@
|
||||
import Vue from "vue";
|
||||
import { Component, Prop, Watch } from "vue-property-decorator";
|
||||
import moment from "moment";
|
||||
import { Container, Draggable } from "vue-smooth-dnd";
|
||||
|
||||
@Component({
|
||||
components: {
|
||||
Container,
|
||||
Draggable
|
||||
}
|
||||
})
|
||||
export default class TimeLineChartRow extends Vue {
|
||||
@Prop({ required: true })
|
||||
value: Date;
|
||||
|
||||
@Prop({ required: true })
|
||||
start: Date;
|
||||
|
||||
@Prop({ required: true })
|
||||
end: Date;
|
||||
|
||||
@Prop({ required: false, default: 40 })
|
||||
interval: number;
|
||||
|
||||
@Prop({ required: false, default: true })
|
||||
showCursor: boolean;
|
||||
|
||||
current: Date = this.value;
|
||||
formatter = {
|
||||
title: "MMMM YYYY",
|
||||
titleInterval: false,
|
||||
interval: "DD",
|
||||
showTime: false
|
||||
};
|
||||
isHandlerDragging: boolean = false;
|
||||
draggingIn: boolean;
|
||||
draggingPosition: any;
|
||||
draggingTool: any;
|
||||
|
||||
oneHour: number = 60 * 60 * 1000;
|
||||
oneDay: number = 24 * this.oneHour;
|
||||
|
||||
@Watch("value")
|
||||
valueChange(value) {
|
||||
this.current = value;
|
||||
}
|
||||
|
||||
get _start(): Date {
|
||||
let _startTime = this.start.getTime();
|
||||
let _endTime = this.end.getTime();
|
||||
let _diffDays = Math.round(Math.abs((_endTime - _startTime) / this.oneDay));
|
||||
if(_diffDays == 0)
|
||||
{
|
||||
_startTime = (new Date(_startTime).setMinutes(0,0));
|
||||
_endTime = (new Date(_endTime).setMinutes(59,59));
|
||||
return new Date(_startTime - this.oneHour);
|
||||
}
|
||||
_startTime = (new Date(_startTime).setHours(0,0,0));
|
||||
_endTime = (new Date(_endTime).setHours(23,59,59));
|
||||
return new Date(_startTime - this.oneDay);
|
||||
}
|
||||
|
||||
get _end(): Date {
|
||||
let _startTime = this.start.getTime();
|
||||
let _endTime = this.end.getTime();
|
||||
let _diffDays = Math.round(Math.abs((_endTime - _startTime) / this.oneDay));
|
||||
|
||||
if(_diffDays == 0)
|
||||
{
|
||||
_startTime = (new Date(_startTime).setMinutes(0,0));
|
||||
_endTime = (new Date(_endTime).setMinutes(59,59));
|
||||
return new Date(_endTime + this.oneHour);
|
||||
}
|
||||
_startTime = (new Date(_startTime).setHours(0,0,0));
|
||||
_endTime = (new Date(_endTime).setHours(23,59,59));
|
||||
return new Date(_endTime + this.oneDay);
|
||||
}
|
||||
|
||||
get intervals(): Date[] {
|
||||
this.bindFormatter()
|
||||
let result: Date[] = [];
|
||||
let step = this.oneDay;
|
||||
|
||||
let diffDays = this.diffDays;
|
||||
let diffHours = this.diffHours;
|
||||
|
||||
if (diffDays <= 1) {
|
||||
step = this.oneHour;
|
||||
let check = Math.ceil(diffHours / this.interval);
|
||||
if (check > 1) step = this.oneHour * check;
|
||||
}
|
||||
else {
|
||||
step = this.oneDay;
|
||||
let check = Math.ceil(diffDays / this.interval);
|
||||
if (check > 1) {
|
||||
step = this.oneDay * check
|
||||
};
|
||||
}
|
||||
|
||||
let interval = this.startTime;
|
||||
while (this.endTime >= interval) {
|
||||
result.push(new Date(interval + (step / 2)));
|
||||
interval += step;
|
||||
}
|
||||
|
||||
// if (this._end.setHours(0,0,0,0) != result[result.length - 1].getTime())
|
||||
// result.push(this._end);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
get startTime(): number {
|
||||
return this.parseToUnixTime(this._start);
|
||||
}
|
||||
|
||||
get endTime(): number {
|
||||
return this.parseToUnixTime(this._end);
|
||||
}
|
||||
|
||||
get diffTime(): number {
|
||||
return this.endTime - this.startTime;
|
||||
}
|
||||
|
||||
get diffDays(): number {
|
||||
return Math.round(Math.abs((this._end.getTime() - this._start.getTime()) / this.oneDay)
|
||||
);
|
||||
}
|
||||
|
||||
get diffHours(): number {
|
||||
return Math.round(
|
||||
Math.abs((this._end.getTime() - this._start.getTime()) / this.oneHour)
|
||||
);
|
||||
}
|
||||
|
||||
get cursorPosition(): number {
|
||||
return this.unixTimeToPercent(this.current.getTime());
|
||||
}
|
||||
|
||||
private bindFormatter(): any {
|
||||
let _startTime = this.start.getTime();
|
||||
let _endTime = this.end.getTime();
|
||||
let _diffDays = Math.round(Math.abs((_endTime - _startTime) / this.oneDay));
|
||||
|
||||
if(_diffDays == 0){
|
||||
this.formatter.titleInterval = false;
|
||||
this.formatter.title = "DD MMMM YYYY";
|
||||
this.formatter.interval = "HH:mm"
|
||||
this.formatter.showTime = true;
|
||||
return new Date(_startTime - this.oneHour);
|
||||
}
|
||||
else
|
||||
{
|
||||
this.formatter.titleInterval = false;
|
||||
this.formatter.title = "MMMM YYYY";
|
||||
this.formatter.interval = "DD"
|
||||
this.formatter.showTime = false;
|
||||
|
||||
let _monthDiff = this.monthDiff(this.start, this.end);
|
||||
if(_monthDiff > 0)
|
||||
{
|
||||
this.formatter.titleInterval = true;
|
||||
this.formatter.title = "MMMM YYYY";
|
||||
this.formatter.interval = "DD/MM"
|
||||
this.formatter.showTime = false;
|
||||
|
||||
let _yearDiff = this.yearDiff(this.start, this.end);
|
||||
if(_yearDiff > 0)
|
||||
{
|
||||
this.formatter.titleInterval = true;
|
||||
if(_monthDiff > 3)
|
||||
{
|
||||
this.formatter.title = "MMMM YYYY";
|
||||
this.formatter.interval = "DD/MM/YY"
|
||||
this.formatter.showTime = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private monthDiff(start: Date, end: Date) : number {
|
||||
let months = (end.getFullYear() - start.getFullYear()) * 12;
|
||||
months -= start.getMonth();
|
||||
months += end.getMonth();
|
||||
return months <= 0 ? 0 : months;
|
||||
}
|
||||
|
||||
private yearDiff(start: Date, end: Date) : number {
|
||||
return end.getFullYear() - start.getFullYear();
|
||||
}
|
||||
|
||||
private _moving: boolean = false;
|
||||
startMove(evt: PointerEvent) {
|
||||
this._moving = true;
|
||||
(this.$refs.cursone as HTMLElement).setPointerCapture(evt.pointerId);
|
||||
}
|
||||
|
||||
moving(evt: PointerEvent) {
|
||||
if (!this._moving) return;
|
||||
|
||||
let w = (this.$refs.header as HTMLElement).clientWidth;
|
||||
let step = this.diffTime / w;
|
||||
var ct = this.current.getTime() + step * evt.movementX;
|
||||
let currentDate = new Date(Math.max(Math.min(ct, this.endTime), this.startTime));
|
||||
this.$emit("input", currentDate);
|
||||
}
|
||||
|
||||
stopMove(evt: PointerEvent) {
|
||||
this._moving = false;
|
||||
(this.$refs.cursone as HTMLElement).releasePointerCapture(evt.pointerId);
|
||||
}
|
||||
|
||||
private parseToUnixTime(date: string | Date): number {
|
||||
if (typeof date === "object") return date.getTime();
|
||||
|
||||
if (typeof date === "string") {
|
||||
let _date = moment(date, "DD/MM/YYYY").toDate();
|
||||
if (!isNaN(_date.getTime())) return _date.getTime();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
private unixTimeToPercent(unixTime: number): number {
|
||||
return (
|
||||
((unixTime - this.parseToUnixTime(this._start)) * 100) / this.diffTime
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
<template>
|
||||
<div class="timeline-chart-header" ref="header" >
|
||||
<div class="timeline-chart-header-title" v-if="formatter.titleInterval">
|
||||
<small><i>da</i></small> {{this.start | date(formatter.title)}}
|
||||
<small><i>a</i></small> {{this.end | date(formatter.title)}}
|
||||
</div>
|
||||
<div class="timeline-chart-header-title" v-else>{{this.current | date(formatter.title)}}</div>
|
||||
<div class="timeline-chart-header-items">
|
||||
<div :class="'timeline-chart-header-item timeline-chart-header-item-' + index" v-for="(interval, index) in intervals" :key="'timeline-chart-header-item-' + index">
|
||||
<label :class="{'rotate': formatter.interval.length >= 5 && !formatter.showTime}">{{interval | date(formatter.interval)}}</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="cursone-gantt" ref="cursone"
|
||||
@pointerdown="startMove"
|
||||
@pointermove="moving"
|
||||
@pointerup="stopMove"
|
||||
:style="{'left': `${cursorPosition}%`}">
|
||||
<div class="line"></div>
|
||||
<div class="oval">
|
||||
<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
width="572.8px" height="572.801px" viewBox="0 0 572.8 572.801" style="enable-background:new 0 0 572.8 572.801;"
|
||||
xml:space="preserve">
|
||||
<g>
|
||||
<path d="M520.25,353.6c0,125-100.5,219.201-233.8,219.201S52.55,478.6,52.55,353.6c0-115.3,164.7-301.5,197.7-337.7
|
||||
c9.3-10.2,22.4-15.9,36.2-15.9s26.9,5.8,36.2,15.9C355.55,52.1,520.25,238.4,520.25,353.6z"/>
|
||||
</g>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script src="./timeline-chart-header.ts" lang="ts"></script>
|
||||
@@ -0,0 +1,91 @@
|
||||
import Vue from "vue";
|
||||
import { Component, Prop } from "vue-property-decorator";
|
||||
import moment from "moment";
|
||||
|
||||
|
||||
@Component({})
|
||||
export default class TimeLineChartRow extends Vue {
|
||||
@Prop({required: true})
|
||||
start: Date;
|
||||
|
||||
@Prop({required: true})
|
||||
end: Date;
|
||||
|
||||
@Prop({required: true, default: [] as server.timeLineChartItem[] })
|
||||
occurrences: server.timeLineChartItem[];
|
||||
|
||||
@Prop({required: false, default: "#c9243f"})
|
||||
color: string;
|
||||
|
||||
oneHour: number = 60 * 60 * 1000;
|
||||
oneDay: number = 24 * this.oneHour;
|
||||
|
||||
get tasks(){
|
||||
return this.occurrences;
|
||||
}
|
||||
|
||||
get _start(): Date {
|
||||
let _startTime = this.start.getTime();
|
||||
let _endTime = this.end.getTime();
|
||||
let _diffDays = Math.round(Math.abs((_endTime - _startTime) / this.oneDay));
|
||||
if(_diffDays == 0)
|
||||
return new Date(_startTime - this.oneHour);
|
||||
|
||||
_startTime = (new Date(this.start.getTime()).setHours(0,0,0));
|
||||
_endTime = (new Date(this.end.getTime()).setHours(23,59,59));
|
||||
return new Date(_startTime - this.oneDay);
|
||||
}
|
||||
|
||||
get _end(): Date {
|
||||
let _startTime = this.start.getTime();
|
||||
let _endTime = this.end.getTime();
|
||||
let _diffDays = Math.round(Math.abs((_endTime - _startTime) / this.oneDay));
|
||||
|
||||
if(_diffDays == 0)
|
||||
return new Date(_endTime + this.oneHour);
|
||||
|
||||
_startTime = (new Date(this.start.getTime()).setHours(0,0,0));
|
||||
_endTime = (new Date(this.end.getTime()).setHours(23,59,59));
|
||||
return new Date(_endTime + this.oneDay);
|
||||
}
|
||||
|
||||
get diff() : number{
|
||||
return this.parseDateTime(this._end) - this.parseDateTime(this._start);
|
||||
}
|
||||
|
||||
from(task: server.timeLineChartItem) : number {
|
||||
let from = this.parseDateTime(task.from);
|
||||
return this.computes(from);
|
||||
}
|
||||
|
||||
to(task: server.timeLineChartItem) : number {
|
||||
let to = this.parseDateTime(task.to);
|
||||
return 100 - this.computes(to);
|
||||
}
|
||||
|
||||
colorOf(task: server.timeLineChartItem) : string {
|
||||
if(task.color) return task.color;
|
||||
return this.color;
|
||||
}
|
||||
|
||||
tooltipOf(task: server.timeLineChartItem) : string {
|
||||
return `${task.name}!`
|
||||
}
|
||||
|
||||
private parseDateTime(date: string | Date) : number
|
||||
{
|
||||
if (typeof (date) === "object")
|
||||
return date.getTime();
|
||||
|
||||
if (typeof (date) === "string")
|
||||
{
|
||||
let _date = moment(date, "DD/MM/YYYY").toDate();
|
||||
if (!isNaN(_date.getTime())) return _date.getTime();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
private computes(value: number) : number {
|
||||
return ((value - this.parseDateTime(this._start)) * 100) / this.diff;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
<template>
|
||||
<div class="timeline-chart-row">
|
||||
<div class="timeline-chart-row-item" v-for="(task, index) in tasks" :key="'timeline-chart-row-item-' + index"
|
||||
:style="{'left': `${from(task)}%`, 'right': `${to(task)}%`, 'background-color': colorOf(task)}"
|
||||
v-tooltip="{content: 'Tooltip content here', trigger: 'click'}"></div>
|
||||
<!-- <svg :width="{endOf}" height="64" :viewBox="`0 0 ${endOf} 64`" xmlns="http://www.w3.org/2000/svg" preserveAspectratio="xMinYMin" class="timeline-chart-row">
|
||||
<g v-for="(task, index) in tasks"
|
||||
:key="'timeline-chart-row-item-' + index"
|
||||
:class="'timeline-chart-row-item timeline-chart-row-item-' + index">
|
||||
<rect :width="`${widthOf(task)}`" height="60" :x="from(task)" :y="2"
|
||||
:fill="colorOf"
|
||||
v-tooltip="{content: tooltipOf(task), trigger: 'hover'}"
|
||||
style="stroke:black;stroke-width:5;" />
|
||||
</g>
|
||||
</svg> -->
|
||||
</div>
|
||||
</template>
|
||||
<script src="./timeline-chart-row.ts" lang="ts"></script>
|
||||
+39
-36
@@ -1,7 +1,7 @@
|
||||
import Vue from "vue";
|
||||
import VueRouter from "vue-router";
|
||||
import VeeValidate from "vee-validate";
|
||||
import { store, machineStatusActions,machineInfoStore } from "./store";
|
||||
import { store, machineStatusActions, machineInfoStore } from "./store";
|
||||
import "./_base/gestures";
|
||||
import "./app.business-logic";
|
||||
import "./app.modules";
|
||||
@@ -13,7 +13,7 @@ import { Factory, MessageService } from "src/_base";
|
||||
// var JustGage = require("justgage/justgage.js");
|
||||
|
||||
const App = () =>
|
||||
import("./App.vue");
|
||||
import ("./App.vue");
|
||||
|
||||
import { routes } from "./app.routes";
|
||||
|
||||
@@ -22,6 +22,9 @@ Vue.use(VueRouter);
|
||||
Vue.use(VeeValidate); // forms validation for vuejs
|
||||
// Vue.use(VueGesture);
|
||||
|
||||
import VTooltip from 'v-tooltip'
|
||||
Vue.use(VTooltip)
|
||||
|
||||
let router = new VueRouter({ linkActiveClass: "inpath", linkExactActiveClass: "active" });
|
||||
router.addRoutes(routes);
|
||||
|
||||
@@ -31,29 +34,29 @@ let developerMode = true;
|
||||
|
||||
// manipulate the title page
|
||||
router.beforeEach((to, from, next) => {
|
||||
console.log("Navigate To:", to);
|
||||
if (to.meta && to.meta.area) {
|
||||
// Check if area is enabled
|
||||
if (!developerMode && !machineStatusActions.isAreaEnabled(store, to.meta.area)) {
|
||||
next({
|
||||
path: '/'
|
||||
})
|
||||
return;
|
||||
console.log("Navigate To:", to);
|
||||
if (to.meta && to.meta.area) {
|
||||
// Check if area is enabled
|
||||
if (!developerMode && !machineStatusActions.isAreaEnabled(store, to.meta.area)) {
|
||||
next({
|
||||
path: '/'
|
||||
})
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (to.meta && to.meta.title) {
|
||||
if (to.meta && to.meta.title) {
|
||||
|
||||
if (typeof cmsClient == "undefined")
|
||||
window.document.title = "CMS Active - " + to.meta.title;
|
||||
else
|
||||
window.document.title = to.meta.title;
|
||||
}
|
||||
if(store.state.machineInfo.canChangePages)
|
||||
next();
|
||||
else{
|
||||
Factory.Get(MessageService).publishToChannel("show-nochange-page");
|
||||
next(false);
|
||||
}
|
||||
if (typeof cmsClient == "undefined")
|
||||
window.document.title = "CMS Active - " + to.meta.title;
|
||||
else
|
||||
window.document.title = to.meta.title;
|
||||
}
|
||||
if (store.state.machineInfo.canChangePages)
|
||||
next();
|
||||
else {
|
||||
Factory.Get(MessageService).publishToChannel("show-nochange-page");
|
||||
next(false);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -63,10 +66,10 @@ new LocalizationService().init();
|
||||
|
||||
|
||||
let v = new Vue({
|
||||
router: router,
|
||||
store,
|
||||
el: "app",
|
||||
render: (h) => h(App),
|
||||
router: router,
|
||||
store,
|
||||
el: "app",
|
||||
render: (h) => h(App),
|
||||
});
|
||||
|
||||
|
||||
@@ -80,12 +83,12 @@ import "./filters/isValidMixin";
|
||||
|
||||
// polyfills !!
|
||||
if (!String.prototype.format) {
|
||||
String.prototype.format = function () {
|
||||
var args = arguments;
|
||||
return this.replace(/{(\d+)}/g, function (match, number) {
|
||||
return typeof args[number] != 'undefined' ?
|
||||
args[number] :
|
||||
match;
|
||||
});
|
||||
};
|
||||
}
|
||||
String.prototype.format = function() {
|
||||
var args = arguments;
|
||||
return this.replace(/{(\d+)}/g, function(match, number) {
|
||||
return typeof args[number] != 'undefined' ?
|
||||
args[number] :
|
||||
match;
|
||||
});
|
||||
};
|
||||
}
|
||||
@@ -1,8 +1,10 @@
|
||||
<template>
|
||||
<div class="accordion-dropdown">
|
||||
<header @click="toggleExpander()">
|
||||
<span>{{title}}</span>
|
||||
<div class="expander" >
|
||||
<slot name="header">
|
||||
<span>{{title}}</span>
|
||||
</slot>
|
||||
<div class="expander">
|
||||
<i class="fa fa-caret-down" v-if="!expanded"></i>
|
||||
<i class="fa fa-caret-up" v-if="expanded"></i>
|
||||
</div>
|
||||
|
||||
@@ -21,13 +21,15 @@ export class ReportService extends baseRestService {
|
||||
|
||||
}
|
||||
|
||||
async TimeLine(filterInterval: Array<string>): Promise<any> {
|
||||
async TimeLine(filterInterval: Array<string>): Promise<server.timeLineChartData> {
|
||||
let filter = {
|
||||
name: "",
|
||||
startDate: filterInterval[0],
|
||||
endDate: filterInterval[1]
|
||||
}
|
||||
return await this.Post<any>('/api/report/timeLine',filter,true);
|
||||
};
|
||||
let result = await this.Post<server.timeLineChartData>('/api/report/timeLine',filter,true);
|
||||
reportActions.updateReportTimeLineChart(store, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
async ProgramsReport(pageSize: number, page: number, name: string, filterInterval: Array<Date>): Promise<any> {
|
||||
@@ -42,9 +44,6 @@ export class ReportService extends baseRestService {
|
||||
reportActions.updateReportTableProduction(store,result.occurrences);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
export const reportService = new ReportService();
|
||||
|
||||
@@ -1,19 +1,22 @@
|
||||
|
||||
export interface ReportStoreModel {
|
||||
reportData: server.reportData
|
||||
reportPieChart: server.pieChartData
|
||||
reportPieChart: server.pieChartData,
|
||||
reportTimeLineChart: server.timeLineChartData,
|
||||
reportTableDataProd: Array<server.programTableData>
|
||||
}
|
||||
|
||||
export interface ReportActions {
|
||||
updateReportData(context, model: server.reportData);
|
||||
updateReportPieChart(context, model: server.pieChartData);
|
||||
updateReportTimeLineChart(context, model: server.timeLineChartData);
|
||||
updateReportTableProduction(context, model: server.programTableData[]);
|
||||
}
|
||||
|
||||
export interface ReportGetters{
|
||||
getReportData: () => server.reportData;
|
||||
getPieChartData: () => server.pieChartData;
|
||||
getTimeLineChartData: () => server.timeLineChartData;
|
||||
getProgramsReportProd: () => server.programTableData[];
|
||||
}
|
||||
|
||||
@@ -23,10 +26,12 @@ export const reportStore = {
|
||||
_reportTableDataProd:new Map < string, server.programTableData > (),
|
||||
reportData: {absoluteValue:0,discardedPieces:0,productedPieces:0},
|
||||
reportPieChart: {idle:0,run:0,stop:0},
|
||||
reportTimeLineChart: {} as server.timeLineChartData,
|
||||
} as ReportStoreModel,
|
||||
getters:{
|
||||
getReportData: (state) => (): server.reportData => (state as ReportStoreModel).reportData,
|
||||
getPieChartData: (state) => (): server.pieChartData => (state as ReportStoreModel).reportPieChart,
|
||||
getTimeLineChartData: (state) => (): server.timeLineChartData => (state as ReportStoreModel).reportTimeLineChart,
|
||||
getProgramsReportProd: (state) => (): Array<server.programTableData> => (state as ReportStoreModel).reportTableDataProd
|
||||
},
|
||||
mutations: {
|
||||
@@ -38,6 +43,9 @@ export const reportStore = {
|
||||
},
|
||||
UpdateReportTableProduction(store, model: server.programTableData[]){
|
||||
store.reportTableDataProd = model;
|
||||
},
|
||||
UpdateReportTimeLineChart(store, model: server.timeLineChartData){
|
||||
store.reportTimeLineChart = model;
|
||||
}
|
||||
},
|
||||
actions: {
|
||||
@@ -49,6 +57,9 @@ export const reportStore = {
|
||||
},
|
||||
updateReportTableProduction(context, model: server.programTableData[]){
|
||||
context.commit("UpdateReportTableProduction", model);
|
||||
},
|
||||
updateReportTimeLineChart(context, model: server.timeLineChartData){
|
||||
context.commit("UpdateReportTimeLineChart", model);
|
||||
}
|
||||
} as ReportActions
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user