【C #】 WPF wave line effect

 using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Threading.Tasks;

using System.Windows;

using System.Windows.Controls;

using System.Windows.Data;

using System.Windows.Documents;

using System.Windows.Input;

using System.Windows.Media;

using System.Windows.Media.Imaging;

using System.Windows.Navigation;

using System.Windows.Shapes;

using WaveLineTextDemo;


namespace waveLine

{

    /// <summary>

    /// Interaction logic for MainWindow.xaml

    /// </summary>

    public partial class MainWindow : Window

    {

        public MainWindow()

        {

            InitializeComponent();

        }

        private Point? _startPoint = null;

        private void ContainerCanvas_OnPreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)

        {

            var position = e.GetPosition(ContainerCanvas);

            if (_startPoint == null)

            {

                _startPoint = position;

            }

            else

            {


                //Delete preview

                if (_previewLineElement != null)

                {

                    ContainerCanvas.Children.Remove(_previewLineElement);

                    _previewLineElement = null;

                    _lastMovedPoint = null;

                }


                //Determine the end point and draw a wavy line

                var myLineElement = new MyLineElement();

                myLineElement.DrawLine((Point)_startPoint, position);

                ContainerCanvas.Children.Add(myLineElement);

                _startPoint = null;

            }

        }


        private MyLineElement _previewLineElement = null;

        private Point? _lastMovedPoint = null;



        private void ContainerCanvas_OnMouseMove(object sender, MouseEventArgs e)

        {

            var position = e.GetPosition(ContainerCanvas);

            if (_startPoint != null && (_lastMovedPoint == null || _lastMovedPoint != null & (position - (Point)_lastMovedPoint).Length >= 2))

            {

                _lastMovedPoint = position;

                if (_previewLineElement != null)

                {

                    ContainerCanvas.Children.Remove(_previewLineElement);

                }

                var myLineElement = new MyLineElement();

                myLineElement.DrawLine((Point)_startPoint, position);

                ContainerCanvas.Children.Add(myLineElement);

                _previewLineElement = myLineElement;

            }

        }

    }

}

<Window x:Class="waveLine.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:waveLine"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Grid>
        <Canvas x:Name="ContainerCanvas" PreviewMouseLeftButtonDown="ContainerCanvas_OnPreviewMouseLeftButtonDown"
               MouseMove="ContainerCanvas_OnMouseMove"
               Background="LightGray"></Canvas>
    </Grid>
</Window>

 using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Shapes;

namespace WaveLineTextDemo
{
    class MyLineElement : FrameworkElement
    {
        public MyLineElement()
        {
            _visualShape = new VisualCollection(this);
        }
        internal void DrawLine(Point startPoint, Point endPoint)
        {
            List<Point> points = ForgePoints(startPoint, endPoint);
            DrawLine(points);
        }
        private const int SeparatorPiexl = 4;
        private const int AbundancePiexl = 3;
        private List<Point> ForgePoints(Point startPoint, Point endPoint)
        {
            var points = new List<Point>();

            var lineVector = endPoint - startPoint;
            var lineDistance = lineVector.Length;
            var lineAngle = Math.Atan2(-(endPoint.Y - startPoint.Y), endPoint.X - startPoint.X);

            points.Add(startPoint);
            int index = 0;
            bool isAbundanceUpward = true;
            while (index * SeparatorPiexl < lineDistance)
            {
                index++;

                //Calculate the interval length (simulation point to starting point)
                var separatorDistance = index * SeparatorPiexl;
                var abundancePiexl = AbundancePiexl;
                var distanceToStartPoint = Math.Sqrt(Math.Pow(separatorDistance, 2) + Math.Pow(abundancePiexl, 2));
                //Calculate the simulation point, starting point, and the angle to the straight line
                var separatorAngle = Math.Atan2(AbundancePiexl, separatorDistance);
                separatorAngle = isAbundanceUpward ? separatorAngle : -separatorAngle;
                isAbundanceUpward = !isAbundanceUpward;

                //Get the horizontal angle of the simulated point
                var mockPointAngle = lineAngle + separatorAngle;

                //Calculate the simulation point coordinates
                var verticalDistance = distanceToStartPoint * Math.Sin(mockPointAngle);
                var horizontalDistance = distanceToStartPoint * Math.Cos(mockPointAngle);
                var mockPoint = new Point(startPoint.X + horizontalDistance, startPoint.Y - verticalDistance);
                points.Add(mockPoint);
            }
            points.Add(endPoint);
            return points;
        }

        private void DrawLine(List<Point> points)
        {
            _visualShape.Clear();

            var geometryTest = new StreamGeometry();
            using (var ctx = geometryTest.Open())
            {
                ctx.BeginFigure(points[0], true, false);
                if (points.Count % 2 == 0)
                {

                    //Draw the second-order Bessel function, need to ensure that it is an even point
                    ctx.PolyQuadraticBezierTo(points, true, true);
                }
                else
                {

                    //Draw the second-order Bessel function, need to ensure that it is an even point
                    points.Insert(0, points[0]);
                    ctx.PolyQuadraticBezierTo(points, true, true);
                }

                ctx.Close();
            }

            var visual = new DrawingVisual();
            using (var context = visual.RenderOpen())
            {
                context.DrawGeometry(FillBrush, StrokePen, geometryTest);
            }
            _visualShape.Add(visual);
        }

        #region InternalMethod

        [Obsolete]
        protected override void OnRender(DrawingContext drawingContext)
        {

            //Deprecated, changed to _visualShape filling implementation
            //drawingContext.DrawGeometry(FillBrush, StrokePen, BaseGeometry);
        }

        protected override int VisualChildrenCount => _visualShape.Count;

        protected override Visual GetVisualChild(int index)
        {
                if (index < 0 || index >= _visualShape.Count)
                {
                    throw new ArgumentOutOfRangeException();
                }

                return _visualShape[index];
            }

        #endregion
        #region CurveAttributes

        private readonly VisualCollection _visualShape;
            protected Brush FillBrush {  get; set; } = Brushes.Transparent;
        public Brush LineBrush {  get; set; } = Brushes.DarkSeaGreen;
        protected double BorderThickness {  get; set; } = 1.0;
        private Pen _defaultPen = null;
        protected Pen StrokePen
        {
            get
            {
                if (_defaultPen == null)
                {
                    _defaultPen = new Pen(LineBrush, BorderThickness);
                }
                return _defaultPen;
            }
            set => _defaultPen = value;
        }

        #endregion}
    }
}

【Laravel 8】 expiry date management/ tracking


https://github.com/edward1986/inventory



 <?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class CreateProductsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('products', function (Blueprint $table) {
$table->id();
$table->integer('quantity')->unsigned();
$table->string('name');
$table->timestamps();
});
}

/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('products');
}
}

<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class CreateTransactionsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('transactions', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('product_id')->unsigned()->nullable();
$table->foreign('product_id')->references('id')
->on('products')->onDelete('cascade');
$table->string('purchase_order')->nullable();
$table->integer('quantity')->unsigned();
$table->integer('display_quantity')->unsigned();
$table->integer('type')->unsigned();
$table->string('expiry_date', 30)->nullable();

$table->timestamps();
});
}

/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('transactions');
}
}

require('./bootstrap');
window.Vue = require('vue')
import VueRouter from 'vue-router'

Vue.use(VueRouter)

const routes = [
{
path: '', component: resolve => require(["./components/Product/product"], resolve), children: [
{
path: '', component: resolve => require(["./components/Product/index"], resolve), name: 'index_product'
},
{
path: 'create',
component: resolve => require(["./components/Product/create"], resolve),
name: 'create_product'
},
{
path: ':id', component: resolve => require(["./components/Product/show"], resolve), name: 'show_product'
}
]
}
]
const router = new VueRouter({
routes
});
new Vue({
router,
data() {
return {

store: {
state: {
products: [],
transactions: [],
id: 1,
},
mutations: {
create(state, data) {
state[data.state].push(data.push)
},
incrementId(state, data) {
state.id++
}
},
dispatch(mutation, data = {}) { //$root.store.dispatch
this.mutations[mutation](this.state, data)
}
}
}
},
render: h => h(require('./components/App.vue').default)
}).$mount('#app')

<template>
<div>
<button v-if="!isCheck" @click="checkType = 1; isCheck = !isCheck">check in</button>
<button v-if="!isCheck" @click="checkType = 0; isCheck = !isCheck">check out</button>
<router-link v-if="!isCheck" :to="{name:'show_product', params:{id: product.id}}">view</router-link>
<div v-if="isCheck">
<input v-if="checkType == 1" type="text" placeholder="purchase number" v-model="purchase_order">
<input type="number" v-model="quantity">
<input type="date" v-if="checkType == 1" v-model="expire_date">
<button v-if="checkType == 1" :disabled="!(quantity > 0 && purchase_order)" @click="check(1)">Check in
</button>
<button v-if="checkType == 0" :disabled="!(quantity > 0 && quantity < product.quantity)" @click="check(0)">
Check out
</button>
<button @click="isCheck = false">cancel</button>
</div>

</div>
</template>

<script>
export default {
name: "check-in",
props: ['product'],
data() {
return {
quantity: 0,
checkType: 0,
isCheck: false,
purchase_order: '',
expire_date: ''
}
},
methods: {
check(type) {
var vm = this
if (type === 0) {
var requested = parseInt(vm.quantity);
var lastTransaction;
axios.get(`/api/transaction/filter/${vm.product.id}` ).then(response => {
lastTransaction = response.data
return lastTransaction
}).then(()=>{
while (requested) {

var quantity = lastTransaction.quantity
if (quantity >= requested) {


axios.post('/api/transactions',{
product_id: vm.product.id,
type: type,
display_quantity: requested,
quantity: requested,
purchase_order: lastTransaction.purchase_order,
expiry_date: lastTransaction.expiry_date
}).then(response =>{
vm.$emit('new-value', response.data)
})
requested = 0;
} else if (requested >= quantity) {
lastTransaction.quantity = 0
axios.post('/api/transactions', {
product_id: vm.product.id,
type: type,
display_quantity: quantity,
quantity: quantity,
purchase_order: lastTransaction.purchase_order,
expire_date: lastTransaction.expire_date
}).then(response =>{
vm.$emit('new-value', response.data)
})

requested = requested - quantity;
}

}
})


} else if (type === 1) {
axios.post('/api/transactions', {
purchase_order: vm.purchase_order,
product_id: vm.product.id,
type: type,
display_quantity: vm.quantity,
quantity: vm.quantity,
expire_date: vm.expire_date
}).then(response =>{
vm.$emit('new-value', response.data)
})
}

vm.quantity = 0
}
}
}
</script>

<style scoped>

</style>
<template>
<div>
create Product

<input type="text" v-model="name" placeholder="name">
<input type="text" v-model="purchase_order" placeholder="purchase_number">
<input type="number" placeholder="quantity" v-model="quantity">
<input type="date" v-model="expire_date">
<button :disabled="!(quantity.length > 0)" @click="create">submit</button>
</div>
</template>

<script>
export default {
name: "create_product",
data(){
return{
name: '',
quantity: 0,
purchase_order: '',
expire_date: ''
}
},
methods:{
create(){
axios.post('/api/products', {name: this.name, quantity: this.quantity, purchase_order: this.purchase_order, expire_date: this.expire_date } ).then(response => {

})
}
}
}
</script>

<style scoped>

</style>

<template>
<div>
<ul v-if="products.length">
<li v-for="(product, index) in products">{{product.name}} - {{product.quantity}} <check-in @new-value="checkOperation(index, $event)" :product="product"/></li>
</ul>
<div v-else>No data</div>
</div>
</template>

<script>
import CheckIn from './check-in'
export default {
name: "index_product",
components:{
'check-in': CheckIn
},
data(){
return {
list:[]
}
},
mounted(){
var vm = this
axios.get('/api/products').then(response => {
vm.list = response.data.data
})
},
methods:{
checkOperation(index, event){
var vm = this
vm.list[index].transactions.push(event)
}
},
computed:{
products(){
var vm = this
return _.map(vm.list, function(product){
var transactions = _.filter(product.transactions, function(transaction){
return new Date(transaction.expiry_date).getTime() >= new Date().getTime()
})
product.quantity = _.reduce(transactions, function(sum, transaction) {
return transaction.type == 1 ? sum + _.toInteger(transaction.display_quantity) : sum - _.toInteger(transaction.display_quantity);
}, 0);
return product
})

}
},
}
</script>

<style scoped>

</style>

<template>
<div>
Products
<ul>
<router-link :to="{name: 'create_product'}">Create Product</router-link>
</ul>
<router-view></router-view>


</div>
</template>

<script>
export default {
name: "product"
}
</script>

<style scoped>

</style>

<template>
<div>
Name:{{product.length ? product.name : ''}}
<h4>Transactions</h4>
<ul v-if="product.transactions.length">
<li v-for="transaction in product.transactions"><span style="color: white;"
:style="`background: ${transaction.type === 1 ? 'green' : 'red'}`">{{`purchase order: ${transaction.purchase_order} ${transaction.type === 1 ? 'in' : 'out'} - ${transaction.display_quantity}`}}{{` expire date: ${transaction.expiry_date}`}}</span>
</li>
</ul>
<div v-else>
no data
</div>
</div>
</template>

<script>
export default {
name: "show_product",
data() {
return {
product: {}
}
},
mounted() {
var vm = this
axios.get(`/api/products/${vm.$route.params.id}`).then(response => {
vm.product = response.data
})
},
}
</script>

<style scoped>

</style>


<template>
<div>
<h2>Home</h2>
<ul>
<li>
<router-link to="/">Products</router-link>
</li>
</ul>
<router-view></router-view>
</div>

</template>

<script>
export default {
name: "App"
}
</script>

<style scoped>

</style>

<?php

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\ProductController;
use App\Http\Controllers\TransactionController;

/*
|--------------------------------------------------------------------------
| API Routes
|--------------------------------------------------------------------------
|
| Here is where you can register API routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| is assigned the "api" middleware group. Enjoy building your API!
|
*/

Route::middleware('auth:api')->get('/user', function (Request $request) {
return $request->user();
});
Route::apiResources([
'products' => ProductController::class,
'transactions' => TransactionController::class
]);

Route::get('transaction/filter/{product_id}' , [TransactionController::class, 'filter']);

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Product extends Model
{
use HasFactory;
public $fillable = ['quantity','name'];
public function transactions()
{
return $this->hasMany(Transaction::class);
}

}

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Transaction extends Model
{
use HasFactory;

public $fillable = [
'purchase_order',
'quantity',
'display_quantity',
'type',
'expiry_date',
];

public function product()
{
return $this->belongsTo(Product::class);
}
}

<?php

namespace App\Http\Controllers;

use App\Models\Product;
use App\Models\Transaction;
use Illuminate\Http\Request;

class ProductController extends Controller
{
/**
* Display a listing of the resource.
*
* @return \Illuminate\Http\Response
*/
public function index()
{
return response()->json(Product::with('transactions')->paginate(10), 201);
}

/**
* Store a newly created resource in storage.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function store(Request $request)
{
$product = new Product;
$product->name = $request->name;
$product->quantity = $request->quantity;
$product->save();
$transaction = new Transaction([
'purchase_order' => $request->purchase_order,
'quantity' => $request->quantity,
'display_quantity' => $request->quantity,
'type' => 1,
'expiry_date' => $request->expire_date,
]
);
$product->transactions()->save($transaction);
return response()->json($product, 201);

}

/**
* Display the specified resource.
*
* @param \App\Models\Product $product
* @return \Illuminate\Http\Response
*/
public function show(Product $product)
{
$item = Product::whereId($product->id)->with('transactions')->first();
return response()->json($item);
}

/**
* Update the specified resource in storage.
*
* @param \Illuminate\Http\Request $request
* @param \App\Models\Product $product
* @return \Illuminate\Http\Response
*/
public function update(Request $request, Product $product)
{
//
}

/**
* Remove the specified resource from storage.
*
* @param \App\Models\Product $product
* @return \Illuminate\Http\Response
*/
public function destroy(Product $product)
{
//
}
}

<?php

namespace App\Http\Controllers;

use App\Models\Product;
use App\Models\Transaction;
use Carbon\Carbon;
use Illuminate\Http\Request;

class TransactionController extends Controller
{
/**
* Display a listing of the resource.
*
* @return \Illuminate\Http\Response
*/
public function index()
{
//
}

/**
* Store a newly created resource in storage.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/

public function filter($product_id){
$transaction = Transaction::whereProductId($product_id)->whereDate('expiry_date', '>', Carbon::parse()->format('Y-m-d'))->where('quantity', '>', 0)->where('type', 1)->first();
return response()->json($transaction);
}

public function store(Request $request)
{
$product = Product::whereId($request->product_id)->first();
$transaction = new Transaction([
'purchase_order' => $request->purchase_order,
'quantity' => $request->quantity,
'display_quantity' => $request->quantity,
'type' => $request->type,
'expiry_date' => $request->expiry_date,
]
);
$product->transactions()->save($transaction);
return response()->json($transaction);
}

/**
* Display the specified resource.
*
* @param \App\Models\Transaction $transaction
* @return \Illuminate\Http\Response
*/
public function show(Transaction $transaction)
{
//
}

/**
* Update the specified resource in storage.
*
* @param \Illuminate\Http\Request $request
* @param \App\Models\Transaction $transaction
* @return \Illuminate\Http\Response
*/
public function update(Request $request, Transaction $transaction)
{
//
}

/**
* Remove the specified resource from storage.
*
* @param \App\Models\Transaction $transaction
* @return \Illuminate\Http\Response
*/
public function destroy(Transaction $transaction)
{
//
}
}

Building Bluesky: a Distributed Social Network (Real-World Engineering Challenges)

Bluesky is built by around 10 engineers, and has amassed 5 million users since publicly launching in February this year. A deep dive into no...

Contact Form

Name

Email *

Message *